Merge "Remove unused keyguard code"

This commit is contained in:
Jim Miller
2013-01-03 15:49:00 -08:00
committed by Android (Google) Code Review
51 changed files with 1 additions and 12663 deletions

View File

@@ -1,245 +0,0 @@
/*
* Copyright (C) 2008 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.internal.widget;
import com.android.internal.R;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.ContentObserver;
import android.graphics.Typeface;
import android.os.Handler;
import android.provider.Settings;
import android.text.format.DateFormat;
import android.util.AttributeSet;
import android.view.View;
import android.widget.RelativeLayout;
import android.widget.TextView;
import java.lang.ref.WeakReference;
import java.text.DateFormatSymbols;
import java.util.Calendar;
/**
* Displays the time
*/
public class DigitalClock extends RelativeLayout {
private static final String SYSTEM = "/system/fonts/";
private static final String SYSTEM_FONT_TIME_BACKGROUND = SYSTEM + "AndroidClock.ttf";
private static final String SYSTEM_FONT_TIME_FOREGROUND = SYSTEM + "AndroidClock_Highlight.ttf";
private final static String M12 = "h:mm";
private final static String M24 = "kk:mm";
private Calendar mCalendar;
private String mFormat;
private TextView mTimeDisplayBackground;
private TextView mTimeDisplayForeground;
private AmPm mAmPm;
private ContentObserver mFormatChangeObserver;
private int mAttached = 0; // for debugging - tells us whether attach/detach is unbalanced
/* called by system on minute ticks */
private final Handler mHandler = new Handler();
private BroadcastReceiver mIntentReceiver;
private static final Typeface sBackgroundFont;
private static final Typeface sForegroundFont;
static {
sBackgroundFont = Typeface.createFromFile(SYSTEM_FONT_TIME_BACKGROUND);
sForegroundFont = Typeface.createFromFile(SYSTEM_FONT_TIME_FOREGROUND);
}
private static class TimeChangedReceiver extends BroadcastReceiver {
private WeakReference<DigitalClock> mClock;
private Context mContext;
public TimeChangedReceiver(DigitalClock clock) {
mClock = new WeakReference<DigitalClock>(clock);
mContext = clock.getContext();
}
@Override
public void onReceive(Context context, Intent intent) {
// Post a runnable to avoid blocking the broadcast.
final boolean timezoneChanged =
intent.getAction().equals(Intent.ACTION_TIMEZONE_CHANGED);
final DigitalClock clock = mClock.get();
if (clock != null) {
clock.mHandler.post(new Runnable() {
public void run() {
if (timezoneChanged) {
clock.mCalendar = Calendar.getInstance();
}
clock.updateTime();
}
});
} else {
try {
mContext.unregisterReceiver(this);
} catch (RuntimeException e) {
// Shouldn't happen
}
}
}
};
static class AmPm {
private TextView mAmPmTextView;
private String mAmString, mPmString;
AmPm(View parent, Typeface tf) {
// No longer used, uncomment if we decide to use AM/PM indicator again
// mAmPmTextView = (TextView) parent.findViewById(R.id.am_pm);
if (mAmPmTextView != null && tf != null) {
mAmPmTextView.setTypeface(tf);
}
String[] ampm = new DateFormatSymbols().getAmPmStrings();
mAmString = ampm[0];
mPmString = ampm[1];
}
void setShowAmPm(boolean show) {
if (mAmPmTextView != null) {
mAmPmTextView.setVisibility(show ? View.VISIBLE : View.GONE);
}
}
void setIsMorning(boolean isMorning) {
if (mAmPmTextView != null) {
mAmPmTextView.setText(isMorning ? mAmString : mPmString);
}
}
}
private static class FormatChangeObserver extends ContentObserver {
private WeakReference<DigitalClock> mClock;
private Context mContext;
public FormatChangeObserver(DigitalClock clock) {
super(new Handler());
mClock = new WeakReference<DigitalClock>(clock);
mContext = clock.getContext();
}
@Override
public void onChange(boolean selfChange) {
DigitalClock digitalClock = mClock.get();
if (digitalClock != null) {
digitalClock.setDateFormat();
digitalClock.updateTime();
} else {
try {
mContext.getContentResolver().unregisterContentObserver(this);
} catch (RuntimeException e) {
// Shouldn't happen
}
}
}
}
public DigitalClock(Context context) {
this(context, null);
}
public DigitalClock(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
/* The time display consists of two tones. That's why we have two overlapping text views. */
mTimeDisplayBackground = (TextView) findViewById(R.id.timeDisplayBackground);
mTimeDisplayBackground.setTypeface(sBackgroundFont);
mTimeDisplayBackground.setVisibility(View.INVISIBLE);
mTimeDisplayForeground = (TextView) findViewById(R.id.timeDisplayForeground);
mTimeDisplayForeground.setTypeface(sForegroundFont);
mAmPm = new AmPm(this, null);
mCalendar = Calendar.getInstance();
setDateFormat();
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
mAttached++;
/* monitor time ticks, time changed, timezone */
if (mIntentReceiver == null) {
mIntentReceiver = new TimeChangedReceiver(this);
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_TIME_TICK);
filter.addAction(Intent.ACTION_TIME_CHANGED);
filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
mContext.registerReceiver(mIntentReceiver, filter);
}
/* monitor 12/24-hour display preference */
if (mFormatChangeObserver == null) {
mFormatChangeObserver = new FormatChangeObserver(this);
mContext.getContentResolver().registerContentObserver(
Settings.System.CONTENT_URI, true, mFormatChangeObserver);
}
updateTime();
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
mAttached--;
if (mIntentReceiver != null) {
mContext.unregisterReceiver(mIntentReceiver);
}
if (mFormatChangeObserver != null) {
mContext.getContentResolver().unregisterContentObserver(
mFormatChangeObserver);
}
mFormatChangeObserver = null;
mIntentReceiver = null;
}
void updateTime(Calendar c) {
mCalendar = c;
updateTime();
}
public void updateTime() {
mCalendar.setTimeInMillis(System.currentTimeMillis());
CharSequence newTime = DateFormat.format(mFormat, mCalendar);
mTimeDisplayBackground.setText(newTime);
mTimeDisplayForeground.setText(newTime);
mAmPm.setIsMorning(mCalendar.get(Calendar.AM_PM) == 0);
}
private void setDateFormat() {
mFormat = android.text.format.DateFormat.is24HourFormat(getContext())
? M24 : M12;
mAmPm.setShowAmPm(mFormat.equals(M12));
}
}

View File

@@ -1,136 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
**
** Copyright 2008, 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.
*/
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@android:color/background_dark"
>
<ScrollView
android:layout_width="match_parent"
android:layout_height="0px"
android:layout_weight="1"
android:layout_above="@+id/emergencyCallButton">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/topHeader"
android:layout_width="match_parent"
android:layout_height="64dip"
android:layout_alignParentTop="true"
android:layout_marginStart="4dip"
android:textAppearance="?android:attr/textAppearanceMedium"
android:gravity="center_vertical"
android:drawableLeft="@drawable/ic_lock_idle_lock"
android:drawablePadding="5dip"
/>
<!-- spacer below header -->
<View
android:id="@+id/spacerTop"
android:layout_width="match_parent"
android:layout_height="1dip"
android:layout_below="@id/topHeader"
android:background="@drawable/divider_horizontal_dark"/>
<TextView
android:id="@+id/instructions"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/spacerTop"
android:layout_marginTop="8dip"
android:layout_marginStart="9dip"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="@android:string/lockscreen_glogin_instructions"
/>
<EditText
android:id="@+id/login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/instructions"
android:layout_marginTop="8dip"
android:layout_marginStart="7dip"
android:layout_marginEnd="7dip"
android:hint="@android:string/lockscreen_glogin_username_hint"
android:inputType="textEmailAddress"
/>
<EditText
android:id="@+id/password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/login"
android:layout_marginTop="15dip"
android:layout_marginStart="7dip"
android:layout_marginEnd="7dip"
android:inputType="textPassword"
android:hint="@android:string/lockscreen_glogin_password_hint"
android:nextFocusRight="@+id/ok"
android:nextFocusDown="@+id/ok"
/>
<!-- ok below password, aligned to right of screen -->
<Button
android:id="@+id/ok"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/password"
android:layout_marginTop="7dip"
android:layout_marginEnd="7dip"
android:layout_alignParentEnd="true"
android:text="@android:string/lockscreen_glogin_submit_button"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/ok"
android:layout_marginTop="50dip"
android:text="@android:string/lockscreen_glogin_account_recovery_hint"
android:textAppearance="?android:attr/textAppearanceMedium"
android:gravity="center_horizontal"
/>
</RelativeLayout>
</ScrollView>
<!-- spacer above emergency call -->
<View
android:layout_width="match_parent"
android:layout_height="1dip"
android:layout_marginBottom="4dip"
android:background="@drawable/divider_horizontal_dark"/>
<!-- emergency call button at bottom center -->
<Button
android:id="@+id/emergencyCallButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:drawableLeft="@drawable/ic_emergency"
android:drawablePadding="8dip"
android:text="@android:string/lockscreen_emergency_call"
android:visibility="gone"
/>
</LinearLayout>

View File

@@ -1,218 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
**
** Copyright 2008, 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.
*/
-->
<!-- This is the general lock screen which shows information about the
state of the device, as well as instructions on how to get past it
depending on the state of the device. It is the same for landscape
and portrait.-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:gravity="bottom"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginBottom="15dip"
android:layout_marginStart="15dip"
android:layout_marginEnd="15dip"
android:paddingTop="20dip"
android:paddingBottom="20dip"
android:background="@android:drawable/popup_full_dark"
>
<!-- when sim is present -->
<TextView android:id="@+id/headerSimOk1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textSize="34sp"/>
<TextView android:id="@+id/headerSimOk2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textSize="34sp"/>
<!-- when sim is missing / locked -->
<TextView android:id="@+id/headerSimBad1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@android:string/lockscreen_missing_sim_message"
android:textAppearance="?android:attr/textAppearanceLarge"/>
<TextView android:id="@+id/headerSimBad2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="7dip"
android:layout_marginBottom="7dip"
android:gravity="center"
android:text="@android:string/lockscreen_missing_sim_instructions"
android:textAppearance="?android:attr/textAppearanceSmall"/>
<!-- spacer after carrier info / sim messages -->
<View
android:layout_width="match_parent"
android:layout_height="1dip"
android:layout_marginTop="8dip"
android:background="@android:drawable/divider_horizontal_dark"/>
<!-- time and date -->
<TextView android:id="@+id/time"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textSize="34sp"/>
<TextView android:id="@+id/date"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textSize="18sp"/>
<!-- spacer after time and date -->
<View
android:layout_width="match_parent"
android:layout_height="1dip"
android:layout_marginBottom="8dip"
android:background="@android:drawable/divider_horizontal_dark"
/>
<!-- battery info -->
<LinearLayout android:id="@+id/batteryInfo"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
>
<ImageView android:id="@+id/batteryInfoIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="6dip"
android:baselineAligned="true"
android:gravity="center"
/>
<TextView android:id="@+id/batteryInfoText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:gravity="center"
/>
</LinearLayout>
<!-- spacer after battery info -->
<View android:id="@+id/batteryInfoSpacer"
android:layout_width="match_parent"
android:layout_height="1dip"
android:layout_marginTop="8dip"
android:layout_marginBottom="8dip"
android:background="@android:drawable/divider_horizontal_dark"
/>
<!-- next alarm info -->
<LinearLayout android:id="@+id/nextAlarmInfo"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="6dip"
android:baselineAligned="true"
android:src="@android:drawable/ic_lock_idle_alarm"
android:gravity="center"
/>
<TextView android:id="@+id/nextAlarmText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:gravity="center"
/>
</LinearLayout>
<!-- spacer after alarm info -->
<View android:id="@+id/nextAlarmSpacer"
android:layout_width="match_parent"
android:layout_height="1dip"
android:layout_marginTop="8dip"
android:layout_marginBottom="8dip"
android:background="@android:drawable/divider_horizontal_dark"/>
<!-- lock icon with 'screen locked' message
(shown when SIM card is present) -->
<LinearLayout android:id="@+id/screenLockedInfo"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="6dip"
android:baselineAligned="true"
android:src="@android:drawable/ic_lock_idle_lock"
android:gravity="center"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:text="@android:string/lockscreen_screen_locked"
android:gravity="center"
/>
</LinearLayout>
<!-- message about how to unlock
(shown when SIM card is present) -->
<TextView android:id="@+id/lockInstructions"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="5dip"
android:gravity="center"
android:textSize="14sp"/>
<!-- emergency call button shown when sim is missing or PUKd -->
<Button
android:id="@+id/emergencyCallButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="5dip"
android:layout_marginTop="5dip"
android:layout_gravity="center_horizontal"
android:drawableLeft="@drawable/ic_emergency"
android:drawablePadding="8dip"
android:text="@android:string/lockscreen_emergency_call"
/>
</LinearLayout>
</LinearLayout>

View File

@@ -1,184 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
**
** Copyright 2008, 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.
*/
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- left side: status and music -->
<RelativeLayout
android:layout_height="match_parent"
android:layout_weight="1"
android:layout_width="0dip"
android:gravity="center">
<RelativeLayout android:id="@+id/transport_bg_protect"
android:layout_width="512dip"
android:layout_height="wrap_content"
android:layout_marginBottom="24dip">
<!-- Status -->
<include layout="@layout/keyguard_screen_status_land"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="50dip"
android:layout_marginTop="50dip"
android:layout_marginBottom="50dip"
android:layout_marginEnd="64dip"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"/>
<!-- Music transport control -->
<include android:id="@+id/transport"
layout="@layout/keyguard_transport_control"
android:layout_row="0"
android:layout_column="0"
android:layout_rowSpan="3"
android:layout_columnSpan="1"
android:layout_gravity="fill"
android:layout_width="match_parent"
android:layout_height="512dip"
/>
</RelativeLayout>
</RelativeLayout>
<!-- right side: password -->
<RelativeLayout
android:layout_width="0dip"
android:layout_weight="1"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center">
<LinearLayout
android:orientation="vertical"
android:layout_centerInParent="true"
android:layout_width="330dip"
android:layout_height="wrap_content">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="@drawable/lockscreen_password_field_dark">
<EditText android:id="@+id/passwordEntry"
android:layout_height="wrap_content"
android:layout_width="0dip"
android:layout_weight="1"
android:gravity="center"
android:layout_gravity="center"
android:singleLine="true"
android:textStyle="normal"
android:inputType="textPassword"
android:textSize="24sp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:background="@null"
android:textColor="#ffffffff"
android:imeOptions="flagForceAscii|flagNoFullscreen|actionDone"
/>
<!-- This delete button is only visible for numeric PIN entry -->
<ImageButton android:id="@+id/pinDel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@android:drawable/ic_input_delete"
android:clickable="true"
android:padding="8dip"
android:layout_gravity="center"
android:background="?android:attr/selectableItemBackground"
android:visibility="gone"
/>
<!-- The IME switcher button is only shown in ASCII password mode (not PIN) -->
<ImageView android:id="@+id/switch_ime_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_lockscreen_ime"
android:clickable="true"
android:padding="8dip"
android:layout_gravity="center"
android:background="?android:attr/selectableItemBackground"
android:visibility="gone"
/>
</LinearLayout>
<!-- Numeric keyboard -->
<com.android.internal.widget.PasswordEntryKeyboardView android:id="@+id/keyboard"
android:layout_width="match_parent"
android:layout_height="330dip"
android:background="#40000000"
android:layout_marginTop="5dip"
android:keyBackground="@drawable/btn_keyboard_key_ics"
android:visibility="gone"
android:clickable="true"
/>
<!-- Emergency call button. Generally not used on tablet devices. -->
<Button
android:id="@+id/emergencyCallButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:drawableLeft="@drawable/ic_emergency"
android:drawablePadding="8dip"
android:text="@string/lockscreen_emergency_call"
android:visibility="gone"
style="@style/Widget.Button.Transparent"
/>
</LinearLayout>
<!-- Area to overlay FaceLock -->
<RelativeLayout
android:id="@+id/face_unlock_area_view"
android:visibility="invisible"
android:layout_width="530dip"
android:layout_height="530dip"
android:layout_centerInParent="true"
android:background="@drawable/intro_bg">
<View
android:id="@+id/spotlightMask"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/facelock_spotlight_mask"
/>
<ImageView
android:id="@+id/cancel_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dip"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:src="@drawable/ic_facial_backup"
/>
</RelativeLayout>
</RelativeLayout>
</LinearLayout>

View File

@@ -1,187 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
**
** Copyright 2008, 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.
*/
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- top: status and emergency/forgot pattern buttons -->
<RelativeLayout
android:layout_height="0dip"
android:layout_weight="0.40"
android:layout_width="match_parent"
android:gravity="center">
<RelativeLayout android:id="@+id/transport_bg_protect"
android:layout_width="512dip"
android:layout_height="wrap_content"
android:gravity="center">
<!-- Status -->
<include layout="@layout/keyguard_screen_status_port"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="50dip"
android:layout_marginTop="50dip"
android:layout_marginEnd="64dip"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"/>
<!-- Music transport control -->
<include android:id="@+id/transport"
layout="@layout/keyguard_transport_control"
android:layout_row="0"
android:layout_column="0"
android:layout_rowSpan="3"
android:layout_columnSpan="1"
android:layout_gravity="fill"
android:layout_width="match_parent"
android:layout_height="512dip"
/>
</RelativeLayout>
</RelativeLayout>
<!-- bottom: password -->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="0.60"
android:gravity="center">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:orientation="vertical"
android:gravity="center">
<!-- Password entry field -->
<LinearLayout
android:orientation="horizontal"
android:layout_width="330dip"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="120dip"
android:layout_marginBottom="5dip"
android:background="@drawable/lockscreen_password_field_dark">
<EditText android:id="@+id/passwordEntry"
android:layout_height="wrap_content"
android:layout_width="0dip"
android:layout_weight="1"
android:singleLine="true"
android:textStyle="normal"
android:inputType="textPassword"
android:gravity="center"
android:layout_gravity="center"
android:textSize="24sp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:background="@null"
android:textColor="#ffffffff"
android:imeOptions="flagForceAscii|actionDone"
/>
<!-- This delete button is only visible for numeric PIN entry -->
<ImageButton android:id="@+id/pinDel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@android:drawable/ic_input_delete"
android:clickable="true"
android:padding="8dip"
android:layout_gravity="center"
android:background="?android:attr/selectableItemBackground"
android:visibility="gone"
/>
<ImageView android:id="@+id/switch_ime_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_lockscreen_ime"
android:clickable="true"
android:padding="8dip"
android:layout_gravity="center"
android:background="?android:attr/selectableItemBackground"
android:visibility="gone"
/>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1"
/>
<!-- Numeric keyboard -->
<com.android.internal.widget.PasswordEntryKeyboardView android:id="@+id/keyboard"
android:layout_width="330dip"
android:layout_height="260dip"
android:background="#40000000"
android:keyBackground="@drawable/btn_keyboard_key_ics"
android:layout_marginBottom="80dip"
android:clickable="true"
/>
<!-- emergency call button -->
<Button android:id="@+id/emergencyCallButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableLeft="@drawable/ic_emergency"
android:drawablePadding="8dip"
android:text="@string/lockscreen_emergency_call"
android:visibility="gone"
style="@style/Widget.Button.Transparent"
/>
</LinearLayout>
<!-- Area to overlay FaceLock -->
<RelativeLayout
android:id="@+id/face_unlock_area_view"
android:visibility="invisible"
android:layout_width="440dip"
android:layout_height="440dip"
android:layout_centerInParent="true"
android:background="@drawable/intro_bg">
<View
android:id="@+id/spotlightMask"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/facelock_spotlight_mask"
/>
<ImageView
android:id="@+id/cancel_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dip"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:src="@drawable/ic_facial_backup"
/>
</RelativeLayout>
</RelativeLayout>
</LinearLayout>

View File

@@ -1,122 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
**
** Copyright 2008, 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.
*/
-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/background_dark"
>
<!-- right side -->
<!-- header text ('Enter Pin Code') -->
<TextView android:id="@+id/headerText"
android:layout_above="@+id/carrier"
android:layout_centerHorizontal="true"
android:layout_marginBottom="30dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="24sp"
/>
<!-- Carrier info -->
<TextView android:id="@+id/carrier"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_above="@+id/pinDisplayGroup"
android:layout_marginTop="9dip"
android:gravity="start|bottom"
android:singleLine="true"
android:ellipsize="marquee"
android:textAppearance="?android:attr/textAppearanceMedium"
/>
<!-- displays dots as user enters pin -->
<LinearLayout android:id="@+id/pinDisplayGroup"
android:orientation="horizontal"
android:layout_centerInParent="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:addStatesFromChildren="true"
android:gravity="center_vertical"
android:baselineAligned="false"
android:paddingEnd="0dip"
android:layout_marginEnd="30dip"
android:layout_marginStart="30dip"
android:background="@android:drawable/edit_text"
>
<EditText android:id="@+id/pinDisplay"
android:layout_width="0dip"
android:layout_weight="1"
android:layout_height="match_parent"
android:maxLines="1"
android:background="@null"
android:textSize="32sp"
android:inputType="textPassword"
/>
<ImageButton android:id="@+id/backspace"
android:src="@android:drawable/ic_input_delete"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginTop="2dip"
android:layout_marginEnd="2dip"
android:layout_marginBottom="2dip"
android:gravity="center"
/>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dip"
android:layout_marginStart="8dip"
android:layout_marginEnd="8dip">
<Button android:id="@+id/emergencyCallButton"
android:text="@android:string/lockscreen_emergency_call"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1.0"
android:layout_marginBottom="8dip"
android:layout_marginEnd="8dip"
android:textSize="18sp"
android:drawableLeft="@drawable/ic_emergency"
android:drawablePadding="8dip"
/>
<Button android:id="@+id/ok"
android:text="@android:string/ok"
android:layout_alignParentBottom="true"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1.0"
android:layout_marginBottom="8dip"
android:layout_marginStart="8dip"
android:textSize="18sp"
/>
</LinearLayout>
</RelativeLayout>

View File

@@ -1,120 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
**
** Copyright 2008, 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.
*/
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@android:color/background_dark"
android:gravity="center_horizontal">
<LinearLayout android:id="@+id/topDisplayGroup"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- header text ('Enter Pin Code') -->
<TextView android:id="@+id/headerText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceLarge"/>
<!-- Carrier info -->
<TextView android:id="@+id/carrier"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="9dip"
android:gravity="center"
android:singleLine="true"
android:ellipsize="marquee"
android:textAppearance="?android:attr/textAppearanceMedium"/>
<!-- password entry -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginEnd="6dip"
android:layout_marginStart="6dip"
android:gravity="center_vertical"
android:background="@android:drawable/edit_text">
<!-- displays dots as user enters pin -->
<EditText android:id="@+id/pinDisplay"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:maxLines="1"
android:textAppearance="?android:attr/textAppearanceLargeInverse"
android:textColor="@android:color/primary_text_holo_light"
android:textStyle="bold"
android:inputType="textPassword"
/>
<ImageButton android:id="@+id/backspace"
android:src="@android:drawable/ic_input_delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="-3dip"
android:layout_marginBottom="-3dip"
/>
</LinearLayout>
</LinearLayout>
<include
android:id="@+id/keyPad"
layout="@android:layout/twelve_key_entry"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/topDisplayGroup"
android:layout_marginTop="10dip"
/>
<!-- spacer below keypad -->
<View
android:id="@+id/spacerBottom"
android:layout_width="match_parent"
android:layout_height="1dip"
android:layout_marginTop="6dip"
android:layout_above="@id/emergencyCallButton"
android:background="@android:drawable/divider_horizontal_dark"
/>
<!-- The emergency button should take the rest of the space and be centered vertically -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical">
<!-- emergency call button -->
<Button
android:id="@+id/emergencyCallButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableLeft="@android:drawable/ic_emergency"
android:drawablePadding="8dip"
android:text="@android:string/lockscreen_emergency_call"
/>
</LinearLayout>
</LinearLayout>

View File

@@ -1,123 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
**
** Copyright 2010, 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.
*/
-->
<!-- Status to show on the left side of lock screen -->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="end">
<TextView
android:id="@+id/carrier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="16sp"
android:drawablePadding="4dip"
android:layout_marginTop="32dip"
android:singleLine="true"
android:ellipsize="marquee"
android:visibility="gone"
/>
<com.android.internal.widget.DigitalClock android:id="@+id/time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dip"
android:layout_marginBottom="8dip"
>
<!-- Because we can't have multi-tone fonts, we render two TextViews, one on
top of the other. Hence the redundant layout... -->
<TextView android:id="@+id/timeDisplayBackground"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:ellipsize="none"
android:textSize="@dimen/keyguard_pattern_unlock_clock_font_size"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="@color/lockscreen_clock_background"
android:layout_marginBottom="6dip"
/>
<TextView android:id="@+id/timeDisplayForeground"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:ellipsize="none"
android:textSize="@dimen/keyguard_pattern_unlock_clock_font_size"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="@color/lockscreen_clock_foreground"
android:layout_alignStart="@id/timeDisplayBackground"
android:layout_alignTop="@id/timeDisplayBackground"
android:layout_marginBottom="6dip"
/>
</com.android.internal.widget.DigitalClock>
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/time"
android:layout_marginTop="10dip">
<TextView
android:id="@+id/date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="16sp"/>
<TextView
android:id="@+id/alarm_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dip"
android:textAppearance="?android:attr/textAppearanceMedium"
android:drawablePadding="4dip"
android:textSize="16sp"/>
</LinearLayout>
<!-- Status1 is generally battery status and informational messages -->
<TextView
android:id="@+id/status1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dip"
android:textSize="16sp"
android:textAppearance="?android:attr/textAppearanceMedium"
/>
<TextView
android:id="@+id/owner_info"
android:lineSpacingExtra="8dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="16sp"
android:layout_marginTop="20dip"
android:singleLine="false"
android:textColor="@color/lockscreen_owner_info"
android:visibility="invisible"
/>
</LinearLayout>

View File

@@ -1,123 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
**
** Copyright 2010, 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.
*/
-->
<!-- Status to show on the left side of lock screen -->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dip"
android:gravity="end"
>
<TextView
android:id="@+id/carrier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="16sp"
android:drawablePadding="4dip"
android:layout_marginTop="32dip"
android:singleLine="true"
android:ellipsize="marquee"
android:visibility="gone"
/>
<com.android.internal.widget.DigitalClock android:id="@+id/time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dip"
android:layout_marginBottom="8dip">
<!-- Because we can't have multi-tone fonts, we render two TextViews, one on
top of the other. Hence the redundant layout... -->
<TextView android:id="@+id/timeDisplayBackground"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:ellipsize="none"
android:textSize="@dimen/keyguard_pattern_unlock_clock_font_size"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="@color/lockscreen_clock_background"
android:layout_marginBottom="6dip"
/>
<TextView android:id="@+id/timeDisplayForeground"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:ellipsize="none"
android:textSize="@dimen/keyguard_pattern_unlock_clock_font_size"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="@color/lockscreen_clock_foreground"
android:layout_marginBottom="6dip"
android:layout_alignStart="@id/timeDisplayBackground"
android:layout_alignTop="@id/timeDisplayBackground"
/>
</com.android.internal.widget.DigitalClock>
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/time"
android:layout_marginTop="10dip">
<TextView
android:id="@+id/date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="16sp"/>
<TextView
android:id="@+id/alarm_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dip"
android:textAppearance="?android:attr/textAppearanceMedium"
android:drawablePadding="4dip"
android:textSize="16sp"/>
</LinearLayout>
<TextView
android:id="@+id/status1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dip"
android:textSize="16sp"
android:textAppearance="?android:attr/textAppearanceMedium"
/>
<TextView
android:id="@+id/owner_info"
android:lineSpacingExtra="8dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dip"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="16sp"
android:singleLine="false"
android:visibility="invisible"
android:textColor="@color/lockscreen_owner_info"
/>
</LinearLayout>

View File

@@ -1,124 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
**
** Copyright 2009, 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.
*/
-->
<!-- This is the general lock screen which shows information about the
state of the device, as well as instructions on how to get past it
depending on the state of the device. It is the same for landscape
and portrait.-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tabunlock="http://schemas.android.com/apk/res/com.android.tabunlock"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="@+id/root">
<!-- top: status -->
<RelativeLayout
android:layout_height="0dip"
android:layout_weight="0.42"
android:layout_width="match_parent"
android:gravity="center">
<RelativeLayout android:id="@+id/transport_bg_protect"
android:layout_width="512dip"
android:layout_height="wrap_content"
android:gravity="center">
<!-- Status -->
<include layout="@layout/keyguard_screen_status_port"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="50dip"
android:layout_marginTop="50dip"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"/>
<!-- Music transport control -->
<include android:id="@+id/transport"
layout="@layout/keyguard_transport_control"
android:layout_row="0"
android:layout_column="0"
android:layout_rowSpan="3"
android:layout_columnSpan="1"
android:layout_gravity="fill"
android:layout_width="match_parent"
android:layout_height="512dip"
/>
</RelativeLayout>
</RelativeLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="0.58"
android:orientation="vertical"
android:gravity="bottom">
<TextView
android:id="@+id/screenLocked"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="24dip"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_marginTop="12dip"
android:drawablePadding="4dip"
/>
<com.android.internal.widget.multiwaveview.GlowPadView
android:id="@+id/unlock_widget"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:gravity="center"
android:focusable="true"
android:targetDrawables="@array/lockscreen_targets_with_camera"
android:targetDescriptions="@array/lockscreen_target_descriptions_with_camera"
android:directionDescriptions="@array/lockscreen_direction_descriptions"
android:handleDrawable="@drawable/ic_lockscreen_handle"
android:outerRingDrawable="@drawable/ic_lockscreen_outerring"
android:outerRadius="@dimen/glowpadview_target_placement_radius"
android:innerRadius="@dimen/glowpadview_inner_radius"
android:snapMargin="@dimen/glowpadview_snap_margin"
android:feedbackCount="1"
android:vibrationDuration="20"
android:glowRadius="@dimen/glowpadview_glow_radius"
android:pointDrawable="@drawable/ic_lockscreen_glowdot"
/>
<!-- emergency call button shown when sim is PUKd and tab_selector is hidden -->
<Button
android:id="@+id/emergencyCallButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableLeft="@drawable/ic_emergency"
android:layout_centerInParent="true"
android:layout_alignParentBottom="true"
android:layout_marginBottom="90dip"
style="@style/Widget.Button.Transparent"
android:drawablePadding="8dip"
android:visibility="gone"
/>
</LinearLayout>
</LinearLayout>

View File

@@ -1,124 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
**
** Copyright 2009, 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.
*/
-->
<!-- This is the general lock screen which shows information about the
state of the device, as well as instructions on how to get past it
depending on the state of the device.-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tabunlock="http://schemas.android.com/apk/res/com.android.tabunlock"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:id="@+id/root">
<!-- left side: status and music -->
<RelativeLayout
android:layout_height="match_parent"
android:layout_weight="0.42"
android:layout_width="0dip"
android:gravity="center">
<RelativeLayout android:id="@+id/transport_bg_protect"
android:layout_width="512dip"
android:layout_height="wrap_content">
<!-- Status -->
<include layout="@layout/keyguard_screen_status_land"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="50dip"
android:layout_marginTop="50dip"
android:layout_marginEnd="64dip"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"/>
<!-- Music transport control -->
<include android:id="@+id/transport"
layout="@layout/keyguard_transport_control"
android:layout_row="0"
android:layout_column="0"
android:layout_rowSpan="3"
android:layout_columnSpan="1"
android:layout_gravity="fill"
android:layout_width="match_parent"
android:layout_height="512dip"
/>
</RelativeLayout>
</RelativeLayout>
<!-- right side -->
<RelativeLayout
android:layout_height="match_parent"
android:layout_weight="0.58"
android:layout_width="0dip"
android:gravity="center_horizontal|center_vertical">
<TextView
android:id="@+id/screenLocked"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:gravity="center"
android:layout_marginTop="12dip"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:drawablePadding="4dip"/>
<com.android.internal.widget.multiwaveview.GlowPadView
android:id="@+id/unlock_widget"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_rowSpan="7"
android:layout_gravity="center_vertical|end"
android:gravity="center"
android:focusable="true"
android:targetDrawables="@array/lockscreen_targets_with_camera"
android:targetDescriptions="@array/lockscreen_target_descriptions_with_camera"
android:directionDescriptions="@array/lockscreen_direction_descriptions"
android:handleDrawable="@drawable/ic_lockscreen_handle"
android:outerRingDrawable="@drawable/ic_lockscreen_outerring"
android:outerRadius="@dimen/glowpadview_target_placement_radius"
android:innerRadius="@dimen/glowpadview_inner_radius"
android:snapMargin="@dimen/glowpadview_snap_margin"
android:feedbackCount="1"
android:vibrationDuration="20"
android:glowRadius="@dimen/glowpadview_glow_radius"
android:pointDrawable="@drawable/ic_lockscreen_glowdot"
/>
<!-- emergency call button shown when sim is PUKd and tab_selector is hidden -->
<Button
android:id="@+id/emergencyCallButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="80dip"
android:layout_marginBottom="80dip"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true"
android:drawableLeft="@drawable/ic_emergency"
style="@style/Widget.Button.Transparent"
android:drawablePadding="8dip"
android:visibility="gone"/>
</RelativeLayout>
</LinearLayout>

