Merge "Correct screenshot JNI code."
diff --git a/api/current.txt b/api/current.txt
index 56fedf6..c7c7c54 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -23851,8 +23851,16 @@
}
public static final class TvContract.Programs implements android.media.tv.TvContract.BaseTvColumns {
+ field public static final java.lang.String ASPECT_RATIO_16_9 = "ASPECT_RATIO_16_9";
+ field public static final java.lang.String ASPECT_RATIO_1_1 = "ASPECT_RATIO_1_1";
+ field public static final java.lang.String ASPECT_RATIO_2_3 = "ASPECT_RATIO_2_3";
+ field public static final java.lang.String ASPECT_RATIO_3_2 = "ASPECT_RATIO_3_2";
+ field public static final java.lang.String AVAILABILITY_AVAILABLE = "AVAILABILITY_AVAILABLE";
+ field public static final java.lang.String AVAILABILITY_FREE_WITH_SUBSCRIPTION = "AVAILABILITY_FREE_WITH_SUBSCRIPTION";
+ field public static final java.lang.String AVAILABILITY_PAID_CONTENT = "AVAILABILITY_PAID_CONTENT";
field public static final java.lang.String COLUMN_AUDIO_LANGUAGE = "audio_language";
field public static final java.lang.String COLUMN_AUTHOR = "author";
+ field public static final java.lang.String COLUMN_AVAILABILITY = "availability";
field public static final java.lang.String COLUMN_BROADCAST_GENRE = "broadcast_genre";
field public static final java.lang.String COLUMN_CANONICAL_GENRE = "canonical_genre";
field public static final java.lang.String COLUMN_CHANNEL_ID = "channel_id";
@@ -23869,7 +23877,12 @@
field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG3 = "internal_provider_flag3";
field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4";
field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_ID = "internal_provider_id";
+ field public static final java.lang.String COLUMN_ITEM_COUNT = "item_count";
+ field public static final java.lang.String COLUMN_LIVE = "live";
+ field public static final java.lang.String COLUMN_LOGO = "logo";
field public static final java.lang.String COLUMN_LONG_DESCRIPTION = "long_description";
+ field public static final java.lang.String COLUMN_OFFER_PRICE = "offer_price";
+ field public static final java.lang.String COLUMN_POSTER_ART_ASPECT_RATIO = "poster_art_aspect_ratio";
field public static final java.lang.String COLUMN_POSTER_ART_URI = "poster_art_uri";
field public static final java.lang.String COLUMN_PREVIEW_DURATION = "preview_duration";
field public static final java.lang.String COLUMN_PREVIEW_INTENT_URI = "preview_intent_uri";
@@ -23877,6 +23890,7 @@
field public static final java.lang.String COLUMN_PREVIEW_VIDEO_URI = "preview_video_uri";
field public static final java.lang.String COLUMN_PREVIEW_WEIGHT = "preview_weight";
field public static final java.lang.String COLUMN_RECORDING_PROHIBITED = "recording_prohibited";
+ field public static final java.lang.String COLUMN_RELEASE_DATE = "release_date";
field public static final java.lang.String COLUMN_REVIEW_RATING = "review_rating";
field public static final java.lang.String COLUMN_REVIEW_RATING_STYLE = "review_rating_style";
field public static final java.lang.String COLUMN_SEARCHABLE = "searchable";
@@ -23884,12 +23898,16 @@
field public static final deprecated java.lang.String COLUMN_SEASON_NUMBER = "season_number";
field public static final java.lang.String COLUMN_SEASON_TITLE = "season_title";
field public static final java.lang.String COLUMN_SHORT_DESCRIPTION = "short_description";
+ field public static final java.lang.String COLUMN_STARTING_PRICE = "starting_price";
field public static final java.lang.String COLUMN_START_TIME_UTC_MILLIS = "start_time_utc_millis";
+ field public static final java.lang.String COLUMN_THUMBNAIL_ASPECT_RATIO = "poster_thumbnail_aspect_ratio";
field public static final java.lang.String COLUMN_THUMBNAIL_URI = "thumbnail_uri";
field public static final java.lang.String COLUMN_TITLE = "title";
+ field public static final java.lang.String COLUMN_TYPE = "type";
field public static final java.lang.String COLUMN_VERSION_NUMBER = "version_number";
field public static final java.lang.String COLUMN_VIDEO_HEIGHT = "video_height";
field public static final java.lang.String COLUMN_VIDEO_WIDTH = "video_width";
+ field public static final java.lang.String COLUMN_WATCH_NEXT_TYPE = "watch_next_type";
field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/program";
field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/program";
field public static final android.net.Uri CONTENT_URI;
@@ -23902,7 +23920,22 @@
field public static final java.lang.String INTERACTION_TYPE_VIEWS = "INTERACTION_TYPE_VIEWS";
field public static final java.lang.String REVIEW_RATING_STYLE_PERCENTAGE = "REVIEW_RATING_STYLE_PERCENTAGE";
field public static final java.lang.String REVIEW_RATING_STYLE_STARS = "REVIEW_RATING_STYLE_STARS";
- field public static final java.lang.String REVIEW_RATING_STYLE_THUMPS_UP_DOWN = "REVIEW_RATING_STYLE_THUMPS_UP_DOWN";
+ field public static final java.lang.String REVIEW_RATING_STYLE_THUMBS_UP_DOWN = "REVIEW_RATING_STYLE_THUMBS_UP_DOWN";
+ field public static final java.lang.String TYPE_ALBUM = "TYPE_ALBUM";
+ field public static final java.lang.String TYPE_ARTIST = "TYPE_ARTIST";
+ field public static final java.lang.String TYPE_CHANNEL = "TYPE_CHANNEL";
+ field public static final java.lang.String TYPE_CLIP = "TYPE_CLIP";
+ field public static final java.lang.String TYPE_EVENT = "TYPE_EVENT";
+ field public static final java.lang.String TYPE_MOVIE = "TYPE_MOVIE";
+ field public static final java.lang.String TYPE_PLAYLIST = "TYPE_PLAYLIST";
+ field public static final java.lang.String TYPE_STATION = "TYPE_STATION";
+ field public static final java.lang.String TYPE_TRACK = "TYPE_TRACK";
+ field public static final java.lang.String TYPE_TV_EPISODE = "TYPE_TV_EPISODE";
+ field public static final java.lang.String TYPE_TV_SEASON = "TYPE_TV_SEASON";
+ field public static final java.lang.String TYPE_TV_SERIES = "TYPE_TV_SERIES";
+ field public static final java.lang.String WATCH_NEXT_TYPE_CONTINUE = "WATCH_NEXT_TYPE_CONTINUE";
+ field public static final java.lang.String WATCH_NEXT_TYPE_NEW = "WATCH_NEXT_TYPE_NEW";
+ field public static final java.lang.String WATCH_NEXT_TYPE_NEXT = "WATCH_NEXT_TYPE_NEXT";
}
public static final class TvContract.Programs.Genres {
diff --git a/api/system-current.txt b/api/system-current.txt
index 7f79c70..eb3d5e5 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -25598,8 +25598,16 @@
}
public static final class TvContract.Programs implements android.media.tv.TvContract.BaseTvColumns {
+ field public static final java.lang.String ASPECT_RATIO_16_9 = "ASPECT_RATIO_16_9";
+ field public static final java.lang.String ASPECT_RATIO_1_1 = "ASPECT_RATIO_1_1";
+ field public static final java.lang.String ASPECT_RATIO_2_3 = "ASPECT_RATIO_2_3";
+ field public static final java.lang.String ASPECT_RATIO_3_2 = "ASPECT_RATIO_3_2";
+ field public static final java.lang.String AVAILABILITY_AVAILABLE = "AVAILABILITY_AVAILABLE";
+ field public static final java.lang.String AVAILABILITY_FREE_WITH_SUBSCRIPTION = "AVAILABILITY_FREE_WITH_SUBSCRIPTION";
+ field public static final java.lang.String AVAILABILITY_PAID_CONTENT = "AVAILABILITY_PAID_CONTENT";
field public static final java.lang.String COLUMN_AUDIO_LANGUAGE = "audio_language";
field public static final java.lang.String COLUMN_AUTHOR = "author";
+ field public static final java.lang.String COLUMN_AVAILABILITY = "availability";
field public static final java.lang.String COLUMN_BROADCAST_GENRE = "broadcast_genre";
field public static final java.lang.String COLUMN_CANONICAL_GENRE = "canonical_genre";
field public static final java.lang.String COLUMN_CHANNEL_ID = "channel_id";
@@ -25616,7 +25624,12 @@
field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG3 = "internal_provider_flag3";
field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4";
field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_ID = "internal_provider_id";
+ field public static final java.lang.String COLUMN_ITEM_COUNT = "item_count";
+ field public static final java.lang.String COLUMN_LIVE = "live";
+ field public static final java.lang.String COLUMN_LOGO = "logo";
field public static final java.lang.String COLUMN_LONG_DESCRIPTION = "long_description";
+ field public static final java.lang.String COLUMN_OFFER_PRICE = "offer_price";
+ field public static final java.lang.String COLUMN_POSTER_ART_ASPECT_RATIO = "poster_art_aspect_ratio";
field public static final java.lang.String COLUMN_POSTER_ART_URI = "poster_art_uri";
field public static final java.lang.String COLUMN_PREVIEW_DURATION = "preview_duration";
field public static final java.lang.String COLUMN_PREVIEW_INTENT_URI = "preview_intent_uri";
@@ -25624,6 +25637,7 @@
field public static final java.lang.String COLUMN_PREVIEW_VIDEO_URI = "preview_video_uri";
field public static final java.lang.String COLUMN_PREVIEW_WEIGHT = "preview_weight";
field public static final java.lang.String COLUMN_RECORDING_PROHIBITED = "recording_prohibited";
+ field public static final java.lang.String COLUMN_RELEASE_DATE = "release_date";
field public static final java.lang.String COLUMN_REVIEW_RATING = "review_rating";
field public static final java.lang.String COLUMN_REVIEW_RATING_STYLE = "review_rating_style";
field public static final java.lang.String COLUMN_SEARCHABLE = "searchable";
@@ -25631,13 +25645,17 @@
field public static final deprecated java.lang.String COLUMN_SEASON_NUMBER = "season_number";
field public static final java.lang.String COLUMN_SEASON_TITLE = "season_title";
field public static final java.lang.String COLUMN_SHORT_DESCRIPTION = "short_description";
+ field public static final java.lang.String COLUMN_STARTING_PRICE = "starting_price";
field public static final java.lang.String COLUMN_START_TIME_UTC_MILLIS = "start_time_utc_millis";
+ field public static final java.lang.String COLUMN_THUMBNAIL_ASPECT_RATIO = "poster_thumbnail_aspect_ratio";
field public static final java.lang.String COLUMN_THUMBNAIL_URI = "thumbnail_uri";
field public static final java.lang.String COLUMN_TITLE = "title";
field public static final java.lang.String COLUMN_TRANSIENT = "transient";
+ field public static final java.lang.String COLUMN_TYPE = "type";
field public static final java.lang.String COLUMN_VERSION_NUMBER = "version_number";
field public static final java.lang.String COLUMN_VIDEO_HEIGHT = "video_height";
field public static final java.lang.String COLUMN_VIDEO_WIDTH = "video_width";
+ field public static final java.lang.String COLUMN_WATCH_NEXT_TYPE = "watch_next_type";
field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/program";
field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/program";
field public static final android.net.Uri CONTENT_URI;
@@ -25650,7 +25668,22 @@
field public static final java.lang.String INTERACTION_TYPE_VIEWS = "INTERACTION_TYPE_VIEWS";
field public static final java.lang.String REVIEW_RATING_STYLE_PERCENTAGE = "REVIEW_RATING_STYLE_PERCENTAGE";
field public static final java.lang.String REVIEW_RATING_STYLE_STARS = "REVIEW_RATING_STYLE_STARS";
- field public static final java.lang.String REVIEW_RATING_STYLE_THUMPS_UP_DOWN = "REVIEW_RATING_STYLE_THUMPS_UP_DOWN";
+ field public static final java.lang.String REVIEW_RATING_STYLE_THUMBS_UP_DOWN = "REVIEW_RATING_STYLE_THUMBS_UP_DOWN";
+ field public static final java.lang.String TYPE_ALBUM = "TYPE_ALBUM";
+ field public static final java.lang.String TYPE_ARTIST = "TYPE_ARTIST";
+ field public static final java.lang.String TYPE_CHANNEL = "TYPE_CHANNEL";
+ field public static final java.lang.String TYPE_CLIP = "TYPE_CLIP";
+ field public static final java.lang.String TYPE_EVENT = "TYPE_EVENT";
+ field public static final java.lang.String TYPE_MOVIE = "TYPE_MOVIE";
+ field public static final java.lang.String TYPE_PLAYLIST = "TYPE_PLAYLIST";
+ field public static final java.lang.String TYPE_STATION = "TYPE_STATION";
+ field public static final java.lang.String TYPE_TRACK = "TYPE_TRACK";
+ field public static final java.lang.String TYPE_TV_EPISODE = "TYPE_TV_EPISODE";
+ field public static final java.lang.String TYPE_TV_SEASON = "TYPE_TV_SEASON";
+ field public static final java.lang.String TYPE_TV_SERIES = "TYPE_TV_SERIES";
+ field public static final java.lang.String WATCH_NEXT_TYPE_CONTINUE = "WATCH_NEXT_TYPE_CONTINUE";
+ field public static final java.lang.String WATCH_NEXT_TYPE_NEW = "WATCH_NEXT_TYPE_NEW";
+ field public static final java.lang.String WATCH_NEXT_TYPE_NEXT = "WATCH_NEXT_TYPE_NEXT";
}
public static final class TvContract.Programs.Genres {
@@ -36611,6 +36644,7 @@
field public static final java.lang.String ACTION_APPLICATION_DETAILS_SETTINGS = "android.settings.APPLICATION_DETAILS_SETTINGS";
field public static final java.lang.String ACTION_APPLICATION_DEVELOPMENT_SETTINGS = "android.settings.APPLICATION_DEVELOPMENT_SETTINGS";
field public static final java.lang.String ACTION_APPLICATION_SETTINGS = "android.settings.APPLICATION_SETTINGS";
+ field public static final java.lang.String ACTION_APP_NOTIFICATION_SETTINGS = "android.settings.APP_NOTIFICATION_SETTINGS";
field public static final java.lang.String ACTION_BATTERY_SAVER_SETTINGS = "android.settings.BATTERY_SAVER_SETTINGS";
field public static final java.lang.String ACTION_BLUETOOTH_SETTINGS = "android.settings.BLUETOOTH_SETTINGS";
field public static final java.lang.String ACTION_CAPTIONING_SETTINGS = "android.settings.CAPTIONING_SETTINGS";
diff --git a/api/test-current.txt b/api/test-current.txt
index 9b2bf2b..9a8d308 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -23942,8 +23942,16 @@
}
public static final class TvContract.Programs implements android.media.tv.TvContract.BaseTvColumns {
+ field public static final java.lang.String ASPECT_RATIO_16_9 = "ASPECT_RATIO_16_9";
+ field public static final java.lang.String ASPECT_RATIO_1_1 = "ASPECT_RATIO_1_1";
+ field public static final java.lang.String ASPECT_RATIO_2_3 = "ASPECT_RATIO_2_3";
+ field public static final java.lang.String ASPECT_RATIO_3_2 = "ASPECT_RATIO_3_2";
+ field public static final java.lang.String AVAILABILITY_AVAILABLE = "AVAILABILITY_AVAILABLE";
+ field public static final java.lang.String AVAILABILITY_FREE_WITH_SUBSCRIPTION = "AVAILABILITY_FREE_WITH_SUBSCRIPTION";
+ field public static final java.lang.String AVAILABILITY_PAID_CONTENT = "AVAILABILITY_PAID_CONTENT";
field public static final java.lang.String COLUMN_AUDIO_LANGUAGE = "audio_language";
field public static final java.lang.String COLUMN_AUTHOR = "author";
+ field public static final java.lang.String COLUMN_AVAILABILITY = "availability";
field public static final java.lang.String COLUMN_BROADCAST_GENRE = "broadcast_genre";
field public static final java.lang.String COLUMN_CANONICAL_GENRE = "canonical_genre";
field public static final java.lang.String COLUMN_CHANNEL_ID = "channel_id";
@@ -23960,7 +23968,12 @@
field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG3 = "internal_provider_flag3";
field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4";
field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_ID = "internal_provider_id";
+ field public static final java.lang.String COLUMN_ITEM_COUNT = "item_count";
+ field public static final java.lang.String COLUMN_LIVE = "live";
+ field public static final java.lang.String COLUMN_LOGO = "logo";
field public static final java.lang.String COLUMN_LONG_DESCRIPTION = "long_description";
+ field public static final java.lang.String COLUMN_OFFER_PRICE = "offer_price";
+ field public static final java.lang.String COLUMN_POSTER_ART_ASPECT_RATIO = "poster_art_aspect_ratio";
field public static final java.lang.String COLUMN_POSTER_ART_URI = "poster_art_uri";
field public static final java.lang.String COLUMN_PREVIEW_DURATION = "preview_duration";
field public static final java.lang.String COLUMN_PREVIEW_INTENT_URI = "preview_intent_uri";
@@ -23968,6 +23981,7 @@
field public static final java.lang.String COLUMN_PREVIEW_VIDEO_URI = "preview_video_uri";
field public static final java.lang.String COLUMN_PREVIEW_WEIGHT = "preview_weight";
field public static final java.lang.String COLUMN_RECORDING_PROHIBITED = "recording_prohibited";
+ field public static final java.lang.String COLUMN_RELEASE_DATE = "release_date";
field public static final java.lang.String COLUMN_REVIEW_RATING = "review_rating";
field public static final java.lang.String COLUMN_REVIEW_RATING_STYLE = "review_rating_style";
field public static final java.lang.String COLUMN_SEARCHABLE = "searchable";
@@ -23975,12 +23989,16 @@
field public static final deprecated java.lang.String COLUMN_SEASON_NUMBER = "season_number";
field public static final java.lang.String COLUMN_SEASON_TITLE = "season_title";
field public static final java.lang.String COLUMN_SHORT_DESCRIPTION = "short_description";
+ field public static final java.lang.String COLUMN_STARTING_PRICE = "starting_price";
field public static final java.lang.String COLUMN_START_TIME_UTC_MILLIS = "start_time_utc_millis";
+ field public static final java.lang.String COLUMN_THUMBNAIL_ASPECT_RATIO = "poster_thumbnail_aspect_ratio";
field public static final java.lang.String COLUMN_THUMBNAIL_URI = "thumbnail_uri";
field public static final java.lang.String COLUMN_TITLE = "title";
+ field public static final java.lang.String COLUMN_TYPE = "type";
field public static final java.lang.String COLUMN_VERSION_NUMBER = "version_number";
field public static final java.lang.String COLUMN_VIDEO_HEIGHT = "video_height";
field public static final java.lang.String COLUMN_VIDEO_WIDTH = "video_width";
+ field public static final java.lang.String COLUMN_WATCH_NEXT_TYPE = "watch_next_type";
field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/program";
field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/program";
field public static final android.net.Uri CONTENT_URI;
@@ -23993,7 +24011,22 @@
field public static final java.lang.String INTERACTION_TYPE_VIEWS = "INTERACTION_TYPE_VIEWS";
field public static final java.lang.String REVIEW_RATING_STYLE_PERCENTAGE = "REVIEW_RATING_STYLE_PERCENTAGE";
field public static final java.lang.String REVIEW_RATING_STYLE_STARS = "REVIEW_RATING_STYLE_STARS";
- field public static final java.lang.String REVIEW_RATING_STYLE_THUMPS_UP_DOWN = "REVIEW_RATING_STYLE_THUMPS_UP_DOWN";
+ field public static final java.lang.String REVIEW_RATING_STYLE_THUMBS_UP_DOWN = "REVIEW_RATING_STYLE_THUMBS_UP_DOWN";
+ field public static final java.lang.String TYPE_ALBUM = "TYPE_ALBUM";
+ field public static final java.lang.String TYPE_ARTIST = "TYPE_ARTIST";
+ field public static final java.lang.String TYPE_CHANNEL = "TYPE_CHANNEL";
+ field public static final java.lang.String TYPE_CLIP = "TYPE_CLIP";
+ field public static final java.lang.String TYPE_EVENT = "TYPE_EVENT";
+ field public static final java.lang.String TYPE_MOVIE = "TYPE_MOVIE";
+ field public static final java.lang.String TYPE_PLAYLIST = "TYPE_PLAYLIST";
+ field public static final java.lang.String TYPE_STATION = "TYPE_STATION";
+ field public static final java.lang.String TYPE_TRACK = "TYPE_TRACK";
+ field public static final java.lang.String TYPE_TV_EPISODE = "TYPE_TV_EPISODE";
+ field public static final java.lang.String TYPE_TV_SEASON = "TYPE_TV_SEASON";
+ field public static final java.lang.String TYPE_TV_SERIES = "TYPE_TV_SERIES";
+ field public static final java.lang.String WATCH_NEXT_TYPE_CONTINUE = "WATCH_NEXT_TYPE_CONTINUE";
+ field public static final java.lang.String WATCH_NEXT_TYPE_NEW = "WATCH_NEXT_TYPE_NEW";
+ field public static final java.lang.String WATCH_NEXT_TYPE_NEXT = "WATCH_NEXT_TYPE_NEXT";
}
public static final class TvContract.Programs.Genres {
diff --git a/core/java/android/animation/AnimatorSet.java b/core/java/android/animation/AnimatorSet.java
index bca736a25..d508544 100644
--- a/core/java/android/animation/AnimatorSet.java
+++ b/core/java/android/animation/AnimatorSet.java
@@ -174,6 +174,10 @@
*/
private long mPauseTime = -1;
+ // This is to work around a bug in b/34736819. This needs to be removed once play team
+ // fixes their side.
+ private AnimatorListenerAdapter mDummyListener = new AnimatorListenerAdapter() {};
+
public AnimatorSet() {
super();
mNodeMap.put(mDelayAnim, mRootNode);
@@ -1018,6 +1022,8 @@
}
private void startAnimation() {
+ addDummyListener();
+
// Register animation callback
addAnimationCallback(mStartDelay);
@@ -1062,6 +1068,20 @@
}
}
+ // This is to work around the issue in b/34736819, as the old behavior in AnimatorSet had
+ // masked a real bug in play movies. TODO: remove this and below once the root cause is fixed.
+ private void addDummyListener() {
+ for (int i = 1; i < mNodes.size(); i++) {
+ mNodes.get(i).mAnimation.addListener(mDummyListener);
+ }
+ }
+
+ private void removeDummyListener() {
+ for (int i = 1; i < mNodes.size(); i++) {
+ mNodes.get(i).mAnimation.removeListener(mDummyListener);
+ }
+ }
+
private int findLatestEventIdForTime(long currentPlayTime) {
int size = mEvents.size();
int latestId = mLastEventId;
@@ -1107,6 +1127,7 @@
tmpListeners.get(i).onAnimationEnd(this, mReversing);
}
}
+ removeDummyListener();
mSelfPulse = true;
mReversing = false;
}
diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java
index 8d9ceb6..7cdb3ce 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -272,6 +272,11 @@
}
/** {@hide} */
+ public static File getDataMiscCeDirectory() {
+ return buildPath(getDataDirectory(), "misc_ce");
+ }
+
+ /** {@hide} */
public static File getDataMiscCeDirectory(int userId) {
return buildPath(getDataDirectory(), "misc_ce", String.valueOf(userId));
}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 48f73df..834dc57 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1274,10 +1274,14 @@
/**
* Activity Action: Show notification settings for a single app.
- *
- * Input: Optionally, {@link #EXTRA_CHANNEL_ID}, to highlight that channel.
+ * <p>
+ * Input: {@link #EXTRA_APP_PACKAGE}, the package containing the channel to display.
+ * Input: Optionally, {@link #EXTRA_CHANNEL_ID}, to highlight that channel.
+ * <p>
+ * Output: Nothing.
* @hide
*/
+ @SystemApi
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
public static final String ACTION_APP_NOTIFICATION_SETTINGS
= "android.settings.APP_NOTIFICATION_SETTINGS";
diff --git a/media/java/android/media/tv/TvContract.java b/media/java/android/media/tv/TvContract.java
index 44f31526..9a08fbe 100644
--- a/media/java/android/media/tv/TvContract.java
+++ b/media/java/android/media/tv/TvContract.java
@@ -1088,6 +1088,166 @@
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/program";
/**
+ * The program type for movie.
+ *
+ * @see #COLUMN_TYPE
+ */
+ public static final String TYPE_MOVIE = "TYPE_MOVIE";
+
+ /**
+ * The program type for TV series.
+ *
+ * @see #COLUMN_TYPE
+ */
+ public static final String TYPE_TV_SERIES = "TYPE_TV_SERIES";
+
+ /**
+ * The program type for TV season.
+ *
+ * @see #COLUMN_TYPE
+ */
+ public static final String TYPE_TV_SEASON = "TYPE_TV_SEASON";
+
+ /**
+ * The program type for TV episode.
+ *
+ * @see #COLUMN_TYPE
+ */
+ public static final String TYPE_TV_EPISODE = "TYPE_TV_EPISODE";
+
+ /**
+ * The program type for clip.
+ *
+ * @see #COLUMN_TYPE
+ */
+ public static final String TYPE_CLIP = "TYPE_CLIP";
+
+ /**
+ * The program type for event.
+ *
+ * @see #COLUMN_TYPE
+ */
+ public static final String TYPE_EVENT = "TYPE_EVENT";
+
+ /**
+ * The program type for channel.
+ *
+ * @see #COLUMN_TYPE
+ */
+ public static final String TYPE_CHANNEL = "TYPE_CHANNEL";
+
+ /**
+ * The program type for track.
+ *
+ * @see #COLUMN_TYPE
+ */
+ public static final String TYPE_TRACK = "TYPE_TRACK";
+
+ /**
+ * The program type for album.
+ *
+ * @see #COLUMN_TYPE
+ */
+ public static final String TYPE_ALBUM = "TYPE_ALBUM";
+
+ /**
+ * The program type for artist.
+ *
+ * @see #COLUMN_TYPE
+ */
+ public static final String TYPE_ARTIST = "TYPE_ARTIST";
+
+ /**
+ * The program type for playlist.
+ *
+ * @see #COLUMN_TYPE
+ */
+ public static final String TYPE_PLAYLIST = "TYPE_PLAYLIST";
+
+ /**
+ * The program type for station.
+ *
+ * @see #COLUMN_TYPE
+ */
+ public static final String TYPE_STATION = "TYPE_STATION";
+
+ /**
+ * The watch next type for CONTINUE.
+ *
+ * @see #COLUMN_WATCH_NEXT_TYPE
+ */
+ public static final String WATCH_NEXT_TYPE_CONTINUE = "WATCH_NEXT_TYPE_CONTINUE";
+
+ /**
+ * The watch next type for NEXT.
+ *
+ * @see #COLUMN_WATCH_NEXT_TYPE
+ */
+ public static final String WATCH_NEXT_TYPE_NEXT = "WATCH_NEXT_TYPE_NEXT";
+
+ /**
+ * The watch next type for NEW.
+ *
+ * @see #COLUMN_WATCH_NEXT_TYPE
+ */
+ public static final String WATCH_NEXT_TYPE_NEW = "WATCH_NEXT_TYPE_NEW";
+
+ /**
+ * The aspect ratio for 16:9.
+ *
+ * @see #COLUMN_POSTER_ART_ASPECT_RATIO
+ * @see #COLUMN_THUMBNAIL_ASPECT_RATIO
+ */
+ public static final String ASPECT_RATIO_16_9 = "ASPECT_RATIO_16_9";
+
+ /**
+ * The aspect ratio for 3:2.
+ *
+ * @see #COLUMN_POSTER_ART_ASPECT_RATIO
+ * @see #COLUMN_THUMBNAIL_ASPECT_RATIO
+ */
+ public static final String ASPECT_RATIO_3_2 = "ASPECT_RATIO_3_2";
+
+ /**
+ * The aspect ratio for 1:1.
+ *
+ * @see #COLUMN_POSTER_ART_ASPECT_RATIO
+ * @see #COLUMN_THUMBNAIL_ASPECT_RATIO
+ */
+ public static final String ASPECT_RATIO_1_1 = "ASPECT_RATIO_1_1";
+
+ /**
+ * The aspect ratio for 2:3.
+ *
+ * @see #COLUMN_POSTER_ART_ASPECT_RATIO
+ * @see #COLUMN_THUMBNAIL_ASPECT_RATIO
+ */
+ public static final String ASPECT_RATIO_2_3 = "ASPECT_RATIO_2_3";
+
+ /**
+ * The availability for "available to this user".
+ *
+ * @see #COLUMN_AVAILABILITY
+ */
+ public static final String AVAILABILITY_AVAILABLE = "AVAILABILITY_AVAILABLE";
+
+ /**
+ * The availability for "free with subscription".
+ *
+ * @see #COLUMN_AVAILABILITY
+ */
+ public static final String AVAILABILITY_FREE_WITH_SUBSCRIPTION =
+ "AVAILABILITY_FREE_WITH_SUBSCRIPTION";
+
+ /**
+ * The availability for "paid content, either to-own or rental
+ * (user has not purchased/rented).
+ *
+ * @see #COLUMN_AVAILABILITY
+ */
+ public static final String AVAILABILITY_PAID_CONTENT = "AVAILABILITY_PAID_CONTENT";
+
+ /**
* The interaction type for "listens".
*
* @see #COLUMN_INTERACTION_TYPE
@@ -1148,8 +1308,8 @@
*
* @see #COLUMN_REVIEW_RATING_STYLE
*/
- public static final String REVIEW_RATING_STYLE_THUMPS_UP_DOWN =
- "REVIEW_RATING_STYLE_THUMPS_UP_DOWN";
+ public static final String REVIEW_RATING_STYLE_THUMBS_UP_DOWN =
+ "REVIEW_RATING_STYLE_THUMBS_UP_DOWN";
/**
* The review rating style for 0 to 100 point system.
@@ -1171,6 +1331,44 @@
public static final String COLUMN_CHANNEL_ID = "channel_id";
/**
+ * The type of this program content.
+ *
+ * <p>The value should match one of the followings:
+ * {@link #TYPE_MOVIE},
+ * {@link #TYPE_TV_SERIES},
+ * {@link #TYPE_TV_SEASON},
+ * {@link #TYPE_TV_EPISODE},
+ * {@link #TYPE_CLIP},
+ * {@link #TYPE_EVENT},
+ * {@link #TYPE_CHANNEL},
+ * {@link #TYPE_TRACK},
+ * {@link #TYPE_ALBUM},
+ * {@link #TYPE_ARTIST},
+ * {@link #TYPE_PLAYLIST}, and
+ * {@link #TYPE_STATION}.
+ *
+ * <p>This is a required field if the program is from a {@link Channels#TYPE_PREVIEW}
+ * channel.
+ *
+ * <p>Type: TEXT
+ */
+ public static final String COLUMN_TYPE = "type";
+
+ /**
+ * The "watch next" type of this program content.
+ *
+ * <p>The value should match one of the followings:
+ * {@link #WATCH_NEXT_TYPE_CONTINUE},
+ * {@link #WATCH_NEXT_TYPE_NEXT}, and
+ * {@link #WATCH_NEXT_TYPE_NEW}.
+ *
+ * <p>Can be empty.
+ *
+ * <p>Type: TEXT
+ */
+ public static final String COLUMN_WATCH_NEXT_TYPE = "watch_next_type";
+
+ /**
* The title of this TV program.
*
* <p>If this program is an episodic TV show, it is recommended that the title is the series
@@ -1401,6 +1599,19 @@
public static final String COLUMN_POSTER_ART_URI = "poster_art_uri";
/**
+ * The aspect ratio of the poster art for this TV program.
+ *
+ * <p>The value should match one of the followings:
+ * {@link #ASPECT_RATIO_16_9},
+ * {@link #ASPECT_RATIO_3_2},
+ * {@link #ASPECT_RATIO_1_1}, and
+ * {@link #ASPECT_RATIO_2_3}.
+ *
+ * <p>Type: TEXT
+ */
+ public static final String COLUMN_POSTER_ART_ASPECT_RATIO = "poster_art_aspect_ratio";
+
+ /**
* The URI for the thumbnail of this TV program.
*
* <p>The system can generate a thumbnail from the poster art if this column is not
@@ -1423,6 +1634,104 @@
public static final String COLUMN_THUMBNAIL_URI = "thumbnail_uri";
/**
+ * The aspect ratio of the thumbnail for this TV program.
+ *
+ * <p>The value should match one of the followings:
+ * {@link #ASPECT_RATIO_16_9},
+ * {@link #ASPECT_RATIO_3_2},
+ * {@link #ASPECT_RATIO_1_1}, and
+ * {@link #ASPECT_RATIO_2_3}.
+ *
+ * <p>Type: TEXT
+ */
+ public static final String COLUMN_THUMBNAIL_ASPECT_RATIO = "poster_thumbnail_aspect_ratio";
+
+ /**
+ * The URI for the logo of this TV program.
+ *
+ * <p>This is a small badge shown on top of the poster art or thumbnail representing the
+ * source of the content.
+ *
+ * <p>The data in the column must be a URL, or a URI in one of the following formats:
+ *
+ * <ul>
+ * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li>
+ * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE})
+ * </li>
+ * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li>
+ * </ul>
+ *
+ * <p>Can be empty.
+ *
+ * <p>Type: TEXT
+ */
+ public static final String COLUMN_LOGO = "logo";
+
+ /**
+ * The availability of this TV program.
+ *
+ * <p>The value should match one of the followings:
+ * {@link #AVAILABILITY_AVAILABLE},
+ * {@link #AVAILABILITY_FREE_WITH_SUBSCRIPTION}, and
+ * {@link #AVAILABILITY_PAID_CONTENT}.
+ *
+ * <p>Type: TEXT
+ */
+ public static final String COLUMN_AVAILABILITY = "availability";
+
+ /**
+ * The starting price of this TV program.
+ *
+ * <p>This indicates the lowest regular acquisition cost of the content. It is only used
+ * if the availability of the program is {@link #AVAILABILITY_PAID_CONTENT}.
+ *
+ * <p>Type: TEXT
+ * @see #COLUMN_OFFER_PRICE
+ */
+ public static final String COLUMN_STARTING_PRICE = "starting_price";
+
+ /**
+ * The offer price of this TV program.
+ *
+ * <p>This is the promotional cost of the content. It is only used if the availability of
+ * the program is {@link #AVAILABILITY_PAID_CONTENT}.
+ *
+ * <p>Type: TEXT
+ * @see #COLUMN_STARTING_PRICE
+ */
+ public static final String COLUMN_OFFER_PRICE = "offer_price";
+
+ /**
+ * The release date of this TV program.
+ *
+ * <p>The value should be in the form of either "yyyy-MM-dd" or "yyyy".
+ *
+ * <p>Type: TEXT
+ */
+ public static final String COLUMN_RELEASE_DATE = "release_date";
+
+ /**
+ * The count of the items included in this TV program.
+ *
+ * <p>This is only relevant if the program represents a collection of items such as series,
+ * episodes, or music tracks.
+ *
+ * <p>Type: INTEGER
+ */
+ public static final String COLUMN_ITEM_COUNT = "item_count";
+
+ /**
+ * The flag indicating whether this TV program is live or not.
+ *
+ * <p>A value of 1 indicates that the content is airing and should be consumed now, a value
+ * of 0 indicates that the content is off the air and does not need to be consumed at the
+ * present time. If not specified, the value is set to 0 (not live) by default.
+ *
+ * <p>Type: INTEGER (boolean)
+ */
+ public static final String COLUMN_LIVE = "live";
+
+ /**
* The flag indicating whether this TV program is searchable or not.
*
* <p>The columns of searchable programs can be read by other applications that have proper
@@ -1645,7 +1954,7 @@
* The review rating score style used for {@link #COLUMN_REVIEW_RATING}.
*
* <p> The value should match one of the followings: {@link #REVIEW_RATING_STYLE_STARS},
- * {@link #REVIEW_RATING_STYLE_THUMPS_UP_DOWN}, and {@link #REVIEW_RATING_STYLE_PERCENTAGE}.
+ * {@link #REVIEW_RATING_STYLE_THUMBS_UP_DOWN}, and {@link #REVIEW_RATING_STYLE_PERCENTAGE}.
*
* <p>Type: TEXT
* @see #COLUMN_REVIEW_RATING
@@ -1657,7 +1966,7 @@
*
* <p>The format of the value is dependent on {@link #COLUMN_REVIEW_RATING_STYLE}. If the
* style is {@link #REVIEW_RATING_STYLE_STARS}, the value should be a real number between
- * 0.0 and 5.0. (e.g. "4.5") If the style is {@link #REVIEW_RATING_STYLE_THUMPS_UP_DOWN},
+ * 0.0 and 5.0. (e.g. "4.5") If the style is {@link #REVIEW_RATING_STYLE_THUMBS_UP_DOWN},
* the value should be two integers, one for thumbs-up count and the other for thumbs-down
* count, with a comma between them. (e.g. "200,40") If the style is
* {@link #REVIEW_RATING_STYLE_PERCENTAGE}, the value shoule be a real number between 0 and
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/Plugin.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/Plugin.java
index b31b199..e75ecb7 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/Plugin.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/Plugin.java
@@ -64,7 +64,7 @@
* new PluginListener<OverlayPlugin>() {
* @Override
* public void onPluginConnected(OverlayPlugin plugin) {
- * PhoneStatusBar phoneStatusBar = getComponent(PhoneStatusBar.class);
+ * StatusBar phoneStatusBar = getComponent(StatusBar.class);
* if (phoneStatusBar != null) {
* plugin.setup(phoneStatusBar.getStatusBarWindow(),
* phoneStatusBar.getNavigationBarView());
diff --git a/packages/SystemUI/proguard.flags b/packages/SystemUI/proguard.flags
index 364885a..6d76798 100644
--- a/packages/SystemUI/proguard.flags
+++ b/packages/SystemUI/proguard.flags
@@ -11,7 +11,7 @@
}
-keep class com.android.systemui.statusbar.car.CarStatusBar
--keep class com.android.systemui.statusbar.phone.PhoneStatusBar
+-keep class com.android.systemui.statusbar.phone.StatusBar
-keep class com.android.systemui.statusbar.tv.TvStatusBar
-keep class com.android.systemui.car.CarSystemUIFactory
-keep class com.android.systemui.SystemUIFactory
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index b7647cf..80f3a0a 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -43,7 +43,7 @@
<!-- Component to be used as the status bar service. Must implement the IStatusBar
interface. This name is in the ComponentName flattened format (package/class) -->
- <string name="config_statusBarComponent" translatable="false">com.android.systemui.statusbar.phone.PhoneStatusBar</string>
+ <string name="config_statusBarComponent" translatable="false">com.android.systemui.statusbar.phone.StatusBar</string>
<!-- Whether or not we show the number in the bar. -->
<bool name="config_statusBarShowNumber">false</bool>
diff --git a/packages/SystemUI/src/com/android/systemui/ActivityStarterDelegate.java b/packages/SystemUI/src/com/android/systemui/ActivityStarterDelegate.java
index 4ae81a7..14c67fe 100644
--- a/packages/SystemUI/src/com/android/systemui/ActivityStarterDelegate.java
+++ b/packages/SystemUI/src/com/android/systemui/ActivityStarterDelegate.java
@@ -19,7 +19,7 @@
/**
* Single common instance of ActivityStarter that can be gotten and referenced from anywhere, but
- * delegates to an actual implementation such as PhoneStatusBar, assuming it exists.
+ * delegates to an actual implementation such as StatusBar, assuming it exists.
*/
public class ActivityStarterDelegate implements ActivityStarter {
diff --git a/packages/SystemUI/src/com/android/systemui/LatencyTester.java b/packages/SystemUI/src/com/android/systemui/LatencyTester.java
index c14b17f..1d55ee5 100644
--- a/packages/SystemUI/src/com/android/systemui/LatencyTester.java
+++ b/packages/SystemUI/src/com/android/systemui/LatencyTester.java
@@ -27,7 +27,7 @@
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.LatencyTracker;
import com.android.systemui.statusbar.phone.FingerprintUnlockController;
-import com.android.systemui.statusbar.phone.PhoneStatusBar;
+import com.android.systemui.statusbar.phone.StatusBar;
/**
* Class that only runs on debuggable builds that listens to broadcasts that simulate actions in the
@@ -72,7 +72,7 @@
}
private void fakeWakeAndUnlock() {
- FingerprintUnlockController fingerprintUnlockController = getComponent(PhoneStatusBar.class)
+ FingerprintUnlockController fingerprintUnlockController = getComponent(StatusBar.class)
.getFingerprintUnlockController();
fingerprintUnlockController.onFingerprintAcquired();
fingerprintUnlockController.onFingerprintAuthenticated(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SystemBars.java b/packages/SystemUI/src/com/android/systemui/SystemBars.java
similarity index 80%
rename from packages/SystemUI/src/com/android/systemui/statusbar/SystemBars.java
rename to packages/SystemUI/src/com/android/systemui/SystemBars.java
index 275fd70..6623cabe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SystemBars.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemBars.java
@@ -1,20 +1,18 @@
/*
- * Copyright (C) 2013 The Android Open Source Project
+ * Copyright (C) 2017 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
+ * 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.
+ * 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;
+package com.android.systemui;
import android.content.res.Configuration;
import android.provider.Settings;
@@ -36,7 +34,7 @@
private static final int WAIT_FOR_BARS_TO_DIE = 500;
// in-process fallback implementation, per the product config
- private BaseStatusBar mStatusBar;
+ private SystemUI mStatusBar;
@Override
public void start() {
@@ -71,7 +69,7 @@
throw andLog("Error loading status bar component: " + clsName, t);
}
try {
- mStatusBar = (BaseStatusBar) cls.newInstance();
+ mStatusBar = (SystemUI) cls.newInstance();
} catch (Throwable t) {
throw andLog("Error creating status bar component: " + clsName, t);
}
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
index afe88c1..9515585 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
@@ -42,8 +42,7 @@
import com.android.systemui.shortcut.ShortcutKeyDispatcher;
import com.android.systemui.stackdivider.Divider;
import com.android.systemui.statusbar.CommandQueue;
-import com.android.systemui.statusbar.SystemBars;
-import com.android.systemui.statusbar.phone.PhoneStatusBar;
+import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.tuner.TunerService;
import com.android.systemui.usb.StorageNotification;
import com.android.systemui.util.NotificationChannels;
@@ -210,10 +209,10 @@
new PluginListener<OverlayPlugin>() {
@Override
public void onPluginConnected(OverlayPlugin plugin, Context pluginContext) {
- PhoneStatusBar phoneStatusBar = getComponent(PhoneStatusBar.class);
- if (phoneStatusBar != null) {
- plugin.setup(phoneStatusBar.getStatusBarWindow(),
- phoneStatusBar.getNavigationBarView());
+ StatusBar statusBar = getComponent(StatusBar.class);
+ if (statusBar != null) {
+ plugin.setup(statusBar.getStatusBarWindow(),
+ statusBar.getNavigationBarView());
}
}
}, OverlayPlugin.VERSION, true /* Allow multiple plugins */);
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
index ec11812..1ff0701 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
@@ -26,10 +26,7 @@
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.ViewMediatorCallback;
import com.android.systemui.Dependency.DependencyProvider;
-import com.android.systemui.R;
-import com.android.systemui.assist.AssistManager;
import com.android.systemui.keyguard.DismissCallbackRegistry;
-import com.android.systemui.statusbar.BaseStatusBar;
import com.android.systemui.statusbar.KeyguardIndicationController;
import com.android.systemui.statusbar.ScrimView;
import com.android.systemui.statusbar.phone.KeyguardBouncer;
@@ -37,26 +34,11 @@
import com.android.systemui.statusbar.phone.LockIcon;
import com.android.systemui.statusbar.phone.LockscreenWallpaper;
import com.android.systemui.statusbar.phone.NotificationIconAreaController;
-import com.android.systemui.statusbar.phone.PhoneStatusBar;
+import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.QSTileHost;
import com.android.systemui.statusbar.phone.ScrimController;
import com.android.systemui.statusbar.phone.StatusBarIconController;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
-import com.android.systemui.statusbar.phone.StatusBarWindowManager;
-import com.android.systemui.statusbar.policy.BatteryController;
-import com.android.systemui.statusbar.policy.BluetoothController;
-import com.android.systemui.statusbar.policy.CastController;
-import com.android.systemui.statusbar.policy.FlashlightController;
-import com.android.systemui.statusbar.policy.HotspotController;
-import com.android.systemui.statusbar.policy.KeyguardMonitor;
-import com.android.systemui.statusbar.policy.LocationController;
-import com.android.systemui.statusbar.policy.NetworkController;
-import com.android.systemui.statusbar.policy.NextAlarmController;
-import com.android.systemui.statusbar.policy.RotationLockController;
-import com.android.systemui.statusbar.policy.SecurityController;
-import com.android.systemui.statusbar.policy.UserInfoController;
-import com.android.systemui.statusbar.policy.UserSwitcherController;
-import com.android.systemui.statusbar.policy.ZenModeController;
import com.android.systemui.volume.VolumeDialogController;
/**
@@ -113,8 +95,8 @@
}
public NotificationIconAreaController createNotificationIconAreaController(Context context,
- PhoneStatusBar phoneStatusBar) {
- return new NotificationIconAreaController(context, phoneStatusBar);
+ StatusBar statusBar) {
+ return new NotificationIconAreaController(context, statusBar);
}
public KeyguardIndicationController createKeyguardIndicationController(Context context,
@@ -122,7 +104,7 @@
return new KeyguardIndicationController(context, indicationArea, lockIcon);
}
- public QSTileHost createQSTileHost(Context context, PhoneStatusBar statusBar,
+ public QSTileHost createQSTileHost(Context context, StatusBar statusBar,
StatusBarIconController iconController) {
return new QSTileHost(context, statusBar, iconController);
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index ce89aab..99c8c6b 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -80,7 +80,7 @@
import com.android.systemui.SystemUIFactory;
import com.android.systemui.classifier.FalsingManager;
import com.android.systemui.statusbar.phone.FingerprintUnlockController;
-import com.android.systemui.statusbar.phone.PhoneStatusBar;
+import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.ScrimController;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import com.android.systemui.statusbar.phone.StatusBarWindowManager;
@@ -1955,11 +1955,11 @@
Trace.endSection();
}
- public StatusBarKeyguardViewManager registerStatusBar(PhoneStatusBar phoneStatusBar,
+ public StatusBarKeyguardViewManager registerStatusBar(StatusBar statusBar,
ViewGroup container, StatusBarWindowManager statusBarWindowManager,
ScrimController scrimController,
FingerprintUnlockController fingerprintUnlockController) {
- mStatusBarKeyguardViewManager.registerStatusBar(phoneStatusBar, container,
+ mStatusBarKeyguardViewManager.registerStatusBar(statusBar, container,
statusBarWindowManager, scrimController, fingerprintUnlockController,
mDismissCallbackRegistry);
return mStatusBarKeyguardViewManager;
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
index 94ea4dc..82ec69d 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
@@ -41,7 +41,7 @@
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.systemui.R;
import com.android.systemui.SystemUI;
-import com.android.systemui.statusbar.phone.PhoneStatusBar;
+import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.SystemUIDialog;
import com.android.systemui.util.NotificationChannels;
@@ -98,7 +98,7 @@
private SystemUIDialog mHighTempDialog;
public PowerNotificationWarnings(Context context, NotificationManager notificationManager,
- PhoneStatusBar phoneStatusBar) {
+ StatusBar statusBar) {
mContext = context;
mNoMan = notificationManager;
mPowerMan = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
index 1d4a5c7..3d36868 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
@@ -36,7 +36,7 @@
import android.util.Slog;
import com.android.systemui.R;
import com.android.systemui.SystemUI;
-import com.android.systemui.statusbar.phone.PhoneStatusBar;
+import com.android.systemui.statusbar.phone.StatusBar;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.Arrays;
@@ -72,7 +72,7 @@
mWarnings = new PowerNotificationWarnings(
mContext,
(NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE),
- getComponent(PhoneStatusBar.class));
+ getComponent(StatusBar.class));
ContentObserver obs = new ContentObserver(mHandler) {
@Override
@@ -250,8 +250,8 @@
}
private void updateTemperatureWarning() {
- PhoneStatusBar phoneStatusBar = getComponent(PhoneStatusBar.class);
- if (phoneStatusBar != null && phoneStatusBar.isDeviceInVrMode()) {
+ StatusBar statusBar = getComponent(StatusBar.class);
+ if (statusBar != null && statusBar.isDeviceInVrMode()) {
// ensure the warning isn't showing, since VR shows its own warning
mWarnings.dismissTemperatureWarning();
} else {
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 7e04b67..06f4d9d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java
@@ -19,7 +19,6 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.graphics.drawable.Drawable;
import android.service.quicksettings.Tile;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
@@ -42,8 +41,6 @@
import com.android.systemui.R;
import com.android.systemui.plugins.qs.QS.DetailAdapter;
import com.android.systemui.qs.QSTile;
-import com.android.systemui.statusbar.phone.PhoneStatusBar;
-import com.android.systemui.qs.external.TileColorPicker;
import com.android.systemui.statusbar.policy.BatteryController;
import java.text.NumberFormat;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index 06fadd1..a6fe0ea 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -88,7 +88,7 @@
import com.android.systemui.recents.model.TaskStack;
import com.android.systemui.recents.views.RecentsView;
import com.android.systemui.recents.views.SystemBarScrimViews;
-import com.android.systemui.statusbar.BaseStatusBar;
+import com.android.systemui.statusbar.phone.StatusBar;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -283,7 +283,7 @@
dismissEvent.addPostAnimationCallback(new LaunchHomeRunnable(mHomeIntent,
overrideAnimation));
Recents.getSystemServices().sendCloseSystemWindows(
- BaseStatusBar.SYSTEM_DIALOG_REASON_HOME_KEY);
+ StatusBar.SYSTEM_DIALOG_REASON_HOME_KEY);
EventBus.getDefault().send(dismissEvent);
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
index cf6357b..9a8b267 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
@@ -18,7 +18,6 @@
import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
-import static android.app.ActivityManager.StackId.RECENTS_STACK_ID;
import static android.app.ActivityManager.StackId.isHomeOrRecentsStack;
import static android.view.View.MeasureSpec;
@@ -77,9 +76,8 @@
import com.android.systemui.recents.views.TaskViewHeader;
import com.android.systemui.recents.views.TaskViewTransform;
import com.android.systemui.stackdivider.DividerView;
-import com.android.systemui.statusbar.BaseStatusBar;
import com.android.systemui.statusbar.phone.NavigationBarGestureHelper;
-import com.android.systemui.statusbar.phone.PhoneStatusBar;
+import com.android.systemui.statusbar.phone.StatusBar;
import java.util.ArrayList;
@@ -229,7 +227,7 @@
*/
public void onStartScreenPinning(Context context, int taskId) {
SystemUIApplication app = (SystemUIApplication) context;
- PhoneStatusBar statusBar = app.getComponent(PhoneStatusBar.class);
+ StatusBar statusBar = app.getComponent(StatusBar.class);
if (statusBar != null) {
statusBar.showScreenPinningRequest(taskId, false);
}
@@ -351,7 +349,7 @@
growTarget);
// Only close the other system windows if we are actually showing recents
- ssp.sendCloseSystemWindows(BaseStatusBar.SYSTEM_DIALOG_REASON_RECENT_APPS);
+ ssp.sendCloseSystemWindows(StatusBar.SYSTEM_DIALOG_REASON_RECENT_APPS);
mLastToggleTime = SystemClock.elapsedRealtime();
}
} catch (ActivityNotFoundException e) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java
index a2a8199..a691a424 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java
@@ -30,6 +30,8 @@
import android.widget.FrameLayout.LayoutParams;
import com.android.systemui.R;
+import com.android.systemui.pip.tv.PipManager;
+import com.android.systemui.pip.tv.PipRecentsOverlayManager;
import com.android.systemui.recents.Recents;
import com.android.systemui.recents.RecentsActivityLaunchState;
import com.android.systemui.recents.RecentsConfiguration;
@@ -57,9 +59,7 @@
import com.android.systemui.recents.tv.views.TaskCardView;
import com.android.systemui.recents.tv.views.TaskStackHorizontalGridView;
import com.android.systemui.recents.tv.views.TaskStackHorizontalViewAdapter;
-import com.android.systemui.statusbar.BaseStatusBar;
-import com.android.systemui.pip.tv.PipManager;
-import com.android.systemui.pip.tv.PipRecentsOverlayManager;
+import com.android.systemui.statusbar.phone.StatusBar;
import java.util.ArrayList;
import java.util.Collections;
@@ -258,7 +258,7 @@
@Override
public void run() {
Recents.getSystemServices().sendCloseSystemWindows(
- BaseStatusBar.SYSTEM_DIALOG_REASON_HOME_KEY);
+ StatusBar.SYSTEM_DIALOG_REASON_HOME_KEY);
}
};
DismissRecentsToHomeAnimationStarted dismissEvent =
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
index 2bd651b..6a66fca7 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
@@ -51,7 +51,7 @@
import com.android.systemui.recents.misc.SystemServicesProxy;
import com.android.systemui.recents.model.Task;
import com.android.systemui.recents.model.TaskStack;
-import com.android.systemui.statusbar.BaseStatusBar;
+import com.android.systemui.statusbar.phone.StatusBar;
import java.util.ArrayList;
import java.util.Collections;
@@ -170,7 +170,7 @@
}
}
Recents.getSystemServices().sendCloseSystemWindows(
- BaseStatusBar.SYSTEM_DIALOG_REASON_HOME_KEY);
+ StatusBar.SYSTEM_DIALOG_REASON_HOME_KEY);
}
public IRemoteCallback wrapStartedListener(final OnAnimationStartedListener listener) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
deleted file mode 100644
index 20f455a..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ /dev/null
@@ -1,2598 +0,0 @@
-/*
- * Copyright (C) 2010 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.app.ActivityManager;
-import android.app.ActivityManager.StackId;
-import android.app.ActivityOptions;
-import android.app.INotificationManager;
-import android.app.KeyguardManager;
-import android.app.Notification;
-import android.app.NotificationChannel;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.app.RemoteInput;
-import android.app.TaskStackBuilder;
-import android.app.admin.DevicePolicyManager;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.IntentSender;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.UserInfo;
-import android.content.res.Configuration;
-import android.database.ContentObserver;
-import android.graphics.PointF;
-import android.graphics.Rect;
-import android.os.AsyncTask;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.PowerManager;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.SystemClock;
-import android.os.SystemProperties;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.provider.Settings;
-import android.service.dreams.DreamService;
-import android.service.dreams.IDreamManager;
-import android.service.notification.NotificationListenerService;
-import android.service.notification.NotificationListenerService.RankingMap;
-import android.service.notification.StatusBarNotification;
-import android.service.vr.IVrManager;
-import android.service.vr.IVrStateCallbacks;
-import android.text.TextUtils;
-import android.util.ArraySet;
-import android.util.Log;
-import android.util.Slog;
-import android.util.SparseArray;
-import android.util.SparseBooleanArray;
-import android.view.Display;
-import android.view.IWindowManager;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewAnimationUtils;
-import android.view.ViewGroup;
-import android.view.ViewParent;
-import android.view.WindowManager;
-import android.view.WindowManagerGlobal;
-import android.view.accessibility.AccessibilityManager;
-import android.widget.RemoteViews;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
-import com.android.internal.statusbar.IStatusBarService;
-import com.android.internal.statusbar.StatusBarIcon;
-import com.android.internal.widget.LockPatternUtils;
-import com.android.keyguard.KeyguardHostView.OnDismissAction;
-import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.systemui.DejankUtils;
-import com.android.systemui.Dependency;
-import com.android.systemui.Interpolators;
-import com.android.systemui.R;
-import com.android.systemui.RecentsComponent;
-import com.android.systemui.SwipeHelper;
-import com.android.systemui.SystemUI;
-import com.android.systemui.assist.AssistManager;
-import com.android.systemui.plugins.statusbar.NotificationMenuRowProvider;
-import com.android.systemui.plugins.statusbar.NotificationMenuRowProvider.MenuItem;
-import com.android.systemui.plugins.statusbar.NotificationMenuRowProvider.SnoozeGutsContent;
-import com.android.systemui.plugins.statusbar.NotificationMenuRowProvider.SnoozeListener;
-import com.android.systemui.plugins.statusbar.NotificationMenuRowProvider.SnoozeOption;
-import com.android.systemui.recents.Recents;
-import com.android.systemui.statusbar.NotificationData.Entry;
-import com.android.systemui.statusbar.notification.VisualStabilityManager;
-import com.android.systemui.statusbar.phone.NotificationGroupManager;
-import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
-import com.android.systemui.statusbar.policy.DeviceProvisionedController;
-import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
-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.StackStateAnimator;
-import com.android.systemui.util.NotificationChannels;
-
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Collections;
-import java.util.GregorianCalendar;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Locale;
-import java.util.Set;
-import java.util.Stack;
-
-public abstract class BaseStatusBar extends SystemUI implements
- CommandQueue.Callbacks, ActivatableNotificationView.OnActivatedListener,
- ExpandableNotificationRow.ExpansionLogger, NotificationData.Environment,
- ExpandableNotificationRow.OnExpandClickListener {
- public static final String TAG = "StatusBar";
- public static final boolean DEBUG = false;
- public static final boolean MULTIUSER_DEBUG = false;
-
- public static final boolean ENABLE_REMOTE_INPUT =
- SystemProperties.getBoolean("debug.enable_remote_input", true);
- public static final boolean ENABLE_CHILD_NOTIFICATIONS
- = SystemProperties.getBoolean("debug.child_notifs", true);
- public static final boolean FORCE_REMOTE_INPUT_HISTORY =
- SystemProperties.getBoolean("debug.force_remoteinput_history", false);
- private static boolean ENABLE_LOCK_SCREEN_ALLOW_REMOTE_INPUT = false;
-
- protected static final int MSG_SHOW_RECENT_APPS = 1019;
- protected static final int MSG_HIDE_RECENT_APPS = 1020;
- protected static final int MSG_TOGGLE_RECENTS_APPS = 1021;
- protected static final int MSG_PRELOAD_RECENT_APPS = 1022;
- protected static final int MSG_CANCEL_PRELOAD_RECENT_APPS = 1023;
- protected static final int MSG_SHOW_NEXT_AFFILIATED_TASK = 1024;
- protected static final int MSG_SHOW_PREV_AFFILIATED_TASK = 1025;
- protected static final int MSG_TOGGLE_KEYBOARD_SHORTCUTS_MENU = 1026;
- protected static final int MSG_DISMISS_KEYBOARD_SHORTCUTS_MENU = 1027;
-
- protected static final boolean ENABLE_HEADS_UP = true;
- protected static final String SETTING_HEADS_UP_TICKER = "ticker_gets_heads_up";
-
- private static final String PERMISSION_SELF = "com.android.systemui.permission.SELF";
-
- // Should match the values in PhoneWindowManager
- public static final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";
- public static final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey";
-
- private static final String BANNER_ACTION_CANCEL =
- "com.android.systemui.statusbar.banner_action_cancel";
- private static final String BANNER_ACTION_SETUP =
- "com.android.systemui.statusbar.banner_action_setup";
- private static final String NOTIFICATION_UNLOCKED_BY_WORK_CHALLENGE_ACTION
- = "com.android.systemui.statusbar.work_challenge_unlocked_notification_action";
-
- protected CommandQueue mCommandQueue;
- protected IStatusBarService mBarService;
- protected H mHandler = createHandler();
-
- // all notifications
- protected NotificationData mNotificationData;
- protected NotificationStackScrollLayout mStackScroller;
-
- protected NotificationGroupManager mGroupManager = new NotificationGroupManager();
-
- protected RemoteInputController mRemoteInputController;
-
- // for heads up notifications
- protected HeadsUpManager mHeadsUpManager;
-
- // handling reordering
- protected VisualStabilityManager mVisualStabilityManager = new VisualStabilityManager();
-
- protected int mCurrentUserId = 0;
- final protected SparseArray<UserInfo> mCurrentProfiles = new SparseArray<UserInfo>();
-
- protected int mLayoutDirection = -1; // invalid
- protected AccessibilityManager mAccessibilityManager;
-
- protected boolean mDeviceInteractive;
-
- protected boolean mVisible;
- protected ArraySet<Entry> mHeadsUpEntriesToRemoveOnSwitch = new ArraySet<>();
- protected ArraySet<Entry> mRemoteInputEntriesToRemoveOnCollapse = new ArraySet<>();
-
- /**
- * Notifications with keys in this set are not actually around anymore. We kept them around
- * when they were canceled in response to a remote input interaction. This allows us to show
- * what you replied and allows you to continue typing into it.
- */
- protected ArraySet<String> mKeysKeptForRemoteInput = new ArraySet<>();
-
- // mScreenOnFromKeyguard && mVisible.
- private boolean mVisibleToUser;
-
- private Locale mLocale;
- private float mFontScale;
-
- protected boolean mUseHeadsUp = false;
- protected boolean mHeadsUpTicker = false;
- protected boolean mDisableNotificationAlerts = false;
-
- protected DevicePolicyManager mDevicePolicyManager;
- protected IDreamManager mDreamManager;
- protected PowerManager mPowerManager;
- protected StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
-
- // public mode, private notifications, etc
- private final SparseBooleanArray mLockscreenPublicMode = new SparseBooleanArray();
- private final SparseBooleanArray mUsersAllowingPrivateNotifications = new SparseBooleanArray();
- private final SparseBooleanArray mUsersAllowingNotifications = new SparseBooleanArray();
-
- private UserManager mUserManager;
- private int mDensity;
-
- protected KeyguardManager mKeyguardManager;
- private LockPatternUtils mLockPatternUtils;
- private DeviceProvisionedController mDeviceProvisionedController;
-
- // UI-specific methods
-
- /**
- * Create all windows necessary for the status bar (including navigation, overlay panels, etc)
- * and add them to the window manager.
- */
- protected abstract void createAndAddWindows();
-
- protected WindowManager mWindowManager;
- protected IWindowManager mWindowManagerService;
-
- protected Display mDisplay;
-
- protected RecentsComponent mRecents;
-
- protected int mZenMode;
-
- // which notification is currently being longpress-examined by the user
- private NotificationGuts mNotificationGutsExposed;
- private MenuItem mGutsMenuItem;
-
- private KeyboardShortcuts mKeyboardShortcuts;
-
- /**
- * The {@link StatusBarState} of the status bar.
- */
- protected int mState;
- protected boolean mBouncerShowing;
- protected boolean mShowLockscreenNotifications;
- protected boolean mAllowLockscreenRemoteInput;
-
- protected NotificationShelf mNotificationShelf;
- protected DismissView mDismissView;
- protected EmptyShadeView mEmptyShadeView;
-
- private NotificationClicker mNotificationClicker = new NotificationClicker();
-
- protected AssistManager mAssistManager;
-
- protected boolean mVrMode;
-
- private Set<String> mNonBlockablePkgs;
-
- @Override // NotificationData.Environment
- public boolean isDeviceProvisioned() {
- return mDeviceProvisionedController.isDeviceProvisioned();
- }
-
- private final IVrStateCallbacks mVrStateCallbacks = new IVrStateCallbacks.Stub() {
- @Override
- public void onVrStateChanged(boolean enabled) {
- mVrMode = enabled;
- }
- };
-
- public boolean isDeviceInVrMode() {
- return mVrMode;
- }
-
- private final DeviceProvisionedListener mDeviceProvisionedListener =
- new DeviceProvisionedListener() {
- @Override
- public void onDeviceProvisionedChanged() {
- updateNotifications();
- }
- };
-
- protected final ContentObserver mSettingsObserver = new ContentObserver(mHandler) {
- @Override
- public void onChange(boolean selfChange) {
- final int mode = Settings.Global.getInt(mContext.getContentResolver(),
- Settings.Global.ZEN_MODE, Settings.Global.ZEN_MODE_OFF);
- setZenMode(mode);
-
- updateLockscreenNotificationSetting();
- }
- };
-
- private final ContentObserver mLockscreenSettingsObserver = new ContentObserver(mHandler) {
- @Override
- public void onChange(boolean selfChange) {
- // We don't know which user changed LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS or
- // LOCK_SCREEN_SHOW_NOTIFICATIONS, so we just dump our cache ...
- mUsersAllowingPrivateNotifications.clear();
- mUsersAllowingNotifications.clear();
- // ... and refresh all the notifications
- updateLockscreenNotificationSetting();
- updateNotifications();
- }
- };
-
- private RemoteViews.OnClickHandler mOnClickHandler = new RemoteViews.OnClickHandler() {
- private final int[] mTmpInt2 = new int[2];
-
- @Override
- public boolean onClickHandler(
- final View view, final PendingIntent pendingIntent, final Intent fillInIntent) {
- view.getLocationInWindow(mTmpInt2);
- wakeUpIfDozing(SystemClock.uptimeMillis(), new PointF(
- mTmpInt2[0] + view.getWidth() / 2, mTmpInt2[1] + view.getHeight() / 2));
-
-
- if (handleRemoteInput(view, pendingIntent, fillInIntent)) {
- return true;
- }
-
- if (DEBUG) {
- Log.v(TAG, "Notification click handler invoked for intent: " + pendingIntent);
- }
- logActionClick(view);
- // The intent we are sending is for the application, which
- // won't have permission to immediately start an activity after
- // the user switches to home. We know it is safe to do at this
- // point, so make sure new activity switches are now allowed.
- try {
- ActivityManager.getService().resumeAppSwitches();
- } catch (RemoteException e) {
- }
- final boolean isActivity = pendingIntent.isActivity();
- if (isActivity) {
- final boolean keyguardShowing = mStatusBarKeyguardViewManager.isShowing();
- final boolean afterKeyguardGone = PreviewInflater.wouldLaunchResolverActivity(
- mContext, pendingIntent.getIntent(), mCurrentUserId);
- dismissKeyguardThenExecute(new OnDismissAction() {
- @Override
- public boolean onDismiss() {
- try {
- ActivityManager.getService().resumeAppSwitches();
- } catch (RemoteException e) {
- }
-
- boolean handled = superOnClickHandler(view, pendingIntent, fillInIntent);
-
- // close the shade if it was open
- if (handled) {
- animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL,
- true /* force */);
- visibilityChanged(false);
- mAssistManager.hideAssist();
- }
-
- // Wait for activity start.
- return handled;
- }
- }, afterKeyguardGone);
- return true;
- } else {
- return superOnClickHandler(view, pendingIntent, fillInIntent);
- }
- }
-
- private void logActionClick(View view) {
- ViewParent parent = view.getParent();
- String key = getNotificationKeyForParent(parent);
- if (key == null) {
- Log.w(TAG, "Couldn't determine notification for click.");
- return;
- }
- int index = -1;
- // If this is a default template, determine the index of the button.
- if (view.getId() == com.android.internal.R.id.action0 &&
- parent != null && parent instanceof ViewGroup) {
- ViewGroup actionGroup = (ViewGroup) parent;
- index = actionGroup.indexOfChild(view);
- }
- try {
- mBarService.onNotificationActionClick(key, index);
- } catch (RemoteException e) {
- // Ignore
- }
- }
-
- private String getNotificationKeyForParent(ViewParent parent) {
- while (parent != null) {
- if (parent instanceof ExpandableNotificationRow) {
- return ((ExpandableNotificationRow) parent).getStatusBarNotification().getKey();
- }
- parent = parent.getParent();
- }
- return null;
- }
-
- private boolean superOnClickHandler(View view, PendingIntent pendingIntent,
- Intent fillInIntent) {
- return super.onClickHandler(view, pendingIntent, fillInIntent,
- StackId.FULLSCREEN_WORKSPACE_STACK_ID);
- }
-
- private boolean handleRemoteInput(View view, PendingIntent pendingIntent, Intent fillInIntent) {
- Object tag = view.getTag(com.android.internal.R.id.remote_input_tag);
- RemoteInput[] inputs = null;
- if (tag instanceof RemoteInput[]) {
- inputs = (RemoteInput[]) tag;
- }
-
- if (inputs == null) {
- return false;
- }
-
- RemoteInput input = null;
-
- for (RemoteInput i : inputs) {
- if (i.getAllowFreeFormInput()) {
- input = i;
- }
- }
-
- if (input == null) {
- return false;
- }
-
- ViewParent p = view.getParent();
- RemoteInputView riv = null;
- while (p != null) {
- if (p instanceof View) {
- View pv = (View) p;
- if (pv.isRootNamespace()) {
- riv = (RemoteInputView) pv.findViewWithTag(RemoteInputView.VIEW_TAG);
- break;
- }
- }
- p = p.getParent();
- }
- ExpandableNotificationRow row = null;
- while (p != null) {
- if (p instanceof ExpandableNotificationRow) {
- row = (ExpandableNotificationRow) p;
- break;
- }
- p = p.getParent();
- }
-
- if (riv == null || row == null) {
- return false;
- }
-
- row.setUserExpanded(true);
-
- if (!mAllowLockscreenRemoteInput) {
- final int userId = pendingIntent.getCreatorUserHandle().getIdentifier();
- if (isLockscreenPublicMode(userId)) {
- onLockedRemoteInput(row, view);
- return true;
- }
- if (mUserManager.getUserInfo(userId).isManagedProfile()
- && mKeyguardManager.isDeviceLocked(userId)) {
- onLockedWorkRemoteInput(userId, row, view);
- return true;
- }
- }
-
- int width = view.getWidth();
- if (view instanceof TextView) {
- // Center the reveal on the text which might be off-center from the TextView
- TextView tv = (TextView) view;
- if (tv.getLayout() != null) {
- int innerWidth = (int) tv.getLayout().getLineWidth(0);
- innerWidth += tv.getCompoundPaddingLeft() + tv.getCompoundPaddingRight();
- width = Math.min(width, innerWidth);
- }
- }
- int cx = view.getLeft() + width / 2;
- int cy = view.getTop() + view.getHeight() / 2;
- int w = riv.getWidth();
- int h = riv.getHeight();
- int r = Math.max(
- Math.max(cx + cy, cx + (h - cy)),
- Math.max((w - cx) + cy, (w - cx) + (h - cy)));
-
- riv.setRevealParameters(cx, cy, r);
- riv.setPendingIntent(pendingIntent);
- riv.setRemoteInput(inputs, input);
- riv.focusAnimated();
-
- return true;
- }
-
- };
-
- private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- if (Intent.ACTION_USER_SWITCHED.equals(action)) {
- mCurrentUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
- updateCurrentProfilesCache();
- if (true) Log.v(TAG, "userId " + mCurrentUserId + " is in the house");
-
- updateLockscreenNotificationSetting();
-
- userSwitched(mCurrentUserId);
- } else if (Intent.ACTION_USER_ADDED.equals(action)) {
- updateCurrentProfilesCache();
- } else if (Intent.ACTION_USER_PRESENT.equals(action)) {
- List<ActivityManager.RecentTaskInfo> recentTask = null;
- try {
- recentTask = ActivityManager.getService().getRecentTasks(1,
- ActivityManager.RECENT_WITH_EXCLUDED
- | ActivityManager.RECENT_INCLUDE_PROFILES,
- mCurrentUserId).getList();
- } catch (RemoteException e) {
- // Abandon hope activity manager not running.
- }
- if (recentTask != null && recentTask.size() > 0) {
- UserInfo user = mUserManager.getUserInfo(recentTask.get(0).userId);
- if (user != null && user.isManagedProfile()) {
- Toast toast = Toast.makeText(mContext,
- R.string.managed_profile_foreground_toast,
- Toast.LENGTH_SHORT);
- TextView text = (TextView) toast.getView().findViewById(
- android.R.id.message);
- text.setCompoundDrawablesRelativeWithIntrinsicBounds(
- R.drawable.stat_sys_managed_profile_status, 0, 0, 0);
- int paddingPx = mContext.getResources().getDimensionPixelSize(
- R.dimen.managed_profile_toast_padding);
- text.setCompoundDrawablePadding(paddingPx);
- toast.show();
- }
- }
- } else if (BANNER_ACTION_CANCEL.equals(action) || BANNER_ACTION_SETUP.equals(action)) {
- NotificationManager noMan = (NotificationManager)
- mContext.getSystemService(Context.NOTIFICATION_SERVICE);
- noMan.cancel(SystemMessage.NOTE_HIDDEN_NOTIFICATIONS);
-
- Settings.Secure.putInt(mContext.getContentResolver(),
- Settings.Secure.SHOW_NOTE_ABOUT_NOTIFICATION_HIDING, 0);
- if (BANNER_ACTION_SETUP.equals(action)) {
- animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL,
- true /* force */);
- mContext.startActivity(new Intent(Settings.ACTION_APP_NOTIFICATION_REDACTION)
- .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
-
- );
- }
- } else if (NOTIFICATION_UNLOCKED_BY_WORK_CHALLENGE_ACTION.equals(action)) {
- final IntentSender intentSender = intent.getParcelableExtra(Intent.EXTRA_INTENT);
- final String notificationKey = intent.getStringExtra(Intent.EXTRA_INDEX);
- if (intentSender != null) {
- try {
- mContext.startIntentSender(intentSender, null, 0, 0, 0);
- } catch (IntentSender.SendIntentException e) {
- /* ignore */
- }
- }
- if (notificationKey != null) {
- try {
- mBarService.onNotificationClick(notificationKey);
- } catch (RemoteException e) {
- /* ignore */
- }
- }
- }
- }
- };
-
- private final BroadcastReceiver mAllUsersReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- final String action = intent.getAction();
- final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
-
- if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(action) &&
- isCurrentProfile(getSendingUserId())) {
- mUsersAllowingPrivateNotifications.clear();
- updateLockscreenNotificationSetting();
- updateNotifications();
- } else if (Intent.ACTION_DEVICE_LOCKED_CHANGED.equals(action)) {
- if (userId != mCurrentUserId && isCurrentProfile(userId)) {
- onWorkChallengeChanged();
- }
- }
- }
- };
-
- private final NotificationListenerService mNotificationListener =
- new NotificationListenerService() {
- @Override
- public void onListenerConnected() {
- if (DEBUG) Log.d(TAG, "onListenerConnected");
- final StatusBarNotification[] notifications = getActiveNotifications();
- if (notifications == null) {
- Log.w(TAG, "onListenerConnected unable to get active notifications.");
- return;
- }
- final RankingMap currentRanking = getCurrentRanking();
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- for (StatusBarNotification sbn : notifications) {
- addNotification(sbn, currentRanking, null /* oldEntry */);
- }
- }
- });
- }
-
- @Override
- public void onNotificationPosted(final StatusBarNotification sbn,
- final RankingMap rankingMap) {
- if (DEBUG) Log.d(TAG, "onNotificationPosted: " + sbn);
- if (sbn != null) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- processForRemoteInput(sbn.getNotification());
- String key = sbn.getKey();
- mKeysKeptForRemoteInput.remove(key);
- boolean isUpdate = mNotificationData.get(key) != null;
- // In case we don't allow child notifications, we ignore children of
- // notifications that have a summary, since we're not going to show them
- // anyway. This is true also when the summary is canceled,
- // because children are automatically canceled by NoMan in that case.
- if (!ENABLE_CHILD_NOTIFICATIONS
- && mGroupManager.isChildInGroupWithSummary(sbn)) {
- if (DEBUG) {
- Log.d(TAG, "Ignoring group child due to existing summary: " + sbn);
- }
-
- // Remove existing notification to avoid stale data.
- if (isUpdate) {
- removeNotification(key, rankingMap);
- } else {
- mNotificationData.updateRanking(rankingMap);
- }
- return;
- }
- if (isUpdate) {
- updateNotification(sbn, rankingMap);
- } else {
- addNotification(sbn, rankingMap, null /* oldEntry */);
- }
- }
- });
- }
- }
-
- @Override
- public void onNotificationRemoved(StatusBarNotification sbn,
- final RankingMap rankingMap) {
- if (DEBUG) Log.d(TAG, "onNotificationRemoved: " + sbn);
- if (sbn != null) {
- final String key = sbn.getKey();
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- removeNotification(key, rankingMap);
- }
- });
- }
- }
-
- @Override
- public void onNotificationRankingUpdate(final RankingMap rankingMap) {
- if (DEBUG) Log.d(TAG, "onRankingUpdate");
- if (rankingMap != null) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- updateNotificationRanking(rankingMap);
- }
- });
- } }
-
- };
-
- private void updateCurrentProfilesCache() {
- synchronized (mCurrentProfiles) {
- mCurrentProfiles.clear();
- if (mUserManager != null) {
- for (UserInfo user : mUserManager.getProfiles(mCurrentUserId)) {
- mCurrentProfiles.put(user.id, user);
- }
- }
- }
- }
-
- @Override
- public void start() {
- mWindowManager = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
- mWindowManagerService = WindowManagerGlobal.getWindowManagerService();
- mDisplay = mWindowManager.getDefaultDisplay();
- mDevicePolicyManager = (DevicePolicyManager)mContext.getSystemService(
- Context.DEVICE_POLICY_SERVICE);
-
- mNotificationData = new NotificationData(this);
-
- mAccessibilityManager = (AccessibilityManager)
- mContext.getSystemService(Context.ACCESSIBILITY_SERVICE);
-
- mDreamManager = IDreamManager.Stub.asInterface(
- ServiceManager.checkService(DreamService.DREAM_SERVICE));
- mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
-
- mDeviceProvisionedController = Dependency.get(DeviceProvisionedController.class);
- mDeviceProvisionedController.addCallback(mDeviceProvisionedListener);
- mContext.getContentResolver().registerContentObserver(
- Settings.Global.getUriFor(Settings.Global.ZEN_MODE), false,
- mSettingsObserver);
- mContext.getContentResolver().registerContentObserver(
- Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS), false,
- mLockscreenSettingsObserver,
- UserHandle.USER_ALL);
- if (ENABLE_LOCK_SCREEN_ALLOW_REMOTE_INPUT) {
- mContext.getContentResolver().registerContentObserver(
- Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_ALLOW_REMOTE_INPUT),
- false,
- mSettingsObserver,
- UserHandle.USER_ALL);
- }
-
- mContext.getContentResolver().registerContentObserver(
- Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS),
- true,
- mLockscreenSettingsObserver,
- UserHandle.USER_ALL);
-
- mBarService = IStatusBarService.Stub.asInterface(
- ServiceManager.getService(Context.STATUS_BAR_SERVICE));
-
- mRecents = getComponent(Recents.class);
-
- final Configuration currentConfig = mContext.getResources().getConfiguration();
- mLocale = currentConfig.locale;
- mLayoutDirection = TextUtils.getLayoutDirectionFromLocale(mLocale);
- mFontScale = currentConfig.fontScale;
- mDensity = currentConfig.densityDpi;
-
- mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
- mKeyguardManager = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
- mLockPatternUtils = new LockPatternUtils(mContext);
-
- // Connect in to the status bar manager service
- mCommandQueue = getComponent(CommandQueue.class);
- mCommandQueue.addCallbacks(this);
-
- int[] switches = new int[9];
- ArrayList<IBinder> binders = new ArrayList<IBinder>();
- ArrayList<String> iconSlots = new ArrayList<>();
- ArrayList<StatusBarIcon> icons = new ArrayList<>();
- Rect fullscreenStackBounds = new Rect();
- Rect dockedStackBounds = new Rect();
- try {
- mBarService.registerStatusBar(mCommandQueue, iconSlots, icons, switches, binders,
- fullscreenStackBounds, dockedStackBounds);
- } catch (RemoteException ex) {
- // If the system process isn't there we're doomed anyway.
- }
-
- createAndAddWindows();
-
- mSettingsObserver.onChange(false); // set up
- disable(switches[0], switches[6], false /* animate */);
- setSystemUiVisibility(switches[1], switches[7], switches[8], 0xffffffff,
- fullscreenStackBounds, dockedStackBounds);
- topAppWindowChanged(switches[2] != 0);
- // StatusBarManagerService has a back up of IME token and it's restored here.
- setImeWindowStatus(binders.get(0), switches[3], switches[4], switches[5] != 0);
-
- // Set up the initial icon state
- int N = iconSlots.size();
- int viewIndex = 0;
- for (int i=0; i < N; i++) {
- setIcon(iconSlots.get(i), icons.get(i));
- }
-
- // Set up the initial notification state.
- try {
- mNotificationListener.registerAsSystemService(mContext,
- new ComponentName(mContext.getPackageName(), getClass().getCanonicalName()),
- UserHandle.USER_ALL);
- } catch (RemoteException e) {
- Log.e(TAG, "Unable to register notification listener", e);
- }
-
-
- if (DEBUG) {
- Log.d(TAG, String.format(
- "init: icons=%d disabled=0x%08x lights=0x%08x menu=0x%08x imeButton=0x%08x",
- icons.size(),
- switches[0],
- switches[1],
- switches[2],
- switches[3]
- ));
- }
-
- mCurrentUserId = ActivityManager.getCurrentUser();
- setHeadsUpUser(mCurrentUserId);
-
- IntentFilter filter = new IntentFilter();
- filter.addAction(Intent.ACTION_USER_SWITCHED);
- filter.addAction(Intent.ACTION_USER_ADDED);
- filter.addAction(Intent.ACTION_USER_PRESENT);
- mContext.registerReceiver(mBroadcastReceiver, filter);
-
- IntentFilter internalFilter = new IntentFilter();
- internalFilter.addAction(NOTIFICATION_UNLOCKED_BY_WORK_CHALLENGE_ACTION);
- internalFilter.addAction(BANNER_ACTION_CANCEL);
- internalFilter.addAction(BANNER_ACTION_SETUP);
- mContext.registerReceiver(mBroadcastReceiver, internalFilter, PERMISSION_SELF, null);
-
- IntentFilter allUsersFilter = new IntentFilter();
- allUsersFilter.addAction(
- DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
- allUsersFilter.addAction(Intent.ACTION_DEVICE_LOCKED_CHANGED);
- mContext.registerReceiverAsUser(mAllUsersReceiver, UserHandle.ALL, allUsersFilter,
- null, null);
- updateCurrentProfilesCache();
-
- IVrManager vrManager = IVrManager.Stub.asInterface(ServiceManager.getService("vrmanager"));
- try {
- vrManager.registerListener(mVrStateCallbacks);
- } catch (RemoteException e) {
- Slog.e(TAG, "Failed to register VR mode state listener: " + e);
- }
-
- mNonBlockablePkgs = new HashSet<String>();
- Collections.addAll(mNonBlockablePkgs, mContext.getResources().getStringArray(
- com.android.internal.R.array.config_nonBlockableNotificationPackages));
- }
-
- protected void notifyUserAboutHiddenNotifications() {
- if (0 != Settings.Secure.getInt(mContext.getContentResolver(),
- Settings.Secure.SHOW_NOTE_ABOUT_NOTIFICATION_HIDING, 1)) {
- Log.d(TAG, "user hasn't seen notification about hidden notifications");
- if (!mLockPatternUtils.isSecure(KeyguardUpdateMonitor.getCurrentUser())) {
- Log.d(TAG, "insecure lockscreen, skipping notification");
- Settings.Secure.putInt(mContext.getContentResolver(),
- Settings.Secure.SHOW_NOTE_ABOUT_NOTIFICATION_HIDING, 0);
- return;
- }
- Log.d(TAG, "disabling lockecreen notifications and alerting the user");
- // disable lockscreen notifications until user acts on the banner.
- Settings.Secure.putInt(mContext.getContentResolver(),
- Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 0);
- Settings.Secure.putInt(mContext.getContentResolver(),
- Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0);
-
- final String packageName = mContext.getPackageName();
- PendingIntent cancelIntent = PendingIntent.getBroadcast(mContext, 0,
- new Intent(BANNER_ACTION_CANCEL).setPackage(packageName),
- PendingIntent.FLAG_CANCEL_CURRENT);
- PendingIntent setupIntent = PendingIntent.getBroadcast(mContext, 0,
- new Intent(BANNER_ACTION_SETUP).setPackage(packageName),
- PendingIntent.FLAG_CANCEL_CURRENT);
-
- final int colorRes = com.android.internal.R.color.system_notification_accent_color;
- Notification.Builder note = new Notification.Builder(mContext)
- .setSmallIcon(R.drawable.ic_android)
- .setContentTitle(mContext.getString(R.string.hidden_notifications_title))
- .setContentText(mContext.getString(R.string.hidden_notifications_text))
- .setChannel(NotificationChannels.SECURITY)
- .setOngoing(true)
- .setColor(mContext.getColor(colorRes))
- .setContentIntent(setupIntent)
- .addAction(R.drawable.ic_close,
- mContext.getString(R.string.hidden_notifications_cancel),
- cancelIntent)
- .addAction(R.drawable.ic_settings,
- mContext.getString(R.string.hidden_notifications_setup),
- setupIntent);
- overrideNotificationAppName(mContext, note);
-
- NotificationManager noMan =
- (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
- noMan.notify(SystemMessage.NOTE_HIDDEN_NOTIFICATIONS, note.build());
- }
- }
-
- public void userSwitched(int newUserId) {
- setHeadsUpUser(newUserId);
- }
-
- protected abstract void setHeadsUpUser(int newUserId);
-
- @Override // NotificationData.Environment
- public boolean isNotificationForCurrentProfiles(StatusBarNotification n) {
- final int thisUserId = mCurrentUserId;
- final int notificationUserId = n.getUserId();
- if (DEBUG && MULTIUSER_DEBUG) {
- Log.v(TAG, String.format("%s: current userid: %d, notification userid: %d",
- n, thisUserId, notificationUserId));
- }
- return isCurrentProfile(notificationUserId);
- }
-
- protected void setNotificationShown(StatusBarNotification n) {
- setNotificationsShown(new String[]{n.getKey()});
- }
-
- protected void setNotificationsShown(String[] keys) {
- try {
- mNotificationListener.setNotificationsShown(keys);
- } catch (RuntimeException e) {
- Log.d(TAG, "failed setNotificationsShown: ", e);
- }
- }
-
- protected boolean isCurrentProfile(int userId) {
- synchronized (mCurrentProfiles) {
- return userId == UserHandle.USER_ALL || mCurrentProfiles.get(userId) != null;
- }
- }
-
- @Override
- public String getCurrentMediaNotificationKey() {
- return null;
- }
-
- @Override
- public NotificationGroupManager getGroupManager() {
- return mGroupManager;
- }
-
- /**
- * Takes the necessary steps to prepare the status bar for starting an activity, then starts it.
- * @param action A dismiss action that is called if it's safe to start the activity.
- * @param afterKeyguardGone Whether the action should be executed after the Keyguard is gone.
- */
- protected void dismissKeyguardThenExecute(OnDismissAction action, boolean afterKeyguardGone) {
- action.onDismiss();
- }
-
- @Override
- protected void onConfigurationChanged(Configuration newConfig) {
- final float fontScale = newConfig.fontScale;
- final int density = newConfig.densityDpi;
- if (density != mDensity || mFontScale != fontScale) {
- onDensityOrFontScaleChanged();
- mDensity = density;
- mFontScale = fontScale;
- }
- }
-
- protected void onDensityOrFontScaleChanged() {
- ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
- for (int i = 0; i < activeNotifications.size(); i++) {
- Entry entry = activeNotifications.get(i);
- boolean exposedGuts = entry.row.getGuts() == mNotificationGutsExposed;
- entry.row.reInflateViews();
- if (exposedGuts) {
- mNotificationGutsExposed = entry.row.getGuts();
- bindGuts(entry.row, mGutsMenuItem);
- }
- inflateViews(entry, mStackScroller);
- }
- }
-
- protected void bindDismissRunnable(final ExpandableNotificationRow row) {
- row.setOnDismissRunnable(() -> performRemoveNotification(row.getStatusBarNotification()));
- }
-
- protected void performRemoveNotification(StatusBarNotification n) {
- final String pkg = n.getPackageName();
- final String tag = n.getTag();
- final int id = n.getId();
- final int userId = n.getUserId();
- try {
- mBarService.onNotificationClear(pkg, tag, id, userId);
- if (FORCE_REMOTE_INPUT_HISTORY
- && mKeysKeptForRemoteInput.contains(n.getKey())) {
- mKeysKeptForRemoteInput.remove(n.getKey());
- }
- removeNotification(n.getKey(), null);
-
- } catch (RemoteException ex) {
- // system process is dead if we're here.
- }
- }
-
-
- protected void applyColorsAndBackgrounds(StatusBarNotification sbn,
- NotificationData.Entry entry) {
-
- if (entry.getContentView().getId()
- != com.android.internal.R.id.status_bar_latest_event_content) {
- // Using custom RemoteViews
- if (entry.targetSdk >= Build.VERSION_CODES.GINGERBREAD
- && entry.targetSdk < Build.VERSION_CODES.LOLLIPOP) {
- entry.row.setShowingLegacyBackground(true);
- entry.legacy = true;
- }
- }
-
- entry.setIconTag(R.id.icon_is_pre_L, entry.targetSdk < Build.VERSION_CODES.LOLLIPOP);
- }
-
- public boolean isMediaNotification(NotificationData.Entry entry) {
- // TODO: confirm that there's a valid media key
- return entry.getExpandedContentView() != null &&
- entry.getExpandedContentView()
- .findViewById(com.android.internal.R.id.media_actions) != null;
- }
-
- // The (i) button in the guts that links to the system notification settings for that app
- private void startAppNotificationSettingsActivity(String packageName, final int appUid) {
- final Intent intent = new Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
- intent.putExtra(Settings.EXTRA_APP_PACKAGE, packageName);
- intent.putExtra(Settings.EXTRA_APP_UID, appUid);
- startNotificationGutsIntent(intent, appUid);
- }
-
- private void startNotificationGutsIntent(final Intent intent, final int appUid) {
- dismissKeyguardThenExecute(new OnDismissAction() {
- @Override
- public boolean onDismiss() {
- AsyncTask.execute(new Runnable() {
- @Override
- public void run() {
- TaskStackBuilder.create(mContext)
- .addNextIntentWithParentStack(intent)
- .startActivities(getActivityOptions(),
- new UserHandle(UserHandle.getUserId(appUid)));
- }
- });
- animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL, true /* force */);
- return true;
- }
- }, false /* afterKeyguardGone */);
- }
-
- protected void setNotificationSnoozed(StatusBarNotification sbn, SnoozeOption snoozeOption) {
- if (snoozeOption.criterion != null) {
- mNotificationListener.snoozeNotification(sbn.getKey(), snoozeOption.criterion.getId());
- } else {
- GregorianCalendar snoozeUntil = new GregorianCalendar();
- snoozeUntil.add(Calendar.MINUTE, snoozeOption.snoozeForMinutes);
- mNotificationListener.snoozeNotification(sbn.getKey(), snoozeUntil.getTimeInMillis());
- }
- }
-
- public SnoozeListener getSnoozeListener() {
- return null;
- }
-
- private void bindGuts(final ExpandableNotificationRow row, MenuItem item) {
- row.inflateGuts();
- row.setGutsView(item);
- final StatusBarNotification sbn = row.getStatusBarNotification();
- row.setTag(sbn.getPackageName());
- final NotificationGuts guts = row.getGuts();
- guts.setClosedListener((NotificationGuts g) -> {
- if (!row.isRemoved()) {
- mStackScroller.onHeightChanged(row, !isPanelFullyCollapsed() /* needsAnimation */);
- }
- mNotificationGutsExposed = null;
- });
-
- if (item.gutsContent instanceof SnoozeGutsContent) {
- ((SnoozeGutsContent) item.gutsContent).setSnoozeListener(getSnoozeListener());
- ((SnoozeGutsContent) item.gutsContent).setStatusBarNotification(sbn);
- ((NotificationSnooze) item.gutsContent).setSnoozeOptions(row.getEntry().snoozeCriteria);
- }
-
- if (item.gutsContent instanceof NotificationInfo) {
- final NotificationChannel channel = row.getEntry().channel;
- PackageManager pmUser = getPackageManagerForUser(mContext,
- sbn.getUser().getIdentifier());
- final INotificationManager iNotificationManager = INotificationManager.Stub.asInterface(
- ServiceManager.getService(Context.NOTIFICATION_SERVICE));
- final String pkg = sbn.getPackageName();
- NotificationInfo info = (NotificationInfo) item.gutsContent;
- final NotificationInfo.OnSettingsClickListener onSettingsClick = (View v,
- int appUid) -> {
- MetricsLogger.action(mContext, MetricsEvent.ACTION_NOTE_INFO);
- guts.resetFalsingCheck();
- startAppNotificationSettingsActivity(pkg, appUid);
- };
- final View.OnClickListener onDoneClick = (View v) -> {
- // If the user has security enabled, show challenge if the setting is changed.
- if (info.hasImportanceChanged()
- && isLockscreenPublicMode(sbn.getUser().getIdentifier())
- && (mState == StatusBarState.KEYGUARD
- || mState == StatusBarState.SHADE_LOCKED)) {
- OnDismissAction dismissAction = new OnDismissAction() {
- @Override
- public boolean onDismiss() {
- saveAndCloseNotificationMenu(info, row, guts, v);
- return true;
- }
- };
- onLockedNotificationImportanceChange(dismissAction);
- } else {
- saveAndCloseNotificationMenu(info, row, guts, v);
- }
- };
- info.bindNotification(pmUser, iNotificationManager, sbn, channel, onSettingsClick,
- onDoneClick,
- mNonBlockablePkgs);
- }
- }
-
- private void saveAndCloseNotificationMenu(NotificationInfo info,
- ExpandableNotificationRow row, NotificationGuts guts, View done) {
- guts.resetFalsingCheck();
- info.saveImportance();
- int[] rowLocation = new int[2];
- int[] doneLocation = new int[2];
- row.getLocationOnScreen(rowLocation);
- done.getLocationOnScreen(doneLocation);
-
- final int centerX = done.getWidth() / 2;
- final int centerY = done.getHeight() / 2;
- final int x = doneLocation[0] - rowLocation[0] + centerX;
- final int y = doneLocation[1] - rowLocation[1] + centerY;
- dismissPopups(x, y);
- }
-
- protected SwipeHelper.LongPressListener getNotificationLongClicker() {
- return new SwipeHelper.LongPressListener() {
- @Override
- public boolean onLongPress(View v, final int x, final int y,
- MenuItem item) {
- if (!(v instanceof ExpandableNotificationRow)) {
- return false;
- }
- if (v.getWindowToken() == null) {
- Log.e(TAG, "Trying to show notification guts, but not attached to window");
- return false;
- }
-
- final ExpandableNotificationRow row = (ExpandableNotificationRow) v;
- bindGuts(row, item);
- NotificationGuts guts = row.getGuts();
-
- // Assume we are a status_bar_notification_row
- if (guts == null) {
- // This view has no guts. Examples are the more card or the dismiss all view
- return false;
- }
-
- // Already showing?
- if (guts.getVisibility() == View.VISIBLE) {
- dismissPopups(x, y);
- return false;
- }
-
- MetricsLogger.action(mContext, MetricsEvent.ACTION_NOTE_CONTROLS);
-
- // ensure that it's laid but not visible until actually laid out
- guts.setVisibility(View.INVISIBLE);
- // Post to ensure the the guts are properly laid out.
- guts.post(new Runnable() {
- @Override
- public void run() {
- if (row.getWindowToken() == null) {
- Log.e(TAG, "Trying to show notification guts, but not attached to "
- + "window");
- return;
- }
- dismissPopups(-1 /* x */, -1 /* y */, false /* resetGear */,
- false /* animate */);
- guts.setVisibility(View.VISIBLE);
- final double horz = Math.max(guts.getWidth() - x, x);
- final double vert = Math.max(guts.getHeight() - y, y);
- final float r = (float) Math.hypot(horz, vert);
- final Animator a
- = 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 /* exposed */,
- mState == StatusBarState.KEYGUARD /* needsFalsingProtection */);
- row.closeRemoteInput();
- mStackScroller.onHeightChanged(row, true /* needsAnimation */);
- mNotificationGutsExposed = guts;
- mGutsMenuItem = item;
- }
- });
- return true;
- }
- };
- }
-
- /**
- * Returns the exposed NotificationGuts or null if none are exposed.
- */
- public NotificationGuts getExposedGuts() {
- return mNotificationGutsExposed;
- }
-
- public void dismissPopups() {
- dismissPopups(-1 /* x */, -1 /* y */, true /* resetGear */, false /* animate */);
- }
-
- private void dismissPopups(int x, int y) {
- dismissPopups(x, y, true /* resetGear */, false /* animate */);
- }
-
- public void dismissPopups(int x, int y, boolean resetGear, boolean animate) {
- if (mNotificationGutsExposed != null) {
- mNotificationGutsExposed.closeControls(x, y, true /* save */);
- }
- if (resetGear) {
- mStackScroller.resetExposedGearView(animate, true /* force */);
- }
- }
-
- @Override
- public void showRecentApps(boolean triggeredFromAltTab, boolean fromHome) {
- int msg = MSG_SHOW_RECENT_APPS;
- mHandler.removeMessages(msg);
- mHandler.obtainMessage(msg, triggeredFromAltTab ? 1 : 0, fromHome ? 1 : 0).sendToTarget();
- }
-
- @Override
- public void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
- int msg = MSG_HIDE_RECENT_APPS;
- mHandler.removeMessages(msg);
- mHandler.obtainMessage(msg, triggeredFromAltTab ? 1 : 0,
- triggeredFromHomeKey ? 1 : 0).sendToTarget();
- }
-
- @Override
- public void toggleRecentApps() {
- toggleRecents();
- }
-
- @Override
- public void toggleSplitScreen() {
- toggleSplitScreenMode(-1 /* metricsDockAction */, -1 /* metricsUndockAction */);
- }
-
- @Override
- public void preloadRecentApps() {
- int msg = MSG_PRELOAD_RECENT_APPS;
- mHandler.removeMessages(msg);
- mHandler.sendEmptyMessage(msg);
- }
-
- @Override
- public void cancelPreloadRecentApps() {
- int msg = MSG_CANCEL_PRELOAD_RECENT_APPS;
- mHandler.removeMessages(msg);
- mHandler.sendEmptyMessage(msg);
- }
-
- @Override
- public void dismissKeyboardShortcutsMenu() {
- int msg = MSG_DISMISS_KEYBOARD_SHORTCUTS_MENU;
- mHandler.removeMessages(msg);
- mHandler.sendEmptyMessage(msg);
- }
-
- @Override
- public void toggleKeyboardShortcutsMenu(int deviceId) {
- int msg = MSG_TOGGLE_KEYBOARD_SHORTCUTS_MENU;
- mHandler.removeMessages(msg);
- mHandler.obtainMessage(msg, deviceId, 0).sendToTarget();
- }
-
- /** Jumps to the next affiliated task in the group. */
- public void showNextAffiliatedTask() {
- int msg = MSG_SHOW_NEXT_AFFILIATED_TASK;
- mHandler.removeMessages(msg);
- mHandler.sendEmptyMessage(msg);
- }
-
- /** Jumps to the previous affiliated task in the group. */
- public void showPreviousAffiliatedTask() {
- int msg = MSG_SHOW_PREV_AFFILIATED_TASK;
- mHandler.removeMessages(msg);
- mHandler.sendEmptyMessage(msg);
- }
-
- protected H createHandler() {
- return new H();
- }
-
- protected void sendCloseSystemWindows(String reason) {
- try {
- ActivityManager.getService().closeSystemDialogs(reason);
- } catch (RemoteException e) {
- }
- }
-
- protected abstract View getStatusBarView();
-
- /**
- * Toggle docking the app window
- *
- * @param metricsDockAction the action to log when docking is successful, or -1 to not log
- * anything on successful docking
- * @param metricsUndockAction the action to log when undocking, or -1 to not log anything when
- * undocking
- * @return true if toggle split screen was successful
- */
- protected abstract boolean toggleSplitScreenMode(int metricsDockAction, int metricsUndockAction);
-
- /** Proxy for RecentsComponent */
-
- protected void showRecents(boolean triggeredFromAltTab, boolean fromHome) {
- if (mRecents != null) {
- sendCloseSystemWindows(SYSTEM_DIALOG_REASON_RECENT_APPS);
- mRecents.showRecents(triggeredFromAltTab, fromHome);
- }
- }
-
- protected void hideRecents(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
- if (mRecents != null) {
- mRecents.hideRecents(triggeredFromAltTab, triggeredFromHomeKey);
- }
- }
-
- protected void toggleRecents() {
- if (mRecents != null) {
- mRecents.toggleRecents(mDisplay);
- }
- }
-
- protected void preloadRecents() {
- if (mRecents != null) {
- mRecents.preloadRecents();
- }
- }
-
- protected void toggleKeyboardShortcuts(int deviceId) {
- KeyboardShortcuts.toggle(mContext, deviceId);
- }
-
- protected void dismissKeyboardShortcuts() {
- KeyboardShortcuts.dismiss();
- }
-
- protected void cancelPreloadingRecents() {
- if (mRecents != null) {
- mRecents.cancelPreloadingRecents();
- }
- }
-
- protected void showRecentsNextAffiliatedTask() {
- if (mRecents != null) {
- mRecents.showNextAffiliatedTask();
- }
- }
-
- protected void showRecentsPreviousAffiliatedTask() {
- if (mRecents != null) {
- mRecents.showPrevAffiliatedTask();
- }
- }
-
- /**
- * If there is an active heads-up notification and it has a fullscreen intent, fire it now.
- */
- public abstract void maybeEscalateHeadsUp();
-
- /**
- * Save the current "public" (locked and secure) state of the lockscreen.
- */
- public void setLockscreenPublicMode(boolean publicMode, int userId) {
- mLockscreenPublicMode.put(userId, publicMode);
- }
-
- public boolean isLockscreenPublicMode(int userId) {
- return mLockscreenPublicMode.get(userId, false);
- }
-
- protected void onWorkChallengeChanged() {}
-
- /**
- * Has the given user chosen to allow notifications to be shown even when the lockscreen is in
- * "public" (secure & locked) mode?
- */
- public boolean userAllowsNotificationsInPublic(int userHandle) {
- if (userHandle == UserHandle.USER_ALL) {
- return true;
- }
-
- if (mUsersAllowingNotifications.indexOfKey(userHandle) < 0) {
- final boolean allowed = 0 != Settings.Secure.getIntForUser(
- mContext.getContentResolver(),
- Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 0, userHandle);
- mUsersAllowingNotifications.append(userHandle, allowed);
- return allowed;
- }
-
- return mUsersAllowingNotifications.get(userHandle);
- }
-
- /**
- * Has the given user chosen to allow their private (full) notifications to be shown even
- * when the lockscreen is in "public" (secure & locked) mode?
- */
- public boolean userAllowsPrivateNotificationsInPublic(int userHandle) {
- if (userHandle == UserHandle.USER_ALL) {
- return true;
- }
-
- if (mUsersAllowingPrivateNotifications.indexOfKey(userHandle) < 0) {
- final boolean allowedByUser = 0 != Settings.Secure.getIntForUser(
- mContext.getContentResolver(),
- Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, userHandle);
- final boolean allowedByDpm = adminAllowsUnredactedNotifications(userHandle);
- final boolean allowed = allowedByUser && allowedByDpm;
- mUsersAllowingPrivateNotifications.append(userHandle, allowed);
- return allowed;
- }
-
- return mUsersAllowingPrivateNotifications.get(userHandle);
- }
-
- private boolean adminAllowsUnredactedNotifications(int userHandle) {
- if (userHandle == UserHandle.USER_ALL) {
- return true;
- }
- final int dpmFlags = mDevicePolicyManager.getKeyguardDisabledFeatures(null /* admin */,
- userHandle);
- return (dpmFlags & DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS) == 0;
- }
-
- /**
- * Returns true if we're on a secure lockscreen and the user wants to hide notification data.
- * If so, notifications should be hidden.
- */
- @Override // NotificationData.Environment
- public boolean shouldHideNotifications(int userId) {
- return isLockscreenPublicMode(userId) && !userAllowsNotificationsInPublic(userId)
- || (userId != mCurrentUserId && shouldHideNotifications(mCurrentUserId));
- }
-
- /**
- * Returns true if we're on a secure lockscreen and the user wants to hide notifications via
- * package-specific override.
- */
- @Override // NotificationDate.Environment
- public boolean shouldHideNotifications(String key) {
- return isLockscreenPublicMode(mCurrentUserId)
- && mNotificationData.getVisibilityOverride(key) == Notification.VISIBILITY_SECRET;
- }
-
- /**
- * Returns true if we're on a secure lockscreen.
- */
- @Override // NotificationData.Environment
- public boolean isSecurelyLocked(int userId) {
- return isLockscreenPublicMode(userId);
- }
-
- public void onNotificationClear(StatusBarNotification notification) {
- try {
- mBarService.onNotificationClear(
- notification.getPackageName(),
- notification.getTag(),
- notification.getId(),
- notification.getUserId());
- } catch (android.os.RemoteException ex) {
- // oh well
- }
- }
-
- /**
- * Called when the notification panel layouts
- */
- public void onPanelLaidOut() {
- if (mState == StatusBarState.KEYGUARD) {
- // Since the number of notifications is determined based on the height of the view, we
- // need to update them.
- int maxBefore = getMaxKeyguardNotifications(false /* recompute */);
- int maxNotifications = getMaxKeyguardNotifications(true /* recompute */);
- if (maxBefore != maxNotifications) {
- updateRowStates();
- }
- }
- }
-
- protected void onLockedNotificationImportanceChange(OnDismissAction dismissAction) {}
-
- protected void onLockedRemoteInput(ExpandableNotificationRow row, View clickedView) {}
-
- protected void onLockedWorkRemoteInput(int userId, ExpandableNotificationRow row,
- View clicked) {}
-
- @Override
- public void onExpandClicked(Entry clickedEntry, boolean nowExpanded) {
- }
-
- protected class H extends Handler {
- @Override
- public void handleMessage(Message m) {
- switch (m.what) {
- case MSG_SHOW_RECENT_APPS:
- showRecents(m.arg1 > 0, m.arg2 != 0);
- break;
- case MSG_HIDE_RECENT_APPS:
- hideRecents(m.arg1 > 0, m.arg2 > 0);
- break;
- case MSG_TOGGLE_RECENTS_APPS:
- toggleRecents();
- break;
- case MSG_PRELOAD_RECENT_APPS:
- preloadRecents();
- break;
- case MSG_CANCEL_PRELOAD_RECENT_APPS:
- cancelPreloadingRecents();
- break;
- case MSG_SHOW_NEXT_AFFILIATED_TASK:
- showRecentsNextAffiliatedTask();
- break;
- case MSG_SHOW_PREV_AFFILIATED_TASK:
- showRecentsPreviousAffiliatedTask();
- break;
- case MSG_TOGGLE_KEYBOARD_SHORTCUTS_MENU:
- toggleKeyboardShortcuts(m.arg1);
- break;
- case MSG_DISMISS_KEYBOARD_SHORTCUTS_MENU:
- dismissKeyboardShortcuts();
- break;
- }
- }
- }
-
- protected void workAroundBadLayerDrawableOpacity(View v) {
- }
-
- protected boolean inflateViews(Entry entry, ViewGroup parent) {
- PackageManager pmUser = getPackageManagerForUser(mContext,
- entry.notification.getUser().getIdentifier());
-
- final StatusBarNotification sbn = entry.notification;
- boolean isLowPriority = mNotificationData.isAmbient(sbn.getKey());
- try {
- entry.cacheContentViews(mContext, null, isLowPriority);
- } catch (RuntimeException e) {
- Log.e(TAG, "Unable to get notification remote views", e);
- return false;
- }
-
- final RemoteViews contentView = entry.cachedContentView;
- final RemoteViews bigContentView = entry.cachedBigContentView;
- final RemoteViews headsUpContentView = entry.cachedHeadsUpContentView;
- final RemoteViews publicContentView = entry.cachedPublicContentView;
- final RemoteViews ambientContentView = entry.cachedAmbientContentView;
-
- if (contentView == null) {
- Log.v(TAG, "no contentView for: " + sbn.getNotification());
- return false;
- }
-
- if (DEBUG) {
- Log.v(TAG, "publicContentView: " + publicContentView);
- }
-
- ExpandableNotificationRow row;
-
- // Stash away previous user expansion state so we can restore it at
- // the end.
- boolean hasUserChangedExpansion = false;
- boolean userExpanded = false;
- boolean userLocked = false;
-
- if (entry.row != null) {
- row = entry.row;
- hasUserChangedExpansion = row.hasUserChangedExpansion();
- userExpanded = row.isUserExpanded();
- userLocked = row.isUserLocked();
- entry.reset();
- if (hasUserChangedExpansion) {
- row.setUserExpanded(userExpanded);
- }
- } else {
- // create the row view
- LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
- Context.LAYOUT_INFLATER_SERVICE);
- row = (ExpandableNotificationRow) inflater.inflate(R.layout.status_bar_notification_row,
- parent, false);
- row.setExpansionLogger(this, entry.notification.getKey());
- row.setGroupManager(mGroupManager);
- row.setHeadsUpManager(mHeadsUpManager);
- row.setRemoteInputController(mRemoteInputController);
- row.setOnExpandClickListener(this);
-
- // Get the app name.
- // Note that Notification.Builder#bindHeaderAppName has similar logic
- // but since this field is used in the guts, it must be accurate.
- // Therefore we will only show the application label, or, failing that, the
- // package name. No substitutions.
- final String pkg = sbn.getPackageName();
- String appname = pkg;
- try {
- final ApplicationInfo info = pmUser.getApplicationInfo(pkg,
- PackageManager.MATCH_UNINSTALLED_PACKAGES
- | PackageManager.MATCH_DISABLED_COMPONENTS);
- if (info != null) {
- appname = String.valueOf(pmUser.getApplicationLabel(info));
- }
- } catch (NameNotFoundException e) {
- // Do nothing
- }
- row.setAppName(appname);
- }
-
- workAroundBadLayerDrawableOpacity(row);
- bindDismissRunnable(row);
- row.setIsLowPriority(isLowPriority);
-
- // NB: the large icon is now handled entirely by the template
-
- // bind the click event to the content area
- NotificationContentView contentContainer = row.getPrivateLayout();
- NotificationContentView contentContainerPublic = row.getPublicLayout();
-
- row.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
- if (ENABLE_REMOTE_INPUT) {
- row.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);
- }
-
- mNotificationClicker.register(row, sbn);
-
- // set up the adaptive layout
- View contentViewLocal = null;
- View bigContentViewLocal = null;
- View headsUpContentViewLocal = null;
- View publicViewLocal = null;
- View ambientViewLocal = null;
- try {
- contentViewLocal = contentView.apply(
- sbn.getPackageContext(mContext),
- contentContainer,
- mOnClickHandler);
- if (bigContentView != null) {
- bigContentViewLocal = bigContentView.apply(
- sbn.getPackageContext(mContext),
- contentContainer,
- mOnClickHandler);
- }
- if (headsUpContentView != null) {
- headsUpContentViewLocal = headsUpContentView.apply(
- sbn.getPackageContext(mContext),
- contentContainer,
- mOnClickHandler);
- }
- if (publicContentView != null) {
- publicViewLocal = publicContentView.apply(
- sbn.getPackageContext(mContext),
- contentContainerPublic, mOnClickHandler);
- }
- if (ambientContentView != null) {
- ambientViewLocal = ambientContentView.apply(
- sbn.getPackageContext(mContext),
- contentContainer, mOnClickHandler);
- }
-
- if (contentViewLocal != null) {
- contentViewLocal.setIsRootNamespace(true);
- contentContainer.setContractedChild(contentViewLocal);
- }
- if (bigContentViewLocal != null) {
- bigContentViewLocal.setIsRootNamespace(true);
- contentContainer.setExpandedChild(bigContentViewLocal);
- }
- if (headsUpContentViewLocal != null) {
- headsUpContentViewLocal.setIsRootNamespace(true);
- contentContainer.setHeadsUpChild(headsUpContentViewLocal);
- }
- if (publicViewLocal != null) {
- publicViewLocal.setIsRootNamespace(true);
- contentContainerPublic.setContractedChild(publicViewLocal);
- }
-
- if (ambientViewLocal != null) {
- ambientViewLocal.setIsRootNamespace(true);
- contentContainer.setAmbientChild(ambientViewLocal);
- }
- }
- catch (RuntimeException e) {
- final String ident = sbn.getPackageName() + "/0x" + Integer.toHexString(sbn.getId());
- Log.e(TAG, "couldn't inflate view for notification " + ident, e);
- return false;
- }
-
- // Extract target SDK version.
- try {
- ApplicationInfo info = pmUser.getApplicationInfo(sbn.getPackageName(), 0);
- entry.targetSdk = info.targetSdkVersion;
- } catch (NameNotFoundException ex) {
- Log.e(TAG, "Failed looking up ApplicationInfo for " + sbn.getPackageName(), ex);
- }
- entry.autoRedacted = entry.notification.getNotification().publicVersion == null;
-
- entry.row = row;
- entry.row.setOnActivatedListener(this);
- entry.row.setExpandable(bigContentViewLocal != null);
-
- applyColorsAndBackgrounds(sbn, entry);
-
- // Restore previous flags.
- if (hasUserChangedExpansion) {
- // Note: setUserExpanded() conveniently ignores calls with
- // userExpanded=true if !isExpandable().
- row.setUserExpanded(userExpanded);
- }
- row.setUserLocked(userLocked);
- row.onNotificationUpdated(entry);
- return true;
- }
-
- /**
- * Adds RemoteInput actions from the WearableExtender; to be removed once more apps support this
- * via first-class API.
- *
- * TODO: Remove once enough apps specify remote inputs on their own.
- */
- private void processForRemoteInput(Notification n) {
- if (!ENABLE_REMOTE_INPUT) return;
-
- if (n.extras != null && n.extras.containsKey("android.wearable.EXTENSIONS") &&
- (n.actions == null || n.actions.length == 0)) {
- Notification.Action viableAction = null;
- Notification.WearableExtender we = new Notification.WearableExtender(n);
-
- List<Notification.Action> actions = we.getActions();
- final int numActions = actions.size();
-
- for (int i = 0; i < numActions; i++) {
- Notification.Action action = actions.get(i);
- if (action == null) {
- continue;
- }
- RemoteInput[] remoteInputs = action.getRemoteInputs();
- if (remoteInputs == null) {
- continue;
- }
- for (RemoteInput ri : remoteInputs) {
- if (ri.getAllowFreeFormInput()) {
- viableAction = action;
- break;
- }
- }
- if (viableAction != null) {
- break;
- }
- }
-
- if (viableAction != null) {
- Notification.Builder rebuilder = Notification.Builder.recoverBuilder(mContext, n);
- rebuilder.setActions(viableAction);
- rebuilder.build(); // will rewrite n
- }
- }
- }
-
- public void startPendingIntentDismissingKeyguard(final PendingIntent intent) {
- if (!isDeviceProvisioned()) return;
-
- final boolean keyguardShowing = mStatusBarKeyguardViewManager.isShowing();
- final boolean afterKeyguardGone = intent.isActivity()
- && PreviewInflater.wouldLaunchResolverActivity(mContext, intent.getIntent(),
- mCurrentUserId);
- dismissKeyguardThenExecute(new OnDismissAction() {
- @Override
- public boolean onDismiss() {
- new Thread() {
- @Override
- public void run() {
- try {
- // The intent we are sending is for the application, which
- // won't have permission to immediately start an activity after
- // the user switches to home. We know it is safe to do at this
- // point, so make sure new activity switches are now allowed.
- ActivityManager.getService().resumeAppSwitches();
- } catch (RemoteException e) {
- }
- try {
- intent.send(null, 0, null, null, null, null, getActivityOptions());
- } catch (PendingIntent.CanceledException e) {
- // the stack trace isn't very helpful here.
- // Just log the exception message.
- Log.w(TAG, "Sending intent failed: " + e);
-
- // TODO: Dismiss Keyguard.
- }
- if (intent.isActivity()) {
- mAssistManager.hideAssist();
- }
- }
- }.start();
-
- // close the shade if it was open
- animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL,
- true /* force */, true /* delayed */);
- visibilityChanged(false);
-
- return true;
- }
- }, afterKeyguardGone);
- }
-
- public void addPostCollapseAction(Runnable r) {
- }
-
- public boolean isCollapsing() {
- return false;
- }
-
- public void wakeUpIfDozing(long time, PointF where) {
- }
-
- private final class NotificationClicker implements View.OnClickListener {
- private final int[] mTmpInt2 = new int[2];
-
- @Override
- public void onClick(final View v) {
- if (!(v instanceof ExpandableNotificationRow)) {
- Log.e(TAG, "NotificationClicker called on a view that is not a notification row.");
- return;
- }
-
- v.getLocationInWindow(mTmpInt2);
- wakeUpIfDozing(SystemClock.uptimeMillis(),
- new PointF(mTmpInt2[0] + v.getWidth() / 2, mTmpInt2[1] + v.getHeight() / 2));
-
- final ExpandableNotificationRow row = (ExpandableNotificationRow) v;
- final StatusBarNotification sbn = row.getStatusBarNotification();
- if (sbn == null) {
- Log.e(TAG, "NotificationClicker called on an unclickable notification,");
- return;
- }
-
- // Check if the notification is displaying the gear, if so slide notification back
- if (row.getSettingsRow() != null && row.getSettingsRow().isVisible()) {
- row.animateTranslateNotification(0);
- return;
- }
-
- Notification notification = sbn.getNotification();
- final PendingIntent intent = notification.contentIntent != null
- ? notification.contentIntent
- : notification.fullScreenIntent;
- final String notificationKey = sbn.getKey();
-
- // Mark notification for one frame.
- row.setJustClicked(true);
- DejankUtils.postAfterTraversal(new Runnable() {
- @Override
- public void run() {
- row.setJustClicked(false);
- }
- });
-
- final boolean keyguardShowing = mStatusBarKeyguardViewManager.isShowing();
- final boolean afterKeyguardGone = intent.isActivity()
- && PreviewInflater.wouldLaunchResolverActivity(mContext, intent.getIntent(),
- mCurrentUserId);
- dismissKeyguardThenExecute(new OnDismissAction() {
- @Override
- public boolean onDismiss() {
- if (mHeadsUpManager != null && mHeadsUpManager.isHeadsUp(notificationKey)) {
- // Release the HUN notification to the shade.
-
- if (isPanelFullyCollapsed()) {
- HeadsUpManager.setIsClickedNotification(row, true);
- }
- //
- // In most cases, when FLAG_AUTO_CANCEL is set, the notification will
- // become canceled shortly by NoMan, but we can't assume that.
- mHeadsUpManager.releaseImmediately(notificationKey);
- }
- StatusBarNotification parentToCancel = null;
- if (shouldAutoCancel(sbn) && mGroupManager.isOnlyChildInGroup(sbn)) {
- StatusBarNotification summarySbn = mGroupManager.getLogicalGroupSummary(sbn)
- .getStatusBarNotification();
- if (shouldAutoCancel(summarySbn)) {
- parentToCancel = summarySbn;
- }
- }
- final StatusBarNotification parentToCancelFinal = parentToCancel;
- new Thread() {
- @Override
- public void run() {
- try {
- // The intent we are sending is for the application, which
- // won't have permission to immediately start an activity after
- // the user switches to home. We know it is safe to do at this
- // point, so make sure new activity switches are now allowed.
- ActivityManager.getService().resumeAppSwitches();
- } catch (RemoteException e) {
- }
- if (intent != null) {
- // If we are launching a work activity and require to launch
- // separate work challenge, we defer the activity action and cancel
- // notification until work challenge is unlocked.
- if (intent.isActivity()) {
- final int userId = intent.getCreatorUserHandle()
- .getIdentifier();
- if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)
- && mKeyguardManager.isDeviceLocked(userId)) {
- boolean canBypass = false;
- try {
- canBypass = ActivityManager.getService()
- .canBypassWorkChallenge(intent);
- } catch (RemoteException e) {
- }
- // For direct-boot aware activities, they can be shown when
- // the device is still locked without triggering the work
- // challenge.
- if ((!canBypass) && startWorkChallengeIfNecessary(userId,
- intent.getIntentSender(), notificationKey)) {
- // Show work challenge, do not run PendingIntent and
- // remove notification
- return;
- }
- }
- }
- try {
- intent.send(null, 0, null, null, null, null,
- getActivityOptions());
- } catch (PendingIntent.CanceledException e) {
- // the stack trace isn't very helpful here.
- // Just log the exception message.
- Log.w(TAG, "Sending contentIntent failed: " + e);
-
- // TODO: Dismiss Keyguard.
- }
- if (intent.isActivity()) {
- mAssistManager.hideAssist();
- }
- }
-
- try {
- mBarService.onNotificationClick(notificationKey);
- } catch (RemoteException ex) {
- // system process is dead if we're here.
- }
- if (parentToCancelFinal != null) {
- // We have to post it to the UI thread for synchronization
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- Runnable removeRunnable = new Runnable() {
- @Override
- public void run() {
- performRemoveNotification(parentToCancelFinal);
- }
- };
- if (isCollapsing()) {
- // To avoid lags we're only performing the remove
- // after the shade was collapsed
- addPostCollapseAction(removeRunnable);
- } else {
- removeRunnable.run();
- }
- }
- });
- }
- }
- }.start();
-
- // close the shade if it was open
- animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL,
- true /* force */, true /* delayed */);
- visibilityChanged(false);
-
- return true;
- }
- }, afterKeyguardGone);
- }
-
- private boolean shouldAutoCancel(StatusBarNotification sbn) {
- int flags = sbn.getNotification().flags;
- if ((flags & Notification.FLAG_AUTO_CANCEL) != Notification.FLAG_AUTO_CANCEL) {
- return false;
- }
- if ((flags & Notification.FLAG_FOREGROUND_SERVICE) != 0) {
- return false;
- }
- return true;
- }
-
- public void register(ExpandableNotificationRow row, StatusBarNotification sbn) {
- Notification notification = sbn.getNotification();
- if (notification.contentIntent != null || notification.fullScreenIntent != null) {
- row.setOnClickListener(this);
- } else {
- row.setOnClickListener(null);
- }
- }
- }
-
- public void animateCollapsePanels(int flags, boolean force) {
- }
-
- public void animateCollapsePanels(int flags, boolean force, boolean delayed) {
- }
-
- protected boolean startWorkChallengeIfNecessary(int userId, IntentSender intendSender,
- String notificationKey) {
- final Intent newIntent = mKeyguardManager.createConfirmDeviceCredentialIntent(null,
- null, userId);
- if (newIntent == null) {
- return false;
- }
- final Intent callBackIntent = new Intent(NOTIFICATION_UNLOCKED_BY_WORK_CHALLENGE_ACTION);
- callBackIntent.putExtra(Intent.EXTRA_INTENT, intendSender);
- callBackIntent.putExtra(Intent.EXTRA_INDEX, notificationKey);
- callBackIntent.setPackage(mContext.getPackageName());
-
- PendingIntent callBackPendingIntent = PendingIntent.getBroadcast(
- mContext,
- 0,
- callBackIntent,
- PendingIntent.FLAG_CANCEL_CURRENT |
- PendingIntent.FLAG_ONE_SHOT |
- PendingIntent.FLAG_IMMUTABLE);
- newIntent.putExtra(
- Intent.EXTRA_INTENT,
- callBackPendingIntent.getIntentSender());
- try {
- ActivityManager.getService().startConfirmDeviceCredentialIntent(newIntent,
- null /*options*/);
- } catch (RemoteException ex) {
- // ignore
- }
- return true;
- }
-
- protected Bundle getActivityOptions() {
- // Anything launched from the notification shade should always go into the
- // fullscreen stack.
- ActivityOptions options = ActivityOptions.makeBasic();
- options.setLaunchStackId(StackId.FULLSCREEN_WORKSPACE_STACK_ID);
- return options.toBundle();
- }
-
- protected void visibilityChanged(boolean visible) {
- if (mVisible != visible) {
- mVisible = visible;
- if (!visible) {
- dismissPopups();
- }
- }
- updateVisibleToUser();
- }
-
- protected void updateVisibleToUser() {
- boolean oldVisibleToUser = mVisibleToUser;
- mVisibleToUser = mVisible && mDeviceInteractive;
-
- if (oldVisibleToUser != mVisibleToUser) {
- handleVisibleToUserChanged(mVisibleToUser);
- }
- }
-
- /**
- * The LEDs are turned off when the notification panel is shown, even just a little bit.
- * See also PhoneStatusBar.setPanelExpanded for another place where we attempt to do this.
- */
- protected void handleVisibleToUserChanged(boolean visibleToUser) {
- try {
- if (visibleToUser) {
- boolean pinnedHeadsUp = mHeadsUpManager.hasPinnedHeadsUp();
- boolean clearNotificationEffects =
- !isPanelFullyCollapsed() &&
- (mState == StatusBarState.SHADE || mState == StatusBarState.SHADE_LOCKED);
- int notificationLoad = mNotificationData.getActiveNotifications().size();
- if (pinnedHeadsUp && isPanelFullyCollapsed()) {
- notificationLoad = 1;
- } else {
- MetricsLogger.histogram(mContext, "note_load", notificationLoad);
- }
- mBarService.onPanelRevealed(clearNotificationEffects, notificationLoad);
- } else {
- mBarService.onPanelHidden();
- }
- } catch (RemoteException ex) {
- // Won't fail unless the world has ended.
- }
- }
-
- /**
- * Clear Buzz/Beep/Blink.
- */
- public void clearNotificationEffects() {
- try {
- mBarService.clearNotificationEffects();
- } catch (RemoteException e) {
- // Won't fail unless the world has ended.
- }
- }
-
- public abstract boolean isPanelFullyCollapsed();
-
- /**
- * Cancel this notification and tell the StatusBarManagerService / NotificationManagerService
- * about the failure.
- *
- * WARNING: this will call back into us. Don't hold any locks.
- */
- void handleNotificationError(StatusBarNotification n, String message) {
- removeNotification(n.getKey(), null);
- try {
- mBarService.onNotificationError(n.getPackageName(), n.getTag(), n.getId(), n.getUid(),
- n.getInitialPid(), message, n.getUserId());
- } catch (RemoteException ex) {
- // The end is nigh.
- }
- }
-
- protected StatusBarNotification removeNotificationViews(String key, RankingMap ranking) {
- NotificationData.Entry entry = mNotificationData.remove(key, ranking);
- if (entry == null) {
- Log.w(TAG, "removeNotification for unknown key: " + key);
- return null;
- }
- updateNotifications();
- return entry.notification;
- }
-
- protected NotificationData.Entry createNotificationViews(StatusBarNotification sbn) {
- if (DEBUG) {
- Log.d(TAG, "createNotificationViews(notification=" + sbn);
- }
- NotificationData.Entry entry = new NotificationData.Entry(sbn);
- try {
- entry.createIcons(mContext, sbn);
- } catch (NotificationData.IconException exception) {
- handleNotificationError(sbn, exception.getMessage());
- }
-
- // Construct the expanded view.
- if (!inflateViews(entry, mStackScroller)) {
- handleNotificationError(sbn, "Couldn't expand RemoteViews for: " + sbn);
- return null;
- }
- return entry;
- }
-
- protected void addNotificationViews(Entry entry, RankingMap ranking) {
- if (entry == null) {
- return;
- }
- // Add the expanded view and icon.
- mNotificationData.add(entry, ranking);
- updateNotifications();
- }
-
- /**
- * @param recompute wheter the number should be recomputed
- * @return The number of notifications we show on Keyguard.
- */
- protected abstract int getMaxKeyguardNotifications(boolean recompute);
-
- /**
- * Updates expanded, dimmed and locked states of notification rows.
- */
- protected void updateRowStates() {
- final int N = mStackScroller.getChildCount();
-
- int visibleNotifications = 0;
- boolean onKeyguard = mState == StatusBarState.KEYGUARD;
- int maxNotifications = -1;
- if (onKeyguard) {
- maxNotifications = getMaxKeyguardNotifications(true /* recompute */);
- }
- mStackScroller.setMaxDisplayedNotifications(maxNotifications);
- Stack<ExpandableNotificationRow> stack = new Stack<>();
- for (int i = N - 1; i >= 0; i--) {
- View child = mStackScroller.getChildAt(i);
- if (!(child instanceof ExpandableNotificationRow)) {
- continue;
- }
- stack.push((ExpandableNotificationRow) child);
- }
- while(!stack.isEmpty()) {
- ExpandableNotificationRow row = stack.pop();
- NotificationData.Entry entry = row.getEntry();
- boolean childNotification = mGroupManager.isChildInGroupWithSummary(entry.notification);
- if (onKeyguard) {
- row.setOnKeyguard(true);
- } else {
- row.setOnKeyguard(false);
- row.setSystemExpanded(visibleNotifications == 0 && !childNotification);
- }
- entry.row.setShowAmbient(isDozing());
- int userId = entry.notification.getUserId();
- boolean suppressedSummary = mGroupManager.isSummaryOfSuppressedGroup(
- entry.notification) && !entry.row.isRemoved();
- boolean showOnKeyguard = shouldShowOnKeyguard(entry.notification);
- if (suppressedSummary
- || (isLockscreenPublicMode(userId) && !mShowLockscreenNotifications)
- || (onKeyguard && !showOnKeyguard)) {
- entry.row.setVisibility(View.GONE);
- } else {
- boolean wasGone = entry.row.getVisibility() == View.GONE;
- if (wasGone) {
- entry.row.setVisibility(View.VISIBLE);
- }
- if (!childNotification && !entry.row.isRemoved()) {
- if (wasGone) {
- // notify the scroller of a child addition
- mStackScroller.generateAddAnimation(entry.row,
- !showOnKeyguard /* fromMoreCard */);
- }
- visibleNotifications++;
- }
- }
- if (row.isSummaryWithChildren()) {
- List<ExpandableNotificationRow> notificationChildren =
- row.getNotificationChildren();
- int size = notificationChildren.size();
- for (int i = size - 1; i >= 0; i--) {
- stack.push(notificationChildren.get(i));
- }
- }
- }
-
- mStackScroller.changeViewPosition(mDismissView, mStackScroller.getChildCount() - 1);
- mStackScroller.changeViewPosition(mEmptyShadeView, mStackScroller.getChildCount() - 2);
- mStackScroller.changeViewPosition(mNotificationShelf, mStackScroller.getChildCount() - 3);
- }
-
- public boolean isDozing() {
- return false;
- }
-
- public boolean shouldShowOnKeyguard(StatusBarNotification sbn) {
- return mShowLockscreenNotifications && !mNotificationData.isAmbient(sbn.getKey());
- }
-
- protected void setZenMode(int mode) {
- if (!isDeviceProvisioned()) return;
- mZenMode = mode;
- updateNotifications();
- }
-
- // extended in PhoneStatusBar
- protected void setShowLockscreenNotifications(boolean show) {
- mShowLockscreenNotifications = show;
- }
-
- protected void setLockScreenAllowRemoteInput(boolean allowLockscreenRemoteInput) {
- mAllowLockscreenRemoteInput = allowLockscreenRemoteInput;
- }
-
- private void updateLockscreenNotificationSetting() {
- final boolean show = Settings.Secure.getIntForUser(mContext.getContentResolver(),
- Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS,
- 1,
- mCurrentUserId) != 0;
- final int dpmFlags = mDevicePolicyManager.getKeyguardDisabledFeatures(
- null /* admin */, mCurrentUserId);
- final boolean allowedByDpm = (dpmFlags
- & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_NOTIFICATIONS) == 0;
-
- setShowLockscreenNotifications(show && allowedByDpm);
-
- if (ENABLE_LOCK_SCREEN_ALLOW_REMOTE_INPUT) {
- final boolean remoteInput = Settings.Secure.getIntForUser(mContext.getContentResolver(),
- Settings.Secure.LOCK_SCREEN_ALLOW_REMOTE_INPUT,
- 0,
- mCurrentUserId) != 0;
- final boolean remoteInputDpm =
- (dpmFlags & DevicePolicyManager.KEYGUARD_DISABLE_REMOTE_INPUT) == 0;
-
- setLockScreenAllowRemoteInput(remoteInput && remoteInputDpm);
- } else {
- setLockScreenAllowRemoteInput(false);
- }
- }
-
- protected abstract void setAreThereNotifications();
- protected abstract void updateNotifications();
-
- public abstract void addNotification(StatusBarNotification notification,
- RankingMap ranking, Entry oldEntry);
- protected abstract void updateNotificationRanking(RankingMap ranking);
- public abstract void removeNotification(String key, RankingMap ranking);
-
- public void updateNotification(StatusBarNotification notification, RankingMap ranking) {
- if (DEBUG) Log.d(TAG, "updateNotification(" + notification + ")");
-
- final String key = notification.getKey();
- Entry entry = mNotificationData.get(key);
- if (entry == null) {
- return;
- } else {
- mHeadsUpEntriesToRemoveOnSwitch.remove(entry);
- mRemoteInputEntriesToRemoveOnCollapse.remove(entry);
- }
-
- Notification n = notification.getNotification();
- mNotificationData.updateRanking(ranking);
-
- boolean applyInPlace;
- try {
- applyInPlace = entry.cacheContentViews(mContext, notification.getNotification(),
- mNotificationData.isAmbient(key));
- } catch (RuntimeException e) {
- Log.e(TAG, "Unable to get notification remote views", e);
- applyInPlace = false;
- }
- boolean shouldPeek = shouldPeek(entry, notification);
- boolean alertAgain = alertAgain(entry, n);
- if (DEBUG) {
- Log.d(TAG, "applyInPlace=" + applyInPlace
- + " shouldPeek=" + shouldPeek
- + " alertAgain=" + alertAgain);
- }
-
- final StatusBarNotification oldNotification = entry.notification;
- entry.notification = notification;
- mGroupManager.onEntryUpdated(entry, oldNotification);
-
- boolean updateSuccessful = false;
- try {
- if (applyInPlace) {
- if (DEBUG) Log.d(TAG, "reusing notification for key: " + key);
- try {
- entry.updateIcons(mContext, n);
- updateNotificationViews(entry, notification);
- updateSuccessful = true;
- } catch (RuntimeException e) {
- // It failed to apply cleanly.
- Log.w(TAG, "Couldn't reapply views for package " +
- notification.getPackageName(), e);
- }
- }
- if (!updateSuccessful) {
- entry.updateIcons(mContext, n);
- if (!inflateViews(entry, mStackScroller)) {
- handleNotificationError(notification, "Couldn't update remote views for: "
- + notification);
- }
- }
- } catch (NotificationData.IconException e) {
- handleNotificationError(notification, e.getMessage());
- }
- updateHeadsUp(key, entry, shouldPeek, alertAgain);
- updateNotifications();
-
- if (!notification.isClearable()) {
- // The user may have performed a dismiss action on the notification, since it's
- // not clearable we should snap it back.
- mStackScroller.snapViewIfNeeded(entry.row);
- }
-
- if (DEBUG) {
- // Is this for you?
- boolean isForCurrentUser = isNotificationForCurrentProfiles(notification);
- Log.d(TAG, "notification is " + (isForCurrentUser ? "" : "not ") + "for you");
- }
-
- setAreThereNotifications();
- }
-
- protected abstract void updateHeadsUp(String key, Entry entry, boolean shouldPeek,
- boolean alertAgain);
-
- private void updateNotificationViews(Entry entry, StatusBarNotification sbn) {
- final RemoteViews contentView = entry.cachedContentView;
- final RemoteViews bigContentView = entry.cachedBigContentView;
- final RemoteViews headsUpContentView = entry.cachedHeadsUpContentView;
- final RemoteViews publicContentView = entry.cachedPublicContentView;
-
- // Reapply the RemoteViews
- contentView.reapply(mContext, entry.getContentView(), mOnClickHandler);
- if (bigContentView != null && entry.getExpandedContentView() != null) {
- bigContentView.reapply(sbn.getPackageContext(mContext),
- entry.getExpandedContentView(),
- mOnClickHandler);
- }
- View headsUpChild = entry.getHeadsUpContentView();
- if (headsUpContentView != null && headsUpChild != null) {
- headsUpContentView.reapply(sbn.getPackageContext(mContext),
- headsUpChild, mOnClickHandler);
- }
- if (publicContentView != null && entry.getPublicContentView() != null) {
- publicContentView.reapply(sbn.getPackageContext(mContext),
- entry.getPublicContentView(), mOnClickHandler);
- }
- // update the contentIntent
- mNotificationClicker.register(entry.row, sbn);
-
- entry.row.onNotificationUpdated(entry);
- entry.row.resetHeight();
- }
-
- protected void updatePublicContentView(Entry entry,
- StatusBarNotification sbn) {
- final RemoteViews publicContentView = entry.cachedPublicContentView;
- View inflatedView = entry.getPublicContentView();
- if (entry.autoRedacted && publicContentView != null && inflatedView != null) {
- final boolean disabledByPolicy =
- !adminAllowsUnredactedNotifications(entry.notification.getUserId());
- String notificationHiddenText = mContext.getString(disabledByPolicy
- ? com.android.internal.R.string.notification_hidden_by_policy_text
- : com.android.internal.R.string.notification_hidden_text);
- TextView titleView = (TextView) inflatedView.findViewById(android.R.id.title);
- if (titleView != null
- && !titleView.getText().toString().equals(notificationHiddenText)) {
- publicContentView.setTextViewText(android.R.id.title, notificationHiddenText);
- publicContentView.reapply(sbn.getPackageContext(mContext),
- inflatedView, mOnClickHandler);
- entry.row.onNotificationUpdated(entry);
- }
- }
- }
-
- protected void notifyHeadsUpScreenOff() {
- maybeEscalateHeadsUp();
- }
-
- private boolean alertAgain(Entry oldEntry, Notification newNotification) {
- return oldEntry == null || !oldEntry.hasInterrupted()
- || (newNotification.flags & Notification.FLAG_ONLY_ALERT_ONCE) == 0;
- }
-
- protected boolean shouldPeek(Entry entry) {
- return shouldPeek(entry, entry.notification);
- }
-
- protected boolean shouldPeek(Entry entry, StatusBarNotification sbn) {
- if (!mUseHeadsUp || isDeviceInVrMode()) {
- return false;
- }
-
- if (mNotificationData.shouldFilterOut(sbn)) {
- if (DEBUG) Log.d(TAG, "No peeking: filtered notification: " + sbn.getKey());
- return false;
- }
-
- boolean inUse = mPowerManager.isScreenOn();
- try {
- inUse = inUse && !mDreamManager.isDreaming();
- } catch (RemoteException e) {
- Log.d(TAG, "failed to query dream manager", e);
- }
-
- if (!inUse && !isDozing()) {
- if (DEBUG) {
- Log.d(TAG, "No peeking: not in use: " + sbn.getKey());
- }
- return false;
- }
-
- if (mNotificationData.shouldSuppressScreenOn(sbn.getKey())) {
- if (DEBUG) Log.d(TAG, "No peeking: suppressed by DND: " + sbn.getKey());
- return false;
- }
-
- if (entry.hasJustLaunchedFullScreenIntent()) {
- if (DEBUG) Log.d(TAG, "No peeking: recent fullscreen: " + sbn.getKey());
- return false;
- }
-
- if (isSnoozedPackage(sbn)) {
- if (DEBUG) Log.d(TAG, "No peeking: snoozed package: " + sbn.getKey());
- return false;
- }
-
- if (mNotificationData.getImportance(sbn.getKey()) < NotificationManager.IMPORTANCE_HIGH) {
- if (DEBUG) Log.d(TAG, "No peeking: unimportant notification: " + sbn.getKey());
- return false;
- }
-
- if (sbn.getNotification().fullScreenIntent != null) {
- if (mAccessibilityManager.isTouchExplorationEnabled()) {
- if (DEBUG) Log.d(TAG, "No peeking: accessible fullscreen: " + sbn.getKey());
- return false;
- } else {
- // we only allow head-up on the lockscreen if it doesn't have a fullscreen intent
- return !mStatusBarKeyguardViewManager.isShowing()
- || mStatusBarKeyguardViewManager.isOccluded();
- }
- }
-
- return true;
- }
-
- protected abstract boolean isSnoozedPackage(StatusBarNotification sbn);
-
- public void setInteracting(int barWindow, boolean interacting) {
- // hook for subclasses
- }
-
- public void setBouncerShowing(boolean bouncerShowing) {
- mBouncerShowing = bouncerShowing;
- }
-
- /**
- * @return Whether the security bouncer from Keyguard is showing.
- */
- public boolean isBouncerShowing() {
- return mBouncerShowing;
- }
-
- public void destroy() {
- mContext.unregisterReceiver(mBroadcastReceiver);
- try {
- mNotificationListener.unregisterAsSystemService();
- } catch (RemoteException e) {
- // Ignore.
- }
- mDeviceProvisionedController.removeCallback(mDeviceProvisionedListener);
- }
-
- /**
- * @return a PackageManger for userId or if userId is < 0 (USER_ALL etc) then
- * return PackageManager for mContext
- */
- public static PackageManager getPackageManagerForUser(Context context, int userId) {
- Context contextForUser = context;
- // UserHandle defines special userId as negative values, e.g. USER_ALL
- if (userId >= 0) {
- try {
- // Create a context for the correct user so if a package isn't installed
- // for user 0 we can still load information about the package.
- contextForUser =
- context.createPackageContextAsUser(context.getPackageName(),
- Context.CONTEXT_RESTRICTED,
- new UserHandle(userId));
- } catch (NameNotFoundException e) {
- // Shouldn't fail to find the package name for system ui.
- }
- }
- return contextForUser.getPackageManager();
- }
-
- @Override
- public void logNotificationExpansion(String key, boolean userAction, boolean expanded) {
- try {
- mBarService.onNotificationExpansionChanged(key, userAction, expanded);
- } catch (RemoteException e) {
- // Ignore.
- }
- }
-
- public boolean isKeyguardSecure() {
- if (mStatusBarKeyguardViewManager == null) {
- // startKeyguard() hasn't been called yet, so we don't know.
- // Make sure anything that needs to know isKeyguardSecure() checks and re-checks this
- // value onVisibilityChanged().
- Slog.w(TAG, "isKeyguardSecure() called before startKeyguard(), returning false",
- new Throwable());
- return false;
- }
- return mStatusBarKeyguardViewManager.isSecure();
- }
-
- @Override
- public void showAssistDisclosure() {
- if (mAssistManager != null) {
- mAssistManager.showDisclosure();
- }
- }
-
- @Override
- public void startAssist(Bundle args) {
- if (mAssistManager != null) {
- mAssistManager.startAssist(args);
- }
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index 9177f4b..d1245b1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -56,6 +56,7 @@
import com.android.systemui.statusbar.notification.NotificationUtils;
import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
+import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.statusbar.stack.AnimationProperties;
import com.android.systemui.statusbar.stack.ExpandableViewState;
@@ -436,7 +437,7 @@
* @param parent the new parent notification
*/
public void setIsChildInGroup(boolean isChildInGroup, ExpandableNotificationRow parent) {;
- boolean childInGroup = BaseStatusBar.ENABLE_CHILD_NOTIFICATIONS && isChildInGroup;
+ boolean childInGroup = StatusBar.ENABLE_CHILD_NOTIFICATIONS && isChildInGroup;
mNotificationParent = childInGroup ? parent : null;
mPrivateLayout.setIsChildInGroup(childInGroup);
resetBackgroundAlpha();
@@ -1420,7 +1421,7 @@
}
private void onChildrenCountChanged() {
- mIsSummaryWithChildren = BaseStatusBar.ENABLE_CHILD_NOTIFICATIONS
+ mIsSummaryWithChildren = StatusBar.ENABLE_CHILD_NOTIFICATIONS
&& mChildrenContainer != null && mChildrenContainer.getNotificationChildCount() > 0;
if (mIsSummaryWithChildren && mChildrenContainer.getHeaderView() == null) {
mChildrenContainer.recreateNotificationHeader(mExpandClickListener,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
index e48c20e..bbfcf31 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
@@ -35,6 +35,7 @@
import com.android.internal.statusbar.StatusBarIcon;
import com.android.internal.util.NotificationColorUtil;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
+import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.policy.HeadsUpManager;
import java.io.PrintWriter;
@@ -518,7 +519,7 @@
Collections.sort(mSortedAndFiltered, mRankingComparator);
}
- boolean shouldFilterOut(StatusBarNotification sbn) {
+ public boolean shouldFilterOut(StatusBarNotification sbn) {
if (!(mEnvironment.isDeviceProvisioned() ||
showNotificationEvenIfUnprovisioned(sbn))) {
return true;
@@ -535,7 +536,7 @@
return true;
}
- if (!BaseStatusBar.ENABLE_CHILD_NOTIFICATIONS
+ if (!StatusBar.ENABLE_CHILD_NOTIFICATIONS
&& mGroupManager.isChildInGroupWithSummary(sbn)) {
return true;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
index 0989846..bdbc9b3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
@@ -91,11 +91,12 @@
super(context, attrs);
}
- interface OnSettingsClickListener {
+ public interface OnSettingsClickListener {
void onClick(View v, int appUid);
}
- void bindNotification(final PackageManager pm, final INotificationManager iNotificationManager,
+ public void bindNotification(final PackageManager pm,
+ final INotificationManager iNotificationManager,
final StatusBarNotification sbn, final NotificationChannel channel,
OnSettingsClickListener onSettingsClick,
OnClickListener onDoneClick, final Set<String> nonBlockablePkgs) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
index f24e40b..f6a5687 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
@@ -39,7 +39,7 @@
import com.android.systemui.recents.misc.SystemServicesProxy;
import com.android.systemui.recents.misc.SystemServicesProxy.TaskStackListener;
import com.android.systemui.statusbar.StatusBarState;
-import com.android.systemui.statusbar.phone.PhoneStatusBar;
+import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.PhoneStatusBarView;
import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.UserSwitcherController;
@@ -47,7 +47,7 @@
/**
* A status bar (and navigation bar) tailored for the automotive use case.
*/
-public class CarStatusBar extends PhoneStatusBar implements
+public class CarStatusBar extends StatusBar implements
CarBatteryController.BatteryViewHandler {
private static final String TAG = "CarStatusBar";
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/ConnectedDeviceSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/ConnectedDeviceSignalController.java
index c308930..67f8426 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/ConnectedDeviceSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/ConnectedDeviceSignalController.java
@@ -20,7 +20,7 @@
import com.android.systemui.statusbar.ScalingDrawableWrapper;
import com.android.systemui.statusbar.policy.BluetoothController;
-import static com.android.systemui.statusbar.phone.PhoneStatusBar.DEBUG;
+import static com.android.systemui.statusbar.phone.StatusBar.DEBUG;
/**
* Controller that monitors signal strength for a device that is connected via bluetooth.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java
index 8e6c153..f8b6dee 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java
@@ -20,7 +20,7 @@
import android.view.ViewStub;
import com.android.systemui.R;
-import com.android.systemui.statusbar.phone.PhoneStatusBar;
+import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.policy.UserSwitcherController;
/**
@@ -32,7 +32,7 @@
private UserGridView mUserGridView;
private UserSwitcherController mUserSwitcherController;
- public FullscreenUserSwitcher(PhoneStatusBar statusBar,
+ public FullscreenUserSwitcher(StatusBar statusBar,
UserSwitcherController userSwitcherController,
ViewStub containerStub) {
mUserSwitcherController = userSwitcherController;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridView.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridView.java
index d90a21d..137b5cf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/UserGridView.java
@@ -29,12 +29,12 @@
import com.android.systemui.R;
import com.android.systemui.statusbar.UserUtil;
-import com.android.systemui.statusbar.phone.PhoneStatusBar;
+import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.policy.UserSwitcherController;
public class UserGridView extends GridView {
- private PhoneStatusBar mStatusBar;
+ private StatusBar mStatusBar;
private UserSwitcherController mUserSwitcherController;
private Adapter mAdapter;
private int mPendingUserId = UserHandle.USER_NULL;
@@ -43,7 +43,7 @@
super(context, attrs);
}
- public void init(PhoneStatusBar statusBar, UserSwitcherController userSwitcherController) {
+ public void init(StatusBar statusBar, UserSwitcherController userSwitcherController) {
mStatusBar = statusBar;
mUserSwitcherController = userSwitcherController;
mAdapter = new Adapter(mUserSwitcherController);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java
index 42d9433..0773108 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java
@@ -16,11 +16,7 @@
package com.android.systemui.statusbar.phone;
-import android.content.BroadcastReceiver;
import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.Build;
import android.os.Handler;
import android.os.PowerManager;
import android.os.SystemClock;
@@ -98,7 +94,7 @@
private DozeScrimController mDozeScrimController;
private KeyguardViewMediator mKeyguardViewMediator;
private ScrimController mScrimController;
- private PhoneStatusBar mPhoneStatusBar;
+ private StatusBar mStatusBar;
private final UnlockMethodCache mUnlockMethodCache;
private final Context mContext;
private boolean mGoingToSleep;
@@ -109,7 +105,7 @@
DozeScrimController dozeScrimController,
KeyguardViewMediator keyguardViewMediator,
ScrimController scrimController,
- PhoneStatusBar phoneStatusBar,
+ StatusBar statusBar,
UnlockMethodCache unlockMethodCache) {
mContext = context;
mPowerManager = context.getSystemService(PowerManager.class);
@@ -119,7 +115,7 @@
mDozeScrimController = dozeScrimController;
mKeyguardViewMediator = keyguardViewMediator;
mScrimController = scrimController;
- mPhoneStatusBar = phoneStatusBar;
+ mStatusBar = statusBar;
mUnlockMethodCache = unlockMethodCache;
}
@@ -218,7 +214,7 @@
break;
case MODE_WAKE_AND_UNLOCK_PULSING:
Trace.beginSection("MODE_WAKE_AND_UNLOCK_PULSING");
- mPhoneStatusBar.updateMediaMetaData(false /* metaDataChanged */,
+ mStatusBar.updateMediaMetaData(false /* metaDataChanged */,
true /* allowEnterAnimation */);
// Fall through.
Trace.endSection();
@@ -228,8 +224,8 @@
mDozeScrimController.abortPulsing();
mKeyguardViewMediator.onWakeAndUnlocking();
mScrimController.setWakeAndUnlocking();
- if (mPhoneStatusBar.getNavigationBarView() != null) {
- mPhoneStatusBar.getNavigationBarView().setWakeAndUnlocking(true);
+ if (mStatusBar.getNavigationBarView() != null) {
+ mStatusBar.getNavigationBarView().setWakeAndUnlocking(true);
}
Trace.endSection();
break;
@@ -240,7 +236,7 @@
if (mMode != MODE_WAKE_AND_UNLOCK_PULSING) {
mStatusBarWindowManager.setForceDozeBrightness(false);
}
- mPhoneStatusBar.notifyFpAuthModeChanged();
+ mStatusBar.notifyFpAuthModeChanged();
Trace.endSection();
}
@@ -309,7 +305,7 @@
mMode = MODE_NONE;
releaseFingerprintWakeLock();
mStatusBarWindowManager.setForceDozeBrightness(false);
- mPhoneStatusBar.notifyFpAuthModeChanged();
+ mStatusBar.notifyFpAuthModeChanged();
}
public void startKeyguardFadingAway() {
@@ -320,14 +316,14 @@
public void run() {
mStatusBarWindowManager.setForceDozeBrightness(false);
}
- }, PhoneStatusBar.FADE_KEYGUARD_DURATION_PULSING);
+ }, StatusBar.FADE_KEYGUARD_DURATION_PULSING);
}
public void finishKeyguardFadingAway() {
mMode = MODE_NONE;
- if (mPhoneStatusBar.getNavigationBarView() != null) {
- mPhoneStatusBar.getNavigationBarView().setWakeAndUnlocking(false);
+ if (mStatusBar.getNavigationBarView() != null) {
+ mStatusBar.getNavigationBarView().setWakeAndUnlocking(false);
}
- mPhoneStatusBar.notifyFpAuthModeChanged();
+ mStatusBar.notifyFpAuthModeChanged();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index 7dcf811..6c71d7f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -18,9 +18,8 @@
import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLICK;
import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
-import static com.android.systemui.tuner.LockscreenFragment.LOCKSCREEN_LEFT_BUTTON;
+
import static com.android.systemui.tuner.LockscreenFragment.LOCKSCREEN_LEFT_UNLOCK;
-import static com.android.systemui.tuner.LockscreenFragment.LOCKSCREEN_RIGHT_BUTTON;
import static com.android.systemui.tuner.LockscreenFragment.LOCKSCREEN_RIGHT_UNLOCK;
import static com.android.systemui.tuner.LockscreenFragment.getIntentButton;
@@ -36,9 +35,7 @@
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
-import android.content.res.ColorStateList;
import android.content.res.Configuration;
-import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Bundle;
@@ -95,7 +92,7 @@
AccessibilityController.AccessibilityStateChangedCallback, View.OnLongClickListener,
Tunable {
- final static String TAG = "PhoneStatusBar/KeyguardBottomAreaView";
+ final static String TAG = "StatusBar/KeyguardBottomAreaView";
public static final String CAMERA_LAUNCH_SOURCE_AFFORDANCE = "lockscreen_affordance";
public static final String CAMERA_LAUNCH_SOURCE_WIGGLE = "wiggle_gesture";
@@ -136,7 +133,7 @@
private PreviewInflater mPreviewInflater;
private KeyguardIndicationController mIndicationController;
private AccessibilityController mAccessibilityController;
- private PhoneStatusBar mPhoneStatusBar;
+ private StatusBar mStatusBar;
private KeyguardAffordanceHelper mAffordanceHelper;
private boolean mUserSetupComplete;
@@ -208,7 +205,7 @@
public boolean performAccessibilityAction(View host, int action, Bundle args) {
if (action == ACTION_CLICK) {
if (host == mLockIcon) {
- mPhoneStatusBar.animateCollapsePanels(
+ mStatusBar.animateCollapsePanels(
CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL, true /* force */);
return true;
} else if (host == mRightAffordanceView) {
@@ -326,8 +323,8 @@
mRightAffordanceView.setContentDescription(state.contentDescription);
}
- public void setPhoneStatusBar(PhoneStatusBar phoneStatusBar) {
- mPhoneStatusBar = phoneStatusBar;
+ public void setStatusBar(StatusBar statusBar) {
+ mStatusBar = statusBar;
updateCameraVisibility(); // in case onFinishInflate() was called too early
}
@@ -391,13 +388,13 @@
private boolean isCameraDisabledByDpm() {
final DevicePolicyManager dpm =
(DevicePolicyManager) getContext().getSystemService(Context.DEVICE_POLICY_SERVICE);
- if (dpm != null && mPhoneStatusBar != null) {
+ if (dpm != null && mStatusBar != null) {
try {
final int userId = ActivityManager.getService().getCurrentUser().id;
final int disabledFlags = dpm.getKeyguardDisabledFeatures(null, userId);
final boolean disabledBecauseKeyguardSecure =
(disabledFlags & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) != 0
- && mPhoneStatusBar.isKeyguardSecure();
+ && mStatusBar.isKeyguardSecure();
return dpm.getCameraDisabled(null) || disabledBecauseKeyguardSecure;
} catch (RemoteException e) {
Log.e(TAG, "Can't get userId", e);
@@ -433,7 +430,7 @@
if (!mAccessibilityController.isAccessibilityEnabled()) {
handleTrustCircleClick();
} else {
- mPhoneStatusBar.animateCollapsePanels(
+ mStatusBar.animateCollapsePanels(
CommandQueue.FLAG_EXCLUDE_NONE, true /* force */);
}
}
@@ -570,12 +567,12 @@
mAssistManager.launchVoiceAssistFromKeyguard();
}
};
- if (mPhoneStatusBar.isKeyguardCurrentlySecure()) {
+ if (mStatusBar.isKeyguardCurrentlySecure()) {
AsyncTask.execute(runnable);
} else {
boolean dismissShade = !TextUtils.isEmpty(mRightButtonStr)
&& TunerService.get(getContext()).getValue(LOCKSCREEN_RIGHT_UNLOCK, 1) != 0;
- mPhoneStatusBar.executeRunnableDismissingKeyguard(runnable, null /* cancelAction */,
+ mStatusBar.executeRunnableDismissingKeyguard(runnable, null /* cancelAction */,
dismissShade, false /* afterKeyguardGone */, true /* deferred */);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java
index af6e259..99b3aa8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java
@@ -51,7 +51,7 @@
private static final String TAG = "LockscreenWallpaper";
- private final PhoneStatusBar mBar;
+ private final StatusBar mBar;
private final WallpaperManager mWallpaperManager;
private final Handler mH;
private final KeyguardUpdateMonitor mUpdateMonitor;
@@ -64,7 +64,7 @@
private UserHandle mSelectedUser;
private AsyncTask<Void, Void, LoaderResult> mLoader;
- public LockscreenWallpaper(Context ctx, PhoneStatusBar bar, Handler h) {
+ public LockscreenWallpaper(Context ctx, StatusBar bar, Handler h) {
mBar = bar;
mH = h;
mWallpaperManager = (WallpaperManager) ctx.getSystemService(Context.WALLPAPER_SERVICE);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
index d40326a..62b536e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
@@ -20,8 +20,8 @@
import static android.app.StatusBarManager.windowStateToString;
import static com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT;
-import static com.android.systemui.statusbar.phone.PhoneStatusBar.DEBUG_WINDOW_STATE;
-import static com.android.systemui.statusbar.phone.PhoneStatusBar.dumpBarTransitions;
+import static com.android.systemui.statusbar.phone.StatusBar.DEBUG_WINDOW_STATE;
+import static com.android.systemui.statusbar.phone.StatusBar.dumpBarTransitions;
import android.annotation.Nullable;
import android.app.ActivityManager;
@@ -67,7 +67,6 @@
import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.SysUiServiceProvider;
-import com.android.systemui.SystemUIApplication;
import com.android.systemui.assist.AssistManager;
import com.android.systemui.fragments.FragmentHostManager;
import com.android.systemui.fragments.FragmentHostManager.FragmentListener;
@@ -105,7 +104,7 @@
protected AccessibilityManager mAccessibilityManager;
private int mDisabledFlags1;
- private PhoneStatusBar mPhoneStatusBar;
+ private StatusBar mStatusBar;
private Recents mRecents;
private Divider mDivider;
private WindowManager mWindowManager;
@@ -128,7 +127,7 @@
super.onCreate(savedInstanceState);
mCommandQueue = SysUiServiceProvider.getComponent(getContext(), CommandQueue.class);
mCommandQueue.addCallbacks(this);
- mPhoneStatusBar = SysUiServiceProvider.getComponent(getContext(), PhoneStatusBar.class);
+ mStatusBar = SysUiServiceProvider.getComponent(getContext(), StatusBar.class);
mRecents = SysUiServiceProvider.getComponent(getContext(), Recents.class);
mDivider = SysUiServiceProvider.getComponent(getContext(), Divider.class);
mWindowManager = getContext().getSystemService(WindowManager.class);
@@ -262,7 +261,7 @@
if (mNavigationBarView != null) {
mNavigationBarView.setNavigationIconHints(hints);
}
- mPhoneStatusBar.checkBarModes();
+ mStatusBar.checkBarModes();
}
@Override
@@ -300,21 +299,21 @@
/**
* Calls appTransitionStarting for the nav bar regardless of whether keyguard is going away.
- * public so PhoneStatusBar can force this when needed.
+ * public so StatusBar can force this when needed.
*/
public void doAppTransitionStarting(long startTime, long duration) {
mNavigationBarView.getLightTransitionsController().appTransitionStarting(startTime,
duration);
}
- // Injected from PhoneStatusBar at creation.
+ // Injected from StatusBar at creation.
public void setCurrentSysuiVisibility(int systemUiVisibility) {
mSystemUiVisibility = systemUiVisibility;
- mNavigationBarMode = mPhoneStatusBar.computeBarMode(0, mSystemUiVisibility,
+ mNavigationBarMode = mStatusBar.computeBarMode(0, mSystemUiVisibility,
View.NAVIGATION_BAR_TRANSIENT, View.NAVIGATION_BAR_TRANSLUCENT,
View.NAVIGATION_BAR_TRANSPARENT);
checkNavBarModes();
- mPhoneStatusBar.touchAutoHide();
+ mStatusBar.touchAutoHide();
mLightBarController.onNavigationVisibilityChanged(mSystemUiVisibility, 0 /* mask */,
true /* nbModeChanged */, mNavigationBarMode);
}
@@ -331,7 +330,7 @@
// update navigation bar mode
final int nbMode = getView() == null
- ? -1 : mPhoneStatusBar.computeBarMode(oldVal, newVal,
+ ? -1 : mStatusBar.computeBarMode(oldVal, newVal,
View.NAVIGATION_BAR_TRANSIENT, View.NAVIGATION_BAR_TRANSLUCENT,
View.NAVIGATION_BAR_TRANSPARENT);
nbModeChanged = nbMode != -1;
@@ -340,7 +339,7 @@
mNavigationBarMode = nbMode;
checkNavBarModes();
}
- mPhoneStatusBar.touchAutoHide();
+ mStatusBar.touchAutoHide();
}
}
@@ -370,7 +369,7 @@
}
private boolean shouldDisableNavbarGestures() {
- return !mPhoneStatusBar.isDeviceProvisioned()
+ return !mStatusBar.isDeviceProvisioned()
|| (mDisabledFlags1 & StatusBarManager.DISABLE_SEARCH) != 0;
}
@@ -418,7 +417,7 @@
TelecomManager telecomManager =
getContext().getSystemService(TelecomManager.class);
if (telecomManager != null && telecomManager.isRinging()) {
- if (mPhoneStatusBar.isKeyguardShowing()) {
+ if (mStatusBar.isKeyguardShowing()) {
Log.i(TAG, "Ignoring HOME; there's a ringing incoming call. " +
"No heads up");
mHomeBlockedThisTouch = true;
@@ -428,18 +427,18 @@
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
- mPhoneStatusBar.awakenDreams();
+ mStatusBar.awakenDreams();
break;
}
return false;
}
private void onVerticalChanged(boolean isVertical) {
- mPhoneStatusBar.setQsScrimEnabled(!isVertical);
+ mStatusBar.setQsScrimEnabled(!isVertical);
}
private boolean onNavigationTouch(View v, MotionEvent event) {
- mPhoneStatusBar.checkUserAutohide(v, event);
+ mStatusBar.checkUserAutohide(v, event);
return false;
}
@@ -450,7 +449,7 @@
}
MetricsLogger.action(getContext(), MetricsEvent.ACTION_ASSIST_LONG_PRESS);
mAssistManager.startAssist(new Bundle() /* args */);
- mPhoneStatusBar.awakenDreams();
+ mStatusBar.awakenDreams();
if (mNavigationBarView != null) {
mNavigationBarView.abortCurrentGesture();
}
@@ -478,7 +477,7 @@
LatencyTracker.getInstance(getContext()).onActionStart(
LatencyTracker.ACTION_TOGGLE_RECENTS);
}
- mPhoneStatusBar.awakenDreams();
+ mStatusBar.awakenDreams();
mCommandQueue.toggleRecentApps();
}
@@ -550,11 +549,11 @@
return false;
}
- return mPhoneStatusBar.toggleSplitScreenMode(MetricsEvent.ACTION_WINDOW_DOCK_LONGPRESS,
+ return mStatusBar.toggleSplitScreenMode(MetricsEvent.ACTION_WINDOW_DOCK_LONGPRESS,
MetricsEvent.ACTION_WINDOW_UNDOCK_LONGPRESS);
}
- // ----- Methods that PhoneStatusBar talks to (should be minimized) -----
+ // ----- Methods that StatusBar talks to (should be minimized) -----
public void setLightBarController(LightBarController lightBarController) {
mLightBarController = lightBarController;
@@ -584,7 +583,7 @@
}
public void checkNavBarModes() {
- mPhoneStatusBar.checkBarMode(mNavigationBarMode,
+ mStatusBar.checkBarMode(mNavigationBarMode,
mNavigationBarWindowState, mNavigationBarView.getBarTransitions());
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index 2f4f30e..5e988fc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -28,7 +28,6 @@
import android.content.res.Configuration;
import android.graphics.Point;
import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;
import android.os.RemoteException;
@@ -53,7 +52,6 @@
import com.android.systemui.plugins.PluginManager;
import com.android.systemui.plugins.statusbar.phone.NavGesture;
import com.android.systemui.plugins.statusbar.phone.NavGesture.GestureHelper;
-import com.android.systemui.recents.misc.SystemServicesProxy;
import com.android.systemui.stackdivider.Divider;
import com.android.systemui.statusbar.policy.DeadZone;
import com.android.systemui.statusbar.policy.KeyButtonDrawable;
@@ -784,7 +782,7 @@
final Point size = new Point();
mDisplay.getRealSize(size);
- pw.println(String.format(" this: " + PhoneStatusBar.viewInfo(this)
+ pw.println(String.format(" this: " + StatusBar.viewInfo(this)
+ " " + visibilityToString(getVisibility())));
getWindowVisibleDisplayFrame(r);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
index 32b9969..0386398 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
@@ -33,7 +33,7 @@
private int mIconHPadding;
private int mIconTint = Color.WHITE;
- private PhoneStatusBar mPhoneStatusBar;
+ private StatusBar mStatusBar;
protected View mNotificationIconArea;
private NotificationIconContainer mNotificationIcons;
private NotificationIconContainer mShelfIcons;
@@ -41,8 +41,8 @@
private NotificationStackScrollLayout mNotificationScrollLayout;
private Context mContext;
- public NotificationIconAreaController(Context context, PhoneStatusBar phoneStatusBar) {
- mPhoneStatusBar = phoneStatusBar;
+ public NotificationIconAreaController(Context context, StatusBar statusBar) {
+ mStatusBar = statusBar;
mNotificationColorUtil = NotificationColorUtil.getInstance(context);
mContext = context;
@@ -64,11 +64,11 @@
mNotificationIcons = (NotificationIconContainer) mNotificationIconArea.findViewById(
R.id.notificationIcons);
- NotificationShelf shelf = mPhoneStatusBar.getNotificationShelf();
+ NotificationShelf shelf = mStatusBar.getNotificationShelf();
mShelfIcons = shelf.getShelfIcons();
shelf.setCollapsedIcons(mNotificationIcons);
- mNotificationScrollLayout = mPhoneStatusBar.getNotificationScrollLayout();
+ mNotificationScrollLayout = mStatusBar.getNotificationScrollLayout();
}
public void onDensityOrFontScaleChanged(Context context) {
@@ -124,7 +124,7 @@
}
protected int getHeight() {
- return mPhoneStatusBar.getStatusBarHeight();
+ return mStatusBar.getStatusBarHeight();
}
protected boolean shouldShowNotificationIcon(NotificationData.Entry entry,
@@ -133,7 +133,7 @@
&& !NotificationData.showNotificationEvenIfUnprovisioned(entry.notification)) {
return false;
}
- if (!PhoneStatusBar.isTopLevelChild(entry)) {
+ if (!StatusBar.isTopLevelChild(entry)) {
return false;
}
if (entry.row.getVisibility() == View.GONE) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 3bdd5e5..aefb95d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -219,7 +219,7 @@
mFalsingManager = FalsingManager.getInstance(context);
}
- public void setStatusBar(PhoneStatusBar bar) {
+ public void setStatusBar(StatusBar bar) {
mStatusBar = bar;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index 18e394e..5f67468 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -60,7 +60,7 @@
Log.v(TAG, (mViewName != null ? (mViewName + ": ") : "") + String.format(fmt, args));
}
- protected PhoneStatusBar mStatusBar;
+ protected StatusBar mStatusBar;
protected HeadsUpManager mHeadsUpManager;
private float mPeekHeight;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
index c80b3ad..7e08812 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
@@ -30,10 +30,10 @@
public class PhoneStatusBarView extends PanelBar {
private static final String TAG = "PhoneStatusBarView";
- private static final boolean DEBUG = PhoneStatusBar.DEBUG;
+ private static final boolean DEBUG = StatusBar.DEBUG;
private static final boolean DEBUG_GESTURES = false;
- PhoneStatusBar mBar;
+ StatusBar mBar;
boolean mIsFullyOpenedPanel = false;
private final PhoneStatusBarTransitions mBarTransitions;
@@ -59,7 +59,7 @@
return mBarTransitions;
}
- public void setBar(PhoneStatusBar bar) {
+ public void setBar(StatusBar bar) {
mBar = bar;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
index 2f76cb1..dd567e8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
@@ -71,7 +71,7 @@
public static final String TILES_SETTING = Secure.QS_TILES;
private final Context mContext;
- private final PhoneStatusBar mStatusBar;
+ private final StatusBar mStatusBar;
private final LinkedHashMap<String, QSTile<?>> mTiles = new LinkedHashMap<>();
protected final ArrayList<String> mTileSpecs = new ArrayList<>();
private final TileServices mServices;
@@ -81,7 +81,7 @@
private final StatusBarIconController mIconController;
private int mCurrentUser;
- public QSTileHost(Context context, PhoneStatusBar statusBar,
+ public QSTileHost(Context context, StatusBar statusBar,
StatusBarIconController iconController) {
mIconController = iconController;
mContext = context;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
similarity index 65%
rename from packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 6c2e27a..45fd7ec 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -72,9 +72,7 @@
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
-import android.os.HandlerThread;
import android.os.IBinder;
-import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
import android.os.RemoteException;
@@ -127,8 +125,6 @@
import com.android.systemui.Interpolators;
import com.android.systemui.Prefs;
import com.android.systemui.R;
-import com.android.systemui.SysUiServiceProvider;
-import com.android.systemui.SystemUIApplication;
import com.android.systemui.SystemUIFactory;
import com.android.systemui.assist.AssistManager;
import com.android.systemui.classifier.FalsingLog;
@@ -153,7 +149,6 @@
import com.android.systemui.stackdivider.WindowManagerProxy;
import com.android.systemui.statusbar.ActivatableNotificationView;
import com.android.systemui.statusbar.BackDropView;
-import com.android.systemui.statusbar.BaseStatusBar;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.DismissView;
import com.android.systemui.statusbar.DragDownHelper;
@@ -162,9 +157,13 @@
import com.android.systemui.statusbar.GestureRecorder;
import com.android.systemui.statusbar.KeyboardShortcuts;
import com.android.systemui.statusbar.KeyguardIndicationController;
+import com.android.systemui.statusbar.NotificationContentView;
import com.android.systemui.statusbar.NotificationData;
import com.android.systemui.statusbar.NotificationData.Entry;
+import com.android.systemui.statusbar.NotificationGuts;
+import com.android.systemui.statusbar.NotificationInfo;
import com.android.systemui.statusbar.NotificationShelf;
+import com.android.systemui.statusbar.NotificationSnooze;
import com.android.systemui.statusbar.RemoteInputController;
import com.android.systemui.statusbar.ScrimView;
import com.android.systemui.statusbar.SignalClusterView;
@@ -173,7 +172,6 @@
import com.android.systemui.statusbar.phone.UnlockMethodCache.OnUnlockMethodChangedListener;
import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback;
-import com.android.systemui.statusbar.policy.BatteryControllerImpl;
import com.android.systemui.statusbar.policy.BrightnessMirrorController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
@@ -185,11 +183,9 @@
import com.android.systemui.statusbar.policy.NetworkController;
import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
import com.android.systemui.statusbar.policy.PreviewInflater;
-import com.android.systemui.statusbar.policy.SecurityController;
import com.android.systemui.statusbar.policy.UserInfoController;
import com.android.systemui.statusbar.policy.UserInfoControllerImpl;
import com.android.systemui.statusbar.policy.UserSwitcherController;
-import com.android.systemui.statusbar.policy.ZenModeController;
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout.OnChildLocationsChangedListener;
@@ -199,17 +195,102 @@
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
+import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
+import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
+import android.app.ActivityManager.StackId;
+import android.app.INotificationManager;
+import android.app.KeyguardManager;
+import android.app.NotificationChannel;
+import android.app.RemoteInput;
+import android.app.TaskStackBuilder;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.UserInfo;
+import android.os.Build;
+import android.os.Handler;
+import android.service.dreams.DreamService;
+import android.service.dreams.IDreamManager;
+import android.service.notification.NotificationListenerService;
+import android.service.vr.IVrManager;
+import android.service.vr.IVrStateCallbacks;
+import android.text.TextUtils;
+import android.util.Slog;
+import android.util.SparseArray;
+import android.util.SparseBooleanArray;
+import android.view.IWindowManager;
+import android.view.ViewAnimationUtils;
+import android.view.accessibility.AccessibilityManager;
+import android.widget.RemoteViews;
+import android.widget.Toast;
+
+import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
+import com.android.internal.statusbar.IStatusBarService;
+import com.android.internal.widget.LockPatternUtils;
+import com.android.systemui.DejankUtils;
+import com.android.systemui.RecentsComponent;
+import com.android.systemui.SwipeHelper;
+import com.android.systemui.SystemUI;
+import com.android.systemui.plugins.statusbar.NotificationMenuRowProvider.MenuItem;
+import com.android.systemui.plugins.statusbar.NotificationMenuRowProvider.SnoozeGutsContent;
+import com.android.systemui.recents.Recents;
+import com.android.systemui.statusbar.policy.RemoteInputView;
+import com.android.systemui.statusbar.stack.StackStateAnimator;
+import com.android.systemui.util.NotificationChannels;
+
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Set;
+import java.util.Stack;
+
+public class StatusBar extends SystemUI implements DemoMode,
DragDownHelper.DragDownCallback, ActivityStarter, OnUnlockMethodChangedListener,
- OnHeadsUpChangedListener, VisualStabilityManager.Callback, SnoozeListener {
- static final String TAG = "PhoneStatusBar";
- public static final boolean DEBUG = BaseStatusBar.DEBUG;
+ OnHeadsUpChangedListener, VisualStabilityManager.Callback, SnoozeListener,
+ CommandQueue.Callbacks, ActivatableNotificationView.OnActivatedListener,
+ ExpandableNotificationRow.ExpansionLogger, NotificationData.Environment,
+ ExpandableNotificationRow.OnExpandClickListener {
+ public static final boolean MULTIUSER_DEBUG = false;
+
+ public static final boolean ENABLE_REMOTE_INPUT =
+ SystemProperties.getBoolean("debug.enable_remote_input", true);
+ public static final boolean ENABLE_CHILD_NOTIFICATIONS
+ = SystemProperties.getBoolean("debug.child_notifs", true);
+ public static final boolean FORCE_REMOTE_INPUT_HISTORY =
+ SystemProperties.getBoolean("debug.force_remoteinput_history", false);
+ private static boolean ENABLE_LOCK_SCREEN_ALLOW_REMOTE_INPUT = false;
+
+ protected static final int MSG_SHOW_RECENT_APPS = 1019;
+ protected static final int MSG_HIDE_RECENT_APPS = 1020;
+ protected static final int MSG_TOGGLE_RECENTS_APPS = 1021;
+ protected static final int MSG_PRELOAD_RECENT_APPS = 1022;
+ protected static final int MSG_CANCEL_PRELOAD_RECENT_APPS = 1023;
+ protected static final int MSG_SHOW_NEXT_AFFILIATED_TASK = 1024;
+ protected static final int MSG_SHOW_PREV_AFFILIATED_TASK = 1025;
+ protected static final int MSG_TOGGLE_KEYBOARD_SHORTCUTS_MENU = 1026;
+ protected static final int MSG_DISMISS_KEYBOARD_SHORTCUTS_MENU = 1027;
+
+ protected static final boolean ENABLE_HEADS_UP = true;
+ protected static final String SETTING_HEADS_UP_TICKER = "ticker_gets_heads_up";
+
+ private static final String PERMISSION_SELF = "com.android.systemui.permission.SELF";
+
+ // Should match the values in PhoneWindowManager
+ public static final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";
+ public static final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey";
+
+ private static final String BANNER_ACTION_CANCEL =
+ "com.android.systemui.statusbar.banner_action_cancel";
+ private static final String BANNER_ACTION_SETUP =
+ "com.android.systemui.statusbar.banner_action_setup";
+ private static final String NOTIFICATION_UNLOCKED_BY_WORK_CHALLENGE_ACTION
+ = "com.android.systemui.statusbar.work_challenge_unlocked_notification_action";
+ static final String TAG = "StatusBar";
+ public static final boolean DEBUG = false;
public static final boolean SPEW = false;
public static final boolean DUMPTRUCK = true; // extra dumpsys info
public static final boolean DEBUG_GESTURES = false;
@@ -301,6 +382,14 @@
FREEFORM_WINDOW_MANAGEMENT = freeformWindowManagement;
}
+ /**
+ * The {@link StatusBarState} of the status bar.
+ */
+ protected int mState;
+ protected boolean mBouncerShowing;
+ protected boolean mShowLockscreenNotifications;
+ protected boolean mAllowLockscreenRemoteInput;
+
PhoneStatusBarPolicy mIconPolicy;
VolumeComponent mVolumeComponent;
@@ -311,7 +400,6 @@
int mNaturalBarHeight = -1;
- Display mDisplay;
Point mCurrentDisplaySize = new Point();
protected StatusBarWindowView mStatusBarWindow;
@@ -417,6 +505,7 @@
}
};
+ protected H mHandler = createHandler();
final private ContentObserver mHeadsUpObserver = new ContentObserver(mHandler) {
@Override
public void onChange(boolean selfChange) {
@@ -615,7 +704,6 @@
private NetworkController mNetworkController;
private KeyguardMonitorImpl mKeyguardMonitor;
private BatteryController mBatteryController;
- private DeviceProvisionedController mDeviceProvisionedController;
private void recycleAllVisibilityObjects(ArraySet<NotificationVisibility> array) {
final int N = array.size();
@@ -657,16 +745,156 @@
mAssistManager = Dependency.get(AssistManager.class);
mDeviceProvisionedController = Dependency.get(DeviceProvisionedController.class);
- mDisplay = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
- .getDefaultDisplay();
+ mWindowManager = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
+ mDisplay = mWindowManager.getDefaultDisplay();
updateDisplaySize();
mScrimSrcModeEnabled = mContext.getResources().getBoolean(
R.bool.config_status_bar_scrim_behind_use_src);
DateTimeView.setReceiverHandler(Dependency.get(Dependency.TIME_TICK_HANDLER));
- putComponent(PhoneStatusBar.class, this);
+ putComponent(StatusBar.class, this);
- super.start(); // calls createAndAddWindows()
+ // start old BaseStatusBar.start().
+ mWindowManagerService = WindowManagerGlobal.getWindowManagerService();
+ mDevicePolicyManager = (DevicePolicyManager)mContext.getSystemService(
+ Context.DEVICE_POLICY_SERVICE);
+
+ mNotificationData = new NotificationData(this);
+
+ mAccessibilityManager = (AccessibilityManager)
+ mContext.getSystemService(Context.ACCESSIBILITY_SERVICE);
+
+ mDreamManager = IDreamManager.Stub.asInterface(
+ ServiceManager.checkService(DreamService.DREAM_SERVICE));
+ mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+
+ mDeviceProvisionedController = Dependency.get(DeviceProvisionedController.class);
+ mDeviceProvisionedController.addCallback(mDeviceProvisionedListener);
+ mContext.getContentResolver().registerContentObserver(
+ Settings.Global.getUriFor(Settings.Global.ZEN_MODE), false,
+ mSettingsObserver);
+ mContext.getContentResolver().registerContentObserver(
+ Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS), false,
+ mLockscreenSettingsObserver,
+ UserHandle.USER_ALL);
+ if (ENABLE_LOCK_SCREEN_ALLOW_REMOTE_INPUT) {
+ mContext.getContentResolver().registerContentObserver(
+ Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_ALLOW_REMOTE_INPUT),
+ false,
+ mSettingsObserver,
+ UserHandle.USER_ALL);
+ }
+
+ mContext.getContentResolver().registerContentObserver(
+ Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS),
+ true,
+ mLockscreenSettingsObserver,
+ UserHandle.USER_ALL);
+
+ mBarService = IStatusBarService.Stub.asInterface(
+ ServiceManager.getService(Context.STATUS_BAR_SERVICE));
+
+ mRecents = getComponent(Recents.class);
+
+ final Configuration currentConfig = mContext.getResources().getConfiguration();
+ mLocale = currentConfig.locale;
+ mLayoutDirection = TextUtils.getLayoutDirectionFromLocale(mLocale);
+ mFontScale = currentConfig.fontScale;
+ mDensity = currentConfig.densityDpi;
+
+ mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+ mKeyguardManager = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
+ mLockPatternUtils = new LockPatternUtils(mContext);
+
+ // Connect in to the status bar manager service
+ mCommandQueue = getComponent(CommandQueue.class);
+ mCommandQueue.addCallbacks(this);
+
+ int[] switches = new int[9];
+ ArrayList<IBinder> binders = new ArrayList<IBinder>();
+ ArrayList<String> iconSlots = new ArrayList<>();
+ ArrayList<StatusBarIcon> icons = new ArrayList<>();
+ Rect fullscreenStackBounds = new Rect();
+ Rect dockedStackBounds = new Rect();
+ try {
+ mBarService.registerStatusBar(mCommandQueue, iconSlots, icons, switches, binders,
+ fullscreenStackBounds, dockedStackBounds);
+ } catch (RemoteException ex) {
+ // If the system process isn't there we're doomed anyway.
+ }
+
+ createAndAddWindows();
+
+ mSettingsObserver.onChange(false); // set up
+ disable(switches[0], switches[6], false /* animate */);
+ setSystemUiVisibility(switches[1], switches[7], switches[8], 0xffffffff,
+ fullscreenStackBounds, dockedStackBounds);
+ topAppWindowChanged(switches[2] != 0);
+ // StatusBarManagerService has a back up of IME token and it's restored here.
+ setImeWindowStatus(binders.get(0), switches[3], switches[4], switches[5] != 0);
+
+ // Set up the initial icon state
+ int N = iconSlots.size();
+ int viewIndex = 0;
+ for (int i=0; i < N; i++) {
+ setIcon(iconSlots.get(i), icons.get(i));
+ }
+
+ // Set up the initial notification state.
+ try {
+ mNotificationListener.registerAsSystemService(mContext,
+ new ComponentName(mContext.getPackageName(), getClass().getCanonicalName()),
+ UserHandle.USER_ALL);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Unable to register notification listener", e);
+ }
+
+
+ if (DEBUG) {
+ Log.d(TAG, String.format(
+ "init: icons=%d disabled=0x%08x lights=0x%08x menu=0x%08x imeButton=0x%08x",
+ icons.size(),
+ switches[0],
+ switches[1],
+ switches[2],
+ switches[3]
+ ));
+ }
+
+ mCurrentUserId = ActivityManager.getCurrentUser();
+ setHeadsUpUser(mCurrentUserId);
+
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_USER_SWITCHED);
+ filter.addAction(Intent.ACTION_USER_ADDED);
+ filter.addAction(Intent.ACTION_USER_PRESENT);
+ mContext.registerReceiver(mBaseBroadcastReceiver, filter);
+
+ IntentFilter internalFilter = new IntentFilter();
+ internalFilter.addAction(NOTIFICATION_UNLOCKED_BY_WORK_CHALLENGE_ACTION);
+ internalFilter.addAction(BANNER_ACTION_CANCEL);
+ internalFilter.addAction(BANNER_ACTION_SETUP);
+ mContext.registerReceiver(mBaseBroadcastReceiver, internalFilter, PERMISSION_SELF, null);
+
+ IntentFilter allUsersFilter = new IntentFilter();
+ allUsersFilter.addAction(
+ DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
+ allUsersFilter.addAction(Intent.ACTION_DEVICE_LOCKED_CHANGED);
+ mContext.registerReceiverAsUser(mAllUsersReceiver, UserHandle.ALL, allUsersFilter,
+ null, null);
+ updateCurrentProfilesCache();
+
+ IVrManager vrManager = IVrManager.Stub.asInterface(ServiceManager.getService("vrmanager"));
+ try {
+ vrManager.registerListener(mVrStateCallbacks);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Failed to register VR mode state listener: " + e);
+ }
+
+ mNonBlockablePkgs = new HashSet<String>();
+ Collections.addAll(mNonBlockablePkgs, mContext.getResources().getStringArray(
+ com.android.internal.R.array.config_nonBlockableNotificationPackages));
+ // end old BaseStatusBar.start().
mMediaSessionManager
= (MediaSessionManager) mContext.getSystemService(Context.MEDIA_SESSION_SERVICE);
@@ -779,7 +1007,7 @@
mStackScroller = (NotificationStackScrollLayout) mStatusBarWindow.findViewById(
R.id.notification_stack_scroller);
mStackScroller.setLongPressListener(getNotificationLongClicker());
- mStackScroller.setPhoneStatusBar(this);
+ mStackScroller.setStatusBar(this);
mStackScroller.setGroupManager(mGroupManager);
mStackScroller.setHeadsUpManager(mHeadsUpManager);
mGroupManager.setOnGroupChangeListener(mStackScroller);
@@ -863,7 +1091,7 @@
initEmergencyCryptkeeperText();
- mKeyguardBottomArea.setPhoneStatusBar(this);
+ mKeyguardBottomArea.setStatusBar(this);
mKeyguardBottomArea.setUserSetupComplete(mUserSetup);
if (UserManager.get(mContext).isUserSwitcherEnabled()) {
createUserSwitcher();
@@ -1002,9 +1230,21 @@
mNotificationShelf.setStatusBarState(mState);
}
- @Override
protected void onDensityOrFontScaleChanged() {
- super.onDensityOrFontScaleChanged();
+ // start old BaseStatusBar.onDensityOrFontScaleChanged().
+ ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
+ for (int i = 0; i < activeNotifications.size(); i++) {
+ Entry entry = activeNotifications.get(i);
+ boolean exposedGuts = mNotificationGutsExposed != null
+ && entry.row.getGuts() == mNotificationGutsExposed;
+ entry.row.reInflateViews();
+ if (exposedGuts) {
+ mNotificationGutsExposed = entry.row.getGuts();
+ bindGuts(entry.row, mGutsMenuItem);
+ }
+ inflateViews(entry, mStackScroller);
+ }
+ // end old BaseStatusBar.onDensityOrFontScaleChanged().
mScrimController.onDensityOrFontScaleChanged();
mStatusBarView.onDensityOrFontScaleChanged();
if (mBrightnessMirrorController != null) {
@@ -1017,7 +1257,7 @@
inflateEmptyShadeView();
updateEmptyShadeView();
mStatusBarKeyguardViewManager.onDensityOrFontScaleChanged();
- // TODO: Bring these out of PhoneStatusBar.
+ // TODO: Bring these out of StatusBar.
((UserInfoControllerImpl) Dependency.get(UserInfoController.class))
.onDensityOrFontScaleChanged();
Dependency.get(UserSwitcherController.class).onDensityOrFontScaleChanged();
@@ -1163,16 +1403,20 @@
}
}
- @Override
protected void setZenMode(int mode) {
- super.setZenMode(mode);
+ // start old BaseStatusBar.setZenMode().
+ if (isDeviceProvisioned()) {
+ mZenMode = mode;
+ updateNotifications();
+ }
+ // end old BaseStatusBar.setZenMode().
if (mIconPolicy != null) {
mIconPolicy.setZenMode(mode);
}
}
protected void startKeyguard() {
- Trace.beginSection("PhoneStatusBar#startKeyguard");
+ Trace.beginSection("StatusBar#startKeyguard");
KeyguardViewMediator keyguardViewMediator = getComponent(KeyguardViewMediator.class);
mFingerprintUnlockController = new FingerprintUnlockController(mContext,
mStatusBarWindowManager, mDozeScrimController, keyguardViewMediator,
@@ -1212,7 +1456,6 @@
Trace.endSection();
}
- @Override
protected View getStatusBarView() {
return mStatusBarView;
}
@@ -1234,7 +1477,6 @@
return mNaturalBarHeight;
}
- @Override
protected boolean toggleSplitScreenMode(int metricsDockAction, int metricsUndockAction) {
if (mRecents == null) {
return false;
@@ -1282,7 +1524,6 @@
return new UserHandle(mCurrentUserId);
}
- @Override
public void addNotification(StatusBarNotification notification, RankingMap ranking,
Entry oldEntry) {
if (DEBUG) Log.d(TAG, "addNotification key=" + notification.getKey());
@@ -1345,13 +1586,11 @@
}
}
- @Override
protected void updateNotificationRanking(RankingMap ranking) {
mNotificationData.updateRanking(ranking);
updateNotifications();
}
- @Override
public void removeNotification(String key, RankingMap ranking) {
boolean deferRemoval = false;
if (mHeadsUpManager.isHeadsUp(key)) {
@@ -1482,13 +1721,28 @@
}
}
- @Override
protected void performRemoveNotification(StatusBarNotification n) {
Entry entry = mNotificationData.get(n.getKey());
if (mRemoteInputController.isRemoteInputActive(entry)) {
mRemoteInputController.removeRemoteInput(entry, null);
}
- super.performRemoveNotification(n);
+ // start old BaseStatusBar.performRemoveNotification.
+ final String pkg = n.getPackageName();
+ final String tag = n.getTag();
+ final int id = n.getId();
+ final int userId = n.getUserId();
+ try {
+ mBarService.onNotificationClear(pkg, tag, id, userId);
+ if (FORCE_REMOTE_INPUT_HISTORY
+ && mKeysKeptForRemoteInput.contains(n.getKey())) {
+ mKeysKeptForRemoteInput.remove(n.getKey());
+ }
+ removeNotification(n.getKey(), null);
+
+ } catch (RemoteException ex) {
+ // system process is dead if we're here.
+ }
+ // end old BaseStatusBar.performRemoveNotification.
}
private void updateNotificationShade() {
@@ -1717,17 +1971,14 @@
}
}
- @Override
public void addQsTile(ComponentName tile) {
mQSPanel.getHost().addTile(tile);
}
- @Override
public void remQsTile(ComponentName tile) {
mQSPanel.getHost().removeTile(tile);
}
- @Override
public void clickTile(ComponentName tile) {
mQSPanel.clickTile(tile);
}
@@ -1790,7 +2041,6 @@
return entry.row.getParent() instanceof NotificationStackScrollLayout;
}
- @Override
protected void updateNotifications() {
mNotificationData.filterAndSort();
@@ -1801,7 +2051,6 @@
updateNotifications();
}
- @Override
protected void setAreThereNotifications() {
if (SPEW) {
@@ -1985,7 +2234,7 @@
* Refresh or remove lockscreen artwork from media metadata or the lockscreen wallpaper.
*/
public void updateMediaMetaData(boolean metaDataChanged, boolean allowEnterAnimation) {
- Trace.beginSection("PhoneStatusBar#updateMediaMetaData");
+ Trace.beginSection("StatusBar#updateMediaMetaData");
if (!SHOW_LOCKSCREEN_MEDIA_ARTWORK) {
Trace.endSection();
return;
@@ -2280,9 +2529,8 @@
disable(mDisabledUnmodified1, mDisabledUnmodified2, animate);
}
- @Override
- protected BaseStatusBar.H createHandler() {
- return new PhoneStatusBar.H();
+ protected H createHandler() {
+ return new StatusBar.H();
}
@Override
@@ -2319,7 +2567,6 @@
return getBarState() == StatusBarState.KEYGUARD;
}
- @Override
public boolean isDozing() {
return mDozing;
}
@@ -2413,7 +2660,6 @@
}
- @Override
protected void updateHeadsUp(String key, Entry entry, boolean shouldPeek,
boolean alertAgain) {
final boolean wasHeadsUp = isHeadsUp(key);
@@ -2430,7 +2676,6 @@
}
}
- @Override
protected void setHeadsUpUser(int newUserId) {
if (mHeadsUpManager != null) {
mHeadsUpManager.setUser(newUserId);
@@ -2441,7 +2686,6 @@
return mHeadsUpManager.isHeadsUp(key);
}
- @Override
protected boolean isSnoozedPackage(StatusBarNotification sbn) {
return mHeadsUpManager.isSnoozed(sbn.getPackageName());
}
@@ -2498,11 +2742,39 @@
/**
* All changes to the status bar and notifications funnel through here and are batched.
*/
- private class H extends BaseStatusBar.H {
+ protected class H extends Handler {
@Override
public void handleMessage(Message m) {
- super.handleMessage(m);
switch (m.what) {
+ // start old BaseStatusBar.H handling.
+ case MSG_SHOW_RECENT_APPS:
+ showRecents(m.arg1 > 0, m.arg2 != 0);
+ break;
+ case MSG_HIDE_RECENT_APPS:
+ hideRecents(m.arg1 > 0, m.arg2 > 0);
+ break;
+ case MSG_TOGGLE_RECENTS_APPS:
+ toggleRecents();
+ break;
+ case MSG_PRELOAD_RECENT_APPS:
+ preloadRecents();
+ break;
+ case MSG_CANCEL_PRELOAD_RECENT_APPS:
+ cancelPreloadingRecents();
+ break;
+ case MSG_SHOW_NEXT_AFFILIATED_TASK:
+ showRecentsNextAffiliatedTask();
+ break;
+ case MSG_SHOW_PREV_AFFILIATED_TASK:
+ showRecentsPreviousAffiliatedTask();
+ break;
+ case MSG_TOGGLE_KEYBOARD_SHORTCUTS_MENU:
+ toggleKeyboardShortcuts(m.arg1);
+ break;
+ case MSG_DISMISS_KEYBOARD_SHORTCUTS_MENU:
+ dismissKeyboardShortcuts();
+ break;
+ // End old BaseStatusBar.H handling.
case MSG_OPEN_NOTIFICATION_PANEL:
animateExpandNotificationsPanel();
break;
@@ -2519,7 +2791,6 @@
}
}
- @Override
public void maybeEscalateHeadsUp() {
Collection<HeadsUpManager.HeadsUpEntry> entries = mHeadsUpManager.getAllEntries();
for (HeadsUpManager.HeadsUpEntry entry : entries) {
@@ -2619,12 +2890,10 @@
1.0f /* speedUpFactor */);
}
- @Override
public void animateCollapsePanels(int flags, boolean force) {
animateCollapsePanels(flags, force, false /* delayed */, 1.0f /* speedUpFactor */);
}
- @Override
public void animateCollapsePanels(int flags, boolean force, boolean delayed) {
animateCollapsePanels(flags, force, delayed, 1.0f /* speedUpFactor */);
}
@@ -2949,7 +3218,6 @@
}
};
- @Override
public void setInteracting(int barWindow, boolean interacting) {
final boolean changing = ((mInteractingWindows & barWindow) != 0) != interacting;
mInteractingWindows = interacting
@@ -3171,7 +3439,6 @@
pw.println(BarTransitions.modeToString(transitions.getMode()));
}
- @Override
public void createAndAddWindows() {
addStatusBarWindow();
}
@@ -3354,7 +3621,6 @@
}
}
- @Override
protected void dismissKeyguardThenExecute(OnDismissAction action, boolean afterKeyguardGone) {
dismissKeyguardThenExecute(action, null /* cancelRunnable */, afterKeyguardGone);
}
@@ -3374,7 +3640,15 @@
protected void onConfigurationChanged(Configuration newConfig) {
updateResources();
updateDisplaySize(); // populates mDisplayMetrics
- super.onConfigurationChanged(newConfig); // calls refreshLayout
+ // Begin old BaseStatusBar.onConfigurationChanged
+ final float fontScale = newConfig.fontScale;
+ final int density = newConfig.densityDpi;
+ if (density != mDensity || mFontScale != fontScale) {
+ onDensityOrFontScaleChanged();
+ mDensity = density;
+ mFontScale = fontScale;
+ }
+ // End old BaseStatusBar.onConfigurationChanged
if (DEBUG) {
Log.v(TAG, "configuration changed: " + mContext.getResources().getConfiguration());
@@ -3384,9 +3658,10 @@
mScreenPinningRequest.onConfigurationChanged();
}
- @Override
public void userSwitched(int newUserId) {
- super.userSwitched(newUserId);
+ // Begin old BaseStatusBar.userSwitched
+ setHeadsUpUser(newUserId);
+ // End old BaseStatusBar.userSwitched
if (MULTIUSER_DEBUG) mNotificationPanelDebugText.setText("USER " + newUserId);
animateCollapsePanels();
updatePublicMode();
@@ -3441,14 +3716,40 @@
// Visibility reporting
- @Override
protected void handleVisibleToUserChanged(boolean visibleToUser) {
if (visibleToUser) {
- super.handleVisibleToUserChanged(visibleToUser);
+ handleVisibleToUserChangedImpl(visibleToUser);
startNotificationLogging();
} else {
stopNotificationLogging();
- super.handleVisibleToUserChanged(visibleToUser);
+ handleVisibleToUserChangedImpl(visibleToUser);
+ }
+ }
+
+ /**
+ * The LEDs are turned off when the notification panel is shown, even just a little bit.
+ * See also StatusBar.setPanelExpanded for another place where we attempt to do this.
+ */
+ // Old BaseStatusBar.handleVisibileToUserChanged
+ private void handleVisibleToUserChangedImpl(boolean visibleToUser) {
+ try {
+ if (visibleToUser) {
+ boolean pinnedHeadsUp = mHeadsUpManager.hasPinnedHeadsUp();
+ boolean clearNotificationEffects =
+ !isPanelFullyCollapsed() &&
+ (mState == StatusBarState.SHADE || mState == StatusBarState.SHADE_LOCKED);
+ int notificationLoad = mNotificationData.getActiveNotifications().size();
+ if (pinnedHeadsUp && isPanelFullyCollapsed()) {
+ notificationLoad = 1;
+ } else {
+ MetricsLogger.histogram(mContext, "note_load", notificationLoad);
+ }
+ mBarService.onPanelRevealed(clearNotificationEffects, notificationLoad);
+ } else {
+ mBarService.onPanelHidden();
+ }
+ } catch (RemoteException ex) {
+ // Won't fail unless the world has ended.
}
}
@@ -3639,9 +3940,16 @@
}
}
- @Override
public void destroy() {
- super.destroy();
+ // Begin old BaseStatusBar.destroy().
+ mContext.unregisterReceiver(mBaseBroadcastReceiver);
+ try {
+ mNotificationListener.unregisterAsSystemService();
+ } catch (RemoteException e) {
+ // Ignore.
+ }
+ mDeviceProvisionedController.removeCallback(mDeviceProvisionedListener);
+ // End old BaseStatusBar.destroy().
if (mStatusBarWindow != null) {
mWindowManager.removeViewImmediate(mStatusBarWindow);
mStatusBarWindow = null;
@@ -3746,7 +4054,6 @@
return mState;
}
- @Override
public boolean isPanelFullyCollapsed() {
return mNotificationPanel.isFullyCollapsed();
}
@@ -3795,12 +4102,10 @@
updateMediaMetaData(true /* metaDataChanged */, true);
}
- @Override
public boolean isCollapsing() {
return mNotificationPanel.isCollapsing();
}
- @Override
public void addPostCollapseAction(Runnable r) {
mPostCollapseRunnables.add(r);
}
@@ -3914,7 +4219,7 @@
* @return true if we would like to stay in the shade, false if it should go away entirely
*/
public boolean hideKeyguard() {
- Trace.beginSection("PhoneStatusBar#hideKeyguard");
+ Trace.beginSection("StatusBar#hideKeyguard");
boolean staying = mLeaveOpenOnKeyguardHide;
setBarState(StatusBarState.SHADE);
View viewToClick = null;
@@ -4046,7 +4351,7 @@
}
protected void updateKeyguardState(boolean goingToFullShade, boolean fromShadeLocked) {
- Trace.beginSection("PhoneStatusBar#updateKeyguardState");
+ Trace.beginSection("StatusBar#updateKeyguardState");
if (mState == StatusBarState.KEYGUARD) {
mKeyguardIndicationController.setVisible(true);
mNotificationPanel.resetViews();
@@ -4083,7 +4388,7 @@
}
private void updateDozingState() {
- Trace.beginSection("PhoneStatusBar#updateDozingState");
+ Trace.beginSection("StatusBar#updateDozingState");
boolean animate = !mDozing && mDozeScrimController.isPulsing();
mNotificationPanel.setDozing(mDozing, animate);
mStackScroller.setDark(mDozing, animate, mWakeUpTouchLocation);
@@ -4289,7 +4594,6 @@
}
}
- @Override
protected int getMaxKeyguardNotifications(boolean recompute) {
if (recompute) {
mMaxKeyguardNotifications = Math.max(1,
@@ -4389,29 +4693,53 @@
}
}
- @Override
public void onLockedNotificationImportanceChange(OnDismissAction dismissAction) {
mLeaveOpenOnKeyguardHide = true;
dismissKeyguardThenExecute(dismissAction, true /* afterKeyguardGone */);
}
- @Override
protected void onLockedRemoteInput(ExpandableNotificationRow row, View clicked) {
mLeaveOpenOnKeyguardHide = true;
showBouncer();
mPendingRemoteInputView = clicked;
}
- @Override
protected boolean startWorkChallengeIfNecessary(int userId, IntentSender intendSender,
String notificationKey) {
// Clear pending remote view, as we do not want to trigger pending remote input view when
// it's called by other code
mPendingWorkRemoteInputView = null;
- return super.startWorkChallengeIfNecessary(userId, intendSender, notificationKey);
+ // Begin old BaseStatusBar.startWorkChallengeIfNecessary.
+ final Intent newIntent = mKeyguardManager.createConfirmDeviceCredentialIntent(null,
+ null, userId);
+ if (newIntent == null) {
+ return false;
+ }
+ final Intent callBackIntent = new Intent(NOTIFICATION_UNLOCKED_BY_WORK_CHALLENGE_ACTION);
+ callBackIntent.putExtra(Intent.EXTRA_INTENT, intendSender);
+ callBackIntent.putExtra(Intent.EXTRA_INDEX, notificationKey);
+ callBackIntent.setPackage(mContext.getPackageName());
+
+ PendingIntent callBackPendingIntent = PendingIntent.getBroadcast(
+ mContext,
+ 0,
+ callBackIntent,
+ PendingIntent.FLAG_CANCEL_CURRENT |
+ PendingIntent.FLAG_ONE_SHOT |
+ PendingIntent.FLAG_IMMUTABLE);
+ newIntent.putExtra(
+ Intent.EXTRA_INTENT,
+ callBackPendingIntent.getIntentSender());
+ try {
+ ActivityManager.getService().startConfirmDeviceCredentialIntent(newIntent,
+ null /*options*/);
+ } catch (RemoteException ex) {
+ // ignore
+ }
+ return true;
+ // End old BaseStatusBar.startWorkChallengeIfNecessary.
}
- @Override
protected void onLockedWorkRemoteInput(int userId, ExpandableNotificationRow row,
View clicked) {
// Collapse notification and show work challenge
@@ -4431,7 +4759,6 @@
return false;
}
- @Override
protected void onWorkChallengeChanged() {
updatePublicMode();
updateNotifications();
@@ -4528,9 +4855,8 @@
return mKeyguardFadingAwayDuration;
}
- @Override
public void setBouncerShowing(boolean bouncerShowing) {
- super.setBouncerShowing(bouncerShowing);
+ mBouncerShowing = bouncerShowing;
mStatusBarView.setBouncerShowing(bouncerShowing);
recomputeDisableFlags(true /* animate */);
}
@@ -4610,7 +4936,6 @@
return !mNotificationData.getActiveNotifications().isEmpty();
}
- @Override
public void wakeUpIfDozing(long time, PointF where) {
if (mDozing && mDozeScrimController.isPulsing()) {
PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
@@ -4704,7 +5029,7 @@
}
private void updateDozing() {
- Trace.beginSection("PhoneStatusBar#updateDozing");
+ Trace.beginSection("StatusBar#updateDozing");
// When in wake-and-unlock while pulsing, keep dozing state until fully unlocked.
mDozing = mDozingRequested && mState == StatusBarState.KEYGUARD
|| mFingerprintUnlockController.getMode()
@@ -4856,12 +5181,11 @@
@Override
public void startPendingIntentDismissingKeyguard(PendingIntent intent) {
- PhoneStatusBar.this.startPendingIntentDismissingKeyguard(intent);
+ StatusBar.this.startPendingIntentDismissingKeyguard(intent);
}
}
- @Override
public SnoozeListener getSnoozeListener() {
return this;
}
@@ -4870,4 +5194,2009 @@
public void snoozeNotification(StatusBarNotification sbn, SnoozeOption snoozeOption) {
setNotificationSnoozed(sbn, snoozeOption);
}
+
+ // Begin Extra BaseStatusBar methods.
+
+ protected CommandQueue mCommandQueue;
+ protected IStatusBarService mBarService;
+
+ // all notifications
+ protected NotificationData mNotificationData;
+ protected NotificationStackScrollLayout mStackScroller;
+
+ protected NotificationGroupManager mGroupManager = new NotificationGroupManager();
+
+ protected RemoteInputController mRemoteInputController;
+
+ // for heads up notifications
+ protected HeadsUpManager mHeadsUpManager;
+
+ // handling reordering
+ protected VisualStabilityManager mVisualStabilityManager = new VisualStabilityManager();
+
+ protected int mCurrentUserId = 0;
+ final protected SparseArray<UserInfo> mCurrentProfiles = new SparseArray<UserInfo>();
+
+ protected int mLayoutDirection = -1; // invalid
+ protected AccessibilityManager mAccessibilityManager;
+
+ protected boolean mDeviceInteractive;
+
+ protected boolean mVisible;
+ protected ArraySet<Entry> mHeadsUpEntriesToRemoveOnSwitch = new ArraySet<>();
+ protected ArraySet<Entry> mRemoteInputEntriesToRemoveOnCollapse = new ArraySet<>();
+
+ /**
+ * Notifications with keys in this set are not actually around anymore. We kept them around
+ * when they were canceled in response to a remote input interaction. This allows us to show
+ * what you replied and allows you to continue typing into it.
+ */
+ protected ArraySet<String> mKeysKeptForRemoteInput = new ArraySet<>();
+
+ // mScreenOnFromKeyguard && mVisible.
+ private boolean mVisibleToUser;
+
+ private Locale mLocale;
+ private float mFontScale;
+
+ protected boolean mUseHeadsUp = false;
+ protected boolean mHeadsUpTicker = false;
+ protected boolean mDisableNotificationAlerts = false;
+
+ protected DevicePolicyManager mDevicePolicyManager;
+ protected IDreamManager mDreamManager;
+ protected PowerManager mPowerManager;
+ protected StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
+
+ // public mode, private notifications, etc
+ private final SparseBooleanArray mLockscreenPublicMode = new SparseBooleanArray();
+ private final SparseBooleanArray mUsersAllowingPrivateNotifications = new SparseBooleanArray();
+ private final SparseBooleanArray mUsersAllowingNotifications = new SparseBooleanArray();
+
+ private UserManager mUserManager;
+ private int mDensity;
+
+ protected KeyguardManager mKeyguardManager;
+ private LockPatternUtils mLockPatternUtils;
+ private DeviceProvisionedController mDeviceProvisionedController;
+
+ // UI-specific methods
+
+ protected WindowManager mWindowManager;
+ protected IWindowManager mWindowManagerService;
+
+ protected Display mDisplay;
+
+ protected RecentsComponent mRecents;
+
+ protected int mZenMode;
+
+ // which notification is currently being longpress-examined by the user
+ private NotificationGuts mNotificationGutsExposed;
+ private MenuItem mGutsMenuItem;
+
+ private KeyboardShortcuts mKeyboardShortcuts;
+
+ protected NotificationShelf mNotificationShelf;
+ protected DismissView mDismissView;
+ protected EmptyShadeView mEmptyShadeView;
+
+ private NotificationClicker mNotificationClicker = new NotificationClicker();
+
+ protected AssistManager mAssistManager;
+
+ protected boolean mVrMode;
+
+ private Set<String> mNonBlockablePkgs;
+
+ @Override // NotificationData.Environment
+ public boolean isDeviceProvisioned() {
+ return mDeviceProvisionedController.isDeviceProvisioned();
+ }
+
+ private final IVrStateCallbacks mVrStateCallbacks = new IVrStateCallbacks.Stub() {
+ @Override
+ public void onVrStateChanged(boolean enabled) {
+ mVrMode = enabled;
+ }
+ };
+
+ public boolean isDeviceInVrMode() {
+ return mVrMode;
+ }
+
+ private final DeviceProvisionedListener mDeviceProvisionedListener =
+ new DeviceProvisionedListener() {
+ @Override
+ public void onDeviceProvisionedChanged() {
+ updateNotifications();
+ }
+ };
+
+ protected final ContentObserver mSettingsObserver = new ContentObserver(mHandler) {
+ @Override
+ public void onChange(boolean selfChange) {
+ final int mode = Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.ZEN_MODE, Settings.Global.ZEN_MODE_OFF);
+ setZenMode(mode);
+
+ updateLockscreenNotificationSetting();
+ }
+ };
+
+ private final ContentObserver mLockscreenSettingsObserver = new ContentObserver(mHandler) {
+ @Override
+ public void onChange(boolean selfChange) {
+ // We don't know which user changed LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS or
+ // LOCK_SCREEN_SHOW_NOTIFICATIONS, so we just dump our cache ...
+ mUsersAllowingPrivateNotifications.clear();
+ mUsersAllowingNotifications.clear();
+ // ... and refresh all the notifications
+ updateLockscreenNotificationSetting();
+ updateNotifications();
+ }
+ };
+
+ private RemoteViews.OnClickHandler mOnClickHandler = new RemoteViews.OnClickHandler() {
+ private final int[] mTmpInt2 = new int[2];
+
+ @Override
+ public boolean onClickHandler(
+ final View view, final PendingIntent pendingIntent, final Intent fillInIntent) {
+ view.getLocationInWindow(mTmpInt2);
+ wakeUpIfDozing(SystemClock.uptimeMillis(), new PointF(
+ mTmpInt2[0] + view.getWidth() / 2, mTmpInt2[1] + view.getHeight() / 2));
+
+
+ if (handleRemoteInput(view, pendingIntent, fillInIntent)) {
+ return true;
+ }
+
+ if (DEBUG) {
+ Log.v(TAG, "Notification click handler invoked for intent: " + pendingIntent);
+ }
+ logActionClick(view);
+ // The intent we are sending is for the application, which
+ // won't have permission to immediately start an activity after
+ // the user switches to home. We know it is safe to do at this
+ // point, so make sure new activity switches are now allowed.
+ try {
+ ActivityManager.getService().resumeAppSwitches();
+ } catch (RemoteException e) {
+ }
+ final boolean isActivity = pendingIntent.isActivity();
+ if (isActivity) {
+ final boolean keyguardShowing = mStatusBarKeyguardViewManager.isShowing();
+ final boolean afterKeyguardGone = PreviewInflater.wouldLaunchResolverActivity(
+ mContext, pendingIntent.getIntent(), mCurrentUserId);
+ dismissKeyguardThenExecute(new OnDismissAction() {
+ @Override
+ public boolean onDismiss() {
+ try {
+ ActivityManager.getService().resumeAppSwitches();
+ } catch (RemoteException e) {
+ }
+
+ boolean handled = superOnClickHandler(view, pendingIntent, fillInIntent);
+
+ // close the shade if it was open
+ if (handled) {
+ animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL,
+ true /* force */);
+ visibilityChanged(false);
+ mAssistManager.hideAssist();
+ }
+
+ // Wait for activity start.
+ return handled;
+ }
+ }, afterKeyguardGone);
+ return true;
+ } else {
+ return superOnClickHandler(view, pendingIntent, fillInIntent);
+ }
+ }
+
+ private void logActionClick(View view) {
+ ViewParent parent = view.getParent();
+ String key = getNotificationKeyForParent(parent);
+ if (key == null) {
+ Log.w(TAG, "Couldn't determine notification for click.");
+ return;
+ }
+ int index = -1;
+ // If this is a default template, determine the index of the button.
+ if (view.getId() == com.android.internal.R.id.action0 &&
+ parent != null && parent instanceof ViewGroup) {
+ ViewGroup actionGroup = (ViewGroup) parent;
+ index = actionGroup.indexOfChild(view);
+ }
+ try {
+ mBarService.onNotificationActionClick(key, index);
+ } catch (RemoteException e) {
+ // Ignore
+ }
+ }
+
+ private String getNotificationKeyForParent(ViewParent parent) {
+ while (parent != null) {
+ if (parent instanceof ExpandableNotificationRow) {
+ return ((ExpandableNotificationRow) parent).getStatusBarNotification().getKey();
+ }
+ parent = parent.getParent();
+ }
+ return null;
+ }
+
+ private boolean superOnClickHandler(View view, PendingIntent pendingIntent,
+ Intent fillInIntent) {
+ return super.onClickHandler(view, pendingIntent, fillInIntent,
+ StackId.FULLSCREEN_WORKSPACE_STACK_ID);
+ }
+
+ private boolean handleRemoteInput(View view, PendingIntent pendingIntent, Intent fillInIntent) {
+ Object tag = view.getTag(com.android.internal.R.id.remote_input_tag);
+ RemoteInput[] inputs = null;
+ if (tag instanceof RemoteInput[]) {
+ inputs = (RemoteInput[]) tag;
+ }
+
+ if (inputs == null) {
+ return false;
+ }
+
+ RemoteInput input = null;
+
+ for (RemoteInput i : inputs) {
+ if (i.getAllowFreeFormInput()) {
+ input = i;
+ }
+ }
+
+ if (input == null) {
+ return false;
+ }
+
+ ViewParent p = view.getParent();
+ RemoteInputView riv = null;
+ while (p != null) {
+ if (p instanceof View) {
+ View pv = (View) p;
+ if (pv.isRootNamespace()) {
+ riv = (RemoteInputView) pv.findViewWithTag(RemoteInputView.VIEW_TAG);
+ break;
+ }
+ }
+ p = p.getParent();
+ }
+ ExpandableNotificationRow row = null;
+ while (p != null) {
+ if (p instanceof ExpandableNotificationRow) {
+ row = (ExpandableNotificationRow) p;
+ break;
+ }
+ p = p.getParent();
+ }
+
+ if (riv == null || row == null) {
+ return false;
+ }
+
+ row.setUserExpanded(true);
+
+ if (!mAllowLockscreenRemoteInput) {
+ final int userId = pendingIntent.getCreatorUserHandle().getIdentifier();
+ if (isLockscreenPublicMode(userId)) {
+ onLockedRemoteInput(row, view);
+ return true;
+ }
+ if (mUserManager.getUserInfo(userId).isManagedProfile()
+ && mKeyguardManager.isDeviceLocked(userId)) {
+ onLockedWorkRemoteInput(userId, row, view);
+ return true;
+ }
+ }
+
+ int width = view.getWidth();
+ if (view instanceof TextView) {
+ // Center the reveal on the text which might be off-center from the TextView
+ TextView tv = (TextView) view;
+ if (tv.getLayout() != null) {
+ int innerWidth = (int) tv.getLayout().getLineWidth(0);
+ innerWidth += tv.getCompoundPaddingLeft() + tv.getCompoundPaddingRight();
+ width = Math.min(width, innerWidth);
+ }
+ }
+ int cx = view.getLeft() + width / 2;
+ int cy = view.getTop() + view.getHeight() / 2;
+ int w = riv.getWidth();
+ int h = riv.getHeight();
+ int r = Math.max(
+ Math.max(cx + cy, cx + (h - cy)),
+ Math.max((w - cx) + cy, (w - cx) + (h - cy)));
+
+ riv.setRevealParameters(cx, cy, r);
+ riv.setPendingIntent(pendingIntent);
+ riv.setRemoteInput(inputs, input);
+ riv.focusAnimated();
+
+ return true;
+ }
+
+ };
+
+ private final BroadcastReceiver mBaseBroadcastReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ if (Intent.ACTION_USER_SWITCHED.equals(action)) {
+ mCurrentUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
+ updateCurrentProfilesCache();
+ if (true) Log.v(TAG, "userId " + mCurrentUserId + " is in the house");
+
+ updateLockscreenNotificationSetting();
+
+ userSwitched(mCurrentUserId);
+ } else if (Intent.ACTION_USER_ADDED.equals(action)) {
+ updateCurrentProfilesCache();
+ } else if (Intent.ACTION_USER_PRESENT.equals(action)) {
+ List<ActivityManager.RecentTaskInfo> recentTask = null;
+ try {
+ recentTask = ActivityManager.getService().getRecentTasks(1,
+ ActivityManager.RECENT_WITH_EXCLUDED
+ | ActivityManager.RECENT_INCLUDE_PROFILES,
+ mCurrentUserId).getList();
+ } catch (RemoteException e) {
+ // Abandon hope activity manager not running.
+ }
+ if (recentTask != null && recentTask.size() > 0) {
+ UserInfo user = mUserManager.getUserInfo(recentTask.get(0).userId);
+ if (user != null && user.isManagedProfile()) {
+ Toast toast = Toast.makeText(mContext,
+ R.string.managed_profile_foreground_toast,
+ Toast.LENGTH_SHORT);
+ TextView text = (TextView) toast.getView().findViewById(
+ android.R.id.message);
+ text.setCompoundDrawablesRelativeWithIntrinsicBounds(
+ R.drawable.stat_sys_managed_profile_status, 0, 0, 0);
+ int paddingPx = mContext.getResources().getDimensionPixelSize(
+ R.dimen.managed_profile_toast_padding);
+ text.setCompoundDrawablePadding(paddingPx);
+ toast.show();
+ }
+ }
+ } else if (BANNER_ACTION_CANCEL.equals(action) || BANNER_ACTION_SETUP.equals(action)) {
+ NotificationManager noMan = (NotificationManager)
+ mContext.getSystemService(Context.NOTIFICATION_SERVICE);
+ noMan.cancel(SystemMessage.NOTE_HIDDEN_NOTIFICATIONS);
+
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.SHOW_NOTE_ABOUT_NOTIFICATION_HIDING, 0);
+ if (BANNER_ACTION_SETUP.equals(action)) {
+ animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL,
+ true /* force */);
+ mContext.startActivity(new Intent(Settings.ACTION_APP_NOTIFICATION_REDACTION)
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+
+ );
+ }
+ } else if (NOTIFICATION_UNLOCKED_BY_WORK_CHALLENGE_ACTION.equals(action)) {
+ final IntentSender intentSender = intent.getParcelableExtra(Intent.EXTRA_INTENT);
+ final String notificationKey = intent.getStringExtra(Intent.EXTRA_INDEX);
+ if (intentSender != null) {
+ try {
+ mContext.startIntentSender(intentSender, null, 0, 0, 0);
+ } catch (IntentSender.SendIntentException e) {
+ /* ignore */
+ }
+ }
+ if (notificationKey != null) {
+ try {
+ mBarService.onNotificationClick(notificationKey);
+ } catch (RemoteException e) {
+ /* ignore */
+ }
+ }
+ }
+ }
+ };
+
+ private final BroadcastReceiver mAllUsersReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ final String action = intent.getAction();
+ final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
+
+ if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(action) &&
+ isCurrentProfile(getSendingUserId())) {
+ mUsersAllowingPrivateNotifications.clear();
+ updateLockscreenNotificationSetting();
+ updateNotifications();
+ } else if (Intent.ACTION_DEVICE_LOCKED_CHANGED.equals(action)) {
+ if (userId != mCurrentUserId && isCurrentProfile(userId)) {
+ onWorkChallengeChanged();
+ }
+ }
+ }
+ };
+
+ private final NotificationListenerService mNotificationListener =
+ new NotificationListenerService() {
+ @Override
+ public void onListenerConnected() {
+ if (DEBUG) Log.d(TAG, "onListenerConnected");
+ final StatusBarNotification[] notifications = getActiveNotifications();
+ if (notifications == null) {
+ Log.w(TAG, "onListenerConnected unable to get active notifications.");
+ return;
+ }
+ final RankingMap currentRanking = getCurrentRanking();
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ for (StatusBarNotification sbn : notifications) {
+ addNotification(sbn, currentRanking, null /* oldEntry */);
+ }
+ }
+ });
+ }
+
+ @Override
+ public void onNotificationPosted(final StatusBarNotification sbn,
+ final RankingMap rankingMap) {
+ if (DEBUG) Log.d(TAG, "onNotificationPosted: " + sbn);
+ if (sbn != null) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ processForRemoteInput(sbn.getNotification());
+ String key = sbn.getKey();
+ mKeysKeptForRemoteInput.remove(key);
+ boolean isUpdate = mNotificationData.get(key) != null;
+ // In case we don't allow child notifications, we ignore children of
+ // notifications that have a summary, since we're not going to show them
+ // anyway. This is true also when the summary is canceled,
+ // because children are automatically canceled by NoMan in that case.
+ if (!ENABLE_CHILD_NOTIFICATIONS
+ && mGroupManager.isChildInGroupWithSummary(sbn)) {
+ if (DEBUG) {
+ Log.d(TAG, "Ignoring group child due to existing summary: " + sbn);
+ }
+
+ // Remove existing notification to avoid stale data.
+ if (isUpdate) {
+ removeNotification(key, rankingMap);
+ } else {
+ mNotificationData.updateRanking(rankingMap);
+ }
+ return;
+ }
+ if (isUpdate) {
+ updateNotification(sbn, rankingMap);
+ } else {
+ addNotification(sbn, rankingMap, null /* oldEntry */);
+ }
+ }
+ });
+ }
+ }
+
+ @Override
+ public void onNotificationRemoved(StatusBarNotification sbn,
+ final RankingMap rankingMap) {
+ if (DEBUG) Log.d(TAG, "onNotificationRemoved: " + sbn);
+ if (sbn != null) {
+ final String key = sbn.getKey();
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ removeNotification(key, rankingMap);
+ }
+ });
+ }
+ }
+
+ @Override
+ public void onNotificationRankingUpdate(final RankingMap rankingMap) {
+ if (DEBUG) Log.d(TAG, "onRankingUpdate");
+ if (rankingMap != null) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ updateNotificationRanking(rankingMap);
+ }
+ });
+ } }
+
+ };
+
+ private void updateCurrentProfilesCache() {
+ synchronized (mCurrentProfiles) {
+ mCurrentProfiles.clear();
+ if (mUserManager != null) {
+ for (UserInfo user : mUserManager.getProfiles(mCurrentUserId)) {
+ mCurrentProfiles.put(user.id, user);
+ }
+ }
+ }
+ }
+
+ protected void notifyUserAboutHiddenNotifications() {
+ if (0 != Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.SHOW_NOTE_ABOUT_NOTIFICATION_HIDING, 1)) {
+ Log.d(TAG, "user hasn't seen notification about hidden notifications");
+ if (!mLockPatternUtils.isSecure(KeyguardUpdateMonitor.getCurrentUser())) {
+ Log.d(TAG, "insecure lockscreen, skipping notification");
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.SHOW_NOTE_ABOUT_NOTIFICATION_HIDING, 0);
+ return;
+ }
+ Log.d(TAG, "disabling lockecreen notifications and alerting the user");
+ // disable lockscreen notifications until user acts on the banner.
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 0);
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0);
+
+ final String packageName = mContext.getPackageName();
+ PendingIntent cancelIntent = PendingIntent.getBroadcast(mContext, 0,
+ new Intent(BANNER_ACTION_CANCEL).setPackage(packageName),
+ PendingIntent.FLAG_CANCEL_CURRENT);
+ PendingIntent setupIntent = PendingIntent.getBroadcast(mContext, 0,
+ new Intent(BANNER_ACTION_SETUP).setPackage(packageName),
+ PendingIntent.FLAG_CANCEL_CURRENT);
+
+ final int colorRes = com.android.internal.R.color.system_notification_accent_color;
+ Notification.Builder note = new Notification.Builder(mContext)
+ .setSmallIcon(R.drawable.ic_android)
+ .setContentTitle(mContext.getString(R.string.hidden_notifications_title))
+ .setContentText(mContext.getString(R.string.hidden_notifications_text))
+ .setChannel(NotificationChannels.SECURITY)
+ .setOngoing(true)
+ .setColor(mContext.getColor(colorRes))
+ .setContentIntent(setupIntent)
+ .addAction(R.drawable.ic_close,
+ mContext.getString(R.string.hidden_notifications_cancel),
+ cancelIntent)
+ .addAction(R.drawable.ic_settings,
+ mContext.getString(R.string.hidden_notifications_setup),
+ setupIntent);
+ overrideNotificationAppName(mContext, note);
+
+ NotificationManager noMan =
+ (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
+ noMan.notify(SystemMessage.NOTE_HIDDEN_NOTIFICATIONS, note.build());
+ }
+ }
+
+ @Override // NotificationData.Environment
+ public boolean isNotificationForCurrentProfiles(StatusBarNotification n) {
+ final int thisUserId = mCurrentUserId;
+ final int notificationUserId = n.getUserId();
+ if (DEBUG && MULTIUSER_DEBUG) {
+ Log.v(TAG, String.format("%s: current userid: %d, notification userid: %d",
+ n, thisUserId, notificationUserId));
+ }
+ return isCurrentProfile(notificationUserId);
+ }
+
+ protected void setNotificationShown(StatusBarNotification n) {
+ setNotificationsShown(new String[]{n.getKey()});
+ }
+
+ protected void setNotificationsShown(String[] keys) {
+ try {
+ mNotificationListener.setNotificationsShown(keys);
+ } catch (RuntimeException e) {
+ Log.d(TAG, "failed setNotificationsShown: ", e);
+ }
+ }
+
+ protected boolean isCurrentProfile(int userId) {
+ synchronized (mCurrentProfiles) {
+ return userId == UserHandle.USER_ALL || mCurrentProfiles.get(userId) != null;
+ }
+ }
+
+ @Override
+ public NotificationGroupManager getGroupManager() {
+ return mGroupManager;
+ }
+
+ protected void bindDismissRunnable(final ExpandableNotificationRow row) {
+ row.setOnDismissRunnable(() -> performRemoveNotification(row.getStatusBarNotification()));
+ }
+
+ protected void applyColorsAndBackgrounds(StatusBarNotification sbn,
+ NotificationData.Entry entry) {
+
+ if (entry.getContentView().getId()
+ != com.android.internal.R.id.status_bar_latest_event_content) {
+ // Using custom RemoteViews
+ if (entry.targetSdk >= Build.VERSION_CODES.GINGERBREAD
+ && entry.targetSdk < Build.VERSION_CODES.LOLLIPOP) {
+ entry.row.setShowingLegacyBackground(true);
+ entry.legacy = true;
+ }
+ }
+
+ entry.setIconTag(R.id.icon_is_pre_L, entry.targetSdk < Build.VERSION_CODES.LOLLIPOP);
+ }
+
+ public boolean isMediaNotification(NotificationData.Entry entry) {
+ // TODO: confirm that there's a valid media key
+ return entry.getExpandedContentView() != null &&
+ entry.getExpandedContentView()
+ .findViewById(com.android.internal.R.id.media_actions) != null;
+ }
+
+ // The (i) button in the guts that links to the system notification settings for that app
+ private void startAppNotificationSettingsActivity(String packageName, final int appUid) {
+ final Intent intent = new Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS);
+ intent.putExtra(Settings.EXTRA_APP_PACKAGE, packageName);
+ intent.putExtra(Settings.EXTRA_APP_UID, appUid);
+ startNotificationGutsIntent(intent, appUid);
+ }
+
+ private void startNotificationGutsIntent(final Intent intent, final int appUid) {
+ dismissKeyguardThenExecute(new OnDismissAction() {
+ @Override
+ public boolean onDismiss() {
+ AsyncTask.execute(new Runnable() {
+ @Override
+ public void run() {
+ TaskStackBuilder.create(mContext)
+ .addNextIntentWithParentStack(intent)
+ .startActivities(getActivityOptions(),
+ new UserHandle(UserHandle.getUserId(appUid)));
+ }
+ });
+ animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL, true /* force */);
+ return true;
+ }
+ }, false /* afterKeyguardGone */);
+ }
+
+ protected void setNotificationSnoozed(StatusBarNotification sbn, SnoozeOption snoozeOption) {
+ if (snoozeOption.criterion != null) {
+ mNotificationListener.snoozeNotification(sbn.getKey(), snoozeOption.criterion.getId());
+ } else {
+ GregorianCalendar snoozeUntil = new GregorianCalendar();
+ snoozeUntil.add(Calendar.MINUTE, snoozeOption.snoozeForMinutes);
+ mNotificationListener.snoozeNotification(sbn.getKey(), snoozeUntil.getTimeInMillis());
+ }
+ }
+
+ private void bindGuts(final ExpandableNotificationRow row, MenuItem item) {
+ row.inflateGuts();
+ row.setGutsView(item);
+ final StatusBarNotification sbn = row.getStatusBarNotification();
+ row.setTag(sbn.getPackageName());
+ final NotificationGuts guts = row.getGuts();
+ guts.setClosedListener((NotificationGuts g) -> {
+ if (!row.isRemoved()) {
+ mStackScroller.onHeightChanged(row, !isPanelFullyCollapsed() /* needsAnimation */);
+ }
+ mNotificationGutsExposed = null;
+ mGutsMenuItem = null;
+ });
+
+ if (item.gutsContent instanceof SnoozeGutsContent) {
+ ((SnoozeGutsContent) item.gutsContent).setSnoozeListener(getSnoozeListener());
+ ((SnoozeGutsContent) item.gutsContent).setStatusBarNotification(sbn);
+ ((NotificationSnooze) item.gutsContent).setSnoozeOptions(row.getEntry().snoozeCriteria);
+ }
+
+ if (item.gutsContent instanceof NotificationInfo) {
+ final NotificationChannel channel = row.getEntry().channel;
+ PackageManager pmUser = getPackageManagerForUser(mContext,
+ sbn.getUser().getIdentifier());
+ final INotificationManager iNotificationManager = INotificationManager.Stub.asInterface(
+ ServiceManager.getService(Context.NOTIFICATION_SERVICE));
+ final String pkg = sbn.getPackageName();
+ NotificationInfo info = (NotificationInfo) item.gutsContent;
+ final NotificationInfo.OnSettingsClickListener onSettingsClick = (View v,
+ int appUid) -> {
+ MetricsLogger.action(mContext, MetricsEvent.ACTION_NOTE_INFO);
+ guts.resetFalsingCheck();
+ startAppNotificationSettingsActivity(pkg, appUid);
+ };
+ final View.OnClickListener onDoneClick = (View v) -> {
+ // If the user has security enabled, show challenge if the setting is changed.
+ if (info.hasImportanceChanged()
+ && isLockscreenPublicMode(sbn.getUser().getIdentifier())
+ && (mState == StatusBarState.KEYGUARD
+ || mState == StatusBarState.SHADE_LOCKED)) {
+ OnDismissAction dismissAction = new OnDismissAction() {
+ @Override
+ public boolean onDismiss() {
+ saveAndCloseNotificationMenu(info, row, guts, v);
+ return true;
+ }
+ };
+ onLockedNotificationImportanceChange(dismissAction);
+ } else {
+ saveAndCloseNotificationMenu(info, row, guts, v);
+ }
+ };
+ info.bindNotification(pmUser, iNotificationManager, sbn, channel, onSettingsClick,
+ onDoneClick,
+ mNonBlockablePkgs);
+ }
+ }
+
+ private void saveAndCloseNotificationMenu(NotificationInfo info,
+ ExpandableNotificationRow row, NotificationGuts guts, View done) {
+ guts.resetFalsingCheck();
+ info.saveImportance();
+ int[] rowLocation = new int[2];
+ int[] doneLocation = new int[2];
+ row.getLocationOnScreen(rowLocation);
+ done.getLocationOnScreen(doneLocation);
+
+ final int centerX = done.getWidth() / 2;
+ final int centerY = done.getHeight() / 2;
+ final int x = doneLocation[0] - rowLocation[0] + centerX;
+ final int y = doneLocation[1] - rowLocation[1] + centerY;
+ dismissPopups(x, y);
+ }
+
+ protected SwipeHelper.LongPressListener getNotificationLongClicker() {
+ return new SwipeHelper.LongPressListener() {
+ @Override
+ public boolean onLongPress(View v, final int x, final int y,
+ MenuItem item) {
+ if (!(v instanceof ExpandableNotificationRow)) {
+ return false;
+ }
+ if (v.getWindowToken() == null) {
+ Log.e(TAG, "Trying to show notification guts, but not attached to window");
+ return false;
+ }
+
+ final ExpandableNotificationRow row = (ExpandableNotificationRow) v;
+ bindGuts(row, item);
+ NotificationGuts guts = row.getGuts();
+
+ // Assume we are a status_bar_notification_row
+ if (guts == null) {
+ // This view has no guts. Examples are the more card or the dismiss all view
+ return false;
+ }
+
+ // Already showing?
+ if (guts.getVisibility() == View.VISIBLE) {
+ dismissPopups(x, y);
+ return false;
+ }
+
+ MetricsLogger.action(mContext, MetricsEvent.ACTION_NOTE_CONTROLS);
+
+ // ensure that it's laid but not visible until actually laid out
+ guts.setVisibility(View.INVISIBLE);
+ // Post to ensure the the guts are properly laid out.
+ guts.post(new Runnable() {
+ @Override
+ public void run() {
+ if (row.getWindowToken() == null) {
+ Log.e(TAG, "Trying to show notification guts, but not attached to "
+ + "window");
+ return;
+ }
+ dismissPopups(-1 /* x */, -1 /* y */, false /* resetGear */,
+ false /* animate */);
+ guts.setVisibility(View.VISIBLE);
+ final double horz = Math.max(guts.getWidth() - x, x);
+ final double vert = Math.max(guts.getHeight() - y, y);
+ final float r = (float) Math.hypot(horz, vert);
+ final Animator a
+ = 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 /* exposed */,
+ mState == StatusBarState.KEYGUARD /* needsFalsingProtection */);
+ row.closeRemoteInput();
+ mStackScroller.onHeightChanged(row, true /* needsAnimation */);
+ mNotificationGutsExposed = guts;
+ mGutsMenuItem = item;
+ }
+ });
+ return true;
+ }
+ };
+ }
+
+ /**
+ * Returns the exposed NotificationGuts or null if none are exposed.
+ */
+ public NotificationGuts getExposedGuts() {
+ return mNotificationGutsExposed;
+ }
+
+ public void dismissPopups() {
+ dismissPopups(-1 /* x */, -1 /* y */, true /* resetGear */, false /* animate */);
+ }
+
+ private void dismissPopups(int x, int y) {
+ dismissPopups(x, y, true /* resetGear */, false /* animate */);
+ }
+
+ public void dismissPopups(int x, int y, boolean resetGear, boolean animate) {
+ if (mNotificationGutsExposed != null) {
+ mNotificationGutsExposed.closeControls(x, y, true /* save */);
+ }
+ if (resetGear) {
+ mStackScroller.resetExposedGearView(animate, true /* force */);
+ }
+ }
+
+ @Override
+ public void showRecentApps(boolean triggeredFromAltTab, boolean fromHome) {
+ int msg = MSG_SHOW_RECENT_APPS;
+ mHandler.removeMessages(msg);
+ mHandler.obtainMessage(msg, triggeredFromAltTab ? 1 : 0, fromHome ? 1 : 0).sendToTarget();
+ }
+
+ @Override
+ public void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
+ int msg = MSG_HIDE_RECENT_APPS;
+ mHandler.removeMessages(msg);
+ mHandler.obtainMessage(msg, triggeredFromAltTab ? 1 : 0,
+ triggeredFromHomeKey ? 1 : 0).sendToTarget();
+ }
+
+ @Override
+ public void toggleRecentApps() {
+ toggleRecents();
+ }
+
+ @Override
+ public void toggleSplitScreen() {
+ toggleSplitScreenMode(-1 /* metricsDockAction */, -1 /* metricsUndockAction */);
+ }
+
+ @Override
+ public void preloadRecentApps() {
+ int msg = MSG_PRELOAD_RECENT_APPS;
+ mHandler.removeMessages(msg);
+ mHandler.sendEmptyMessage(msg);
+ }
+
+ @Override
+ public void cancelPreloadRecentApps() {
+ int msg = MSG_CANCEL_PRELOAD_RECENT_APPS;
+ mHandler.removeMessages(msg);
+ mHandler.sendEmptyMessage(msg);
+ }
+
+ @Override
+ public void dismissKeyboardShortcutsMenu() {
+ int msg = MSG_DISMISS_KEYBOARD_SHORTCUTS_MENU;
+ mHandler.removeMessages(msg);
+ mHandler.sendEmptyMessage(msg);
+ }
+
+ @Override
+ public void toggleKeyboardShortcutsMenu(int deviceId) {
+ int msg = MSG_TOGGLE_KEYBOARD_SHORTCUTS_MENU;
+ mHandler.removeMessages(msg);
+ mHandler.obtainMessage(msg, deviceId, 0).sendToTarget();
+ }
+
+ /** Jumps to the next affiliated task in the group. */
+ public void showNextAffiliatedTask() {
+ int msg = MSG_SHOW_NEXT_AFFILIATED_TASK;
+ mHandler.removeMessages(msg);
+ mHandler.sendEmptyMessage(msg);
+ }
+
+ /** Jumps to the previous affiliated task in the group. */
+ public void showPreviousAffiliatedTask() {
+ int msg = MSG_SHOW_PREV_AFFILIATED_TASK;
+ mHandler.removeMessages(msg);
+ mHandler.sendEmptyMessage(msg);
+ }
+
+ protected void sendCloseSystemWindows(String reason) {
+ try {
+ ActivityManager.getService().closeSystemDialogs(reason);
+ } catch (RemoteException e) {
+ }
+ }
+
+ /** Proxy for RecentsComponent */
+
+ protected void showRecents(boolean triggeredFromAltTab, boolean fromHome) {
+ if (mRecents != null) {
+ sendCloseSystemWindows(SYSTEM_DIALOG_REASON_RECENT_APPS);
+ mRecents.showRecents(triggeredFromAltTab, fromHome);
+ }
+ }
+
+ protected void hideRecents(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
+ if (mRecents != null) {
+ mRecents.hideRecents(triggeredFromAltTab, triggeredFromHomeKey);
+ }
+ }
+
+ protected void toggleRecents() {
+ if (mRecents != null) {
+ mRecents.toggleRecents(mDisplay);
+ }
+ }
+
+ protected void preloadRecents() {
+ if (mRecents != null) {
+ mRecents.preloadRecents();
+ }
+ }
+
+ protected void toggleKeyboardShortcuts(int deviceId) {
+ KeyboardShortcuts.toggle(mContext, deviceId);
+ }
+
+ protected void dismissKeyboardShortcuts() {
+ KeyboardShortcuts.dismiss();
+ }
+
+ protected void cancelPreloadingRecents() {
+ if (mRecents != null) {
+ mRecents.cancelPreloadingRecents();
+ }
+ }
+
+ protected void showRecentsNextAffiliatedTask() {
+ if (mRecents != null) {
+ mRecents.showNextAffiliatedTask();
+ }
+ }
+
+ protected void showRecentsPreviousAffiliatedTask() {
+ if (mRecents != null) {
+ mRecents.showPrevAffiliatedTask();
+ }
+ }
+
+ /**
+ * Save the current "public" (locked and secure) state of the lockscreen.
+ */
+ public void setLockscreenPublicMode(boolean publicMode, int userId) {
+ mLockscreenPublicMode.put(userId, publicMode);
+ }
+
+ public boolean isLockscreenPublicMode(int userId) {
+ return mLockscreenPublicMode.get(userId, false);
+ }
+
+ /**
+ * Has the given user chosen to allow notifications to be shown even when the lockscreen is in
+ * "public" (secure & locked) mode?
+ */
+ public boolean userAllowsNotificationsInPublic(int userHandle) {
+ if (userHandle == UserHandle.USER_ALL) {
+ return true;
+ }
+
+ if (mUsersAllowingNotifications.indexOfKey(userHandle) < 0) {
+ final boolean allowed = 0 != Settings.Secure.getIntForUser(
+ mContext.getContentResolver(),
+ Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 0, userHandle);
+ mUsersAllowingNotifications.append(userHandle, allowed);
+ return allowed;
+ }
+
+ return mUsersAllowingNotifications.get(userHandle);
+ }
+
+ /**
+ * Has the given user chosen to allow their private (full) notifications to be shown even
+ * when the lockscreen is in "public" (secure & locked) mode?
+ */
+ public boolean userAllowsPrivateNotificationsInPublic(int userHandle) {
+ if (userHandle == UserHandle.USER_ALL) {
+ return true;
+ }
+
+ if (mUsersAllowingPrivateNotifications.indexOfKey(userHandle) < 0) {
+ final boolean allowedByUser = 0 != Settings.Secure.getIntForUser(
+ mContext.getContentResolver(),
+ Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, userHandle);
+ final boolean allowedByDpm = adminAllowsUnredactedNotifications(userHandle);
+ final boolean allowed = allowedByUser && allowedByDpm;
+ mUsersAllowingPrivateNotifications.append(userHandle, allowed);
+ return allowed;
+ }
+
+ return mUsersAllowingPrivateNotifications.get(userHandle);
+ }
+
+ private boolean adminAllowsUnredactedNotifications(int userHandle) {
+ if (userHandle == UserHandle.USER_ALL) {
+ return true;
+ }
+ final int dpmFlags = mDevicePolicyManager.getKeyguardDisabledFeatures(null /* admin */,
+ userHandle);
+ return (dpmFlags & DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS) == 0;
+ }
+
+ /**
+ * Returns true if we're on a secure lockscreen and the user wants to hide notification data.
+ * If so, notifications should be hidden.
+ */
+ @Override // NotificationData.Environment
+ public boolean shouldHideNotifications(int userId) {
+ return isLockscreenPublicMode(userId) && !userAllowsNotificationsInPublic(userId)
+ || (userId != mCurrentUserId && shouldHideNotifications(mCurrentUserId));
+ }
+
+ /**
+ * Returns true if we're on a secure lockscreen and the user wants to hide notifications via
+ * package-specific override.
+ */
+ @Override // NotificationDate.Environment
+ public boolean shouldHideNotifications(String key) {
+ return isLockscreenPublicMode(mCurrentUserId)
+ && mNotificationData.getVisibilityOverride(key) == Notification.VISIBILITY_SECRET;
+ }
+
+ /**
+ * Returns true if we're on a secure lockscreen.
+ */
+ @Override // NotificationData.Environment
+ public boolean isSecurelyLocked(int userId) {
+ return isLockscreenPublicMode(userId);
+ }
+
+ public void onNotificationClear(StatusBarNotification notification) {
+ try {
+ mBarService.onNotificationClear(
+ notification.getPackageName(),
+ notification.getTag(),
+ notification.getId(),
+ notification.getUserId());
+ } catch (android.os.RemoteException ex) {
+ // oh well
+ }
+ }
+
+ /**
+ * Called when the notification panel layouts
+ */
+ public void onPanelLaidOut() {
+ if (mState == StatusBarState.KEYGUARD) {
+ // Since the number of notifications is determined based on the height of the view, we
+ // need to update them.
+ int maxBefore = getMaxKeyguardNotifications(false /* recompute */);
+ int maxNotifications = getMaxKeyguardNotifications(true /* recompute */);
+ if (maxBefore != maxNotifications) {
+ updateRowStates();
+ }
+ }
+ }
+
+ protected boolean inflateViews(Entry entry, ViewGroup parent) {
+ PackageManager pmUser = getPackageManagerForUser(mContext,
+ entry.notification.getUser().getIdentifier());
+
+ final StatusBarNotification sbn = entry.notification;
+ boolean isLowPriority = mNotificationData.isAmbient(sbn.getKey());
+ try {
+ entry.cacheContentViews(mContext, null, isLowPriority);
+ } catch (RuntimeException e) {
+ Log.e(TAG, "Unable to get notification remote views", e);
+ return false;
+ }
+
+ final RemoteViews contentView = entry.cachedContentView;
+ final RemoteViews bigContentView = entry.cachedBigContentView;
+ final RemoteViews headsUpContentView = entry.cachedHeadsUpContentView;
+ final RemoteViews publicContentView = entry.cachedPublicContentView;
+ final RemoteViews ambientContentView = entry.cachedAmbientContentView;
+
+ if (contentView == null) {
+ Log.v(TAG, "no contentView for: " + sbn.getNotification());
+ return false;
+ }
+
+ if (DEBUG) {
+ Log.v(TAG, "publicContentView: " + publicContentView);
+ }
+
+ ExpandableNotificationRow row;
+
+ // Stash away previous user expansion state so we can restore it at
+ // the end.
+ boolean hasUserChangedExpansion = false;
+ boolean userExpanded = false;
+ boolean userLocked = false;
+
+ if (entry.row != null) {
+ row = entry.row;
+ hasUserChangedExpansion = row.hasUserChangedExpansion();
+ userExpanded = row.isUserExpanded();
+ userLocked = row.isUserLocked();
+ entry.reset();
+ if (hasUserChangedExpansion) {
+ row.setUserExpanded(userExpanded);
+ }
+ } else {
+ // create the row view
+ LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
+ Context.LAYOUT_INFLATER_SERVICE);
+ row = (ExpandableNotificationRow) inflater.inflate(R.layout.status_bar_notification_row,
+ parent, false);
+ row.setExpansionLogger(this, entry.notification.getKey());
+ row.setGroupManager(mGroupManager);
+ row.setHeadsUpManager(mHeadsUpManager);
+ row.setRemoteInputController(mRemoteInputController);
+ row.setOnExpandClickListener(this);
+
+ // Get the app name.
+ // Note that Notification.Builder#bindHeaderAppName has similar logic
+ // but since this field is used in the guts, it must be accurate.
+ // Therefore we will only show the application label, or, failing that, the
+ // package name. No substitutions.
+ final String pkg = sbn.getPackageName();
+ String appname = pkg;
+ try {
+ final ApplicationInfo info = pmUser.getApplicationInfo(pkg,
+ PackageManager.MATCH_UNINSTALLED_PACKAGES
+ | PackageManager.MATCH_DISABLED_COMPONENTS);
+ if (info != null) {
+ appname = String.valueOf(pmUser.getApplicationLabel(info));
+ }
+ } catch (NameNotFoundException e) {
+ // Do nothing
+ }
+ row.setAppName(appname);
+ }
+
+ bindDismissRunnable(row);
+ row.setIsLowPriority(isLowPriority);
+
+ // NB: the large icon is now handled entirely by the template
+
+ // bind the click event to the content area
+ NotificationContentView contentContainer = row.getPrivateLayout();
+ NotificationContentView contentContainerPublic = row.getPublicLayout();
+
+ row.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
+ if (ENABLE_REMOTE_INPUT) {
+ row.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);
+ }
+
+ mNotificationClicker.register(row, sbn);
+
+ // set up the adaptive layout
+ View contentViewLocal = null;
+ View bigContentViewLocal = null;
+ View headsUpContentViewLocal = null;
+ View publicViewLocal = null;
+ View ambientViewLocal = null;
+ try {
+ contentViewLocal = contentView.apply(
+ sbn.getPackageContext(mContext),
+ contentContainer,
+ mOnClickHandler);
+ if (bigContentView != null) {
+ bigContentViewLocal = bigContentView.apply(
+ sbn.getPackageContext(mContext),
+ contentContainer,
+ mOnClickHandler);
+ }
+ if (headsUpContentView != null) {
+ headsUpContentViewLocal = headsUpContentView.apply(
+ sbn.getPackageContext(mContext),
+ contentContainer,
+ mOnClickHandler);
+ }
+ if (publicContentView != null) {
+ publicViewLocal = publicContentView.apply(
+ sbn.getPackageContext(mContext),
+ contentContainerPublic, mOnClickHandler);
+ }
+ if (ambientContentView != null) {
+ ambientViewLocal = ambientContentView.apply(
+ sbn.getPackageContext(mContext),
+ contentContainer, mOnClickHandler);
+ }
+
+ if (contentViewLocal != null) {
+ contentViewLocal.setIsRootNamespace(true);
+ contentContainer.setContractedChild(contentViewLocal);
+ }
+ if (bigContentViewLocal != null) {
+ bigContentViewLocal.setIsRootNamespace(true);
+ contentContainer.setExpandedChild(bigContentViewLocal);
+ }
+ if (headsUpContentViewLocal != null) {
+ headsUpContentViewLocal.setIsRootNamespace(true);
+ contentContainer.setHeadsUpChild(headsUpContentViewLocal);
+ }
+ if (publicViewLocal != null) {
+ publicViewLocal.setIsRootNamespace(true);
+ contentContainerPublic.setContractedChild(publicViewLocal);
+ }
+
+ if (ambientViewLocal != null) {
+ ambientViewLocal.setIsRootNamespace(true);
+ contentContainer.setAmbientChild(ambientViewLocal);
+ }
+ }
+ catch (RuntimeException e) {
+ final String ident = sbn.getPackageName() + "/0x" + Integer.toHexString(sbn.getId());
+ Log.e(TAG, "couldn't inflate view for notification " + ident, e);
+ return false;
+ }
+
+ // Extract target SDK version.
+ try {
+ ApplicationInfo info = pmUser.getApplicationInfo(sbn.getPackageName(), 0);
+ entry.targetSdk = info.targetSdkVersion;
+ } catch (NameNotFoundException ex) {
+ Log.e(TAG, "Failed looking up ApplicationInfo for " + sbn.getPackageName(), ex);
+ }
+ entry.autoRedacted = entry.notification.getNotification().publicVersion == null;
+
+ entry.row = row;
+ entry.row.setOnActivatedListener(this);
+ entry.row.setExpandable(bigContentViewLocal != null);
+
+ applyColorsAndBackgrounds(sbn, entry);
+
+ // Restore previous flags.
+ if (hasUserChangedExpansion) {
+ // Note: setUserExpanded() conveniently ignores calls with
+ // userExpanded=true if !isExpandable().
+ row.setUserExpanded(userExpanded);
+ }
+ row.setUserLocked(userLocked);
+ row.onNotificationUpdated(entry);
+ return true;
+ }
+
+ /**
+ * Adds RemoteInput actions from the WearableExtender; to be removed once more apps support this
+ * via first-class API.
+ *
+ * TODO: Remove once enough apps specify remote inputs on their own.
+ */
+ private void processForRemoteInput(Notification n) {
+ if (!ENABLE_REMOTE_INPUT) return;
+
+ if (n.extras != null && n.extras.containsKey("android.wearable.EXTENSIONS") &&
+ (n.actions == null || n.actions.length == 0)) {
+ Notification.Action viableAction = null;
+ Notification.WearableExtender we = new Notification.WearableExtender(n);
+
+ List<Notification.Action> actions = we.getActions();
+ final int numActions = actions.size();
+
+ for (int i = 0; i < numActions; i++) {
+ Notification.Action action = actions.get(i);
+ if (action == null) {
+ continue;
+ }
+ RemoteInput[] remoteInputs = action.getRemoteInputs();
+ if (remoteInputs == null) {
+ continue;
+ }
+ for (RemoteInput ri : remoteInputs) {
+ if (ri.getAllowFreeFormInput()) {
+ viableAction = action;
+ break;
+ }
+ }
+ if (viableAction != null) {
+ break;
+ }
+ }
+
+ if (viableAction != null) {
+ Notification.Builder rebuilder = Notification.Builder.recoverBuilder(mContext, n);
+ rebuilder.setActions(viableAction);
+ rebuilder.build(); // will rewrite n
+ }
+ }
+ }
+
+ public void startPendingIntentDismissingKeyguard(final PendingIntent intent) {
+ if (!isDeviceProvisioned()) return;
+
+ final boolean keyguardShowing = mStatusBarKeyguardViewManager.isShowing();
+ final boolean afterKeyguardGone = intent.isActivity()
+ && PreviewInflater.wouldLaunchResolverActivity(mContext, intent.getIntent(),
+ mCurrentUserId);
+ dismissKeyguardThenExecute(new OnDismissAction() {
+ @Override
+ public boolean onDismiss() {
+ new Thread() {
+ @Override
+ public void run() {
+ try {
+ // The intent we are sending is for the application, which
+ // won't have permission to immediately start an activity after
+ // the user switches to home. We know it is safe to do at this
+ // point, so make sure new activity switches are now allowed.
+ ActivityManager.getService().resumeAppSwitches();
+ } catch (RemoteException e) {
+ }
+ try {
+ intent.send(null, 0, null, null, null, null, getActivityOptions());
+ } catch (PendingIntent.CanceledException e) {
+ // the stack trace isn't very helpful here.
+ // Just log the exception message.
+ Log.w(TAG, "Sending intent failed: " + e);
+
+ // TODO: Dismiss Keyguard.
+ }
+ if (intent.isActivity()) {
+ mAssistManager.hideAssist();
+ }
+ }
+ }.start();
+
+ // close the shade if it was open
+ animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL,
+ true /* force */, true /* delayed */);
+ visibilityChanged(false);
+
+ return true;
+ }
+ }, afterKeyguardGone);
+ }
+
+
+ private final class NotificationClicker implements View.OnClickListener {
+ private final int[] mTmpInt2 = new int[2];
+
+ @Override
+ public void onClick(final View v) {
+ if (!(v instanceof ExpandableNotificationRow)) {
+ Log.e(TAG, "NotificationClicker called on a view that is not a notification row.");
+ return;
+ }
+
+ v.getLocationInWindow(mTmpInt2);
+ wakeUpIfDozing(SystemClock.uptimeMillis(),
+ new PointF(mTmpInt2[0] + v.getWidth() / 2, mTmpInt2[1] + v.getHeight() / 2));
+
+ final ExpandableNotificationRow row = (ExpandableNotificationRow) v;
+ final StatusBarNotification sbn = row.getStatusBarNotification();
+ if (sbn == null) {
+ Log.e(TAG, "NotificationClicker called on an unclickable notification,");
+ return;
+ }
+
+ // Check if the notification is displaying the gear, if so slide notification back
+ if (row.getSettingsRow() != null && row.getSettingsRow().isVisible()) {
+ row.animateTranslateNotification(0);
+ return;
+ }
+
+ Notification notification = sbn.getNotification();
+ final PendingIntent intent = notification.contentIntent != null
+ ? notification.contentIntent
+ : notification.fullScreenIntent;
+ final String notificationKey = sbn.getKey();
+
+ // Mark notification for one frame.
+ row.setJustClicked(true);
+ DejankUtils.postAfterTraversal(new Runnable() {
+ @Override
+ public void run() {
+ row.setJustClicked(false);
+ }
+ });
+
+ final boolean keyguardShowing = mStatusBarKeyguardViewManager.isShowing();
+ final boolean afterKeyguardGone = intent.isActivity()
+ && PreviewInflater.wouldLaunchResolverActivity(mContext, intent.getIntent(),
+ mCurrentUserId);
+ dismissKeyguardThenExecute(new OnDismissAction() {
+ @Override
+ public boolean onDismiss() {
+ if (mHeadsUpManager != null && mHeadsUpManager.isHeadsUp(notificationKey)) {
+ // Release the HUN notification to the shade.
+
+ if (isPanelFullyCollapsed()) {
+ HeadsUpManager.setIsClickedNotification(row, true);
+ }
+ //
+ // In most cases, when FLAG_AUTO_CANCEL is set, the notification will
+ // become canceled shortly by NoMan, but we can't assume that.
+ mHeadsUpManager.releaseImmediately(notificationKey);
+ }
+ StatusBarNotification parentToCancel = null;
+ if (shouldAutoCancel(sbn) && mGroupManager.isOnlyChildInGroup(sbn)) {
+ StatusBarNotification summarySbn = mGroupManager.getLogicalGroupSummary(sbn)
+ .getStatusBarNotification();
+ if (shouldAutoCancel(summarySbn)) {
+ parentToCancel = summarySbn;
+ }
+ }
+ final StatusBarNotification parentToCancelFinal = parentToCancel;
+ new Thread() {
+ @Override
+ public void run() {
+ try {
+ // The intent we are sending is for the application, which
+ // won't have permission to immediately start an activity after
+ // the user switches to home. We know it is safe to do at this
+ // point, so make sure new activity switches are now allowed.
+ ActivityManager.getService().resumeAppSwitches();
+ } catch (RemoteException e) {
+ }
+ if (intent != null) {
+ // If we are launching a work activity and require to launch
+ // separate work challenge, we defer the activity action and cancel
+ // notification until work challenge is unlocked.
+ if (intent.isActivity()) {
+ final int userId = intent.getCreatorUserHandle()
+ .getIdentifier();
+ if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)
+ && mKeyguardManager.isDeviceLocked(userId)) {
+ boolean canBypass = false;
+ try {
+ canBypass = ActivityManager.getService()
+ .canBypassWorkChallenge(intent);
+ } catch (RemoteException e) {
+ }
+ // For direct-boot aware activities, they can be shown when
+ // the device is still locked without triggering the work
+ // challenge.
+ if ((!canBypass) && startWorkChallengeIfNecessary(userId,
+ intent.getIntentSender(), notificationKey)) {
+ // Show work challenge, do not run PendingIntent and
+ // remove notification
+ return;
+ }
+ }
+ }
+ try {
+ intent.send(null, 0, null, null, null, null,
+ getActivityOptions());
+ } catch (PendingIntent.CanceledException e) {
+ // the stack trace isn't very helpful here.
+ // Just log the exception message.
+ Log.w(TAG, "Sending contentIntent failed: " + e);
+
+ // TODO: Dismiss Keyguard.
+ }
+ if (intent.isActivity()) {
+ mAssistManager.hideAssist();
+ }
+ }
+
+ try {
+ mBarService.onNotificationClick(notificationKey);
+ } catch (RemoteException ex) {
+ // system process is dead if we're here.
+ }
+ if (parentToCancelFinal != null) {
+ // We have to post it to the UI thread for synchronization
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ Runnable removeRunnable = new Runnable() {
+ @Override
+ public void run() {
+ performRemoveNotification(parentToCancelFinal);
+ }
+ };
+ if (isCollapsing()) {
+ // To avoid lags we're only performing the remove
+ // after the shade was collapsed
+ addPostCollapseAction(removeRunnable);
+ } else {
+ removeRunnable.run();
+ }
+ }
+ });
+ }
+ }
+ }.start();
+
+ // close the shade if it was open
+ animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL,
+ true /* force */, true /* delayed */);
+ visibilityChanged(false);
+
+ return true;
+ }
+ }, afterKeyguardGone);
+ }
+
+ private boolean shouldAutoCancel(StatusBarNotification sbn) {
+ int flags = sbn.getNotification().flags;
+ if ((flags & Notification.FLAG_AUTO_CANCEL) != Notification.FLAG_AUTO_CANCEL) {
+ return false;
+ }
+ if ((flags & Notification.FLAG_FOREGROUND_SERVICE) != 0) {
+ return false;
+ }
+ return true;
+ }
+
+ public void register(ExpandableNotificationRow row, StatusBarNotification sbn) {
+ Notification notification = sbn.getNotification();
+ if (notification.contentIntent != null || notification.fullScreenIntent != null) {
+ row.setOnClickListener(this);
+ } else {
+ row.setOnClickListener(null);
+ }
+ }
+ }
+
+ protected Bundle getActivityOptions() {
+ // Anything launched from the notification shade should always go into the
+ // fullscreen stack.
+ ActivityOptions options = ActivityOptions.makeBasic();
+ options.setLaunchStackId(StackId.FULLSCREEN_WORKSPACE_STACK_ID);
+ return options.toBundle();
+ }
+
+ protected void visibilityChanged(boolean visible) {
+ if (mVisible != visible) {
+ mVisible = visible;
+ if (!visible) {
+ dismissPopups();
+ }
+ }
+ updateVisibleToUser();
+ }
+
+ protected void updateVisibleToUser() {
+ boolean oldVisibleToUser = mVisibleToUser;
+ mVisibleToUser = mVisible && mDeviceInteractive;
+
+ if (oldVisibleToUser != mVisibleToUser) {
+ handleVisibleToUserChanged(mVisibleToUser);
+ }
+ }
+
+ /**
+ * Clear Buzz/Beep/Blink.
+ */
+ public void clearNotificationEffects() {
+ try {
+ mBarService.clearNotificationEffects();
+ } catch (RemoteException e) {
+ // Won't fail unless the world has ended.
+ }
+ }
+
+ /**
+ * Cancel this notification and tell the StatusBarManagerService / NotificationManagerService
+ * about the failure.
+ *
+ * WARNING: this will call back into us. Don't hold any locks.
+ */
+ void handleNotificationError(StatusBarNotification n, String message) {
+ removeNotification(n.getKey(), null);
+ try {
+ mBarService.onNotificationError(n.getPackageName(), n.getTag(), n.getId(), n.getUid(),
+ n.getInitialPid(), message, n.getUserId());
+ } catch (RemoteException ex) {
+ // The end is nigh.
+ }
+ }
+
+ protected StatusBarNotification removeNotificationViews(String key, RankingMap ranking) {
+ NotificationData.Entry entry = mNotificationData.remove(key, ranking);
+ if (entry == null) {
+ Log.w(TAG, "removeNotification for unknown key: " + key);
+ return null;
+ }
+ updateNotifications();
+ return entry.notification;
+ }
+
+ protected NotificationData.Entry createNotificationViews(StatusBarNotification sbn) {
+ if (DEBUG) {
+ Log.d(TAG, "createNotificationViews(notification=" + sbn);
+ }
+ NotificationData.Entry entry = new NotificationData.Entry(sbn);
+ try {
+ entry.createIcons(mContext, sbn);
+ } catch (NotificationData.IconException exception) {
+ handleNotificationError(sbn, exception.getMessage());
+ }
+
+ // Construct the expanded view.
+ if (!inflateViews(entry, mStackScroller)) {
+ handleNotificationError(sbn, "Couldn't expand RemoteViews for: " + sbn);
+ return null;
+ }
+ return entry;
+ }
+
+ protected void addNotificationViews(Entry entry, RankingMap ranking) {
+ if (entry == null) {
+ return;
+ }
+ // Add the expanded view and icon.
+ mNotificationData.add(entry, ranking);
+ updateNotifications();
+ }
+
+ /**
+ * Updates expanded, dimmed and locked states of notification rows.
+ */
+ protected void updateRowStates() {
+ final int N = mStackScroller.getChildCount();
+
+ int visibleNotifications = 0;
+ boolean onKeyguard = mState == StatusBarState.KEYGUARD;
+ int maxNotifications = -1;
+ if (onKeyguard) {
+ maxNotifications = getMaxKeyguardNotifications(true /* recompute */);
+ }
+ mStackScroller.setMaxDisplayedNotifications(maxNotifications);
+ Stack<ExpandableNotificationRow> stack = new Stack<>();
+ for (int i = N - 1; i >= 0; i--) {
+ View child = mStackScroller.getChildAt(i);
+ if (!(child instanceof ExpandableNotificationRow)) {
+ continue;
+ }
+ stack.push((ExpandableNotificationRow) child);
+ }
+ while(!stack.isEmpty()) {
+ ExpandableNotificationRow row = stack.pop();
+ NotificationData.Entry entry = row.getEntry();
+ boolean childNotification = mGroupManager.isChildInGroupWithSummary(entry.notification);
+ if (onKeyguard) {
+ row.setOnKeyguard(true);
+ } else {
+ row.setOnKeyguard(false);
+ row.setSystemExpanded(visibleNotifications == 0 && !childNotification);
+ }
+ entry.row.setShowAmbient(isDozing());
+ int userId = entry.notification.getUserId();
+ boolean suppressedSummary = mGroupManager.isSummaryOfSuppressedGroup(
+ entry.notification) && !entry.row.isRemoved();
+ boolean showOnKeyguard = shouldShowOnKeyguard(entry.notification);
+ if (suppressedSummary
+ || (isLockscreenPublicMode(userId) && !mShowLockscreenNotifications)
+ || (onKeyguard && !showOnKeyguard)) {
+ entry.row.setVisibility(View.GONE);
+ } else {
+ boolean wasGone = entry.row.getVisibility() == View.GONE;
+ if (wasGone) {
+ entry.row.setVisibility(View.VISIBLE);
+ }
+ if (!childNotification && !entry.row.isRemoved()) {
+ if (wasGone) {
+ // notify the scroller of a child addition
+ mStackScroller.generateAddAnimation(entry.row,
+ !showOnKeyguard /* fromMoreCard */);
+ }
+ visibleNotifications++;
+ }
+ }
+ if (row.isSummaryWithChildren()) {
+ List<ExpandableNotificationRow> notificationChildren =
+ row.getNotificationChildren();
+ int size = notificationChildren.size();
+ for (int i = size - 1; i >= 0; i--) {
+ stack.push(notificationChildren.get(i));
+ }
+ }
+ }
+
+ mStackScroller.changeViewPosition(mDismissView, mStackScroller.getChildCount() - 1);
+ mStackScroller.changeViewPosition(mEmptyShadeView, mStackScroller.getChildCount() - 2);
+ mStackScroller.changeViewPosition(mNotificationShelf, mStackScroller.getChildCount() - 3);
+ }
+
+ public boolean shouldShowOnKeyguard(StatusBarNotification sbn) {
+ return mShowLockscreenNotifications && !mNotificationData.isAmbient(sbn.getKey());
+ }
+
+ // extended in StatusBar
+ protected void setShowLockscreenNotifications(boolean show) {
+ mShowLockscreenNotifications = show;
+ }
+
+ protected void setLockScreenAllowRemoteInput(boolean allowLockscreenRemoteInput) {
+ mAllowLockscreenRemoteInput = allowLockscreenRemoteInput;
+ }
+
+ private void updateLockscreenNotificationSetting() {
+ final boolean show = Settings.Secure.getIntForUser(mContext.getContentResolver(),
+ Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS,
+ 1,
+ mCurrentUserId) != 0;
+ final int dpmFlags = mDevicePolicyManager.getKeyguardDisabledFeatures(
+ null /* admin */, mCurrentUserId);
+ final boolean allowedByDpm = (dpmFlags
+ & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_NOTIFICATIONS) == 0;
+
+ setShowLockscreenNotifications(show && allowedByDpm);
+
+ if (ENABLE_LOCK_SCREEN_ALLOW_REMOTE_INPUT) {
+ final boolean remoteInput = Settings.Secure.getIntForUser(mContext.getContentResolver(),
+ Settings.Secure.LOCK_SCREEN_ALLOW_REMOTE_INPUT,
+ 0,
+ mCurrentUserId) != 0;
+ final boolean remoteInputDpm =
+ (dpmFlags & DevicePolicyManager.KEYGUARD_DISABLE_REMOTE_INPUT) == 0;
+
+ setLockScreenAllowRemoteInput(remoteInput && remoteInputDpm);
+ } else {
+ setLockScreenAllowRemoteInput(false);
+ }
+ }
+
+ public void updateNotification(StatusBarNotification notification, RankingMap ranking) {
+ if (DEBUG) Log.d(TAG, "updateNotification(" + notification + ")");
+
+ final String key = notification.getKey();
+ Entry entry = mNotificationData.get(key);
+ if (entry == null) {
+ return;
+ } else {
+ mHeadsUpEntriesToRemoveOnSwitch.remove(entry);
+ mRemoteInputEntriesToRemoveOnCollapse.remove(entry);
+ }
+
+ Notification n = notification.getNotification();
+ mNotificationData.updateRanking(ranking);
+
+ boolean applyInPlace;
+ try {
+ applyInPlace = entry.cacheContentViews(mContext, notification.getNotification(),
+ mNotificationData.isAmbient(key));
+ } catch (RuntimeException e) {
+ Log.e(TAG, "Unable to get notification remote views", e);
+ applyInPlace = false;
+ }
+ boolean shouldPeek = shouldPeek(entry, notification);
+ boolean alertAgain = alertAgain(entry, n);
+ if (DEBUG) {
+ Log.d(TAG, "applyInPlace=" + applyInPlace
+ + " shouldPeek=" + shouldPeek
+ + " alertAgain=" + alertAgain);
+ }
+
+ final StatusBarNotification oldNotification = entry.notification;
+ entry.notification = notification;
+ mGroupManager.onEntryUpdated(entry, oldNotification);
+
+ boolean updateSuccessful = false;
+ try {
+ if (applyInPlace) {
+ if (DEBUG) Log.d(TAG, "reusing notification for key: " + key);
+ try {
+ entry.updateIcons(mContext, n);
+ updateNotificationViews(entry, notification);
+ updateSuccessful = true;
+ } catch (RuntimeException e) {
+ // It failed to apply cleanly.
+ Log.w(TAG, "Couldn't reapply views for package " +
+ notification.getPackageName(), e);
+ }
+ }
+ if (!updateSuccessful) {
+ entry.updateIcons(mContext, n);
+ if (!inflateViews(entry, mStackScroller)) {
+ handleNotificationError(notification, "Couldn't update remote views for: "
+ + notification);
+ }
+ }
+ } catch (NotificationData.IconException e) {
+ handleNotificationError(notification, e.getMessage());
+ }
+ updateHeadsUp(key, entry, shouldPeek, alertAgain);
+ updateNotifications();
+
+ if (!notification.isClearable()) {
+ // The user may have performed a dismiss action on the notification, since it's
+ // not clearable we should snap it back.
+ mStackScroller.snapViewIfNeeded(entry.row);
+ }
+
+ if (DEBUG) {
+ // Is this for you?
+ boolean isForCurrentUser = isNotificationForCurrentProfiles(notification);
+ Log.d(TAG, "notification is " + (isForCurrentUser ? "" : "not ") + "for you");
+ }
+
+ setAreThereNotifications();
+ }
+
+ private void updateNotificationViews(Entry entry, StatusBarNotification sbn) {
+ final RemoteViews contentView = entry.cachedContentView;
+ final RemoteViews bigContentView = entry.cachedBigContentView;
+ final RemoteViews headsUpContentView = entry.cachedHeadsUpContentView;
+ final RemoteViews publicContentView = entry.cachedPublicContentView;
+
+ // Reapply the RemoteViews
+ contentView.reapply(mContext, entry.getContentView(), mOnClickHandler);
+ if (bigContentView != null && entry.getExpandedContentView() != null) {
+ bigContentView.reapply(sbn.getPackageContext(mContext),
+ entry.getExpandedContentView(),
+ mOnClickHandler);
+ }
+ View headsUpChild = entry.getHeadsUpContentView();
+ if (headsUpContentView != null && headsUpChild != null) {
+ headsUpContentView.reapply(sbn.getPackageContext(mContext),
+ headsUpChild, mOnClickHandler);
+ }
+ if (publicContentView != null && entry.getPublicContentView() != null) {
+ publicContentView.reapply(sbn.getPackageContext(mContext),
+ entry.getPublicContentView(), mOnClickHandler);
+ }
+ // update the contentIntent
+ mNotificationClicker.register(entry.row, sbn);
+
+ entry.row.onNotificationUpdated(entry);
+ entry.row.resetHeight();
+ }
+
+ protected void updatePublicContentView(Entry entry,
+ StatusBarNotification sbn) {
+ final RemoteViews publicContentView = entry.cachedPublicContentView;
+ View inflatedView = entry.getPublicContentView();
+ if (entry.autoRedacted && publicContentView != null && inflatedView != null) {
+ final boolean disabledByPolicy =
+ !adminAllowsUnredactedNotifications(entry.notification.getUserId());
+ String notificationHiddenText = mContext.getString(disabledByPolicy
+ ? com.android.internal.R.string.notification_hidden_by_policy_text
+ : com.android.internal.R.string.notification_hidden_text);
+ TextView titleView = (TextView) inflatedView.findViewById(android.R.id.title);
+ if (titleView != null
+ && !titleView.getText().toString().equals(notificationHiddenText)) {
+ publicContentView.setTextViewText(android.R.id.title, notificationHiddenText);
+ publicContentView.reapply(sbn.getPackageContext(mContext),
+ inflatedView, mOnClickHandler);
+ entry.row.onNotificationUpdated(entry);
+ }
+ }
+ }
+
+ protected void notifyHeadsUpScreenOff() {
+ maybeEscalateHeadsUp();
+ }
+
+ private boolean alertAgain(Entry oldEntry, Notification newNotification) {
+ return oldEntry == null || !oldEntry.hasInterrupted()
+ || (newNotification.flags & Notification.FLAG_ONLY_ALERT_ONCE) == 0;
+ }
+
+ protected boolean shouldPeek(Entry entry) {
+ return shouldPeek(entry, entry.notification);
+ }
+
+ protected boolean shouldPeek(Entry entry, StatusBarNotification sbn) {
+ if (!mUseHeadsUp || isDeviceInVrMode()) {
+ return false;
+ }
+
+ if (mNotificationData.shouldFilterOut(sbn)) {
+ if (DEBUG) Log.d(TAG, "No peeking: filtered notification: " + sbn.getKey());
+ return false;
+ }
+
+ boolean inUse = mPowerManager.isScreenOn();
+ try {
+ inUse = inUse && !mDreamManager.isDreaming();
+ } catch (RemoteException e) {
+ Log.d(TAG, "failed to query dream manager", e);
+ }
+
+ if (!inUse && !isDozing()) {
+ if (DEBUG) {
+ Log.d(TAG, "No peeking: not in use: " + sbn.getKey());
+ }
+ return false;
+ }
+
+ if (mNotificationData.shouldSuppressScreenOn(sbn.getKey())) {
+ if (DEBUG) Log.d(TAG, "No peeking: suppressed by DND: " + sbn.getKey());
+ return false;
+ }
+
+ if (entry.hasJustLaunchedFullScreenIntent()) {
+ if (DEBUG) Log.d(TAG, "No peeking: recent fullscreen: " + sbn.getKey());
+ return false;
+ }
+
+ if (isSnoozedPackage(sbn)) {
+ if (DEBUG) Log.d(TAG, "No peeking: snoozed package: " + sbn.getKey());
+ return false;
+ }
+
+ if (mNotificationData.getImportance(sbn.getKey()) < NotificationManager.IMPORTANCE_HIGH) {
+ if (DEBUG) Log.d(TAG, "No peeking: unimportant notification: " + sbn.getKey());
+ return false;
+ }
+
+ if (sbn.getNotification().fullScreenIntent != null) {
+ if (mAccessibilityManager.isTouchExplorationEnabled()) {
+ if (DEBUG) Log.d(TAG, "No peeking: accessible fullscreen: " + sbn.getKey());
+ return false;
+ } else {
+ // we only allow head-up on the lockscreen if it doesn't have a fullscreen intent
+ return !mStatusBarKeyguardViewManager.isShowing()
+ || mStatusBarKeyguardViewManager.isOccluded();
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * @return Whether the security bouncer from Keyguard is showing.
+ */
+ public boolean isBouncerShowing() {
+ return mBouncerShowing;
+ }
+
+ /**
+ * @return a PackageManger for userId or if userId is < 0 (USER_ALL etc) then
+ * return PackageManager for mContext
+ */
+ public static PackageManager getPackageManagerForUser(Context context, int userId) {
+ Context contextForUser = context;
+ // UserHandle defines special userId as negative values, e.g. USER_ALL
+ if (userId >= 0) {
+ try {
+ // Create a context for the correct user so if a package isn't installed
+ // for user 0 we can still load information about the package.
+ contextForUser =
+ context.createPackageContextAsUser(context.getPackageName(),
+ Context.CONTEXT_RESTRICTED,
+ new UserHandle(userId));
+ } catch (NameNotFoundException e) {
+ // Shouldn't fail to find the package name for system ui.
+ }
+ }
+ return contextForUser.getPackageManager();
+ }
+
+ @Override
+ public void logNotificationExpansion(String key, boolean userAction, boolean expanded) {
+ try {
+ mBarService.onNotificationExpansionChanged(key, userAction, expanded);
+ } catch (RemoteException e) {
+ // Ignore.
+ }
+ }
+
+ public boolean isKeyguardSecure() {
+ if (mStatusBarKeyguardViewManager == null) {
+ // startKeyguard() hasn't been called yet, so we don't know.
+ // Make sure anything that needs to know isKeyguardSecure() checks and re-checks this
+ // value onVisibilityChanged().
+ Slog.w(TAG, "isKeyguardSecure() called before startKeyguard(), returning false",
+ new Throwable());
+ return false;
+ }
+ return mStatusBarKeyguardViewManager.isSecure();
+ }
+
+ @Override
+ public void showAssistDisclosure() {
+ if (mAssistManager != null) {
+ mAssistManager.showDisclosure();
+ }
+ }
+
+ @Override
+ public void startAssist(Bundle args) {
+ if (mAssistManager != null) {
+ mAssistManager.startAssist(args);
+ }
+ }
+ // End Extra BaseStatusBarMethods.
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
index a0425e6..46ca3c6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
@@ -17,7 +17,6 @@
package com.android.systemui.statusbar.phone;
import android.animation.ArgbEvaluator;
-import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.Resources;
@@ -25,8 +24,6 @@
import android.graphics.Rect;
import android.graphics.drawable.Icon;
import android.os.Bundle;
-import android.os.Handler;
-import android.os.SystemClock;
import android.os.UserHandle;
import android.text.TextUtils;
import android.util.ArraySet;
@@ -64,7 +61,7 @@
public static final int DEFAULT_ICON_TINT = Color.WHITE;
private Context mContext;
- private PhoneStatusBar mPhoneStatusBar;
+ private StatusBar mStatusBar;
private DemoStatusIcons mDemoStatusIcons;
private LinearLayout mSystemIconArea;
@@ -100,11 +97,11 @@
private final ArraySet<String> mIconBlacklist = new ArraySet<>();
public StatusBarIconController(Context context, View statusBar, View keyguardStatusBar,
- PhoneStatusBar phoneStatusBar) {
+ StatusBar phoneStatusBar) {
super(context.getResources().getStringArray(
com.android.internal.R.array.config_statusBarIcons));
mContext = context;
- mPhoneStatusBar = phoneStatusBar;
+ mStatusBar = phoneStatusBar;
mSystemIconArea = (LinearLayout) statusBar.findViewById(R.id.system_icon_area);
mStatusIcons = (LinearLayout) statusBar.findViewById(R.id.statusIcons);
mSignalCluster = (SignalClusterView) statusBar.findViewById(R.id.signal_cluster);
@@ -405,11 +402,11 @@
.withEndAction(null);
// Synchronize the motion with the Keyguard fading if necessary.
- if (mPhoneStatusBar.isKeyguardFadingAway()) {
+ if (mStatusBar.isKeyguardFadingAway()) {
v.animate()
- .setDuration(mPhoneStatusBar.getKeyguardFadingAwayDuration())
+ .setDuration(mStatusBar.getKeyguardFadingAwayDuration())
.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN)
- .setStartDelay(mPhoneStatusBar.getKeyguardFadingAwayDelay())
+ .setStartDelay(mStatusBar.getKeyguardFadingAwayDelay())
.start();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 7e5a7da..8d5d890 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -70,7 +70,7 @@
protected LockPatternUtils mLockPatternUtils;
protected ViewMediatorCallback mViewMediatorCallback;
- protected PhoneStatusBar mPhoneStatusBar;
+ protected StatusBar mStatusBar;
private ScrimController mScrimController;
private FingerprintUnlockController mFingerprintUnlockController;
@@ -103,12 +103,12 @@
mLockPatternUtils = lockPatternUtils;
}
- public void registerStatusBar(PhoneStatusBar phoneStatusBar,
+ public void registerStatusBar(StatusBar statusBar,
ViewGroup container, StatusBarWindowManager statusBarWindowManager,
ScrimController scrimController,
FingerprintUnlockController fingerprintUnlockController,
DismissCallbackRegistry dismissCallbackRegistry) {
- mPhoneStatusBar = phoneStatusBar;
+ mStatusBar = statusBar;
mContainer = container;
mStatusBarWindowManager = statusBarWindowManager;
mScrimController = scrimController;
@@ -136,10 +136,10 @@
if (mBouncer.needsFullscreenBouncer()) {
// The keyguard might be showing (already). So we need to hide it.
- mPhoneStatusBar.hideKeyguard();
+ mStatusBar.hideKeyguard();
mBouncer.show(true /* resetSecuritySelection */);
} else {
- mPhoneStatusBar.showKeyguard();
+ mStatusBar.showKeyguard();
if (hideBouncerWhenShowing) {
mBouncer.hide(false /* destroyView */);
mBouncer.prepare();
@@ -180,8 +180,8 @@
public void reset(boolean hideBouncerWhenShowing) {
if (mShowing) {
if (mOccluded) {
- mPhoneStatusBar.hideKeyguard();
- mPhoneStatusBar.stopWaitingForKeyguardExit();
+ mStatusBar.hideKeyguard();
+ mStatusBar.stopWaitingForKeyguardExit();
mBouncer.hide(false /* destroyView */);
} else {
showBouncerOrKeyguard(hideBouncerWhenShowing);
@@ -192,12 +192,12 @@
}
public void onStartedGoingToSleep() {
- mPhoneStatusBar.onStartedGoingToSleep();
+ mStatusBar.onStartedGoingToSleep();
}
public void onFinishedGoingToSleep() {
mDeviceInteractive = false;
- mPhoneStatusBar.onFinishedGoingToSleep();
+ mStatusBar.onFinishedGoingToSleep();
mBouncer.onScreenTurnedOff();
}
@@ -205,13 +205,13 @@
Trace.beginSection("StatusBarKeyguardViewManager#onStartedWakingUp");
mDeviceInteractive = true;
mDeviceWillWakeUp = false;
- mPhoneStatusBar.onStartedWakingUp();
+ mStatusBar.onStartedWakingUp();
Trace.endSection();
}
public void onScreenTurningOn() {
Trace.beginSection("StatusBarKeyguardViewManager#onScreenTurningOn");
- mPhoneStatusBar.onScreenTurningOn();
+ mStatusBar.onScreenTurningOn();
Trace.endSection();
}
@@ -228,7 +228,7 @@
true /* skipFirstFrame */);
updateStates();
}
- mPhoneStatusBar.onScreenTurnedOn();
+ mStatusBar.onScreenTurnedOn();
Trace.endSection();
}
@@ -240,7 +240,7 @@
public void onScreenTurnedOff() {
mScreenTurnedOn = false;
- mPhoneStatusBar.onScreenTurnedOff();
+ mStatusBar.onScreenTurnedOff();
}
public void notifyDeviceWakeUpRequested() {
@@ -257,12 +257,12 @@
public void setOccluded(boolean occluded, boolean animate) {
if (occluded != mOccluded) {
- mPhoneStatusBar.onKeyguardOccludedChanged(occluded);
+ mStatusBar.onKeyguardOccludedChanged(occluded);
}
if (occluded && !mOccluded && mShowing) {
- if (mPhoneStatusBar.isInLaunchTransition()) {
+ if (mStatusBar.isInLaunchTransition()) {
mOccluded = true;
- mPhoneStatusBar.fadeKeyguardAfterLaunchTransition(null /* beforeFading */,
+ mStatusBar.fadeKeyguardAfterLaunchTransition(null /* beforeFading */,
new Runnable() {
@Override
public void run() {
@@ -275,7 +275,7 @@
}
mOccluded = occluded;
if (mShowing) {
- mPhoneStatusBar.updateMediaMetaData(false, animate && !occluded);
+ mStatusBar.updateMediaMetaData(false, animate && !occluded);
}
mStatusBarWindowManager.setKeyguardOccluded(occluded);
@@ -283,7 +283,7 @@
// a FLAG_DISMISS_KEYGUARD_ACTIVITY.
reset(false /* hideBouncerWhenShowing*/);
if (animate && !occluded && mShowing) {
- mPhoneStatusBar.animateKeyguardUnoccluding();
+ mStatusBar.animateKeyguardUnoccluding();
}
}
@@ -318,8 +318,8 @@
long uptimeMillis = SystemClock.uptimeMillis();
long delay = Math.max(0, startTime + HIDE_TIMING_CORRECTION_MS - uptimeMillis);
- if (mPhoneStatusBar.isInLaunchTransition() ) {
- mPhoneStatusBar.fadeKeyguardAfterLaunchTransition(new Runnable() {
+ if (mStatusBar.isInLaunchTransition() ) {
+ mStatusBar.fadeKeyguardAfterLaunchTransition(new Runnable() {
@Override
public void run() {
mStatusBarWindowManager.setKeyguardShowing(false);
@@ -327,14 +327,14 @@
mBouncer.hide(true /* destroyView */);
updateStates();
mScrimController.animateKeyguardFadingOut(
- PhoneStatusBar.FADE_KEYGUARD_START_DELAY,
- PhoneStatusBar.FADE_KEYGUARD_DURATION, null,
+ StatusBar.FADE_KEYGUARD_START_DELAY,
+ StatusBar.FADE_KEYGUARD_DURATION, null,
false /* skipFirstFrame */);
}
}, new Runnable() {
@Override
public void run() {
- mPhoneStatusBar.hideKeyguard();
+ mStatusBar.hideKeyguard();
mStatusBarWindowManager.setKeyguardFadingAway(false);
mViewMediatorCallback.keyguardGone();
executeAfterKeyguardGoneAction();
@@ -348,19 +348,19 @@
delay = 0;
fadeoutDuration = 240;
}
- mPhoneStatusBar.setKeyguardFadingAway(startTime, delay, fadeoutDuration);
+ mStatusBar.setKeyguardFadingAway(startTime, delay, fadeoutDuration);
mFingerprintUnlockController.startKeyguardFadingAway();
mBouncer.hide(true /* destroyView */);
updateStates();
if (wakeUnlockPulsing) {
mStatusBarWindowManager.setKeyguardFadingAway(true);
- mPhoneStatusBar.fadeKeyguardWhilePulsing();
+ mStatusBar.fadeKeyguardWhilePulsing();
animateScrimControllerKeyguardFadingOut(delay, fadeoutDuration,
- mPhoneStatusBar::hideKeyguard, false /* skipFirstFrame */);
+ mStatusBar::hideKeyguard, false /* skipFirstFrame */);
} else {
mFingerprintUnlockController.startKeyguardFadingAway();
- mPhoneStatusBar.setKeyguardFadingAway(startTime, delay, fadeoutDuration);
- boolean staying = mPhoneStatusBar.hideKeyguard();
+ mStatusBar.setKeyguardFadingAway(startTime, delay, fadeoutDuration);
+ boolean staying = mStatusBar.hideKeyguard();
if (!staying) {
mStatusBarWindowManager.setKeyguardFadingAway(true);
if (mFingerprintUnlockController.getMode() == MODE_WAKE_AND_UNLOCK) {
@@ -379,7 +379,7 @@
}
} else {
mScrimController.animateGoingToFullShade(delay, fadeoutDuration);
- mPhoneStatusBar.finishKeyguardFadingAway();
+ mStatusBar.finishKeyguardFadingAway();
}
}
mStatusBarWindowManager.setKeyguardShowing(false);
@@ -408,7 +408,7 @@
}
mContainer.postDelayed(() -> mStatusBarWindowManager.setKeyguardFadingAway(false),
100);
- mPhoneStatusBar.finishKeyguardFadingAway();
+ mStatusBar.finishKeyguardFadingAway();
mFingerprintUnlockController.finishKeyguardFadingAway();
WindowManagerGlobal.getInstance().trimMemory(
ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
@@ -438,7 +438,7 @@
* Dismisses the keyguard by going to the next screen or making it gone.
*/
public void dismissAndCollapse() {
- mPhoneStatusBar.executeRunnableDismissingKeyguard(null, null, true, false, true);
+ mStatusBar.executeRunnableDismissingKeyguard(null, null, true, false, true);
}
public void dismiss() {
@@ -466,7 +466,7 @@
*/
public boolean onBackPressed() {
if (mBouncer.isShowing()) {
- mPhoneStatusBar.endAffordanceLaunch();
+ mStatusBar.endAffordanceLaunch();
reset(true /* hideBouncerWhenShowing */);
return true;
}
@@ -478,8 +478,8 @@
}
private long getNavBarShowDelay() {
- if (mPhoneStatusBar.isKeyguardFadingAway()) {
- return mPhoneStatusBar.getKeyguardFadingAwayDelay();
+ if (mStatusBar.isKeyguardFadingAway()) {
+ return mStatusBar.getKeyguardFadingAwayDelay();
} else {
// Keyguard is not going away, thus we are showing the navigation bar because the
@@ -491,7 +491,7 @@
private Runnable mMakeNavigationBarVisibleRunnable = new Runnable() {
@Override
public void run() {
- mPhoneStatusBar.getNavigationBarView().getRootView().setVisibility(View.VISIBLE);
+ mStatusBar.getNavigationBarView().getRootView().setVisibility(View.VISIBLE);
}
};
@@ -516,7 +516,7 @@
boolean navBarVisible = isNavBarVisible();
boolean lastNavBarVisible = getLastNavBarVisible();
if (navBarVisible != lastNavBarVisible || mFirstUpdate) {
- if (mPhoneStatusBar.getNavigationBarView() != null) {
+ if (mStatusBar.getNavigationBarView() != null) {
if (navBarVisible) {
long delay = getNavBarShowDelay();
if (delay == 0) {
@@ -527,14 +527,14 @@
}
} else {
mContainer.removeCallbacks(mMakeNavigationBarVisibleRunnable);
- mPhoneStatusBar.getNavigationBarView().getRootView().setVisibility(View.GONE);
+ mStatusBar.getNavigationBarView().getRootView().setVisibility(View.GONE);
}
}
}
if (bouncerShowing != mLastBouncerShowing || mFirstUpdate) {
mStatusBarWindowManager.setBouncerShowing(bouncerShowing);
- mPhoneStatusBar.setBouncerShowing(bouncerShowing);
+ mStatusBar.setBouncerShowing(bouncerShowing);
mScrimController.setBouncerShowing(bouncerShowing);
}
@@ -553,7 +553,7 @@
mLastBouncerDismissible = bouncerDismissible;
mLastRemoteInputActive = remoteInputActive;
- mPhoneStatusBar.onKeyguardViewManagerStatesUpdated();
+ mStatusBar.onKeyguardViewManagerStatesUpdated();
}
/**
@@ -583,11 +583,11 @@
}
public boolean shouldDisableWindowAnimationsForUnlock() {
- return mPhoneStatusBar.isInLaunchTransition();
+ return mStatusBar.isInLaunchTransition();
}
public boolean isGoingToNotificationShade() {
- return mPhoneStatusBar.isGoingToNotificationShade();
+ return mStatusBar.isGoingToNotificationShade();
}
public boolean isSecure(int userId) {
@@ -595,11 +595,11 @@
}
public void keyguardGoingAway() {
- mPhoneStatusBar.keyguardGoingAway();
+ mStatusBar.keyguardGoingAway();
}
public void animateCollapsePanels(float speedUpFactor) {
- mPhoneStatusBar.animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE, true /* force */,
+ mStatusBar.animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE, true /* force */,
false /* delayed */, speedUpFactor);
}
@@ -616,6 +616,6 @@
}
public ViewRootImpl getViewRootImpl() {
- return mPhoneStatusBar.getStatusBarView().getViewRootImpl();
+ return mStatusBar.getStatusBarView().getViewRootImpl();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
index 0660054..16999b2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
@@ -25,7 +25,6 @@
import android.os.Binder;
import android.os.RemoteException;
import android.os.SystemProperties;
-import android.os.Trace;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
@@ -34,7 +33,6 @@
import com.android.keyguard.R;
import com.android.systemui.keyguard.KeyguardViewMediator;
-import com.android.systemui.statusbar.BaseStatusBar;
import com.android.systemui.statusbar.RemoteInputController;
import com.android.systemui.statusbar.StatusBarState;
@@ -140,7 +138,7 @@
private void applyFocusableFlag(State state) {
boolean panelFocusable = state.statusBarFocusable && state.panelExpanded;
if (state.bouncerShowing && (state.keyguardOccluded || state.keyguardNeedsInput)
- || BaseStatusBar.ENABLE_REMOTE_INPUT && state.remoteInputActive) {
+ || StatusBar.ENABLE_REMOTE_INPUT && state.remoteInputActive) {
mLpChanged.flags &= ~WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
mLpChanged.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
} else if (state.isKeyguardShowingAndNotOccluded() || panelFocusable) {
@@ -385,7 +383,7 @@
boolean backdropShowing;
/**
- * The {@link BaseStatusBar} state from the status bar.
+ * The {@link StatusBar} state from the status bar.
*/
int statusBarState;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
index ccd6357..7c42d00 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
@@ -34,7 +34,6 @@
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
-import android.os.Trace;
import android.util.AttributeSet;
import android.view.ActionMode;
import android.view.InputQueue;
@@ -56,7 +55,6 @@
import com.android.internal.widget.FloatingToolbar;
import com.android.systemui.R;
import com.android.systemui.classifier.FalsingManager;
-import com.android.systemui.statusbar.BaseStatusBar;
import com.android.systemui.statusbar.DragDownHelper;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
@@ -64,7 +62,7 @@
public class StatusBarWindowView extends FrameLayout {
public static final String TAG = "StatusBarWindowView";
- public static final boolean DEBUG = BaseStatusBar.DEBUG;
+ public static final boolean DEBUG = StatusBar.DEBUG;
private DragDownHelper mDragDownHelper;
private NotificationStackScrollLayout mStackScrollLayout;
@@ -74,7 +72,7 @@
private int mRightInset = 0;
private int mLeftInset = 0;
- private PhoneStatusBar mService;
+ private StatusBar mService;
private final Paint mTransparentSrcPaint = new Paint();
private FalsingManager mFalsingManager;
@@ -173,7 +171,7 @@
}
}
- public void setService(PhoneStatusBar service) {
+ public void setService(StatusBar service) {
mService = service;
mDragDownHelper = new DragDownHelper(getContext(), this, mStackScrollLayout, mService);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
index a8d8f60..8c805fe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
@@ -37,7 +37,7 @@
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
-import com.android.systemui.statusbar.phone.PhoneStatusBar;
+import com.android.systemui.statusbar.phone.StatusBar;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -90,7 +90,7 @@
private final int mStatusBarHeight;
private final Context mContext;
private final NotificationGroupManager mGroupManager;
- private PhoneStatusBar mBar;
+ private StatusBar mBar;
private int mSnoozeLengthMs;
private ContentObserver mSettingsObserver;
private HashMap<String, HeadsUpEntry> mHeadsUpEntries = new HashMap<>();
@@ -162,7 +162,7 @@
mIsObserving = shouldObserve;
}
- public void setBar(PhoneStatusBar bar) {
+ public void setBar(StatusBar bar) {
mBar = bar;
}
@@ -170,7 +170,7 @@
mListeners.add(listener);
}
- public PhoneStatusBar getBar() {
+ public StatusBar getBar() {
return mBar;
}
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 5d48df9..85b1c32 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -79,7 +79,7 @@
import com.android.systemui.statusbar.notification.NotificationUtils;
import com.android.systemui.statusbar.notification.VisibilityLocationProvider;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
-import com.android.systemui.statusbar.phone.PhoneStatusBar;
+import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.ScrimController;
import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.statusbar.policy.ScrollAdapter;
@@ -251,7 +251,7 @@
return true;
}
};
- private PhoneStatusBar mPhoneStatusBar;
+ private StatusBar mStatusBar;
private int[] mTempInt2 = new int[2];
private boolean mGenerateChildOrderChangedEvent;
private HashSet<Runnable> mAnimationFinishedRunnables = new HashSet<>();
@@ -877,7 +877,7 @@
mFalsingManager.onNotificationDismissed();
if (mFalsingManager.shouldEnforceBouncer()) {
- mPhoneStatusBar.executeRunnableDismissingKeyguard(null, null /* cancelAction */,
+ mStatusBar.executeRunnableDismissingKeyguard(null, null /* cancelAction */,
false /* dismissShade */, true /* afterKeyguardGone */, false /* deferred */);
}
}
@@ -968,7 +968,7 @@
@Override
public float getFalsingThresholdFactor() {
- return mPhoneStatusBar.isWakeUpComingFromTouch() ? 1.5f : 1.0f;
+ return mStatusBar.isWakeUpComingFromTouch() ? 1.5f : 1.0f;
}
@Override
@@ -3222,7 +3222,7 @@
mAmbientState.setExpansionChanging(false);
if (!mIsExpanded) {
setOwnScrollY(0);
- mPhoneStatusBar.resetUserExpandedStates();
+ mStatusBar.resetUserExpandedStates();
// lets make sure nothing is in the overlay / transient anymore
clearTemporaryViews(this);
@@ -3757,8 +3757,8 @@
return max + getStackTranslation();
}
- public void setPhoneStatusBar(PhoneStatusBar phoneStatusBar) {
- this.mPhoneStatusBar = phoneStatusBar;
+ public void setStatusBar(StatusBar statusBar) {
+ this.mStatusBar = statusBar;
}
public void setGroupManager(NotificationGroupManager groupManager) {
@@ -3829,7 +3829,7 @@
@Override
public void onGroupCreatedFromChildren(NotificationGroupManager.NotificationGroup group) {
- mPhoneStatusBar.requestNotificationUpdate();
+ mStatusBar.requestNotificationUpdate();
}
/** @hide */
@@ -3897,7 +3897,7 @@
@Override
public void onGroupsChanged() {
- mPhoneStatusBar.requestNotificationUpdate();
+ mStatusBar.requestNotificationUpdate();
}
public void generateChildOrderChangedEvent() {
@@ -4367,7 +4367,7 @@
}
public void closeControlsIfOutsideTouch(MotionEvent ev) {
- NotificationGuts guts = mPhoneStatusBar.getExposedGuts();
+ NotificationGuts guts = mStatusBar.getExposedGuts();
View view = null;
int height = 0;
if (guts != null) {
@@ -4390,7 +4390,7 @@
Rect rect = new Rect(x, y, x + view.getWidth(), y + height);
if (!rect.contains(rx, ry)) {
// Touch was outside visible guts / gear notification, close what's visible
- mPhoneStatusBar.dismissPopups(-1, -1, true /* resetGear */, true /* animate */);
+ mStatusBar.dismissPopups(-1, -1, true /* resetGear */, true /* animate */);
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
index 9b8183b..ab562d1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
@@ -17,23 +17,29 @@
package com.android.systemui.statusbar.tv;
import android.content.ComponentName;
+import android.content.Context;
import android.graphics.Rect;
import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
import android.service.notification.NotificationListenerService.RankingMap;
-import android.service.notification.StatusBarNotification;
-import android.view.View;
+import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.statusbar.StatusBarIcon;
-import com.android.systemui.statusbar.ActivatableNotificationView;
-import com.android.systemui.statusbar.BaseStatusBar;
-import com.android.systemui.statusbar.NotificationData;
+import com.android.systemui.SystemUI;
import com.android.systemui.pip.tv.PipManager;
+import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.CommandQueue.Callbacks;
+
+import java.util.ArrayList;
/**
* Status bar implementation for "large screen" products that mostly present no on-screen nav
*/
-public class TvStatusBar extends BaseStatusBar {
+public class TvStatusBar extends SystemUI implements Callbacks {
+
+ private IStatusBarService mBarService;
@Override
public void setIcon(String slot, StatusBarIcon icon) {
@@ -43,16 +49,6 @@
public void removeIcon(String slot) {
}
- @Override
- public void addNotification(StatusBarNotification notification, RankingMap ranking,
- NotificationData.Entry entry) {
- }
-
- @Override
- protected void updateNotificationRanking(RankingMap ranking) {
- }
-
- @Override
public void removeNotification(String key, RankingMap ranking) {
}
@@ -99,53 +95,10 @@
}
@Override
- protected void setAreThereNotifications() {
- }
-
- @Override
- protected void updateNotifications() {
- }
-
- public View getStatusBarView() {
- return null;
- }
-
- @Override
- protected boolean toggleSplitScreenMode(int metricsDockAction, int metricsUndockAction) {
- return false;
- }
-
- @Override
- public void maybeEscalateHeadsUp() {
- }
-
- @Override
- public boolean isPanelFullyCollapsed() {
- return false;
- }
-
- @Override
- protected int getMaxKeyguardNotifications(boolean recompute) {
- return 0;
- }
-
- @Override
public void animateExpandSettingsPanel(String subPanel) {
}
@Override
- protected void createAndAddWindows() {
- }
-
- @Override
- public void onActivated(ActivatableNotificationView view) {
- }
-
- @Override
- public void onActivationReset(ActivatableNotificationView view) {
- }
-
- @Override
public void showScreenPinningRequest(int taskId) {
}
@@ -175,19 +128,6 @@
}
@Override
- protected void updateHeadsUp(String key, NotificationData.Entry entry, boolean shouldPeek,
- boolean alertAgain) {
- }
-
- @Override
- protected void setHeadsUpUser(int newUserId) {
- }
-
- protected boolean isSnoozedPackage(StatusBarNotification sbn) {
- return false;
- }
-
- @Override
public void addQsTile(ComponentName tile) {
}
@@ -201,8 +141,23 @@
@Override
public void start() {
- super.start();
putComponent(TvStatusBar.class, this);
+ CommandQueue commandQueue = getComponent(CommandQueue.class);
+ commandQueue.addCallbacks(this);
+ int[] switches = new int[9];
+ ArrayList<IBinder> binders = new ArrayList<>();
+ ArrayList<String> iconSlots = new ArrayList<>();
+ ArrayList<StatusBarIcon> icons = new ArrayList<>();
+ Rect fullscreenStackBounds = new Rect();
+ Rect dockedStackBounds = new Rect();
+ mBarService = IStatusBarService.Stub.asInterface(
+ ServiceManager.getService(Context.STATUS_BAR_SERVICE));
+ try {
+ mBarService.registerStatusBar(commandQueue, iconSlots, icons, switches, binders,
+ fullscreenStackBounds, dockedStackBounds);
+ } catch (RemoteException ex) {
+ // If the system process isn't there we're doomed anyway.
+ }
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java
index 137a12f..78145fe 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java
@@ -31,7 +31,6 @@
import com.android.systemui.SystemUIFactory;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.qs.tiles.DndTile;
-import com.android.systemui.statusbar.phone.PhoneStatusBar;
import com.android.systemui.statusbar.policy.ZenModeController;
import com.android.systemui.tuner.TunerService;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java
index 525a361..e28d077 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarFragmentTest.java
@@ -20,7 +20,6 @@
import android.view.WindowManager;
import com.android.systemui.FragmentTestCase;
-import com.android.systemui.assist.AssistManager;
import com.android.systemui.recents.Recents;
import com.android.systemui.stackdivider.Divider;
import com.android.systemui.statusbar.CommandQueue;
@@ -37,7 +36,7 @@
@Before
public void setup() {
mContext.putComponent(CommandQueue.class, mock(CommandQueue.class));
- mContext.putComponent(PhoneStatusBar.class, mock(PhoneStatusBar.class));
+ mContext.putComponent(StatusBar.class, mock(StatusBar.class));
mContext.putComponent(Recents.class, mock(Recents.class));
mContext.putComponent(Divider.class, mock(Divider.class));
mContext.addMockSystemService(Context.WINDOW_SERVICE, mock(WindowManager.class));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
similarity index 80%
rename from packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarTest.java
rename to packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
index d82566f..309559b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
@@ -27,7 +27,6 @@
import com.android.keyguard.KeyguardHostView.OnDismissAction;
import com.android.systemui.SysuiTestCase;
-import com.android.systemui.statusbar.BaseStatusBar;
import org.junit.Before;
import org.junit.Test;
@@ -35,15 +34,15 @@
@SmallTest
@RunWith(AndroidJUnit4.class)
-public class PhoneStatusBarTest extends SysuiTestCase {
+public class StatusBarTest extends SysuiTestCase {
StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
- PhoneStatusBar mPhoneStatusBar;
+ StatusBar mStatusBar;
@Before
public void setup() {
mStatusBarKeyguardViewManager = mock(StatusBarKeyguardViewManager.class);
- mPhoneStatusBar = new TestablePhoneStatusBar(mStatusBarKeyguardViewManager);
+ mStatusBar = new TestableStatusBar(mStatusBarKeyguardViewManager);
doAnswer(invocation -> {
OnDismissAction onDismissAction = (OnDismissAction) invocation.getArguments()[0];
@@ -63,7 +62,7 @@
when(mStatusBarKeyguardViewManager.isShowing()).thenReturn(true);
when(mStatusBarKeyguardViewManager.isOccluded()).thenReturn(true);
- mPhoneStatusBar.executeRunnableDismissingKeyguard(null, null, false, false, false);
+ mStatusBar.executeRunnableDismissingKeyguard(null, null, false, false, false);
}
@Test
@@ -71,7 +70,7 @@
when(mStatusBarKeyguardViewManager.isShowing()).thenReturn(true);
when(mStatusBarKeyguardViewManager.isOccluded()).thenReturn(false);
- mPhoneStatusBar.executeRunnableDismissingKeyguard(null, null, false, false, false);
+ mStatusBar.executeRunnableDismissingKeyguard(null, null, false, false, false);
}
@Test
@@ -79,16 +78,16 @@
when(mStatusBarKeyguardViewManager.isShowing()).thenReturn(false);
when(mStatusBarKeyguardViewManager.isOccluded()).thenReturn(false);
- mPhoneStatusBar.executeRunnableDismissingKeyguard(null, null, false, false, false);
+ mStatusBar.executeRunnableDismissingKeyguard(null, null, false, false, false);
}
- static class TestablePhoneStatusBar extends PhoneStatusBar {
- public TestablePhoneStatusBar(StatusBarKeyguardViewManager man) {
+ static class TestableStatusBar extends StatusBar {
+ public TestableStatusBar(StatusBarKeyguardViewManager man) {
mStatusBarKeyguardViewManager = man;
}
@Override
- protected BaseStatusBar.H createHandler() {
+ protected H createHandler() {
return null;
}
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 23a6a90..abf3526 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -21333,9 +21333,11 @@
if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) {
FileUtils.deleteContentsAndDir(Environment.getUserSystemDirectory(userId));
FileUtils.deleteContentsAndDir(Environment.getDataSystemDeDirectory(userId));
+ FileUtils.deleteContentsAndDir(Environment.getDataMiscDeDirectory(userId));
}
if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
FileUtils.deleteContentsAndDir(Environment.getDataSystemCeDirectory(userId));
+ FileUtils.deleteContentsAndDir(Environment.getDataMiscCeDirectory(userId));
}
}
@@ -21363,6 +21365,8 @@
.listFilesOrEmpty(Environment.getDataSystemDeDirectory()));
Collections.addAll(files, FileUtils
.listFilesOrEmpty(Environment.getDataSystemCeDirectory()));
+ Collections.addAll(files, FileUtils
+ .listFilesOrEmpty(Environment.getDataMiscCeDirectory()));
for (File file : files) {
if (!file.isDirectory()) continue;