Merge "Remove unused keyguard code"
This commit is contained in:
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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" />
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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 "";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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) { }
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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();
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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>
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user