View File

@@ -1,157 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
**
** Copyright 2008, 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.
*/
-->
<!-- This is the screen that shows the 9 circle unlock widget and instructs
the user how to unlock their device, or make an emergency call. This
is the portrait layout. -->
<com.android.internal.widget.LinearLayoutWithDefaultTouchRecepient
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- left side: status and music -->
<RelativeLayout
android:layout_height="match_parent"
android:layout_weight="1"
android:layout_width="0dip"
android:gravity="center">
<RelativeLayout android:id="@+id/transport_bg_protect"
android:layout_width="512dip"
android:layout_height="wrap_content"
android:layout_marginBottom="24dip">
<!-- Status -->
<include layout="@layout/keyguard_screen_status_land"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="50dip"
android:layout_marginTop="50dip"
android:layout_marginBottom="50dip"
android:layout_marginEnd="64dip"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"/>
<!-- Music transport control -->
<include android:id="@+id/transport"
layout="@layout/keyguard_transport_control"
android:layout_row="0"
android:layout_column="0"
android:layout_rowSpan="3"
android:layout_columnSpan="1"
android:layout_gravity="fill"
android:layout_width="match_parent"
android:layout_height="512dip"
/>
</RelativeLayout>
</RelativeLayout>
<!-- right side: lock pattern -->
<RelativeLayout
android:layout_weight="1"
android:layout_width="0dip"
android:layout_height="match_parent"
android:gravity="center_vertical|center_horizontal">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center_vertical|center_horizontal">
<com.android.internal.widget.LockPatternView android:id="@+id/lockPattern"
android:layout_width="354dip"
android:layout_height="354dip"
android:layout_gravity="center_vertical"
/>
<!-- Emergency and forgot pattern buttons. -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_below="@id/lockPattern"
android:layout_alignStart="@id/lockPattern"
android:layout_alignEnd="@id/lockPattern"
android:layout_marginTop="28dip"
style="?android:attr/buttonBarStyle"
android:gravity="center"
android:weightSum="2">
<Button android:id="@+id/forgotPatternButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
style="?android:attr/buttonBarButtonStyle"
android:drawableLeft="@drawable/lockscreen_forgot_password_button"
android:drawablePadding="8dip"
android:text="@string/lockscreen_forgot_pattern_button_text"
android:visibility="gone"
/>
<Button android:id="@+id/emergencyCallButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
style="?android:attr/buttonBarButtonStyle"
android:drawableLeft="@drawable/ic_emergency"
android:drawablePadding="8dip"
android:text="@string/lockscreen_emergency_call"
android:visibility="gone"
/>
</LinearLayout>
</RelativeLayout>
<!-- Area to overlay FaceLock -->
<RelativeLayout
android:id="@+id/face_unlock_area_view"
android:visibility="invisible"
android:layout_width="530dip"
android:layout_height="530dip"
android:layout_centerInParent="true"
android:background="@drawable/intro_bg">
<View
android:id="@+id/spotlightMask"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/facelock_spotlight_mask"
/>
<ImageView
android:id="@+id/cancel_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dip"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:src="@drawable/ic_facial_backup"
/>
</RelativeLayout>
</RelativeLayout>
</com.android.internal.widget.LinearLayoutWithDefaultTouchRecepient>

View File

@@ -1,150 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
**
** Copyright 2008, 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.
*/
-->
<com.android.internal.widget.LinearLayoutWithDefaultTouchRecepient
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- top: status -->
<RelativeLayout
android:layout_height="0dip"
android:layout_weight="0.40"
android:layout_width="match_parent"
android:gravity="center">
<RelativeLayout android:id="@+id/transport_bg_protect"
android:layout_width="512dip"
android:layout_height="wrap_content"
android:gravity="center">
<!-- Status -->
<include layout="@layout/keyguard_screen_status_land"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="50dip"
android:layout_marginTop="50dip"
android:layout_marginEnd="64dip"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"/>
<!-- Music transport control -->
<include android:id="@+id/transport"
layout="@layout/keyguard_transport_control"
android:layout_row="0"
android:layout_column="0"
android:layout_rowSpan="3"
android:layout_columnSpan="1"
android:layout_gravity="fill"
android:layout_width="match_parent"
android:layout_height="512dip"
/>
</RelativeLayout>
</RelativeLayout>
<!-- bottom: lock pattern, emergency dialer and forgot pattern button -->
<RelativeLayout
android:layout_weight="0.60"
android:layout_width="match_parent"
android:layout_height="0dip"
android:gravity="center">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center">
<com.android.internal.widget.LockPatternView android:id="@+id/lockPattern"
android:layout_width="354dip"
android:layout_height="354dip"
/>
<!-- Emergency and forgot pattern buttons. -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_below="@id/lockPattern"
android:layout_alignStart="@id/lockPattern"
android:layout_alignEnd="@id/lockPattern"
style="?android:attr/buttonBarStyle"
android:gravity="center"
android:weightSum="2">
<Button android:id="@+id/forgotPatternButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
style="?android:attr/buttonBarButtonStyle"
android:drawableLeft="@drawable/lockscreen_forgot_password_button"
android:drawablePadding="8dip"
android:text="@string/lockscreen_forgot_pattern_button_text"
android:visibility="gone"
/>
<Button android:id="@+id/emergencyCallButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
style="?android:attr/buttonBarButtonStyle"
android:drawableLeft="@drawable/ic_emergency"
android:drawablePadding="8dip"
android:text="@string/lockscreen_emergency_call"
android:visibility="gone"
/>
</LinearLayout>
</RelativeLayout>
<!-- Area to overlay FaceLock -->
<RelativeLayout
android:id="@+id/face_unlock_area_view"
android:visibility="invisible"
android:layout_width="440dip"
android:layout_height="440dip"
android:layout_centerInParent="true"
android:background="@drawable/intro_bg">
<View
android:id="@+id/spotlightMask"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/facelock_spotlight_mask"
/>
<ImageView
android:id="@+id/cancel_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dip"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:src="@drawable/ic_facial_backup"
/>
</RelativeLayout>
</RelativeLayout>
</com.android.internal.widget.LinearLayoutWithDefaultTouchRecepient>

View File

@@ -1,126 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
**
** Copyright 2008, 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.
*/
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@android:color/background_dark"
>
<ScrollView
android:layout_width="match_parent"
android:layout_height="0px"
android:layout_weight="1"
android:layout_above="@+id/emergencyCallButton">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<TextView
android:id="@+id/topHeader"
android:layout_width="match_parent"
android:layout_height="64dip"
android:layout_alignParentTop="true"
android:layout_marginStart="4dip"
android:textAppearance="?android:attr/textAppearanceMedium"
android:gravity="center_vertical"
android:drawableLeft="@drawable/ic_lock_idle_lock"
android:drawablePadding="5dip"
/>
<!-- spacer below header -->
<View
android:id="@+id/spacerTop"
android:layout_width="match_parent"
android:layout_height="1dip"
android:layout_below="@id/topHeader"
android:background="@drawable/divider_horizontal_dark"/>
<TextView
android:id="@+id/instructions"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/spacerTop"
android:layout_marginTop="8dip"
android:layout_marginStart="9dip"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="@android:string/lockscreen_glogin_instructions"
/>
<EditText
android:id="@+id/login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/instructions"
android:layout_marginTop="8dip"
android:layout_marginStart="7dip"
android:layout_marginEnd="7dip"
android:hint="@android:string/lockscreen_glogin_username_hint"
android:inputType="textEmailAddress"
/>
<EditText
android:id="@+id/password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/login"
android:layout_marginTop="15dip"
android:layout_marginStart="7dip"
android:layout_marginEnd="7dip"
android:inputType="textPassword"
android:hint="@android:string/lockscreen_glogin_password_hint"
android:nextFocusRight="@+id/ok"
android:nextFocusDown="@+id/ok"
/>
<!-- ok below password, aligned to right of screen -->
<Button
android:id="@+id/ok"
android:layout_width="85dip"
android:layout_height="wrap_content"
android:layout_below="@id/password"
android:layout_marginTop="7dip"
android:layout_marginEnd="7dip"
android:layout_alignParentEnd="true"
android:text="@android:string/lockscreen_glogin_submit_button"
/>
</RelativeLayout>
</ScrollView>
<!-- spacer above emergency call -->
<View
android:layout_width="match_parent"
android:layout_height="1dip"
android:layout_marginBottom="4dip"
android:background="@drawable/divider_horizontal_dark"/>
<!-- emergency call button at bottom center -->
<Button
android:id="@+id/emergencyCallButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:drawableLeft="@drawable/ic_emergency"
android:drawablePadding="4dip"
android:text="@android:string/lockscreen_emergency_call"
/>
</LinearLayout>

View File

@@ -1,219 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
**
** Copyright 2008, 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.
*/
-->
<!-- This is the general lock screen which shows information about the
state of the device, as well as instructions on how to get past it
depending on the state of the device. It is the same for landscape
and portrait.-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:gravity="bottom"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginBottom="15dip"
android:layout_marginStart="15dip"
android:layout_marginEnd="15dip"
android:paddingTop="20dip"
android:paddingBottom="20dip"
android:background="@android:drawable/popup_full_dark"
>
<!-- when sim is present -->
<TextView android:id="@+id/headerSimOk1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textSize="34sp"/>
<TextView android:id="@+id/headerSimOk2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textSize="34sp"/>
<!-- when sim is missing / locked -->
<TextView android:id="@+id/headerSimBad1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@android:string/lockscreen_missing_sim_message"
android:textAppearance="?android:attr/textAppearanceLarge"/>
<TextView android:id="@+id/headerSimBad2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="7dip"
android:layout_marginBottom="7dip"
android:gravity="center"
android:text="@android:string/lockscreen_missing_sim_instructions"
android:textAppearance="?android:attr/textAppearanceSmall"/>
<!-- spacer after carrier info / sim messages -->
<View
android:layout_width="match_parent"
android:layout_height="1dip"
android:layout_marginTop="8dip"
android:background="@android:drawable/divider_horizontal_dark"/>
<!-- time and date -->
<TextView android:id="@+id/time"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textSize="34sp"/>
<TextView android:id="@+id/date"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textSize="18sp"/>
<!-- spacer after time and date -->
<View
android:layout_width="match_parent"
android:layout_height="1dip"
android:layout_marginBottom="8dip"
android:background="@android:drawable/divider_horizontal_dark"
/>
<!-- battery info -->
<LinearLayout android:id="@+id/batteryInfo"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
>
<ImageView android:id="@+id/batteryInfoIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="6dip"
android:baselineAligned="true"
android:gravity="center"
/>
<TextView android:id="@+id/batteryInfoText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:gravity="center"
/>
</LinearLayout>
<!-- spacer after battery info -->
<View android:id="@+id/batteryInfoSpacer"
android:layout_width="match_parent"
android:layout_height="1dip"
android:layout_marginTop="8dip"
android:layout_marginBottom="8dip"
android:background="@android:drawable/divider_horizontal_dark"
/>
<!-- next alarm info -->
<LinearLayout android:id="@+id/nextAlarmInfo"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="6dip"
android:baselineAligned="true"
android:src="@android:drawable/ic_lock_idle_alarm"
android:gravity="center"
/>
<TextView android:id="@+id/nextAlarmText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:gravity="center"
/>
</LinearLayout>
<!-- spacer after alarm info -->
<View android:id="@+id/nextAlarmSpacer"
android:layout_width="match_parent"
android:layout_height="1dip"
android:layout_marginTop="8dip"
android:layout_marginBottom="8dip"
android:background="@android:drawable/divider_horizontal_dark"/>
<!-- lock icon with 'screen locked' message
(shown when SIM card is present) -->
<LinearLayout android:id="@+id/screenLockedInfo"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="6dip"
android:baselineAligned="true"
android:src="@android:drawable/ic_lock_idle_lock"
android:gravity="center"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:text="@android:string/lockscreen_screen_locked"
android:gravity="center"
/>
</LinearLayout>
<!-- message about how to unlock
(shown when SIM card is present) -->
<TextView android:id="@+id/lockInstructions"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="5dip"
android:gravity="center"
android:textSize="14sp"/>
<!-- emergency call button shown when sim is missing or PUKd -->
<Button
android:id="@+id/emergencyCallButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="5dip"
android:layout_marginTop="5dip"
android:layout_gravity="center_horizontal"
android:drawableLeft="@drawable/ic_emergency"
android:drawablePadding="4dip"
android:text="@android:string/lockscreen_emergency_call"
/>
</LinearLayout>
</LinearLayout>

View File

@@ -1,241 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
**
** Copyright 2009, 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.
*/
-->
<!-- This is the general lock screen which shows information about the
state of the device, as well as instructions on how to get past it
depending on the state of the device.-->
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:rowCount="8"
android:id="@+id/root"
android:clipChildren="false"
android:rowOrderPreserved="false">
<!-- Column 0 -->
<com.android.internal.widget.DigitalClock android:id="@+id/time"
android:layout_marginTop="8dip"
android:layout_marginBottom="8dip"
android:layout_gravity="end"
android:layout_rowSpan="2">
<!-- Because we can't have multi-tone fonts, we render two TextViews, one on
top of the other. Hence the redundant layout... -->
<TextView android:id="@+id/timeDisplayBackground"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:ellipsize="none"
android:textSize="@dimen/keyguard_lockscreen_clock_font_size"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_marginBottom="6dip"
android:textColor="@color/lockscreen_clock_background"
/>
<TextView android:id="@+id/timeDisplayForeground"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:ellipsize="none"
android:textSize="@dimen/keyguard_lockscreen_clock_font_size"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_marginBottom="6dip"
android:textColor="@color/lockscreen_clock_foreground"
android:layout_alignStart="@id/timeDisplayBackground"
android:layout_alignTop="@id/timeDisplayBackground"
/>
</com.android.internal.widget.DigitalClock>
<TextView
android:id="@+id/date"
android:layout_width="0dip"
android:layout_gravity="fill_horizontal"
android:gravity="end"
android:layout_below="@id/time"
android:layout_marginTop="6dip"
android:singleLine="true"
android:ellipsize="marquee"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="@dimen/keyguard_lockscreen_status_line_font_size"
/>
<TextView
android:id="@+id/alarm_status"
android:singleLine="true"
android:ellipsize="marquee"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="@dimen/keyguard_lockscreen_status_line_font_size"
android:drawablePadding="4dip"
android:layout_marginTop="4dip"
android:layout_gravity="end"
/>
<TextView
android:id="@+id/status1"
android:layout_width="0dip"
android:layout_gravity="fill_horizontal"
android:gravity="end"
android:layout_marginTop="4dip"
android:singleLine="true"
android:ellipsize="marquee"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="@dimen/keyguard_lockscreen_status_line_font_size"
android:drawablePadding="4dip"
/>
<Space android:layout_gravity="fill" />
<TextView
android:id="@+id/carrier"
android:layout_width="0dip"
android:layout_gravity="fill_horizontal"
android:gravity="end"
android:singleLine="true"
android:ellipsize="marquee"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="@dimen/keyguard_lockscreen_status_line_font_size"
android:textColor="?android:attr/textColorSecondary"
/>
<Button
android:id="@+id/emergencyCallButton"
android:layout_gravity="end"
android:drawableLeft="@drawable/lockscreen_emergency_button"
android:text="@string/lockscreen_emergency_call"
style="?android:attr/buttonBarButtonStyle"
android:drawablePadding="8dip"
android:visibility="visible"
/>
<!-- Column 1 -->
<Space
android:layout_width="16dip"
android:layout_rowSpan="8"
android:layout_gravity="fill_vertical" />
<!-- Column 2 - password entry field and PIN keyboard -->
<LinearLayout
android:orientation="horizontal"
android:layout_width="270dip"
android:layout_gravity="center_vertical"
android:background="@drawable/lockscreen_password_field_dark">
<EditText android:id="@+id/passwordEntry"
android:layout_height="wrap_content"
android:layout_width="0dip"
android:layout_weight="1"
android:gravity="center"
android:layout_gravity="center_vertical"
android:singleLine="true"
android:textStyle="normal"
android:inputType="textPassword"
android:textSize="24sp"
android:minEms="8"
android:textAppearance="?android:attr/textAppearanceMedium"
android:background="@null"
android:textColor="?android:attr/textColorPrimary"
android:imeOptions="flagForceAscii|flagNoFullscreen|actionDone"
/>
<!-- This delete button is only visible for numeric PIN entry -->
<ImageButton android:id="@+id/pinDel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@android:drawable/ic_input_delete"
android:clickable="true"
android:padding="8dip"
android:layout_gravity="center"
android:background="?android:attr/selectableItemBackground"
android:visibility="gone"
/>
<ImageView android:id="@+id/switch_ime_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_lockscreen_ime"
android:clickable="true"
android:padding="8dip"
android:layout_gravity="center"
android:background="?android:attr/selectableItemBackground"
android:visibility="gone"
/>
</LinearLayout>
<!-- Numeric keyboard -->
<com.android.internal.widget.PasswordEntryKeyboardView android:id="@+id/keyboard"
android:layout_width="270dip"
android:layout_height="wrap_content"
android:layout_marginStart="4dip"
android:layout_marginEnd="4dip"
android:background="#40000000"
android:layout_marginTop="5dip"
android:keyBackground="@*android:drawable/btn_keyboard_key_ics"
android:visibility="gone"
android:layout_rowSpan="7"
android:clickable="true"
/>
<!-- Music transport control -->
<include android:id="@+id/transport"
layout="@layout/keyguard_transport_control"
android:layout_row="0"
android:layout_column="0"
android:layout_rowSpan="6"
android:layout_columnSpan="1"
android:layout_gravity="fill"
android:layout_width="0dip"
android:layout_height="0dip"
/>
<!-- Area to overlay FaceLock -->
<RelativeLayout
android:id="@+id/face_unlock_area_view"
android:visibility="invisible"
android:layout_row="0"
android:layout_column="2"
android:layout_rowSpan="8"
android:layout_columnSpan="1"
android:layout_gravity="fill"
android:layout_width="0dip"
android:layout_height="0dip"
android:background="@drawable/intro_bg">
<View
android:id="@+id/spotlightMask"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/facelock_spotlight_mask"
/>
<ImageView
android:id="@+id/cancel_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dip"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:src="@drawable/ic_facial_backup"
/>
</RelativeLayout>
</GridLayout>

View File

@@ -1,231 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
**
** Copyright 2008, 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.
*/
-->
<GridLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal">
<com.android.internal.widget.DigitalClock android:id="@+id/time"
android:layout_marginBottom="18dip"
android:layout_marginEnd="@dimen/keyguard_lockscreen_status_line_font_right_margin"
android:layout_gravity="end">
<!-- Because we can't have multi-tone fonts, we render two TextViews, one on
top of the other. Hence the redundant layout... -->
<TextView android:id="@+id/timeDisplayBackground"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:ellipsize="none"
android:textSize="@dimen/keyguard_lockscreen_clock_font_size"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_marginBottom="6dip"
android:textColor="@*android:color/lockscreen_clock_background"
/>
<TextView android:id="@+id/timeDisplayForeground"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:ellipsize="none"
android:textSize="@dimen/keyguard_lockscreen_clock_font_size"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_marginBottom="6dip"
android:textColor="@color/lockscreen_clock_foreground"
/>
</com.android.internal.widget.DigitalClock>
<LinearLayout
android:orientation="horizontal"
android:layout_gravity="end"
android:layout_marginEnd="@dimen/keyguard_lockscreen_status_line_font_right_margin">
<TextView
android:id="@+id/date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:ellipsize="marquee"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="@dimen/keyguard_lockscreen_status_line_font_size"
/>
<TextView
android:id="@+id/alarm_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dip"
android:singleLine="true"
android:ellipsize="marquee"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="@dimen/keyguard_lockscreen_status_line_font_size"
android:drawablePadding="4dip"
/>
</LinearLayout>
<TextView
android:id="@+id/status1"
android:layout_gravity="end"
android:layout_marginEnd="@dimen/keyguard_lockscreen_status_line_font_right_margin"
android:singleLine="true"
android:ellipsize="marquee"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="@dimen/keyguard_lockscreen_status_line_font_size"
android:drawablePadding="4dip"
android:paddingBottom="4dip"
/>
<!-- Password entry field -->
<!-- Note: the entire container is styled to look like the edit field,
since the backspace/IME switcher looks better inside -->
<LinearLayout
android:layout_gravity="center_vertical|fill_horizontal"
android:orientation="horizontal"
android:background="@drawable/lockscreen_password_field_dark"
android:layout_marginStart="16dip"
android:layout_marginEnd="16dip">
<EditText android:id="@+id/passwordEntry"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:layout_gravity="center_vertical"
android:singleLine="true"
android:textStyle="normal"
android:inputType="textPassword"
android:textSize="36sp"
android:background="@null"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#ffffffff"
android:imeOptions="flagForceAscii|actionDone"
/>
<!-- This delete button is only visible for numeric PIN entry -->
<ImageButton android:id="@+id/pinDel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@android:drawable/ic_input_delete"
android:clickable="true"
android:padding="8dip"
android:layout_gravity="center_vertical"
android:background="?android:attr/selectableItemBackground"
android:visibility="gone"
/>
<ImageView android:id="@+id/switch_ime_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_lockscreen_ime"
android:clickable="true"
android:padding="8dip"
android:layout_gravity="center"
android:background="?android:attr/selectableItemBackground"
android:visibility="gone"
/>
</LinearLayout>
<!-- Numeric keyboard -->
<com.android.internal.widget.PasswordEntryKeyboardView android:id="@+id/keyboard"
android:layout_width="match_parent"
android:layout_marginStart="4dip"
android:layout_marginEnd="4dip"
android:paddingTop="4dip"
android:paddingBottom="4dip"
android:background="#40000000"
android:keyBackground="@*android:drawable/btn_keyboard_key_ics"
android:visibility="gone"
android:clickable="true"
/>
<TextView
android:id="@+id/carrier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="@dimen/keyguard_lockscreen_status_line_font_size"
android:drawablePadding="4dip"
android:singleLine="true"
android:ellipsize="marquee"
android:paddingTop="4dip"
/>
<Button
android:id="@+id/emergencyCallButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dip"
android:layout_gravity="center_horizontal"
android:drawableLeft="@*android:drawable/lockscreen_emergency_button"
style="?android:attr/buttonBarButtonStyle"
android:drawablePadding="4dip"
android:text="@*android:string/lockscreen_emergency_call"
android:visibility="gone"
/>
<!-- Music transport control -->
<include android:id="@+id/transport"
layout="@layout/keyguard_transport_control"
android:layout_row="0"
android:layout_column="0"
android:layout_rowSpan="3"
android:layout_columnSpan="1"
android:layout_gravity="fill"
android:layout_width="0dip"
android:layout_height="0dip"
/>
<!-- Area to overlay FaceLock -->
<RelativeLayout
android:id="@+id/face_unlock_area_view"
android:visibility="invisible"
android:layout_row="3"
android:layout_column="0"
android:layout_rowSpan="2"
android:layout_columnSpan="1"
android:layout_gravity="fill"
android:layout_width="0dip"
android:layout_height="0dip"
android:background="@drawable/intro_bg">
<View
android:id="@+id/spotlightMask"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/facelock_spotlight_mask"
/>
<ImageView
android:id="@+id/cancel_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dip"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:src="@drawable/ic_facial_backup"
/>
</RelativeLayout>
</GridLayout>

View File

@@ -1,120 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
**
** Copyright 2008, 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.
*/
-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/background_dark"
>
<!-- header text ('Enter Pin Code') -->
<TextView android:id="@+id/headerText"
android:layout_above="@+id/carrier"
android:layout_centerHorizontal="true"
android:layout_marginBottom="30dip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="24sp"
/>
<!-- Carrier info -->
<TextView android:id="@+id/carrier"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_above="@+id/pinDisplayGroup"
android:layout_marginTop="9dip"
android:gravity="start|bottom"
android:singleLine="true"
android:ellipsize="marquee"
android:textAppearance="?android:attr/textAppearanceMedium"
/>
<!-- displays dots as user enters pin -->
<LinearLayout android:id="@+id/pinDisplayGroup"
android:orientation="horizontal"
android:layout_centerInParent="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:addStatesFromChildren="true"
android:gravity="center_vertical"
android:baselineAligned="false"
android:paddingEnd="0dip"
android:layout_marginEnd="30dip"
android:layout_marginStart="30dip"
android:background="@android:drawable/edit_text"
>
<EditText android:id="@+id/pinDisplay"
android:layout_width="0dip"
android:layout_weight="1"
android:layout_height="match_parent"
android:maxLines="1"
android:background="@null"
android:textSize="32sp"
android:inputType="textPassword"
/>
<ImageButton android:id="@+id/backspace"
android:src="@android:drawable/ic_input_delete"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginTop="2dip"
android:layout_marginEnd="2dip"
android:layout_marginBottom="2dip"
android:gravity="center"
/>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dip"
android:layout_marginStart="8dip"
android:layout_marginEnd="8dip">
<Button android:id="@+id/emergencyCallButton"
android:text="@android:string/lockscreen_emergency_call"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1.0"
android:layout_marginBottom="8dip"
android:layout_marginEnd="8dip"
android:textSize="18sp"
android:drawableLeft="@drawable/ic_emergency"
android:drawablePadding="4dip"
/>
<Button android:id="@+id/ok"
android:text="@android:string/ok"
android:layout_alignParentBottom="true"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1.0"
android:layout_marginBottom="8dip"
android:layout_marginStart="8dip"
android:textSize="18sp"
/>
</LinearLayout>
</RelativeLayout>

View File

@@ -1,120 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
**
** Copyright 2008, 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.
*/
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@android:color/background_dark"
android:gravity="center_horizontal">
<LinearLayout android:id="@+id/topDisplayGroup"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- header text ('Enter Pin Code') -->
<TextView android:id="@+id/headerText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceLarge"/>
<!-- Carrier info -->
<TextView android:id="@+id/carrier"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="9dip"
android:gravity="center"
android:singleLine="true"
android:ellipsize="marquee"
android:textAppearance="?android:attr/textAppearanceMedium"/>
<!-- password entry -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginEnd="6dip"
android:layout_marginStart="6dip"
android:gravity="center_vertical"
android:background="@android:drawable/edit_text">
<!-- displays dots as user enters pin -->
<EditText android:id="@+id/pinDisplay"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:maxLines="1"
android:textAppearance="?android:attr/textAppearanceLargeInverse"
android:textColor="@android:color/primary_text_holo_light"
android:textStyle="bold"
android:inputType="textPassword"
/>
<ImageButton android:id="@+id/backspace"
android:src="@android:drawable/ic_input_delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="-3dip"
android:layout_marginBottom="-3dip"
/>
</LinearLayout>
</LinearLayout>
<include
android:id="@+id/keyPad"
layout="@android:layout/twelve_key_entry"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/topDisplayGroup"
android:layout_marginTop="10dip"
/>
<!-- spacer below keypad -->
<View
android:id="@+id/spacerBottom"
android:layout_width="match_parent"
android:layout_height="1dip"
android:layout_marginTop="6dip"
android:layout_above="@id/emergencyCallButton"
android:background="@android:drawable/divider_horizontal_dark"
/>
<!-- The emergency button should take the rest of the space and be centered vertically -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical">
<!-- emergency call button -->
<Button
android:id="@+id/emergencyCallButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableLeft="@android:drawable/ic_emergency"
android:drawablePadding="4dip"
android:text="@android:string/lockscreen_emergency_call"
/>
</LinearLayout>
</LinearLayout>

View File

@@ -1,184 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
**
** Copyright 2008, 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.
*/
-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/background_dark"
>
<LinearLayout android:id="@+id/topDisplayGroup"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- header text ('Enter Puk Code') -->
<TextView android:id="@+id/headerText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceLarge"/>
<!-- Carrier info -->
<TextView android:id="@+id/carrier"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="9dip"
android:gravity="center"
android:singleLine="true"
android:ellipsize="marquee"
android:textAppearance="?android:attr/textAppearanceMedium"/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginEnd="10dip"
android:layout_marginStart="10dip">
<TextView android:id="@+id/enter_puk"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:text="@android:string/keyguard_password_enter_puk_prompt"
android:textSize="30sp"
android:layout_marginBottom="10dip"/>
<TextView android:id="@+id/enter_pin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:text="@android:string/keyguard_password_enter_pin_prompt"
android:textSize="30sp"
android:layout_marginTop="10dip"/>
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_weight="1"
android:layout_height="match_parent"
android:paddingEnd="0dip"
android:layout_marginEnd="10dip"
android:layout_marginStart="10dip">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginEnd="6dip"
android:layout_marginStart="6dip"
android:gravity="center_vertical"
android:background="@android:drawable/edit_text">
<!-- displays dots as user enters puk -->
<TextView android:id="@+id/pukDisplay"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:maxLines="1"
android:textAppearance="?android:attr/textAppearanceLargeInverse"
android:textStyle="bold"
android:inputType="textPassword"
/>
<ImageButton android:id="@+id/pukDel"
android:src="@android:drawable/ic_input_delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="-3dip"
android:layout_marginBottom="-3dip"
/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginEnd="6dip"
android:layout_marginStart="6dip"
android:gravity="center_vertical"
android:background="@android:drawable/edit_text">
<!-- displays dots as user enters new pin -->
<EditText android:id="@+id/pinDisplay"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:maxLines="1"
android:textAppearance="?android:attr/textAppearanceLargeInverse"
android:textColor="@android:color/primary_text_holo_light"
android:textStyle="bold"
android:inputType="textPassword"
android:hint="@android:string/keyguard_password_enter_pin_prompt"
/>
<ImageButton android:id="@+id/pinDel"
android:src="@android:drawable/ic_input_delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="-3dip"
android:layout_marginBottom="-3dip"
/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="8dip"
android:layout_marginStart="8dip"
android:layout_marginEnd="8dip">
<Button android:id="@+id/emergencyCallButton"
android:text="@android:string/lockscreen_emergency_call"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1.0"
android:layout_marginBottom="8dip"
android:layout_marginEnd="8dip"
android:textSize="18sp"
android:drawableLeft="@drawable/ic_emergency"
android:drawablePadding="4dip"
/>
<Button android:id="@+id/ok"
android:text="@android:string/ok"
android:layout_alignParentBottom="true"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1.0"
android:layout_marginBottom="8dip"
android:layout_marginStart="8dip"
android:textSize="18sp"
/>
</LinearLayout>
</RelativeLayout>

View File

