1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.car.notification;
17 
18 import android.app.Activity;
19 import android.content.ComponentName;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.content.ServiceConnection;
23 import android.os.Bundle;
24 import android.os.IBinder;
25 import android.os.RemoteException;
26 import android.os.ServiceManager;
27 import android.util.Log;
28 
29 import com.android.internal.statusbar.IStatusBarService;
30 
31 /**
32  * Displays all undismissed notifications.
33  */
34 public class CarNotificationCenterActivity extends Activity {
35 
36     private static final String TAG = "CarNotificationActivity";
37 
38     private CarNotificationListener mNotificationListener;
39     private PreprocessingManager mPreprocessingManager;
40     private CarNotificationView mCarNotificationView;
41     private NotificationViewController mNotificationViewController;
42     private IStatusBarService mStatusBarService;
43     private NotificationDataManager mNotificationDataManager;
44     private CarNotificationVisibilityLogger mNotificationVisibilityLogger;
45 
46     private ServiceConnection mNotificationListenerConnectionListener = new ServiceConnection() {
47         public void onServiceConnected(ComponentName className, IBinder binder) {
48             Log.d(TAG, "onServiceConnected");
49             mNotificationListener = ((CarNotificationListener.LocalBinder) binder).getService();
50             NotificationApplication app = (NotificationApplication) getApplication();
51             mNotificationViewController =
52                     new NotificationViewController(mCarNotificationView,
53                             mPreprocessingManager,
54                             mNotificationListener,
55                             app.getCarUxRestrictionWrapper());
56             mNotificationViewController.enable();
57             mNotificationDataManager.setOnUnseenCountUpdateListener(() -> {
58                 mNotificationListener.setNotificationsShown(
59                         NotificationDataManager.getInstance().getSeenNotifications());
60                 mNotificationVisibilityLogger.notifyVisibilityChanged(isResumed());
61             });
62             getApplicationContext().getMainExecutor().execute(() -> {
63                 if (isResumed()) {
64                     notifyVisibilityChanged(/* isVisible= */ true);
65                     mCarNotificationView.setVisibleNotificationsAsSeen();
66                 }
67             });
68         }
69 
70         public void onServiceDisconnected(ComponentName className) {
71             Log.d(TAG, "onServiceDisconnected");
72             mNotificationViewController.disable();
73             mNotificationDataManager.setOnUnseenCountUpdateListener(null);
74             mNotificationViewController = null;
75             mNotificationListener = null;
76         }
77     };
78 
79     @Override
onCreate(Bundle savedInstanceState)80     protected void onCreate(Bundle savedInstanceState) {
81         super.onCreate(savedInstanceState);
82         mPreprocessingManager = PreprocessingManager.getInstance(getApplicationContext());
83         NotificationApplication app = (NotificationApplication) getApplication();
84         setContentView(R.layout.notification_center_activity);
85         mCarNotificationView = findViewById(R.id.notification_view);
86         mCarNotificationView.setClickHandlerFactory(app.getClickHandlerFactory());
87         findViewById(R.id.exit_button_container).setOnClickListener(v -> finish());
88         mNotificationDataManager = NotificationDataManager.getInstance();
89         mStatusBarService = IStatusBarService.Stub.asInterface(
90                 ServiceManager.getService(Context.STATUS_BAR_SERVICE));
91         mNotificationVisibilityLogger = new CarNotificationVisibilityLogger(mStatusBarService,
92                 mNotificationDataManager);
93     }
94 
95     @Override
onStart()96     protected void onStart() {
97         super.onStart();
98         // Bind notification listener
99         Intent intent = new Intent(this, CarNotificationListener.class);
100         intent.setAction(CarNotificationListener.ACTION_LOCAL_BINDING);
101         bindService(intent, mNotificationListenerConnectionListener, Context.BIND_AUTO_CREATE);
102         if (mNotificationViewController != null) {
103             mNotificationViewController.onVisibilityChanged(/* isVisible= */ true);
104         }
105     }
106 
107     @Override
onStop()108     protected void onStop() {
109         super.onStop();
110         notifyVisibilityChanged(/* isVisible= */ false);
111 
112         // Unbind notification listener
113         if (mNotificationViewController != null) {
114             mNotificationViewController.disable();
115             mNotificationViewController = null;
116         }
117 
118         if (mNotificationListenerConnectionListener != null) {
119             unbindService(mNotificationListenerConnectionListener);
120         }
121     }
122 
notifyVisibilityChanged(boolean isVisible)123     private void notifyVisibilityChanged(boolean isVisible) {
124         if (mNotificationViewController != null) {
125             mNotificationViewController.onVisibilityChanged(isVisible);
126         }
127         try {
128             if (isVisible) {
129                 mStatusBarService.onPanelRevealed(/* clearNotificationEffects= */ true,
130                         mNotificationDataManager.getVisibleNotifications().size());
131             } else {
132                 mStatusBarService.onPanelHidden();
133             }
134         } catch (RemoteException ex) {
135             Log.e(TAG, "Unable to report notification visibility changes", ex);
136         }
137     }
138 }
139