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;