@@ -1,170 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
**
** Copyright 2008, 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.
*/
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@android:color/background_dark"
android:gravity="center_horizontal">
<LinearLayout android:id="@+id/topDisplayGroup"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- header text ('Enter Puk Code') -->
<TextView android:id="@+id/headerText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:singleLine="true"
android:ellipsize="marquee"
android:layout_marginEnd="6dip"
android:layout_marginStart="6dip"
android:textAppearance="?android:attr/textAppearanceLarge"/>
<!-- Carrier info -->
<TextView android:id="@+id/carrier"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="9dip"
android:gravity="center"
android:singleLine="true"
android:ellipsize="marquee"
android:layout_marginEnd="6dip"
android:layout_marginStart="6dip"
android:textAppearance="?android:attr/textAppearanceMedium"/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_weight="1"
android:layout_height="match_parent"
android:paddingEnd="0dip"
android:layout_marginEnd="10dip"
android:layout_marginStart="10dip">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginEnd="6dip"
android:layout_marginStart="6dip"
android:gravity="center_vertical"
android:background="@android:drawable/edit_text">
<!-- displays dots as user enters puk -->
<EditText android:id="@+id/pukDisplay"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:maxLines="1"
android:textStyle="bold"
android:inputType="textPassword"
android:textColor="#000"
android:hint="@android:string/keyguard_password_enter_puk_prompt"
/>
<ImageButton android:id="@+id/pukDel"
android:src="@android:drawable/ic_input_delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="-3dip"
android:layout_marginBottom="-3dip"
/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginEnd="6dip"
android:layout_marginStart="6dip"
android:gravity="center_vertical"
android:background="@android:drawable/edit_text">
<!-- displays dots as user enters new pin -->
<EditText android:id="@+id/pinDisplay"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:maxLines="1"
android:textStyle="bold"
android:inputType="textPassword"
android:textColor="#000"
android:hint="@android:string/keyguard_password_enter_pin_prompt"
/>
<ImageButton android:id="@+id/pinDel"
android:src="@android:drawable/ic_input_delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="-3dip"
android:layout_marginBottom="-3dip"
/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>
<include
android:id="@+id/keyPad"
layout="@android:layout/twelve_key_entry"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/topDisplayGroup"
android:layout_marginTop="10dip"
/>
<!-- spacer below keypad -->
<View
android:id="@+id/spacerBottom"
android:layout_width="match_parent"
android:layout_height="1dip"
android:layout_marginTop="6dip"
android:layout_above="@id/emergencyCallButton"
android:background="@android:drawable/divider_horizontal_dark"
/>
<!-- The emergency button should take the rest of the space and be centered vertically -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical">
<!-- emergency call button -->
<Button
android:id="@+id/emergencyCallButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableLeft="@android:drawable/ic_emergency"
android:drawablePadding="4dip"
android:text="@android:string/lockscreen_emergency_call"
/>
</LinearLayout>
</LinearLayout>

View File

@@ -1,200 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
**
** Copyright 2009, 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.
*/
-->
<!-- This is the general lock screen which shows information about the
state of the device, as well as instructions on how to get past it
depending on the state of the device. It is the same for landscape
and portrait.-->
<GridLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal">
<com.android.internal.widget.DigitalClock android:id="@+id/time"
android:layout_marginTop="@dimen/keyguard_lockscreen_status_line_clockfont_top_margin"
android:layout_marginBottom="12dip"
android:layout_marginEnd="@dimen/keyguard_lockscreen_status_line_font_right_margin"
android:layout_gravity="end">
<!-- Because we can't have multi-tone fonts, we render two TextViews, one on
top of the other. Hence the redundant layout... -->
<TextView android:id="@+id/timeDisplayBackground"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:ellipsize="none"
android:textSize="@dimen/keyguard_lockscreen_clock_font_size"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_marginBottom="6dip"
android:textColor="@color/lockscreen_clock_background"
/>
<TextView android:id="@+id/timeDisplayForeground"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:ellipsize="none"
android:textSize="@dimen/keyguard_lockscreen_clock_font_size"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_marginBottom="6dip"
android:textColor="@color/lockscreen_clock_foreground"
android:layout_alignStart="@id/timeDisplayBackground"
android:layout_alignTop="@id/timeDisplayBackground"
/>
</com.android.internal.widget.DigitalClock>
<LinearLayout
android:orientation="horizontal"
android:layout_gravity="end"
android:layout_marginEnd="@dimen/keyguard_lockscreen_status_line_font_right_margin">
<TextView
android:id="@+id/date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:ellipsize="marquee"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="@dimen/keyguard_lockscreen_status_line_font_size"
/>
<TextView
android:id="@+id/alarm_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dip"
android:singleLine="true"
android:ellipsize="marquee"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="@dimen/keyguard_lockscreen_status_line_font_size"
android:drawablePadding="4dip"
/>
</LinearLayout>
<TextView
android:id="@+id/status1"
android:layout_gravity="end"
android:layout_marginEnd="@dimen/keyguard_lockscreen_status_line_font_right_margin"
android:singleLine="true"
android:ellipsize="marquee"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="@dimen/keyguard_lockscreen_status_line_font_size"
android:drawablePadding="4dip"
/>
<Space android:layout_gravity="fill" />
<!-- emergency call button shown when sim is PUKd and tab_selector is hidden -->
<Button
android:id="@+id/emergencyCallButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dip"
android:layout_marginEnd="16dip"
android:layout_gravity="end"
android:drawableLeft="@*android:drawable/lockscreen_emergency_button"
style="?android:attr/buttonBarButtonStyle"
android:drawablePadding="4dip"
android:text="@*android:string/lockscreen_emergency_call"
android:visibility="gone"
/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="302dip">
<com.android.internal.widget.multiwaveview.GlowPadView
android:id="@+id/unlock_widget"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentBottom="true"
android:gravity="top"
android:focusable="true"
android:targetDrawables="@array/lockscreen_targets_with_camera"
android:targetDescriptions="@array/lockscreen_target_descriptions_with_camera"
android:directionDescriptions="@array/lockscreen_direction_descriptions"
android:handleDrawable="@drawable/ic_lockscreen_handle"
android:outerRingDrawable="@drawable/ic_lockscreen_outerring"
android:outerRadius="@dimen/glowpadview_target_placement_radius"
android:innerRadius="@dimen/glowpadview_inner_radius"
android:snapMargin="@dimen/glowpadview_snap_margin"
android:feedbackCount="1"
android:vibrationDuration="20"
android:glowRadius="@dimen/glowpadview_glow_radius"
android:pointDrawable="@drawable/ic_lockscreen_glowdot"
/>
<TextView
android:id="@+id/carrier"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="12dip"
android:gravity="center_horizontal"
android:singleLine="true"
android:ellipsize="marquee"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="@dimen/keyguard_lockscreen_status_line_font_size"
android:textColor="?android:attr/textColorSecondary"
/>
</RelativeLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
style="?android:attr/buttonBarStyle"
android:gravity="center"
android:weightSum="2">
<Button android:id="@+id/emergencyCallButton"
android:layout_gravity="center_horizontal"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
style="?android:attr/buttonBarButtonStyle"
android:textSize="@dimen/keyguard_lockscreen_status_line_font_size"
android:text="@*android:string/lockscreen_emergency_call"
android:drawableLeft="@*android:drawable/lockscreen_emergency_button"
android:drawablePadding="0dip"
android:visibility="gone"
/>
</LinearLayout>
<!-- Music transport control -->
<include android:id="@+id/transport"
layout="@layout/keyguard_transport_control"
android:layout_row="0"
android:layout_column="0"
android:layout_rowSpan="4"
android:layout_columnSpan="1"
android:layout_gravity="fill"
android:layout_width="0dip"
android:layout_height="0dip"
/>
</GridLayout>

View File

@@ -1,166 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
**
** Copyright 2009, 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.
*/
-->
<!-- This is the general lock screen which shows information about the
state of the device, as well as instructions on how to get past it
depending on the state of the device.-->
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:rowCount="7"
android:id="@+id/root"
android:clipChildren="false">
<!-- Column 0 -->
<com.android.internal.widget.DigitalClock android:id="@+id/time"
android:layout_marginTop="80dip"
android:layout_marginBottom="8dip"
android:layout_gravity="end">
<!-- Because we can't have multi-tone fonts, we render two TextViews, one on
top of the other. Hence the redundant layout... -->
<TextView android:id="@+id/timeDisplayBackground"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:ellipsize="none"
android:textSize="@dimen/keyguard_lockscreen_clock_font_size"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_marginBottom="6dip"
android:textColor="@color/lockscreen_clock_background"
/>
<TextView android:id="@+id/timeDisplayForeground"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:ellipsize="none"
android:textSize="@dimen/keyguard_lockscreen_clock_font_size"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_marginBottom="6dip"
android:textColor="@color/lockscreen_clock_foreground"
android:layout_alignStart="@id/timeDisplayBackground"
android:layout_alignTop="@id/timeDisplayBackground"
/>
</com.android.internal.widget.DigitalClock>
<TextView
android:id="@+id/date"
android:layout_width="0dip"
android:layout_gravity="fill_horizontal"
android:gravity="end"
android:layout_marginTop="6dip"
android:singleLine="true"
android:ellipsize="marquee"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="@dimen/keyguard_lockscreen_status_line_font_size"
/>
<TextView
android:id="@+id/alarm_status"
android:singleLine="true"
android:ellipsize="marquee"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="@dimen/keyguard_lockscreen_status_line_font_size"
android:drawablePadding="4dip"
android:layout_marginTop="4dip"
android:layout_gravity="end"
/>
<TextView
android:id="@+id/status1"
android:layout_width="0dip"
android:layout_gravity="fill_horizontal"
android:gravity="end"
android:layout_marginTop="4dip"
android:singleLine="true"
android:ellipsize="marquee"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="@dimen/keyguard_lockscreen_status_line_font_size"
android:drawablePadding="4dip"
/>
<Space android:layout_gravity="fill" />
<TextView
android:id="@+id/carrier"
android:layout_width="0dip"
android:layout_gravity="fill_horizontal"
android:layout_marginBottom="12dip"
android:gravity="end"
android:singleLine="true"
android:ellipsize="marquee"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="@dimen/keyguard_lockscreen_status_line_font_size"
android:textColor="?android:attr/textColorSecondary"
/>
<Button
android:id="@+id/emergencyCallButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:drawableLeft="@*android:drawable/lockscreen_emergency_button"
android:text="@*android:string/lockscreen_emergency_call"
style="?android:attr/buttonBarButtonStyle"
android:drawablePadding="8dip"
android:visibility="gone"
/>
<!-- Column 1 -->
<Space android:layout_width="64dip" android:layout_rowSpan="7" />
<!-- Column 2 -->
<com.android.internal.widget.multiwaveview.GlowPadView
android:id="@+id/unlock_widget"
android:layout_width="302dip"
android:layout_height="match_parent"
android:layout_rowSpan="7"
android:gravity="start|center_vertical"
android:focusable="true"
android:targetDrawables="@array/lockscreen_targets_with_camera"
android:targetDescriptions="@array/lockscreen_target_descriptions_with_camera"
android:directionDescriptions="@array/lockscreen_direction_descriptions"
android:handleDrawable="@drawable/ic_lockscreen_handle"
android:outerRingDrawable="@drawable/ic_lockscreen_outerring"
android:outerRadius="@dimen/glowpadview_target_placement_radius"
android:innerRadius="@dimen/glowpadview_inner_radius"
android:snapMargin="@dimen/glowpadview_snap_margin"
android:feedbackCount="1"
android:vibrationDuration="20"
android:glowRadius="@dimen/glowpadview_glow_radius"
android:pointDrawable="@drawable/ic_lockscreen_glowdot"
/>
<!-- Music transport control -->
<include android:id="@+id/transport"
layout="@layout/keyguard_transport_control"
android:layout_row="0"
android:layout_column="0"
android:layout_rowSpan="5"
android:layout_columnSpan="1"
android:layout_gravity="fill"
android:layout_width="0dip"
android:layout_height="0dip"
/>
</GridLayout>

View File

@@ -1,196 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
**
** Copyright 2008, 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.
*/
-->
<!-- This is the screen that shows the 9 circle unlock widget and instructs
the user how to unlock their device, or make an emergency call. This
is the portrait layout. -->
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/root"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:rowCount="7">
<!-- Column 0: Time, date and status -->
<com.android.internal.widget.DigitalClock android:id="@+id/time"
android:layout_marginTop="8dip"
android:layout_marginBottom="12dip"
android:layout_gravity="end">
<!-- Because we can't have multi-tone fonts, we render two TextViews, one on
top of the other. Hence the redundant layout... -->
<TextView android:id="@+id/timeDisplayBackground"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:ellipsize="none"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="@dimen/keyguard_lockscreen_clock_font_size"
android:layout_marginBottom="6dip"
android:textColor="@color/lockscreen_clock_background"
/>
<TextView android:id="@+id/timeDisplayForeground"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:ellipsize="none"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="@dimen/keyguard_lockscreen_clock_font_size"
android:layout_marginBottom="6dip"
android:layout_alignStart="@id/timeDisplayBackground"
android:layout_alignTop="@id/timeDisplayBackground"
android:textColor="@color/lockscreen_clock_foreground"
/>
</com.android.internal.widget.DigitalClock>
<TextView
android:id="@+id/date"
android:layout_width="0dip"
android:layout_gravity="fill_horizontal"
android:gravity="end"
android:singleLine="true"
android:ellipsize="marquee"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="@dimen/keyguard_lockscreen_status_line_font_size"
/>
<TextView
android:id="@+id/alarm_status"
android:singleLine="true"
android:ellipsize="marquee"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="@dimen/keyguard_lockscreen_status_line_font_size"
android:layout_gravity="end"
android:drawablePadding="4dip"
/>
<TextView
android:id="@+id/status1"
android:layout_width="0dip"
android:layout_gravity="fill_horizontal"
android:gravity="end"
android:singleLine="true"
android:ellipsize="marquee"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="@dimen/keyguard_lockscreen_status_line_font_size"
/>
<Space android:layout_gravity="fill" />
<TextView android:id="@+id/carrier"
android:layout_width="0dip"
android:layout_gravity="fill_horizontal"
android:gravity="end"
android:singleLine="true"
android:ellipsize="marquee"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="@dimen/keyguard_lockscreen_status_line_font_size"
/>
<LinearLayout
style="?android:attr/buttonBarStyle"
android:orientation="vertical"
android:layout_gravity="end">
<Button android:id="@+id/emergencyCallButton"
style="?android:attr/buttonBarButtonStyle"
android:layout_gravity="end"
android:layout_width="wrap_content"
android:layout_height="0dip"
android:layout_weight="1"
android:textSize="@dimen/keyguard_lockscreen_status_line_font_size"
android:text="@string/lockscreen_emergency_call"
android:drawableLeft="@drawable/lockscreen_emergency_button"
android:drawablePadding="0dip"
/>
<Button android:id="@+id/forgotPatternButton"
style="?android:attr/buttonBarButtonStyle"
android:layout_gravity="end"
android:layout_width="wrap_content"
android:layout_height="0dip"
android:layout_weight="1"
android:textSize="@dimen/keyguard_lockscreen_status_line_font_size"
android:text="@string/lockscreen_forgot_pattern_button_text"
android:drawableLeft="@drawable/lockscreen_forgot_password_button"
android:drawablePadding="0dip"
/>
</LinearLayout>
<!-- Column 1: lock pattern -->
<com.android.internal.widget.LockPatternView android:id="@+id/lockPattern"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="8dip"
android:layout_marginEnd="8dip"
android:layout_marginBottom="8dip"
android:layout_marginStart="8dip"
android:layout_rowSpan="7"/>
<!-- Music transport control -->
<include android:id="@+id/transport"
layout="@layout/keyguard_transport_control"
android:layout_row="0"
android:layout_column="0"
android:layout_rowSpan="5"
android:layout_columnSpan="1"
android:layout_gravity="fill"
android:layout_width="0dip"
android:layout_height="0dip"
/>
<!-- Area to overlay FaceLock -->
<RelativeLayout
android:id="@+id/face_unlock_area_view"
android:visibility="invisible"
android:layout_row="0"
android:layout_column="1"
android:layout_rowSpan="7"
android:layout_columnSpan="1"
android:layout_gravity="fill"
android:layout_marginStart="8dip"
android:layout_width="0dip"
android:layout_height="0dip"
android:background="@drawable/intro_bg">
<View
android:id="@+id/spotlightMask"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/facelock_spotlight_mask"
/>
<ImageView
android:id="@+id/cancel_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dip"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:src="@drawable/ic_facial_backup"
/>
</RelativeLayout>
</GridLayout>

View File

@@ -1,205 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
**
** Copyright 2008, 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.
*/
-->
<!-- This is the screen that shows the 9 circle unlock widget and instructs
the user how to unlock their device, or make an emergency call. This
is the portrait layout. -->
<GridLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal">
<com.android.internal.widget.DigitalClock android:id="@+id/time"
android:layout_marginTop="@dimen/keyguard_lockscreen_status_line_clockfont_top_margin"
android:layout_marginBottom="@dimen/keyguard_lockscreen_status_line_clockfont_bottom_margin"
android:layout_marginEnd="@dimen/keyguard_lockscreen_status_line_font_right_margin"
android:layout_gravity="end">
<!-- Because we can't have multi-tone fonts, we render two TextViews, one on
top of the other. Hence the redundant layout... -->
<TextView android:id="@+id/timeDisplayBackground"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:ellipsize="none"
android:textSize="@dimen/keyguard_lockscreen_clock_font_size"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="@color/lockscreen_clock_background"
/>
<TextView android:id="@+id/timeDisplayForeground"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:ellipsize="none"
android:textSize="@dimen/keyguard_lockscreen_clock_font_size"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="@color/lockscreen_clock_foreground"
/>
</com.android.internal.widget.DigitalClock>
<LinearLayout
android:orientation="horizontal"
android:layout_gravity="end"
android:layout_marginEnd="@dimen/keyguard_lockscreen_status_line_font_right_margin">
<TextView
android:id="@+id/date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:ellipsize="marquee"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="@dimen/keyguard_lockscreen_status_line_font_size"
/>
<TextView
android:id="@+id/alarm_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dip"
android:singleLine="true"
android:ellipsize="marquee"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="@dimen/keyguard_lockscreen_status_line_font_size"
android:drawablePadding="4dip"
/>
</LinearLayout>
<TextView
android:id="@+id/status1"
android:layout_gravity="end"
android:layout_marginEnd="@dimen/keyguard_lockscreen_status_line_font_right_margin"
android:singleLine="true"
android:ellipsize="marquee"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="@dimen/keyguard_lockscreen_status_line_font_size"
android:drawablePadding="4dip"
/>
<Space android:layout_gravity="fill" />
<!-- We need MATCH_PARENT here only to force the size of the parent to be passed to
the pattern view for it to compute its size. This is an unusual case, caused by
LockPatternView's requirement to maintain a square aspect ratio based on the width
of the screen. -->
<com.android.internal.widget.LockPatternView
android:id="@+id/lockPattern"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginEnd="8dip"
android:layout_marginBottom="4dip"
android:layout_marginStart="8dip"
android:layout_gravity="center_horizontal"
/>
<TextView
android:id="@+id/carrier"
android:layout_gravity="center_horizontal"
android:singleLine="true"
android:ellipsize="marquee"
android:textSize="@dimen/keyguard_lockscreen_status_line_font_size"
android:textAppearance="?android:attr/textAppearanceMedium"
/>
<!-- Footer: an emergency call button and an initially hidden "Forgot pattern" button -->
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
style="?android:attr/buttonBarStyle"
android:gravity="center"
android:weightSum="2">
<Button android:id="@+id/emergencyCallButton"
android:layout_gravity="center_horizontal"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
style="?android:attr/buttonBarButtonStyle"
android:textSize="@dimen/keyguard_lockscreen_status_line_font_size"
android:text="@string/lockscreen_emergency_call"
android:drawableLeft="@drawable/lockscreen_emergency_button"
android:drawablePadding="0dip"
/>
<Button android:id="@+id/forgotPatternButton"
android:layout_gravity="center_horizontal"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
style="?android:attr/buttonBarButtonStyle"
android:textSize="@dimen/keyguard_lockscreen_status_line_font_size"
android:text="@string/lockscreen_forgot_pattern_button_text"
android:drawableLeft="@drawable/lockscreen_forgot_password_button"
android:drawablePadding="0dip"
/>
</LinearLayout>
<!-- Music transport control -->
<include android:id="@+id/transport"
layout="@layout/keyguard_transport_control"
android:layout_row="0"
android:layout_column="0"
android:layout_rowSpan="4"
android:layout_columnSpan="1"
android:layout_gravity="fill"
android:layout_width="0dip"
android:layout_height="0dip"
/>
<!-- Area to overlay FaceLock -->
<RelativeLayout
android:id="@+id/face_unlock_area_view"
android:visibility="invisible"
android:layout_row="4"
android:layout_column="0"
android:layout_rowSpan="1"
android:layout_columnSpan="1"
android:layout_gravity="fill"
android:layout_marginBottom="4dip"
android:layout_width="0dip"
android:layout_height="0dip"
android:background="@drawable/intro_bg">
<View
android:id="@+id/spotlightMask"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/facelock_spotlight_mask"
/>
<ImageView
android:id="@+id/cancel_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dip"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:src="@drawable/ic_facial_backup"
/>
</RelativeLayout>
</GridLayout>

View File

@@ -172,8 +172,6 @@
<java-symbol type="id" name="text" />
<java-symbol type="id" name="time" />
<java-symbol type="id" name="time_current" />
<java-symbol type="id" name="timeDisplayBackground" />
<java-symbol type="id" name="timeDisplayForeground" />
<java-symbol type="id" name="titleDivider" />
<java-symbol type="id" name="titleDividerTop" />
<java-symbol type="id" name="timePicker" />
@@ -1272,27 +1270,20 @@
<java-symbol type="drawable" name="kg_widget_bg_padded" />
<java-symbol type="id" name="action_mode_bar_stub" />
<java-symbol type="id" name="alarm_status" />
<java-symbol type="id" name="backspace" />
<java-symbol type="id" name="button0" />
<java-symbol type="id" name="button4" />
<java-symbol type="id" name="button5" />
<java-symbol type="id" name="button6" />
<java-symbol type="id" name="button7" />
<java-symbol type="id" name="carrier" />
<java-symbol type="id" name="date" />
<java-symbol type="id" name="eight" />
<java-symbol type="id" name="emergencyCallButton" />
<java-symbol type="id" name="face_unlock_area_view" />
<java-symbol type="id" name="face_unlock_cancel_button" />
<java-symbol type="id" name="five" />
<java-symbol type="id" name="forgotPatternButton" />
<java-symbol type="id" name="four" />
<java-symbol type="id" name="headerText" />
<java-symbol type="id" name="icon_menu_presenter" />
<java-symbol type="id" name="instructions" />
<java-symbol type="id" name="keyboard" />
<java-symbol type="id" name="list_menu_presenter" />
<java-symbol type="id" name="lockPattern" />
<java-symbol type="id" name="lock_screen" />
<java-symbol type="id" name="login" />
<java-symbol type="id" name="nine" />
@@ -1305,24 +1296,14 @@
<java-symbol type="id" name="password" />
<java-symbol type="id" name="passwordEntry" />
<java-symbol type="id" name="pinEntry" />
<java-symbol type="id" name="pinDel" />
<java-symbol type="id" name="pinDisplay" />
<java-symbol type="id" name="owner_info" />
<java-symbol type="id" name="pukDel" />
<java-symbol type="id" name="pukDisplay" />
<java-symbol type="id" name="right_icon" />
<java-symbol type="id" name="seven" />
<java-symbol type="id" name="six" />
<java-symbol type="id" name="status" />
<java-symbol type="id" name="status1" />
<java-symbol type="id" name="switch_ime_button" />
<java-symbol type="id" name="three" />
<java-symbol type="id" name="title_container" />
<java-symbol type="id" name="topHeader" />
<java-symbol type="id" name="transport" />
<java-symbol type="id" name="transport_bg_protect" />
<java-symbol type="id" name="two" />
<java-symbol type="id" name="unlock_widget" />
<java-symbol type="id" name="zero" />
<java-symbol type="id" name="keyguard_message_area" />
<java-symbol type="id" name="keyguard_click_area" />
@@ -1374,17 +1355,6 @@
<java-symbol type="integer" name="kg_carousel_angle" />
<java-symbol type="layout" name="global_actions_item" />
<java-symbol type="layout" name="global_actions_silent_mode" />
<java-symbol type="layout" name="keyguard_screen_glogin_unlock" />
<java-symbol type="layout" name="keyguard_screen_password_landscape" />
<java-symbol type="layout" name="keyguard_screen_password_portrait" />
<java-symbol type="layout" name="keyguard_screen_sim_pin_landscape" />
<java-symbol type="layout" name="keyguard_screen_sim_pin_portrait" />
<java-symbol type="layout" name="keyguard_screen_sim_puk_landscape" />
<java-symbol type="layout" name="keyguard_screen_sim_puk_portrait" />
<java-symbol type="layout" name="keyguard_screen_tab_unlock" />
<java-symbol type="layout" name="keyguard_screen_tab_unlock_land" />
<java-symbol type="layout" name="keyguard_screen_unlock_landscape" />
<java-symbol type="layout" name="keyguard_screen_unlock_portrait" />
<java-symbol type="layout" name="keyguard_selector_view" />
<java-symbol type="layout" name="keyguard_pattern_view" />
<java-symbol type="layout" name="keyguard_password_view" />

View File

@@ -141,8 +141,7 @@ public class KeyguardStatusView extends GridLayout {
}
private void maybeSetUpperCaseText(TextView textView, CharSequence text) {
if (KeyguardViewManager.USE_UPPER_CASE
&& textView.getId() != R.id.owner_info) { // currently only required for date view
if (KeyguardViewManager.USE_UPPER_CASE) {
textView.setText(text != null ? text.toString().toUpperCase() : null);
} else {
textView.setText(text);

View File

@@ -1,317 +0,0 @@
/*
* Copyright (C) 2008 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.internal.policy.impl.keyguard_obsolete;
import com.android.internal.R;
import com.android.internal.widget.LockPatternUtils;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.OperationCanceledException;
import android.accounts.AccountManagerFuture;
import android.accounts.AuthenticatorException;
import android.accounts.AccountManagerCallback;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.text.Editable;
import android.text.InputFilter;
import android.text.LoginFilter;
import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.os.Bundle;
import java.io.IOException;
/**
* When the user forgets their password a bunch of times, we fall back on their
* account's login/password to unlock the phone (and reset their lock pattern).
*/
public class AccountUnlockScreen extends RelativeLayout implements KeyguardScreen,
View.OnClickListener, TextWatcher {
private static final String LOCK_PATTERN_PACKAGE = "com.android.settings";
private static final String LOCK_PATTERN_CLASS = LOCK_PATTERN_PACKAGE + ".ChooseLockGeneric";
/**
* The amount of millis to stay awake once this screen detects activity
*/
private static final int AWAKE_POKE_MILLIS = 30000;
private KeyguardScreenCallback mCallback;
private LockPatternUtils mLockPatternUtils;
private KeyguardUpdateMonitor mUpdateMonitor;
private TextView mTopHeader;
private TextView mInstructions;
private EditText mLogin;
private EditText mPassword;
private Button mOk;
/**
* Shown while making asynchronous check of password.
*/
private ProgressDialog mCheckingDialog;
private KeyguardStatusViewManager mKeyguardStatusViewManager;
/**
* AccountUnlockScreen constructor.
* @param configuration
* @param updateMonitor
*/
public AccountUnlockScreen(Context context, Configuration configuration,
KeyguardUpdateMonitor updateMonitor, KeyguardScreenCallback callback,
LockPatternUtils lockPatternUtils) {
super(context);
mCallback = callback;
mLockPatternUtils = lockPatternUtils;
LayoutInflater.from(context).inflate(
R.layout.keyguard_screen_glogin_unlock, this, true);
mTopHeader = (TextView) findViewById(R.id.topHeader);
mTopHeader.setText(mLockPatternUtils.isPermanentlyLocked() ?
R.string.lockscreen_glogin_too_many_attempts :
R.string.lockscreen_glogin_forgot_pattern);
mInstructions = (TextView) findViewById(R.id.instructions);
mLogin = (EditText) findViewById(R.id.login);
mLogin.setFilters(new InputFilter[] { new LoginFilter.UsernameFilterGeneric() } );
mLogin.addTextChangedListener(this);
mPassword = (EditText) findViewById(R.id.password);
mPassword.addTextChangedListener(this);
mOk = (Button) findViewById(R.id.ok);
mOk.setOnClickListener(this);
mUpdateMonitor = updateMonitor;
mKeyguardStatusViewManager = new KeyguardStatusViewManager(this, updateMonitor,
lockPatternUtils, callback, true);
}
public void afterTextChanged(Editable s) {
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
mCallback.pokeWakelock(AWAKE_POKE_MILLIS);
}
@Override
protected boolean onRequestFocusInDescendants(int direction,
Rect previouslyFocusedRect) {
// send focus to the login field
return mLogin.requestFocus(direction, previouslyFocusedRect);
}
/** {@inheritDoc} */
public boolean needsInput() {
return true;
}
/** {@inheritDoc} */
public void onPause() {
mKeyguardStatusViewManager.onPause();
}
/** {@inheritDoc} */
public void onResume() {
// start fresh
mLogin.setText("");
mPassword.setText("");
mLogin.requestFocus();
mKeyguardStatusViewManager.onResume();
}
/** {@inheritDoc} */
public void cleanUp() {
if (mCheckingDialog != null) {
mCheckingDialog.hide();
}
mUpdateMonitor.removeCallback(this); // this must be first
mCallback = null;
mLockPatternUtils = null;
mUpdateMonitor = null;
}
/** {@inheritDoc} */
public void onClick(View v) {
mCallback.pokeWakelock();
if (v == mOk) {
asyncCheckPassword();
}
}
private void postOnCheckPasswordResult(final boolean success) {
// ensure this runs on UI thread
mLogin.post(new Runnable() {
public void run() {
if (success) {
// clear out forgotten password
mLockPatternUtils.setPermanentlyLocked(false);
mLockPatternUtils.setLockPatternEnabled(false);
mLockPatternUtils.saveLockPattern(null);
// launch the 'choose lock pattern' activity so
// the user can pick a new one if they want to
Intent intent = new Intent();
intent.setClassName(LOCK_PATTERN_PACKAGE, LOCK_PATTERN_CLASS);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(intent);
mCallback.reportSuccessfulUnlockAttempt();
// close the keyguard
mCallback.keyguardDone(true);
} else {
mInstructions.setText(R.string.lockscreen_glogin_invalid_input);
mPassword.setText("");
mCallback.reportFailedUnlockAttempt();
}
}
});
}
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN
&& event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
if (mLockPatternUtils.isPermanentlyLocked()) {
mCallback.goToLockScreen();
} else {
mCallback.forgotPattern(false);
}
return true;
}
return super.dispatchKeyEvent(event);
}
/**
* Given the string the user entered in the 'username' field, find
* the stored account that they probably intended. Prefer, in order:
*
* - an exact match for what was typed, or
* - a case-insensitive match for what was typed, or
* - if they didn't include a domain, an exact match of the username, or
* - if they didn't include a domain, a case-insensitive
* match of the username.
*
* If there is a tie for the best match, choose neither --
* the user needs to be more specific.
*
* @return an account name from the database, or null if we can't
* find a single best match.
*/
private Account findIntendedAccount(String username) {
Account[] accounts = AccountManager.get(mContext).getAccountsByType("com.google");
// Try to figure out which account they meant if they
// typed only the username (and not the domain), or got
// the case wrong.
Account bestAccount = null;
int bestScore = 0;
for (Account a: accounts) {
int score = 0;
if (username.equals(a.name)) {
score = 4;
} else if (username.equalsIgnoreCase(a.name)) {
score = 3;
} else if (username.indexOf('@') < 0) {
int i = a.name.indexOf('@');
if (i >= 0) {
String aUsername = a.name.substring(0, i);
if (username.equals(aUsername)) {
score = 2;
} else if (username.equalsIgnoreCase(aUsername)) {
score = 1;
}
}
}
if (score > bestScore) {
bestAccount = a;
bestScore = score;
} else if (score == bestScore) {
bestAccount = null;
}
}
return bestAccount;
}
private void asyncCheckPassword() {
mCallback.pokeWakelock(AWAKE_POKE_MILLIS);
final String login = mLogin.getText().toString();
final String password = mPassword.getText().toString();
Account account = findIntendedAccount(login);
if (account == null) {
postOnCheckPasswordResult(false);
return;
}
getProgressDialog().show();
Bundle options = new Bundle();
options.putString(AccountManager.KEY_PASSWORD, password);
AccountManager.get(mContext).confirmCredentials(account, options, null /* activity */,
new AccountManagerCallback<Bundle>() {
public void run(AccountManagerFuture<Bundle> future) {
try {
mCallback.pokeWakelock(AWAKE_POKE_MILLIS);
final Bundle result = future.getResult();
final boolean verified = result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT);
postOnCheckPasswordResult(verified);
} catch (OperationCanceledException e) {
postOnCheckPasswordResult(false);
} catch (IOException e) {
postOnCheckPasswordResult(false);
} catch (AuthenticatorException e) {
postOnCheckPasswordResult(false);
} finally {
mLogin.post(new Runnable() {
public void run() {
getProgressDialog().hide();
}
});
}
}
}, null /* handler */);
}
private Dialog getProgressDialog() {
if (mCheckingDialog == null) {
mCheckingDialog = new ProgressDialog(mContext);
mCheckingDialog.setMessage(
mContext.getString(R.string.lockscreen_glogin_checking_password));
mCheckingDialog.setIndeterminate(true);
mCheckingDialog.setCancelable(false);
mCheckingDialog.getWindow().setType(
WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
}
return mCheckingDialog;
}
}

View File

@@ -1,80 +0,0 @@
/*
* 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.internal.policy.impl.keyguard_obsolete;
import android.view.View;
interface BiometricSensorUnlock {
/**
* Initializes the view provided for the biometric unlock UI to work within. The provided area
* completely covers the backup unlock mechanism.
* @param biometricUnlockView View provided for the biometric unlock UI.
*/
public void initializeView(View biometricUnlockView);
/**
* Indicates whether the biometric unlock is running. Before
* {@link BiometricSensorUnlock#start} is called, isRunning() returns false. After a successful
* call to {@link BiometricSensorUnlock#start}, isRunning() returns true until the biometric
* unlock completes, {@link BiometricSensorUnlock#stop} has been called, or an error has
* forced the biometric unlock to stop.
* @return whether the biometric unlock is currently running.
*/
public boolean isRunning();
/**
* Covers the backup unlock mechanism by showing the contents of the view initialized in
* {@link BiometricSensorUnlock#initializeView(View)}. The view should disappear after the
* specified timeout. If the timeout is 0, the interface shows until another event, such as
* calling {@link BiometricSensorUnlock#hide()}, causes it to disappear. Called on the UI
* thread.
* @param timeoutMilliseconds Amount of time in milliseconds to display the view before
* disappearing. A value of 0 means the view should remain visible.
*/
public void show(long timeoutMilliseconds);
/**
* Uncovers the backup unlock mechanism by hiding the contents of the view initialized in
* {@link BiometricSensorUnlock#initializeView(View)}.
*/
public void hide();
/**
* Binds to the biometric unlock service and starts the unlock procedure. Called on the UI
* thread.
* @return false if it can't be started or the backup should be used.
*/
public boolean start();
/**
* Stops the biometric unlock procedure and unbinds from the service. Called on the UI thread.
* @return whether the biometric unlock was running when called.
*/
public boolean stop();
/**
* Cleans up any resources used by the biometric unlock.
*/
public void cleanUp();
/**
* Gets the Device Policy Manager quality of the biometric unlock sensor
* (e.g., PASSWORD_QUALITY_BIOMETRIC_WEAK).
* @return biometric unlock sensor quality, as defined by Device Policy Manager.
*/
public int getQuality();
}

