Add "emergency call" button to CryptKeeper

This allows you to make an emergency call without needing to decrypt
your device first.

The exact appearance of the button, and the two possible icons shown to
the left of the text, are taken directly from the corresponding
framework resources (see keyguard_screen_*.xml, ic_emergency.png, and
stat_sys_phone_call.png.)

Also, the code in CryptKeeper.java for updating the state of, and
handling clicks from, the "Emergency call" button is mostly duplicated
from the corresponding code in LockPatternUtils and
LockPatternKeyguardView under frameworks/base.

Bug: 4494186
Change-Id: I36a713fdbc3281a7ba46762d47d5b61fb3cd194d
This commit is contained in:
David Brown
2011-06-20 12:38:45 -07:00
parent 127757637b
commit 8373b45169
7 changed files with 96 additions and 2 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 900 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 773 B

View File

@@ -42,4 +42,16 @@
android:textColor="#ffffffff" android:textColor="#ffffffff"
/> />
</LinearLayout> <!-- Emergency call button.
Text and icon are set by CryptKeeper.updateEmergencyCallButtonState() -->
<Button android:id="@+id/emergencyCallButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:layout_marginTop="10dip"
style="@*android:style/Widget.Button.Transparent"
android:textSize="14sp"
android:drawablePadding="6dip"
/>
</LinearLayout>

View File

@@ -3481,4 +3481,9 @@ found in the list of installed applications.</string>
<!-- Label displaying current network data usage warning threshold. [CHAR LIMIT=18] --> <!-- Label displaying current network data usage warning threshold. [CHAR LIMIT=18] -->
<string name="data_usage_sweep_warning"><font size="32"><xliff:g id="number" example="128">%1$s</xliff:g></font> <font size="12"><xliff:g id="unit" example="KB">%2$s</xliff:g></font>\n<font size="12">warning</font></string> <string name="data_usage_sweep_warning"><font size="32"><xliff:g id="number" example="128">%1$s</xliff:g></font> <font size="12"><xliff:g id="unit" example="KB">%2$s</xliff:g></font>\n<font size="12">warning</font></string>
<!-- Button at the bottom of the CryptKeeper screen to make an emergency call. -->
<string name="cryptkeeper_emergency_call">Emergency call</string>
<!-- Button at the bottom of the CryptKeeper screen that lets the user return to a call -->
<string name="cryptkeeper_return_to_call">Return to call</string>
</resources> </resources>

View File

@@ -16,6 +16,7 @@
package com.android.settings; package com.android.settings;
import com.android.internal.telephony.ITelephony;
import com.android.internal.widget.PasswordEntryKeyboardHelper; import com.android.internal.widget.PasswordEntryKeyboardHelper;
import com.android.internal.widget.PasswordEntryKeyboardView; import com.android.internal.widget.PasswordEntryKeyboardView;
@@ -33,9 +34,11 @@ import android.os.Handler;
import android.os.IBinder; import android.os.IBinder;
import android.os.Message; import android.os.Message;
import android.os.PowerManager; import android.os.PowerManager;
import android.os.RemoteException;
import android.os.ServiceManager; import android.os.ServiceManager;
import android.os.SystemProperties; import android.os.SystemProperties;
import android.os.storage.IMountService; import android.os.storage.IMountService;
import android.telephony.TelephonyManager;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.util.Log; import android.util.Log;
@@ -62,6 +65,9 @@ public class CryptKeeper extends Activity implements TextView.OnEditorActionList
private static final int COOL_DOWN_ATTEMPTS = 10; private static final int COOL_DOWN_ATTEMPTS = 10;
private static final int COOL_DOWN_INTERVAL = 30; // 30 seconds private static final int COOL_DOWN_INTERVAL = 30; // 30 seconds
// Intent action for launching the Emergency Dialer activity.
static final String ACTION_EMERGENCY_DIAL = "com.android.phone.EmergencyDialer.DIAL";
private int mCooldown; private int mCooldown;
PowerManager.WakeLock mWakeLock; PowerManager.WakeLock mWakeLock;
private EditText mPasswordEntry; private EditText mPasswordEntry;
@@ -347,6 +353,8 @@ public class CryptKeeper extends Activity implements TextView.OnEditorActionList
keyboardView, mPasswordEntry, false); keyboardView, mPasswordEntry, false);
keyboardHelper.setKeyboardMode(PasswordEntryKeyboardHelper.KEYBOARD_MODE_ALPHA); keyboardHelper.setKeyboardMode(PasswordEntryKeyboardHelper.KEYBOARD_MODE_ALPHA);
} }
updateEmergencyCallButtonState();
} }
private IMountService getMountService() { private IMountService getMountService() {
@@ -381,4 +389,73 @@ public class CryptKeeper extends Activity implements TextView.OnEditorActionList
} }
return false; return false;
} }
}
//
// Code to update the state of, and handle clicks from, the "Emergency call" button.
//
// This code is mostly duplicated from the corresponding code in
// LockPatternUtils and LockPatternKeyguardView under frameworks/base.
//
private void updateEmergencyCallButtonState() {
Button button = (Button) findViewById(R.id.emergencyCallButton);
// The button isn't present at all in some configurations.
if (button == null) return;
if (isEmergencyCallCapable()) {
button.setVisibility(View.VISIBLE);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
takeEmergencyCallAction();
}
});
} else {
button.setVisibility(View.GONE);
return;
}
int newState = TelephonyManager.getDefault().getCallState();
int textId;
if (newState == TelephonyManager.CALL_STATE_OFFHOOK) {
// show "return to call" text and show phone icon
textId = R.string.cryptkeeper_return_to_call;
int phoneCallIcon = R.drawable.stat_sys_phone_call;
button.setCompoundDrawablesWithIntrinsicBounds(phoneCallIcon, 0, 0, 0);
} else {
textId = R.string.cryptkeeper_emergency_call;
int emergencyIcon = R.drawable.ic_emergency;
button.setCompoundDrawablesWithIntrinsicBounds(emergencyIcon, 0, 0, 0);
}
button.setText(textId);
}
private boolean isEmergencyCallCapable() {
return getResources().getBoolean(com.android.internal.R.bool.config_voice_capable);
}
private void takeEmergencyCallAction() {
if (TelephonyManager.getDefault().getCallState() == TelephonyManager.CALL_STATE_OFFHOOK) {
resumeCall();
} else {
launchEmergencyDialer();
}
}
private void resumeCall() {
ITelephony phone = ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
if (phone != null) {
try {
phone.showCallScreen();
} catch (RemoteException e) {
Log.e(TAG, "Error calling ITelephony service: " + e);
}
}
}
private void launchEmergencyDialer() {
Intent intent = new Intent(ACTION_EMERGENCY_DIAL);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
startActivity(intent);
}
}