Home | History | Annotate | Download | only in car
      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
     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
     67     public void destroy() {
     68         mCarBatteryController.stopListening();
     69         super.destroy();
     70     }
     71 
     72     @Override
     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
     90     protected BatteryController createBatteryController() {
     91         mCarBatteryController = new CarBatteryController(mContext);
     92         mCarBatteryController.addBatteryViewHandler(this);
     93         return mCarBatteryController;
     94     }
     95 
     96     @Override
     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
    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
    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
    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 
    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
    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
    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
    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
    197     public void userSwitched(int newUserId) {
    198         super.userSwitched(newUserId);
    199         if (mFullscreenUserSwitcher != null) {
    200             mFullscreenUserSwitcher.onUserSwitched(newUserId);
    201         }
    202     }
    203 
    204     @Override
    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