View File

@@ -1,554 +0,0 @@
/*
* Copyright (C) 2011 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.internal.policy.impl.keyguard_obsolete;
import com.android.internal.R;
import com.android.internal.policy.IFaceLockCallback;
import com.android.internal.policy.IFaceLockInterface;
import com.android.internal.widget.LockPatternUtils;
import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.View;
public class FaceUnlock implements BiometricSensorUnlock, Handler.Callback {
private static final boolean DEBUG = false;
private static final String TAG = "FULLockscreen";
private final Context mContext;
private final LockPatternUtils mLockPatternUtils;
private final KeyguardUpdateMonitor mUpdateMonitor;
// TODO: is mServiceRunning needed or can we just use mIsRunning or check if mService is null?
private boolean mServiceRunning = false;
// TODO: now that the code has been restructure to do almost all operations from a handler, this
// lock may no longer be necessary.
private final Object mServiceRunningLock = new Object();
private IFaceLockInterface mService;
private boolean mBoundToService = false;
private View mFaceUnlockView;
private Handler mHandler;
private final int MSG_SHOW_FACE_UNLOCK_VIEW = 0;
private final int MSG_HIDE_FACE_UNLOCK_VIEW = 1;
private final int MSG_SERVICE_CONNECTED = 2;
private final int MSG_SERVICE_DISCONNECTED = 3;
private final int MSG_UNLOCK = 4;
private final int MSG_CANCEL = 5;
private final int MSG_REPORT_FAILED_ATTEMPT = 6;
//private final int MSG_EXPOSE_FALLBACK = 7;
private final int MSG_POKE_WAKELOCK = 8;
// TODO: This was added for the purpose of adhering to what the biometric interface expects
// the isRunning() function to return. However, it is probably not necessary to have both
// mRunning and mServiceRunning. I'd just rather wait to change that logic.
private volatile boolean mIsRunning = false;
// Long enough to stay visible while the service starts
// Short enough to not have to wait long for backup if service fails to start or crashes
// The service can take a couple of seconds to start on the first try after boot
private final int SERVICE_STARTUP_VIEW_TIMEOUT = 3000;
// So the user has a consistent amount of time when brought to the backup method from Face
// Unlock
private final int BACKUP_LOCK_TIMEOUT = 5000;
KeyguardScreenCallback mKeyguardScreenCallback;
/**
* Stores some of the structures that Face Unlock will need to access and creates the handler
* will be used to execute messages on the UI thread.
*/
public FaceUnlock(Context context, KeyguardUpdateMonitor updateMonitor,
LockPatternUtils lockPatternUtils, KeyguardScreenCallback keyguardScreenCallback) {
mContext = context;
mUpdateMonitor = updateMonitor;
mLockPatternUtils = lockPatternUtils;
mKeyguardScreenCallback = keyguardScreenCallback;
mHandler = new Handler(this);
}
/**
* Stores and displays the view that Face Unlock is allowed to draw within.
* TODO: since the layout object will eventually be shared by multiple biometric unlock
* methods, we will have to add our other views (background, cancel button) here.
*/
public void initializeView(View biometricUnlockView) {
Log.d(TAG, "initializeView()");
mFaceUnlockView = biometricUnlockView;
}
/**
* Indicates whether Face Unlock is currently running.
*/
public boolean isRunning() {
return mIsRunning;
}
/**
* Sets the Face Unlock view to visible, hiding it after the specified amount of time. If
* timeoutMillis is 0, no hide is performed. Called on the UI thread.
*/
public void show(long timeoutMillis) {
if (DEBUG) Log.d(TAG, "show()");
if (mHandler.getLooper() != Looper.myLooper()) {
Log.e(TAG, "show() called off of the UI thread");
}
removeDisplayMessages();
if (mFaceUnlockView != null) {
mFaceUnlockView.setVisibility(View.VISIBLE);
}
if (timeoutMillis > 0) {
mHandler.sendEmptyMessageDelayed(MSG_HIDE_FACE_UNLOCK_VIEW, timeoutMillis);
}
}
/**
* Hides the Face Unlock view.
*/
public void hide() {
if (DEBUG) Log.d(TAG, "hide()");
// Remove messages to prevent a delayed show message from undo-ing the hide
removeDisplayMessages();
mHandler.sendEmptyMessage(MSG_HIDE_FACE_UNLOCK_VIEW);
}
/**
* Binds to the Face Unlock service. Face Unlock will be started when the bind completes. The
* Face Unlock view is displayed to hide the backup lock while the service is starting up.
* Called on the UI thread.
*/
public boolean start() {
if (DEBUG) Log.d(TAG, "start()");
if (mHandler.getLooper() != Looper.myLooper()) {
Log.e(TAG, "start() called off of the UI thread");
}
if (mIsRunning) {
Log.w(TAG, "start() called when already running");
}
// Show Face Unlock view, but only for a little bit so lockpattern will become visible if
// Face Unlock fails to start or crashes
// This must show before bind to guarantee that Face Unlock has a place to display
show(SERVICE_STARTUP_VIEW_TIMEOUT);
if (!mBoundToService) {
Log.d(TAG, "Binding to Face Unlock service");
mContext.bindService(new Intent(IFaceLockInterface.class.getName()),
mConnection,
Context.BIND_AUTO_CREATE,
mLockPatternUtils.getCurrentUser());
mBoundToService = true;
} else {
Log.w(TAG, "Attempt to bind to Face Unlock when already bound");
}
mIsRunning = true;
return true;
}
/**
* Stops Face Unlock and unbinds from the service. Called on the UI thread.
*/
public boolean stop() {
if (DEBUG) Log.d(TAG, "stop()");
if (mHandler.getLooper() != Looper.myLooper()) {
Log.e(TAG, "stop() called off of the UI thread");
}
boolean mWasRunning = mIsRunning;
stopUi();
if (mBoundToService) {
if (mService != null) {
try {
mService.unregisterCallback(mFaceUnlockCallback);
} catch (RemoteException e) {
// Not much we can do
}
}
Log.d(TAG, "Unbinding from Face Unlock service");
mContext.unbindService(mConnection);
mBoundToService = false;
} else {
// This is usually not an error when this happens. Sometimes we will tell it to
// unbind multiple times because it's called from both onWindowFocusChanged and
// onDetachedFromWindow.
if (DEBUG) Log.d(TAG, "Attempt to unbind from Face Unlock when not bound");
}
mIsRunning = false;
return mWasRunning;
}
/**
* Frees up resources used by Face Unlock and stops it if it is still running.
*/
public void cleanUp() {
if (DEBUG) Log.d(TAG, "cleanUp()");
if (mService != null) {
try {
mService.unregisterCallback(mFaceUnlockCallback);
} catch (RemoteException e) {
// Not much we can do
}
stopUi();
mService = null;
}
}
/**
* Returns the Device Policy Manager quality for Face Unlock, which is BIOMETRIC_WEAK.
*/
public int getQuality() {
return DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK;
}
/**
* Handles messages such that everything happens on the UI thread in a deterministic order.
* Calls from the Face Unlock service come from binder threads. Calls from lockscreen typically
* come from the UI thread. This makes sure there are no race conditions between those calls.
*/
@Override
public boolean handleMessage(Message msg) {
switch (msg.what) {
case MSG_SHOW_FACE_UNLOCK_VIEW:
handleShowFaceUnlockView();
break;
case MSG_HIDE_FACE_UNLOCK_VIEW:
handleHideFaceUnlockView();
break;
case MSG_SERVICE_CONNECTED:
handleServiceConnected();
break;
case MSG_SERVICE_DISCONNECTED:
handleServiceDisconnected();
break;
case MSG_UNLOCK:
handleUnlock();
break;
case MSG_CANCEL:
handleCancel();
break;
case MSG_REPORT_FAILED_ATTEMPT:
handleReportFailedAttempt();
break;
//case MSG_EXPOSE_FALLBACK:
//handleExposeFallback();
//break;
case MSG_POKE_WAKELOCK:
handlePokeWakelock(msg.arg1);
break;
default:
Log.e(TAG, "Unhandled message");
return false;
}
return true;
}
/**
* Sets the Face Unlock view to visible, thus covering the backup lock.
*/
void handleShowFaceUnlockView() {
if (DEBUG) Log.d(TAG, "handleShowFaceUnlockView()");
if (mFaceUnlockView != null) {
mFaceUnlockView.setVisibility(View.VISIBLE);
} else {
Log.e(TAG, "mFaceUnlockView is null in handleShowFaceUnlockView()");
}
}
/**
* Sets the Face Unlock view to invisible, thus exposing the backup lock.
*/
void handleHideFaceUnlockView() {
if (DEBUG) Log.d(TAG, "handleHideFaceUnlockView()");
if (mFaceUnlockView != null) {
mFaceUnlockView.setVisibility(View.INVISIBLE);
} else {
Log.e(TAG, "mFaceUnlockView is null in handleHideFaceUnlockView()");
}
}
/**
* Tells the service to start its UI via an AIDL interface. Called when the
* onServiceConnected() callback is received.
*/
void handleServiceConnected() {
Log.d(TAG, "handleServiceConnected()");
// It is possible that an unbind has occurred in the time between the bind and when this
// function is reached. If an unbind has already occurred, proceeding on to call startUi()
// can result in a fatal error. Note that the onServiceConnected() callback is
// asynchronous, so this possibility would still exist if we executed this directly in
// onServiceConnected() rather than using a handler.
if (!mBoundToService) {
Log.d(TAG, "Dropping startUi() in handleServiceConnected() because no longer bound");
return;
}
try {
mService.registerCallback(mFaceUnlockCallback);
} catch (RemoteException e) {
Log.e(TAG, "Caught exception connecting to Face Unlock: " + e.toString());
mService = null;
mBoundToService = false;
mIsRunning = false;
return;
}
if (mFaceUnlockView != null) {
IBinder windowToken = mFaceUnlockView.getWindowToken();
if (windowToken != null) {
// When switching between portrait and landscape view while Face Unlock is running,
// the screen will eventually go dark unless we poke the wakelock when Face Unlock
// is restarted.
mKeyguardScreenCallback.pokeWakelock();
int[] position;
position = new int[2];
mFaceUnlockView.getLocationInWindow(position);
startUi(windowToken, position[0], position[1], mFaceUnlockView.getWidth(),
mFaceUnlockView.getHeight());
} else {
Log.e(TAG, "windowToken is null in handleServiceConnected()");
}
}
}
/**
* Called when the onServiceDisconnected() callback is received. This should not happen during
* normal operation. It indicates an error has occurred.
*/
void handleServiceDisconnected() {
Log.e(TAG, "handleServiceDisconnected()");
// TODO: this lock may no longer be needed now that everything is being called from a
// handler
synchronized (mServiceRunningLock) {
mService = null;
mServiceRunning = false;
}
mBoundToService = false;
mIsRunning = false;
}
/**
* Stops the Face Unlock service and tells the device to grant access to the user. Shows the
* Face Unlock view to keep the backup lock covered while the device unlocks.
*/
void handleUnlock() {
if (DEBUG) Log.d(TAG, "handleUnlock()");
removeDisplayMessages();
if (mFaceUnlockView != null) {
mFaceUnlockView.setVisibility(View.VISIBLE);
} else {
Log.e(TAG, "mFaceUnlockView is null in handleUnlock()");
}
stop();
mKeyguardScreenCallback.keyguardDone(true);
mKeyguardScreenCallback.reportSuccessfulUnlockAttempt();
}
/**
* Stops the Face Unlock service and exposes the backup lock.
*/
void handleCancel() {
if (DEBUG) Log.d(TAG, "handleCancel()");
if (mFaceUnlockView != null) {
mFaceUnlockView.setVisibility(View.INVISIBLE);
} else {
Log.e(TAG, "mFaceUnlockView is null in handleCancel()");
}
stop();
mKeyguardScreenCallback.pokeWakelock(BACKUP_LOCK_TIMEOUT);
}
/**
* Increments the number of failed Face Unlock attempts.
*/
void handleReportFailedAttempt() {
if (DEBUG) Log.d(TAG, "handleReportFailedAttempt()");
mUpdateMonitor.reportFailedBiometricUnlockAttempt();
}
/**
* Hides the Face Unlock view to expose the backup lock. Called when the Face Unlock service UI
* is started, indicating there is no need to continue displaying the underlying view because
* the service UI is now covering the backup lock.
*/
//void handleExposeFallback() {
// if (DEBUG) Log.d(TAG, "handleExposeFallback()");
// if (mFaceUnlockView != null) {
// mFaceUnlockView.setVisibility(View.INVISIBLE);
// } else {
// Log.e(TAG, "mFaceUnlockView is null in handleExposeFallback()");
// }
//}
/**
* Pokes the wakelock to keep the screen alive and active for a specific amount of time.
*/
void handlePokeWakelock(int millis) {
mKeyguardScreenCallback.pokeWakelock(millis);
}
/**
* Removes show and hide messages from the message queue. Called to prevent delayed show/hide
* messages from undoing a new message.
*/
private void removeDisplayMessages() {
mHandler.removeMessages(MSG_SHOW_FACE_UNLOCK_VIEW);
mHandler.removeMessages(MSG_HIDE_FACE_UNLOCK_VIEW);
}
/**
* Implements service connection methods.
*/
private ServiceConnection mConnection = new ServiceConnection() {
/**
* Called when the Face Unlock service connects after calling bind().
*/
@Override
public void onServiceConnected(ComponentName className, IBinder iservice) {
Log.d(TAG, "Connected to Face Unlock service");
mService = IFaceLockInterface.Stub.asInterface(iservice);
mHandler.sendEmptyMessage(MSG_SERVICE_CONNECTED);
}
/**
* Called if the Face Unlock service unexpectedly disconnects. This indicates an error.
*/
@Override
public void onServiceDisconnected(ComponentName className) {
Log.e(TAG, "Unexpected disconnect from Face Unlock service");
mHandler.sendEmptyMessage(MSG_SERVICE_DISCONNECTED);
}
};
/**
* Tells the Face Unlock service to start displaying its UI and start processing.
*/
private void startUi(IBinder windowToken, int x, int y, int w, int h) {
if (DEBUG) Log.d(TAG, "startUi()");
synchronized (mServiceRunningLock) {
if (!mServiceRunning) {
Log.d(TAG, "Starting Face Unlock");
try {
mService.startUi(windowToken, x, y, w, h,
mLockPatternUtils.isBiometricWeakLivelinessEnabled());
} catch (RemoteException e) {
Log.e(TAG, "Caught exception starting Face Unlock: " + e.toString());
return;
}
mServiceRunning = true;
} else {
Log.w(TAG, "startUi() attempted while running");
}
}
}
/**
* Tells the Face Unlock service to stop displaying its UI and stop processing.
*/
private void stopUi() {
if (DEBUG) Log.d(TAG, "stopUi()");
// Note that attempting to stop Face Unlock when it's not running is not an issue.
// Face Unlock can return, which stops it and then we try to stop it when the
// screen is turned off. That's why we check.
synchronized (mServiceRunningLock) {
if (mServiceRunning) {
Log.d(TAG, "Stopping Face Unlock");
try {
mService.stopUi();
} catch (RemoteException e) {
Log.e(TAG, "Caught exception stopping Face Unlock: " + e.toString());
}
mServiceRunning = false;
} else {
// This is usually not an error when this happens. Sometimes we will tell it to
// stop multiple times because it's called from both onWindowFocusChanged and
// onDetachedFromWindow.
if (DEBUG) Log.d(TAG, "stopUi() attempted while not running");
}
}
}
/**
* Implements the AIDL biometric unlock service callback interface.
*/
private final IFaceLockCallback mFaceUnlockCallback = new IFaceLockCallback.Stub() {
/**
* Called when Face Unlock wants to grant access to the user.
*/
@Override
public void unlock() {
if (DEBUG) Log.d(TAG, "unlock()");
mHandler.sendEmptyMessage(MSG_UNLOCK);
}
/**
* Called when Face Unlock wants to go to the backup.
*/
@Override
public void cancel() {
if (DEBUG) Log.d(TAG, "cancel()");
mHandler.sendEmptyMessage(MSG_CANCEL);
}
/**
* Called when Face Unlock wants to increment the number of failed attempts.
*/
@Override
public void reportFailedAttempt() {
if (DEBUG) Log.d(TAG, "reportFailedAttempt()");
mHandler.sendEmptyMessage(MSG_REPORT_FAILED_ATTEMPT);
}
/**
* Called when the Face Unlock service starts displaying the UI, indicating that the backup
* unlock can be exposed because the Face Unlock service is now covering the backup with its
* UI.
**/
//@Override
//public void exposeFallback() {
// if (DEBUG) Log.d(TAG, "exposeFallback()");
// mHandler.sendEmptyMessage(MSG_EXPOSE_FALLBACK);
//}
/**
* Called when Face Unlock wants to keep the screen alive and active for a specific amount
* of time.
*/
public void pokeWakelock(int millis) {
if (DEBUG) Log.d(TAG, "pokeWakelock() for " + millis + "ms");
Message message = mHandler.obtainMessage(MSG_POKE_WAKELOCK, millis, -1);
mHandler.sendMessage(message);
}
};
}

View File

@@ -1,45 +0,0 @@
/*
* Copyright (C) 2008 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.internal.policy.impl.keyguard_obsolete;
/**
* Common interface of each {@link android.view.View} that is a screen of
* {@link LockPatternKeyguardView}.
*/
public interface KeyguardScreen {
/**
* Return true if your view needs input, so should allow the soft
* keyboard to be displayed.
*/
boolean needsInput();
/**
* This screen is no longer in front of the user.
*/
void onPause();
/**
* This screen is going to be in front of the user.
*/
void onResume();
/**
* This view is going away; a hook to do cleanup.
*/
void cleanUp();
}

View File

@@ -1,82 +0,0 @@
/*
* Copyright (C) 2008 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.internal.policy.impl.keyguard_obsolete;
import android.content.res.Configuration;
/**
* Within a keyguard, there may be several screens that need a callback
* to the host keyguard view.
*/
public interface KeyguardScreenCallback extends KeyguardViewCallback {
/**
* Transition to the lock screen.
*/
void goToLockScreen();
/**
* Transition to the unlock screen.
*/
void goToUnlockScreen();
/**
* The user reported that they forgot their pattern (or not, when they want to back out of the
* forgot pattern screen).
*
* @param isForgotten True if the user hit the forgot pattern, false if they want to back out
* of the account screen.
*/
void forgotPattern(boolean isForgotten);
/**
* @return Whether the keyguard requires some sort of PIN.
*/
boolean isSecure();
/**
* @return Whether we are in a mode where we only want to verify the
* user can get past the keyguard.
*/
boolean isVerifyUnlockOnly();
/**
* Stay on me, but recreate me (so I can use a different layout).
*/
void recreateMe(Configuration config);
/**
* Take action to send an emergency call.
*/
void takeEmergencyCallAction();
/**
* Report that the user had a failed attempt to unlock with password or pattern.
*/
void reportFailedUnlockAttempt();
/**
* Report that the user successfully entered their password or pattern.
*/
void reportSuccessfulUnlockAttempt();
/**
* Report whether we there's another way to unlock the device.
* @return true
*/
boolean doesFallbackUnlockScreenExist();
}

View File

