Home | History | Annotate | Download | only in statusbar
      1 /*
      2  * Copyright (C) 2014 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 com.android.internal.app.IBatteryStats;
     20 import com.android.keyguard.KeyguardUpdateMonitor;
     21 import com.android.keyguard.KeyguardUpdateMonitorCallback;
     22 import com.android.systemui.R;
     23 import com.android.systemui.statusbar.phone.KeyguardIndicationTextView;
     24 
     25 import android.content.BroadcastReceiver;
     26 import android.content.Context;
     27 import android.content.Intent;
     28 import android.content.IntentFilter;
     29 import android.os.BatteryManager;
     30 import android.os.BatteryStats;
     31 import android.os.Handler;
     32 import android.os.Message;
     33 import android.os.RemoteException;
     34 import android.os.ServiceManager;
     35 import android.os.UserHandle;
     36 import android.text.TextUtils;
     37 import android.text.format.Formatter;
     38 import android.util.Log;
     39 import android.view.View;
     40 
     41 /**
     42  * Controls the little text indicator on the keyguard.
     43  */
     44 public class KeyguardIndicationController {
     45 
     46     private static final String TAG = "KeyguardIndicationController";
     47 
     48     private static final int MSG_HIDE_TRANSIENT = 1;
     49 
     50     private final Context mContext;
     51     private final KeyguardIndicationTextView mTextView;
     52     private final IBatteryStats mBatteryInfo;
     53 
     54     private String mRestingIndication;
     55     private String mTransientIndication;
     56     private boolean mVisible;
     57 
     58     private boolean mPowerPluggedIn;
     59     private boolean mPowerCharged;
     60 
     61     public KeyguardIndicationController(Context context, KeyguardIndicationTextView textView) {
     62         mContext = context;
     63         mTextView = textView;
     64 
     65         mBatteryInfo = IBatteryStats.Stub.asInterface(
     66                 ServiceManager.getService(BatteryStats.SERVICE_NAME));
     67         KeyguardUpdateMonitor.getInstance(context).registerCallback(mUpdateMonitor);
     68         context.registerReceiverAsUser(
     69                 mReceiver, UserHandle.OWNER, new IntentFilter(Intent.ACTION_TIME_TICK), null, null);
     70     }
     71 
     72     public void setVisible(boolean visible) {
     73         mVisible = visible;
     74         mTextView.setVisibility(visible ? View.VISIBLE : View.GONE);
     75         if (visible) {
     76             hideTransientIndication();
     77             updateIndication();
     78         }
     79     }
     80 
     81     /**
     82      * Sets the indication that is shown if nothing else is showing.
     83      */
     84     public void setRestingIndication(String restingIndication) {
     85         mRestingIndication = restingIndication;
     86         updateIndication();
     87     }
     88 
     89     /**
     90      * Hides transient indication in {@param delayMs}.
     91      */
     92     public void hideTransientIndicationDelayed(long delayMs) {
     93         mHandler.sendMessageDelayed(
     94                 mHandler.obtainMessage(MSG_HIDE_TRANSIENT), delayMs);
     95     }
     96 
     97     /**
     98      * Shows {@param transientIndication} until it is hidden by {@link #hideTransientIndication}.
     99      */
    100     public void showTransientIndication(int transientIndication) {
    101         showTransientIndication(mContext.getResources().getString(transientIndication));
    102     }
    103 
    104     /**
    105      * Shows {@param transientIndication} until it is hidden by {@link #hideTransientIndication}.
    106      */
    107     public void showTransientIndication(String transientIndication) {
    108         mTransientIndication = transientIndication;
    109         mHandler.removeMessages(MSG_HIDE_TRANSIENT);
    110         updateIndication();
    111     }
    112 
    113     /**
    114      * Hides transient indication.
    115      */
    116     public void hideTransientIndication() {
    117         if (mTransientIndication != null) {
    118             mTransientIndication = null;
    119             mHandler.removeMessages(MSG_HIDE_TRANSIENT);
    120             updateIndication();
    121         }
    122     }
    123 
    124     private void updateIndication() {
    125         if (mVisible) {
    126             mTextView.switchIndication(computeIndication());
    127         }
    128     }
    129 
    130     private String computeIndication() {
    131         if (!TextUtils.isEmpty(mTransientIndication)) {
    132             return mTransientIndication;
    133         }
    134         if (mPowerPluggedIn) {
    135             return computePowerIndication();
    136         }
    137         return mRestingIndication;
    138     }
    139 
    140     private String computePowerIndication() {
    141         if (mPowerCharged) {
    142             return mContext.getResources().getString(R.string.keyguard_charged);
    143         }
    144 
    145         // Try fetching charging time from battery stats.
    146         try {
    147             long chargingTimeRemaining = mBatteryInfo.computeChargeTimeRemaining();
    148             if (chargingTimeRemaining > 0) {
    149                 String chargingTimeFormatted =
    150                         Formatter.formatShortElapsedTime(mContext, chargingTimeRemaining);
    151                 return mContext.getResources().getString(
    152                         R.string.keyguard_indication_charging_time, chargingTimeFormatted);
    153             }
    154         } catch (RemoteException e) {
    155             Log.e(TAG, "Error calling IBatteryStats: ", e);
    156         }
    157 
    158         // Fall back to simple charging label.
    159         return mContext.getResources().getString(R.string.keyguard_plugged_in);
    160     }
    161 
    162     KeyguardUpdateMonitorCallback mUpdateMonitor = new KeyguardUpdateMonitorCallback() {
    163         @Override
    164         public void onRefreshBatteryInfo(KeyguardUpdateMonitor.BatteryStatus status) {
    165             mPowerPluggedIn = status.status == BatteryManager.BATTERY_STATUS_CHARGING
    166                     || status.status == BatteryManager.BATTERY_STATUS_FULL;
    167             mPowerCharged = status.isCharged();
    168             updateIndication();
    169         }
    170     };
    171 
    172     BroadcastReceiver mReceiver = new BroadcastReceiver() {
    173         @Override
    174         public void onReceive(Context context, Intent intent) {
    175             if (mVisible) {
    176                 updateIndication();
    177             }
    178         }
    179     };
    180 
    181     private final Handler mHandler = new Handler() {
    182         @Override
    183         public void handleMessage(Message msg) {
    184             if (msg.what == MSG_HIDE_TRANSIENT && mTransientIndication != null) {
    185                 mTransientIndication = null;
    186                 updateIndication();
    187             }
    188         }
    189     };
    190 }
    191