diff options
| author | 2020-12-01 16:20:53 +0000 | |
|---|---|---|
| committer | 2020-12-01 16:20:53 +0000 | |
| commit | 5333b04ee0f9fab59e87b80394bd24fd507b0a0b (patch) | |
| tree | 21e0d865dabefa5c69a7ef6a0f7f3c0015d3ed26 | |
| parent | e7080f41dfe212ce2f374f6c498dad61466192a6 (diff) | |
| parent | 5c395a46a540e4157d379902a1d753e03ce1577c (diff) | |
Merge "Adds a tv notification panel for aosp which is shown when keyevent NOTIFICATION is received"
17 files changed, 509 insertions, 13 deletions
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index 7120cc21c821..52b41a43c63e 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -530,6 +530,14 @@ androidprv:alwaysFocusable="true" android:excludeFromRecents="true" /> + <!-- started from TvNotificationPanel --> + <activity + android:name=".statusbar.tv.notifications.TvNotificationPanelActivity" + android:excludeFromRecents="true" + android:launchMode="singleTask" + android:noHistory="true" + android:theme="@style/TvSidePanelTheme" /> + <!-- started from SliceProvider --> <activity android:name=".SlicePermissionActivity" android:theme="@style/Theme.SystemUI.Dialog.Alert" diff --git a/packages/SystemUI/res/layout/tv_notification_item.xml b/packages/SystemUI/res/layout/tv_notification_item.xml new file mode 100644 index 000000000000..711cd4e4258a --- /dev/null +++ b/packages/SystemUI/res/layout/tv_notification_item.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2020 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. + --> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="@dimen/tv_notification_panel_width" + android:layout_height="wrap_content" + android:background="?android:attr/selectableItemBackground" + android:orientation="vertical" + android:padding="12dp"> + + <TextView + android:id="@+id/tv_notification_title" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingBottom="12dp" + android:textColor="@color/tv_notification_text_color" + android:textSize="18sp" /> + + <TextView + android:id="@+id/tv_notification_details" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:textColor="@color/tv_notification_text_color" /> + +</LinearLayout> diff --git a/packages/SystemUI/res/layout/tv_notification_panel.xml b/packages/SystemUI/res/layout/tv_notification_panel.xml new file mode 100644 index 000000000000..8f00a727b912 --- /dev/null +++ b/packages/SystemUI/res/layout/tv_notification_panel.xml @@ -0,0 +1,53 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2020 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. + --> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/tv_notification_panel" + android:layout_width="@dimen/tv_notification_panel_width" + android:layout_height="match_parent" + android:layout_gravity="end" + android:background="@color/tv_notification_background_color" + android:orientation="vertical"> + + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:padding="12dp" + android:paddingTop="24dp" + android:text="@string/tv_notification_panel_title" + android:textColor="@color/tv_notification_text_color" + android:textSize="24sp" + android:textStyle="bold" /> + + <TextView + android:id="@+id/no_tv_notifications" + style="?android:attr/titleTextStyle" + android:layout_width="match_parent" + android:layout_height="0dp" + android:layout_weight="1" + android:gravity="top|center" + android:paddingTop="24dp" + android:text="@string/tv_notification_panel_no_notifications" + android:textColor="@color/tv_notification_text_color" + android:visibility="gone" /> + + <androidx.leanback.widget.VerticalGridView + android:id="@+id/notifications_list" + android:layout_width="match_parent" + android:layout_height="0dp" + android:layout_weight="1" /> +</LinearLayout> diff --git a/packages/SystemUI/res/values-television/config.xml b/packages/SystemUI/res/values-television/config.xml index 09ec439b183e..0c8c5c443c4a 100644 --- a/packages/SystemUI/res/values-television/config.xml +++ b/packages/SystemUI/res/values-television/config.xml @@ -29,7 +29,8 @@ <item>com.android.systemui.util.NotificationChannels</item> <item>com.android.systemui.volume.VolumeUI</item> <item>com.android.systemui.statusbar.tv.TvStatusBar</item> - <item>com.android.systemui.statusbar.tv.TvNotificationPanel</item> + <item>com.android.systemui.statusbar.tv.notifications.TvNotificationPanel</item> + <item>com.android.systemui.statusbar.tv.notifications.TvNotificationHandler</item> <item>com.android.systemui.statusbar.tv.VpnStatusObserver</item> <item>com.android.systemui.usb.StorageNotification</item> <item>com.android.systemui.power.PowerUI</item> diff --git a/packages/SystemUI/res/values/colors_tv.xml b/packages/SystemUI/res/values/colors_tv.xml index 9b0ae1d61de6..0961f503e7d4 100644 --- a/packages/SystemUI/res/values/colors_tv.xml +++ b/packages/SystemUI/res/values/colors_tv.xml @@ -33,4 +33,7 @@ <color name="tv_volume_dialog_seek_bar_background">#A03C4043</color> <color name="tv_volume_dialog_seek_bar_fill">#FFF8F9FA</color> <color name="tv_volume_dialog_accent">#FFDADCE0</color> + + <color name="tv_notification_background_color">#383838</color> + <color name="tv_notification_text_color">#FFFFFF</color> </resources> diff --git a/packages/SystemUI/res/values/dimens_tv.xml b/packages/SystemUI/res/values/dimens_tv.xml new file mode 100644 index 000000000000..9545bfd088a0 --- /dev/null +++ b/packages/SystemUI/res/values/dimens_tv.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2020 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. + --> +<resources> + <dimen name="tv_notification_panel_width">360dp</dimen> +</resources>
\ No newline at end of file diff --git a/packages/SystemUI/res/values/strings_tv.xml b/packages/SystemUI/res/values/strings_tv.xml index 13271d6f7f2e..b51cb5619f0c 100644 --- a/packages/SystemUI/res/values/strings_tv.xml +++ b/packages/SystemUI/res/values/strings_tv.xml @@ -26,4 +26,6 @@ <!-- Disclosure text in the connected notification that indicates that the device is connected to a VPN. The placeholder is the VPN name. [CHAR LIMIT=40] --> <string name="notification_disclosure_vpn_text">Via <xliff:g id="vpn_app" example="Foo VPN App">%1$s</xliff:g></string> + <string name="tv_notification_panel_title">Notifications</string> + <string name="tv_notification_panel_no_notifications">No Notifications</string> </resources> diff --git a/packages/SystemUI/res/values/styles_tv.xml b/packages/SystemUI/res/values/styles_tv.xml index 0c4fd23ca107..cb433f3a6009 100644 --- a/packages/SystemUI/res/values/styles_tv.xml +++ b/packages/SystemUI/res/values/styles_tv.xml @@ -23,4 +23,12 @@ <item name="android:backgroundDimEnabled">false</item> <item name="android:windowDisablePreview">true</item> </style> + + <style name="TvSidePanelTheme"> + <item name="android:windowIsTranslucent">true</item> + <item name="android:windowBackground">@android:color/transparent</item> + <item name="android:backgroundDimEnabled">false</item> + <item name="android:windowNoTitle">true</item> + <item name="android:windowContentOverlay">@null</item> + </style> </resources> diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java b/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java index 13ff3f5c4e6c..ec4a91c24464 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java @@ -22,6 +22,7 @@ import com.android.systemui.ForegroundServicesDialog; import com.android.systemui.keyguard.WorkLockActivity; import com.android.systemui.screenrecord.ScreenRecordDialog; import com.android.systemui.settings.brightness.BrightnessDialog; +import com.android.systemui.statusbar.tv.notifications.TvNotificationPanelActivity; import com.android.systemui.tuner.TunerActivity; import com.android.systemui.usb.UsbDebuggingActivity; import com.android.systemui.usb.UsbDebuggingSecondaryUserActivity; @@ -85,4 +86,10 @@ public abstract class DefaultActivityBinder { @IntoMap @ClassKey(CreateUserActivity.class) public abstract Activity bindCreateUserActivity(CreateUserActivity activity); + + /** Inject into TvNotificationPanelActivity. */ + @Binds + @IntoMap + @ClassKey(TvNotificationPanelActivity.class) + public abstract Activity bindTvNotificationPanelActivity(TvNotificationPanelActivity activity); } diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java index c0013d8cb981..9f6c19bdf06f 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java @@ -34,8 +34,8 @@ import com.android.systemui.shortcut.ShortcutKeyDispatcher; import com.android.systemui.statusbar.dagger.StatusBarModule; import com.android.systemui.statusbar.notification.InstantAppNotifier; import com.android.systemui.statusbar.phone.StatusBar; -import com.android.systemui.statusbar.tv.TvNotificationPanel; import com.android.systemui.statusbar.tv.TvStatusBar; +import com.android.systemui.statusbar.tv.notifications.TvNotificationPanel; import com.android.systemui.theme.ThemeOverlayController; import com.android.systemui.toast.ToastUI; import com.android.systemui.util.leak.GarbageMonitor; 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 2795857383e8..bdf2b0c24ba5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java @@ -71,7 +71,6 @@ public class TvStatusBar extends SystemUI implements CommandQueue.Callbacks { // Creating AudioRecordingDisclosureBar and just letting it run new AudioRecordingDisclosureBar(mContext); } - } @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/notifications/TvNotificationAdapter.java b/packages/SystemUI/src/com/android/systemui/statusbar/tv/notifications/TvNotificationAdapter.java new file mode 100644 index 000000000000..3b1a4db067a3 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/notifications/TvNotificationAdapter.java @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2020 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.tv.notifications; + +import android.app.Notification; +import android.app.PendingIntent; +import android.service.notification.StatusBarNotification; +import android.util.Log; +import android.util.SparseArray; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.android.systemui.R; + +/** + * Adapter for the VerticalGridView of the TvNotificationsPanelView. + */ +public class TvNotificationAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { + private static final String TAG = "TvNotificationAdapter"; + private SparseArray<StatusBarNotification> mNotifications; + + public TvNotificationAdapter() { + setHasStableIds(true); + } + + @NonNull + @Override + public TvNotificationViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.tv_notification_item, + parent, false); + return new TvNotificationViewHolder(view); + } + + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) { + if (mNotifications == null) { + Log.e(TAG, "Could not bind view holder because the notification is missing"); + return; + } + + TvNotificationViewHolder holder = (TvNotificationViewHolder) viewHolder; + Notification notification = mNotifications.valueAt(position).getNotification(); + holder.mTitle.setText(notification.extras.getString(Notification.EXTRA_TITLE)); + holder.mDetails.setText(notification.extras.getString(Notification.EXTRA_TEXT)); + holder.mPendingIntent = notification.contentIntent; + } + + @Override + public int getItemCount() { + return mNotifications == null ? 0 : mNotifications.size(); + } + + @Override + public long getItemId(int position) { + // the item id is the notification id + return mNotifications.keyAt(position); + } + + /** + * Updates the notifications and calls notifyDataSetChanged(). + */ + public void setNotifications(SparseArray<StatusBarNotification> notifications) { + this.mNotifications = notifications; + notifyDataSetChanged(); + } + + private static class TvNotificationViewHolder extends RecyclerView.ViewHolder implements + View.OnClickListener { + final TextView mTitle; + final TextView mDetails; + PendingIntent mPendingIntent; + + protected TvNotificationViewHolder(View itemView) { + super(itemView); + mTitle = itemView.findViewById(R.id.tv_notification_title); + mDetails = itemView.findViewById(R.id.tv_notification_details); + itemView.setOnClickListener(this); + } + + @Override + public void onClick(View v) { + try { + if (mPendingIntent != null) { + mPendingIntent.send(); + } + } catch (PendingIntent.CanceledException e) { + Log.d(TAG, "Pending intent canceled for : " + mPendingIntent); + } + } + } + +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/notifications/TvNotificationHandler.java b/packages/SystemUI/src/com/android/systemui/statusbar/tv/notifications/TvNotificationHandler.java new file mode 100644 index 000000000000..d985803c2b39 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/notifications/TvNotificationHandler.java @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2020 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.tv.notifications; + +import android.annotation.Nullable; +import android.app.Notification; +import android.content.Context; +import android.service.notification.NotificationListenerService; +import android.service.notification.StatusBarNotification; +import android.util.Log; +import android.util.SparseArray; + +import com.android.systemui.SystemUI; +import com.android.systemui.statusbar.NotificationListener; + +import javax.inject.Inject; + +/** + * Keeps track of the notifications on TV. + */ +public class TvNotificationHandler extends SystemUI implements + NotificationListener.NotificationHandler { + private static final String TAG = "TvNotificationHandler"; + private final NotificationListener mNotificationListener; + private final SparseArray<StatusBarNotification> mNotifications = new SparseArray<>(); + @Nullable + private Listener mUpdateListener; + + @Inject + public TvNotificationHandler(Context context, NotificationListener notificationListener) { + super(context); + mNotificationListener = notificationListener; + } + + public SparseArray<StatusBarNotification> getCurrentNotifications() { + return mNotifications; + } + + public void setTvNotificationListener(Listener listener) { + mUpdateListener = listener; + } + + @Override + public void start() { + mNotificationListener.addNotificationHandler(this); + mNotificationListener.registerAsSystemService(); + } + + @Override + public void onNotificationPosted(StatusBarNotification sbn, + NotificationListenerService.RankingMap rankingMap) { + if (!new Notification.TvExtender(sbn.getNotification()).isAvailableOnTv()) { + Log.v(TAG, "Notification not added because it isn't relevant for tv"); + return; + } + + mNotifications.put(sbn.getId(), sbn); + if (mUpdateListener != null) { + mUpdateListener.notificationsUpdated(mNotifications); + } + Log.d(TAG, "Notification added"); + } + + @Override + public void onNotificationRemoved(StatusBarNotification sbn, + NotificationListenerService.RankingMap rankingMap) { + + if (mNotifications.contains(sbn.getId())) { + mNotifications.remove(sbn.getId()); + Log.d(TAG, "Notification removed"); + + if (mUpdateListener != null) { + mUpdateListener.notificationsUpdated(mNotifications); + } + } + } + + @Override + public void onNotificationRemoved(StatusBarNotification sbn, + NotificationListenerService.RankingMap rankingMap, int reason) { + onNotificationRemoved(sbn, rankingMap); + } + + @Override + public void onNotificationRankingUpdate(NotificationListenerService.RankingMap rankingMap) { + // noop + } + + @Override + public void onNotificationsInitialized() { + // noop + } + + /** + * Get notified when the notifications are updated. + */ + interface Listener { + void notificationsUpdated(SparseArray<StatusBarNotification> sbns); + } + +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvNotificationPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tv/notifications/TvNotificationPanel.java index 0bd36240a366..477424c55a73 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvNotificationPanel.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/notifications/TvNotificationPanel.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.statusbar.tv; +package com.android.systemui.statusbar.tv.notifications; import android.Manifest; import android.app.NotificationManager; @@ -59,9 +59,8 @@ public class TvNotificationPanel extends SystemUI implements CommandQueue.Callba startNotificationHandlerActivity( new Intent(NotificationManager.ACTION_TOGGLE_NOTIFICATION_HANDLER_PANEL)); } else { - Log.w(TAG, - "Not toggling notification panel: config_notificationHandlerPackage is " - + "empty"); + openInternalNotificationPanel( + NotificationManager.ACTION_TOGGLE_NOTIFICATION_HANDLER_PANEL); } } @@ -71,9 +70,8 @@ public class TvNotificationPanel extends SystemUI implements CommandQueue.Callba startNotificationHandlerActivity( new Intent(NotificationManager.ACTION_OPEN_NOTIFICATION_HANDLER_PANEL)); } else { - Log.w(TAG, - "Not expanding notification panel: config_notificationHandlerPackage is " - + "empty"); + openInternalNotificationPanel( + NotificationManager.ACTION_OPEN_NOTIFICATION_HANDLER_PANEL); } } @@ -86,11 +84,17 @@ public class TvNotificationPanel extends SystemUI implements CommandQueue.Callba closeNotificationIntent.setPackage(mNotificationHandlerPackage); mContext.sendBroadcastAsUser(closeNotificationIntent, UserHandle.CURRENT); } else { - Log.w(TAG, - "Not closing notification panel: config_notificationHandlerPackage is empty"); + openInternalNotificationPanel( + NotificationManager.ACTION_CLOSE_NOTIFICATION_HANDLER_PANEL); } } + private void openInternalNotificationPanel(String action) { + Intent intent = new Intent(mContext, TvNotificationPanelActivity.class); + intent.setAction(action); + mContext.startActivityAsUser(intent, UserHandle.SYSTEM); + } + /** * Starts the activity intent if all of the following are true * <ul> diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/notifications/TvNotificationPanelActivity.java b/packages/SystemUI/src/com/android/systemui/statusbar/tv/notifications/TvNotificationPanelActivity.java new file mode 100644 index 000000000000..30f401b91d25 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/notifications/TvNotificationPanelActivity.java @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2020 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.tv.notifications; + +import android.annotation.NonNull; +import android.app.Activity; +import android.app.NotificationManager; +import android.content.Intent; +import android.os.Bundle; +import android.service.notification.StatusBarNotification; +import android.util.SparseArray; +import android.view.View; + +import androidx.leanback.widget.VerticalGridView; + +import com.android.systemui.R; + +import javax.inject.Inject; + +/** + * This Activity shows a notification panel for tv. It is used if no other app (e.g. a launcher) can + * be found to show the notifications. + */ +public class TvNotificationPanelActivity extends Activity implements + TvNotificationHandler.Listener { + private final TvNotificationHandler mTvNotificationHandler; + private TvNotificationAdapter mTvNotificationAdapter; + private VerticalGridView mNotificationListView; + private View mNotificationPlaceholder; + private boolean mPanelAlreadyOpen = false; + + @Inject + public TvNotificationPanelActivity(TvNotificationHandler tvNotificationHandler) { + super(); + mTvNotificationHandler = tvNotificationHandler; + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + if (maybeClosePanel(getIntent())) { + return; + } + mPanelAlreadyOpen = true; + + setContentView(R.layout.tv_notification_panel); + + mNotificationPlaceholder = findViewById(R.id.no_tv_notifications); + mTvNotificationAdapter = new TvNotificationAdapter(); + + mNotificationListView = findViewById(R.id.notifications_list); + mNotificationListView.setAdapter(mTvNotificationAdapter); + mNotificationListView.setColumnWidth(R.dimen.tv_notification_panel_width); + + mTvNotificationHandler.setTvNotificationListener(this); + notificationsUpdated(mTvNotificationHandler.getCurrentNotifications()); + } + + @Override + public void notificationsUpdated(@NonNull SparseArray<StatusBarNotification> notificationList) { + mTvNotificationAdapter.setNotifications(notificationList); + + boolean noNotifications = notificationList.size() == 0; + mNotificationListView.setVisibility(noNotifications ? View.GONE : View.VISIBLE); + mNotificationPlaceholder.setVisibility(noNotifications ? View.VISIBLE : View.GONE); + } + + @Override + public void onNewIntent(Intent intent) { + super.onNewIntent(intent); + maybeClosePanel(intent); + } + + /** + * Handles intents from onCreate and onNewIntent. + * + * @return true if the panel is being closed, false if it is being opened + */ + private boolean maybeClosePanel(Intent intent) { + if (NotificationManager.ACTION_CLOSE_NOTIFICATION_HANDLER_PANEL.equals(intent.getAction()) + || (mPanelAlreadyOpen + && NotificationManager.ACTION_TOGGLE_NOTIFICATION_HANDLER_PANEL.equals( + intent.getAction()))) { + finish(); + return true; + } + return false; + } + + @Override + public void onDestroy() { + super.onDestroy(); + mTvNotificationHandler.setTvNotificationListener(null); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIBinder.java b/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIBinder.java index 2c3ea4f452bb..353333f714d4 100644 --- a/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIBinder.java +++ b/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIBinder.java @@ -16,14 +16,22 @@ package com.android.systemui.tv; +import com.android.systemui.SystemUI; import com.android.systemui.dagger.GlobalRootComponent; -import com.android.systemui.wmshell.TvPipModule; +import com.android.systemui.statusbar.tv.notifications.TvNotificationHandler; import dagger.Binds; import dagger.Module; +import dagger.multibindings.ClassKey; +import dagger.multibindings.IntoMap; @Module interface TvSystemUIBinder { @Binds GlobalRootComponent bindGlobalRootComponent(TvGlobalRootComponent globalRootComponent); + + @Binds + @IntoMap + @ClassKey(TvNotificationHandler.class) + SystemUI bindTvNotificationHandler(TvNotificationHandler systemui); } diff --git a/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java b/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java index 8ffc7cf568ff..56a4c203e840 100644 --- a/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java +++ b/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java @@ -43,6 +43,7 @@ import com.android.systemui.qs.tileimpl.QSFactoryImpl; import com.android.systemui.recents.Recents; import com.android.systemui.recents.RecentsImplementation; import com.android.systemui.statusbar.CommandQueue; +import com.android.systemui.statusbar.NotificationListener; import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.NotificationLockscreenUserManagerImpl; import com.android.systemui.statusbar.NotificationShadeWindowController; @@ -62,6 +63,7 @@ import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.DeviceProvisionedController; import com.android.systemui.statusbar.policy.DeviceProvisionedControllerImpl; import com.android.systemui.statusbar.policy.HeadsUpManager; +import com.android.systemui.statusbar.tv.notifications.TvNotificationHandler; import javax.inject.Named; @@ -164,4 +166,11 @@ public abstract class TvSystemUIModule { @Binds abstract DozeHost provideDozeHost(DozeServiceHost dozeServiceHost); + + @Provides + @SysUISingleton + static TvNotificationHandler provideTvNotificationHandler(Context context, + NotificationListener notificationListener) { + return new TvNotificationHandler(context, notificationListener); + } } |