@@ -1,682 +0,0 @@
/*
* Copyright (C) 2011 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.internal.policy.impl.keyguard_obsolete;
import com.android.internal.R;
import com.android.internal.telephony.IccCardConstants;
import com.android.internal.widget.DigitalClock;
import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.TransportControlView;
import java.util.ArrayList;
import java.util.Date;
import libcore.util.MutableInt;
import android.content.ContentResolver;
import android.content.Context;
import android.provider.Settings;
import android.text.TextUtils;
import android.text.format.DateFormat;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
/***
* Manages a number of views inside of LockScreen layouts. See below for a list of widgets
*
*/
class KeyguardStatusViewManager implements OnClickListener {
private static final boolean DEBUG = false;
private static final String TAG = "KeyguardStatusView";
public static final int LOCK_ICON = 0; // R.drawable.ic_lock_idle_lock;
public static final int ALARM_ICON = R.drawable.ic_lock_idle_alarm;
public static final int CHARGING_ICON = 0; //R.drawable.ic_lock_idle_charging;
public static final int BATTERY_LOW_ICON = 0; //R.drawable.ic_lock_idle_low_battery;
private static final long INSTRUCTION_RESET_DELAY = 2000; // time until instruction text resets
private static final int INSTRUCTION_TEXT = 10;
private static final int CARRIER_TEXT = 11;
private static final int CARRIER_HELP_TEXT = 12;
private static final int HELP_MESSAGE_TEXT = 13;
private static final int OWNER_INFO = 14;
private static final int BATTERY_INFO = 15;
private StatusMode mStatus;
private String mDateFormatString;
private TransientTextManager mTransientTextManager;
// Views that this class controls.
// NOTE: These may be null in some LockScreen screens and should protect from NPE
private TextView mCarrierView;
private TextView mDateView;
private TextView mStatus1View;
private TextView mOwnerInfoView;
private TextView mAlarmStatusView;
private TransportControlView mTransportView;
// Top-level container view for above views
private View mContainer;
// are we showing battery information?
private boolean mShowingBatteryInfo = false;
// last known plugged in state
private boolean mPluggedIn = false;
// last known battery level
private int mBatteryLevel = 100;
// last known SIM state
protected IccCardConstants.State mSimState;
private LockPatternUtils mLockPatternUtils;
private KeyguardUpdateMonitor mUpdateMonitor;
private Button mEmergencyCallButton;
private boolean mEmergencyButtonEnabledBecauseSimLocked;
// Shadowed text values
private CharSequence mCarrierText;
private CharSequence mCarrierHelpText;
private String mHelpMessageText;
private String mInstructionText;
private CharSequence mOwnerInfoText;
private boolean mShowingStatus;
private KeyguardScreenCallback mCallback;
private final boolean mEmergencyCallButtonEnabledInScreen;
private CharSequence mPlmn;
private CharSequence mSpn;
protected int mPhoneState;
private DigitalClock mDigitalClock;
protected boolean mBatteryCharged;
protected boolean mBatteryIsLow;
private class TransientTextManager {
private TextView mTextView;
private class Data {
final int icon;
final CharSequence text;
Data(CharSequence t, int i) {
text = t;
icon = i;
}
};
private ArrayList<Data> mMessages = new ArrayList<Data>(5);
TransientTextManager(TextView textView) {
mTextView = textView;
}
/* Show given message with icon for up to duration ms. Newer messages override older ones.
* The most recent message with the longest duration is shown as messages expire until
* nothing is left, in which case the text/icon is defined by a call to
* getAltTextMessage() */
void post(final CharSequence message, final int icon, long duration) {
if (mTextView == null) {
return;
}
mTextView.setText(message);
mTextView.setCompoundDrawablesWithIntrinsicBounds(icon, 0, 0, 0);
final Data data = new Data(message, icon);
mContainer.postDelayed(new Runnable() {
public void run() {
mMessages.remove(data);
int last = mMessages.size() - 1;
final CharSequence lastText;
final int lastIcon;
if (last > 0) {
final Data oldData = mMessages.get(last);
lastText = oldData.text;
lastIcon = oldData.icon;
} else {
final MutableInt tmpIcon = new MutableInt(0);
lastText = getAltTextMessage(tmpIcon);
lastIcon = tmpIcon.value;
}
mTextView.setText(lastText);
mTextView.setCompoundDrawablesWithIntrinsicBounds(lastIcon, 0, 0, 0);
}
}, duration);
}
};
/**
*
* @param view the containing view of all widgets
* @param updateMonitor the update monitor to use
* @param lockPatternUtils lock pattern util object
* @param callback used to invoke emergency dialer
* @param emergencyButtonEnabledInScreen whether emergency button is enabled by default
*/
public KeyguardStatusViewManager(View view, KeyguardUpdateMonitor updateMonitor,
LockPatternUtils lockPatternUtils, KeyguardScreenCallback callback,
boolean emergencyButtonEnabledInScreen) {
if (DEBUG) Log.v(TAG, "KeyguardStatusViewManager()");
mContainer = view;
mDateFormatString = getContext().getString(R.string.abbrev_wday_month_day_no_year);
mLockPatternUtils = lockPatternUtils;
mUpdateMonitor = updateMonitor;
mCallback = callback;
mCarrierView = (TextView) findViewById(R.id.carrier);
mDateView = (TextView) findViewById(R.id.date);
mStatus1View = (TextView) findViewById(R.id.status1);
mAlarmStatusView = (TextView) findViewById(R.id.alarm_status);
mOwnerInfoView = (TextView) findViewById(R.id.owner_info);
mTransportView = (TransportControlView) findViewById(R.id.transport);
mEmergencyCallButton = (Button) findViewById(R.id.emergencyCallButton);
mEmergencyCallButtonEnabledInScreen = emergencyButtonEnabledInScreen;
mDigitalClock = (DigitalClock) findViewById(R.id.time);
// Hide transport control view until we know we need to show it.
if (mTransportView != null) {
mTransportView.setVisibility(View.GONE);
}
if (mEmergencyCallButton != null) {
mEmergencyCallButton.setText(R.string.lockscreen_emergency_call);
mEmergencyCallButton.setOnClickListener(this);
mEmergencyCallButton.setFocusable(false); // touch only!
}
mTransientTextManager = new TransientTextManager(mCarrierView);
// Registering this callback immediately updates the battery state, among other things.
mUpdateMonitor.registerCallback(mInfoCallback);
resetStatusInfo();
refreshDate();
updateOwnerInfo();
// Required to get Marquee to work.
final View scrollableViews[] = { mCarrierView, mDateView, mStatus1View, mOwnerInfoView,
mAlarmStatusView };
for (View v : scrollableViews) {
if (v != null) {
v.setSelected(true);
}
}
}
private boolean inWidgetMode() {
return mTransportView != null && mTransportView.getVisibility() == View.VISIBLE;
}
void setInstructionText(String string) {
mInstructionText = string;
update(INSTRUCTION_TEXT, string);
}
void setCarrierText(CharSequence string) {
mCarrierText = string;
update(CARRIER_TEXT, string);
}
void setOwnerInfo(CharSequence string) {
mOwnerInfoText = string;
update(OWNER_INFO, string);
}
/**
* Sets the carrier help text message, if view is present. Carrier help text messages are
* typically for help dealing with SIMS and connectivity.
*
* @param resId resource id of the message
*/
public void setCarrierHelpText(int resId) {
mCarrierHelpText = getText(resId);
update(CARRIER_HELP_TEXT, mCarrierHelpText);
}
private CharSequence getText(int resId) {
return resId == 0 ? null : getContext().getText(resId);
}
/**
* Unlock help message. This is typically for help with unlock widgets, e.g. "wrong password"
* or "try again."
*
* @param textResId
* @param lockIcon
*/
public void setHelpMessage(int textResId, int lockIcon) {
final CharSequence tmp = getText(textResId);
mHelpMessageText = tmp == null ? null : tmp.toString();
update(HELP_MESSAGE_TEXT, mHelpMessageText);
}
private void update(int what, CharSequence string) {
if (inWidgetMode()) {
if (DEBUG) Log.v(TAG, "inWidgetMode() is true");
// Use Transient text for messages shown while widget is shown.
switch (what) {
case INSTRUCTION_TEXT:
case CARRIER_HELP_TEXT:
case HELP_MESSAGE_TEXT:
case BATTERY_INFO:
mTransientTextManager.post(string, 0, INSTRUCTION_RESET_DELAY);
break;
case OWNER_INFO:
case CARRIER_TEXT:
default:
if (DEBUG) Log.w(TAG, "Not showing message id " + what + ", str=" + string);
}
} else {
updateStatusLines(mShowingStatus);
}
}
public void onPause() {
if (DEBUG) Log.v(TAG, "onPause()");
mUpdateMonitor.removeCallback(mInfoCallback);
}
/** {@inheritDoc} */
public void onResume() {
if (DEBUG) Log.v(TAG, "onResume()");
// First update the clock, if present.
if (mDigitalClock != null) {
mDigitalClock.updateTime();
}
mUpdateMonitor.registerCallback(mInfoCallback);
resetStatusInfo();
// Issue the biometric unlock failure message in a centralized place
// TODO: we either need to make the Face Unlock multiple failures string a more general
// 'biometric unlock' or have each biometric unlock handle this on their own.
if (mUpdateMonitor.getMaxBiometricUnlockAttemptsReached()) {
setInstructionText(getContext().getString(R.string.faceunlock_multiple_failures));
}
}
void resetStatusInfo() {
mInstructionText = null;
updateStatusLines(true);
}
/**
* Update the status lines based on these rules:
* AlarmStatus: Alarm state always gets it's own line.
* Status1 is shared between help, battery status and generic unlock instructions,
* prioritized in that order.
* @param showStatusLines status lines are shown if true
*/
void updateStatusLines(boolean showStatusLines) {
if (DEBUG) Log.v(TAG, "updateStatusLines(" + showStatusLines + ")");
mShowingStatus = showStatusLines;
updateAlarmInfo();
updateOwnerInfo();
updateStatus1();
updateCarrierText();
}
private void updateAlarmInfo() {
if (mAlarmStatusView != null) {
String nextAlarm = mLockPatternUtils.getNextAlarm();
boolean showAlarm = mShowingStatus && !TextUtils.isEmpty(nextAlarm);
mAlarmStatusView.setText(nextAlarm);
mAlarmStatusView.setCompoundDrawablesWithIntrinsicBounds(ALARM_ICON, 0, 0, 0);
mAlarmStatusView.setVisibility(showAlarm ? View.VISIBLE : View.GONE);
}
}
private void updateOwnerInfo() {
final ContentResolver res = getContext().getContentResolver();
final boolean ownerInfoEnabled = Settings.Secure.getInt(res,
Settings.Secure.LOCK_SCREEN_OWNER_INFO_ENABLED, 1) != 0;
mOwnerInfoText = ownerInfoEnabled ?
Settings.Secure.getString(res, Settings.Secure.LOCK_SCREEN_OWNER_INFO) : null;
if (mOwnerInfoView != null) {
mOwnerInfoView.setText(mOwnerInfoText);
mOwnerInfoView.setVisibility(TextUtils.isEmpty(mOwnerInfoText) ? View.GONE:View.VISIBLE);
}
}
private void updateStatus1() {
if (mStatus1View != null) {
MutableInt icon = new MutableInt(0);
CharSequence string = getPriorityTextMessage(icon);
mStatus1View.setText(string);
mStatus1View.setCompoundDrawablesWithIntrinsicBounds(icon.value, 0, 0, 0);
mStatus1View.setVisibility(mShowingStatus ? View.VISIBLE : View.INVISIBLE);
}
}
private void updateCarrierText() {
if (!inWidgetMode() && mCarrierView != null) {
mCarrierView.setText(mCarrierText);
}
}
private CharSequence getAltTextMessage(MutableInt icon) {
// If we have replaced the status area with a single widget, then this code
// prioritizes what to show in that space when all transient messages are gone.
CharSequence string = null;
if (mShowingBatteryInfo) {
// Battery status
if (mPluggedIn) {
// Charging, charged or waiting to charge.
string = getContext().getString(mBatteryCharged ? R.string.lockscreen_charged
:R.string.lockscreen_plugged_in, mBatteryLevel);
icon.value = CHARGING_ICON;
} else if (mBatteryIsLow) {
// Battery is low
string = getContext().getString(R.string.lockscreen_low_battery);
icon.value = BATTERY_LOW_ICON;
}
} else {
string = mCarrierText;
}
return string;
}
private CharSequence getPriorityTextMessage(MutableInt icon) {
CharSequence string = null;
if (!TextUtils.isEmpty(mInstructionText)) {
// Instructions only
string = mInstructionText;
icon.value = LOCK_ICON;
} else if (mShowingBatteryInfo) {
// Battery status
if (mPluggedIn) {
// Charging, charged or waiting to charge.
string = getContext().getString(mBatteryCharged ? R.string.lockscreen_charged
:R.string.lockscreen_plugged_in, mBatteryLevel);
icon.value = CHARGING_ICON;
} else if (mBatteryIsLow) {
// Battery is low
string = getContext().getString(R.string.lockscreen_low_battery);
icon.value = BATTERY_LOW_ICON;
}
} else if (!inWidgetMode() && mOwnerInfoView == null && mOwnerInfoText != null) {
// OwnerInfo shows in status if we don't have a dedicated widget
string = mOwnerInfoText;
}
return string;
}
void refreshDate() {
if (mDateView != null) {
mDateView.setText(DateFormat.format(mDateFormatString, new Date()));
}
}
/**
* Determine the current status of the lock screen given the sim state and other stuff.
*/
public StatusMode getStatusForIccState(IccCardConstants.State simState) {
// Since reading the SIM may take a while, we assume it is present until told otherwise.
if (simState == null) {
return StatusMode.Normal;
}
final boolean missingAndNotProvisioned = (!mUpdateMonitor.isDeviceProvisioned()
&& (simState == IccCardConstants.State.ABSENT ||
simState == IccCardConstants.State.PERM_DISABLED));
// Assume we're NETWORK_LOCKED if not provisioned
simState = missingAndNotProvisioned ? IccCardConstants.State.NETWORK_LOCKED : simState;
switch (simState) {
case ABSENT:
return StatusMode.SimMissing;
case NETWORK_LOCKED:
return StatusMode.SimMissingLocked;
case NOT_READY:
return StatusMode.SimMissing;
case PIN_REQUIRED:
return StatusMode.SimLocked;
case PUK_REQUIRED:
return StatusMode.SimPukLocked;
case READY:
return StatusMode.Normal;
case PERM_DISABLED:
return StatusMode.SimPermDisabled;
case UNKNOWN:
return StatusMode.SimMissing;
}
return StatusMode.SimMissing;
}
private Context getContext() {
return mContainer.getContext();
}
/**
* Update carrier text, carrier help and emergency button to match the current status based
* on SIM state.
*
* @param simState
*/
private void updateCarrierStateWithSimStatus(IccCardConstants.State simState) {
if (DEBUG) Log.d(TAG, "updateCarrierTextWithSimStatus(), simState = " + simState);
CharSequence carrierText = null;
int carrierHelpTextId = 0;
mEmergencyButtonEnabledBecauseSimLocked = false;
mStatus = getStatusForIccState(simState);
mSimState = simState;
switch (mStatus) {
case Normal:
carrierText = makeCarierString(mPlmn, mSpn);
break;
case NetworkLocked:
carrierText = makeCarrierStringOnEmergencyCapable(
getContext().getText(R.string.lockscreen_network_locked_message),
mPlmn);
carrierHelpTextId = R.string.lockscreen_instructions_when_pattern_disabled;
break;
case SimMissing:
// Shows "No SIM card | Emergency calls only" on devices that are voice-capable.
// This depends on mPlmn containing the text "Emergency calls only" when the radio
// has some connectivity. Otherwise, it should be null or empty and just show
// "No SIM card"
carrierText = makeCarrierStringOnEmergencyCapable(
getContext().getText(R.string.lockscreen_missing_sim_message_short),
mPlmn);
carrierHelpTextId = R.string.lockscreen_missing_sim_instructions_long;
break;
case SimPermDisabled:
carrierText = getContext().getText(
R.string.lockscreen_permanent_disabled_sim_message_short);
carrierHelpTextId = R.string.lockscreen_permanent_disabled_sim_instructions;
mEmergencyButtonEnabledBecauseSimLocked = true;
break;
case SimMissingLocked:
carrierText = makeCarrierStringOnEmergencyCapable(
getContext().getText(R.string.lockscreen_missing_sim_message_short),
mPlmn);
carrierHelpTextId = R.string.lockscreen_missing_sim_instructions;
mEmergencyButtonEnabledBecauseSimLocked = true;
break;
case SimLocked:
carrierText = makeCarrierStringOnEmergencyCapable(
getContext().getText(R.string.lockscreen_sim_locked_message),
mPlmn);
mEmergencyButtonEnabledBecauseSimLocked = true;
break;
case SimPukLocked:
carrierText = makeCarrierStringOnEmergencyCapable(
getContext().getText(R.string.lockscreen_sim_puk_locked_message),
mPlmn);
if (!mLockPatternUtils.isPukUnlockScreenEnable()) {
// This means we're showing the PUK unlock screen
mEmergencyButtonEnabledBecauseSimLocked = true;
}
break;
}
setCarrierText(carrierText);
setCarrierHelpText(carrierHelpTextId);
updateEmergencyCallButtonState(mPhoneState);
}
/*
* Add emergencyCallMessage to carrier string only if phone supports emergency calls.
*/
private CharSequence makeCarrierStringOnEmergencyCapable(
CharSequence simMessage, CharSequence emergencyCallMessage) {
if (mLockPatternUtils.isEmergencyCallCapable()) {
return makeCarierString(simMessage, emergencyCallMessage);
}
return simMessage;
}
private View findViewById(int id) {
return mContainer.findViewById(id);
}
/**
* The status of this lock screen. Primarily used for widgets on LockScreen.
*/
enum StatusMode {
/**
* Normal case (sim card present, it's not locked)
*/
Normal(true),
/**
* The sim card is 'network locked'.
*/
NetworkLocked(true),
/**
* The sim card is missing.
*/
SimMissing(false),
/**
* The sim card is missing, and this is the device isn't provisioned, so we don't let
* them get past the screen.
*/
SimMissingLocked(false),
/**
* The sim card is PUK locked, meaning they've entered the wrong sim unlock code too many
* times.
*/
SimPukLocked(false),
/**
* The sim card is locked.
*/
SimLocked(true),
/**
* The sim card is permanently disabled due to puk unlock failure
*/
SimPermDisabled(false);
private final boolean mShowStatusLines;
StatusMode(boolean mShowStatusLines) {
this.mShowStatusLines = mShowStatusLines;
}
/**
* @return Whether the status lines (battery level and / or next alarm) are shown while
* in this state. Mostly dictated by whether this is room for them.
*/
public boolean shouldShowStatusLines() {
return mShowStatusLines;
}
}
private void updateEmergencyCallButtonState(int phoneState) {
if (mEmergencyCallButton != null) {
boolean enabledBecauseSimLocked =
mLockPatternUtils.isEmergencyCallEnabledWhileSimLocked()
&& mEmergencyButtonEnabledBecauseSimLocked;
boolean shown = mEmergencyCallButtonEnabledInScreen || enabledBecauseSimLocked;
mLockPatternUtils.updateEmergencyCallButtonState(mEmergencyCallButton,
phoneState, shown);
}
}
private KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() {
public void onRefreshBatteryInfo(KeyguardUpdateMonitor.BatteryStatus status) {
mShowingBatteryInfo = status.isPluggedIn() || status.isBatteryLow();
mPluggedIn = status.isPluggedIn();
mBatteryLevel = status.level;
mBatteryCharged = status.isCharged();
mBatteryIsLow = status.isBatteryLow();
final MutableInt tmpIcon = new MutableInt(0);
update(BATTERY_INFO, getAltTextMessage(tmpIcon));
}
@Override
public void onTimeChanged() {
refreshDate();
}
@Override
public void onRefreshCarrierInfo(CharSequence plmn, CharSequence spn) {
mPlmn = plmn;
mSpn = spn;
updateCarrierStateWithSimStatus(mSimState);
}
@Override
public void onPhoneStateChanged(int phoneState) {
mPhoneState = phoneState;
updateEmergencyCallButtonState(phoneState);
}
@Override
public void onSimStateChanged(IccCardConstants.State simState) {
updateCarrierStateWithSimStatus(simState);
}
};
public void onClick(View v) {
if (v == mEmergencyCallButton) {
mCallback.takeEmergencyCallAction();
}
}
/**
* Performs concentenation of PLMN/SPN
* @param plmn
* @param spn
* @return
*/
private static CharSequence makeCarierString(CharSequence plmn, CharSequence spn) {
final boolean plmnValid = !TextUtils.isEmpty(plmn);
final boolean spnValid = !TextUtils.isEmpty(spn);
if (plmnValid && spnValid) {
return plmn + "|" + spn;
} else if (plmnValid) {
return plmn;
} else if (spnValid) {
return spn;
} else {
return "";
}
}
}

View File

@@ -1,642 +0,0 @@
/*
* Copyright (C) 2008 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.internal.policy.impl.keyguard_obsolete;
import android.app.admin.DevicePolicyManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.ContentObserver;
import static android.os.BatteryManager.BATTERY_STATUS_FULL;
import static android.os.BatteryManager.BATTERY_STATUS_UNKNOWN;
import static android.os.BatteryManager.BATTERY_HEALTH_UNKNOWN;
import static android.os.BatteryManager.EXTRA_STATUS;
import static android.os.BatteryManager.EXTRA_PLUGGED;
import static android.os.BatteryManager.EXTRA_LEVEL;
import static android.os.BatteryManager.EXTRA_HEALTH;
import android.media.AudioManager;
import android.os.BatteryManager;
import android.os.Handler;
import android.os.Message;
import android.provider.Settings;
import com.android.internal.telephony.IccCardConstants;
import com.android.internal.telephony.TelephonyIntents;
import android.telephony.TelephonyManager;
import android.util.Log;
import com.android.internal.R;
import com.google.android.collect.Lists;
import java.util.ArrayList;
/**
* Watches for updates that may be interesting to the keyguard, and provides
* the up to date information as well as a registration for callbacks that care
* to be updated.
*
* Note: under time crunch, this has been extended to include some stuff that
* doesn't really belong here. see {@link #handleBatteryUpdate} where it shutdowns
* the device, and {@link #getFailedAttempts()}, {@link #reportFailedAttempt()}
* and {@link #clearFailedAttempts()}. Maybe we should rename this 'KeyguardContext'...
*/
public class KeyguardUpdateMonitor {
private static final String TAG = "KeyguardUpdateMonitor";
private static final boolean DEBUG = false;
private static final boolean DEBUG_SIM_STATES = DEBUG || false;
private static final int FAILED_BIOMETRIC_UNLOCK_ATTEMPTS_BEFORE_BACKUP = 3;
private static final int LOW_BATTERY_THRESHOLD = 20;
// Callback messages
private static final int MSG_TIME_UPDATE = 301;
private static final int MSG_BATTERY_UPDATE = 302;
private static final int MSG_CARRIER_INFO_UPDATE = 303;
private static final int MSG_SIM_STATE_CHANGE = 304;
private static final int MSG_RINGER_MODE_CHANGED = 305;
private static final int MSG_PHONE_STATE_CHANGED = 306;
private static final int MSG_CLOCK_VISIBILITY_CHANGED = 307;
private static final int MSG_DEVICE_PROVISIONED = 308;
protected static final int MSG_DPM_STATE_CHANGED = 309;
protected static final int MSG_USER_SWITCHED = 310;
protected static final int MSG_USER_REMOVED = 311;
private final Context mContext;
// Telephony state
private IccCardConstants.State mSimState = IccCardConstants.State.READY;
private CharSequence mTelephonyPlmn;
private CharSequence mTelephonySpn;
private int mRingMode;
private int mPhoneState;
private boolean mDeviceProvisioned;
private BatteryStatus mBatteryStatus;
private int mFailedAttempts = 0;
private int mFailedBiometricUnlockAttempts = 0;
private boolean mClockVisible;
private ArrayList<KeyguardUpdateMonitorCallback> mCallbacks = Lists.newArrayList();
private ContentObserver mContentObserver;
private final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_TIME_UPDATE:
handleTimeUpdate();
break;
case MSG_BATTERY_UPDATE:
handleBatteryUpdate((BatteryStatus) msg.obj);
break;
case MSG_CARRIER_INFO_UPDATE:
handleCarrierInfoUpdate();
break;
case MSG_SIM_STATE_CHANGE:
handleSimStateChange((SimArgs) msg.obj);
break;
case MSG_RINGER_MODE_CHANGED:
handleRingerModeChange(msg.arg1);
break;
case MSG_PHONE_STATE_CHANGED:
handlePhoneStateChanged((String)msg.obj);
break;
case MSG_CLOCK_VISIBILITY_CHANGED:
handleClockVisibilityChanged();
break;
case MSG_DEVICE_PROVISIONED:
handleDeviceProvisioned();
break;
case MSG_DPM_STATE_CHANGED:
handleDevicePolicyManagerStateChanged();
break;
case MSG_USER_SWITCHED:
handleUserSwitched(msg.arg1);
break;
case MSG_USER_REMOVED:
handleUserRemoved(msg.arg1);
break;
}
}
};
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (DEBUG) Log.d(TAG, "received broadcast " + action);
if (Intent.ACTION_TIME_TICK.equals(action)
|| Intent.ACTION_TIME_CHANGED.equals(action)
|| Intent.ACTION_TIMEZONE_CHANGED.equals(action)) {
mHandler.sendMessage(mHandler.obtainMessage(MSG_TIME_UPDATE));
} else if (TelephonyIntents.SPN_STRINGS_UPDATED_ACTION.equals(action)) {
mTelephonyPlmn = getTelephonyPlmnFrom(intent);
mTelephonySpn = getTelephonySpnFrom(intent);
mHandler.sendMessage(mHandler.obtainMessage(MSG_CARRIER_INFO_UPDATE));
} else if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
final int status = intent.getIntExtra(EXTRA_STATUS, BATTERY_STATUS_UNKNOWN);
final int plugged = intent.getIntExtra(EXTRA_PLUGGED, 0);
final int level = intent.getIntExtra(EXTRA_LEVEL, 0);
final int health = intent.getIntExtra(EXTRA_HEALTH, BATTERY_HEALTH_UNKNOWN);
final Message msg = mHandler.obtainMessage(
MSG_BATTERY_UPDATE, new BatteryStatus(status, level, plugged, health));
mHandler.sendMessage(msg);
} else if (TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(action)) {
if (DEBUG_SIM_STATES) {
Log.v(TAG, "action " + action + " state" +
intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE));
}
mHandler.sendMessage(mHandler.obtainMessage(
MSG_SIM_STATE_CHANGE, SimArgs.fromIntent(intent)));
} else if (AudioManager.RINGER_MODE_CHANGED_ACTION.equals(action)) {
mHandler.sendMessage(mHandler.obtainMessage(MSG_RINGER_MODE_CHANGED,
intent.getIntExtra(AudioManager.EXTRA_RINGER_MODE, -1), 0));
} else if (TelephonyManager.ACTION_PHONE_STATE_CHANGED.equals(action)) {
String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
mHandler.sendMessage(mHandler.obtainMessage(MSG_PHONE_STATE_CHANGED, state));
} else if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED
.equals(action)) {
mHandler.sendMessage(mHandler.obtainMessage(MSG_DPM_STATE_CHANGED));
} else if (Intent.ACTION_USER_SWITCHED.equals(action)) {
mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCHED,
intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0), 0));
} else if (Intent.ACTION_USER_REMOVED.equals(action)) {
mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_REMOVED,
intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0), 0));
}
}
};
/**
* When we receive a
* {@link com.android.internal.telephony.TelephonyIntents#ACTION_SIM_STATE_CHANGED} broadcast,
* and then pass a result via our handler to {@link KeyguardUpdateMonitor#handleSimStateChange},
* we need a single object to pass to the handler. This class helps decode
* the intent and provide a {@link SimCard.State} result.
*/
private static class SimArgs {
public final IccCardConstants.State simState;
SimArgs(IccCardConstants.State state) {
simState = state;
}
static SimArgs fromIntent(Intent intent) {
IccCardConstants.State state;
if (!TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(intent.getAction())) {
throw new IllegalArgumentException("only handles intent ACTION_SIM_STATE_CHANGED");
}
String stateExtra = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
final String absentReason = intent
.getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
if (IccCardConstants.INTENT_VALUE_ABSENT_ON_PERM_DISABLED.equals(
absentReason)) {
state = IccCardConstants.State.PERM_DISABLED;
} else {
state = IccCardConstants.State.ABSENT;
}
} else if (IccCardConstants.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
state = IccCardConstants.State.READY;
} else if (IccCardConstants.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
final String lockedReason = intent
.getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {
state = IccCardConstants.State.PIN_REQUIRED;
} else if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
state = IccCardConstants.State.PUK_REQUIRED;
} else {
state = IccCardConstants.State.UNKNOWN;
}
} else if (IccCardConstants.INTENT_VALUE_LOCKED_NETWORK.equals(stateExtra)) {
state = IccCardConstants.State.NETWORK_LOCKED;
} else {
state = IccCardConstants.State.UNKNOWN;
}
return new SimArgs(state);
}
public String toString() {
return simState.toString();
}
}
/* package */ static class BatteryStatus {
public final int status;
public final int level;
public final int plugged;
public final int health;
public BatteryStatus(int status, int level, int plugged, int health) {
this.status = status;
this.level = level;
this.plugged = plugged;
this.health = health;
}
/**
* Determine whether the device is plugged in (USB or power).
* @return true if the device is plugged in.
*/
boolean isPluggedIn() {
return plugged == BatteryManager.BATTERY_PLUGGED_AC
|| plugged == BatteryManager.BATTERY_PLUGGED_USB
|| plugged == BatteryManager.BATTERY_PLUGGED_WIRELESS;
}
/**
* Whether or not the device is charged. Note that some devices never return 100% for
* battery level, so this allows either battery level or status to determine if the
* battery is charged.
* @return true if the device is charged
*/
public boolean isCharged() {
return status == BATTERY_STATUS_FULL || level >= 100;
}
/**
* Whether battery is low and needs to be charged.
* @return true if battery is low
*/
public boolean isBatteryLow() {
return level < LOW_BATTERY_THRESHOLD;
}
}
public KeyguardUpdateMonitor(Context context) {
mContext = context;
mDeviceProvisioned = Settings.Global.getInt(
mContext.getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 0) != 0;
// Since device can't be un-provisioned, we only need to register a content observer
// to update mDeviceProvisioned when we are...
if (!mDeviceProvisioned) {
watchForDeviceProvisioning();
}
// Take a guess at initial SIM state, battery status and PLMN until we get an update
mSimState = IccCardConstants.State.NOT_READY;
mBatteryStatus = new BatteryStatus(BATTERY_STATUS_UNKNOWN, 100, 0, 0);
mTelephonyPlmn = getDefaultPlmn();
// Watch for interesting updates
final IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_TIME_TICK);
filter.addAction(Intent.ACTION_TIME_CHANGED);
filter.addAction(Intent.ACTION_BATTERY_CHANGED);
filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
filter.addAction(TelephonyIntents.SPN_STRINGS_UPDATED_ACTION);
filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
filter.addAction(Intent.ACTION_USER_SWITCHED);
filter.addAction(Intent.ACTION_USER_REMOVED);
context.registerReceiver(mBroadcastReceiver, filter);
}
private void watchForDeviceProvisioning() {
mContentObserver = new ContentObserver(mHandler) {
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
mDeviceProvisioned = Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.DEVICE_PROVISIONED, 0) != 0;
if (mDeviceProvisioned) {
mHandler.sendMessage(mHandler.obtainMessage(MSG_DEVICE_PROVISIONED));
}
if (DEBUG) Log.d(TAG, "DEVICE_PROVISIONED state = " + mDeviceProvisioned);
}
};
mContext.getContentResolver().registerContentObserver(
Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED),
false, mContentObserver);
// prevent a race condition between where we check the flag and where we register the
// observer by grabbing the value once again...
boolean provisioned = Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.DEVICE_PROVISIONED, 0) != 0;
if (provisioned != mDeviceProvisioned) {
mDeviceProvisioned = provisioned;
if (mDeviceProvisioned) {
mHandler.sendMessage(mHandler.obtainMessage(MSG_DEVICE_PROVISIONED));
}
}
}
/**
* Handle {@link #MSG_DPM_STATE_CHANGED}
*/
protected void handleDevicePolicyManagerStateChanged() {
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).onDevicePolicyManagerStateChanged();
}
}
/**
* Handle {@link #MSG_USER_SWITCHED}
*/
protected void handleUserSwitched(int userId) {
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).onUserSwitched(userId);
}
}
/**
* Handle {@link #MSG_USER_SWITCHED}
*/
protected void handleUserRemoved(int userId) {
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).onUserRemoved(userId);
}
}
/**
* Handle {@link #MSG_DEVICE_PROVISIONED}
*/
protected void handleDeviceProvisioned() {
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).onDeviceProvisioned();
}
if (mContentObserver != null) {
// We don't need the observer anymore...
mContext.getContentResolver().unregisterContentObserver(mContentObserver);
mContentObserver = null;
}
}
/**
* Handle {@link #MSG_PHONE_STATE_CHANGED}
*/
protected void handlePhoneStateChanged(String newState) {
if (DEBUG) Log.d(TAG, "handlePhoneStateChanged(" + newState + ")");
if (TelephonyManager.EXTRA_STATE_IDLE.equals(newState)) {
mPhoneState = TelephonyManager.CALL_STATE_IDLE;
} else if (TelephonyManager.EXTRA_STATE_OFFHOOK.equals(newState)) {
mPhoneState = TelephonyManager.CALL_STATE_OFFHOOK;
} else if (TelephonyManager.EXTRA_STATE_RINGING.equals(newState)) {
mPhoneState = TelephonyManager.CALL_STATE_RINGING;
}
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).onPhoneStateChanged(mPhoneState);
}
}
/**
* Handle {@link #MSG_RINGER_MODE_CHANGED}
*/
protected void handleRingerModeChange(int mode) {
if (DEBUG) Log.d(TAG, "handleRingerModeChange(" + mode + ")");
mRingMode = mode;
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).onRingerModeChanged(mode);
}
}
/**
* Handle {@link #MSG_TIME_UPDATE}
*/
private void handleTimeUpdate() {
if (DEBUG) Log.d(TAG, "handleTimeUpdate");
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).onTimeChanged();
}
}
/**
* Handle {@link #MSG_BATTERY_UPDATE}
*/
private void handleBatteryUpdate(BatteryStatus status) {
if (DEBUG) Log.d(TAG, "handleBatteryUpdate");
final boolean batteryUpdateInteresting = isBatteryUpdateInteresting(mBatteryStatus, status);
mBatteryStatus = status;
if (batteryUpdateInteresting) {
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).onRefreshBatteryInfo(status);
}
}
}
/**
* Handle {@link #MSG_CARRIER_INFO_UPDATE}
*/
private void handleCarrierInfoUpdate() {
if (DEBUG) Log.d(TAG, "handleCarrierInfoUpdate: plmn = " + mTelephonyPlmn
+ ", spn = " + mTelephonySpn);
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).onRefreshCarrierInfo(mTelephonyPlmn, mTelephonySpn);
}
}
/**
* Handle {@link #MSG_SIM_STATE_CHANGE}
*/
private void handleSimStateChange(SimArgs simArgs) {
final IccCardConstants.State state = simArgs.simState;
if (DEBUG) {
Log.d(TAG, "handleSimStateChange: intentValue = " + simArgs + " "
+ "state resolved to " + state.toString());
}
if (state != IccCardConstants.State.UNKNOWN && state != mSimState) {
mSimState = state;
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).onSimStateChanged(state);
}
}
}
/**
* Handle {@link #MSG_CLOCK_VISIBILITY_CHANGED}
*/
private void handleClockVisibilityChanged() {
if (DEBUG) Log.d(TAG, "handleClockVisibilityChanged()");
for (int i = 0; i < mCallbacks.size(); i++) {
mCallbacks.get(i).onClockVisibilityChanged();
}
}
private static boolean isBatteryUpdateInteresting(BatteryStatus old, BatteryStatus current) {
final boolean nowPluggedIn = current.isPluggedIn();
final boolean wasPluggedIn = old.isPluggedIn();
final boolean stateChangedWhilePluggedIn =
wasPluggedIn == true && nowPluggedIn == true
&& (old.status != current.status);
// change in plug state is always interesting
if (wasPluggedIn != nowPluggedIn || stateChangedWhilePluggedIn) {
return true;
}
// change in battery level while plugged in
if (nowPluggedIn && old.level != current.level) {
return true;
}
// change where battery needs charging
if (!nowPluggedIn && current.isBatteryLow() && current.level != old.level) {
return true;
}
return false;
}
/**
* @param intent The intent with action {@link TelephonyIntents#SPN_STRINGS_UPDATED_ACTION}
* @return The string to use for the plmn, or null if it should not be shown.
*/
private CharSequence getTelephonyPlmnFrom(Intent intent) {
if (intent.getBooleanExtra(TelephonyIntents.EXTRA_SHOW_PLMN, false)) {
final String plmn = intent.getStringExtra(TelephonyIntents.EXTRA_PLMN);
return (plmn != null) ? plmn : getDefaultPlmn();
}
return null;
}
/**
* @return The default plmn (no service)
*/
private CharSequence getDefaultPlmn() {
return mContext.getResources().getText(R.string.lockscreen_carrier_default);
}
/**
* @param intent The intent with action {@link Telephony.Intents#SPN_STRINGS_UPDATED_ACTION}
* @return The string to use for the plmn, or null if it should not be shown.
*/
private CharSequence getTelephonySpnFrom(Intent intent) {
if (intent.getBooleanExtra(TelephonyIntents.EXTRA_SHOW_SPN, false)) {
final String spn = intent.getStringExtra(TelephonyIntents.EXTRA_SPN);
if (spn != null) {
return spn;
}
}
return null;
}
/**
* Remove the given observer's callback.
*
* @param observer The observer to remove
*/
public void removeCallback(Object observer) {
mCallbacks.remove(observer);
}
/**
* Register to receive notifications about general keyguard information
* (see {@link InfoCallback}.
* @param callback The callback.
*/
public void registerCallback(KeyguardUpdateMonitorCallback callback) {
if (!mCallbacks.contains(callback)) {
mCallbacks.add(callback);
// Notify listener of the current state
callback.onRefreshBatteryInfo(mBatteryStatus);
callback.onTimeChanged();
callback.onRingerModeChanged(mRingMode);
callback.onPhoneStateChanged(mPhoneState);
callback.onRefreshCarrierInfo(mTelephonyPlmn, mTelephonySpn);
callback.onClockVisibilityChanged();
callback.onSimStateChanged(mSimState);
} else {
if (DEBUG) Log.e(TAG, "Object tried to add another callback",
new Exception("Called by"));
}
}
public void reportClockVisible(boolean visible) {
mClockVisible = visible;
mHandler.obtainMessage(MSG_CLOCK_VISIBILITY_CHANGED).sendToTarget();
}
public IccCardConstants.State getSimState() {
return mSimState;
}
/**
* Report that the user successfully entered the SIM PIN or PUK/SIM PIN so we
* have the information earlier than waiting for the intent
* broadcast from the telephony code.
*
* NOTE: Because handleSimStateChange() invokes callbacks immediately without going
* through mHandler, this *must* be called from the UI thread.
*/
public void reportSimUnlocked() {
handleSimStateChange(new SimArgs(IccCardConstants.State.READY));
}
public CharSequence getTelephonyPlmn() {
return mTelephonyPlmn;
}
public CharSequence getTelephonySpn() {
return mTelephonySpn;
}
/**
* @return Whether the device is provisioned (whether they have gone through
* the setup wizard)
*/
public boolean isDeviceProvisioned() {
return mDeviceProvisioned;
}
public int getFailedAttempts() {
return mFailedAttempts;
}
public void clearFailedAttempts() {
mFailedAttempts = 0;
mFailedBiometricUnlockAttempts = 0;
}
public void reportFailedAttempt() {
mFailedAttempts++;
}
public boolean isClockVisible() {
return mClockVisible;
}
public int getPhoneState() {
return mPhoneState;
}
public void reportFailedBiometricUnlockAttempt() {
mFailedBiometricUnlockAttempts++;
}
public boolean getMaxBiometricUnlockAttemptsReached() {
return mFailedBiometricUnlockAttempts >= FAILED_BIOMETRIC_UNLOCK_ATTEMPTS_BEFORE_BACKUP;
}
public boolean isSimLocked() {
return mSimState == IccCardConstants.State.PIN_REQUIRED
|| mSimState == IccCardConstants.State.PUK_REQUIRED
|| mSimState == IccCardConstants.State.PERM_DISABLED;
}
}

View File

@@ -1,96 +0,0 @@
/*
* 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.internal.policy.impl.keyguard_obsolete;
import android.app.admin.DevicePolicyManager;
import android.media.AudioManager;
import com.android.internal.telephony.IccCardConstants;
/**
* Callback for general information relevant to lock screen.
*/
class KeyguardUpdateMonitorCallback {
/**
* Called when the battery status changes, e.g. when plugged in or unplugged, charge
* level, etc. changes.
*
* @param status current battery status
*/
void onRefreshBatteryInfo(KeyguardUpdateMonitor.BatteryStatus status) { }
/**
* Called once per minute or when the time changes.
*/
void onTimeChanged() { }
/**
* Called when the carrier PLMN or SPN changes.
*
* @param plmn The operator name of the registered network. May be null if it shouldn't
* be displayed.
* @param spn The service provider name. May be null if it shouldn't be displayed.
*/
void onRefreshCarrierInfo(CharSequence plmn, CharSequence spn) { }
/**
* Called when the ringer mode changes.
* @param state the current ringer state, as defined in
* {@link AudioManager#RINGER_MODE_CHANGED_ACTION}
*/
void onRingerModeChanged(int state) { }
/**
* Called when the phone state changes. String will be one of:
* {@link TelephonyManager#EXTRA_STATE_IDLE}
* {@link TelephonyManager@EXTRA_STATE_RINGING}
* {@link TelephonyManager#EXTRA_STATE_OFFHOOK
*/
void onPhoneStateChanged(int phoneState) { }
/**
* Called when visibility of lockscreen clock changes, such as when
* obscured by a widget.
*/
void onClockVisibilityChanged() { }
/**
* Called when the device becomes provisioned
*/
void onDeviceProvisioned() { }
/**
* Called when the device policy changes.
* See {@link DevicePolicyManager#ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED}
*/
void onDevicePolicyManagerStateChanged() { }
/**
* Called when the user changes.
*/
void onUserSwitched(int userId) { }
/**
* Called when the SIM state changes.
* @param simState
*/
void onSimStateChanged(IccCardConstants.State simState) { }
/**
* Called when a user is removed.
*/
void onUserRemoved(int userId) { }
}

