summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Jacqueline Bronger <bronger@google.com> 2020-12-01 16:20:53 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2020-12-01 16:20:53 +0000
commit5333b04ee0f9fab59e87b80394bd24fd507b0a0b (patch)
tree21e0d865dabefa5c69a7ef6a0f7f3c0015d3ed26
parente7080f41dfe212ce2f374f6c498dad61466192a6 (diff)
parent5c395a46a540e4157d379902a1d753e03ce1577c (diff)
Merge "Adds a tv notification panel for aosp which is shown when keyevent NOTIFICATION is received"
-rw-r--r--packages/SystemUI/AndroidManifest.xml8
-rw-r--r--packages/SystemUI/res/layout/tv_notification_item.xml39
-rw-r--r--packages/SystemUI/res/layout/tv_notification_panel.xml53
-rw-r--r--packages/SystemUI/res/values-television/config.xml3
-rw-r--r--packages/SystemUI/res/values/colors_tv.xml3
-rw-r--r--packages/SystemUI/res/values/dimens_tv.xml19
-rw-r--r--packages/SystemUI/res/values/strings_tv.xml2
-rw-r--r--packages/SystemUI/res/values/styles_tv.xml8
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/tv/notifications/TvNotificationAdapter.java111
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/tv/notifications/TvNotificationHandler.java115
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/tv/notifications/TvNotificationPanel.java (renamed from packages/SystemUI/src/com/android/systemui/statusbar/tv/TvNotificationPanel.java)22
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/tv/notifications/TvNotificationPanelActivity.java110
-rw-r--r--packages/SystemUI/src/com/android/systemui/tv/TvSystemUIBinder.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java9
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);
+ }
}