1 /*
2  * Copyright (C) 2015 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.car;
18 
19 import android.app.ActivityManager;
20 import android.content.BroadcastReceiver;
21 import android.content.Context;
22 import android.content.Intent;
23 import android.content.IntentFilter;
24 import android.graphics.PixelFormat;
25 import android.util.Log;
26 import android.view.View;
27 import android.view.ViewGroup.LayoutParams;
28 import android.view.ViewStub;
29 import android.view.WindowManager;
30 import com.android.systemui.BatteryMeterView;
31 import com.android.systemui.R;
32 import com.android.systemui.recents.Recents;
33 import com.android.systemui.recents.misc.SystemServicesProxy;
34 import com.android.systemui.recents.misc.SystemServicesProxy.TaskStackListener;
35 import com.android.systemui.statusbar.StatusBarState;
36 import com.android.systemui.statusbar.phone.PhoneStatusBar;
37 import com.android.systemui.statusbar.phone.PhoneStatusBarView;
38 import com.android.systemui.statusbar.policy.BatteryController;
39 
40 /**
41  * A status bar (and navigation bar) tailored for the automotive use case.
42  */
43 public class CarStatusBar extends PhoneStatusBar implements
44         CarBatteryController.BatteryViewHandler {
45     private static final String TAG = "CarStatusBar";
46 
47     private TaskStackListenerImpl mTaskStackListener;
48 
49     private CarNavigationBarView mCarNavigationBar;
50     private CarNavigationBarController mController;
51     private FullscreenUserSwitcher mFullscreenUserSwitcher;
52 
53     private CarBatteryController mCarBatteryController;
54     private BatteryMeterView mBatteryMeterView;
55 
56     @Override
start()57     public void start() {
58         super.start();
59         mTaskStackListener = new TaskStackListenerImpl();
60         SystemServicesProxy.getInstance(mContext).registerTaskStackListener(mTaskStackListener);
61         registerPackageChangeReceivers();
62 
63         mCarBatteryController.startListening();
64     }
65 
66     @Override
destroy()67     public void destroy() {
68         mCarBatteryController.stopListening();
69         super.destroy();
70     }
71 
72     @Override
makeStatusBarView()73     protected PhoneStatusBarView makeStatusBarView() {
74         PhoneStatusBarView statusBarView = super.makeStatusBarView();
75 
76         mBatteryMeterView = ((BatteryMeterView) statusBarView.findViewById(R.id.battery));
77 
78         // By default, the BatteryMeterView should not be visible. It will be toggled visible
79         // when a device has connected by bluetooth.
80         mBatteryMeterView.setVisibility(View.GONE);
81 
82         if (Log.isLoggable(TAG, Log.DEBUG)) {
83             Log.d(TAG, "makeStatusBarView(). mBatteryMeterView: " + mBatteryMeterView);
84         }
85 
86         return statusBarView;
87     }
88 
89     @Override
createBatteryController()90     protected BatteryController createBatteryController() {
91         mCarBatteryController = new CarBatteryController(mContext);
92         mCarBatteryController.addBatteryViewHandler(this);
93         return mCarBatteryController;
94     }
95 
96     @Override
addNavigationBar()97     protected void addNavigationBar() {
98         WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
99                 LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
100                 WindowManager.LayoutParams.TYPE_NAVIGATION_BAR,
101                 WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
102                         | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
103                         | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
104                         | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
105                         | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
106                         | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
107                 PixelFormat.TRANSLUCENT);
108         lp.setTitle("CarNavigationBar");
109         lp.windowAnimations = 0;
110         mWindowManager.addView(mNavigationBarView, lp);
111     }
112 
113     @Override
createNavigationBarView(Context context)114     protected void createNavigationBarView(Context context) {
115         if (mNavigationBarView != null) {
116             return;
117         }
118         mCarNavigationBar =
119                 (CarNavigationBarView) View.inflate(context, R.layout.car_navigation_bar, null);
120         mController = new CarNavigationBarController(context, mCarNavigationBar,
121                 this /* ActivityStarter*/);
122         mNavigationBarView = mCarNavigationBar;
123 
124     }
125 
126     @Override
showBatteryView()127     public void showBatteryView() {
128         if (Log.isLoggable(TAG, Log.DEBUG)) {
129             Log.d(TAG, "showBatteryView(). mBatteryMeterView: " + mBatteryMeterView);
130         }
131 
132         if (mBatteryMeterView != null) {
133             mBatteryMeterView.setVisibility(View.VISIBLE);
134         }
135     }
136 
137     @Override
hideBatteryView()138     public void hideBatteryView() {
139         if (Log.isLoggable(TAG, Log.DEBUG)) {
140             Log.d(TAG, "hideBatteryView(). mBatteryMeterView: " + mBatteryMeterView);
141         }
142 
143         if (mBatteryMeterView != null) {
144             mBatteryMeterView.setVisibility(View.GONE);
145         }
146     }
147 
148     private BroadcastReceiver mPackageChangeReceiver = new BroadcastReceiver() {
149         @Override
150         public void onReceive(Context context, Intent intent) {
151             if (intent.getData() == null || mController == null) {
152                 return;
153             }
154             String packageName = intent.getData().getSchemeSpecificPart();
155             mController.onPackageChange(packageName);
156         }
157     };
158 
registerPackageChangeReceivers()159     private void registerPackageChangeReceivers() {
160         IntentFilter filter = new IntentFilter();
161         filter.addAction(Intent.ACTION_PACKAGE_ADDED);
162         filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
163         filter.addDataScheme("package");
164         mContext.registerReceiver(mPackageChangeReceiver, filter);
165     }
166 
167     @Override
repositionNavigationBar()168     protected void repositionNavigationBar() {
169         // The navigation bar for a vehicle will not need to be repositioned, as it is always
170         // set at the bottom.
171     }
172 
173     /**
174      * An implementation of TaskStackListener, that listens for changes in the system task
175      * stack and notifies the navigation bar.
176      */
177     private class TaskStackListenerImpl extends TaskStackListener {
178         @Override
onTaskStackChanged()179         public void onTaskStackChanged() {
180             SystemServicesProxy ssp = Recents.getSystemServices();
181             ActivityManager.RunningTaskInfo runningTaskInfo = ssp.getRunningTask();
182             mController.taskChanged(runningTaskInfo.baseActivity.getPackageName());
183         }
184     }
185 
186     @Override
createUserSwitcher()187     protected void createUserSwitcher() {
188         if (mUserSwitcherController.useFullscreenUserSwitcher()) {
189             mFullscreenUserSwitcher = new FullscreenUserSwitcher(this, mUserSwitcherController,
190                     (ViewStub) mStatusBarWindow.findViewById(R.id.fullscreen_user_switcher_stub));
191         } else {
192             super.createUserSwitcher();
193         }
194     }
195 
196     @Override
userSwitched(int newUserId)197     public void userSwitched(int newUserId) {
198         super.userSwitched(newUserId);
199         if (mFullscreenUserSwitcher != null) {
200             mFullscreenUserSwitcher.onUserSwitched(newUserId);
201         }
202     }
203 
204     @Override
updateKeyguardState(boolean goingToFullShade, boolean fromShadeLocked)205     public void updateKeyguardState(boolean goingToFullShade, boolean fromShadeLocked) {
206         super.updateKeyguardState(goingToFullShade, fromShadeLocked);
207         if (mFullscreenUserSwitcher != null) {
208             if (mState == StatusBarState.FULLSCREEN_USER_SWITCHER) {
209                 mFullscreenUserSwitcher.show();
210             } else {
211                 mFullscreenUserSwitcher.hide();
212             }
213         }
214     }
215 }
216