View File

@@ -1,270 +0,0 @@
/*
* Copyright (C) 2007 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.internal.policy.impl.keyguard_obsolete;
import android.content.Context;
import android.content.Intent;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.media.AudioManager;
import android.media.IAudioService;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.telephony.TelephonyManager;
import android.view.KeyEvent;
import android.view.View;
import android.view.Gravity;
import android.widget.FrameLayout;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Slog;
/**
* Base class for keyguard views. {@link #reset} is where you should
* reset the state of your view. Use the {@link KeyguardViewCallback} via
* {@link #getCallback()} to send information back (such as poking the wake lock,
* or finishing the keyguard).
*
* Handles intercepting of media keys that still work when the keyguard is
* showing.
*/
public abstract class KeyguardViewBase extends FrameLayout {
private static final int BACKGROUND_COLOR = 0x70000000;
private KeyguardViewCallback mCallback;
private AudioManager mAudioManager;
private TelephonyManager mTelephonyManager = null;
// Whether the volume keys should be handled by keyguard. If true, then
// they will be handled here for specific media types such as music, otherwise
// the audio service will bring up the volume dialog.
private static final boolean KEYGUARD_MANAGES_VOLUME = true;
// This is a faster way to draw the background on devices without hardware acceleration
Drawable mBackgroundDrawable = new Drawable() {
@Override
public void draw(Canvas canvas) {
canvas.drawColor(BACKGROUND_COLOR, PorterDuff.Mode.SRC);
}
@Override
public void setAlpha(int alpha) {
}
@Override
public void setColorFilter(ColorFilter cf) {
}
@Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
};
public KeyguardViewBase(Context context, KeyguardViewCallback callback) {
super(context);
mCallback = callback;
resetBackground();
}
public void resetBackground() {
setBackgroundDrawable(mBackgroundDrawable);
}
public KeyguardViewCallback getCallback() {
return mCallback;
}
/**
* Called when you need to reset the state of your view.
*/
abstract public void reset();
/**
* Called when the screen turned off.
*/
abstract public void onScreenTurnedOff();
/**
* Called when the screen turned on.
*/
abstract public void onScreenTurnedOn();
/**
* Called when the view needs to be shown.
*/
abstract public void show();
/**
* Called when a key has woken the device to give us a chance to adjust our
* state according the the key. We are responsible for waking the device
* (by poking the wake lock) once we are ready.
*
* The 'Tq' suffix is per the documentation in {@link android.view.WindowManagerPolicy}.
* Be sure not to take any action that takes a long time; any significant
* action should be posted to a handler.
*
* @param keyCode The wake key, which may be relevant for configuring the
* keyguard. May be {@link KeyEvent#KEYCODE_UNKNOWN} if waking for a reason
* other than a key press.
*/
abstract public void wakeWhenReadyTq(int keyCode);
/**
* Verify that the user can get past the keyguard securely. This is called,
* for example, when the phone disables the keyguard but then wants to launch
* something else that requires secure access.
*
* The result will be propogated back via {@link KeyguardViewCallback#keyguardDone(boolean)}
*/
abstract public void verifyUnlock();
/**
* Called before this view is being removed.
*/
abstract public void cleanUp();
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (shouldEventKeepScreenOnWhileKeyguardShowing(event)) {
mCallback.pokeWakelock();
}
if (interceptMediaKey(event)) {
return true;
}
return super.dispatchKeyEvent(event);
}
private boolean shouldEventKeepScreenOnWhileKeyguardShowing(KeyEvent event) {
if (event.getAction() != KeyEvent.ACTION_DOWN) {
return false;
}
switch (event.getKeyCode()) {
case KeyEvent.KEYCODE_DPAD_DOWN:
case KeyEvent.KEYCODE_DPAD_LEFT:
case KeyEvent.KEYCODE_DPAD_RIGHT:
case KeyEvent.KEYCODE_DPAD_UP:
return false;
default:
return true;
}
}
/**
* Allows the media keys to work when the keyguard is showing.
* The media keys should be of no interest to the actual keyguard view(s),
* so intercepting them here should not be of any harm.
* @param event The key event
* @return whether the event was consumed as a media key.
*/
private boolean interceptMediaKey(KeyEvent event) {
final int keyCode = event.getKeyCode();
if (event.getAction() == KeyEvent.ACTION_DOWN) {
switch (keyCode) {
case KeyEvent.KEYCODE_MEDIA_PLAY:
case KeyEvent.KEYCODE_MEDIA_PAUSE:
case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
/* Suppress PLAY/PAUSE toggle when phone is ringing or
* in-call to avoid music playback */
if (mTelephonyManager == null) {
mTelephonyManager = (TelephonyManager) getContext().getSystemService(
Context.TELEPHONY_SERVICE);
}
if (mTelephonyManager != null &&
mTelephonyManager.getCallState() != TelephonyManager.CALL_STATE_IDLE) {
return true; // suppress key event
}
case KeyEvent.KEYCODE_MUTE:
case KeyEvent.KEYCODE_HEADSETHOOK:
case KeyEvent.KEYCODE_MEDIA_STOP:
case KeyEvent.KEYCODE_MEDIA_NEXT:
case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
case KeyEvent.KEYCODE_MEDIA_REWIND:
case KeyEvent.KEYCODE_MEDIA_RECORD:
case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD: {
handleMediaKeyEvent(event);
return true;
}
case KeyEvent.KEYCODE_VOLUME_UP:
case KeyEvent.KEYCODE_VOLUME_DOWN:
case KeyEvent.KEYCODE_VOLUME_MUTE: {
if (KEYGUARD_MANAGES_VOLUME) {
synchronized (this) {
if (mAudioManager == null) {
mAudioManager = (AudioManager) getContext().getSystemService(
Context.AUDIO_SERVICE);
}
}
// Volume buttons should only function for music (local or remote).
// TODO: Actually handle MUTE.
mAudioManager.adjustLocalOrRemoteStreamVolume(
AudioManager.STREAM_MUSIC,
keyCode == KeyEvent.KEYCODE_VOLUME_UP
? AudioManager.ADJUST_RAISE
: AudioManager.ADJUST_LOWER);
// Don't execute default volume behavior
return true;
} else {
return false;
}
}
}
} else if (event.getAction() == KeyEvent.ACTION_UP) {
switch (keyCode) {
case KeyEvent.KEYCODE_MUTE:
case KeyEvent.KEYCODE_HEADSETHOOK:
case KeyEvent.KEYCODE_MEDIA_PLAY:
case KeyEvent.KEYCODE_MEDIA_PAUSE:
case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
case KeyEvent.KEYCODE_MEDIA_STOP:
case KeyEvent.KEYCODE_MEDIA_NEXT:
case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
case KeyEvent.KEYCODE_MEDIA_REWIND:
case KeyEvent.KEYCODE_MEDIA_RECORD:
case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD: {
handleMediaKeyEvent(event);
return true;
}
}
}
return false;
}
void handleMediaKeyEvent(KeyEvent keyEvent) {
IAudioService audioService = IAudioService.Stub.asInterface(
ServiceManager.checkService(Context.AUDIO_SERVICE));
if (audioService != null) {
try {
audioService.dispatchMediaKeyEvent(keyEvent);
} catch (RemoteException e) {
Log.e("KeyguardViewBase", "dispatchMediaKeyEvent threw exception " + e);
}
} else {
Slog.w("KeyguardViewBase", "Unable to find IAudioService for media key event");
}
}
@Override
public void dispatchSystemUiVisibilityChanged(int visibility) {
super.dispatchSystemUiVisibilityChanged(visibility);
setSystemUiVisibility(STATUS_BAR_DISABLE_BACK);
}
}

View File

@@ -1,49 +0,0 @@
/*
* Copyright (C) 2007 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.internal.policy.impl.keyguard_obsolete;
/**
* The callback used by the keyguard view to tell the {@link KeyguardViewMediator}
* various things.
*/
public interface KeyguardViewCallback {
/**
* Request the wakelock to be poked for the default amount of time.
*/
void pokeWakelock();
/**
* Request the wakelock to be poked for a specific amount of time.
* @param millis The amount of time in millis.
*/
void pokeWakelock(int millis);
/**
* Report that the keyguard is done.
* @param authenticated Whether the user securely got past the keyguard.
* the only reason for this to be false is if the keyguard was instructed
* to appear temporarily to verify the user is supposed to get past the
* keyguard, and the user fails to do so.
*/
void keyguardDone(boolean authenticated);
/**
* Report that the keyguard is done drawing.
*/
void keyguardDoneDrawing();
}

View File

@@ -1,309 +0,0 @@
/*
* Copyright (C) 2007 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.internal.policy.impl.keyguard_obsolete;
import com.android.internal.R;
import android.app.ActivityManager;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.res.Resources;
import android.graphics.PixelFormat;
import android.graphics.Canvas;
import android.os.IBinder;
import android.os.SystemProperties;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewManager;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.graphics.Color;
/**
* Manages creating, showing, hiding and resetting the keyguard. Calls back
* via {@link com.android.internal.policy.impl.KeyguardViewCallback} to poke
* the wake lock and report that the keyguard is done, which is in turn,
* reported to this class by the current {@link KeyguardViewBase}.
*/
public class KeyguardViewManager implements KeyguardWindowController {
private final static boolean DEBUG = false;
private static String TAG = "KeyguardViewManager";
private final Context mContext;
private final ViewManager mViewManager;
private final KeyguardViewCallback mCallback;
private final KeyguardViewProperties mKeyguardViewProperties;
private final KeyguardUpdateMonitor mUpdateMonitor;
private WindowManager.LayoutParams mWindowLayoutParams;
private boolean mNeedsInput = false;
private FrameLayout mKeyguardHost;
private KeyguardViewBase mKeyguardView;
private boolean mScreenOn = false;
public interface ShowListener {
void onShown(IBinder windowToken);
};
/**
* @param context Used to create views.
* @param viewManager Keyguard will be attached to this.
* @param callback Used to notify of changes.
*/
public KeyguardViewManager(Context context, ViewManager viewManager,
KeyguardViewCallback callback, KeyguardViewProperties keyguardViewProperties,
KeyguardUpdateMonitor updateMonitor) {
mContext = context;
mViewManager = viewManager;
mCallback = callback;
mKeyguardViewProperties = keyguardViewProperties;
mUpdateMonitor = updateMonitor;
}
/**
* Helper class to host the keyguard view.
*/
private static class KeyguardViewHost extends FrameLayout {
private final KeyguardViewCallback mCallback;
private KeyguardViewHost(Context context, KeyguardViewCallback callback) {
super(context);
mCallback = callback;
}
@Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
mCallback.keyguardDoneDrawing();
}
}
/**
* Show the keyguard. Will handle creating and attaching to the view manager
* lazily.
*/
public synchronized void show() {
if (DEBUG) Log.d(TAG, "show(); mKeyguardView==" + mKeyguardView);
Resources res = mContext.getResources();
boolean enableScreenRotation =
SystemProperties.getBoolean("lockscreen.rot_override",false)
|| res.getBoolean(R.bool.config_enableLockScreenRotation);
if (mKeyguardHost == null) {
if (DEBUG) Log.d(TAG, "keyguard host is null, creating it...");
mKeyguardHost = new KeyguardViewHost(mContext, mCallback);
final int stretch = ViewGroup.LayoutParams.MATCH_PARENT;
int flags = WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN
| WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER
| WindowManager.LayoutParams.FLAG_SLIPPERY
/*| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
| WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR*/ ;
if (!mNeedsInput) {
flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
}
if (ActivityManager.isHighEndGfx()) {
flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
}
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
stretch, stretch, WindowManager.LayoutParams.TYPE_KEYGUARD,
flags, PixelFormat.TRANSLUCENT);
lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
lp.windowAnimations = com.android.internal.R.style.Animation_LockScreen;
if (ActivityManager.isHighEndGfx()) {
lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
lp.privateFlags |=
WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_HARDWARE_ACCELERATED;
}
lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SET_NEEDS_MENU_KEY;
lp.setTitle("Keyguard");
mWindowLayoutParams = lp;
mViewManager.addView(mKeyguardHost, lp);
}
if (enableScreenRotation) {
if (DEBUG) Log.d(TAG, "Rotation sensor for lock screen On!");
mWindowLayoutParams.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_USER;
} else {
if (DEBUG) Log.d(TAG, "Rotation sensor for lock screen Off!");
mWindowLayoutParams.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
}
mViewManager.updateViewLayout(mKeyguardHost, mWindowLayoutParams);
if (mKeyguardView == null) {
if (DEBUG) Log.d(TAG, "keyguard view is null, creating it...");
mKeyguardView = mKeyguardViewProperties.createKeyguardView(mContext, mCallback,
mUpdateMonitor, this);
mKeyguardView.setId(R.id.lock_screen);
final ViewGroup.LayoutParams lp = new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
mKeyguardHost.addView(mKeyguardView, lp);
if (mScreenOn) {
mKeyguardView.show();
}
}
// Disable aspects of the system/status/navigation bars that are not appropriate or
// useful for the lockscreen but can be re-shown by dialogs or SHOW_WHEN_LOCKED activities.
// Other disabled bits are handled by the KeyguardViewMediator talking directly to the
// status bar service.
int visFlags =
( View.STATUS_BAR_DISABLE_BACK
| View.STATUS_BAR_DISABLE_HOME
);
Log.v(TAG, "KGVM: Set visibility on " + mKeyguardHost + " to " + visFlags);
mKeyguardHost.setSystemUiVisibility(visFlags);
mViewManager.updateViewLayout(mKeyguardHost, mWindowLayoutParams);
mKeyguardHost.setVisibility(View.VISIBLE);
mKeyguardView.requestFocus();
}
public void setNeedsInput(boolean needsInput) {
mNeedsInput = needsInput;
if (mWindowLayoutParams != null) {
if (needsInput) {
mWindowLayoutParams.flags &=
~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
} else {
mWindowLayoutParams.flags |=
WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
}
mViewManager.updateViewLayout(mKeyguardHost, mWindowLayoutParams);
}
}
/**
* Reset the state of the view.
*/
public synchronized void reset() {
if (DEBUG) Log.d(TAG, "reset()");
if (mKeyguardView != null) {
mKeyguardView.reset();
}
}
public synchronized void onScreenTurnedOff() {
if (DEBUG) Log.d(TAG, "onScreenTurnedOff()");
mScreenOn = false;
if (mKeyguardView != null) {
mKeyguardView.onScreenTurnedOff();
}
}
public synchronized void onScreenTurnedOn(
final KeyguardViewManager.ShowListener showListener) {
if (DEBUG) Log.d(TAG, "onScreenTurnedOn()");
mScreenOn = true;
if (mKeyguardView != null) {
mKeyguardView.onScreenTurnedOn();
// Caller should wait for this window to be shown before turning
// on the screen.
if (mKeyguardHost.getVisibility() == View.VISIBLE) {
// Keyguard may be in the process of being shown, but not yet
// updated with the window manager... give it a chance to do so.
mKeyguardHost.post(new Runnable() {
public void run() {
if (mKeyguardHost.getVisibility() == View.VISIBLE) {
showListener.onShown(mKeyguardHost.getWindowToken());
} else {
showListener.onShown(null);
}
}
});
} else {
showListener.onShown(null);
}
} else {
showListener.onShown(null);
}
}
public synchronized void verifyUnlock() {
if (DEBUG) Log.d(TAG, "verifyUnlock()");
show();
mKeyguardView.verifyUnlock();
}
/**
* A key has woken the device. We use this to potentially adjust the state
* of the lock screen based on the key.
*
* The 'Tq' suffix is per the documentation in {@link android.view.WindowManagerPolicy}.
* Be sure not to take any action that takes a long time; any significant
* action should be posted to a handler.
*
* @param keyCode The wake key. May be {@link KeyEvent#KEYCODE_UNKNOWN} if waking
* for a reason other than a key press.
*/
public boolean wakeWhenReadyTq(int keyCode) {
if (DEBUG) Log.d(TAG, "wakeWhenReady(" + keyCode + ")");
if (mKeyguardView != null) {
mKeyguardView.wakeWhenReadyTq(keyCode);
return true;
} else {
Log.w(TAG, "mKeyguardView is null in wakeWhenReadyTq");
return false;
}
}
/**
* Hides the keyguard view
*/
public synchronized void hide() {
if (DEBUG) Log.d(TAG, "hide()");
if (mKeyguardHost != null) {
mKeyguardHost.setVisibility(View.GONE);
// Don't do this right away, so we can let the view continue to animate
// as it goes away.
if (mKeyguardView != null) {
final KeyguardViewBase lastView = mKeyguardView;
mKeyguardView = null;
mKeyguardHost.postDelayed(new Runnable() {
public void run() {
synchronized (KeyguardViewManager.this) {
lastView.cleanUp();
mKeyguardHost.removeView(lastView);
}
}
}, 500);
}
}
}
/**
* @return Whether the keyguard is showing
*/
public synchronized boolean isShowing() {
return (mKeyguardHost != null && mKeyguardHost.getVisibility() == View.VISIBLE);
}
}

View File

@@ -1,47 +0,0 @@
/*
* Copyright (C) 2008 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.internal.policy.impl.keyguard_obsolete;
import android.content.Context;
/**
* Defines operations necessary for showing a keyguard, including how to create
* it, and various properties that are useful to be able to query independant
* of whether the keyguard instance is around or not.
*/
public interface KeyguardViewProperties {
/**
* Create a keyguard view.
* @param context the context to use when creating the view.
* @param callback keyguard callback object for pokewakelock(), etc.
* @param updateMonitor configuration may be based on this.
* @param controller for talking back with the containing window.
* @return the view.
*/
KeyguardViewBase createKeyguardView(Context context,
KeyguardViewCallback mCallback, KeyguardUpdateMonitor updateMonitor,
KeyguardWindowController controller);
/**
* Would the keyguard be secure right now?
* @return Whether the keyguard is currently secure, meaning it will block
* the user from getting past it until the user enters some sort of PIN.
*/
boolean isSecure();
}

View File

@@ -1,29 +0,0 @@
/*
* Copyright (C) 2009 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.internal.policy.impl.keyguard_obsolete;
/**
* Interface passed to the keyguard view, for it to call up to control
* its containing window.
*/
public interface KeyguardWindowController {
/**
* Control whether the window needs input -- that is if it has
* text fields and thus should allow input method interaction.
*/
void setNeedsInput(boolean needsInput);
}

View File

@@ -1,64 +0,0 @@
/*
* Copyright (C) 2008 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.internal.policy.impl.keyguard_obsolete;
import com.android.internal.widget.LockPatternUtils;
import android.content.Context;
import com.android.internal.telephony.IccCardConstants;
/**
* Knows how to create a lock pattern keyguard view, and answer questions about
* it (even if it hasn't been created, per the interface specs).
*/
public class LockPatternKeyguardViewProperties implements KeyguardViewProperties {
private final LockPatternUtils mLockPatternUtils;
private final KeyguardUpdateMonitor mUpdateMonitor;
/**
* @param lockPatternUtils Used to know whether the pattern enabled, and passed
* onto the keygaurd view when it is created.
* @param updateMonitor Used to know whether the sim pin is enabled, and passed
* onto the keyguard view when it is created.
*/
public LockPatternKeyguardViewProperties(LockPatternUtils lockPatternUtils,
KeyguardUpdateMonitor updateMonitor) {
mLockPatternUtils = lockPatternUtils;
mUpdateMonitor = updateMonitor;
}
public KeyguardViewBase createKeyguardView(Context context,
KeyguardViewCallback callback,
KeyguardUpdateMonitor updateMonitor,
KeyguardWindowController controller) {
return new LockPatternKeyguardView(context, callback, updateMonitor,
mLockPatternUtils, controller);
}
public boolean isSecure() {
return mLockPatternUtils.isSecure() || isSimPinSecure();
}
private boolean isSimPinSecure() {
final IccCardConstants.State simState = mUpdateMonitor.getSimState();
return (simState == IccCardConstants.State.PIN_REQUIRED
|| simState == IccCardConstants.State.PUK_REQUIRED
|| simState == IccCardConstants.State.PERM_DISABLED);
}
}

View File

