diff options
Diffstat (limited to 'packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java')
-rw-r--r-- | packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java | 282 |
1 files changed, 282 insertions, 0 deletions
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java new file mode 100644 index 000000000000..f8f4f2a8b8fc --- /dev/null +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java @@ -0,0 +1,282 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.keyguard; + +import android.app.ActivityManager; +import android.app.AlarmManager; +import android.content.Context; +import android.content.res.Configuration; +import android.content.res.Resources; +import android.os.UserHandle; +import android.text.TextUtils; +import android.text.format.DateFormat; +import android.util.AttributeSet; +import android.util.Log; +import android.util.Slog; +import android.util.TypedValue; +import android.view.View; +import android.view.ViewGroup; +import android.widget.GridLayout; +import android.widget.TextClock; +import android.widget.TextView; + +import com.android.internal.widget.LockPatternUtils; + +import java.util.Locale; + +public class KeyguardStatusView extends GridLayout { + private static final boolean DEBUG = KeyguardConstants.DEBUG; + private static final String TAG = "KeyguardStatusView"; + + private final LockPatternUtils mLockPatternUtils; + private final AlarmManager mAlarmManager; + + private TextView mAlarmStatusView; + private TextClock mDateView; + private TextClock mClockView; + private TextView mOwnerInfo; + private ViewGroup mClockContainer; + + private KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() { + + @Override + public void onTimeChanged() { + refresh(); + } + + @Override + public void onKeyguardVisibilityChanged(boolean showing) { + if (showing) { + if (DEBUG) Slog.v(TAG, "refresh statusview showing:" + showing); + refresh(); + updateOwnerInfo(); + } + } + + @Override + public void onStartedWakingUp() { + setEnableMarquee(true); + } + + @Override + public void onFinishedGoingToSleep(int why) { + setEnableMarquee(false); + } + + @Override + public void onUserSwitchComplete(int userId) { + refresh(); + updateOwnerInfo(); + } + }; + + public KeyguardStatusView(Context context) { + this(context, null, 0); + } + + public KeyguardStatusView(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public KeyguardStatusView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); + mLockPatternUtils = new LockPatternUtils(getContext()); + } + + private void setEnableMarquee(boolean enabled) { + if (DEBUG) Log.v(TAG, (enabled ? "Enable" : "Disable") + " transport text marquee"); + if (mAlarmStatusView != null) mAlarmStatusView.setSelected(enabled); + if (mOwnerInfo != null) mOwnerInfo.setSelected(enabled); + } + + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + mClockContainer = (ViewGroup) findViewById(R.id.keyguard_clock_container); + mAlarmStatusView = (TextView) findViewById(R.id.alarm_status); + mDateView = (TextClock) findViewById(R.id.date_view); + mClockView = (TextClock) findViewById(R.id.clock_view); + mDateView.setShowCurrentUserTime(true); + mClockView.setShowCurrentUserTime(true); + mOwnerInfo = (TextView) findViewById(R.id.owner_info); + + boolean shouldMarquee = KeyguardUpdateMonitor.getInstance(mContext).isDeviceInteractive(); + setEnableMarquee(shouldMarquee); + refresh(); + updateOwnerInfo(); + + // Disable elegant text height because our fancy colon makes the ymin value huge for no + // reason. + mClockView.setElegantTextHeight(false); + } + + @Override + protected void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + mClockView.setTextSize(TypedValue.COMPLEX_UNIT_PX, + getResources().getDimensionPixelSize(R.dimen.widget_big_font_size)); + // Some layouts like burmese have a different margin for the clock + MarginLayoutParams layoutParams = (MarginLayoutParams) mClockView.getLayoutParams(); + layoutParams.bottomMargin = getResources().getDimensionPixelSize( + R.dimen.bottom_text_spacing_digital); + mClockView.setLayoutParams(layoutParams); + mDateView.setTextSize(TypedValue.COMPLEX_UNIT_PX, + getResources().getDimensionPixelSize(R.dimen.widget_label_font_size)); + mOwnerInfo.setTextSize(TypedValue.COMPLEX_UNIT_PX, + getResources().getDimensionPixelSize(R.dimen.widget_label_font_size)); + } + + public void refreshTime() { + mDateView.setFormat24Hour(Patterns.dateView); + mDateView.setFormat12Hour(Patterns.dateView); + + mClockView.setFormat12Hour(Patterns.clockView12); + mClockView.setFormat24Hour(Patterns.clockView24); + } + + private void refresh() { + AlarmManager.AlarmClockInfo nextAlarm = + mAlarmManager.getNextAlarmClock(UserHandle.USER_CURRENT); + Patterns.update(mContext, nextAlarm != null); + + refreshTime(); + refreshAlarmStatus(nextAlarm); + } + + void refreshAlarmStatus(AlarmManager.AlarmClockInfo nextAlarm) { + if (nextAlarm != null) { + String alarm = formatNextAlarm(mContext, nextAlarm); + mAlarmStatusView.setText(alarm); + mAlarmStatusView.setContentDescription( + getResources().getString(R.string.keyguard_accessibility_next_alarm, alarm)); + mAlarmStatusView.setVisibility(View.VISIBLE); + } else { + mAlarmStatusView.setVisibility(View.GONE); + } + } + + public int getClockBottom() { + return mClockView.getBottom() + + ((MarginLayoutParams) mClockView.getLayoutParams()).bottomMargin; + } + + public static String formatNextAlarm(Context context, AlarmManager.AlarmClockInfo info) { + if (info == null) { + return ""; + } + String skeleton = DateFormat.is24HourFormat(context, ActivityManager.getCurrentUser()) + ? "EHm" + : "Ehma"; + String pattern = DateFormat.getBestDateTimePattern(Locale.getDefault(), skeleton); + return DateFormat.format(pattern, info.getTriggerTime()).toString(); + } + + private void updateOwnerInfo() { + if (mOwnerInfo == null) return; + String ownerInfo = getOwnerInfo(); + if (!TextUtils.isEmpty(ownerInfo)) { + mOwnerInfo.setVisibility(View.VISIBLE); + mOwnerInfo.setText(ownerInfo); + } else { + mOwnerInfo.setVisibility(View.GONE); + } + } + + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mInfoCallback); + } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mInfoCallback); + } + + private String getOwnerInfo() { + String info = null; + if (mLockPatternUtils.isDeviceOwnerInfoEnabled()) { + // Use the device owner information set by device policy client via + // device policy manager. + info = mLockPatternUtils.getDeviceOwnerInfo(); + } else { + // Use the current user owner information if enabled. + final boolean ownerInfoEnabled = mLockPatternUtils.isOwnerInfoEnabled( + KeyguardUpdateMonitor.getCurrentUser()); + if (ownerInfoEnabled) { + info = mLockPatternUtils.getOwnerInfo(KeyguardUpdateMonitor.getCurrentUser()); + } + } + return info; + } + + @Override + public boolean hasOverlappingRendering() { + return false; + } + + // DateFormat.getBestDateTimePattern is extremely expensive, and refresh is called often. + // This is an optimization to ensure we only recompute the patterns when the inputs change. + private static final class Patterns { + static String dateView; + static String clockView12; + static String clockView24; + static String cacheKey; + + static void update(Context context, boolean hasAlarm) { + final Locale locale = Locale.getDefault(); + final Resources res = context.getResources(); + final String dateViewSkel = res.getString(hasAlarm + ? R.string.abbrev_wday_month_day_no_year_alarm + : R.string.abbrev_wday_month_day_no_year); + final String clockView12Skel = res.getString(R.string.clock_12hr_format); + final String clockView24Skel = res.getString(R.string.clock_24hr_format); + final String key = locale.toString() + dateViewSkel + clockView12Skel + clockView24Skel; + if (key.equals(cacheKey)) return; + + dateView = DateFormat.getBestDateTimePattern(locale, dateViewSkel); + + clockView12 = DateFormat.getBestDateTimePattern(locale, clockView12Skel); + // CLDR insists on adding an AM/PM indicator even though it wasn't in the skeleton + // format. The following code removes the AM/PM indicator if we didn't want it. + if (!clockView12Skel.contains("a")) { + clockView12 = clockView12.replaceAll("a", "").trim(); + } + + clockView24 = DateFormat.getBestDateTimePattern(locale, clockView24Skel); + + // Use fancy colon. + clockView24 = clockView24.replace(':', '\uee01'); + clockView12 = clockView12.replace(':', '\uee01'); + + cacheKey = key; + } + } + + public void setDark(boolean dark) { + final int N = mClockContainer.getChildCount(); + for (int i = 0; i < N; i++) { + View child = mClockContainer.getChildAt(i); + if (child == mClockView) { + continue; + } + child.setAlpha(dark ? 0 : 1); + } + } +} |