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 KeyguardIndicationController(Context context, KeyguardIndicationTextView textView)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 setVisible(boolean visible)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 */ setRestingIndication(String restingIndication)84 public void setRestingIndication(String restingIndication) { 85 mRestingIndication = restingIndication; 86 updateIndication(); 87 } 88 89 /** 90 * Hides transient indication in {@param delayMs}. 91 */ hideTransientIndicationDelayed(long delayMs)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 */ showTransientIndication(int transientIndication)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 */ showTransientIndication(String transientIndication)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 */ hideTransientIndication()116 public void hideTransientIndication() { 117 if (mTransientIndication != null) { 118 mTransientIndication = null; 119 mHandler.removeMessages(MSG_HIDE_TRANSIENT); 120 updateIndication(); 121 } 122 } 123 updateIndication()124 private void updateIndication() { 125 if (mVisible) { 126 mTextView.switchIndication(computeIndication()); 127 } 128 } 129 computeIndication()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 computePowerIndication()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