@@ -1,619 +0,0 @@
/*
* Copyright (C) 2008 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.internal.policy.impl.keyguard_obsolete;
import com.android.internal.R;
import com.android.internal.telephony.IccCardConstants;
import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.SlidingTab;
import com.android.internal.widget.WaveView;
import com.android.internal.widget.multiwaveview.GlowPadView;
import android.app.ActivityManager;
import android.app.ActivityManagerNative;
import android.app.SearchManager;
import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.UserHandle;
import android.os.Vibrator;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.*;
import android.util.Log;
import android.util.Slog;
import android.media.AudioManager;
import android.os.RemoteException;
import android.provider.MediaStore;
import java.io.File;
/**
* The screen within {@link LockPatternKeyguardView} that shows general
* information about the device depending on its state, and how to get
* past it, as applicable.
*/
class LockScreen extends LinearLayout implements KeyguardScreen {
private static final int ON_RESUME_PING_DELAY = 500; // delay first ping until the screen is on
private static final boolean DBG = false;
private static final String TAG = "LockScreen";
private static final String ENABLE_MENU_KEY_FILE = "/data/local/enable_menu_key";
private static final int WAIT_FOR_ANIMATION_TIMEOUT = 0;
private static final int STAY_ON_WHILE_GRABBED_TIMEOUT = 30000;
private static final String ASSIST_ICON_METADATA_NAME =
"com.android.systemui.action_assist_icon";
private LockPatternUtils mLockPatternUtils;
private KeyguardUpdateMonitor mUpdateMonitor;
private KeyguardScreenCallback mCallback;
// set to 'true' to show the ring/silence target when camera isn't available
private boolean mEnableRingSilenceFallback = false;
// current configuration state of keyboard and display
private int mCreationOrientation;
private boolean mSilentMode;
private AudioManager mAudioManager;
private boolean mEnableMenuKeyInLockScreen;
private KeyguardStatusViewManager mStatusViewManager;
private UnlockWidgetCommonMethods mUnlockWidgetMethods;
private View mUnlockWidget;
private boolean mCameraDisabled;
private boolean mSearchDisabled;
// Is there a vibrator
private final boolean mHasVibrator;
KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() {
@Override
public void onRingerModeChanged(int state) {
boolean silent = AudioManager.RINGER_MODE_NORMAL != state;
if (silent != mSilentMode) {
mSilentMode = silent;
mUnlockWidgetMethods.updateResources();
}
}
@Override
public void onDevicePolicyManagerStateChanged() {
updateTargets();
}
@Override
public void onSimStateChanged(IccCardConstants.State simState) {
updateTargets();
}
};
private interface UnlockWidgetCommonMethods {
// Update resources based on phone state
public void updateResources();
// Get the view associated with this widget
public View getView();
// Reset the view
public void reset(boolean animate);
// Animate the widget if it supports ping()
public void ping();
// Enable or disable a target. ResourceId is the id of the *drawable* associated with the
// target.
public void setEnabled(int resourceId, boolean enabled);
// Get the target position for the given resource. Returns -1 if not found.
public int getTargetPosition(int resourceId);
// Clean up when this widget is going away
public void cleanUp();
}
class SlidingTabMethods implements SlidingTab.OnTriggerListener, UnlockWidgetCommonMethods {
private final SlidingTab mSlidingTab;
SlidingTabMethods(SlidingTab slidingTab) {
mSlidingTab = slidingTab;
}
public void updateResources() {
boolean vibe = mSilentMode
&& (mAudioManager.getRingerMode() == AudioManager.RINGER_MODE_VIBRATE);
mSlidingTab.setRightTabResources(
mSilentMode ? ( vibe ? R.drawable.ic_jog_dial_vibrate_on
: R.drawable.ic_jog_dial_sound_off )
: R.drawable.ic_jog_dial_sound_on,
mSilentMode ? R.drawable.jog_tab_target_yellow
: R.drawable.jog_tab_target_gray,
mSilentMode ? R.drawable.jog_tab_bar_right_sound_on
: R.drawable.jog_tab_bar_right_sound_off,
mSilentMode ? R.drawable.jog_tab_right_sound_on
: R.drawable.jog_tab_right_sound_off);
}
/** {@inheritDoc} */
public void onTrigger(View v, int whichHandle) {
if (whichHandle == SlidingTab.OnTriggerListener.LEFT_HANDLE) {
mCallback.goToUnlockScreen();
} else if (whichHandle == SlidingTab.OnTriggerListener.RIGHT_HANDLE) {
toggleRingMode();
mCallback.pokeWakelock();
}
}
/** {@inheritDoc} */
public void onGrabbedStateChange(View v, int grabbedState) {
if (grabbedState == SlidingTab.OnTriggerListener.RIGHT_HANDLE) {
mSilentMode = isSilentMode();
mSlidingTab.setRightHintText(mSilentMode ? R.string.lockscreen_sound_on_label
: R.string.lockscreen_sound_off_label);
}
// Don't poke the wake lock when returning to a state where the handle is
// not grabbed since that can happen when the system (instead of the user)
// cancels the grab.
if (grabbedState != SlidingTab.OnTriggerListener.NO_HANDLE) {
mCallback.pokeWakelock();
}
}
public View getView() {
return mSlidingTab;
}
public void reset(boolean animate) {
mSlidingTab.reset(animate);
}
public void ping() {
}
public void setEnabled(int resourceId, boolean enabled) {
// Not used
}
public int getTargetPosition(int resourceId) {
return -1; // Not supported
}
public void cleanUp() {
mSlidingTab.setOnTriggerListener(null);
}
}
class WaveViewMethods implements WaveView.OnTriggerListener, UnlockWidgetCommonMethods {
private final WaveView mWaveView;
WaveViewMethods(WaveView waveView) {
mWaveView = waveView;
}
/** {@inheritDoc} */
public void onTrigger(View v, int whichHandle) {
if (whichHandle == WaveView.OnTriggerListener.CENTER_HANDLE) {
requestUnlockScreen();
}
}
/** {@inheritDoc} */
public void onGrabbedStateChange(View v, int grabbedState) {
// Don't poke the wake lock when returning to a state where the handle is
// not grabbed since that can happen when the system (instead of the user)
// cancels the grab.
if (grabbedState == WaveView.OnTriggerListener.CENTER_HANDLE) {
mCallback.pokeWakelock(STAY_ON_WHILE_GRABBED_TIMEOUT);
}
}
public void updateResources() {
}
public View getView() {
return mWaveView;
}
public void reset(boolean animate) {
mWaveView.reset();
}
public void ping() {
}
public void setEnabled(int resourceId, boolean enabled) {
// Not used
}
public int getTargetPosition(int resourceId) {
return -1; // Not supported
}
public void cleanUp() {
mWaveView.setOnTriggerListener(null);
}
}
class GlowPadViewMethods implements GlowPadView.OnTriggerListener,
UnlockWidgetCommonMethods {
private final GlowPadView mGlowPadView;
GlowPadViewMethods(GlowPadView glowPadView) {
mGlowPadView = glowPadView;
}
public boolean isTargetPresent(int resId) {
return mGlowPadView.getTargetPosition(resId) != -1;
}
public void updateResources() {
int resId;
if (mCameraDisabled && mEnableRingSilenceFallback) {
// Fall back to showing ring/silence if camera is disabled...
resId = mSilentMode ? R.array.lockscreen_targets_when_silent
: R.array.lockscreen_targets_when_soundon;
} else {
resId = R.array.lockscreen_targets_with_camera;
}
if (mGlowPadView.getTargetResourceId() != resId) {
mGlowPadView.setTargetResources(resId);
}
// Update the search icon with drawable from the search .apk
if (!mSearchDisabled) {
Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
.getAssistIntent(mContext, UserHandle.USER_CURRENT);
if (intent != null) {
// XXX Hack. We need to substitute the icon here but haven't formalized
// the public API. The "_google" metadata will be going away, so
// DON'T USE IT!
ComponentName component = intent.getComponent();
boolean replaced = mGlowPadView.replaceTargetDrawablesIfPresent(component,
ASSIST_ICON_METADATA_NAME + "_google",
com.android.internal.R.drawable.ic_action_assist_generic);
if (!replaced && !mGlowPadView.replaceTargetDrawablesIfPresent(component,
ASSIST_ICON_METADATA_NAME,
com.android.internal.R.drawable.ic_action_assist_generic)) {
Slog.w(TAG, "Couldn't grab icon from package " + component);
}
}
}
setEnabled(com.android.internal.R.drawable.ic_lockscreen_camera, !mCameraDisabled);
setEnabled(com.android.internal.R.drawable.ic_action_assist_generic, !mSearchDisabled);
}
public void onGrabbed(View v, int handle) {
}
public void onReleased(View v, int handle) {
}
public void onTrigger(View v, int target) {
final int resId = mGlowPadView.getResourceIdForTarget(target);
switch (resId) {
case com.android.internal.R.drawable.ic_action_assist_generic:
Intent assistIntent =
((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
.getAssistIntent(mContext, UserHandle.USER_CURRENT);
if (assistIntent != null) {
launchActivity(assistIntent);
} else {
Log.w(TAG, "Failed to get intent for assist activity");
}
mCallback.pokeWakelock();
break;
case com.android.internal.R.drawable.ic_lockscreen_camera:
launchActivity(new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA));
mCallback.pokeWakelock();
break;
case com.android.internal.R.drawable.ic_lockscreen_silent:
toggleRingMode();
mCallback.pokeWakelock();
break;
case com.android.internal.R.drawable.ic_lockscreen_unlock_phantom:
case com.android.internal.R.drawable.ic_lockscreen_unlock:
mCallback.goToUnlockScreen();
break;
}
}
/**
* Launches the said intent for the current foreground user.
* @param intent
*/
private void launchActivity(Intent intent) {
intent.setFlags(
Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_SINGLE_TOP
| Intent.FLAG_ACTIVITY_CLEAR_TOP);
try {
ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity();
} catch (RemoteException e) {
Log.w(TAG, "can't dismiss keyguard on launch");
}
try {
mContext.startActivityAsUser(intent, new UserHandle(UserHandle.USER_CURRENT));
} catch (ActivityNotFoundException e) {
Log.w(TAG, "Activity not found for intent + " + intent.getAction());
}
}
public void onGrabbedStateChange(View v, int handle) {
// Don't poke the wake lock when returning to a state where the handle is
// not grabbed since that can happen when the system (instead of the user)
// cancels the grab.
if (handle != GlowPadView.OnTriggerListener.NO_HANDLE) {
mCallback.pokeWakelock();
}
}
public View getView() {
return mGlowPadView;
}
public void reset(boolean animate) {
mGlowPadView.reset(animate);
}
public void ping() {
mGlowPadView.ping();
}
public void setEnabled(int resourceId, boolean enabled) {
mGlowPadView.setEnableTarget(resourceId, enabled);
}
public int getTargetPosition(int resourceId) {
return mGlowPadView.getTargetPosition(resourceId);
}
public void cleanUp() {
mGlowPadView.setOnTriggerListener(null);
}
public void onFinishFinalAnimation() {
}
}
private void requestUnlockScreen() {
// Delay hiding lock screen long enough for animation to finish
postDelayed(new Runnable() {
public void run() {
mCallback.goToUnlockScreen();
}
}, WAIT_FOR_ANIMATION_TIMEOUT);
}
private void toggleRingMode() {
// toggle silent mode
mSilentMode = !mSilentMode;
if (mSilentMode) {
mAudioManager.setRingerMode(mHasVibrator
? AudioManager.RINGER_MODE_VIBRATE
: AudioManager.RINGER_MODE_SILENT);
} else {
mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
}
}
/**
* In general, we enable unlocking the insecure key guard with the menu key. However, there are
* some cases where we wish to disable it, notably when the menu button placement or technology
* is prone to false positives.
*
* @return true if the menu key should be enabled
*/
private boolean shouldEnableMenuKey() {
final Resources res = getResources();
final boolean configDisabled = res.getBoolean(R.bool.config_disableMenuKeyInLockScreen);
final boolean isTestHarness = ActivityManager.isRunningInTestHarness();
final boolean fileOverride = (new File(ENABLE_MENU_KEY_FILE)).exists();
return !configDisabled || isTestHarness || fileOverride;
}
/**
* @param context Used to setup the view.
* @param configuration The current configuration. Used to use when selecting layout, etc.
* @param lockPatternUtils Used to know the state of the lock pattern settings.
* @param updateMonitor Used to register for updates on various keyguard related
* state, and query the initial state at setup.
* @param callback Used to communicate back to the host keyguard view.
*/
LockScreen(Context context, Configuration configuration, LockPatternUtils lockPatternUtils,
KeyguardUpdateMonitor updateMonitor,
KeyguardScreenCallback callback) {
super(context);
mLockPatternUtils = lockPatternUtils;
mUpdateMonitor = updateMonitor;
mCallback = callback;
mEnableMenuKeyInLockScreen = shouldEnableMenuKey();
mCreationOrientation = configuration.orientation;
if (LockPatternKeyguardView.DEBUG_CONFIGURATION) {
Log.v(TAG, "***** CREATING LOCK SCREEN", new RuntimeException());
Log.v(TAG, "Cur orient=" + mCreationOrientation
+ " res orient=" + context.getResources().getConfiguration().orientation);
}
final LayoutInflater inflater = LayoutInflater.from(context);
if (DBG) Log.v(TAG, "Creation orientation = " + mCreationOrientation);
if (mCreationOrientation != Configuration.ORIENTATION_LANDSCAPE) {
inflater.inflate(R.layout.keyguard_screen_tab_unlock, this, true);
} else {
inflater.inflate(R.layout.keyguard_screen_tab_unlock_land, this, true);
}
mStatusViewManager = new KeyguardStatusViewManager(this, mUpdateMonitor, mLockPatternUtils,
mCallback, false);
setFocusable(true);
setFocusableInTouchMode(true);
setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
mHasVibrator = vibrator == null ? false : vibrator.hasVibrator();
mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
mSilentMode = isSilentMode();
mUnlockWidget = findViewById(R.id.unlock_widget);
mUnlockWidgetMethods = createUnlockMethods(mUnlockWidget);
if (DBG) Log.v(TAG, "*** LockScreen accel is "
+ (mUnlockWidget.isHardwareAccelerated() ? "on":"off"));
}
private UnlockWidgetCommonMethods createUnlockMethods(View unlockWidget) {
if (unlockWidget instanceof SlidingTab) {
SlidingTab slidingTabView = (SlidingTab) unlockWidget;
slidingTabView.setHoldAfterTrigger(true, false);
slidingTabView.setLeftHintText(R.string.lockscreen_unlock_label);
slidingTabView.setLeftTabResources(
R.drawable.ic_jog_dial_unlock,
R.drawable.jog_tab_target_green,
R.drawable.jog_tab_bar_left_unlock,
R.drawable.jog_tab_left_unlock);
SlidingTabMethods slidingTabMethods = new SlidingTabMethods(slidingTabView);
slidingTabView.setOnTriggerListener(slidingTabMethods);
return slidingTabMethods;
} else if (unlockWidget instanceof WaveView) {
WaveView waveView = (WaveView) unlockWidget;
WaveViewMethods waveViewMethods = new WaveViewMethods(waveView);
waveView.setOnTriggerListener(waveViewMethods);
return waveViewMethods;
} else if (unlockWidget instanceof GlowPadView) {
GlowPadView glowPadView = (GlowPadView) unlockWidget;
GlowPadViewMethods glowPadViewMethods = new GlowPadViewMethods(glowPadView);
glowPadView.setOnTriggerListener(glowPadViewMethods);
return glowPadViewMethods;
} else {
throw new IllegalStateException("Unrecognized unlock widget: " + unlockWidget);
}
}
private void updateTargets() {
boolean disabledByAdmin = mLockPatternUtils.getDevicePolicyManager()
.getCameraDisabled(null);
boolean disabledBySimState = mUpdateMonitor.isSimLocked();
boolean cameraTargetPresent = (mUnlockWidgetMethods instanceof GlowPadViewMethods)
? ((GlowPadViewMethods) mUnlockWidgetMethods)
.isTargetPresent(com.android.internal.R.drawable.ic_lockscreen_camera)
: false;
boolean searchTargetPresent = (mUnlockWidgetMethods instanceof GlowPadViewMethods)
? ((GlowPadViewMethods) mUnlockWidgetMethods)
.isTargetPresent(com.android.internal.R.drawable.ic_action_assist_generic)
: false;
if (disabledByAdmin) {
Log.v(TAG, "Camera disabled by Device Policy");
} else if (disabledBySimState) {
Log.v(TAG, "Camera disabled by Sim State");
}
boolean searchActionAvailable =
((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
.getAssistIntent(mContext, UserHandle.USER_CURRENT) != null;
mCameraDisabled = disabledByAdmin || disabledBySimState || !cameraTargetPresent;
mSearchDisabled = disabledBySimState || !searchActionAvailable || !searchTargetPresent;
mUnlockWidgetMethods.updateResources();
}
private boolean isSilentMode() {
return mAudioManager.getRingerMode() != AudioManager.RINGER_MODE_NORMAL;
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_MENU && mEnableMenuKeyInLockScreen) {
mCallback.goToUnlockScreen();
}
return false;
}
void updateConfiguration() {
Configuration newConfig = getResources().getConfiguration();
if (newConfig.orientation != mCreationOrientation) {
mCallback.recreateMe(newConfig);
}
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
if (LockPatternKeyguardView.DEBUG_CONFIGURATION) {
Log.v(TAG, "***** LOCK ATTACHED TO WINDOW");
Log.v(TAG, "Cur orient=" + mCreationOrientation
+ ", new config=" + getResources().getConfiguration());
}
updateConfiguration();
}
/** {@inheritDoc} */
@Override
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (LockPatternKeyguardView.DEBUG_CONFIGURATION) {
Log.w(TAG, "***** LOCK CONFIG CHANGING", new RuntimeException());
Log.v(TAG, "Cur orient=" + mCreationOrientation
+ ", new config=" + newConfig);
}
updateConfiguration();
}
/** {@inheritDoc} */
public boolean needsInput() {
return false;
}
/** {@inheritDoc} */
public void onPause() {
mUpdateMonitor.removeCallback(mInfoCallback);
mStatusViewManager.onPause();
mUnlockWidgetMethods.reset(false);
}
private final Runnable mOnResumePing = new Runnable() {
public void run() {
mUnlockWidgetMethods.ping();
}
};
/** {@inheritDoc} */
public void onResume() {
// We don't want to show the camera target if SIM state prevents us from
// launching the camera. So watch for SIM changes...
mUpdateMonitor.registerCallback(mInfoCallback);
mStatusViewManager.onResume();
postDelayed(mOnResumePing, ON_RESUME_PING_DELAY);
}
/** {@inheritDoc} */
public void cleanUp() {
mUpdateMonitor.removeCallback(mInfoCallback); // this must be first
mUnlockWidgetMethods.cleanUp();
mLockPatternUtils = null;
mUpdateMonitor = null;
mCallback = null;
}
}

View File

@@ -1,383 +0,0 @@
/*
* Copyright (C) 2010 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.internal.policy.impl.keyguard_obsolete;
import java.util.List;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Rect;
import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.PasswordEntryKeyboardView;
import android.os.CountDownTimer;
import android.os.SystemClock;
import android.provider.Settings;
import android.security.KeyStore;
import android.text.Editable;
import android.text.InputType;
import android.text.TextWatcher;
import android.text.method.DigitsKeyListener;
import android.text.method.TextKeyListener;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodManager;
import android.view.inputmethod.InputMethodSubtype;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.Space;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
import com.android.internal.R;
import com.android.internal.widget.PasswordEntryKeyboardHelper;
/**
* Displays a dialer-like interface or alphanumeric (latin-1) key entry for the user to enter
* an unlock password
*/
public class PasswordUnlockScreen extends LinearLayout implements KeyguardScreen,
OnEditorActionListener {
private static final String TAG = "PasswordUnlockScreen";
private final KeyguardUpdateMonitor mUpdateMonitor;
private final KeyguardScreenCallback mCallback;
private final boolean mIsAlpha;
private final EditText mPasswordEntry;
private final LockPatternUtils mLockPatternUtils;
private final PasswordEntryKeyboardView mKeyboardView;
private final PasswordEntryKeyboardHelper mKeyboardHelper;
private final int mCreationOrientation;
private final int mCreationHardKeyboardHidden;
private final KeyguardStatusViewManager mStatusViewManager;
private final boolean mUseSystemIME = true; // TODO: Make configurable
private boolean mResuming; // used to prevent poking the wakelock during onResume()
// To avoid accidental lockout due to events while the device in in the pocket, ignore
// any passwords with length less than or equal to this length.
private static final int MINIMUM_PASSWORD_LENGTH_BEFORE_REPORT = 3;
public PasswordUnlockScreen(Context context, Configuration configuration,
LockPatternUtils lockPatternUtils, KeyguardUpdateMonitor updateMonitor,
KeyguardScreenCallback callback) {
super(context);
mCreationHardKeyboardHidden = configuration.hardKeyboardHidden;
mCreationOrientation = configuration.orientation;
mUpdateMonitor = updateMonitor;
mCallback = callback;
mLockPatternUtils = lockPatternUtils;
LayoutInflater layoutInflater = LayoutInflater.from(context);
if (mCreationOrientation != Configuration.ORIENTATION_LANDSCAPE) {
layoutInflater.inflate(R.layout.keyguard_screen_password_portrait, this, true);
} else {
layoutInflater.inflate(R.layout.keyguard_screen_password_landscape, this, true);
}
mStatusViewManager = new KeyguardStatusViewManager(this, mUpdateMonitor, mLockPatternUtils,
mCallback, true);
final int quality = lockPatternUtils.getKeyguardStoredPasswordQuality();
mIsAlpha = DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC == quality
|| DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC == quality
|| DevicePolicyManager.PASSWORD_QUALITY_COMPLEX == quality;
mKeyboardView = (PasswordEntryKeyboardView) findViewById(R.id.keyboard);
mPasswordEntry = (EditText) findViewById(R.id.passwordEntry);
mPasswordEntry.setOnEditorActionListener(this);
mKeyboardHelper = new PasswordEntryKeyboardHelper(context, mKeyboardView, this, false);
mKeyboardHelper.setEnableHaptics(mLockPatternUtils.isTactileFeedbackEnabled());
boolean imeOrDeleteButtonVisible = false;
if (mIsAlpha) {
// We always use the system IME for alpha keyboard, so hide lockscreen's soft keyboard
mKeyboardHelper.setKeyboardMode(PasswordEntryKeyboardHelper.KEYBOARD_MODE_ALPHA);
mKeyboardView.setVisibility(View.GONE);
} else {
// Use lockscreen's numeric keyboard if the physical keyboard isn't showing
mKeyboardHelper.setKeyboardMode(PasswordEntryKeyboardHelper.KEYBOARD_MODE_NUMERIC);
mKeyboardView.setVisibility(mCreationHardKeyboardHidden
== Configuration.HARDKEYBOARDHIDDEN_NO ? View.INVISIBLE : View.VISIBLE);
// The delete button is of the PIN keyboard itself in some (e.g. tablet) layouts,
// not a separate view
View pinDelete = findViewById(R.id.pinDel);
if (pinDelete != null) {
pinDelete.setVisibility(View.VISIBLE);
imeOrDeleteButtonVisible = true;
pinDelete.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mKeyboardHelper.handleBackspace();
}
});
}
}
mPasswordEntry.requestFocus();
// This allows keyboards with overlapping qwerty/numeric keys to choose just numeric keys.
if (mIsAlpha) {
mPasswordEntry.setKeyListener(TextKeyListener.getInstance());
mPasswordEntry.setInputType(InputType.TYPE_CLASS_TEXT
| InputType.TYPE_TEXT_VARIATION_PASSWORD);
//mStatusViewManager.setHelpMessage(R.string.keyguard_password_enter_password_code,
//KeyguardStatusViewManager.LOCK_ICON);
} else {
mPasswordEntry.setKeyListener(DigitsKeyListener.getInstance());
mPasswordEntry.setInputType(InputType.TYPE_CLASS_NUMBER
| InputType.TYPE_NUMBER_VARIATION_PASSWORD);
//mStatusViewManager.setHelpMessage(R.string.keyguard_password_enter_pin_code,
//KeyguardStatusViewManager.LOCK_ICON);
}
// Poke the wakelock any time the text is selected or modified
mPasswordEntry.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
mCallback.pokeWakelock();
}
});
mPasswordEntry.addTextChangedListener(new TextWatcher() {
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void afterTextChanged(Editable s) {
if (!mResuming) {
mCallback.pokeWakelock();
}
}
});
// If there's more than one IME, enable the IME switcher button
View switchImeButton = findViewById(R.id.switch_ime_button);
final InputMethodManager imm = (InputMethodManager) getContext().getSystemService(
Context.INPUT_METHOD_SERVICE);
if (mIsAlpha && switchImeButton != null && hasMultipleEnabledIMEsOrSubtypes(imm, false)) {
switchImeButton.setVisibility(View.VISIBLE);
imeOrDeleteButtonVisible = true;
switchImeButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
mCallback.pokeWakelock(); // Leave the screen on a bit longer
imm.showInputMethodPicker();
}
});
}
// If no icon is visible, reset the left margin on the password field so the text is
// still centered.
if (!imeOrDeleteButtonVisible) {
android.view.ViewGroup.LayoutParams params = mPasswordEntry.getLayoutParams();
if (params instanceof MarginLayoutParams) {
((MarginLayoutParams)params).leftMargin = 0;
mPasswordEntry.setLayoutParams(params);
}
}
}
/**
* Method adapted from com.android.inputmethod.latin.Utils
*
* @param imm The input method manager
* @param shouldIncludeAuxiliarySubtypes
* @return true if we have multiple IMEs to choose from
*/
private boolean hasMultipleEnabledIMEsOrSubtypes(InputMethodManager imm,
final boolean shouldIncludeAuxiliarySubtypes) {
final List<InputMethodInfo> enabledImis = imm.getEnabledInputMethodList();
// Number of the filtered IMEs
int filteredImisCount = 0;
for (InputMethodInfo imi : enabledImis) {
// We can return true immediately after we find two or more filtered IMEs.
if (filteredImisCount > 1) return true;
final List<InputMethodSubtype> subtypes =
imm.getEnabledInputMethodSubtypeList(imi, true);
// IMEs that have no subtypes should be counted.
if (subtypes.isEmpty()) {
++filteredImisCount;
continue;
}
int auxCount = 0;
for (InputMethodSubtype subtype : subtypes) {
if (subtype.isAuxiliary()) {
++auxCount;
}
}
final int nonAuxCount = subtypes.size() - auxCount;
// IMEs that have one or more non-auxiliary subtypes should be counted.
// If shouldIncludeAuxiliarySubtypes is true, IMEs that have two or more auxiliary
// subtypes should be counted as well.
if (nonAuxCount > 0 || (shouldIncludeAuxiliarySubtypes && auxCount > 1)) {
++filteredImisCount;
continue;
}
}
return filteredImisCount > 1
// imm.getEnabledInputMethodSubtypeList(null, false) will return the current IME's enabled
// input method subtype (The current IME should be LatinIME.)
|| imm.getEnabledInputMethodSubtypeList(null, false).size() > 1;
}
@Override
protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) {
// send focus to the password field
return mPasswordEntry.requestFocus(direction, previouslyFocusedRect);
}
/** {@inheritDoc} */
public boolean needsInput() {
return mUseSystemIME && mIsAlpha;
}
/** {@inheritDoc} */
public void onPause() {
mStatusViewManager.onPause();
}
/** {@inheritDoc} */
public void onResume() {
mResuming = true;
// reset status
mStatusViewManager.onResume();
// start fresh
mPasswordEntry.setText("");
mPasswordEntry.requestFocus();
// if the user is currently locked out, enforce it.
long deadline = mLockPatternUtils.getLockoutAttemptDeadline();
if (deadline != 0) {
handleAttemptLockout(deadline);
}
mResuming = false;
}
/** {@inheritDoc} */
public void cleanUp() {
mUpdateMonitor.removeCallback(this);
}
private void verifyPasswordAndUnlock() {
String entry = mPasswordEntry.getText().toString();
if (mLockPatternUtils.checkPassword(entry)) {
mCallback.keyguardDone(true);
mCallback.reportSuccessfulUnlockAttempt();
mStatusViewManager.setInstructionText(null);
KeyStore.getInstance().password(entry);
} else if (entry.length() > MINIMUM_PASSWORD_LENGTH_BEFORE_REPORT ) {
// to avoid accidental lockout, only count attempts that are long enough to be a
// real password. This may require some tweaking.
mCallback.reportFailedUnlockAttempt();
if (0 == (mUpdateMonitor.getFailedAttempts()
% LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT)) {
long deadline = mLockPatternUtils.setLockoutAttemptDeadline();
handleAttemptLockout(deadline);
}
mStatusViewManager.setInstructionText(
mContext.getString(R.string.lockscreen_password_wrong));
} else if (entry.length() > 0) {
mStatusViewManager.setInstructionText(
mContext.getString(R.string.lockscreen_password_wrong));
}
mPasswordEntry.setText("");
}
// Prevent user from using the PIN/Password entry until scheduled deadline.
private void handleAttemptLockout(long elapsedRealtimeDeadline) {
mPasswordEntry.setEnabled(false);
mKeyboardView.setEnabled(false);
long elapsedRealtime = SystemClock.elapsedRealtime();
new CountDownTimer(elapsedRealtimeDeadline - elapsedRealtime, 1000) {
@Override
public void onTick(long millisUntilFinished) {
int secondsRemaining = (int) (millisUntilFinished / 1000);
String instructions = getContext().getString(
R.string.lockscreen_too_many_failed_attempts_countdown,
secondsRemaining);
mStatusViewManager.setInstructionText(instructions);
}
@Override
public void onFinish() {
mPasswordEntry.setEnabled(true);
mKeyboardView.setEnabled(true);
mStatusViewManager.resetStatusInfo();
}
}.start();
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
mCallback.pokeWakelock();
return false;
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
Configuration config = getResources().getConfiguration();
if (config.orientation != mCreationOrientation
|| config.hardKeyboardHidden != mCreationHardKeyboardHidden) {
mCallback.recreateMe(config);
}
}
/** {@inheritDoc} */
@Override
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (newConfig.orientation != mCreationOrientation
|| newConfig.hardKeyboardHidden != mCreationHardKeyboardHidden) {
mCallback.recreateMe(newConfig);
}
}
public void onKeyboardChange(boolean isKeyboardOpen) {
// Don't show the soft keyboard when the real keyboard is open
mKeyboardView.setVisibility(isKeyboardOpen ? View.INVISIBLE : View.VISIBLE);
}
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
// Check if this was the result of hitting the enter key
if (actionId == EditorInfo.IME_NULL || actionId == EditorInfo.IME_ACTION_DONE
|| actionId == EditorInfo.IME_ACTION_NEXT) {
verifyPasswordAndUnlock();
return true;
}
return false;
}
}

View File

@@ -1,416 +0,0 @@
/*
* Copyright (C) 2008 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.internal.policy.impl.keyguard_obsolete;
import android.content.Context;
import android.content.res.Configuration;
import android.os.CountDownTimer;
import android.os.SystemClock;
import android.security.KeyStore;
import android.view.LayoutInflater;
import android.view.View;
import android.view.MotionEvent;
import android.widget.Button;
import android.util.Log;
import com.android.internal.R;
import com.android.internal.widget.LinearLayoutWithDefaultTouchRecepient;
import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.LockPatternView;
import com.android.internal.widget.LockPatternView.Cell;
import java.util.List;
/**
* This is the screen that shows the 9 circle unlock widget and instructs
* the user how to unlock their device, or make an emergency call.
*/
class PatternUnlockScreen extends LinearLayoutWithDefaultTouchRecepient
implements KeyguardScreen {
private static final boolean DEBUG = false;
private static final String TAG = "UnlockScreen";
// how long before we clear the wrong pattern
private static final int PATTERN_CLEAR_TIMEOUT_MS = 2000;
// how long we stay awake after each key beyond MIN_PATTERN_BEFORE_POKE_WAKELOCK
private static final int UNLOCK_PATTERN_WAKE_INTERVAL_MS = 7000;
// how long we stay awake after the user hits the first dot.
private static final int UNLOCK_PATTERN_WAKE_INTERVAL_FIRST_DOTS_MS = 2000;
// how many cells the user has to cross before we poke the wakelock
private static final int MIN_PATTERN_BEFORE_POKE_WAKELOCK = 2;
private int mFailedPatternAttemptsSinceLastTimeout = 0;
private int mTotalFailedPatternAttempts = 0;
private CountDownTimer mCountdownTimer = null;
private LockPatternUtils mLockPatternUtils;
private KeyguardUpdateMonitor mUpdateMonitor;
private KeyguardScreenCallback mCallback;
/**
* whether there is a fallback option available when the pattern is forgotten.
*/
private boolean mEnableFallback;
private KeyguardStatusViewManager mKeyguardStatusViewManager;
private LockPatternView mLockPatternView;
/**
* Keeps track of the last time we poked the wake lock during dispatching
* of the touch event, initalized to something gauranteed to make us
* poke it when the user starts drawing the pattern.
* @see #dispatchTouchEvent(android.view.MotionEvent)
*/
private long mLastPokeTime = -UNLOCK_PATTERN_WAKE_INTERVAL_MS;
/**
* Useful for clearing out the wrong pattern after a delay
*/
private Runnable mCancelPatternRunnable = new Runnable() {
public void run() {
mLockPatternView.clearPattern();
}
};
private final OnClickListener mForgotPatternClick = new OnClickListener() {
public void onClick(View v) {
mCallback.forgotPattern(true);
}
};
private Button mForgotPatternButton;
private int mCreationOrientation;
enum FooterMode {
Normal,
ForgotLockPattern,
VerifyUnlocked
}
private void hideForgotPatternButton() {
mForgotPatternButton.setVisibility(View.GONE);
}
private void showForgotPatternButton() {
mForgotPatternButton.setVisibility(View.VISIBLE);
}
private void updateFooter(FooterMode mode) {
switch (mode) {
case Normal:
if (DEBUG) Log.d(TAG, "mode normal");
hideForgotPatternButton();
break;
case ForgotLockPattern:
if (DEBUG) Log.d(TAG, "mode ForgotLockPattern");
showForgotPatternButton();
break;
case VerifyUnlocked:
if (DEBUG) Log.d(TAG, "mode VerifyUnlocked");
hideForgotPatternButton();
}
}
/**
* @param context The context.
* @param configuration
* @param lockPatternUtils Used to lookup lock pattern settings.
* @param updateMonitor Used to lookup state affecting keyguard.
* @param callback Used to notify the manager when we're done, etc.
* @param totalFailedAttempts The current number of failed attempts.
* @param enableFallback True if a backup unlock option is available when the user has forgotten
* their pattern (e.g they have a google account so we can show them the account based
* backup option).
*/
PatternUnlockScreen(Context context,
Configuration configuration, LockPatternUtils lockPatternUtils,
KeyguardUpdateMonitor updateMonitor,
KeyguardScreenCallback callback,
int totalFailedAttempts) {
super(context);
mLockPatternUtils = lockPatternUtils;
mUpdateMonitor = updateMonitor;
mCallback = callback;
mTotalFailedPatternAttempts = totalFailedAttempts;
mFailedPatternAttemptsSinceLastTimeout =
totalFailedAttempts % LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT;
if (DEBUG) Log.d(TAG,
"UnlockScreen() ctor: totalFailedAttempts="
+ totalFailedAttempts + ", mFailedPat...="
+ mFailedPatternAttemptsSinceLastTimeout
);
mCreationOrientation = configuration.orientation;
LayoutInflater inflater = LayoutInflater.from(context);
if (mCreationOrientation != Configuration.ORIENTATION_LANDSCAPE) {
Log.d(TAG, "portrait mode");
inflater.inflate(R.layout.keyguard_screen_unlock_portrait, this, true);
} else {
Log.d(TAG, "landscape mode");
inflater.inflate(R.layout.keyguard_screen_unlock_landscape, this, true);
}
mKeyguardStatusViewManager = new KeyguardStatusViewManager(this, mUpdateMonitor,
mLockPatternUtils, mCallback, true);
mLockPatternView = (LockPatternView) findViewById(R.id.lockPattern);
mForgotPatternButton = (Button) findViewById(R.id.forgotPatternButton);
mForgotPatternButton.setText(R.string.lockscreen_forgot_pattern_button_text);
mForgotPatternButton.setOnClickListener(mForgotPatternClick);
// make it so unhandled touch events within the unlock screen go to the
// lock pattern view.
setDefaultTouchRecepient(mLockPatternView);
mLockPatternView.setSaveEnabled(false);
mLockPatternView.setFocusable(false);
mLockPatternView.setOnPatternListener(new UnlockPatternListener());
// stealth mode will be the same for the life of this screen
mLockPatternView.setInStealthMode(!mLockPatternUtils.isVisiblePatternEnabled());
// vibrate mode will be the same for the life of this screen
mLockPatternView.setTactileFeedbackEnabled(mLockPatternUtils.isTactileFeedbackEnabled());
// assume normal footer mode for now
updateFooter(FooterMode.Normal);
setFocusableInTouchMode(true);
}
public void setEnableFallback(boolean state) {
if (DEBUG) Log.d(TAG, "setEnableFallback(" + state + ")");
mEnableFallback = state;
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
// as long as the user is entering a pattern (i.e sending a touch
// event that was handled by this screen), keep poking the
// wake lock so that the screen will stay on.
final boolean result = super.dispatchTouchEvent(ev);
if (result &&
((SystemClock.elapsedRealtime() - mLastPokeTime)
> (UNLOCK_PATTERN_WAKE_INTERVAL_MS - 100))) {
mLastPokeTime = SystemClock.elapsedRealtime();
}
return result;
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
if (LockPatternKeyguardView.DEBUG_CONFIGURATION) {
Log.v(TAG, "***** PATTERN ATTACHED TO WINDOW");
Log.v(TAG, "Cur orient=" + mCreationOrientation
+ ", new config=" + getResources().getConfiguration());
}
if (getResources().getConfiguration().orientation != mCreationOrientation) {
mCallback.recreateMe(getResources().getConfiguration());
}
}
/** {@inheritDoc} */
@Override
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (LockPatternKeyguardView.DEBUG_CONFIGURATION) {
Log.v(TAG, "***** PATTERN CONFIGURATION CHANGED");
Log.v(TAG, "Cur orient=" + mCreationOrientation
+ ", new config=" + getResources().getConfiguration());
}
if (newConfig.orientation != mCreationOrientation) {
mCallback.recreateMe(newConfig);
}
}
/** {@inheritDoc} */
public void onKeyboardChange(boolean isKeyboardOpen) {}
/** {@inheritDoc} */
public boolean needsInput() {
return false;
}
/** {@inheritDoc} */
public void onPause() {
if (mCountdownTimer != null) {
mCountdownTimer.cancel();
mCountdownTimer = null;
}
mKeyguardStatusViewManager.onPause();
}
/** {@inheritDoc} */
public void onResume() {
// reset status
mKeyguardStatusViewManager.onResume();
// reset lock pattern
mLockPatternView.enableInput();
mLockPatternView.setEnabled(true);
mLockPatternView.clearPattern();
// show "forgot pattern?" button if we have an alternate authentication method
if (mCallback.doesFallbackUnlockScreenExist()) {
showForgotPatternButton();
} else {
hideForgotPatternButton();
}
// if the user is currently locked out, enforce it.
long deadline = mLockPatternUtils.getLockoutAttemptDeadline();
if (deadline != 0) {
handleAttemptLockout(deadline);
}
// the footer depends on how many total attempts the user has failed
if (mCallback.isVerifyUnlockOnly()) {
updateFooter(FooterMode.VerifyUnlocked);
} else if (mEnableFallback &&
(mTotalFailedPatternAttempts >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT)) {
updateFooter(FooterMode.ForgotLockPattern);
} else {
updateFooter(FooterMode.Normal);
}
}
/** {@inheritDoc} */
public void cleanUp() {
if (DEBUG) Log.v(TAG, "Cleanup() called on " + this);
mUpdateMonitor.removeCallback(this);
mLockPatternUtils = null;
mUpdateMonitor = null;
mCallback = null;
mLockPatternView.setOnPatternListener(null);
}
@Override
public void onWindowFocusChanged(boolean hasWindowFocus) {
super.onWindowFocusChanged(hasWindowFocus);
if (hasWindowFocus) {
// when timeout dialog closes we want to update our state
onResume();
}
}
private class UnlockPatternListener
implements LockPatternView.OnPatternListener {
public void onPatternStart() {
mLockPatternView.removeCallbacks(mCancelPatternRunnable);
}
public void onPatternCleared() {
}
public void onPatternCellAdded(List<Cell> pattern) {
// To guard against accidental poking of the wakelock, look for
// the user actually trying to draw a pattern of some minimal length.
if (pattern.size() > MIN_PATTERN_BEFORE_POKE_WAKELOCK) {
mCallback.pokeWakelock(UNLOCK_PATTERN_WAKE_INTERVAL_MS);
} else {
// Give just a little extra time if they hit one of the first few dots
mCallback.pokeWakelock(UNLOCK_PATTERN_WAKE_INTERVAL_FIRST_DOTS_MS);
}
}
public void onPatternDetected(List<LockPatternView.Cell> pattern) {
if (mLockPatternUtils.checkPattern(pattern)) {
mLockPatternView
.setDisplayMode(LockPatternView.DisplayMode.Correct);
mKeyguardStatusViewManager.setInstructionText("");
mKeyguardStatusViewManager.updateStatusLines(true);
mCallback.keyguardDone(true);
mCallback.reportSuccessfulUnlockAttempt();
KeyStore.getInstance().password(LockPatternUtils.patternToString(pattern));
} else {
boolean reportFailedAttempt = false;
if (pattern.size() > MIN_PATTERN_BEFORE_POKE_WAKELOCK) {
mCallback.pokeWakelock(UNLOCK_PATTERN_WAKE_INTERVAL_MS);
}
mLockPatternView.setDisplayMode(LockPatternView.DisplayMode.Wrong);
if (pattern.size() >= LockPatternUtils.MIN_PATTERN_REGISTER_FAIL) {
mTotalFailedPatternAttempts++;
mFailedPatternAttemptsSinceLastTimeout++;
reportFailedAttempt = true;
}
if (mFailedPatternAttemptsSinceLastTimeout
>= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT) {
long deadline = mLockPatternUtils.setLockoutAttemptDeadline();
handleAttemptLockout(deadline);
} else {
// TODO mUnlockIcon.setVisibility(View.VISIBLE);
mKeyguardStatusViewManager.setInstructionText(
getContext().getString(R.string.lockscreen_pattern_wrong));
mKeyguardStatusViewManager.updateStatusLines(true);
mLockPatternView.postDelayed(
mCancelPatternRunnable,
PATTERN_CLEAR_TIMEOUT_MS);
}
// Because the following can result in cleanUp() being called on this screen,
// member variables reset in cleanUp() shouldn't be accessed after this call.
if (reportFailedAttempt) {
mCallback.reportFailedUnlockAttempt();
}
}
}
}
private void handleAttemptLockout(long elapsedRealtimeDeadline) {
mLockPatternView.clearPattern();
mLockPatternView.setEnabled(false);
long elapsedRealtime = SystemClock.elapsedRealtime();
mCountdownTimer = new CountDownTimer(elapsedRealtimeDeadline - elapsedRealtime, 1000) {
@Override
public void onTick(long millisUntilFinished) {
int secondsRemaining = (int) (millisUntilFinished / 1000);
mKeyguardStatusViewManager.setInstructionText(getContext().getString(
R.string.lockscreen_too_many_failed_attempts_countdown,
secondsRemaining));
mKeyguardStatusViewManager.updateStatusLines(true);
}
@Override
public void onFinish() {
mLockPatternView.setEnabled(true);
mKeyguardStatusViewManager.setInstructionText(getContext().getString(
R.string.lockscreen_pattern_instructions));
mKeyguardStatusViewManager.updateStatusLines(true);
// TODO mUnlockIcon.setVisibility(View.VISIBLE);
mFailedPatternAttemptsSinceLastTimeout = 0;
if (mEnableFallback) {
updateFooter(FooterMode.ForgotLockPattern);
} else {
updateFooter(FooterMode.Normal);
}
}
}.start();
}
}

