1 /*
2  * Copyright (C) 2019 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 
17 package com.android.systemui.statusbar;
18 
19 import android.content.Context;
20 import android.view.LayoutInflater;
21 import android.view.ViewGroup;
22 
23 import com.android.systemui.R;
24 import com.android.systemui.statusbar.notification.row.dagger.NotificationRowComponent;
25 import com.android.systemui.statusbar.phone.LockIcon;
26 import com.android.systemui.statusbar.phone.LockscreenLockIconController;
27 import com.android.systemui.statusbar.phone.NotificationPanelView;
28 import com.android.systemui.statusbar.phone.NotificationShadeWindowView;
29 import com.android.systemui.statusbar.phone.StatusBarWindowView;
30 import com.android.systemui.util.InjectionInflationController;
31 
32 import javax.inject.Inject;
33 import javax.inject.Singleton;
34 
35 /**
36  * Creates a single instance of super_status_bar and super_notification_shade that can be shared
37  * across various system ui objects.
38  */
39 @Singleton
40 public class SuperStatusBarViewFactory {
41 
42     private final Context mContext;
43     private final InjectionInflationController mInjectionInflationController;
44     private final NotificationRowComponent.Builder mNotificationRowComponentBuilder;
45     private final LockscreenLockIconController mLockIconController;
46 
47     private NotificationShadeWindowView mNotificationShadeWindowView;
48     private StatusBarWindowView mStatusBarWindowView;
49     private NotificationShelf mNotificationShelf;
50 
51     @Inject
SuperStatusBarViewFactory(Context context, InjectionInflationController injectionInflationController, NotificationRowComponent.Builder notificationRowComponentBuilder, LockscreenLockIconController lockIconController)52     public SuperStatusBarViewFactory(Context context,
53             InjectionInflationController injectionInflationController,
54             NotificationRowComponent.Builder notificationRowComponentBuilder,
55             LockscreenLockIconController lockIconController) {
56         mContext = context;
57         mInjectionInflationController = injectionInflationController;
58         mNotificationRowComponentBuilder = notificationRowComponentBuilder;
59         mLockIconController = lockIconController;
60     }
61 
62     /**
63      * Gets the inflated {@link NotificationShadeWindowView} from
64      * {@link R.layout#super_notification_shade}.
65      * Returns a cached instance, if it has already been inflated.
66      */
getNotificationShadeWindowView()67     public NotificationShadeWindowView getNotificationShadeWindowView() {
68         if (mNotificationShadeWindowView != null) {
69             return mNotificationShadeWindowView;
70         }
71 
72         mNotificationShadeWindowView = (NotificationShadeWindowView)
73                 mInjectionInflationController.injectable(
74                 LayoutInflater.from(mContext)).inflate(R.layout.super_notification_shade,
75                 /* root= */ null);
76         if (mNotificationShadeWindowView == null) {
77             throw new IllegalStateException(
78                     "R.layout.super_notification_shade could not be properly inflated");
79         }
80         LockIcon lockIcon = mNotificationShadeWindowView.findViewById(R.id.lock_icon);
81         if (lockIcon != null) {
82             mLockIconController.attach(lockIcon);
83         }
84 
85         return mNotificationShadeWindowView;
86     }
87 
88     /**
89      * Gets the inflated {@link StatusBarWindowView} from {@link R.layout#super_status_bar}.
90      * Returns a cached instance, if it has already been inflated.
91      */
getStatusBarWindowView()92     public StatusBarWindowView getStatusBarWindowView() {
93         if (mStatusBarWindowView != null) {
94             return mStatusBarWindowView;
95         }
96 
97         mStatusBarWindowView =
98                 (StatusBarWindowView) mInjectionInflationController.injectable(
99                 LayoutInflater.from(mContext)).inflate(R.layout.super_status_bar,
100                 /* root= */ null);
101         if (mStatusBarWindowView == null) {
102             throw new IllegalStateException(
103                     "R.layout.super_status_bar could not be properly inflated");
104         }
105         return mStatusBarWindowView;
106     }
107 
108     /**
109      * Gets the inflated {@link NotificationShelf} from
110      * {@link R.layout#status_bar_notification_shelf}.
111      * Returns a cached instance, if it has already been inflated.
112      *
113      * @param container the expected container to hold the {@link NotificationShelf}. The view
114      *                  isn't immediately attached, but the layout params of this view is used
115      *                  during inflation.
116      */
getNotificationShelf(ViewGroup container)117     public NotificationShelf getNotificationShelf(ViewGroup container) {
118         if (mNotificationShelf != null) {
119             return mNotificationShelf;
120         }
121 
122         mNotificationShelf = (NotificationShelf) mInjectionInflationController.injectable(
123                 LayoutInflater.from(mContext)).inflate(R.layout.status_bar_notification_shelf,
124                 container, /* attachToRoot= */ false);
125 
126         NotificationRowComponent component = mNotificationRowComponentBuilder
127                 .activatableNotificationView(mNotificationShelf)
128                 .build();
129         component.getActivatableNotificationViewController().init();
130 
131         if (mNotificationShelf == null) {
132             throw new IllegalStateException(
133                     "R.layout.status_bar_notification_shelf could not be properly inflated");
134         }
135         return mNotificationShelf;
136     }
137 
getNotificationPanelView()138     public NotificationPanelView getNotificationPanelView() {
139         NotificationShadeWindowView notificationShadeWindowView = getNotificationShadeWindowView();
140         if (notificationShadeWindowView == null) {
141             return null;
142         }
143 
144         return mNotificationShadeWindowView.findViewById(R.id.notification_panel);
145     }
146 }
147