KeyguardStatusView.java revision 93afa1dba63311dfdd43da82fed765240857ee30
1/* 2 * Copyright (C) 2012 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 17package com.android.keyguard; 18 19import android.content.ContentResolver; 20import android.content.Context; 21import android.content.res.Resources; 22import android.text.TextUtils; 23import android.text.format.DateFormat; 24import android.util.AttributeSet; 25import android.util.Log; 26import android.util.Slog; 27import android.view.View; 28import android.widget.GridLayout; 29import android.widget.TextClock; 30import android.widget.TextView; 31 32import com.android.internal.widget.LockPatternUtils; 33 34import java.util.Locale; 35 36public class KeyguardStatusView extends GridLayout { 37 private static final boolean DEBUG = KeyguardConstants.DEBUG; 38 private static final String TAG = "KeyguardStatusView"; 39 40 private LockPatternUtils mLockPatternUtils; 41 42 private TextView mAlarmStatusView; 43 private TextClock mDateView; 44 private TextClock mClockView; 45 private TextView mOwnerInfo; 46 47 private KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() { 48 49 @Override 50 public void onTimeChanged() { 51 refresh(); 52 } 53 54 @Override 55 public void onKeyguardVisibilityChanged(boolean showing) { 56 if (showing) { 57 if (DEBUG) Slog.v(TAG, "refresh statusview showing:" + showing); 58 refresh(); 59 updateOwnerInfo(); 60 } 61 } 62 63 @Override 64 public void onScreenTurnedOn() { 65 setEnableMarquee(true); 66 } 67 68 @Override 69 public void onScreenTurnedOff(int why) { 70 setEnableMarquee(false); 71 } 72 }; 73 74 public KeyguardStatusView(Context context) { 75 this(context, null, 0); 76 } 77 78 public KeyguardStatusView(Context context, AttributeSet attrs) { 79 this(context, attrs, 0); 80 } 81 82 public KeyguardStatusView(Context context, AttributeSet attrs, int defStyle) { 83 super(context, attrs, defStyle); 84 } 85 86 private void setEnableMarquee(boolean enabled) { 87 if (DEBUG) Log.v(TAG, (enabled ? "Enable" : "Disable") + " transport text marquee"); 88 if (mAlarmStatusView != null) mAlarmStatusView.setSelected(enabled); 89 mOwnerInfo.setSelected(enabled); 90 } 91 92 @Override 93 protected void onFinishInflate() { 94 super.onFinishInflate(); 95 mAlarmStatusView = (TextView) findViewById(R.id.alarm_status); 96 mDateView = (TextClock) findViewById(R.id.date_view); 97 mClockView = (TextClock) findViewById(R.id.clock_view); 98 mOwnerInfo = (TextView) findViewById(R.id.owner_info); 99 mLockPatternUtils = new LockPatternUtils(getContext()); 100 final boolean screenOn = KeyguardUpdateMonitor.getInstance(mContext).isScreenOn(); 101 setEnableMarquee(screenOn); 102 refresh(); 103 updateOwnerInfo(); 104 105 // Disable elegant text height because our fancy colon makes the ymin value huge for no 106 // reason. 107 mClockView.setElegantTextHeight(false); 108 } 109 110 protected void refresh() { 111 Patterns.update(mContext); 112 113 mDateView.setFormat24Hour(Patterns.dateView); 114 mDateView.setFormat12Hour(Patterns.dateView); 115 116 mClockView.setFormat12Hour(Patterns.clockView12); 117 mClockView.setFormat24Hour(Patterns.clockView24); 118 119 refreshAlarmStatus(); 120 } 121 122 void refreshAlarmStatus() { 123 // Update Alarm status 124 String nextAlarm = mLockPatternUtils.getNextAlarm(); 125 if (!TextUtils.isEmpty(nextAlarm)) { 126 mAlarmStatusView.setText(nextAlarm); 127 mAlarmStatusView.setVisibility(View.VISIBLE); 128 } else { 129 mAlarmStatusView.setVisibility(View.GONE); 130 } 131 } 132 133 private void updateOwnerInfo() { 134 String ownerInfo = getOwnerInfo(); 135 if (!TextUtils.isEmpty(ownerInfo)) { 136 mOwnerInfo.setVisibility(View.VISIBLE); 137 mOwnerInfo.setText(ownerInfo); 138 } else { 139 mOwnerInfo.setVisibility(View.GONE); 140 } 141 } 142 143 @Override 144 protected void onAttachedToWindow() { 145 super.onAttachedToWindow(); 146 KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mInfoCallback); 147 } 148 149 @Override 150 protected void onDetachedFromWindow() { 151 super.onDetachedFromWindow(); 152 KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mInfoCallback); 153 } 154 155 public int getAppWidgetId() { 156 return LockPatternUtils.ID_DEFAULT_STATUS_WIDGET; 157 } 158 159 private String getOwnerInfo() { 160 ContentResolver res = getContext().getContentResolver(); 161 String info = null; 162 final boolean ownerInfoEnabled = mLockPatternUtils.isOwnerInfoEnabled(); 163 if (ownerInfoEnabled) { 164 info = mLockPatternUtils.getOwnerInfo(mLockPatternUtils.getCurrentUser()); 165 } 166 return info; 167 } 168 169 // DateFormat.getBestDateTimePattern is extremely expensive, and refresh is called often. 170 // This is an optimization to ensure we only recompute the patterns when the inputs change. 171 private static final class Patterns { 172 static String dateView; 173 static String clockView12; 174 static String clockView24; 175 static String cacheKey; 176 177 static void update(Context context) { 178 final Locale locale = Locale.getDefault(); 179 final Resources res = context.getResources(); 180 final String dateViewSkel = res.getString(R.string.abbrev_wday_month_day_no_year); 181 final String clockView12Skel = res.getString(R.string.clock_12hr_format); 182 final String clockView24Skel = res.getString(R.string.clock_24hr_format); 183 final String key = locale.toString() + dateViewSkel + clockView12Skel + clockView24Skel; 184 if (key.equals(cacheKey)) return; 185 186 dateView = DateFormat.getBestDateTimePattern(locale, dateViewSkel); 187 188 clockView12 = DateFormat.getBestDateTimePattern(locale, clockView12Skel); 189 // CLDR insists on adding an AM/PM indicator even though it wasn't in the skeleton 190 // format. The following code removes the AM/PM indicator if we didn't want it. 191 if (!clockView12Skel.contains("a")) { 192 clockView12 = clockView12.replaceAll("a", "").trim(); 193 } 194 195 clockView24 = DateFormat.getBestDateTimePattern(locale, clockView24Skel); 196 197 // Use fancy colon. 198 clockView24 = clockView24.replace(':', '\uee01'); 199 clockView12 = clockView12.replace(':', '\uee01'); 200 201 cacheKey = key; 202 } 203 } 204} 205