View File

@@ -1,422 +0,0 @@
/*
* Copyright (C) 2008 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.internal.policy.impl.keyguard_obsolete;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.res.Configuration;
import android.os.RemoteException;
import android.os.ServiceManager;
import com.android.internal.telephony.ITelephony;
import com.android.internal.widget.LockPatternUtils;
import android.text.Editable;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.android.internal.R;
/**
* Displays a dialer like interface to unlock the SIM PUK.
*/
public class SimPukUnlockScreen extends LinearLayout implements KeyguardScreen,
View.OnClickListener, View.OnFocusChangeListener {
private static final int DIGIT_PRESS_WAKE_MILLIS = 5000;
private final KeyguardUpdateMonitor mUpdateMonitor;
private final KeyguardScreenCallback mCallback;
private KeyguardStatusViewManager mKeyguardStatusViewManager;
private TextView mHeaderText;
private TextView mPukText;
private TextView mPinText;
private TextView mFocusedEntry;
private View mOkButton;
private View mDelPukButton;
private View mDelPinButton;
private ProgressDialog mSimUnlockProgressDialog = null;
private LockPatternUtils mLockPatternUtils;
private int mCreationOrientation;
private int mKeyboardHidden;
private static final char[] DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
public SimPukUnlockScreen(Context context, Configuration configuration,
KeyguardUpdateMonitor updateMonitor, KeyguardScreenCallback callback,
LockPatternUtils lockpatternutils) {
super(context);
mUpdateMonitor = updateMonitor;
mCallback = callback;;
mCreationOrientation = configuration.orientation;
mKeyboardHidden = configuration.hardKeyboardHidden;
mLockPatternUtils = lockpatternutils;
LayoutInflater inflater = LayoutInflater.from(context);
if (mKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO) {
inflater.inflate(
R.layout.keyguard_screen_sim_puk_landscape, this, true);
} else {
inflater.inflate(
R.layout.keyguard_screen_sim_puk_portrait, this, true);
new TouchInput();
}
mHeaderText = (TextView) findViewById(R.id.headerText);
mPukText = (TextView) findViewById(R.id.pukDisplay);
mPinText = (TextView) findViewById(R.id.pinDisplay);
mDelPukButton = findViewById(R.id.pukDel);
mDelPinButton = findViewById(R.id.pinDel);
mOkButton = findViewById(R.id.ok);
mDelPinButton.setOnClickListener(this);
mDelPukButton.setOnClickListener(this);
mOkButton.setOnClickListener(this);
mHeaderText.setText(R.string.keyguard_password_enter_puk_code);
// To make marquee work
mHeaderText.setSelected(true);
mKeyguardStatusViewManager = new KeyguardStatusViewManager(this, updateMonitor,
lockpatternutils, callback, true);
mPinText.setFocusableInTouchMode(true);
mPinText.setOnFocusChangeListener(this);
mPukText.setFocusableInTouchMode(true);
mPukText.setOnFocusChangeListener(this);
}
/** {@inheritDoc} */
public boolean needsInput() {
return false;
}
/** {@inheritDoc} */
public void onPause() {
mKeyguardStatusViewManager.onPause();
}
/** {@inheritDoc} */
public void onResume() {
// start fresh
mHeaderText.setText(R.string.keyguard_password_enter_puk_code);
mKeyguardStatusViewManager.onResume();
}
/** {@inheritDoc} */
public void cleanUp() {
// dismiss the dialog.
if (mSimUnlockProgressDialog != null) {
mSimUnlockProgressDialog.dismiss();
mSimUnlockProgressDialog = null;
}
mUpdateMonitor.removeCallback(this);
}
/**
* Since the IPC can block, we want to run the request in a separate thread
* with a callback.
*/
private abstract class CheckSimPuk extends Thread {
private final String mPin, mPuk;
protected CheckSimPuk(String puk, String pin) {
mPuk = puk;
mPin = pin;
}
abstract void onSimLockChangedResponse(boolean success);
@Override
public void run() {
try {
final boolean result = ITelephony.Stub.asInterface(ServiceManager
.checkService("phone")).supplyPuk(mPuk, mPin);
post(new Runnable() {
public void run() {
onSimLockChangedResponse(result);
}
});
} catch (RemoteException e) {
post(new Runnable() {
public void run() {
onSimLockChangedResponse(false);
}
});
}
}
}
public void onClick(View v) {
if (v == mDelPukButton) {
if (mFocusedEntry != mPukText)
mPukText.requestFocus();
final Editable digits = mPukText.getEditableText();
final int len = digits.length();
if (len > 0) {
digits.delete(len-1, len);
}
} else if (v == mDelPinButton) {
if (mFocusedEntry != mPinText)
mPinText.requestFocus();
final Editable digits = mPinText.getEditableText();
final int len = digits.length();
if (len > 0) {
digits.delete(len-1, len);
}
} else if (v == mOkButton) {
checkPuk();
}
mCallback.pokeWakelock(DIGIT_PRESS_WAKE_MILLIS);
}
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus)
mFocusedEntry = (TextView)v;
}
private Dialog getSimUnlockProgressDialog() {
if (mSimUnlockProgressDialog == null) {
mSimUnlockProgressDialog = new ProgressDialog(mContext);
mSimUnlockProgressDialog.setMessage(
mContext.getString(R.string.lockscreen_sim_unlock_progress_dialog_message));
mSimUnlockProgressDialog.setIndeterminate(true);
mSimUnlockProgressDialog.setCancelable(false);
mSimUnlockProgressDialog.getWindow().setType(
WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
}
return mSimUnlockProgressDialog;
}
private void checkPuk() {
// make sure that the puk is at least 8 digits long.
if (mPukText.getText().length() < 8) {
// otherwise, display a message to the user, and don't submit.
mHeaderText.setText(R.string.invalidPuk);
mPukText.setText("");
return;
}
if (mPinText.getText().length() < 4
|| mPinText.getText().length() > 8) {
// otherwise, display a message to the user, and don't submit.
mHeaderText.setText(R.string.invalidPin);
mPinText.setText("");
return;
}
getSimUnlockProgressDialog().show();
new CheckSimPuk(mPukText.getText().toString(),
mPinText.getText().toString()) {
void onSimLockChangedResponse(final boolean success) {
mPinText.post(new Runnable() {
public void run() {
if (mSimUnlockProgressDialog != null) {
mSimUnlockProgressDialog.hide();
}
if (success) {
// before closing the keyguard, report back that
// the sim is unlocked so it knows right away
mUpdateMonitor.reportSimUnlocked();
mCallback.goToUnlockScreen();
} else {
mHeaderText.setText(R.string.badPuk);
mPukText.setText("");
mPinText.setText("");
}
}
});
}
}.start();
}
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
mCallback.goToLockScreen();
return true;
}
final char match = event.getMatch(DIGITS);
if (match != 0) {
reportDigit(match - '0');
return true;
}
if (keyCode == KeyEvent.KEYCODE_DEL) {
mFocusedEntry.onKeyDown(keyCode, event);
final Editable digits = mFocusedEntry.getEditableText();
final int len = digits.length();
if (len > 0) {
digits.delete(len-1, len);
}
mCallback.pokeWakelock(DIGIT_PRESS_WAKE_MILLIS);
return true;
}
if (keyCode == KeyEvent.KEYCODE_ENTER) {
checkPuk();
return true;
}
return false;
}
private void reportDigit(int digit) {
mFocusedEntry.append(Integer.toString(digit));
}
void updateConfiguration() {
Configuration newConfig = getResources().getConfiguration();
if (newConfig.orientation != mCreationOrientation) {
mCallback.recreateMe(newConfig);
} else if (newConfig.hardKeyboardHidden != mKeyboardHidden) {
mKeyboardHidden = newConfig.hardKeyboardHidden;
}
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
updateConfiguration();
}
/** {@inheritDoc} */
@Override
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
updateConfiguration();
}
/**
* Helper class to handle input from touch dialer. Only relevant when
* the keyboard is shut.
*/
private class TouchInput implements View.OnClickListener {
private TextView mZero;
private TextView mOne;
private TextView mTwo;
private TextView mThree;
private TextView mFour;
private TextView mFive;
private TextView mSix;
private TextView mSeven;
private TextView mEight;
private TextView mNine;
private TextView mCancelButton;
private TouchInput() {
mZero = (TextView) findViewById(R.id.zero);
mOne = (TextView) findViewById(R.id.one);
mTwo = (TextView) findViewById(R.id.two);
mThree = (TextView) findViewById(R.id.three);
mFour = (TextView) findViewById(R.id.four);
mFive = (TextView) findViewById(R.id.five);
mSix = (TextView) findViewById(R.id.six);
mSeven = (TextView) findViewById(R.id.seven);
mEight = (TextView) findViewById(R.id.eight);
mNine = (TextView) findViewById(R.id.nine);
mCancelButton = (TextView) findViewById(R.id.cancel);
mZero.setText("0");
mOne.setText("1");
mTwo.setText("2");
mThree.setText("3");
mFour.setText("4");
mFive.setText("5");
mSix.setText("6");
mSeven.setText("7");
mEight.setText("8");
mNine.setText("9");
mZero.setOnClickListener(this);
mOne.setOnClickListener(this);
mTwo.setOnClickListener(this);
mThree.setOnClickListener(this);
mFour.setOnClickListener(this);
mFive.setOnClickListener(this);
mSix.setOnClickListener(this);
mSeven.setOnClickListener(this);
mEight.setOnClickListener(this);
mNine.setOnClickListener(this);
mCancelButton.setOnClickListener(this);
}
public void onClick(View v) {
if (v == mCancelButton) {
// clear the PIN/PUK entry fields if the user cancels
mPinText.setText("");
mPukText.setText("");
mCallback.goToLockScreen();
return;
}
final int digit = checkDigit(v);
if (digit >= 0) {
mCallback.pokeWakelock(DIGIT_PRESS_WAKE_MILLIS);
reportDigit(digit);
}
}
private int checkDigit(View v) {
int digit = -1;
if (v == mZero) {
digit = 0;
} else if (v == mOne) {
digit = 1;
} else if (v == mTwo) {
digit = 2;
} else if (v == mThree) {
digit = 3;
} else if (v == mFour) {
digit = 4;
} else if (v == mFive) {
digit = 5;
} else if (v == mSix) {
digit = 6;
} else if (v == mSeven) {
digit = 7;
} else if (v == mEight) {
digit = 8;
} else if (v == mNine) {
digit = 9;
}
return digit;
}
}
}

View File

@@ -1,396 +0,0 @@
/*
* Copyright (C) 2008 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.internal.policy.impl.keyguard_obsolete;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.res.Configuration;
import android.os.RemoteException;
import android.os.ServiceManager;
import com.android.internal.telephony.ITelephony;
import com.android.internal.widget.LockPatternUtils;
import android.text.Editable;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.android.internal.R;
/**
* Displays a dialer like interface to unlock the SIM PIN.
*/
public class SimUnlockScreen extends LinearLayout implements KeyguardScreen, View.OnClickListener {
private static final int DIGIT_PRESS_WAKE_MILLIS = 5000;
private final KeyguardUpdateMonitor mUpdateMonitor;
private final KeyguardScreenCallback mCallback;
private TextView mHeaderText;
private TextView mPinText;
private TextView mOkButton;
private View mBackSpaceButton;
private final int[] mEnteredPin = {0, 0, 0, 0, 0, 0, 0, 0};
private int mEnteredDigits = 0;
private ProgressDialog mSimUnlockProgressDialog = null;
private LockPatternUtils mLockPatternUtils;
private int mCreationOrientation;
private int mKeyboardHidden;
private KeyguardStatusViewManager mKeyguardStatusViewManager;
private static final char[] DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
public SimUnlockScreen(Context context, Configuration configuration,
KeyguardUpdateMonitor updateMonitor, KeyguardScreenCallback callback,
LockPatternUtils lockpatternutils) {
super(context);
mUpdateMonitor = updateMonitor;
mCallback = callback;
mCreationOrientation = configuration.orientation;
mKeyboardHidden = configuration.hardKeyboardHidden;
mLockPatternUtils = lockpatternutils;
LayoutInflater inflater = LayoutInflater.from(context);
if (mKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO) {
inflater.inflate(R.layout.keyguard_screen_sim_pin_landscape, this, true);
} else {
inflater.inflate(R.layout.keyguard_screen_sim_pin_portrait, this, true);
new TouchInput();
}
mHeaderText = (TextView) findViewById(R.id.headerText);
mPinText = (TextView) findViewById(R.id.pinDisplay);
mBackSpaceButton = findViewById(R.id.backspace);
mBackSpaceButton.setOnClickListener(this);
mOkButton = (TextView) findViewById(R.id.ok);
mHeaderText.setText(R.string.keyguard_password_enter_pin_code);
mPinText.setFocusable(false);
mOkButton.setOnClickListener(this);
mKeyguardStatusViewManager = new KeyguardStatusViewManager(this, updateMonitor,
lockpatternutils, callback, false);
setFocusableInTouchMode(true);
}
/** {@inheritDoc} */
public boolean needsInput() {
return true;
}
/** {@inheritDoc} */
public void onPause() {
mKeyguardStatusViewManager.onPause();
}
/** {@inheritDoc} */
public void onResume() {
// start fresh
mHeaderText.setText(R.string.keyguard_password_enter_pin_code);
// make sure that the number of entered digits is consistent when we
// erase the SIM unlock code, including orientation changes.
mPinText.setText("");
mEnteredDigits = 0;
mKeyguardStatusViewManager.onResume();
}
/** {@inheritDoc} */
public void cleanUp() {
// dismiss the dialog.
if (mSimUnlockProgressDialog != null) {
mSimUnlockProgressDialog.dismiss();
mSimUnlockProgressDialog = null;
}
mUpdateMonitor.removeCallback(this);
}
/**
* Since the IPC can block, we want to run the request in a separate thread
* with a callback.
*/
private abstract class CheckSimPin extends Thread {
private final String mPin;
protected CheckSimPin(String pin) {
mPin = pin;
}
abstract void onSimLockChangedResponse(boolean success);
@Override
public void run() {
try {
final boolean result = ITelephony.Stub.asInterface(ServiceManager
.checkService("phone")).supplyPin(mPin);
post(new Runnable() {
public void run() {
onSimLockChangedResponse(result);
}
});
} catch (RemoteException e) {
post(new Runnable() {
public void run() {
onSimLockChangedResponse(false);
}
});
}
}
}
public void onClick(View v) {
if (v == mBackSpaceButton) {
final Editable digits = mPinText.getEditableText();
final int len = digits.length();
if (len > 0) {
digits.delete(len-1, len);
mEnteredDigits--;
}
mCallback.pokeWakelock();
} else if (v == mOkButton) {
checkPin();
}
}
private Dialog getSimUnlockProgressDialog() {
if (mSimUnlockProgressDialog == null) {
mSimUnlockProgressDialog = new ProgressDialog(mContext);
mSimUnlockProgressDialog.setMessage(
mContext.getString(R.string.lockscreen_sim_unlock_progress_dialog_message));
mSimUnlockProgressDialog.setIndeterminate(true);
mSimUnlockProgressDialog.setCancelable(false);
mSimUnlockProgressDialog.getWindow().setType(
WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
}
return mSimUnlockProgressDialog;
}
private void checkPin() {
// make sure that the pin is at least 4 digits long.
if (mEnteredDigits < 4) {
// otherwise, display a message to the user, and don't submit.
mHeaderText.setText(R.string.invalidPin);
mPinText.setText("");
mEnteredDigits = 0;
mCallback.pokeWakelock();
return;
}
getSimUnlockProgressDialog().show();
new CheckSimPin(mPinText.getText().toString()) {
void onSimLockChangedResponse(final boolean success) {
mPinText.post(new Runnable() {
public void run() {
if (mSimUnlockProgressDialog != null) {
mSimUnlockProgressDialog.hide();
}
if (success) {
// before closing the keyguard, report back that
// the sim is unlocked so it knows right away
mUpdateMonitor.reportSimUnlocked();
mCallback.goToUnlockScreen();
} else {
mHeaderText.setText(R.string.keyguard_password_wrong_pin_code);
mPinText.setText("");
mEnteredDigits = 0;
}
mCallback.pokeWakelock();
}
});
}
}.start();
}
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
mCallback.goToLockScreen();
return true;
}
final char match = event.getMatch(DIGITS);
if (match != 0) {
reportDigit(match - '0');
return true;
}
if (keyCode == KeyEvent.KEYCODE_DEL) {
if (mEnteredDigits > 0) {
mPinText.onKeyDown(keyCode, event);
mEnteredDigits--;
}
return true;
}
if (keyCode == KeyEvent.KEYCODE_ENTER) {
checkPin();
return true;
}
return false;
}
private void reportDigit(int digit) {
if (mEnteredDigits == 0) {
mPinText.setText("");
}
if (mEnteredDigits == 8) {
return;
}
mPinText.append(Integer.toString(digit));
mEnteredPin[mEnteredDigits++] = digit;
}
void updateConfiguration() {
Configuration newConfig = getResources().getConfiguration();
if (newConfig.orientation != mCreationOrientation) {
mCallback.recreateMe(newConfig);
} else if (newConfig.hardKeyboardHidden != mKeyboardHidden) {
mKeyboardHidden = newConfig.hardKeyboardHidden;
}
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
updateConfiguration();
}
/** {@inheritDoc} */
@Override
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
updateConfiguration();
}
/**
* Helper class to handle input from touch dialer. Only relevant when
* the keyboard is shut.
*/
private class TouchInput implements View.OnClickListener {
private TextView mZero;
private TextView mOne;
private TextView mTwo;
private TextView mThree;
private TextView mFour;
private TextView mFive;
private TextView mSix;
private TextView mSeven;
private TextView mEight;
private TextView mNine;
private TextView mCancelButton;
private TouchInput() {
mZero = (TextView) findViewById(R.id.zero);
mOne = (TextView) findViewById(R.id.one);
mTwo = (TextView) findViewById(R.id.two);
mThree = (TextView) findViewById(R.id.three);
mFour = (TextView) findViewById(R.id.four);
mFive = (TextView) findViewById(R.id.five);
mSix = (TextView) findViewById(R.id.six);
mSeven = (TextView) findViewById(R.id.seven);
mEight = (TextView) findViewById(R.id.eight);
mNine = (TextView) findViewById(R.id.nine);
mCancelButton = (TextView) findViewById(R.id.cancel);
mZero.setText("0");
mOne.setText("1");
mTwo.setText("2");
mThree.setText("3");
mFour.setText("4");
mFive.setText("5");
mSix.setText("6");
mSeven.setText("7");
mEight.setText("8");
mNine.setText("9");
mZero.setOnClickListener(this);
mOne.setOnClickListener(this);
mTwo.setOnClickListener(this);
mThree.setOnClickListener(this);
mFour.setOnClickListener(this);
mFive.setOnClickListener(this);
mSix.setOnClickListener(this);
mSeven.setOnClickListener(this);
mEight.setOnClickListener(this);
mNine.setOnClickListener(this);
mCancelButton.setOnClickListener(this);
}
public void onClick(View v) {
if (v == mCancelButton) {
mPinText.setText(""); // clear the PIN entry field if the user cancels
mCallback.goToLockScreen();
return;
}
final int digit = checkDigit(v);
if (digit >= 0) {
mCallback.pokeWakelock(DIGIT_PRESS_WAKE_MILLIS);
reportDigit(digit);
}
}
private int checkDigit(View v) {
int digit = -1;
if (v == mZero) {
digit = 0;
} else if (v == mOne) {
digit = 1;
} else if (v == mTwo) {
digit = 2;
} else if (v == mThree) {
digit = 3;
} else if (v == mFour) {
digit = 4;
} else if (v == mFive) {
digit = 5;
} else if (v == mSix) {
digit = 6;
} else if (v == mSeven) {
digit = 7;
} else if (v == mEight) {
digit = 8;
} else if (v == mNine) {
digit = 9;
}
return digit;
}
}
}

View File

@@ -1,29 +0,0 @@
# Copyright 2010, 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.
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
# We only want this apk build for tests.
LOCAL_MODULE_TAGS := tests
LOCAL_JAVA_LIBRARIES := android.policy android.test.runner
# Include all test java files.
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_PACKAGE_NAME := FrameworkPolicyTests
include $(BUILD_PACKAGE)

View File

@@ -1,31 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2010 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.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.frameworks.policy.tests">
<application>
<uses-library android:name="android.test.runner" />
</application>
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
<instrumentation
android:name="android.test.InstrumentationTestRunner"
android:targetPackage="com.android.frameworks.policy.tests"
android:label="Framework policy tests" />
</manifest>

View File

@@ -1,356 +0,0 @@
/*
* Copyright (C) 2008 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.internal.policy.impl.keyguard_obsolete;
import android.content.Context;
import com.android.internal.policy.impl.keyguard_obsolete.KeyguardScreen;
import com.android.internal.policy.impl.keyguard_obsolete.KeyguardUpdateMonitor;
import com.android.internal.policy.impl.keyguard_obsolete.KeyguardViewCallback;
import com.android.internal.policy.impl.keyguard_obsolete.KeyguardWindowController;
import com.android.internal.policy.impl.keyguard_obsolete.LockPatternKeyguardView;
import com.android.internal.telephony.IccCardConstants;
import android.content.res.Configuration;
import android.test.AndroidTestCase;
import android.view.View;
import android.view.KeyEvent;
import com.android.internal.widget.LockPatternUtils;
import com.google.android.collect.Lists;
import java.util.List;
/**
* Tests for {@link com.android.internal.policy.impl.LockPatternKeyguardView},
* which handles the management of screens while the keyguard is showing.
*/
public class LockPatternKeyguardViewTest extends AndroidTestCase {
private MockUpdateMonitor mUpdateMonitor;
private LockPatternUtils mLockPatternUtils;
private TestableLockPatternKeyguardView mLPKV;
private MockKeyguardCallback mKeyguardViewCallback;
private static class MockUpdateMonitor extends KeyguardUpdateMonitor {
public IccCardConstants.State simState = IccCardConstants.State.READY;
private MockUpdateMonitor(Context context) {
super(context);
}
@Override
public IccCardConstants.State getSimState() {
return simState;
}
}
private static class MockLockPatternUtils extends LockPatternUtils {
boolean isLockPatternEnabled = true;
public boolean isPermanentlyLocked = false;
public MockLockPatternUtils(Context context) {
super(context);
}
@Override
public boolean isLockPatternEnabled() {
return isLockPatternEnabled;
}
@Override
public void setLockPatternEnabled(boolean lockPatternEnabled) {
isLockPatternEnabled = lockPatternEnabled;
}
@Override
public boolean isPermanentlyLocked() {
return isPermanentlyLocked;
}
public void setPermanentlyLocked(boolean permanentlyLocked) {
isPermanentlyLocked = permanentlyLocked;
}
}
private static class MockKeyguardScreen extends View implements KeyguardScreen {
private int mOnPauseCount = 0;
private int mOnResumeCount = 0;
private int mCleanupCount = 0;
private MockKeyguardScreen(Context context) {
super(context);
setFocusable(true);
}
/** {@inheritDoc} */
public boolean needsInput() {
return false;
}
/** {@inheritDoc} */
public void onPause() {
mOnPauseCount++;
}
/** {@inheritDoc} */
public void onResume() {
mOnResumeCount++;
}
/** {@inheritDoc} */
public void cleanUp() {
mCleanupCount++;
}
public int getOnPauseCount() {
return mOnPauseCount;
}
public int getOnResumeCount() {
return mOnResumeCount;
}
public int getCleanupCount() {
return mCleanupCount;
}
}
/**
* Allows us to inject the lock and unlock views to simulate their behavior
* and detect their creation.
*/
private static class TestableLockPatternKeyguardView extends LockPatternKeyguardView {
private List<MockKeyguardScreen> mInjectedLockScreens;
private List<MockKeyguardScreen> mInjectedUnlockScreens;
private TestableLockPatternKeyguardView(Context context, KeyguardViewCallback callback,
KeyguardUpdateMonitor updateMonitor,
LockPatternUtils lockPatternUtils, KeyguardWindowController controller) {
super(context, callback, updateMonitor, lockPatternUtils, controller);
}
@Override
View createLockScreen() {
final MockKeyguardScreen newView = new MockKeyguardScreen(getContext());
if (mInjectedLockScreens == null) mInjectedLockScreens = Lists.newArrayList();
mInjectedLockScreens.add(newView);
return newView;
}
@Override
View createUnlockScreenFor(UnlockMode unlockMode) {
final MockKeyguardScreen newView = new MockKeyguardScreen(getContext());
if (mInjectedUnlockScreens == null) mInjectedUnlockScreens = Lists.newArrayList();
mInjectedUnlockScreens.add(newView);
return newView;
}
public List<MockKeyguardScreen> getInjectedLockScreens() {
return mInjectedLockScreens;
}
public List<MockKeyguardScreen> getInjectedUnlockScreens() {
return mInjectedUnlockScreens;
}
}
private static class MockKeyguardCallback implements KeyguardViewCallback {
private int mPokeWakelockCount = 0;
private int mKeyguardDoneCount = 0;
public void pokeWakelock() {
mPokeWakelockCount++;
}
public void pokeWakelock(int millis) {
mPokeWakelockCount++;
}
public void keyguardDone(boolean authenticated) {
mKeyguardDoneCount++;
}
public void keyguardDoneDrawing() {
}
public int getPokeWakelockCount() {
return mPokeWakelockCount;
}
public int getKeyguardDoneCount() {
return mKeyguardDoneCount;
}
}
@Override
protected void setUp() throws Exception {
super.setUp();
mUpdateMonitor = new MockUpdateMonitor(getContext());
mLockPatternUtils = new MockLockPatternUtils(getContext());
mKeyguardViewCallback = new MockKeyguardCallback();
mLPKV = new TestableLockPatternKeyguardView(getContext(), mKeyguardViewCallback,
mUpdateMonitor, mLockPatternUtils, new KeyguardWindowController() {
public void setNeedsInput(boolean needsInput) {
}
});
}
public void testStateAfterCreatedWhileScreenOff() {
assertEquals(1, mLPKV.getInjectedLockScreens().size());
assertEquals(1, mLPKV.getInjectedUnlockScreens().size());
MockKeyguardScreen lockScreen = mLPKV.getInjectedLockScreens().get(0);
MockKeyguardScreen unlockScreen = mLPKV.getInjectedUnlockScreens().get(0);
assertEquals(0, lockScreen.getOnPauseCount());
assertEquals(0, lockScreen.getOnResumeCount());
assertEquals(0, lockScreen.getCleanupCount());
assertEquals(0, unlockScreen.getOnPauseCount());
assertEquals(0, unlockScreen.getOnResumeCount());
assertEquals(0, unlockScreen.getCleanupCount());
assertEquals(0, mKeyguardViewCallback.getPokeWakelockCount());
assertEquals(0, mKeyguardViewCallback.getKeyguardDoneCount());
}
public void testWokenByNonMenuKey() {
mLPKV.wakeWhenReadyTq(0);
// should have poked the wakelock to turn on the screen
assertEquals(1, mKeyguardViewCallback.getPokeWakelockCount());
// shouldn't be any additional views created
assertEquals(1, mLPKV.getInjectedLockScreens().size());
assertEquals(1, mLPKV.getInjectedUnlockScreens().size());
MockKeyguardScreen lockScreen = mLPKV.getInjectedLockScreens().get(0);
MockKeyguardScreen unlockScreen = mLPKV.getInjectedUnlockScreens().get(0);
// lock screen should be only visible one
assertEquals(View.VISIBLE, lockScreen.getVisibility());
assertEquals(View.GONE, unlockScreen.getVisibility());
// on resume not called until screen turns on
assertEquals(0, lockScreen.getOnPauseCount());
assertEquals(0, lockScreen.getOnResumeCount());
assertEquals(0, lockScreen.getCleanupCount());
assertEquals(0, unlockScreen.getOnPauseCount());
assertEquals(0, unlockScreen.getOnResumeCount());
assertEquals(0, unlockScreen.getCleanupCount());
// simulate screen turning on
mLPKV.onScreenTurnedOn();
assertEquals(0, lockScreen.getOnPauseCount());
assertEquals(1, lockScreen.getOnResumeCount());
assertEquals(0, lockScreen.getCleanupCount());
assertEquals(0, unlockScreen.getOnPauseCount());
assertEquals(0, unlockScreen.getOnResumeCount());
assertEquals(0, unlockScreen.getCleanupCount());
}
public void testWokenByMenuKeyWhenPatternSet() {
assertEquals(true, mLockPatternUtils.isLockPatternEnabled());
mLPKV.wakeWhenReadyTq(KeyEvent.KEYCODE_MENU);
// should have poked the wakelock to turn on the screen
assertEquals(1, mKeyguardViewCallback.getPokeWakelockCount());
// shouldn't be any additional views created
assertEquals(1, mLPKV.getInjectedLockScreens().size());
assertEquals(1, mLPKV.getInjectedUnlockScreens().size());
MockKeyguardScreen lockScreen = mLPKV.getInjectedLockScreens().get(0);
MockKeyguardScreen unlockScreen = mLPKV.getInjectedUnlockScreens().get(0);
// unlock screen should be only visible one
assertEquals(View.GONE, lockScreen.getVisibility());
assertEquals(View.VISIBLE, unlockScreen.getVisibility());
}
public void testScreenRequestsRecreation() {
mLPKV.wakeWhenReadyTq(0);
mLPKV.onScreenTurnedOn();
assertEquals(1, mLPKV.getInjectedLockScreens().size());
assertEquals(1, mLPKV.getInjectedUnlockScreens().size());
MockKeyguardScreen lockScreen = mLPKV.getInjectedLockScreens().get(0);
assertEquals(0, lockScreen.getOnPauseCount());
assertEquals(1, lockScreen.getOnResumeCount());
// simulate screen asking to be recreated
mLPKV.mKeyguardScreenCallback.recreateMe(new Configuration());
// should have been recreated
assertEquals(2, mLPKV.getInjectedLockScreens().size());
assertEquals(2, mLPKV.getInjectedUnlockScreens().size());
// both old screens should have been cleaned up
assertEquals(1, mLPKV.getInjectedLockScreens().get(0).getCleanupCount());
assertEquals(1, mLPKV.getInjectedUnlockScreens().get(0).getCleanupCount());
// old lock screen should have been paused
assertEquals(1, mLPKV.getInjectedLockScreens().get(0).getOnPauseCount());
assertEquals(0, mLPKV.getInjectedUnlockScreens().get(0).getOnPauseCount());
// new lock screen should have been resumed
assertEquals(1, mLPKV.getInjectedLockScreens().get(1).getOnResumeCount());
assertEquals(0, mLPKV.getInjectedUnlockScreens().get(1).getOnResumeCount());
}
public void testMenuDoesntGoToUnlockScreenOnWakeWhenPukLocked() {
// PUK locked
mUpdateMonitor.simState = IccCardConstants.State.PUK_REQUIRED;
// wake by menu
mLPKV.wakeWhenReadyTq(KeyEvent.KEYCODE_MENU);
assertEquals(1, mLPKV.getInjectedLockScreens().size());
assertEquals(1, mLPKV.getInjectedUnlockScreens().size());
MockKeyguardScreen lockScreen = mLPKV.getInjectedLockScreens().get(0);
MockKeyguardScreen unlockScreen = mLPKV.getInjectedUnlockScreens().get(0);
// lock screen should be only visible one
assertEquals(View.VISIBLE, lockScreen.getVisibility());
assertEquals(View.GONE, unlockScreen.getVisibility());
}
public void testMenuGoesToLockScreenWhenDeviceNotSecure() {
mLockPatternUtils.setLockPatternEnabled(false);
// wake by menu
mLPKV.wakeWhenReadyTq(KeyEvent.KEYCODE_MENU);
assertEquals(1, mLPKV.getInjectedLockScreens().size());
assertEquals(1, mLPKV.getInjectedUnlockScreens().size());
MockKeyguardScreen lockScreen = mLPKV.getInjectedLockScreens().get(0);
MockKeyguardScreen unlockScreen = mLPKV.getInjectedUnlockScreens().get(0);
// lock screen should be only visible one
assertEquals(View.VISIBLE, lockScreen.getVisibility());
assertEquals(View.GONE, unlockScreen.getVisibility());
}
}