diff options
Diffstat (limited to 'policy/com')
27 files changed, 0 insertions, 12379 deletions
diff --git a/policy/com/android/internal/policy/impl/AccountUnlockScreen.java b/policy/com/android/internal/policy/impl/AccountUnlockScreen.java deleted file mode 100644 index 840c5e1..0000000 --- a/policy/com/android/internal/policy/impl/AccountUnlockScreen.java +++ /dev/null @@ -1,347 +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; - -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, - KeyguardUpdateMonitor.InfoCallback,View.OnClickListener, TextWatcher { - private static final String LOCK_PATTERN_PACKAGE = "com.android.settings"; - private static final String LOCK_PATTERN_CLASS = - "com.android.settings.ChooseLockPattern"; - - /** - * The amount of millis to stay awake once this screen detects activity - */ - private static final int AWAKE_POKE_MILLIS = 30000; - - private final KeyguardScreenCallback mCallback; - private final LockPatternUtils mLockPatternUtils; - private KeyguardUpdateMonitor mUpdateMonitor; - - private TextView mTopHeader; - private TextView mInstructions; - private EditText mLogin; - private EditText mPassword; - private Button mOk; - private Button mEmergencyCall; - - /** - * Shown while making asynchronous check of password. - */ - private ProgressDialog mCheckingDialog; - - /** - * 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); - - mEmergencyCall = (Button) findViewById(R.id.emergencyCall); - mEmergencyCall.setOnClickListener(this); - mLockPatternUtils.updateEmergencyCallButtonState(mEmergencyCall); - - mUpdateMonitor = updateMonitor; - mUpdateMonitor.registerInfoCallback(this); - } - - 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() { - - } - - /** {@inheritDoc} */ - public void onResume() { - // start fresh - mLogin.setText(""); - mPassword.setText(""); - mLogin.requestFocus(); - mLockPatternUtils.updateEmergencyCallButtonState(mEmergencyCall); - } - - /** {@inheritDoc} */ - public void cleanUp() { - if (mCheckingDialog != null) { - mCheckingDialog.hide(); - } - mUpdateMonitor.removeCallback(this); - } - - /** {@inheritDoc} */ - public void onClick(View v) { - mCallback.pokeWakelock(); - if (v == mOk) { - asyncCheckPassword(); - } - - if (v == mEmergencyCall) { - mCallback.takeEmergencyCallAction(); - } - } - - 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); - if (!mContext.getResources().getBoolean( - com.android.internal.R.bool.config_sf_slowBlur)) { - mCheckingDialog.getWindow().setFlags( - WindowManager.LayoutParams.FLAG_BLUR_BEHIND, - WindowManager.LayoutParams.FLAG_BLUR_BEHIND); - } - } - return mCheckingDialog; - } - - public void onPhoneStateChanged(String newState) { - mLockPatternUtils.updateEmergencyCallButtonState(mEmergencyCall); - } - - public void onRefreshBatteryInfo(boolean showBatteryInfo, boolean pluggedIn, int batteryLevel) { - - } - - public void onRefreshCarrierInfo(CharSequence plmn, CharSequence spn) { - - } - - public void onRingerModeChanged(int state) { - - } - - public void onTimeChanged() { - - } -} diff --git a/policy/com/android/internal/policy/impl/GlobalActions.java b/policy/com/android/internal/policy/impl/GlobalActions.java deleted file mode 100644 index 1f06dcc..0000000 --- a/policy/com/android/internal/policy/impl/GlobalActions.java +++ /dev/null @@ -1,578 +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; - -import android.app.Activity; -import android.app.AlertDialog; -import android.app.StatusBarManager; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.IntentFilter; -import android.media.AudioManager; -import android.os.Handler; -import android.os.Message; -import android.os.SystemProperties; -import android.provider.Settings; -import android.telephony.PhoneStateListener; -import android.telephony.ServiceState; -import android.telephony.TelephonyManager; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.view.WindowManager; -import android.widget.BaseAdapter; -import android.widget.ImageView; -import android.widget.TextView; -import com.android.internal.R; -import com.android.internal.app.ShutdownThread; -import com.android.internal.telephony.TelephonyIntents; -import com.android.internal.telephony.TelephonyProperties; -import com.google.android.collect.Lists; - -import java.util.ArrayList; - -/** - * Helper to show the global actions dialog. Each item is an {@link Action} that - * may show depending on whether the keyguard is showing, and whether the device - * is provisioned. - */ -class GlobalActions implements DialogInterface.OnDismissListener, DialogInterface.OnClickListener { - - private static final String TAG = "GlobalActions"; - - private StatusBarManager mStatusBar; - - private final Context mContext; - private final AudioManager mAudioManager; - - private ArrayList<Action> mItems; - private AlertDialog mDialog; - - private ToggleAction mSilentModeToggle; - private ToggleAction mAirplaneModeOn; - - private MyAdapter mAdapter; - - private boolean mKeyguardShowing = false; - private boolean mDeviceProvisioned = false; - private ToggleAction.State mAirplaneState = ToggleAction.State.Off; - private boolean mIsWaitingForEcmExit = false; - - /** - * @param context everything needs a context :( - */ - public GlobalActions(Context context) { - mContext = context; - mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE); - - // receive broadcasts - IntentFilter filter = new IntentFilter(); - filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); - filter.addAction(Intent.ACTION_SCREEN_OFF); - filter.addAction(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED); - context.registerReceiver(mBroadcastReceiver, filter); - - // get notified of phone state changes - TelephonyManager telephonyManager = - (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); - telephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_SERVICE_STATE); - } - - /** - * Show the global actions dialog (creating if necessary) - * @param keyguardShowing True if keyguard is showing - */ - public void showDialog(boolean keyguardShowing, boolean isDeviceProvisioned) { - mKeyguardShowing = keyguardShowing; - mDeviceProvisioned = isDeviceProvisioned; - if (mDialog == null) { - mStatusBar = (StatusBarManager)mContext.getSystemService(Context.STATUS_BAR_SERVICE); - mDialog = createDialog(); - } - prepareDialog(); - - mStatusBar.disable(StatusBarManager.DISABLE_EXPAND); - mDialog.show(); - } - - /** - * Create the global actions dialog. - * @return A new dialog. - */ - private AlertDialog createDialog() { - mSilentModeToggle = new ToggleAction( - R.drawable.ic_lock_silent_mode, - R.drawable.ic_lock_silent_mode_off, - R.string.global_action_toggle_silent_mode, - R.string.global_action_silent_mode_on_status, - R.string.global_action_silent_mode_off_status) { - - void willCreate() { - // XXX: FIXME: switch to ic_lock_vibrate_mode when available - mEnabledIconResId = (Settings.System.getInt(mContext.getContentResolver(), - Settings.System.VIBRATE_IN_SILENT, 1) == 1) - ? R.drawable.ic_lock_silent_mode_vibrate - : R.drawable.ic_lock_silent_mode; - } - - void onToggle(boolean on) { - if (on) { - mAudioManager.setRingerMode((Settings.System.getInt(mContext.getContentResolver(), - Settings.System.VIBRATE_IN_SILENT, 1) == 1) - ? AudioManager.RINGER_MODE_VIBRATE - : AudioManager.RINGER_MODE_SILENT); - } else { - mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL); - } - } - - public boolean showDuringKeyguard() { - return true; - } - - public boolean showBeforeProvisioning() { - return false; - } - }; - - mAirplaneModeOn = new ToggleAction( - R.drawable.ic_lock_airplane_mode, - R.drawable.ic_lock_airplane_mode_off, - R.string.global_actions_toggle_airplane_mode, - R.string.global_actions_airplane_mode_on_status, - R.string.global_actions_airplane_mode_off_status) { - - void onToggle(boolean on) { - if (Boolean.parseBoolean( - SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE))) { - mIsWaitingForEcmExit = true; - // Launch ECM exit dialog - Intent ecmDialogIntent = - new Intent(TelephonyIntents.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS, null); - ecmDialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - mContext.startActivity(ecmDialogIntent); - } else { - changeAirplaneModeSystemSetting(on); - } - } - - @Override - protected void changeStateFromPress(boolean buttonOn) { - // In ECM mode airplane state cannot be changed - if (!(Boolean.parseBoolean( - SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE)))) { - mState = buttonOn ? State.TurningOn : State.TurningOff; - mAirplaneState = mState; - } - } - - public boolean showDuringKeyguard() { - return true; - } - - public boolean showBeforeProvisioning() { - return false; - } - }; - - mItems = Lists.newArrayList( - // silent mode - mSilentModeToggle, - // next: airplane mode - mAirplaneModeOn, - // last: power off - new SinglePressAction( - com.android.internal.R.drawable.ic_lock_power_off, - R.string.global_action_power_off) { - - public void onPress() { - // shutdown by making sure radio and power are handled accordingly. - ShutdownThread.shutdown(mContext, true); - } - - public boolean showDuringKeyguard() { - return true; - } - - public boolean showBeforeProvisioning() { - return true; - } - }); - - mAdapter = new MyAdapter(); - - final AlertDialog.Builder ab = new AlertDialog.Builder(mContext); - - ab.setAdapter(mAdapter, this) - .setInverseBackgroundForced(true) - .setTitle(R.string.global_actions); - - final AlertDialog dialog = ab.create(); - dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG); - if (!mContext.getResources().getBoolean( - com.android.internal.R.bool.config_sf_slowBlur)) { - dialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND, - WindowManager.LayoutParams.FLAG_BLUR_BEHIND); - } - - dialog.setOnDismissListener(this); - - return dialog; - } - - private void prepareDialog() { - final boolean silentModeOn = - mAudioManager.getRingerMode() != AudioManager.RINGER_MODE_NORMAL; - mSilentModeToggle.updateState( - silentModeOn ? ToggleAction.State.On : ToggleAction.State.Off); - mAirplaneModeOn.updateState(mAirplaneState); - mAdapter.notifyDataSetChanged(); - if (mKeyguardShowing) { - mDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG); - } else { - mDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG); - } - } - - - /** {@inheritDoc} */ - public void onDismiss(DialogInterface dialog) { - mStatusBar.disable(StatusBarManager.DISABLE_NONE); - } - - /** {@inheritDoc} */ - public void onClick(DialogInterface dialog, int which) { - dialog.dismiss(); - mAdapter.getItem(which).onPress(); - } - - - /** - * The adapter used for the list within the global actions dialog, taking - * into account whether the keyguard is showing via - * {@link GlobalActions#mKeyguardShowing} and whether the device is provisioned - * via {@link GlobalActions#mDeviceProvisioned}. - */ - private class MyAdapter extends BaseAdapter { - - public int getCount() { - int count = 0; - - for (int i = 0; i < mItems.size(); i++) { - final Action action = mItems.get(i); - - if (mKeyguardShowing && !action.showDuringKeyguard()) { - continue; - } - if (!mDeviceProvisioned && !action.showBeforeProvisioning()) { - continue; - } - count++; - } - return count; - } - - @Override - public boolean isEnabled(int position) { - return getItem(position).isEnabled(); - } - - @Override - public boolean areAllItemsEnabled() { - return false; - } - - public Action getItem(int position) { - - int filteredPos = 0; - for (int i = 0; i < mItems.size(); i++) { - final Action action = mItems.get(i); - if (mKeyguardShowing && !action.showDuringKeyguard()) { - continue; - } - if (!mDeviceProvisioned && !action.showBeforeProvisioning()) { - continue; - } - if (filteredPos == position) { - return action; - } - filteredPos++; - } - - throw new IllegalArgumentException("position " + position + " out of " - + "range of showable actions, filtered count = " - + "= " + getCount() + ", keyguardshowing=" + mKeyguardShowing - + ", provisioned=" + mDeviceProvisioned); - } - - - public long getItemId(int position) { - return position; - } - - public View getView(int position, View convertView, ViewGroup parent) { - Action action = getItem(position); - return action.create(mContext, convertView, parent, LayoutInflater.from(mContext)); - } - } - - // note: the scheme below made more sense when we were planning on having - // 8 different things in the global actions dialog. seems overkill with - // only 3 items now, but may as well keep this flexible approach so it will - // be easy should someone decide at the last minute to include something - // else, such as 'enable wifi', or 'enable bluetooth' - - /** - * What each item in the global actions dialog must be able to support. - */ - private interface Action { - View create(Context context, View convertView, ViewGroup parent, LayoutInflater inflater); - - void onPress(); - - /** - * @return whether this action should appear in the dialog when the keygaurd - * is showing. - */ - boolean showDuringKeyguard(); - - /** - * @return whether this action should appear in the dialog before the - * device is provisioned. - */ - boolean showBeforeProvisioning(); - - boolean isEnabled(); - } - - /** - * A single press action maintains no state, just responds to a press - * and takes an action. - */ - private static abstract class SinglePressAction implements Action { - private final int mIconResId; - private final int mMessageResId; - - protected SinglePressAction(int iconResId, int messageResId) { - mIconResId = iconResId; - mMessageResId = messageResId; - } - - public boolean isEnabled() { - return true; - } - - abstract public void onPress(); - - public View create( - Context context, View convertView, ViewGroup parent, LayoutInflater inflater) { - View v = (convertView != null) ? - convertView : - inflater.inflate(R.layout.global_actions_item, parent, false); - - ImageView icon = (ImageView) v.findViewById(R.id.icon); - TextView messageView = (TextView) v.findViewById(R.id.message); - - v.findViewById(R.id.status).setVisibility(View.GONE); - - icon.setImageDrawable(context.getResources().getDrawable(mIconResId)); - messageView.setText(mMessageResId); - - return v; - } - } - - /** - * A toggle action knows whether it is on or off, and displays an icon - * and status message accordingly. - */ - private static abstract class ToggleAction implements Action { - - enum State { - Off(false), - TurningOn(true), - TurningOff(true), - On(false); - - private final boolean inTransition; - - State(boolean intermediate) { - inTransition = intermediate; - } - - public boolean inTransition() { - return inTransition; - } - } - - protected State mState = State.Off; - - // prefs - protected int mEnabledIconResId; - protected int mDisabledIconResid; - protected int mMessageResId; - protected int mEnabledStatusMessageResId; - protected int mDisabledStatusMessageResId; - - /** - * @param enabledIconResId The icon for when this action is on. - * @param disabledIconResid The icon for when this action is off. - * @param essage The general information message, e.g 'Silent Mode' - * @param enabledStatusMessageResId The on status message, e.g 'sound disabled' - * @param disabledStatusMessageResId The off status message, e.g. 'sound enabled' - */ - public ToggleAction(int enabledIconResId, - int disabledIconResid, - int essage, - int enabledStatusMessageResId, - int disabledStatusMessageResId) { - mEnabledIconResId = enabledIconResId; - mDisabledIconResid = disabledIconResid; - mMessageResId = essage; - mEnabledStatusMessageResId = enabledStatusMessageResId; - mDisabledStatusMessageResId = disabledStatusMessageResId; - } - - /** - * Override to make changes to resource IDs just before creating the - * View. - */ - void willCreate() { - - } - - public View create(Context context, View convertView, ViewGroup parent, - LayoutInflater inflater) { - willCreate(); - - View v = (convertView != null) ? - convertView : - inflater.inflate(R - .layout.global_actions_item, parent, false); - - ImageView icon = (ImageView) v.findViewById(R.id.icon); - TextView messageView = (TextView) v.findViewById(R.id.message); - TextView statusView = (TextView) v.findViewById(R.id.status); - - messageView.setText(mMessageResId); - - boolean on = ((mState == State.On) || (mState == State.TurningOn)); - icon.setImageDrawable(context.getResources().getDrawable( - (on ? mEnabledIconResId : mDisabledIconResid))); - statusView.setText(on ? mEnabledStatusMessageResId : mDisabledStatusMessageResId); - statusView.setVisibility(View.VISIBLE); - - final boolean enabled = isEnabled(); - messageView.setEnabled(enabled); - statusView.setEnabled(enabled); - icon.setEnabled(enabled); - v.setEnabled(enabled); - - return v; - } - - public final void onPress() { - if (mState.inTransition()) { - Log.w(TAG, "shouldn't be able to toggle when in transition"); - return; - } - - final boolean nowOn = !(mState == State.On); - onToggle(nowOn); - changeStateFromPress(nowOn); - } - - public boolean isEnabled() { - return !mState.inTransition(); - } - - /** - * Implementations may override this if their state can be in on of the intermediate - * states until some notification is received (e.g airplane mode is 'turning off' until - * we know the wireless connections are back online - * @param buttonOn Whether the button was turned on or off - */ - protected void changeStateFromPress(boolean buttonOn) { - mState = buttonOn ? State.On : State.Off; - } - - abstract void onToggle(boolean on); - - public void updateState(State state) { - mState = state; - } - } - - private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action) - || Intent.ACTION_SCREEN_OFF.equals(action)) { - String reason = intent.getStringExtra(PhoneWindowManager.SYSTEM_DIALOG_REASON_KEY); - if (!PhoneWindowManager.SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS.equals(reason)) { - mHandler.sendEmptyMessage(MESSAGE_DISMISS); - } - } else if (TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED.equals(action)) { - // Airplane mode can be changed after ECM exits if airplane toggle button - // is pressed during ECM mode - if (!(intent.getBooleanExtra("PHONE_IN_ECM_STATE", false)) && - mIsWaitingForEcmExit) { - mIsWaitingForEcmExit = false; - changeAirplaneModeSystemSetting(true); - } - } - } - }; - - PhoneStateListener mPhoneStateListener = new PhoneStateListener() { - @Override - public void onServiceStateChanged(ServiceState serviceState) { - final boolean inAirplaneMode = serviceState.getState() == ServiceState.STATE_POWER_OFF; - mAirplaneState = inAirplaneMode ? ToggleAction.State.On : ToggleAction.State.Off; - mAirplaneModeOn.updateState(mAirplaneState); - mAdapter.notifyDataSetChanged(); - } - }; - - private static final int MESSAGE_DISMISS = 0; - private Handler mHandler = new Handler() { - public void handleMessage(Message msg) { - if (msg.what == MESSAGE_DISMISS) { - if (mDialog != null) { - mDialog.dismiss(); - } - } - } - }; - - /** - * Change the airplane mode system setting - */ - private void changeAirplaneModeSystemSetting(boolean on) { - Settings.System.putInt( - mContext.getContentResolver(), - Settings.System.AIRPLANE_MODE_ON, - on ? 1 : 0); - Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); - intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); - intent.putExtra("state", on); - mContext.sendBroadcast(intent); - } -} diff --git a/policy/com/android/internal/policy/impl/IconUtilities.java b/policy/com/android/internal/policy/impl/IconUtilities.java deleted file mode 100644 index 99055cf..0000000 --- a/policy/com/android/internal/policy/impl/IconUtilities.java +++ /dev/null @@ -1,192 +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; - -import android.graphics.drawable.BitmapDrawable; -import android.graphics.drawable.Drawable; -import android.graphics.drawable.PaintDrawable; -import android.graphics.drawable.StateListDrawable; -import android.graphics.Bitmap; -import android.graphics.BlurMaskFilter; -import android.graphics.Canvas; -import android.graphics.ColorMatrix; -import android.graphics.ColorMatrixColorFilter; -import android.graphics.Paint; -import android.graphics.PaintFlagsDrawFilter; -import android.graphics.PixelFormat; -import android.graphics.PorterDuff; -import android.graphics.Rect; -import android.graphics.RectF; -import android.graphics.TableMaskFilter; -import android.graphics.Typeface; -import android.text.Layout.Alignment; -import android.text.StaticLayout; -import android.text.TextPaint; -import android.util.DisplayMetrics; -import android.util.Log; -import android.content.res.Resources; -import android.content.Context; - -/** - * Various utilities shared amongst the Launcher's classes. - */ -final class IconUtilities { - private static final String TAG = "IconUtilities"; - - private static final int sColors[] = { 0xffff0000, 0xff00ff00, 0xff0000ff }; - - private int mIconWidth = -1; - private int mIconHeight = -1; - private int mIconTextureWidth = -1; - private int mIconTextureHeight = -1; - - private final Paint mPaint = new Paint(); - private final Paint mBlurPaint = new Paint(); - private final Paint mGlowColorPressedPaint = new Paint(); - private final Paint mGlowColorFocusedPaint = new Paint(); - private final Rect mOldBounds = new Rect(); - private final Canvas mCanvas = new Canvas(); - private final DisplayMetrics mDisplayMetrics; - - private int mColorIndex = 0; - - public IconUtilities(Context context) { - final Resources resources = context.getResources(); - DisplayMetrics metrics = mDisplayMetrics = resources.getDisplayMetrics(); - final float density = metrics.density; - final float blurPx = 5 * density; - - mIconWidth = mIconHeight = (int) resources.getDimension(android.R.dimen.app_icon_size); - mIconTextureWidth = mIconTextureHeight = mIconWidth + (int)(blurPx*2); - - mBlurPaint.setMaskFilter(new BlurMaskFilter(blurPx, BlurMaskFilter.Blur.NORMAL)); - mGlowColorPressedPaint.setColor(0xffffc300); - mGlowColorPressedPaint.setMaskFilter(TableMaskFilter.CreateClipTable(0, 30)); - mGlowColorFocusedPaint.setColor(0xffff8e00); - mGlowColorFocusedPaint.setMaskFilter(TableMaskFilter.CreateClipTable(0, 30)); - - ColorMatrix cm = new ColorMatrix(); - cm.setSaturation(0.2f); - - mCanvas.setDrawFilter(new PaintFlagsDrawFilter(Paint.DITHER_FLAG, - Paint.FILTER_BITMAP_FLAG)); - } - - public Drawable createIconDrawable(Drawable src) { - Bitmap scaled = createIconBitmap(src); - - StateListDrawable result = new StateListDrawable(); - - result.addState(new int[] { android.R.attr.state_focused }, - new BitmapDrawable(createSelectedBitmap(scaled, false))); - result.addState(new int[] { android.R.attr.state_pressed }, - new BitmapDrawable(createSelectedBitmap(scaled, true))); - result.addState(new int[0], new BitmapDrawable(scaled)); - - result.setBounds(0, 0, mIconTextureWidth, mIconTextureHeight); - return result; - } - - /** - * Returns a bitmap suitable for the all apps view. The bitmap will be a power - * of two sized ARGB_8888 bitmap that can be used as a gl texture. - */ - private Bitmap createIconBitmap(Drawable icon) { - int width = mIconWidth; - int height = mIconHeight; - - if (icon instanceof PaintDrawable) { - PaintDrawable painter = (PaintDrawable) icon; - painter.setIntrinsicWidth(width); - painter.setIntrinsicHeight(height); - } else if (icon instanceof BitmapDrawable) { - // Ensure the bitmap has a density. - BitmapDrawable bitmapDrawable = (BitmapDrawable) icon; - Bitmap bitmap = bitmapDrawable.getBitmap(); - if (bitmap.getDensity() == Bitmap.DENSITY_NONE) { - bitmapDrawable.setTargetDensity(mDisplayMetrics); - } - } - int sourceWidth = icon.getIntrinsicWidth(); - int sourceHeight = icon.getIntrinsicHeight(); - - if (sourceWidth > 0 && sourceWidth > 0) { - // There are intrinsic sizes. - if (width < sourceWidth || height < sourceHeight) { - // It's too big, scale it down. - final float ratio = (float) sourceWidth / sourceHeight; - if (sourceWidth > sourceHeight) { - height = (int) (width / ratio); - } else if (sourceHeight > sourceWidth) { - width = (int) (height * ratio); - } - } else if (sourceWidth < width && sourceHeight < height) { - // It's small, use the size they gave us. - width = sourceWidth; - height = sourceHeight; - } - } - - // no intrinsic size --> use default size - int textureWidth = mIconTextureWidth; - int textureHeight = mIconTextureHeight; - - final Bitmap bitmap = Bitmap.createBitmap(textureWidth, textureHeight, - Bitmap.Config.ARGB_8888); - final Canvas canvas = mCanvas; - canvas.setBitmap(bitmap); - - final int left = (textureWidth-width) / 2; - final int top = (textureHeight-height) / 2; - - if (false) { - // draw a big box for the icon for debugging - canvas.drawColor(sColors[mColorIndex]); - if (++mColorIndex >= sColors.length) mColorIndex = 0; - Paint debugPaint = new Paint(); - debugPaint.setColor(0xffcccc00); - canvas.drawRect(left, top, left+width, top+height, debugPaint); - } - - mOldBounds.set(icon.getBounds()); - icon.setBounds(left, top, left+width, top+height); - icon.draw(canvas); - icon.setBounds(mOldBounds); - - return bitmap; - } - - private Bitmap createSelectedBitmap(Bitmap src, boolean pressed) { - final Bitmap result = Bitmap.createBitmap(mIconTextureWidth, mIconTextureHeight, - Bitmap.Config.ARGB_8888); - final Canvas dest = new Canvas(result); - - dest.drawColor(0, PorterDuff.Mode.CLEAR); - - int[] xy = new int[2]; - Bitmap mask = src.extractAlpha(mBlurPaint, xy); - - dest.drawBitmap(mask, xy[0], xy[1], - pressed ? mGlowColorPressedPaint : mGlowColorFocusedPaint); - - mask.recycle(); - - dest.drawBitmap(src, 0, 0, mPaint); - - return result; - } -} diff --git a/policy/com/android/internal/policy/impl/KeyguardScreen.java b/policy/com/android/internal/policy/impl/KeyguardScreen.java deleted file mode 100644 index bbb6875..0000000 --- a/policy/com/android/internal/policy/impl/KeyguardScreen.java +++ /dev/null @@ -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; - -/** - * 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(); -} diff --git a/policy/com/android/internal/policy/impl/KeyguardScreenCallback.java b/policy/com/android/internal/policy/impl/KeyguardScreenCallback.java deleted file mode 100644 index a843603..0000000 --- a/policy/com/android/internal/policy/impl/KeyguardScreenCallback.java +++ /dev/null @@ -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; - -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(); -} diff --git a/policy/com/android/internal/policy/impl/KeyguardUpdateMonitor.java b/policy/com/android/internal/policy/impl/KeyguardUpdateMonitor.java deleted file mode 100644 index b225e56..0000000 --- a/policy/com/android/internal/policy/impl/KeyguardUpdateMonitor.java +++ /dev/null @@ -1,526 +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; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.res.Configuration; -import android.database.ContentObserver; -import static android.os.BatteryManager.BATTERY_STATUS_CHARGING; -import static android.os.BatteryManager.BATTERY_STATUS_FULL; -import static android.os.BatteryManager.BATTERY_STATUS_UNKNOWN; -import android.media.AudioManager; -import android.os.Handler; -import android.os.Message; -import android.os.SystemClock; -import android.provider.Settings; -import android.provider.Telephony; -import static android.provider.Telephony.Intents.EXTRA_PLMN; -import static android.provider.Telephony.Intents.EXTRA_SHOW_PLMN; -import static android.provider.Telephony.Intents.EXTRA_SHOW_SPN; -import static android.provider.Telephony.Intents.EXTRA_SPN; -import static android.provider.Telephony.Intents.SPN_STRINGS_UPDATED_ACTION; - -import com.android.internal.telephony.IccCard; -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 { - - static private final String TAG = "KeyguardUpdateMonitor"; - static private final boolean DEBUG = false; - - private static final int LOW_BATTERY_THRESHOLD = 20; - - private final Context mContext; - - private IccCard.State mSimState = IccCard.State.READY; - - private boolean mKeyguardBypassEnabled; - - private boolean mDevicePluggedIn; - - private boolean mDeviceProvisioned; - - private int mBatteryLevel; - - private CharSequence mTelephonyPlmn; - private CharSequence mTelephonySpn; - - private int mFailedAttempts = 0; - - private Handler mHandler; - - private ArrayList<InfoCallback> mInfoCallbacks = Lists.newArrayList(); - private ArrayList<SimStateCallback> mSimStateCallbacks = Lists.newArrayList(); - private ContentObserver mContentObserver; - - // messages for the handler - 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; - - - /** - * 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 IccCard.State simState; - - private SimArgs(Intent intent) { - if (!TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(intent.getAction())) { - throw new IllegalArgumentException("only handles intent ACTION_SIM_STATE_CHANGED"); - } - String stateExtra = intent.getStringExtra(IccCard.INTENT_KEY_ICC_STATE); - if (IccCard.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) { - this.simState = IccCard.State.ABSENT; - } else if (IccCard.INTENT_VALUE_ICC_READY.equals(stateExtra)) { - this.simState = IccCard.State.READY; - } else if (IccCard.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) { - final String lockedReason = intent - .getStringExtra(IccCard.INTENT_KEY_LOCKED_REASON); - if (IccCard.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) { - this.simState = IccCard.State.PIN_REQUIRED; - } else if (IccCard.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) { - this.simState = IccCard.State.PUK_REQUIRED; - } else { - this.simState = IccCard.State.UNKNOWN; - } - } else if (IccCard.INTENT_VALUE_LOCKED_NETWORK.equals(stateExtra)) { - this.simState = IccCard.State.NETWORK_LOCKED; - } else { - this.simState = IccCard.State.UNKNOWN; - } - } - - public String toString() { - return simState.toString(); - } - } - - public KeyguardUpdateMonitor(Context context) { - mContext = context; - - mHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case MSG_TIME_UPDATE: - handleTimeUpdate(); - break; - case MSG_BATTERY_UPDATE: - handleBatteryUpdate(msg.arg1, msg.arg2); - 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; - } - } - }; - - mKeyguardBypassEnabled = context.getResources().getBoolean( - com.android.internal.R.bool.config_bypass_keyguard_if_slider_open); - - mDeviceProvisioned = Settings.Secure.getInt( - mContext.getContentResolver(), Settings.Secure.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) { - mContentObserver = new ContentObserver(mHandler) { - @Override - public void onChange(boolean selfChange) { - super.onChange(selfChange); - mDeviceProvisioned = Settings.Secure.getInt(mContext.getContentResolver(), - Settings.Secure.DEVICE_PROVISIONED, 0) != 0; - if (mDeviceProvisioned && mContentObserver != null) { - // We don't need the observer anymore... - mContext.getContentResolver().unregisterContentObserver(mContentObserver); - mContentObserver = null; - } - if (DEBUG) Log.d(TAG, "DEVICE_PROVISIONED state = " + mDeviceProvisioned); - } - }; - - mContext.getContentResolver().registerContentObserver( - Settings.Secure.getUriFor(Settings.Secure.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... - mDeviceProvisioned = Settings.Secure.getInt(mContext.getContentResolver(), - Settings.Secure.DEVICE_PROVISIONED, 0) != 0; - } - - // take a guess to start - mSimState = IccCard.State.READY; - mDevicePluggedIn = true; - mBatteryLevel = 100; - - mTelephonyPlmn = getDefaultPlmn(); - - // setup receiver - 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(SPN_STRINGS_UPDATED_ACTION); - filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION); - context.registerReceiver(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 (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 pluggedInStatus = intent - .getIntExtra("status", BATTERY_STATUS_UNKNOWN); - int batteryLevel = intent.getIntExtra("level", 0); - final Message msg = mHandler.obtainMessage( - MSG_BATTERY_UPDATE, - pluggedInStatus, - batteryLevel); - mHandler.sendMessage(msg); - } else if (TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(action)) { - mHandler.sendMessage(mHandler.obtainMessage( - MSG_SIM_STATE_CHANGE, - new SimArgs(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)); - } - } - }, filter); - } - - protected void handlePhoneStateChanged(String newState) { - if (DEBUG) Log.d(TAG, "handlePhoneStateChanged(" + newState + ")"); - for (int i = 0; i < mInfoCallbacks.size(); i++) { - mInfoCallbacks.get(i).onPhoneStateChanged(newState); - } - } - - protected void handleRingerModeChange(int mode) { - if (DEBUG) Log.d(TAG, "handleRingerModeChange(" + mode + ")"); - for (int i = 0; i < mInfoCallbacks.size(); i++) { - mInfoCallbacks.get(i).onRingerModeChanged(mode); - } - } - - /** - * Handle {@link #MSG_TIME_UPDATE} - */ - private void handleTimeUpdate() { - if (DEBUG) Log.d(TAG, "handleTimeUpdate"); - for (int i = 0; i < mInfoCallbacks.size(); i++) { - mInfoCallbacks.get(i).onTimeChanged(); - } - } - - /** - * Handle {@link #MSG_BATTERY_UPDATE} - */ - private void handleBatteryUpdate(int pluggedInStatus, int batteryLevel) { - if (DEBUG) Log.d(TAG, "handleBatteryUpdate"); - final boolean pluggedIn = isPluggedIn(pluggedInStatus); - - if (isBatteryUpdateInteresting(pluggedIn, batteryLevel)) { - mBatteryLevel = batteryLevel; - mDevicePluggedIn = pluggedIn; - for (int i = 0; i < mInfoCallbacks.size(); i++) { - mInfoCallbacks.get(i).onRefreshBatteryInfo( - shouldShowBatteryInfo(), pluggedIn, batteryLevel); - } - } - } - - /** - * Handle {@link #MSG_CARRIER_INFO_UPDATE} - */ - private void handleCarrierInfoUpdate() { - if (DEBUG) Log.d(TAG, "handleCarrierInfoUpdate: plmn = " + mTelephonyPlmn - + ", spn = " + mTelephonySpn); - - for (int i = 0; i < mInfoCallbacks.size(); i++) { - mInfoCallbacks.get(i).onRefreshCarrierInfo(mTelephonyPlmn, mTelephonySpn); - } - } - - /** - * Handle {@link #MSG_SIM_STATE_CHANGE} - */ - private void handleSimStateChange(SimArgs simArgs) { - final IccCard.State state = simArgs.simState; - - if (DEBUG) { - Log.d(TAG, "handleSimStateChange: intentValue = " + simArgs + " " - + "state resolved to " + state.toString()); - } - - if (state != IccCard.State.UNKNOWN && state != mSimState) { - mSimState = state; - for (int i = 0; i < mSimStateCallbacks.size(); i++) { - mSimStateCallbacks.get(i).onSimStateChanged(state); - } - } - } - - /** - * @param status One of the statuses of {@link android.os.BatteryManager} - * @return Whether the status maps to a status for being plugged in. - */ - private boolean isPluggedIn(int status) { - return status == BATTERY_STATUS_CHARGING || status == BATTERY_STATUS_FULL; - } - - private boolean isBatteryUpdateInteresting(boolean pluggedIn, int batteryLevel) { - // change in plug is always interesting - if (mDevicePluggedIn != pluggedIn) { - return true; - } - - // change in battery level while plugged in - if (pluggedIn && mBatteryLevel != batteryLevel) { - return true; - } - - if (!pluggedIn) { - // not plugged in and below threshold - if (batteryLevel < LOW_BATTERY_THRESHOLD && batteryLevel != mBatteryLevel) { - return true; - } - } - return false; - } - - /** - * @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 getTelephonyPlmnFrom(Intent intent) { - if (intent.getBooleanExtra(EXTRA_SHOW_PLMN, false)) { - final String plmn = intent.getStringExtra(EXTRA_PLMN); - if (plmn != null) { - return plmn; - } else { - return 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(EXTRA_SHOW_SPN, false)) { - final String spn = intent.getStringExtra(EXTRA_SPN); - if (spn != null) { - return spn; - } - } - return null; - } - - /** - * Remove the given observer from being registered from any of the kinds - * of callbacks. - * @param observer The observer to remove (an instance of {@link ConfigurationChangeCallback}, - * {@link InfoCallback} or {@link SimStateCallback} - */ - public void removeCallback(Object observer) { - mInfoCallbacks.remove(observer); - mSimStateCallbacks.remove(observer); - } - - /** - * Callback for general information relevant to lock screen. - */ - interface InfoCallback { - void onRefreshBatteryInfo(boolean showBatteryInfo, boolean pluggedIn, int batteryLevel); - void onTimeChanged(); - - /** - * @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(String newState); - } - - /** - * Callback to notify of sim state change. - */ - interface SimStateCallback { - void onSimStateChanged(IccCard.State simState); - } - - /** - * Register to receive notifications about general keyguard information - * (see {@link InfoCallback}. - * @param callback The callback. - */ - public void registerInfoCallback(InfoCallback callback) { - if (!mInfoCallbacks.contains(callback)) { - mInfoCallbacks.add(callback); - } else { - Log.e(TAG, "Object tried to add another INFO callback", new Exception("Whoops")); - } - } - - /** - * Register to be notified of sim state changes. - * @param callback The callback. - */ - public void registerSimStateCallback(SimStateCallback callback) { - if (!mSimStateCallbacks.contains(callback)) { - mSimStateCallbacks.add(callback); - } else { - Log.e(TAG, "Object tried to add another SIM callback", new Exception("Whoops")); - } - } - - public IccCard.State getSimState() { - return mSimState; - } - - /** - * Report that the user succesfully entered the sim pin so we - * have the information earlier than waiting for the intent - * broadcast from the telephony code. - */ - public void reportSimPinUnlocked() { - mSimState = IccCard.State.READY; - } - - public boolean isKeyguardBypassEnabled() { - return mKeyguardBypassEnabled; - } - - public boolean isDevicePluggedIn() { - return mDevicePluggedIn; - } - - public int getBatteryLevel() { - return mBatteryLevel; - } - - public boolean shouldShowBatteryInfo() { - return mDevicePluggedIn || mBatteryLevel < LOW_BATTERY_THRESHOLD; - } - - 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; - } - - public void reportFailedAttempt() { - mFailedAttempts++; - } -} diff --git a/policy/com/android/internal/policy/impl/KeyguardViewBase.java b/policy/com/android/internal/policy/impl/KeyguardViewBase.java deleted file mode 100644 index 9dcbcb6..0000000 --- a/policy/com/android/internal/policy/impl/KeyguardViewBase.java +++ /dev/null @@ -1,209 +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; - -import android.content.Context; -import android.content.Intent; -import android.media.AudioManager; -import android.telephony.TelephonyManager; -import android.view.KeyEvent; -import android.view.View; -import android.view.Gravity; -import android.widget.FrameLayout; -import android.util.AttributeSet; - -/** - * 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 KeyguardViewCallback mCallback; - private AudioManager mAudioManager; - private TelephonyManager mTelephonyManager = null; - - public KeyguardViewBase(Context context) { - super(context); - - // drop shadow below status bar in keyguard too - mForegroundInPadding = false; - setForegroundGravity(Gravity.FILL_HORIZONTAL | Gravity.TOP); - setForeground( - context.getResources().getDrawable( - com.android.internal.R.drawable.title_bar_shadow)); - } - - // used to inject callback - void setCallback(KeyguardViewCallback callback) { - mCallback = callback; - } - - 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 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. - */ - 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_PAUSE: - /* Suppress PLAYPAUSE 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_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_FAST_FORWARD: { - Intent intent = new Intent(Intent.ACTION_MEDIA_BUTTON, null); - intent.putExtra(Intent.EXTRA_KEY_EVENT, event); - getContext().sendOrderedBroadcast(intent, null); - return true; - } - - case KeyEvent.KEYCODE_VOLUME_UP: - case KeyEvent.KEYCODE_VOLUME_DOWN: { - synchronized (this) { - if (mAudioManager == null) { - mAudioManager = (AudioManager) getContext().getSystemService( - Context.AUDIO_SERVICE); - } - } - // Volume buttons should only function for music. - if (mAudioManager.isMusicActive()) { - mAudioManager.adjustStreamVolume( - AudioManager.STREAM_MUSIC, - keyCode == KeyEvent.KEYCODE_VOLUME_UP - ? AudioManager.ADJUST_RAISE - : AudioManager.ADJUST_LOWER, - 0); - } - // Don't execute default volume behavior - return true; - } - } - } else if (event.getAction() == KeyEvent.ACTION_UP) { - switch (keyCode) { - case KeyEvent.KEYCODE_MUTE: - case KeyEvent.KEYCODE_HEADSETHOOK: - 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_FAST_FORWARD: { - Intent intent = new Intent(Intent.ACTION_MEDIA_BUTTON, null); - intent.putExtra(Intent.EXTRA_KEY_EVENT, event); - getContext().sendOrderedBroadcast(intent, null); - return true; - } - } - } - return false; - } - -} diff --git a/policy/com/android/internal/policy/impl/KeyguardViewCallback.java b/policy/com/android/internal/policy/impl/KeyguardViewCallback.java deleted file mode 100644 index b376d65..0000000 --- a/policy/com/android/internal/policy/impl/KeyguardViewCallback.java +++ /dev/null @@ -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; - -/** - * 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(); -} diff --git a/policy/com/android/internal/policy/impl/KeyguardViewManager.java b/policy/com/android/internal/policy/impl/KeyguardViewManager.java deleted file mode 100644 index ba1d7f5..0000000 --- a/policy/com/android/internal/policy/impl/KeyguardViewManager.java +++ /dev/null @@ -1,241 +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; - -import com.android.internal.R; - -import android.content.Context; -import android.content.pm.ActivityInfo; -import android.graphics.PixelFormat; -import android.graphics.Canvas; -import android.util.Log; -import android.view.View; -import android.view.ViewGroup; -import android.view.ViewManager; -import android.view.WindowManager; -import android.widget.FrameLayout; - -/** - * 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; - - /** - * @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); - - 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_KEEP_SURFACE_WHILE_ANIMATING - /*| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN - | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR*/ ; - if (!mNeedsInput) { - flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; - } - WindowManager.LayoutParams lp = new WindowManager.LayoutParams( - stretch, stretch, WindowManager.LayoutParams.TYPE_KEYGUARD, - flags, PixelFormat.TRANSLUCENT); - lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN; - lp.windowAnimations = com.android.internal.R.style.Animation_LockScreen; - lp.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR; - lp.setTitle("Keyguard"); - mWindowLayoutParams = lp; - - mViewManager.addView(mKeyguardHost, lp); - } - - if (mKeyguardView == null) { - if (DEBUG) Log.d(TAG, "keyguard view is null, creating it..."); - mKeyguardView = mKeyguardViewProperties.createKeyguardView(mContext, mUpdateMonitor, this); - mKeyguardView.setId(R.id.lock_screen); - mKeyguardView.setCallback(mCallback); - - final ViewGroup.LayoutParams lp = new FrameLayout.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT); - - mKeyguardHost.addView(mKeyguardView, lp); - - if (mScreenOn) { - mKeyguardView.onScreenTurnedOn(); - } - } - - 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() { - if (DEBUG) Log.d(TAG, "onScreenTurnedOn()"); - mScreenOn = true; - if (mKeyguardView != null) { - mKeyguardView.onScreenTurnedOn(); - } - } - - 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. - */ - 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) { - mKeyguardHost.removeView(lastView); - lastView.cleanUp(); - } - } - }, 500); - } - } - } - - /** - * @return Whether the keyguard is showing - */ - public synchronized boolean isShowing() { - return (mKeyguardHost != null && mKeyguardHost.getVisibility() == View.VISIBLE); - } -} diff --git a/policy/com/android/internal/policy/impl/KeyguardViewMediator.java b/policy/com/android/internal/policy/impl/KeyguardViewMediator.java deleted file mode 100644 index 88203c3..0000000 --- a/policy/com/android/internal/policy/impl/KeyguardViewMediator.java +++ /dev/null @@ -1,1136 +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; - -import com.android.internal.telephony.IccCard; -import com.android.internal.widget.LockPatternUtils; - -import android.app.ActivityManagerNative; -import android.app.AlarmManager; -import android.app.PendingIntent; -import android.app.StatusBarManager; -import android.content.BroadcastReceiver; -import android.content.ContentResolver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.media.AudioManager; -import android.media.Ringtone; -import android.media.RingtoneManager; -import android.net.Uri; -import android.os.Handler; -import android.os.IBinder; -import android.os.LocalPowerManager; -import android.os.Message; -import android.os.PowerManager; -import android.os.RemoteException; -import android.os.SystemClock; -import android.os.SystemProperties; -import android.provider.Settings; -import android.telephony.TelephonyManager; -import android.util.Config; -import android.util.EventLog; -import android.util.Log; -import android.view.KeyEvent; -import android.view.WindowManagerImpl; -import android.view.WindowManagerPolicy; - - -/** - * Mediates requests related to the keyguard. This includes queries about the - * state of the keyguard, power management events that effect whether the keyguard - * should be shown or reset, callbacks to the phone window manager to notify - * it of when the keyguard is showing, and events from the keyguard view itself - * stating that the keyguard was succesfully unlocked. - * - * Note that the keyguard view is shown when the screen is off (as appropriate) - * so that once the screen comes on, it will be ready immediately. - * - * Example queries about the keyguard: - * - is {movement, key} one that should wake the keygaurd? - * - is the keyguard showing? - * - are input events restricted due to the state of the keyguard? - * - * Callbacks to the phone window manager: - * - the keyguard is showing - * - * Example external events that translate to keyguard view changes: - * - screen turned off -> reset the keyguard, and show it so it will be ready - * next time the screen turns on - * - keyboard is slid open -> if the keyguard is not secure, hide it - * - * Events from the keyguard view: - * - user succesfully unlocked keyguard -> hide keyguard view, and no longer - * restrict input events. - * - * Note: in addition to normal power managment events that effect the state of - * whether the keyguard should be showing, external apps and services may request - * that the keyguard be disabled via {@link #setKeyguardEnabled(boolean)}. When - * false, this will override all other conditions for turning on the keyguard. - * - * Threading and synchronization: - * This class is created by the initialization routine of the {@link WindowManagerPolicy}, - * and runs on its thread. The keyguard UI is created from that thread in the - * constructor of this class. The apis may be called from other threads, including the - * {@link com.android.server.InputManager}'s and {@link android.view.WindowManager}'s. - * Therefore, methods on this class are synchronized, and any action that is pointed - * directly to the keyguard UI is posted to a {@link Handler} to ensure it is taken on the UI - * thread of the keyguard. - */ -public class KeyguardViewMediator implements KeyguardViewCallback, - KeyguardUpdateMonitor.SimStateCallback { - private final static boolean DEBUG = false && Config.LOGD; - private final static boolean DBG_WAKE = DEBUG || true; - - private final static String TAG = "KeyguardViewMediator"; - - private static final String DELAYED_KEYGUARD_ACTION = - "com.android.internal.policy.impl.PhoneWindowManager.DELAYED_KEYGUARD"; - - // used for handler messages - private static final int TIMEOUT = 1; - private static final int SHOW = 2; - private static final int HIDE = 3; - private static final int RESET = 4; - private static final int VERIFY_UNLOCK = 5; - private static final int NOTIFY_SCREEN_OFF = 6; - private static final int NOTIFY_SCREEN_ON = 7; - private static final int WAKE_WHEN_READY = 8; - private static final int KEYGUARD_DONE = 9; - private static final int KEYGUARD_DONE_DRAWING = 10; - private static final int KEYGUARD_DONE_AUTHENTICATING = 11; - private static final int SET_HIDDEN = 12; - private static final int KEYGUARD_TIMEOUT = 13; - - /** - * The default amount of time we stay awake (used for all key input) - */ - protected static final int AWAKE_INTERVAL_DEFAULT_MS = 5000; - - - /** - * The default amount of time we stay awake (used for all key input) when - * the keyboard is open - */ - protected static final int AWAKE_INTERVAL_DEFAULT_KEYBOARD_OPEN_MS = 10000; - - /** - * How long to wait after the screen turns off due to timeout before - * turning on the keyguard (i.e, the user has this much time to turn - * the screen back on without having to face the keyguard). - */ - private static final int KEYGUARD_DELAY_MS = 5000; - - /** - * How long we'll wait for the {@link KeyguardViewCallback#keyguardDoneDrawing()} - * callback before unblocking a call to {@link #setKeyguardEnabled(boolean)} - * that is reenabling the keyguard. - */ - private static final int KEYGUARD_DONE_DRAWING_TIMEOUT_MS = 2000; - - private Context mContext; - private AlarmManager mAlarmManager; - private StatusBarManager mStatusBarManager; - private boolean mShowLockIcon; - private boolean mShowingLockIcon; - - private boolean mSystemReady; - - // Whether the next call to playSounds() should be skipped. Defaults to - // true because the first lock (on boot) should be silent. - private boolean mSuppressNextLockSound = true; - - - /** Low level access to the power manager for enableUserActivity. Having this - * requires that we run in the system process. */ - LocalPowerManager mRealPowerManager; - - /** High level access to the power manager for WakeLocks */ - private PowerManager mPM; - - /** - * Used to keep the device awake while the keyguard is showing, i.e for - * calls to {@link #pokeWakelock()} - */ - private PowerManager.WakeLock mWakeLock; - - /** - * Used to keep the device awake while to ensure the keyguard finishes opening before - * we sleep. - */ - private PowerManager.WakeLock mShowKeyguardWakeLock; - - /** - * Does not turn on screen, held while a call to {@link KeyguardViewManager#wakeWhenReadyTq(int)} - * is called to make sure the device doesn't sleep before it has a chance to poke - * the wake lock. - * @see #wakeWhenReadyLocked(int) - */ - private PowerManager.WakeLock mWakeAndHandOff; - - private KeyguardViewManager mKeyguardViewManager; - - // these are protected by synchronized (this) - - /** - * External apps (like the phone app) can tell us to disable the keygaurd. - */ - private boolean mExternallyEnabled = true; - - /** - * Remember if an external call to {@link #setKeyguardEnabled} with value - * false caused us to hide the keyguard, so that we need to reshow it once - * the keygaurd is reenabled with another call with value true. - */ - private boolean mNeedToReshowWhenReenabled = false; - - // cached value of whether we are showing (need to know this to quickly - // answer whether the input should be restricted) - private boolean mShowing = false; - - // true if the keyguard is hidden by another window - private boolean mHidden = false; - - /** - * Helps remember whether the screen has turned on since the last time - * it turned off due to timeout. see {@link #onScreenTurnedOff(int)} - */ - private int mDelayedShowingSequence; - - private int mWakelockSequence; - - private PhoneWindowManager mCallback; - - /** - * If the user has disabled the keyguard, then requests to exit, this is - * how we'll ultimately let them know whether it was successful. We use this - * var being non-null as an indicator that there is an in progress request. - */ - private WindowManagerPolicy.OnKeyguardExitResult mExitSecureCallback; - - // the properties of the keyguard - private KeyguardViewProperties mKeyguardViewProperties; - - private KeyguardUpdateMonitor mUpdateMonitor; - - private boolean mKeyboardOpen = false; - - private boolean mScreenOn = false; - - // last known state of the cellular connection - private String mPhoneState = TelephonyManager.EXTRA_STATE_IDLE; - - /** - * we send this intent when the keyguard is dismissed. - */ - private Intent mUserPresentIntent; - - /** - * {@link #setKeyguardEnabled} waits on this condition when it reenables - * the keyguard. - */ - private boolean mWaitingUntilKeyguardVisible = false; - - public KeyguardViewMediator(Context context, PhoneWindowManager callback, - LocalPowerManager powerManager) { - mContext = context; - - mRealPowerManager = powerManager; - mPM = (PowerManager) context.getSystemService(Context.POWER_SERVICE); - mWakeLock = mPM.newWakeLock( - PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, - "keyguard"); - mWakeLock.setReferenceCounted(false); - mShowKeyguardWakeLock = mPM.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "show keyguard"); - mShowKeyguardWakeLock.setReferenceCounted(false); - - mWakeAndHandOff = mPM.newWakeLock( - PowerManager.PARTIAL_WAKE_LOCK, - "keyguardWakeAndHandOff"); - mWakeAndHandOff.setReferenceCounted(false); - - IntentFilter filter = new IntentFilter(); - filter.addAction(DELAYED_KEYGUARD_ACTION); - filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED); - context.registerReceiver(mBroadCastReceiver, filter); - mAlarmManager = (AlarmManager) context - .getSystemService(Context.ALARM_SERVICE); - mCallback = callback; - - mUpdateMonitor = new KeyguardUpdateMonitor(context); - - mUpdateMonitor.registerSimStateCallback(this); - - mKeyguardViewProperties = new LockPatternKeyguardViewProperties( - new LockPatternUtils(mContext), mUpdateMonitor); - - mKeyguardViewManager = new KeyguardViewManager( - context, WindowManagerImpl.getDefault(), this, - mKeyguardViewProperties, mUpdateMonitor); - - mUserPresentIntent = new Intent(Intent.ACTION_USER_PRESENT); - mUserPresentIntent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); - - final ContentResolver cr = mContext.getContentResolver(); - mShowLockIcon = (Settings.System.getInt(cr, "show_status_bar_lock", 0) == 1); - } - - /** - * Let us know that the system is ready after startup. - */ - public void onSystemReady() { - synchronized (this) { - if (DEBUG) Log.d(TAG, "onSystemReady"); - mSystemReady = true; - doKeyguard(); - } - } - - /** - * Called to let us know the screen was turned off. - * @param why either {@link WindowManagerPolicy#OFF_BECAUSE_OF_USER}, - * {@link WindowManagerPolicy#OFF_BECAUSE_OF_TIMEOUT} or - * {@link WindowManagerPolicy#OFF_BECAUSE_OF_PROX_SENSOR}. - */ - public void onScreenTurnedOff(int why) { - synchronized (this) { - mScreenOn = false; - if (DEBUG) Log.d(TAG, "onScreenTurnedOff(" + why + ")"); - - if (mExitSecureCallback != null) { - if (DEBUG) Log.d(TAG, "pending exit secure callback cancelled"); - mExitSecureCallback.onKeyguardExitResult(false); - mExitSecureCallback = null; - if (!mExternallyEnabled) { - hideLocked(); - } - } else if (mShowing) { - notifyScreenOffLocked(); - resetStateLocked(); - } else if (why == WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT) { - // if the screen turned off because of timeout, set an alarm - // to enable it a little bit later (i.e, give the user a chance - // to turn the screen back on within a certain window without - // having to unlock the screen) - long when = SystemClock.elapsedRealtime() + KEYGUARD_DELAY_MS; - Intent intent = new Intent(DELAYED_KEYGUARD_ACTION); - intent.putExtra("seq", mDelayedShowingSequence); - PendingIntent sender = PendingIntent.getBroadcast(mContext, - 0, intent, PendingIntent.FLAG_CANCEL_CURRENT); - mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, when, - sender); - if (DEBUG) Log.d(TAG, "setting alarm to turn off keyguard, seq = " - + mDelayedShowingSequence); - } else if (why == WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR) { - // Do not enable the keyguard if the prox sensor forced the screen off. - } else { - doKeyguard(); - } - } - } - - /** - * Let's us know the screen was turned on. - */ - public void onScreenTurnedOn() { - synchronized (this) { - mScreenOn = true; - mDelayedShowingSequence++; - if (DEBUG) Log.d(TAG, "onScreenTurnedOn, seq = " + mDelayedShowingSequence); - notifyScreenOnLocked(); - } - } - - /** - * Same semantics as {@link WindowManagerPolicy#enableKeyguard}; provide - * a way for external stuff to override normal keyguard behavior. For instance - * the phone app disables the keyguard when it receives incoming calls. - */ - public void setKeyguardEnabled(boolean enabled) { - synchronized (this) { - if (DEBUG) Log.d(TAG, "setKeyguardEnabled(" + enabled + ")"); - - - mExternallyEnabled = enabled; - - if (!enabled && mShowing) { - if (mExitSecureCallback != null) { - if (DEBUG) Log.d(TAG, "in process of verifyUnlock request, ignoring"); - // we're in the process of handling a request to verify the user - // can get past the keyguard. ignore extraneous requests to disable / reenable - return; - } - - // hiding keyguard that is showing, remember to reshow later - if (DEBUG) Log.d(TAG, "remembering to reshow, hiding keyguard, " - + "disabling status bar expansion"); - mNeedToReshowWhenReenabled = true; - hideLocked(); - } else if (enabled && mNeedToReshowWhenReenabled) { - // reenabled after previously hidden, reshow - if (DEBUG) Log.d(TAG, "previously hidden, reshowing, reenabling " - + "status bar expansion"); - mNeedToReshowWhenReenabled = false; - - if (mExitSecureCallback != null) { - if (DEBUG) Log.d(TAG, "onKeyguardExitResult(false), resetting"); - mExitSecureCallback.onKeyguardExitResult(false); - mExitSecureCallback = null; - resetStateLocked(); - } else { - showLocked(); - - // block until we know the keygaurd is done drawing (and post a message - // to unblock us after a timeout so we don't risk blocking too long - // and causing an ANR). - mWaitingUntilKeyguardVisible = true; - mHandler.sendEmptyMessageDelayed(KEYGUARD_DONE_DRAWING, KEYGUARD_DONE_DRAWING_TIMEOUT_MS); - if (DEBUG) Log.d(TAG, "waiting until mWaitingUntilKeyguardVisible is false"); - while (mWaitingUntilKeyguardVisible) { - try { - wait(); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - } - if (DEBUG) Log.d(TAG, "done waiting for mWaitingUntilKeyguardVisible"); - } - } - } - } - - /** - * @see android.app.KeyguardManager#exitKeyguardSecurely - */ - public void verifyUnlock(WindowManagerPolicy.OnKeyguardExitResult callback) { - synchronized (this) { - if (DEBUG) Log.d(TAG, "verifyUnlock"); - if (!mUpdateMonitor.isDeviceProvisioned()) { - // don't allow this api when the device isn't provisioned - if (DEBUG) Log.d(TAG, "ignoring because device isn't provisioned"); - callback.onKeyguardExitResult(false); - } else if (mExternallyEnabled) { - // this only applies when the user has externally disabled the - // keyguard. this is unexpected and means the user is not - // using the api properly. - Log.w(TAG, "verifyUnlock called when not externally disabled"); - callback.onKeyguardExitResult(false); - } else if (mExitSecureCallback != null) { - // already in progress with someone else - callback.onKeyguardExitResult(false); - } else { - mExitSecureCallback = callback; - verifyUnlockLocked(); - } - } - } - - /** - * Is the keyguard currently showing? - */ - public boolean isShowing() { - return mShowing; - } - - /** - * Is the keyguard currently showing and not being force hidden? - */ - public boolean isShowingAndNotHidden() { - return mShowing && !mHidden; - } - - /** - * Notify us when the keyguard is hidden by another window - */ - public void setHidden(boolean isHidden) { - if (DEBUG) Log.d(TAG, "setHidden " + isHidden); - mHandler.removeMessages(SET_HIDDEN); - Message msg = mHandler.obtainMessage(SET_HIDDEN, (isHidden ? 1 : 0), 0); - mHandler.sendMessage(msg); - } - - /** - * Handles SET_HIDDEN message sent by setHidden() - */ - private void handleSetHidden(boolean isHidden) { - synchronized (KeyguardViewMediator.this) { - if (mHidden != isHidden) { - mHidden = isHidden; - adjustUserActivityLocked(); - adjustStatusBarLocked(); - } - } - } - - /** - * Used by PhoneWindowManager to enable the keyguard due to a user activity timeout. - * This must be safe to call from any thread and with any window manager locks held. - */ - public void doKeyguardTimeout() { - mHandler.removeMessages(KEYGUARD_TIMEOUT); - Message msg = mHandler.obtainMessage(KEYGUARD_TIMEOUT); - mHandler.sendMessage(msg); - } - - /** - * Given the state of the keyguard, is the input restricted? - * Input is restricted when the keyguard is showing, or when the keyguard - * was suppressed by an app that disabled the keyguard or we haven't been provisioned yet. - */ - public boolean isInputRestricted() { - return mShowing || mNeedToReshowWhenReenabled || !mUpdateMonitor.isDeviceProvisioned(); - } - - /** - * Returns true if the change is resulting in the keyguard beign dismissed, - * meaning the screen can turn on immediately. Otherwise returns false. - */ - public boolean doLidChangeTq(boolean isLidOpen) { - mKeyboardOpen = isLidOpen; - - if (mUpdateMonitor.isKeyguardBypassEnabled() && mKeyboardOpen - && !mKeyguardViewProperties.isSecure() && mKeyguardViewManager.isShowing()) { - if (DEBUG) Log.d(TAG, "bypassing keyguard on sliding open of keyboard with non-secure keyguard"); - mHandler.sendEmptyMessage(KEYGUARD_DONE_AUTHENTICATING); - return true; - } - return false; - } - - /** - * Enable the keyguard if the settings are appropriate. - */ - private void doKeyguard() { - synchronized (this) { - // if another app is disabling us, don't show - if (!mExternallyEnabled) { - if (DEBUG) Log.d(TAG, "doKeyguard: not showing because externally disabled"); - - // note: we *should* set mNeedToReshowWhenReenabled=true here, but that makes - // for an occasional ugly flicker in this situation: - // 1) receive a call with the screen on (no keyguard) or make a call - // 2) screen times out - // 3) user hits key to turn screen back on - // instead, we reenable the keyguard when we know the screen is off and the call - // ends (see the broadcast receiver below) - // TODO: clean this up when we have better support at the window manager level - // for apps that wish to be on top of the keyguard - return; - } - - // if the keyguard is already showing, don't bother - if (mKeyguardViewManager.isShowing()) { - if (DEBUG) Log.d(TAG, "doKeyguard: not showing because it is already showing"); - return; - } - - // if the setup wizard hasn't run yet, don't show - final boolean requireSim = !SystemProperties.getBoolean("keyguard.no_require_sim", - false); - final boolean provisioned = mUpdateMonitor.isDeviceProvisioned(); - final IccCard.State state = mUpdateMonitor.getSimState(); - final boolean lockedOrMissing = state.isPinLocked() - || ((state == IccCard.State.ABSENT) && requireSim); - - if (!lockedOrMissing && !provisioned) { - if (DEBUG) Log.d(TAG, "doKeyguard: not showing because device isn't provisioned" - + " and the sim is not locked or missing"); - return; - } - - if (DEBUG) Log.d(TAG, "doKeyguard: showing the lock screen"); - showLocked(); - } - } - - /** - * Send message to keyguard telling it to reset its state. - * @see #handleReset() - */ - private void resetStateLocked() { - if (DEBUG) Log.d(TAG, "resetStateLocked"); - Message msg = mHandler.obtainMessage(RESET); - mHandler.sendMessage(msg); - } - - /** - * Send message to keyguard telling it to verify unlock - * @see #handleVerifyUnlock() - */ - private void verifyUnlockLocked() { - if (DEBUG) Log.d(TAG, "verifyUnlockLocked"); - mHandler.sendEmptyMessage(VERIFY_UNLOCK); - } - - - /** - * Send a message to keyguard telling it the screen just turned on. - * @see #onScreenTurnedOff(int) - * @see #handleNotifyScreenOff - */ - private void notifyScreenOffLocked() { - if (DEBUG) Log.d(TAG, "notifyScreenOffLocked"); - mHandler.sendEmptyMessage(NOTIFY_SCREEN_OFF); - } - - /** - * Send a message to keyguard telling it the screen just turned on. - * @see #onScreenTurnedOn() - * @see #handleNotifyScreenOn - */ - private void notifyScreenOnLocked() { - if (DEBUG) Log.d(TAG, "notifyScreenOnLocked"); - mHandler.sendEmptyMessage(NOTIFY_SCREEN_ON); - } - - /** - * Send message to keyguard telling it about a wake key so it can adjust - * its state accordingly and then poke the wake lock when it is ready. - * @param keyCode The wake key. - * @see #handleWakeWhenReady - * @see #onWakeKeyWhenKeyguardShowingTq(int) - */ - private void wakeWhenReadyLocked(int keyCode) { - if (DBG_WAKE) Log.d(TAG, "wakeWhenReadyLocked(" + keyCode + ")"); - - /** - * acquire the handoff lock that will keep the cpu running. this will - * be released once the keyguard has set itself up and poked the other wakelock - * in {@link #handleWakeWhenReady(int)} - */ - mWakeAndHandOff.acquire(); - - Message msg = mHandler.obtainMessage(WAKE_WHEN_READY, keyCode, 0); - mHandler.sendMessage(msg); - } - - /** - * Send message to keyguard telling it to show itself - * @see #handleShow() - */ - private void showLocked() { - if (DEBUG) Log.d(TAG, "showLocked"); - // ensure we stay awake until we are finished displaying the keyguard - mShowKeyguardWakeLock.acquire(); - Message msg = mHandler.obtainMessage(SHOW); - mHandler.sendMessage(msg); - } - - /** - * Send message to keyguard telling it to hide itself - * @see #handleHide() - */ - private void hideLocked() { - if (DEBUG) Log.d(TAG, "hideLocked"); - Message msg = mHandler.obtainMessage(HIDE); - mHandler.sendMessage(msg); - } - - /** {@inheritDoc} */ - public void onSimStateChanged(IccCard.State simState) { - if (DEBUG) Log.d(TAG, "onSimStateChanged: " + simState); - - switch (simState) { - case ABSENT: - // only force lock screen in case of missing sim if user hasn't - // gone through setup wizard - if (!mUpdateMonitor.isDeviceProvisioned()) { - if (!isShowing()) { - if (DEBUG) Log.d(TAG, "INTENT_VALUE_ICC_ABSENT and keygaurd isn't showing, we need " - + "to show the keyguard since the device isn't provisioned yet."); - doKeyguard(); - } else { - resetStateLocked(); - } - } - break; - case PIN_REQUIRED: - case PUK_REQUIRED: - if (!isShowing()) { - if (DEBUG) Log.d(TAG, "INTENT_VALUE_ICC_LOCKED and keygaurd isn't showing, we need " - + "to show the keyguard so the user can enter their sim pin"); - doKeyguard(); - } else { - resetStateLocked(); - } - - break; - case READY: - if (isShowing()) { - resetStateLocked(); - } - break; - } - } - - public boolean isSecure() { - return mKeyguardViewProperties.isSecure(); - } - - private BroadcastReceiver mBroadCastReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - final String action = intent.getAction(); - if (action.equals(DELAYED_KEYGUARD_ACTION)) { - - int sequence = intent.getIntExtra("seq", 0); - - if (false) Log.d(TAG, "received DELAYED_KEYGUARD_ACTION with seq = " - + sequence + ", mDelayedShowingSequence = " + mDelayedShowingSequence); - - if (mDelayedShowingSequence == sequence) { - // Don't play lockscreen SFX if the screen went off due to - // timeout. - mSuppressNextLockSound = true; - - doKeyguard(); - } - } else if (TelephonyManager.ACTION_PHONE_STATE_CHANGED.equals(action)) { - mPhoneState = intent.getStringExtra(TelephonyManager.EXTRA_STATE); - - if (TelephonyManager.EXTRA_STATE_IDLE.equals(mPhoneState) // call ending - && !mScreenOn // screen off - && mExternallyEnabled) { // not disabled by any app - - // note: this is a way to gracefully reenable the keyguard when the call - // ends and the screen is off without always reenabling the keyguard - // each time the screen turns off while in call (and having an occasional ugly - // flicker while turning back on the screen and disabling the keyguard again). - if (DEBUG) Log.d(TAG, "screen is off and call ended, let's make sure the " - + "keyguard is showing"); - doKeyguard(); - } - } - } - }; - - - /** - * When a key is received when the screen is off and the keyguard is showing, - * we need to decide whether to actually turn on the screen, and if so, tell - * the keyguard to prepare itself and poke the wake lock when it is ready. - * - * The 'Tq' suffix is per the documentation in {@link 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 keycode of the key that woke the device - * @return Whether we poked the wake lock (and turned the screen on) - */ - public boolean onWakeKeyWhenKeyguardShowingTq(int keyCode) { - if (DEBUG) Log.d(TAG, "onWakeKeyWhenKeyguardShowing(" + keyCode + ")"); - - if (isWakeKeyWhenKeyguardShowing(keyCode)) { - // give the keyguard view manager a chance to adjust the state of the - // keyguard based on the key that woke the device before poking - // the wake lock - wakeWhenReadyLocked(keyCode); - return true; - } else { - return false; - } - } - - private boolean isWakeKeyWhenKeyguardShowing(int keyCode) { - switch (keyCode) { - case KeyEvent.KEYCODE_VOLUME_UP: - case KeyEvent.KEYCODE_VOLUME_DOWN: - case KeyEvent.KEYCODE_MUTE: - case KeyEvent.KEYCODE_HEADSETHOOK: - 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_FAST_FORWARD: - case KeyEvent.KEYCODE_CAMERA: - return false; - } - return true; - } - - /** - * Callbacks from {@link KeyguardViewManager}. - */ - - /** {@inheritDoc} */ - public void pokeWakelock() { - pokeWakelock(mKeyboardOpen ? - AWAKE_INTERVAL_DEFAULT_KEYBOARD_OPEN_MS : AWAKE_INTERVAL_DEFAULT_MS); - } - - /** {@inheritDoc} */ - public void pokeWakelock(int holdMs) { - synchronized (this) { - if (DBG_WAKE) Log.d(TAG, "pokeWakelock(" + holdMs + ")"); - mWakeLock.acquire(); - mHandler.removeMessages(TIMEOUT); - mWakelockSequence++; - Message msg = mHandler.obtainMessage(TIMEOUT, mWakelockSequence, 0); - mHandler.sendMessageDelayed(msg, holdMs); - } - } - - /** - * {@inheritDoc} - * - * @see #handleKeyguardDone - */ - public void keyguardDone(boolean authenticated) { - keyguardDone(authenticated, true); - } - - public void keyguardDone(boolean authenticated, boolean wakeup) { - synchronized (this) { - EventLog.writeEvent(70000, 2); - if (DEBUG) Log.d(TAG, "keyguardDone(" + authenticated + ")"); - Message msg = mHandler.obtainMessage(KEYGUARD_DONE); - msg.arg1 = wakeup ? 1 : 0; - mHandler.sendMessage(msg); - - if (authenticated) { - mUpdateMonitor.clearFailedAttempts(); - } - - if (mExitSecureCallback != null) { - mExitSecureCallback.onKeyguardExitResult(authenticated); - mExitSecureCallback = null; - - if (authenticated) { - // after succesfully exiting securely, no need to reshow - // the keyguard when they've released the lock - mExternallyEnabled = true; - mNeedToReshowWhenReenabled = false; - } - } - } - } - - /** - * {@inheritDoc} - * - * @see #handleKeyguardDoneDrawing - */ - public void keyguardDoneDrawing() { - mHandler.sendEmptyMessage(KEYGUARD_DONE_DRAWING); - } - - /** - * This handler will be associated with the policy thread, which will also - * be the UI thread of the keyguard. Since the apis of the policy, and therefore - * this class, can be called by other threads, any action that directly - * interacts with the keyguard ui should be posted to this handler, rather - * than called directly. - */ - private Handler mHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case TIMEOUT: - handleTimeout(msg.arg1); - return ; - case SHOW: - handleShow(); - return ; - case HIDE: - handleHide(); - return ; - case RESET: - handleReset(); - return ; - case VERIFY_UNLOCK: - handleVerifyUnlock(); - return; - case NOTIFY_SCREEN_OFF: - handleNotifyScreenOff(); - return; - case NOTIFY_SCREEN_ON: - handleNotifyScreenOn(); - return; - case WAKE_WHEN_READY: - handleWakeWhenReady(msg.arg1); - return; - case KEYGUARD_DONE: - handleKeyguardDone(msg.arg1 != 0); - return; - case KEYGUARD_DONE_DRAWING: - handleKeyguardDoneDrawing(); - return; - case KEYGUARD_DONE_AUTHENTICATING: - keyguardDone(true); - return; - case SET_HIDDEN: - handleSetHidden(msg.arg1 != 0); - break; - case KEYGUARD_TIMEOUT: - doKeyguard(); - break; - } - } - }; - - /** - * @see #keyguardDone - * @see #KEYGUARD_DONE - */ - private void handleKeyguardDone(boolean wakeup) { - if (DEBUG) Log.d(TAG, "handleKeyguardDone"); - handleHide(); - if (wakeup) { - mPM.userActivity(SystemClock.uptimeMillis(), true); - } - mWakeLock.release(); - mContext.sendBroadcast(mUserPresentIntent); - } - - /** - * @see #keyguardDoneDrawing - * @see #KEYGUARD_DONE_DRAWING - */ - private void handleKeyguardDoneDrawing() { - synchronized(this) { - if (false) Log.d(TAG, "handleKeyguardDoneDrawing"); - if (mWaitingUntilKeyguardVisible) { - if (DEBUG) Log.d(TAG, "handleKeyguardDoneDrawing: notifying mWaitingUntilKeyguardVisible"); - mWaitingUntilKeyguardVisible = false; - notifyAll(); - - // there will usually be two of these sent, one as a timeout, and one - // as a result of the callback, so remove any remaining messages from - // the queue - mHandler.removeMessages(KEYGUARD_DONE_DRAWING); - } - } - } - - /** - * Handles the message sent by {@link #pokeWakelock} - * @param seq used to determine if anything has changed since the message - * was sent. - * @see #TIMEOUT - */ - private void handleTimeout(int seq) { - synchronized (KeyguardViewMediator.this) { - if (DEBUG) Log.d(TAG, "handleTimeout"); - if (seq == mWakelockSequence) { - mWakeLock.release(); - } - } - } - - private void playSounds(boolean locked) { - // User feedback for keyguard. - - if (mSuppressNextLockSound) { - mSuppressNextLockSound = false; - return; - } - - final ContentResolver cr = mContext.getContentResolver(); - if (Settings.System.getInt(cr, Settings.System.LOCKSCREEN_SOUNDS_ENABLED, 1) == 1) - { - final String whichSound = locked - ? Settings.System.LOCK_SOUND - : Settings.System.UNLOCK_SOUND; - final String soundPath = Settings.System.getString(cr, whichSound); - if (soundPath != null) { - final Uri soundUri = Uri.parse("file://" + soundPath); - if (soundUri != null) { - final Ringtone sfx = RingtoneManager.getRingtone(mContext, soundUri); - if (sfx != null) { - sfx.setStreamType(AudioManager.STREAM_SYSTEM); - sfx.play(); - } else { - Log.d(TAG, "playSounds: failed to load ringtone from uri: " + soundUri); - } - } else { - Log.d(TAG, "playSounds: could not parse Uri: " + soundPath); - } - } else { - Log.d(TAG, "playSounds: whichSound = " + whichSound + "; soundPath was null"); - } - } - } - - /** - * Handle message sent by {@link #showLocked}. - * @see #SHOW - */ - private void handleShow() { - synchronized (KeyguardViewMediator.this) { - if (DEBUG) Log.d(TAG, "handleShow"); - if (!mSystemReady) return; - - playSounds(true); - - mKeyguardViewManager.show(); - mShowing = true; - adjustUserActivityLocked(); - adjustStatusBarLocked(); - try { - ActivityManagerNative.getDefault().closeSystemDialogs("lock"); - } catch (RemoteException e) { - } - mShowKeyguardWakeLock.release(); - } - } - - /** - * Handle message sent by {@link #hideLocked()} - * @see #HIDE - */ - private void handleHide() { - synchronized (KeyguardViewMediator.this) { - if (DEBUG) Log.d(TAG, "handleHide"); - if (mWakeAndHandOff.isHeld()) { - Log.w(TAG, "attempt to hide the keyguard while waking, ignored"); - return; - } - - // only play "unlock" noises if not on a call (since the incall UI - // disables the keyguard) - if (TelephonyManager.EXTRA_STATE_IDLE.equals(mPhoneState)) { - playSounds(false); - } - - mKeyguardViewManager.hide(); - mShowing = false; - adjustUserActivityLocked(); - adjustStatusBarLocked(); - } - } - - private void adjustUserActivityLocked() { - // disable user activity if we are shown and not hidden - if (DEBUG) Log.d(TAG, "adjustUserActivityLocked mShowing: " + mShowing + " mHidden: " + mHidden); - boolean enabled = !mShowing || mHidden; - mRealPowerManager.enableUserActivity(enabled); - if (!enabled && mScreenOn) { - // reinstate our short screen timeout policy - pokeWakelock(); - } - } - - private void adjustStatusBarLocked() { - if (mStatusBarManager == null) { - mStatusBarManager = (StatusBarManager) - mContext.getSystemService(Context.STATUS_BAR_SERVICE); - } - if (mStatusBarManager == null) { - Log.w(TAG, "Could not get status bar manager"); - } else { - if (mShowLockIcon) { - // Give feedback to user when secure keyguard is active and engaged - if (mShowing && isSecure()) { - if (!mShowingLockIcon) { - mStatusBarManager.setIcon("secure", - com.android.internal.R.drawable.stat_sys_secure, 0); - mShowingLockIcon = true; - } - } else { - if (mShowingLockIcon) { - mStatusBarManager.removeIcon("secure"); - mShowingLockIcon = false; - } - } - } - - // if the keyguard is shown, allow the status bar to open - // only if the keyguard is insecure and is covered by another window - boolean enable = !mShowing || (mHidden && !isSecure()); - mStatusBarManager.disable(enable ? - StatusBarManager.DISABLE_NONE : - StatusBarManager.DISABLE_EXPAND); - } - } - - /** - * Handle message sent by {@link #wakeWhenReadyLocked(int)} - * @param keyCode The key that woke the device. - * @see #WAKE_WHEN_READY - */ - private void handleWakeWhenReady(int keyCode) { - synchronized (KeyguardViewMediator.this) { - if (DBG_WAKE) Log.d(TAG, "handleWakeWhenReady(" + keyCode + ")"); - - // this should result in a call to 'poke wakelock' which will set a timeout - // on releasing the wakelock - if (!mKeyguardViewManager.wakeWhenReadyTq(keyCode)) { - // poke wakelock ourselves if keyguard is no longer active - Log.w(TAG, "mKeyguardViewManager.wakeWhenReadyTq did not poke wake lock, so poke it ourselves"); - pokeWakelock(); - } - - /** - * Now that the keyguard is ready and has poked the wake lock, we can - * release the handoff wakelock - */ - mWakeAndHandOff.release(); - - if (!mWakeLock.isHeld()) { - Log.w(TAG, "mWakeLock not held in mKeyguardViewManager.wakeWhenReadyTq"); - } - } - } - - /** - * Handle message sent by {@link #resetStateLocked()} - * @see #RESET - */ - private void handleReset() { - synchronized (KeyguardViewMediator.this) { - if (DEBUG) Log.d(TAG, "handleReset"); - mKeyguardViewManager.reset(); - } - } - - /** - * Handle message sent by {@link #verifyUnlock} - * @see #RESET - */ - private void handleVerifyUnlock() { - synchronized (KeyguardViewMediator.this) { - if (DEBUG) Log.d(TAG, "handleVerifyUnlock"); - mKeyguardViewManager.verifyUnlock(); - mShowing = true; - } - } - - /** - * Handle message sent by {@link #notifyScreenOffLocked()} - * @see #NOTIFY_SCREEN_OFF - */ - private void handleNotifyScreenOff() { - synchronized (KeyguardViewMediator.this) { - if (DEBUG) Log.d(TAG, "handleNotifyScreenOff"); - mKeyguardViewManager.onScreenTurnedOff(); - } - } - - /** - * Handle message sent by {@link #notifyScreenOnLocked()} - * @see #NOTIFY_SCREEN_ON - */ - private void handleNotifyScreenOn() { - synchronized (KeyguardViewMediator.this) { - if (DEBUG) Log.d(TAG, "handleNotifyScreenOn"); - mKeyguardViewManager.onScreenTurnedOn(); - } - } -} - - diff --git a/policy/com/android/internal/policy/impl/KeyguardViewProperties.java b/policy/com/android/internal/policy/impl/KeyguardViewProperties.java deleted file mode 100644 index bda08eb..0000000 --- a/policy/com/android/internal/policy/impl/KeyguardViewProperties.java +++ /dev/null @@ -1,46 +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; - -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 updateMonitor configuration may be based on this. - * @param controller for talking back with the containing window. - * @return the view. - */ - KeyguardViewBase createKeyguardView(Context context, - 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(); - -} diff --git a/policy/com/android/internal/policy/impl/KeyguardWindowController.java b/policy/com/android/internal/policy/impl/KeyguardWindowController.java deleted file mode 100644 index 4ad48fb..0000000 --- a/policy/com/android/internal/policy/impl/KeyguardWindowController.java +++ /dev/null @@ -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; - -/** - * 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); -} diff --git a/policy/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/com/android/internal/policy/impl/LockPatternKeyguardView.java deleted file mode 100644 index 27706ef..0000000 --- a/policy/com/android/internal/policy/impl/LockPatternKeyguardView.java +++ /dev/null @@ -1,790 +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; - -import com.android.internal.R; -import com.android.internal.telephony.IccCard; -import com.android.internal.widget.LockPatternUtils; - -import android.accounts.Account; -import android.accounts.AccountManager; -import android.accounts.AccountManagerCallback; -import android.accounts.AccountManagerFuture; -import android.accounts.AuthenticatorException; -import android.accounts.OperationCanceledException; -import android.app.AlertDialog; -import android.app.admin.DevicePolicyManager; -import android.content.Context; -import android.content.Intent; -import android.content.res.Configuration; -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.graphics.ColorFilter; -import android.graphics.PixelFormat; -import android.graphics.drawable.Drawable; -import android.os.Bundle; -import android.os.SystemClock; -import android.os.SystemProperties; -import android.telephony.TelephonyManager; -import android.text.TextUtils; -import android.util.Log; -import android.view.KeyEvent; -import android.view.View; -import android.view.WindowManager; - -import java.io.IOException; - -/** - * The host view for all of the screens of the pattern unlock screen. There are - * two {@link Mode}s of operation, lock and unlock. This will show the appropriate - * screen, and listen for callbacks via - * {@link com.android.internal.policy.impl.KeyguardScreenCallback} - * from the current screen. - * - * This view, in turn, communicates back to - * {@link com.android.internal.policy.impl.KeyguardViewManager} - * via its {@link com.android.internal.policy.impl.KeyguardViewCallback}, as appropriate. - */ -public class LockPatternKeyguardView extends KeyguardViewBase { - - static final boolean DEBUG_CONFIGURATION = false; - - // time after launching EmergencyDialer before the screen goes blank. - private static final int EMERGENCY_CALL_TIMEOUT = 10000; - - // intent action for launching emergency dialer activity. - static final String ACTION_EMERGENCY_DIAL = "com.android.phone.EmergencyDialer.DIAL"; - - private static final boolean DEBUG = false; - private static final String TAG = "LockPatternKeyguardView"; - - private final KeyguardUpdateMonitor mUpdateMonitor; - private final KeyguardWindowController mWindowController; - - private View mLockScreen; - private View mUnlockScreen; - - private boolean mScreenOn = false; - private boolean mEnableFallback = false; // assume no fallback UI until we know better - - /** - * The current {@link KeyguardScreen} will use this to communicate back to us. - */ - KeyguardScreenCallback mKeyguardScreenCallback; - - - private boolean mRequiresSim; - - - /** - * Either a lock screen (an informational keyguard screen), or an unlock - * screen (a means for unlocking the device) is shown at any given time. - */ - enum Mode { - LockScreen, - UnlockScreen - } - - /** - * The different types screens available for {@link Mode#UnlockScreen}. - * @see com.android.internal.policy.impl.LockPatternKeyguardView#getUnlockMode() - */ - enum UnlockMode { - - /** - * Unlock by drawing a pattern. - */ - Pattern, - - /** - * Unlock by entering a sim pin. - */ - SimPin, - - /** - * Unlock by entering an account's login and password. - */ - Account, - - /** - * Unlock by entering a password or PIN - */ - Password, - - /** - * Unknown (uninitialized) value - */ - Unknown - } - - /** - * The current mode. - */ - private Mode mMode = Mode.LockScreen; - - /** - * Keeps track of what mode the current unlock screen is (cached from most recent computation in - * {@link #getUnlockMode}). - */ - private UnlockMode mUnlockScreenMode; - - private boolean mForgotPattern; - - /** - * If true, it means we are in the process of verifying that the user - * can get past the lock screen per {@link #verifyUnlock()} - */ - private boolean mIsVerifyUnlockOnly = false; - - - /** - * Used to lookup the state of the lock pattern - */ - private final LockPatternUtils mLockPatternUtils; - - private UnlockMode mCurrentUnlockMode = UnlockMode.Unknown; - - /** - * The current configuration. - */ - private Configuration mConfiguration; - - /** - * @return Whether we are stuck on the lock screen because the sim is - * missing. - */ - private boolean stuckOnLockScreenBecauseSimMissing() { - return mRequiresSim - && (!mUpdateMonitor.isDeviceProvisioned()) - && (mUpdateMonitor.getSimState() == IccCard.State.ABSENT); - } - - /** - * @param context Used to inflate, and create views. - * @param updateMonitor Knows the state of the world, and passed along to each - * screen so they can use the knowledge, and also register for callbacks - * on dynamic information. - * @param lockPatternUtils Used to look up state of lock pattern. - */ - public LockPatternKeyguardView( - Context context, - KeyguardUpdateMonitor updateMonitor, - LockPatternUtils lockPatternUtils, - KeyguardWindowController controller) { - super(context); - - mConfiguration = context.getResources().getConfiguration(); - mEnableFallback = false; - - mRequiresSim = - TextUtils.isEmpty(SystemProperties.get("keyguard.no_require_sim")); - - mUpdateMonitor = updateMonitor; - mLockPatternUtils = lockPatternUtils; - mWindowController = controller; - - mMode = getInitialMode(); - - mKeyguardScreenCallback = new KeyguardScreenCallback() { - - public void goToLockScreen() { - mForgotPattern = false; - if (mIsVerifyUnlockOnly) { - // navigating away from unlock screen during verify mode means - // we are done and the user failed to authenticate. - mIsVerifyUnlockOnly = false; - getCallback().keyguardDone(false); - } else { - updateScreen(Mode.LockScreen); - } - } - - public void goToUnlockScreen() { - final IccCard.State simState = mUpdateMonitor.getSimState(); - if (stuckOnLockScreenBecauseSimMissing() - || (simState == IccCard.State.PUK_REQUIRED)){ - // stuck on lock screen when sim missing or puk'd - return; - } - if (!isSecure()) { - getCallback().keyguardDone(true); - } else { - updateScreen(Mode.UnlockScreen); - } - } - - public void forgotPattern(boolean isForgotten) { - if (mEnableFallback) { - mForgotPattern = isForgotten; - updateScreen(Mode.UnlockScreen); - } - } - - public boolean isSecure() { - return LockPatternKeyguardView.this.isSecure(); - } - - public boolean isVerifyUnlockOnly() { - return mIsVerifyUnlockOnly; - } - - public void recreateMe(Configuration config) { - mConfiguration = config; - recreateScreens(); - } - - public void takeEmergencyCallAction() { - pokeWakelock(EMERGENCY_CALL_TIMEOUT); - if (TelephonyManager.getDefault().getCallState() - == TelephonyManager.CALL_STATE_OFFHOOK) { - mLockPatternUtils.resumeCall(); - } else { - Intent intent = new Intent(ACTION_EMERGENCY_DIAL); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK - | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); - getContext().startActivity(intent); - } - } - - public void pokeWakelock() { - getCallback().pokeWakelock(); - } - - public void pokeWakelock(int millis) { - getCallback().pokeWakelock(millis); - } - - public void keyguardDone(boolean authenticated) { - getCallback().keyguardDone(authenticated); - } - - public void keyguardDoneDrawing() { - // irrelevant to keyguard screen, they shouldn't be calling this - } - - public void reportFailedUnlockAttempt() { - mUpdateMonitor.reportFailedAttempt(); - final int failedAttempts = mUpdateMonitor.getFailedAttempts(); - if (DEBUG) Log.d(TAG, - "reportFailedPatternAttempt: #" + failedAttempts + - " (enableFallback=" + mEnableFallback + ")"); - final boolean usingLockPattern = mLockPatternUtils.getKeyguardStoredPasswordQuality() - == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING; - if (usingLockPattern && mEnableFallback && failedAttempts == - (LockPatternUtils.FAILED_ATTEMPTS_BEFORE_RESET - - LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT)) { - showAlmostAtAccountLoginDialog(); - } else if (usingLockPattern && mEnableFallback - && failedAttempts >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_RESET) { - mLockPatternUtils.setPermanentlyLocked(true); - updateScreen(mMode); - } else if ((failedAttempts % LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT) - == 0) { - showTimeoutDialog(); - } - mLockPatternUtils.reportFailedPasswordAttempt(); - } - - public boolean doesFallbackUnlockScreenExist() { - return mEnableFallback; - } - - public void reportSuccessfulUnlockAttempt() { - mLockPatternUtils.reportSuccessfulPasswordAttempt(); - } - }; - - /** - * We'll get key events the current screen doesn't use. see - * {@link KeyguardViewBase#onKeyDown(int, android.view.KeyEvent)} - */ - setFocusableInTouchMode(true); - setDescendantFocusability(FOCUS_AFTER_DESCENDANTS); - - // create both the lock and unlock screen so they are quickly available - // when the screen turns on - mLockScreen = createLockScreen(); - addView(mLockScreen); - final UnlockMode unlockMode = getUnlockMode(); - if (DEBUG) Log.d(TAG, - "LockPatternKeyguardView ctor: about to createUnlockScreenFor; mEnableFallback=" - + mEnableFallback); - mUnlockScreen = createUnlockScreenFor(unlockMode); - mUnlockScreenMode = unlockMode; - - maybeEnableFallback(context); - - addView(mUnlockScreen); - updateScreen(mMode); - } - - private class AccountAnalyzer implements AccountManagerCallback<Bundle> { - private final AccountManager mAccountManager; - private final Account[] mAccounts; - private int mAccountIndex; - - private AccountAnalyzer(AccountManager accountManager) { - mAccountManager = accountManager; - mAccounts = accountManager.getAccountsByType("com.google"); - } - - private void next() { - // if we are ready to enable the fallback or if we depleted the list of accounts - // then finish and get out - if (mEnableFallback || mAccountIndex >= mAccounts.length) { - if (mUnlockScreen == null) { - Log.w(TAG, "no unlock screen when trying to enable fallback"); - } else if (mUnlockScreen instanceof PatternUnlockScreen) { - ((PatternUnlockScreen)mUnlockScreen).setEnableFallback(mEnableFallback); - } - return; - } - - // lookup the confirmCredentials intent for the current account - mAccountManager.confirmCredentials(mAccounts[mAccountIndex], null, null, this, null); - } - - public void start() { - mEnableFallback = false; - mAccountIndex = 0; - next(); - } - - public void run(AccountManagerFuture<Bundle> future) { - try { - Bundle result = future.getResult(); - if (result.getParcelable(AccountManager.KEY_INTENT) != null) { - mEnableFallback = true; - } - } catch (OperationCanceledException e) { - // just skip the account if we are unable to query it - } catch (IOException e) { - // just skip the account if we are unable to query it - } catch (AuthenticatorException e) { - // just skip the account if we are unable to query it - } finally { - mAccountIndex++; - next(); - } - } - } - - private void maybeEnableFallback(Context context) { - // Ask the account manager if we have an account that can be used as a - // fallback in case the user forgets his pattern. - AccountAnalyzer accountAnalyzer = new AccountAnalyzer(AccountManager.get(context)); - accountAnalyzer.start(); - } - - - // TODO: - // This overloaded method was added to workaround a race condition in the framework between - // notification for orientation changed, layout() and switching resources. This code attempts - // to avoid drawing the incorrect layout while things are in transition. The method can just - // be removed once the race condition is fixed. See bugs 2262578 and 2292713. - @Override - protected void dispatchDraw(Canvas canvas) { - if (DEBUG) Log.v(TAG, "*** dispatchDraw() time: " + SystemClock.elapsedRealtime()); - super.dispatchDraw(canvas); - } - - @Override - public void reset() { - mIsVerifyUnlockOnly = false; - mForgotPattern = false; - updateScreen(getInitialMode()); - } - - @Override - public void onScreenTurnedOff() { - mScreenOn = false; - mForgotPattern = false; - if (mMode == Mode.LockScreen) { - ((KeyguardScreen) mLockScreen).onPause(); - } else { - ((KeyguardScreen) mUnlockScreen).onPause(); - } - } - - @Override - public void onScreenTurnedOn() { - mScreenOn = true; - if (mMode == Mode.LockScreen) { - ((KeyguardScreen) mLockScreen).onResume(); - } else { - ((KeyguardScreen) mUnlockScreen).onResume(); - } - } - - private void recreateLockScreen() { - if (mLockScreen.getVisibility() == View.VISIBLE) { - ((KeyguardScreen) mLockScreen).onPause(); - } - ((KeyguardScreen) mLockScreen).cleanUp(); - removeView(mLockScreen); - - mLockScreen = createLockScreen(); - mLockScreen.setVisibility(View.INVISIBLE); - addView(mLockScreen); - } - - private void recreateUnlockScreen() { - if (mUnlockScreen.getVisibility() == View.VISIBLE) { - ((KeyguardScreen) mUnlockScreen).onPause(); - } - ((KeyguardScreen) mUnlockScreen).cleanUp(); - removeView(mUnlockScreen); - - final UnlockMode unlockMode = getUnlockMode(); - mUnlockScreen = createUnlockScreenFor(unlockMode); - mUnlockScreen.setVisibility(View.INVISIBLE); - mUnlockScreenMode = unlockMode; - addView(mUnlockScreen); - } - - private void recreateScreens() { - recreateLockScreen(); - recreateUnlockScreen(); - updateScreen(mMode); - } - - @Override - public void wakeWhenReadyTq(int keyCode) { - if (DEBUG) Log.d(TAG, "onWakeKey"); - if (keyCode == KeyEvent.KEYCODE_MENU && isSecure() && (mMode == Mode.LockScreen) - && (mUpdateMonitor.getSimState() != IccCard.State.PUK_REQUIRED)) { - if (DEBUG) Log.d(TAG, "switching screens to unlock screen because wake key was MENU"); - updateScreen(Mode.UnlockScreen); - getCallback().pokeWakelock(); - } else { - if (DEBUG) Log.d(TAG, "poking wake lock immediately"); - getCallback().pokeWakelock(); - } - } - - @Override - public void verifyUnlock() { - if (!isSecure()) { - // non-secure keyguard screens are successfull by default - getCallback().keyguardDone(true); - } else if (mUnlockScreenMode != UnlockMode.Pattern) { - // can only verify unlock when in pattern mode - getCallback().keyguardDone(false); - } else { - // otherwise, go to the unlock screen, see if they can verify it - mIsVerifyUnlockOnly = true; - updateScreen(Mode.UnlockScreen); - } - } - - @Override - public void cleanUp() { - ((KeyguardScreen) mLockScreen).onPause(); - ((KeyguardScreen) mLockScreen).cleanUp(); - ((KeyguardScreen) mUnlockScreen).onPause(); - ((KeyguardScreen) mUnlockScreen).cleanUp(); - } - - private boolean isSecure() { - UnlockMode unlockMode = getUnlockMode(); - boolean secure = false; - switch (unlockMode) { - case Pattern: - secure = mLockPatternUtils.isLockPatternEnabled(); - break; - case SimPin: - secure = mUpdateMonitor.getSimState() == IccCard.State.PIN_REQUIRED - || mUpdateMonitor.getSimState() == IccCard.State.PUK_REQUIRED; - break; - case Account: - secure = true; - break; - case Password: - secure = mLockPatternUtils.isLockPasswordEnabled(); - break; - default: - throw new IllegalStateException("unknown unlock mode " + unlockMode); - } - return secure; - } - - private void updateScreen(final Mode mode) { - - if (DEBUG_CONFIGURATION) Log.v(TAG, "**** UPDATE SCREEN: mode=" + mode - + " last mode=" + mMode, new RuntimeException()); - - mMode = mode; - - // Re-create the unlock screen if necessary. This is primarily required to properly handle - // SIM state changes. This typically happens when this method is called by reset() - if (mode == Mode.UnlockScreen && mCurrentUnlockMode != getUnlockMode()) { - recreateUnlockScreen(); - } - - final View goneScreen = (mode == Mode.LockScreen) ? mUnlockScreen : mLockScreen; - final View visibleScreen = (mode == Mode.LockScreen) ? mLockScreen : mUnlockScreen; - - // do this before changing visibility so focus isn't requested before the input - // flag is set - mWindowController.setNeedsInput(((KeyguardScreen)visibleScreen).needsInput()); - - if (DEBUG_CONFIGURATION) { - Log.v(TAG, "Gone=" + goneScreen); - Log.v(TAG, "Visible=" + visibleScreen); - } - - if (mScreenOn) { - if (goneScreen.getVisibility() == View.VISIBLE) { - ((KeyguardScreen) goneScreen).onPause(); - } - if (visibleScreen.getVisibility() != View.VISIBLE) { - ((KeyguardScreen) visibleScreen).onResume(); - } - } - - goneScreen.setVisibility(View.GONE); - visibleScreen.setVisibility(View.VISIBLE); - requestLayout(); - - if (!visibleScreen.requestFocus()) { - throw new IllegalStateException("keyguard screen must be able to take " - + "focus when shown " + visibleScreen.getClass().getCanonicalName()); - } - } - - View createLockScreen() { - return new LockScreen( - mContext, - mConfiguration, - mLockPatternUtils, - mUpdateMonitor, - mKeyguardScreenCallback); - } - - View createUnlockScreenFor(UnlockMode unlockMode) { - View unlockView = null; - if (unlockMode == UnlockMode.Pattern) { - PatternUnlockScreen view = new PatternUnlockScreen( - mContext, - mConfiguration, - mLockPatternUtils, - mUpdateMonitor, - mKeyguardScreenCallback, - mUpdateMonitor.getFailedAttempts()); - if (DEBUG) Log.d(TAG, - "createUnlockScreenFor(" + unlockMode + "): mEnableFallback=" + mEnableFallback); - view.setEnableFallback(mEnableFallback); - unlockView = view; - } else if (unlockMode == UnlockMode.SimPin) { - unlockView = new SimUnlockScreen( - mContext, - mConfiguration, - mUpdateMonitor, - mKeyguardScreenCallback, - mLockPatternUtils); - } else if (unlockMode == UnlockMode.Account) { - try { - unlockView = new AccountUnlockScreen( - mContext, - mConfiguration, - mUpdateMonitor, - mKeyguardScreenCallback, - mLockPatternUtils); - } catch (IllegalStateException e) { - Log.i(TAG, "Couldn't instantiate AccountUnlockScreen" - + " (IAccountsService isn't available)"); - // TODO: Need a more general way to provide a - // platform-specific fallback UI here. - // For now, if we can't display the account login - // unlock UI, just bring back the regular "Pattern" unlock mode. - - // (We do this by simply returning a regular UnlockScreen - // here. This means that the user will still see the - // regular pattern unlock UI, regardless of the value of - // mUnlockScreenMode or whether or not we're in the - // "permanently locked" state.) - unlockView = createUnlockScreenFor(UnlockMode.Pattern); - } - } else if (unlockMode == UnlockMode.Password) { - unlockView = new PasswordUnlockScreen( - mContext, - mConfiguration, - mLockPatternUtils, - mUpdateMonitor, - mKeyguardScreenCallback); - } else { - throw new IllegalArgumentException("unknown unlock mode " + unlockMode); - } - mCurrentUnlockMode = unlockMode; - return unlockView; - } - - /** - * Given the current state of things, what should be the initial mode of - * the lock screen (lock or unlock). - */ - private Mode getInitialMode() { - final IccCard.State simState = mUpdateMonitor.getSimState(); - if (stuckOnLockScreenBecauseSimMissing() || (simState == IccCard.State.PUK_REQUIRED)) { - return Mode.LockScreen; - } else { - // Show LockScreen first for any screen other than Pattern unlock. - final boolean usingLockPattern = mLockPatternUtils.getKeyguardStoredPasswordQuality() - == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING; - if (isSecure() && usingLockPattern) { - return Mode.UnlockScreen; - } else { - return Mode.LockScreen; - } - } - } - - /** - * Given the current state of things, what should the unlock screen be? - */ - private UnlockMode getUnlockMode() { - final IccCard.State simState = mUpdateMonitor.getSimState(); - UnlockMode currentMode; - if (simState == IccCard.State.PIN_REQUIRED || simState == IccCard.State.PUK_REQUIRED) { - currentMode = UnlockMode.SimPin; - } else { - final int mode = mLockPatternUtils.getKeyguardStoredPasswordQuality(); - switch (mode) { - case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC: - case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC: - case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC: - currentMode = UnlockMode.Password; - break; - case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING: - case DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED: - // "forgot pattern" button is only available in the pattern mode... - if (mForgotPattern || mLockPatternUtils.isPermanentlyLocked()) { - currentMode = UnlockMode.Account; - } else { - currentMode = UnlockMode.Pattern; - } - break; - default: - throw new IllegalStateException("Unknown unlock mode:" + mode); - } - } - return currentMode; - } - - private void showTimeoutDialog() { - int timeoutInSeconds = (int) LockPatternUtils.FAILED_ATTEMPT_TIMEOUT_MS / 1000; - String message = mContext.getString( - R.string.lockscreen_too_many_failed_attempts_dialog_message, - mUpdateMonitor.getFailedAttempts(), - timeoutInSeconds); - final AlertDialog dialog = new AlertDialog.Builder(mContext) - .setTitle(null) - .setMessage(message) - .setNeutralButton(R.string.ok, null) - .create(); - dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG); - if (!mContext.getResources().getBoolean( - com.android.internal.R.bool.config_sf_slowBlur)) { - dialog.getWindow().setFlags( - WindowManager.LayoutParams.FLAG_BLUR_BEHIND, - WindowManager.LayoutParams.FLAG_BLUR_BEHIND); - } - dialog.show(); - } - - private void showAlmostAtAccountLoginDialog() { - int timeoutInSeconds = (int) LockPatternUtils.FAILED_ATTEMPT_TIMEOUT_MS / 1000; - String message = mContext.getString( - R.string.lockscreen_failed_attempts_almost_glogin, - LockPatternUtils.FAILED_ATTEMPTS_BEFORE_RESET - - LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT, - LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT, - timeoutInSeconds); - final AlertDialog dialog = new AlertDialog.Builder(mContext) - .setTitle(null) - .setMessage(message) - .setNeutralButton(R.string.ok, null) - .create(); - dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG); - if (!mContext.getResources().getBoolean( - com.android.internal.R.bool.config_sf_slowBlur)) { - dialog.getWindow().setFlags( - WindowManager.LayoutParams.FLAG_BLUR_BEHIND, - WindowManager.LayoutParams.FLAG_BLUR_BEHIND); - } - dialog.show(); - } - - /** - * Used to put wallpaper on the background of the lock screen. Centers it - * Horizontally and pins the bottom (assuming that the lock screen is aligned - * with the bottom, so the wallpaper should extend above the top into the - * status bar). - */ - static private class FastBitmapDrawable extends Drawable { - private Bitmap mBitmap; - private int mOpacity; - - private FastBitmapDrawable(Bitmap bitmap) { - mBitmap = bitmap; - mOpacity = mBitmap.hasAlpha() ? PixelFormat.TRANSLUCENT : PixelFormat.OPAQUE; - } - - @Override - public void draw(Canvas canvas) { - canvas.drawBitmap( - mBitmap, - (getBounds().width() - mBitmap.getWidth()) / 2, - (getBounds().height() - mBitmap.getHeight()), - null); - } - - @Override - public int getOpacity() { - return mOpacity; - } - - @Override - public void setAlpha(int alpha) { - } - - @Override - public void setColorFilter(ColorFilter cf) { - } - - @Override - public int getIntrinsicWidth() { - return mBitmap.getWidth(); - } - - @Override - public int getIntrinsicHeight() { - return mBitmap.getHeight(); - } - - @Override - public int getMinimumWidth() { - return mBitmap.getWidth(); - } - - @Override - public int getMinimumHeight() { - return mBitmap.getHeight(); - } - } -} - diff --git a/policy/com/android/internal/policy/impl/LockPatternKeyguardViewProperties.java b/policy/com/android/internal/policy/impl/LockPatternKeyguardViewProperties.java deleted file mode 100644 index ed5a058..0000000 --- a/policy/com/android/internal/policy/impl/LockPatternKeyguardViewProperties.java +++ /dev/null @@ -1,62 +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; - -import com.android.internal.widget.LockPatternUtils; - -import android.content.Context; -import com.android.internal.telephony.IccCard; - -/** - * 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, - KeyguardUpdateMonitor updateMonitor, - KeyguardWindowController controller) { - return new LockPatternKeyguardView(context, updateMonitor, - mLockPatternUtils, controller); - } - - public boolean isSecure() { - return mLockPatternUtils.isSecure() || isSimPinSecure(); - } - - private boolean isSimPinSecure() { - final IccCard.State simState = mUpdateMonitor.getSimState(); - return (simState == IccCard.State.PIN_REQUIRED || simState == IccCard.State.PUK_REQUIRED - || simState == IccCard.State.ABSENT); - } - -} diff --git a/policy/com/android/internal/policy/impl/LockScreen.java b/policy/com/android/internal/policy/impl/LockScreen.java deleted file mode 100644 index a5ef1fa..0000000 --- a/policy/com/android/internal/policy/impl/LockScreen.java +++ /dev/null @@ -1,681 +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; - -import com.android.internal.R; -import com.android.internal.telephony.IccCard; -import com.android.internal.widget.LockPatternUtils; -import com.android.internal.widget.SlidingTab; - -import android.content.Context; -import android.content.res.Configuration; -import android.content.res.Resources; -import android.content.res.ColorStateList; -import android.text.format.DateFormat; -import android.view.KeyEvent; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.*; -import android.graphics.drawable.Drawable; -import android.util.Log; -import android.media.AudioManager; -import android.os.SystemClock; -import android.os.SystemProperties; -import android.provider.Settings; - -import java.util.Date; -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, KeyguardUpdateMonitor.InfoCallback, - KeyguardUpdateMonitor.SimStateCallback, SlidingTab.OnTriggerListener { - - 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 Status mStatus = Status.Normal; - - private final LockPatternUtils mLockPatternUtils; - private final KeyguardUpdateMonitor mUpdateMonitor; - private final KeyguardScreenCallback mCallback; - - private TextView mCarrier; - private SlidingTab mSelector; - private TextView mTime; - private TextView mDate; - private TextView mStatus1; - private TextView mStatus2; - private TextView mScreenLocked; - private TextView mEmergencyCallText; - private Button mEmergencyCallButton; - - // current configuration state of keyboard and display - private int mKeyboardHidden; - private int mCreationOrientation; - - // 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; - - private String mNextAlarm = null; - private Drawable mAlarmIcon = null; - private String mCharging = null; - private Drawable mChargingIcon = null; - - private boolean mSilentMode; - private AudioManager mAudioManager; - private String mDateFormatString; - private java.text.DateFormat mTimeFormat; - private boolean mEnableMenuKeyInLockScreen; - - /** - * The status of this lock screen. - */ - enum Status { - /** - * 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); - - private final boolean mShowStatusLines; - - Status(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 showStatusLines() { - return mShowStatusLines; - } - } - - /** - * 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 isMonkey = SystemProperties.getBoolean("ro.monkey", false); - final boolean fileOverride = (new File(ENABLE_MENU_KEY_FILE)).exists(); - return !configDisabled || isMonkey || 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; - - mKeyboardHidden = configuration.hardKeyboardHidden; - - 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); - } - - mCarrier = (TextView) findViewById(R.id.carrier); - // Required for Marquee to work - mCarrier.setSelected(true); - mCarrier.setTextColor(0xffffffff); - - mDate = (TextView) findViewById(R.id.date); - mStatus1 = (TextView) findViewById(R.id.status1); - mStatus2 = (TextView) findViewById(R.id.status2); - - mScreenLocked = (TextView) findViewById(R.id.screenLocked); - mSelector = (SlidingTab) findViewById(R.id.tab_selector); - mSelector.setHoldAfterTrigger(true, false); - mSelector.setLeftHintText(R.string.lockscreen_unlock_label); - - mEmergencyCallText = (TextView) findViewById(R.id.emergencyCallText); - mEmergencyCallButton = (Button) findViewById(R.id.emergencyCallButton); - mEmergencyCallButton.setText(R.string.lockscreen_emergency_call); - - mLockPatternUtils.updateEmergencyCallButtonState(mEmergencyCallButton); - mEmergencyCallButton.setOnClickListener(new View.OnClickListener() { - public void onClick(View v) { - mCallback.takeEmergencyCallAction(); - } - }); - - - setFocusable(true); - setFocusableInTouchMode(true); - setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS); - - updateMonitor.registerInfoCallback(this); - updateMonitor.registerSimStateCallback(this); - - mAudioManager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE); - mSilentMode = isSilentMode(); - - mSelector.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); - - updateRightTabResources(); - - mSelector.setOnTriggerListener(this); - - resetStatusInfo(updateMonitor); - } - - private boolean isSilentMode() { - return mAudioManager.getRingerMode() != AudioManager.RINGER_MODE_NORMAL; - } - - private void updateRightTabResources() { - boolean vibe = mSilentMode - && (mAudioManager.getRingerMode() == AudioManager.RINGER_MODE_VIBRATE); - - mSelector.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); - } - - private void resetStatusInfo(KeyguardUpdateMonitor updateMonitor) { - mShowingBatteryInfo = updateMonitor.shouldShowBatteryInfo(); - mPluggedIn = updateMonitor.isDevicePluggedIn(); - mBatteryLevel = updateMonitor.getBatteryLevel(); - - mStatus = getCurrentStatus(updateMonitor.getSimState()); - updateLayout(mStatus); - - refreshBatteryStringAndIcon(); - refreshAlarmDisplay(); - - mTimeFormat = DateFormat.getTimeFormat(getContext()); - mDateFormatString = getContext().getString(R.string.full_wday_month_day_no_year); - refreshTimeAndDateDisplay(); - updateStatusLines(); - } - - @Override - public boolean onKeyDown(int keyCode, KeyEvent event) { - if (keyCode == KeyEvent.KEYCODE_MENU && mEnableMenuKeyInLockScreen) { - mCallback.goToUnlockScreen(); - } - return false; - } - - /** {@inheritDoc} */ - public void onTrigger(View v, int whichHandle) { - if (whichHandle == SlidingTab.OnTriggerListener.LEFT_HANDLE) { - mCallback.goToUnlockScreen(); - } else if (whichHandle == SlidingTab.OnTriggerListener.RIGHT_HANDLE) { - // toggle silent mode - mSilentMode = !mSilentMode; - if (mSilentMode) { - final boolean vibe = (Settings.System.getInt( - getContext().getContentResolver(), - Settings.System.VIBRATE_IN_SILENT, 1) == 1); - - mAudioManager.setRingerMode(vibe - ? AudioManager.RINGER_MODE_VIBRATE - : AudioManager.RINGER_MODE_SILENT); - } else { - mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL); - } - - updateRightTabResources(); - - String message = mSilentMode ? - getContext().getString(R.string.global_action_silent_mode_on_status) : - getContext().getString(R.string.global_action_silent_mode_off_status); - - final int toastIcon = mSilentMode - ? R.drawable.ic_lock_ringer_off - : R.drawable.ic_lock_ringer_on; - - final int toastColor = mSilentMode - ? getContext().getResources().getColor(R.color.keyguard_text_color_soundoff) - : getContext().getResources().getColor(R.color.keyguard_text_color_soundon); - toastMessage(mScreenLocked, message, toastColor, toastIcon); - mCallback.pokeWakelock(); - } - } - - /** {@inheritDoc} */ - public void onGrabbedStateChange(View v, int grabbedState) { - if (grabbedState == SlidingTab.OnTriggerListener.RIGHT_HANDLE) { - mSilentMode = isSilentMode(); - mSelector.setRightHintText(mSilentMode ? R.string.lockscreen_sound_on_label - : R.string.lockscreen_sound_off_label); - } - mCallback.pokeWakelock(); - } - - /** - * Displays a message in a text view and then restores the previous text. - * @param textView The text view. - * @param text The text. - * @param color The color to apply to the text, or 0 if the existing color should be used. - * @param iconResourceId The left hand icon. - */ - private void toastMessage(final TextView textView, final String text, final int color, final int iconResourceId) { - if (mPendingR1 != null) { - textView.removeCallbacks(mPendingR1); - mPendingR1 = null; - } - if (mPendingR2 != null) { - mPendingR2.run(); // fire immediately, restoring non-toasted appearance - textView.removeCallbacks(mPendingR2); - mPendingR2 = null; - } - - final String oldText = textView.getText().toString(); - final ColorStateList oldColors = textView.getTextColors(); - - mPendingR1 = new Runnable() { - public void run() { - textView.setText(text); - if (color != 0) { - textView.setTextColor(color); - } - textView.setCompoundDrawablesWithIntrinsicBounds(iconResourceId, 0, 0, 0); - } - }; - - textView.postDelayed(mPendingR1, 0); - mPendingR2 = new Runnable() { - public void run() { - textView.setText(oldText); - textView.setTextColor(oldColors); - textView.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0); - } - }; - textView.postDelayed(mPendingR2, 3500); - } - private Runnable mPendingR1; - private Runnable mPendingR2; - - private void refreshAlarmDisplay() { - mNextAlarm = mLockPatternUtils.getNextAlarm(); - if (mNextAlarm != null) { - mAlarmIcon = getContext().getResources().getDrawable(R.drawable.ic_lock_idle_alarm); - } - updateStatusLines(); - } - - /** {@inheritDoc} */ - public void onRefreshBatteryInfo(boolean showBatteryInfo, boolean pluggedIn, - int batteryLevel) { - if (DBG) Log.d(TAG, "onRefreshBatteryInfo(" + showBatteryInfo + ", " + pluggedIn + ")"); - mShowingBatteryInfo = showBatteryInfo; - mPluggedIn = pluggedIn; - mBatteryLevel = batteryLevel; - - refreshBatteryStringAndIcon(); - updateStatusLines(); - } - - private void refreshBatteryStringAndIcon() { - if (!mShowingBatteryInfo) { - mCharging = null; - return; - } - - if (mChargingIcon == null) { - mChargingIcon = - getContext().getResources().getDrawable(R.drawable.ic_lock_idle_charging); - } - - if (mPluggedIn) { - if (mBatteryLevel >= 100) { - mCharging = getContext().getString(R.string.lockscreen_charged); - } else { - mCharging = getContext().getString(R.string.lockscreen_plugged_in, mBatteryLevel); - } - } else { - mCharging = getContext().getString(R.string.lockscreen_low_battery); - } - } - - /** {@inheritDoc} */ - public void onTimeChanged() { - refreshTimeAndDateDisplay(); - } - - private void refreshTimeAndDateDisplay() { - mDate.setText(DateFormat.format(mDateFormatString, new Date())); - } - - private void updateStatusLines() { - if (!mStatus.showStatusLines() - || (mCharging == null && mNextAlarm == null)) { - mStatus1.setVisibility(View.INVISIBLE); - mStatus2.setVisibility(View.INVISIBLE); - } else if (mCharging != null && mNextAlarm == null) { - // charging only - mStatus1.setVisibility(View.VISIBLE); - mStatus2.setVisibility(View.INVISIBLE); - - mStatus1.setText(mCharging); - mStatus1.setCompoundDrawablesWithIntrinsicBounds(mChargingIcon, null, null, null); - } else if (mNextAlarm != null && mCharging == null) { - // next alarm only - mStatus1.setVisibility(View.VISIBLE); - mStatus2.setVisibility(View.INVISIBLE); - - mStatus1.setText(mNextAlarm); - mStatus1.setCompoundDrawablesWithIntrinsicBounds(mAlarmIcon, null, null, null); - } else if (mCharging != null && mNextAlarm != null) { - // both charging and next alarm - mStatus1.setVisibility(View.VISIBLE); - mStatus2.setVisibility(View.VISIBLE); - - mStatus1.setText(mCharging); - mStatus1.setCompoundDrawablesWithIntrinsicBounds(mChargingIcon, null, null, null); - mStatus2.setText(mNextAlarm); - mStatus2.setCompoundDrawablesWithIntrinsicBounds(mAlarmIcon, null, null, null); - } - } - - /** {@inheritDoc} */ - public void onRefreshCarrierInfo(CharSequence plmn, CharSequence spn) { - if (DBG) Log.d(TAG, "onRefreshCarrierInfo(" + plmn + ", " + spn + ")"); - updateLayout(mStatus); - } - - /** - * Determine the current status of the lock screen given the sim state and other stuff. - */ - private Status getCurrentStatus(IccCard.State simState) { - boolean missingAndNotProvisioned = (!mUpdateMonitor.isDeviceProvisioned() - && simState == IccCard.State.ABSENT); - if (missingAndNotProvisioned) { - return Status.SimMissingLocked; - } - - switch (simState) { - case ABSENT: - return Status.SimMissing; - case NETWORK_LOCKED: - return Status.SimMissingLocked; - case NOT_READY: - return Status.SimMissing; - case PIN_REQUIRED: - return Status.SimLocked; - case PUK_REQUIRED: - return Status.SimPukLocked; - case READY: - return Status.Normal; - case UNKNOWN: - return Status.SimMissing; - } - return Status.SimMissing; - } - - /** - * Update the layout to match the current status. - */ - private void updateLayout(Status status) { - // The emergency call button no longer appears on this screen. - if (DBG) Log.d(TAG, "updateLayout: status=" + status); - - mEmergencyCallButton.setVisibility(View.GONE); // in almost all cases - - switch (status) { - case Normal: - // text - mCarrier.setText( - getCarrierString( - mUpdateMonitor.getTelephonyPlmn(), - mUpdateMonitor.getTelephonySpn())); - - // Empty now, but used for sliding tab feedback - mScreenLocked.setText(""); - - // layout - mScreenLocked.setVisibility(View.VISIBLE); - mSelector.setVisibility(View.VISIBLE); - mEmergencyCallText.setVisibility(View.GONE); - break; - case NetworkLocked: - // The carrier string shows both sim card status (i.e. No Sim Card) and - // carrier's name and/or "Emergency Calls Only" status - mCarrier.setText( - getCarrierString( - mUpdateMonitor.getTelephonyPlmn(), - getContext().getText(R.string.lockscreen_network_locked_message))); - mScreenLocked.setText(R.string.lockscreen_instructions_when_pattern_disabled); - - // layout - mScreenLocked.setVisibility(View.VISIBLE); - mSelector.setVisibility(View.VISIBLE); - mEmergencyCallText.setVisibility(View.GONE); - break; - case SimMissing: - // text - mCarrier.setText(R.string.lockscreen_missing_sim_message_short); - mScreenLocked.setText(R.string.lockscreen_missing_sim_instructions); - - // layout - mScreenLocked.setVisibility(View.VISIBLE); - mSelector.setVisibility(View.VISIBLE); - mEmergencyCallText.setVisibility(View.VISIBLE); - // do not need to show the e-call button; user may unlock - break; - case SimMissingLocked: - // text - mCarrier.setText( - getCarrierString( - mUpdateMonitor.getTelephonyPlmn(), - getContext().getText(R.string.lockscreen_missing_sim_message_short))); - mScreenLocked.setText(R.string.lockscreen_missing_sim_instructions); - - // layout - mScreenLocked.setVisibility(View.VISIBLE); - mSelector.setVisibility(View.GONE); // cannot unlock - mEmergencyCallText.setVisibility(View.VISIBLE); - mEmergencyCallButton.setVisibility(View.VISIBLE); - break; - case SimLocked: - // text - mCarrier.setText( - getCarrierString( - mUpdateMonitor.getTelephonyPlmn(), - getContext().getText(R.string.lockscreen_sim_locked_message))); - - // layout - mScreenLocked.setVisibility(View.INVISIBLE); - mSelector.setVisibility(View.VISIBLE); - mEmergencyCallText.setVisibility(View.GONE); - break; - case SimPukLocked: - // text - mCarrier.setText( - getCarrierString( - mUpdateMonitor.getTelephonyPlmn(), - getContext().getText(R.string.lockscreen_sim_puk_locked_message))); - mScreenLocked.setText(R.string.lockscreen_sim_puk_locked_instructions); - - // layout - mScreenLocked.setVisibility(View.VISIBLE); - mSelector.setVisibility(View.GONE); // cannot unlock - mEmergencyCallText.setVisibility(View.VISIBLE); - mEmergencyCallButton.setVisibility(View.VISIBLE); - break; - } - } - - static CharSequence getCarrierString(CharSequence telephonyPlmn, CharSequence telephonySpn) { - if (telephonyPlmn != null && telephonySpn == null) { - return telephonyPlmn; - } else if (telephonyPlmn != null && telephonySpn != null) { - return telephonyPlmn + "|" + telephonySpn; - } else if (telephonyPlmn == null && telephonySpn != null) { - return telephonySpn; - } else { - return ""; - } - } - - public void onSimStateChanged(IccCard.State simState) { - if (DBG) Log.d(TAG, "onSimStateChanged(" + simState + ")"); - mStatus = getCurrentStatus(simState); - updateLayout(mStatus); - updateStatusLines(); - } - - void updateConfiguration() { - Configuration newConfig = getResources().getConfiguration(); - if (newConfig.orientation != mCreationOrientation) { - mCallback.recreateMe(newConfig); - } else if (newConfig.hardKeyboardHidden != mKeyboardHidden) { - mKeyboardHidden = newConfig.hardKeyboardHidden; - final boolean isKeyboardOpen = mKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO; - if (mUpdateMonitor.isKeyguardBypassEnabled() && isKeyboardOpen) { - mCallback.goToUnlockScreen(); - } - } - } - - @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() { - - } - - /** {@inheritDoc} */ - public void onResume() { - resetStatusInfo(mUpdateMonitor); - mLockPatternUtils.updateEmergencyCallButtonState(mEmergencyCallButton); - } - - /** {@inheritDoc} */ - public void cleanUp() { - mUpdateMonitor.removeCallback(this); - } - - /** {@inheritDoc} */ - public void onRingerModeChanged(int state) { - boolean silent = AudioManager.RINGER_MODE_NORMAL != state; - if (silent != mSilentMode) { - mSilentMode = silent; - updateRightTabResources(); - } - } - - public void onPhoneStateChanged(String newState) { - mLockPatternUtils.updateEmergencyCallButtonState(mEmergencyCallButton); - } -} diff --git a/policy/com/android/internal/policy/impl/PasswordUnlockScreen.java b/policy/com/android/internal/policy/impl/PasswordUnlockScreen.java deleted file mode 100644 index 39f2917..0000000 --- a/policy/com/android/internal/policy/impl/PasswordUnlockScreen.java +++ /dev/null @@ -1,267 +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; - -import android.app.admin.DevicePolicyManager; -import android.content.Context; -import android.content.res.Configuration; -import android.graphics.Rect; - -import com.android.internal.policy.impl.PatternUnlockScreen.FooterMode; -import com.android.internal.widget.LockPatternUtils; -import com.android.internal.widget.PasswordEntryKeyboardView; - -import android.os.CountDownTimer; -import android.os.SystemClock; -import android.telephony.TelephonyManager; -import android.text.method.DigitsKeyListener; -import android.text.method.TextKeyListener; -import android.view.KeyEvent; -import android.view.LayoutInflater; -import android.view.View; -import android.view.inputmethod.EditorInfo; -import android.widget.Button; -import android.widget.EditText; -import android.widget.LinearLayout; -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, - View.OnClickListener, KeyguardUpdateMonitor.InfoCallback, OnEditorActionListener { - - private final KeyguardUpdateMonitor mUpdateMonitor; - private final KeyguardScreenCallback mCallback; - - private EditText mPasswordEntry; - private Button mEmergencyCallButton; - private LockPatternUtils mLockPatternUtils; - private PasswordEntryKeyboardView mKeyboardView; - private PasswordEntryKeyboardHelper mKeyboardHelper; - - private int mCreationOrientation; - private int mCreationHardKeyboardHidden; - private CountDownTimer mCountdownTimer; - private TextView mTitle; - - // 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); - } - - final int quality = lockPatternUtils.getKeyguardStoredPasswordQuality(); - final boolean isAlpha = DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC == quality - || DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC == quality; - - mKeyboardView = (PasswordEntryKeyboardView) findViewById(R.id.keyboard); - mPasswordEntry = (EditText) findViewById(R.id.passwordEntry); - mPasswordEntry.setOnEditorActionListener(this); - mEmergencyCallButton = (Button) findViewById(R.id.emergencyCall); - mEmergencyCallButton.setOnClickListener(this); - mLockPatternUtils.updateEmergencyCallButtonState(mEmergencyCallButton); - mTitle = (TextView) findViewById(R.id.enter_password_label); - - mKeyboardHelper = new PasswordEntryKeyboardHelper(context, mKeyboardView, this); - mKeyboardHelper.setKeyboardMode(isAlpha ? PasswordEntryKeyboardHelper.KEYBOARD_MODE_ALPHA - : PasswordEntryKeyboardHelper.KEYBOARD_MODE_NUMERIC); - - mKeyboardView.setVisibility(mCreationHardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO - ? View.INVISIBLE : View.VISIBLE); - mPasswordEntry.requestFocus(); - - // This allows keyboards with overlapping qwerty/numeric keys to choose just the - // numeric keys. - if (isAlpha) { - mPasswordEntry.setKeyListener(TextKeyListener.getInstance()); - } else { - mPasswordEntry.setKeyListener(DigitsKeyListener.getInstance()); - } - - mKeyboardHelper.setVibratePattern(mLockPatternUtils.isTactileFeedbackEnabled() ? - com.android.internal.R.array.config_virtualKeyVibePattern : 0); - } - - @Override - protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) { - // send focus to the password field - return mPasswordEntry.requestFocus(direction, previouslyFocusedRect); - } - - /** {@inheritDoc} */ - public boolean needsInput() { - return false; - } - - /** {@inheritDoc} */ - public void onPause() { - - } - - /** {@inheritDoc} */ - public void onResume() { - // start fresh - mPasswordEntry.setText(""); - mPasswordEntry.requestFocus(); - mLockPatternUtils.updateEmergencyCallButtonState(mEmergencyCallButton); - - // if the user is currently locked out, enforce it. - long deadline = mLockPatternUtils.getLockoutAttemptDeadline(); - if (deadline != 0) { - handleAttemptLockout(deadline); - } - } - - /** {@inheritDoc} */ - public void cleanUp() { - mUpdateMonitor.removeCallback(this); - } - - public void onClick(View v) { - if (v == mEmergencyCallButton) { - mCallback.takeEmergencyCallAction(); - } - mCallback.pokeWakelock(); - } - - private void verifyPasswordAndUnlock() { - String entry = mPasswordEntry.getText().toString(); - if (mLockPatternUtils.checkPassword(entry)) { - mCallback.keyguardDone(true); - mCallback.reportSuccessfulUnlockAttempt(); - } 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); - } - } - 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(); - mCountdownTimer = 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); - mTitle.setText(instructions); - } - - @Override - public void onFinish() { - mPasswordEntry.setEnabled(true); - mTitle.setText(R.string.keyguard_password_enter_password_code); - mKeyboardView.setEnabled(true); - } - }.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) { - verifyPasswordAndUnlock(); - return true; - } - return false; - } - - public void onPhoneStateChanged(String newState) { - mLockPatternUtils.updateEmergencyCallButtonState(mEmergencyCallButton); - } - - public void onRefreshBatteryInfo(boolean showBatteryInfo, boolean pluggedIn, int batteryLevel) { - - } - - public void onRefreshCarrierInfo(CharSequence plmn, CharSequence spn) { - - } - - public void onRingerModeChanged(int state) { - - } - - public void onTimeChanged() { - - } - -} diff --git a/policy/com/android/internal/policy/impl/PatternUnlockScreen.java b/policy/com/android/internal/policy/impl/PatternUnlockScreen.java deleted file mode 100644 index 418e243..0000000 --- a/policy/com/android/internal/policy/impl/PatternUnlockScreen.java +++ /dev/null @@ -1,580 +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; - -import android.content.Context; -import android.content.res.Configuration; -import android.os.CountDownTimer; -import android.os.SystemClock; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.view.MotionEvent; -import android.widget.Button; -import android.widget.TextView; -import android.text.format.DateFormat; -import android.text.TextUtils; -import android.util.Log; -import com.android.internal.R; -import com.android.internal.telephony.IccCard; -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; -import java.util.Date; - -/** - * 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, KeyguardUpdateMonitor.InfoCallback, - KeyguardUpdateMonitor.SimStateCallback { - - 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 final LockPatternUtils mLockPatternUtils; - private final KeyguardUpdateMonitor mUpdateMonitor; - private final KeyguardScreenCallback mCallback; - - /** - * whether there is a fallback option available when the pattern is forgotten. - */ - private boolean mEnableFallback; - - private String mDateFormatString; - - private TextView mCarrier; - private TextView mDate; - - // 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; - - private String mNextAlarm = null; - - private String mInstructions = null; - private TextView mStatus1; - private TextView mStatusSep; - private TextView mStatus2; - - - private LockPatternView mLockPatternView; - - private ViewGroup mFooterNormal; - private ViewGroup mFooterForgotPattern; - - /** - * 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 Button mForgotPatternButton; - private Button mEmergencyAlone; - private Button mEmergencyTogether; - private int mCreationOrientation; - - enum FooterMode { - Normal, - ForgotLockPattern, - VerifyUnlocked - } - - private void updateFooter(FooterMode mode) { - switch (mode) { - case Normal: - mFooterNormal.setVisibility(View.VISIBLE); - mFooterForgotPattern.setVisibility(View.GONE); - break; - case ForgotLockPattern: - mFooterNormal.setVisibility(View.GONE); - mFooterForgotPattern.setVisibility(View.VISIBLE); - mForgotPatternButton.setVisibility(View.VISIBLE); - break; - case VerifyUnlocked: - mFooterNormal.setVisibility(View.GONE); - mFooterForgotPattern.setVisibility(View.GONE); - } - } - - /** - * @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) { - inflater.inflate(R.layout.keyguard_screen_unlock_portrait, this, true); - } else { - inflater.inflate(R.layout.keyguard_screen_unlock_landscape, this, true); - } - - mCarrier = (TextView) findViewById(R.id.carrier); - mDate = (TextView) findViewById(R.id.date); - - mDateFormatString = getContext().getString(R.string.full_wday_month_day_no_year); - refreshTimeAndDateDisplay(); - - mStatus1 = (TextView) findViewById(R.id.status1); - mStatusSep = (TextView) findViewById(R.id.statusSep); - mStatus2 = (TextView) findViewById(R.id.status2); - - resetStatusInfo(); - - - mLockPatternView = (LockPatternView) findViewById(R.id.lockPattern); - - mFooterNormal = (ViewGroup) findViewById(R.id.footerNormal); - mFooterForgotPattern = (ViewGroup) findViewById(R.id.footerForgotPattern); - - // emergency call buttons - final OnClickListener emergencyClick = new OnClickListener() { - public void onClick(View v) { - mCallback.takeEmergencyCallAction(); - } - }; - - mEmergencyAlone = (Button) findViewById(R.id.emergencyCallAlone); - mEmergencyAlone.setFocusable(false); // touch only! - mEmergencyAlone.setOnClickListener(emergencyClick); - mEmergencyTogether = (Button) findViewById(R.id.emergencyCallTogether); - mEmergencyTogether.setFocusable(false); - mEmergencyTogether.setOnClickListener(emergencyClick); - refreshEmergencyButtonText(); - - mForgotPatternButton = (Button) findViewById(R.id.forgotPattern); - mForgotPatternButton.setText(R.string.lockscreen_forgot_pattern_button_text); - mForgotPatternButton.setOnClickListener(new OnClickListener() { - - public void onClick(View v) { - mCallback.forgotPattern(true); - } - }); - - // 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); - - updateMonitor.registerInfoCallback(this); - updateMonitor.registerSimStateCallback(this); - setFocusableInTouchMode(true); - - // Required to get Marquee to work. - mCarrier.setSelected(true); - mCarrier.setTextColor(0xffffffff); - - // until we get an update... - mCarrier.setText( - LockScreen.getCarrierString( - mUpdateMonitor.getTelephonyPlmn(), - mUpdateMonitor.getTelephonySpn())); - } - - private void refreshEmergencyButtonText() { - mLockPatternUtils.updateEmergencyCallButtonState(mEmergencyAlone); - mLockPatternUtils.updateEmergencyCallButtonState(mEmergencyTogether); - } - - public void setEnableFallback(boolean state) { - if (DEBUG) Log.d(TAG, "setEnableFallback(" + state + ")"); - mEnableFallback = state; - } - - private void resetStatusInfo() { - mInstructions = null; - mShowingBatteryInfo = mUpdateMonitor.shouldShowBatteryInfo(); - mPluggedIn = mUpdateMonitor.isDevicePluggedIn(); - mBatteryLevel = mUpdateMonitor.getBatteryLevel(); - mNextAlarm = mLockPatternUtils.getNextAlarm(); - updateStatusLines(); - } - - private void updateStatusLines() { - if (mInstructions != null) { - // instructions only - mStatus1.setText(mInstructions); - if (TextUtils.isEmpty(mInstructions)) { - mStatus1.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0); - } else { - mStatus1.setCompoundDrawablesWithIntrinsicBounds( - R.drawable.ic_lock_idle_lock, 0, 0, 0); - } - - mStatus1.setVisibility(View.VISIBLE); - mStatusSep.setVisibility(View.GONE); - mStatus2.setVisibility(View.GONE); - } else if (mShowingBatteryInfo && mNextAlarm == null) { - // battery only - if (mPluggedIn) { - if (mBatteryLevel >= 100) { - mStatus1.setText(getContext().getString(R.string.lockscreen_charged)); - } else { - mStatus1.setText(getContext().getString(R.string.lockscreen_plugged_in, mBatteryLevel)); - } - } else { - mStatus1.setText(getContext().getString(R.string.lockscreen_low_battery)); - } - mStatus1.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_lock_idle_charging, 0, 0, 0); - - mStatus1.setVisibility(View.VISIBLE); - mStatusSep.setVisibility(View.GONE); - mStatus2.setVisibility(View.GONE); - - } else if (mNextAlarm != null && !mShowingBatteryInfo) { - // alarm only - mStatus1.setText(mNextAlarm); - mStatus1.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_lock_idle_alarm, 0, 0, 0); - - mStatus1.setVisibility(View.VISIBLE); - mStatusSep.setVisibility(View.GONE); - mStatus2.setVisibility(View.GONE); - } else if (mNextAlarm != null && mShowingBatteryInfo) { - // both battery and next alarm - mStatus1.setText(mNextAlarm); - mStatusSep.setText("|"); - mStatus2.setText(getContext().getString( - R.string.lockscreen_battery_short, - Math.min(100, mBatteryLevel))); - mStatus1.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_lock_idle_alarm, 0, 0, 0); - if (mPluggedIn) { - mStatus2.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_lock_idle_charging, 0, 0, 0); - } else { - mStatus2.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0); - } - - mStatus1.setVisibility(View.VISIBLE); - mStatusSep.setVisibility(View.VISIBLE); - mStatus2.setVisibility(View.VISIBLE); - } else { - // nothing specific to show; show general instructions - mStatus1.setText(R.string.lockscreen_pattern_instructions); - mStatus1.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_lock_idle_lock, 0, 0, 0); - - mStatus1.setVisibility(View.VISIBLE); - mStatusSep.setVisibility(View.GONE); - mStatus2.setVisibility(View.GONE); - } - } - - - private void refreshTimeAndDateDisplay() { - mDate.setText(DateFormat.format(mDateFormatString, new Date())); - } - - - @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; - } - - - // ---------- InfoCallback - - /** {@inheritDoc} */ - public void onRefreshBatteryInfo(boolean showBatteryInfo, boolean pluggedIn, int batteryLevel) { - mShowingBatteryInfo = showBatteryInfo; - mPluggedIn = pluggedIn; - mBatteryLevel = batteryLevel; - updateStatusLines(); - } - - /** {@inheritDoc} */ - public void onTimeChanged() { - refreshTimeAndDateDisplay(); - } - - /** {@inheritDoc} */ - public void onRefreshCarrierInfo(CharSequence plmn, CharSequence spn) { - mCarrier.setText(LockScreen.getCarrierString(plmn, spn)); - } - - /** {@inheritDoc} */ - public void onRingerModeChanged(int state) { - // not currently used - } - - // ---------- SimStateCallback - - /** {@inheritDoc} */ - public void onSimStateChanged(IccCard.State simState) { - } - - @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; - } - } - - /** {@inheritDoc} */ - public void onResume() { - // reset header - resetStatusInfo(); - - // reset lock pattern - mLockPatternView.enableInput(); - mLockPatternView.setEnabled(true); - mLockPatternView.clearPattern(); - - // show "forgot pattern?" button if we have an alternate authentication method - mForgotPatternButton.setVisibility(mCallback.doesFallbackUnlockScreenExist() - ? View.VISIBLE : View.INVISIBLE); - - // 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); - } - - refreshEmergencyButtonText(); - } - - /** {@inheritDoc} */ - public void cleanUp() { - mUpdateMonitor.removeCallback(this); - } - - @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); - mInstructions = ""; - updateStatusLines(); - mCallback.keyguardDone(true); - mCallback.reportSuccessfulUnlockAttempt(); - } else { - 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++; - mCallback.reportFailedUnlockAttempt(); - } - if (mFailedPatternAttemptsSinceLastTimeout >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT) { - long deadline = mLockPatternUtils.setLockoutAttemptDeadline(); - handleAttemptLockout(deadline); - } else { - // TODO mUnlockIcon.setVisibility(View.VISIBLE); - mInstructions = getContext().getString(R.string.lockscreen_pattern_wrong); - updateStatusLines(); - mLockPatternView.postDelayed( - mCancelPatternRunnable, - PATTERN_CLEAR_TIMEOUT_MS); - } - } - } - } - - 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); - mInstructions = getContext().getString( - R.string.lockscreen_too_many_failed_attempts_countdown, - secondsRemaining); - updateStatusLines(); - } - - @Override - public void onFinish() { - mLockPatternView.setEnabled(true); - mInstructions = getContext().getString(R.string.lockscreen_pattern_instructions); - updateStatusLines(); - // TODO mUnlockIcon.setVisibility(View.VISIBLE); - mFailedPatternAttemptsSinceLastTimeout = 0; - if (mEnableFallback) { - updateFooter(FooterMode.ForgotLockPattern); - } else { - updateFooter(FooterMode.Normal); - } - } - }.start(); - } - - public void onPhoneStateChanged(String newState) { - refreshEmergencyButtonText(); - } -} diff --git a/policy/com/android/internal/policy/impl/PhoneLayoutInflater.java b/policy/com/android/internal/policy/impl/PhoneLayoutInflater.java deleted file mode 100644 index 6bf4beb..0000000 --- a/policy/com/android/internal/policy/impl/PhoneLayoutInflater.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2006 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; - -import java.util.Map; - -import android.content.Context; -import android.util.AttributeSet; -import android.view.View; -import android.view.LayoutInflater; - -public class PhoneLayoutInflater extends LayoutInflater { - private static final String[] sClassPrefixList = { - "android.widget.", - "android.webkit." - }; - - /** - * Instead of instantiating directly, you should retrieve an instance - * through {@link Context#getSystemService} - * - * @param context The Context in which in which to find resources and other - * application-specific things. - * - * @see Context#getSystemService - */ - public PhoneLayoutInflater(Context context) { - super(context); - } - - protected PhoneLayoutInflater(LayoutInflater original, Context newContext) { - super(original, newContext); - } - - /** Override onCreateView to instantiate names that correspond to the - widgets known to the Widget factory. If we don't find a match, - call through to our super class. - */ - @Override protected View onCreateView(String name, AttributeSet attrs) throws ClassNotFoundException { - for (String prefix : sClassPrefixList) { - try { - View view = createView(name, prefix, attrs); - if (view != null) { - return view; - } - } catch (ClassNotFoundException e) { - // In this case we want to let the base class take a crack - // at it. - } - } - - return super.onCreateView(name, attrs); - } - - public LayoutInflater cloneInContext(Context newContext) { - return new PhoneLayoutInflater(this, newContext); - } -} - diff --git a/policy/com/android/internal/policy/impl/PhoneWindow.java b/policy/com/android/internal/policy/impl/PhoneWindow.java deleted file mode 100644 index 0cb0efc..0000000 --- a/policy/com/android/internal/policy/impl/PhoneWindow.java +++ /dev/null @@ -1,2799 +0,0 @@ -/* - * - * 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; - -import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; -import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; -import static android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN; -import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR; -import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; -import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER; - -import com.android.internal.view.BaseSurfaceHolder; -import com.android.internal.view.RootViewSurfaceTaker; -import com.android.internal.view.menu.ContextMenuBuilder; -import com.android.internal.view.menu.MenuBuilder; -import com.android.internal.view.menu.MenuDialogHelper; -import com.android.internal.view.menu.MenuView; -import com.android.internal.view.menu.SubMenuBuilder; - -import android.app.KeyguardManager; -import android.app.SearchManager; -import android.content.ActivityNotFoundException; -import android.content.Context; -import android.content.Intent; -import android.content.res.Configuration; -import android.content.res.TypedArray; -import android.graphics.Canvas; -import android.graphics.PixelFormat; -import android.graphics.Rect; -import android.graphics.drawable.Drawable; -import android.media.AudioManager; -import android.net.Uri; -import android.os.Bundle; -import android.os.Message; -import android.os.Parcel; -import android.os.Parcelable; -import android.os.SystemClock; -import android.telephony.TelephonyManager; -import android.util.AndroidRuntimeException; -import android.util.Config; -import android.util.EventLog; -import android.util.Log; -import android.util.SparseArray; -import android.view.Gravity; -import android.view.HapticFeedbackConstants; -import android.view.KeyCharacterMap; -import android.view.KeyEvent; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuItem; -import android.view.MotionEvent; -import android.view.Surface; -import android.view.SurfaceHolder; -import android.view.View; -import android.view.ViewGroup; -import android.view.ViewManager; -import android.view.VolumePanel; -import android.view.Window; -import android.view.WindowManager; -import android.view.accessibility.AccessibilityEvent; -import android.view.accessibility.AccessibilityManager; -import android.view.animation.Animation; -import android.view.animation.AnimationUtils; -import android.view.inputmethod.InputMethodManager; -import android.widget.FrameLayout; -import android.widget.ImageView; -import android.widget.ProgressBar; -import android.widget.TextView; - -/** - * Android-specific Window. - * <p> - * todo: need to pull the generic functionality out into a base class - * in android.widget. - */ -public class PhoneWindow extends Window implements MenuBuilder.Callback { - - private final static String TAG = "PhoneWindow"; - - private final static boolean SWEEP_OPEN_MENU = false; - - /** - * Simple callback used by the context menu and its submenus. The options - * menu submenus do not use this (their behavior is more complex). - */ - ContextMenuCallback mContextMenuCallback = new ContextMenuCallback(FEATURE_CONTEXT_MENU); - - // This is the top-level view of the window, containing the window decor. - private DecorView mDecor; - - // This is the view in which the window contents are placed. It is either - // mDecor itself, or a child of mDecor where the contents go. - private ViewGroup mContentParent; - - SurfaceHolder.Callback mTakeSurfaceCallback; - BaseSurfaceHolder mSurfaceHolder; - - private boolean mIsFloating; - - private LayoutInflater mLayoutInflater; - - private TextView mTitleView; - - private DrawableFeatureState[] mDrawables; - - private PanelFeatureState[] mPanels; - - /** - * The panel that is prepared or opened (the most recent one if there are - * multiple panels). Shortcuts will go to this panel. It gets set in - * {@link #preparePanel} and cleared in {@link #closePanel}. - */ - private PanelFeatureState mPreparedPanel; - - /** - * The keycode that is currently held down (as a modifier) for chording. If - * this is 0, there is no key held down. - */ - private int mPanelChordingKey; - private boolean mPanelMayLongPress; - - private ImageView mLeftIconView; - - private ImageView mRightIconView; - - private ProgressBar mCircularProgressBar; - - private ProgressBar mHorizontalProgressBar; - - private int mBackgroundResource = 0; - - private Drawable mBackgroundDrawable; - - private int mFrameResource = 0; - - private int mTextColor = 0; - - private CharSequence mTitle = null; - - private int mTitleColor = 0; - - private ContextMenuBuilder mContextMenu; - private MenuDialogHelper mContextMenuHelper; - - private int mVolumeControlStreamType = AudioManager.USE_DEFAULT_STREAM_TYPE; - private long mVolumeKeyUpTime; - - private KeyguardManager mKeyguardManager = null; - - private SearchManager mSearchManager = null; - - private TelephonyManager mTelephonyManager = null; - - public PhoneWindow(Context context) { - super(context); - mLayoutInflater = LayoutInflater.from(context); - } - - @Override - public final void setContainer(Window container) { - super.setContainer(container); - } - - @Override - public boolean requestFeature(int featureId) { - if (mContentParent != null) { - throw new AndroidRuntimeException("requestFeature() must be called before adding content"); - } - final int features = getFeatures(); - if ((features != DEFAULT_FEATURES) && (featureId == FEATURE_CUSTOM_TITLE)) { - - /* Another feature is enabled and the user is trying to enable the custom title feature */ - throw new AndroidRuntimeException("You cannot combine custom titles with other title features"); - } - if (((features & (1 << FEATURE_CUSTOM_TITLE)) != 0) && (featureId != FEATURE_CUSTOM_TITLE)) { - - /* Custom title feature is enabled and the user is trying to enable another feature */ - throw new AndroidRuntimeException("You cannot combine custom titles with other title features"); - } - if (featureId == FEATURE_OPENGL) { - getAttributes().memoryType = WindowManager.LayoutParams.MEMORY_TYPE_GPU; - } - return super.requestFeature(featureId); - } - - @Override - public void setContentView(int layoutResID) { - if (mContentParent == null) { - installDecor(); - } else { - mContentParent.removeAllViews(); - } - mLayoutInflater.inflate(layoutResID, mContentParent); - final Callback cb = getCallback(); - if (cb != null) { - cb.onContentChanged(); - } - } - - @Override - public void setContentView(View view) { - setContentView(view, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT)); - } - - @Override - public void setContentView(View view, ViewGroup.LayoutParams params) { - if (mContentParent == null) { - installDecor(); - } else { - mContentParent.removeAllViews(); - } - mContentParent.addView(view, params); - final Callback cb = getCallback(); - if (cb != null) { - cb.onContentChanged(); - } - } - - @Override - public void addContentView(View view, ViewGroup.LayoutParams params) { - if (mContentParent == null) { - installDecor(); - } - mContentParent.addView(view, params); - final Callback cb = getCallback(); - if (cb != null) { - cb.onContentChanged(); - } - } - - @Override - public View getCurrentFocus() { - return mDecor != null ? mDecor.findFocus() : null; - } - - @Override - public void takeSurface(SurfaceHolder.Callback callback) { - mTakeSurfaceCallback = callback; - } - - @Override - public boolean isFloating() { - return mIsFloating; - } - - /** - * Return a LayoutInflater instance that can be used to inflate XML view layout - * resources for use in this Window. - * - * @return LayoutInflater The shared LayoutInflater. - */ - @Override - public LayoutInflater getLayoutInflater() { - return mLayoutInflater; - } - - @Override - public void setTitle(CharSequence title) { - if (mTitleView != null) { - mTitleView.setText(title); - } - mTitle = title; - } - - @Override - public void setTitleColor(int textColor) { - if (mTitleView != null) { - mTitleView.setTextColor(textColor); - } - mTitleColor = textColor; - } - - /** - * Prepares the panel to either be opened or chorded. This creates the Menu - * instance for the panel and populates it via the Activity callbacks. - * - * @param st The panel state to prepare. - * @param event The event that triggered the preparing of the panel. - * @return Whether the panel was prepared. If the panel should not be shown, - * returns false. - */ - public final boolean preparePanel(PanelFeatureState st, KeyEvent event) { - // Already prepared (isPrepared will be reset to false later) - if (st.isPrepared) - return true; - - if ((mPreparedPanel != null) && (mPreparedPanel != st)) { - // Another Panel is prepared and possibly open, so close it - closePanel(mPreparedPanel, false); - } - - final Callback cb = getCallback(); - - if (cb != null) { - st.createdPanelView = cb.onCreatePanelView(st.featureId); - } - - if (st.createdPanelView == null) { - // Init the panel state's menu--return false if init failed - if (st.menu == null) { - if (!initializePanelMenu(st) || (st.menu == null)) { - return false; - } - // Call callback, and return if it doesn't want to display menu - if ((cb == null) || !cb.onCreatePanelMenu(st.featureId, st.menu)) { - // Ditch the menu created above - st.menu = null; - - return false; - } - } - - // Callback and return if the callback does not want to show the menu - if (!cb.onPreparePanel(st.featureId, st.createdPanelView, st.menu)) { - return false; - } - - // Set the proper keymap - KeyCharacterMap kmap = KeyCharacterMap.load(event != null ? event.getDeviceId() : 0); - st.qwertyMode = kmap.getKeyboardType() != KeyCharacterMap.NUMERIC; - st.menu.setQwertyMode(st.qwertyMode); - } - - // Set other state - st.isPrepared = true; - st.isHandled = false; - mPreparedPanel = st; - - return true; - } - - @Override - public void onConfigurationChanged(Configuration newConfig) { - PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, false); - if ((st != null) && (st.menu != null)) { - final MenuBuilder menuBuilder = (MenuBuilder) st.menu; - - if (st.isOpen) { - // Freeze state - final Bundle state = new Bundle(); - menuBuilder.saveHierarchyState(state); - - // Remove the menu views since they need to be recreated - // according to the new configuration - clearMenuViews(st); - - // Re-open the same menu - reopenMenu(false); - - // Restore state - menuBuilder.restoreHierarchyState(state); - - } else { - // Clear menu views so on next menu opening, it will use - // the proper layout - clearMenuViews(st); - } - } - - } - - private static void clearMenuViews(PanelFeatureState st) { - - // This can be called on config changes, so we should make sure - // the views will be reconstructed based on the new orientation, etc. - - // Allow the callback to create a new panel view - st.createdPanelView = null; - - // Causes the decor view to be recreated - st.refreshDecorView = true; - - ((MenuBuilder) st.menu).clearMenuViews(); - } - - @Override - public final void openPanel(int featureId, KeyEvent event) { - openPanel(getPanelState(featureId, true), event); - } - - private void openPanel(PanelFeatureState st, KeyEvent event) { - // System.out.println("Open panel: isOpen=" + st.isOpen); - - // Already open, return - if (st.isOpen) { - return; - } - - Callback cb = getCallback(); - if ((cb != null) && (!cb.onMenuOpened(st.featureId, st.menu))) { - // Callback doesn't want the menu to open, reset any state - closePanel(st, true); - return; - } - - final WindowManager wm = getWindowManager(); - if (wm == null) { - return; - } - - // Prepare panel (should have been done before, but just in case) - if (!preparePanel(st, event)) { - return; - } - - if (st.decorView == null || st.refreshDecorView) { - if (st.decorView == null) { - // Initialize the panel decor, this will populate st.decorView - if (!initializePanelDecor(st) || (st.decorView == null)) - return; - } else if (st.refreshDecorView && (st.decorView.getChildCount() > 0)) { - // Decor needs refreshing, so remove its views - st.decorView.removeAllViews(); - } - - // This will populate st.shownPanelView - if (!initializePanelContent(st) || (st.shownPanelView == null)) { - return; - } - - ViewGroup.LayoutParams lp = st.shownPanelView.getLayoutParams(); - if (lp == null) { - lp = new ViewGroup.LayoutParams(WRAP_CONTENT, WRAP_CONTENT); - } - - int backgroundResId; - if (lp.width == ViewGroup.LayoutParams.MATCH_PARENT) { - // If the contents is fill parent for the width, set the - // corresponding background - backgroundResId = st.fullBackground; - } else { - // Otherwise, set the normal panel background - backgroundResId = st.background; - } - st.decorView.setWindowBackground(getContext().getResources().getDrawable( - backgroundResId)); - - - st.decorView.addView(st.shownPanelView, lp); - - /* - * Give focus to the view, if it or one of its children does not - * already have it. - */ - if (!st.shownPanelView.hasFocus()) { - st.shownPanelView.requestFocus(); - } - } - - st.isOpen = true; - st.isHandled = false; - - WindowManager.LayoutParams lp = new WindowManager.LayoutParams( - WRAP_CONTENT, WRAP_CONTENT, - st.x, st.y, WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG, - WindowManager.LayoutParams.FLAG_DITHER - | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM, - st.decorView.mDefaultOpacity); - - lp.gravity = st.gravity; - lp.windowAnimations = st.windowAnimations; - - wm.addView(st.decorView, lp); - // Log.v(TAG, "Adding main menu to window manager."); - } - - @Override - public final void closePanel(int featureId) { - if (featureId == FEATURE_CONTEXT_MENU) { - closeContextMenu(); - } else { - closePanel(getPanelState(featureId, true), true); - } - } - - /** - * Closes the given panel. - * - * @param st The panel to be closed. - * @param doCallback Whether to notify the callback that the panel was - * closed. If the panel is in the process of re-opening or - * opening another panel (e.g., menu opening a sub menu), the - * callback should not happen and this variable should be false. - * In addition, this method internally will only perform the - * callback if the panel is open. - */ - public final void closePanel(PanelFeatureState st, boolean doCallback) { - // System.out.println("Close panel: isOpen=" + st.isOpen); - final ViewManager wm = getWindowManager(); - if ((wm != null) && st.isOpen) { - if (st.decorView != null) { - wm.removeView(st.decorView); - // Log.v(TAG, "Removing main menu from window manager."); - } - - if (doCallback) { - callOnPanelClosed(st.featureId, st, null); - } - } - st.isPrepared = false; - st.isHandled = false; - st.isOpen = false; - - // This view is no longer shown, so null it out - st.shownPanelView = null; - - if (st.isInExpandedMode) { - // Next time the menu opens, it should not be in expanded mode, so - // force a refresh of the decor - st.refreshDecorView = true; - st.isInExpandedMode = false; - } - - if (mPreparedPanel == st) { - mPreparedPanel = null; - mPanelChordingKey = 0; - } - } - - @Override - public final void togglePanel(int featureId, KeyEvent event) { - PanelFeatureState st = getPanelState(featureId, true); - if (st.isOpen) { - closePanel(st, true); - } else { - openPanel(st, event); - } - } - - /** - * Called when the panel key is pushed down. - * @param featureId The feature ID of the relevant panel (defaults to FEATURE_OPTIONS_PANEL}. - * @param event The key event. - * @return Whether the key was handled. - */ - public final boolean onKeyDownPanel(int featureId, KeyEvent event) { - final int keyCode = event.getKeyCode(); - - if (event.getRepeatCount() == 0) { - // The panel key was pushed, so set the chording key - mPanelChordingKey = keyCode; - mPanelMayLongPress = false; - - PanelFeatureState st = getPanelState(featureId, true); - if (!st.isOpen) { - if (getContext().getResources().getConfiguration().keyboard - == Configuration.KEYBOARD_NOKEYS) { - mPanelMayLongPress = true; - } - return preparePanel(st, event); - } - - } else if (mPanelMayLongPress && mPanelChordingKey == keyCode - && (event.getFlags()&KeyEvent.FLAG_LONG_PRESS) != 0) { - // We have had a long press while in a state where this - // should be executed... do it! - mPanelChordingKey = 0; - mPanelMayLongPress = false; - InputMethodManager imm = (InputMethodManager) - getContext().getSystemService(Context.INPUT_METHOD_SERVICE); - if (imm != null) { - mDecor.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); - imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); - } - - } - - return false; - } - - /** - * Called when the panel key is released. - * @param featureId The feature ID of the relevant panel (defaults to FEATURE_OPTIONS_PANEL}. - * @param event The key event. - */ - public final void onKeyUpPanel(int featureId, KeyEvent event) { - // The panel key was released, so clear the chording key - if (mPanelChordingKey != 0) { - mPanelChordingKey = 0; - mPanelMayLongPress = false; - - if (event.isCanceled()) { - return; - } - - boolean playSoundEffect = false; - PanelFeatureState st = getPanelState(featureId, true); - if (st.isOpen || st.isHandled) { - - // Play the sound effect if the user closed an open menu (and not if - // they just released a menu shortcut) - playSoundEffect = st.isOpen; - - // Close menu - closePanel(st, true); - - } else if (st.isPrepared) { - - // Write 'menu opened' to event log - EventLog.writeEvent(50001, 0); - - // Show menu - openPanel(st, event); - - playSoundEffect = true; - } - - if (playSoundEffect) { - AudioManager audioManager = (AudioManager) getContext().getSystemService( - Context.AUDIO_SERVICE); - if (audioManager != null) { - audioManager.playSoundEffect(AudioManager.FX_KEY_CLICK); - } else { - Log.w(TAG, "Couldn't get audio manager"); - } - } - } - } - - @Override - public final void closeAllPanels() { - final ViewManager wm = getWindowManager(); - if (wm == null) { - return; - } - - final PanelFeatureState[] panels = mPanels; - final int N = panels != null ? panels.length : 0; - for (int i = 0; i < N; i++) { - final PanelFeatureState panel = panels[i]; - if (panel != null) { - closePanel(panel, true); - } - } - - closeContextMenu(); - } - - /** - * Closes the context menu. This notifies the menu logic of the close, along - * with dismissing it from the UI. - */ - private synchronized void closeContextMenu() { - if (mContextMenu != null) { - mContextMenu.close(); - dismissContextMenu(); - } - } - - /** - * Dismisses just the context menu UI. To close the context menu, use - * {@link #closeContextMenu()}. - */ - private synchronized void dismissContextMenu() { - mContextMenu = null; - - if (mContextMenuHelper != null) { - mContextMenuHelper.dismiss(); - mContextMenuHelper = null; - } - } - - @Override - public boolean performPanelShortcut(int featureId, int keyCode, KeyEvent event, int flags) { - return performPanelShortcut(getPanelState(featureId, true), keyCode, event, flags); - } - - private boolean performPanelShortcut(PanelFeatureState st, int keyCode, KeyEvent event, - int flags) { - if (event.isSystem() || (st == null)) { - return false; - } - - boolean handled = false; - - // Only try to perform menu shortcuts if preparePanel returned true (possible false - // return value from application not wanting to show the menu). - if ((st.isPrepared || preparePanel(st, event)) && st.menu != null) { - // The menu is prepared now, perform the shortcut on it - handled = st.menu.performShortcut(keyCode, event, flags); - } - - if (handled) { - // Mark as handled - st.isHandled = true; - - if ((flags & Menu.FLAG_PERFORM_NO_CLOSE) == 0) { - closePanel(st, true); - } - } - - return handled; - } - - @Override - public boolean performPanelIdentifierAction(int featureId, int id, int flags) { - - PanelFeatureState st = getPanelState(featureId, true); - if (!preparePanel(st, new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MENU))) { - return false; - } - if (st.menu == null) { - return false; - } - - boolean res = st.menu.performIdentifierAction(id, flags); - - closePanel(st, true); - - return res; - } - - public PanelFeatureState findMenuPanel(Menu menu) { - final PanelFeatureState[] panels = mPanels; - final int N = panels != null ? panels.length : 0; - for (int i = 0; i < N; i++) { - final PanelFeatureState panel = panels[i]; - if (panel != null && panel.menu == menu) { - return panel; - } - } - return null; - } - - public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) { - final Callback cb = getCallback(); - if (cb != null) { - final PanelFeatureState panel = findMenuPanel(menu.getRootMenu()); - if (panel != null) { - return cb.onMenuItemSelected(panel.featureId, item); - } - } - return false; - } - - public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) { - final PanelFeatureState panel = findMenuPanel(menu); - if (panel != null) { - // Close the panel and only do the callback if the menu is being - // closed - // completely, not if opening a sub menu - closePanel(panel, allMenusAreClosing); - } - } - - public void onCloseSubMenu(SubMenuBuilder subMenu) { - final Menu parentMenu = subMenu.getRootMenu(); - final PanelFeatureState panel = findMenuPanel(parentMenu); - - // Callback - if (panel != null) { - callOnPanelClosed(panel.featureId, panel, parentMenu); - closePanel(panel, true); - } - } - - public boolean onSubMenuSelected(final SubMenuBuilder subMenu) { - if (!subMenu.hasVisibleItems()) { - return true; - } - - // The window manager will give us a valid window token - new MenuDialogHelper(subMenu).show(null); - - return true; - } - - public void onMenuModeChange(MenuBuilder menu) { - reopenMenu(true); - } - - private void reopenMenu(boolean toggleMenuMode) { - PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, true); - - // Save the future expanded mode state since closePanel will reset it - boolean newExpandedMode = toggleMenuMode ? !st.isInExpandedMode : st.isInExpandedMode; - - st.refreshDecorView = true; - closePanel(st, false); - - // Set the expanded mode state - st.isInExpandedMode = newExpandedMode; - - openPanel(st, null); - } - - /** - * Initializes the menu associated with the given panel feature state. You - * must at the very least set PanelFeatureState.menu to the Menu to be - * associated with the given panel state. The default implementation creates - * a new menu for the panel state. - * - * @param st The panel whose menu is being initialized. - * @return Whether the initialization was successful. - */ - protected boolean initializePanelMenu(final PanelFeatureState st) { - final MenuBuilder menu = new MenuBuilder(getContext()); - - menu.setCallback(this); - st.setMenu(menu); - - return true; - } - - /** - * Perform initial setup of a panel. This should at the very least set the - * style information in the PanelFeatureState and must set - * PanelFeatureState.decor to the panel's window decor view. - * - * @param st The panel being initialized. - */ - protected boolean initializePanelDecor(PanelFeatureState st) { - st.decorView = new DecorView(getContext(), st.featureId); - st.gravity = Gravity.CENTER | Gravity.BOTTOM; - st.setStyle(getContext()); - - return true; - } - - /** - * Initializes the panel associated with the panel feature state. You must - * at the very least set PanelFeatureState.panel to the View implementing - * its contents. The default implementation gets the panel from the menu. - * - * @param st The panel state being initialized. - * @return Whether the initialization was successful. - */ - protected boolean initializePanelContent(PanelFeatureState st) { - - if (st.createdPanelView != null) { - st.shownPanelView = st.createdPanelView; - return true; - } - - final MenuBuilder menu = (MenuBuilder)st.menu; - if (menu == null) { - return false; - } - - st.shownPanelView = menu.getMenuView((st.isInExpandedMode) ? MenuBuilder.TYPE_EXPANDED - : MenuBuilder.TYPE_ICON, st.decorView); - - if (st.shownPanelView != null) { - // Use the menu View's default animations if it has any - final int defaultAnimations = ((MenuView) st.shownPanelView).getWindowAnimations(); - if (defaultAnimations != 0) { - st.windowAnimations = defaultAnimations; - } - return true; - } else { - return false; - } - } - - @Override - public boolean performContextMenuIdentifierAction(int id, int flags) { - return (mContextMenu != null) ? mContextMenu.performIdentifierAction(id, flags) : false; - } - - @Override - public final void setBackgroundDrawable(Drawable drawable) { - if (drawable != mBackgroundDrawable || mBackgroundResource != 0) { - mBackgroundResource = 0; - mBackgroundDrawable = drawable; - if (mDecor != null) { - mDecor.setWindowBackground(drawable); - } - } - } - - @Override - public final void setFeatureDrawableResource(int featureId, int resId) { - if (resId != 0) { - DrawableFeatureState st = getDrawableState(featureId, true); - if (st.resid != resId) { - st.resid = resId; - st.uri = null; - st.local = getContext().getResources().getDrawable(resId); - updateDrawable(featureId, st, false); - } - } else { - setFeatureDrawable(featureId, null); - } - } - - @Override - public final void setFeatureDrawableUri(int featureId, Uri uri) { - if (uri != null) { - DrawableFeatureState st = getDrawableState(featureId, true); - if (st.uri == null || !st.uri.equals(uri)) { - st.resid = 0; - st.uri = uri; - st.local = loadImageURI(uri); - updateDrawable(featureId, st, false); - } - } else { - setFeatureDrawable(featureId, null); - } - } - - @Override - public final void setFeatureDrawable(int featureId, Drawable drawable) { - DrawableFeatureState st = getDrawableState(featureId, true); - st.resid = 0; - st.uri = null; - if (st.local != drawable) { - st.local = drawable; - updateDrawable(featureId, st, false); - } - } - - @Override - public void setFeatureDrawableAlpha(int featureId, int alpha) { - DrawableFeatureState st = getDrawableState(featureId, true); - if (st.alpha != alpha) { - st.alpha = alpha; - updateDrawable(featureId, st, false); - } - } - - protected final void setFeatureDefaultDrawable(int featureId, Drawable drawable) { - DrawableFeatureState st = getDrawableState(featureId, true); - if (st.def != drawable) { - st.def = drawable; - updateDrawable(featureId, st, false); - } - } - - @Override - public final void setFeatureInt(int featureId, int value) { - // XXX Should do more management (as with drawable features) to - // deal with interactions between multiple window policies. - updateInt(featureId, value, false); - } - - /** - * Update the state of a drawable feature. This should be called, for every - * drawable feature supported, as part of onActive(), to make sure that the - * contents of a containing window is properly updated. - * - * @see #onActive - * @param featureId The desired drawable feature to change. - * @param fromActive Always true when called from onActive(). - */ - protected final void updateDrawable(int featureId, boolean fromActive) { - final DrawableFeatureState st = getDrawableState(featureId, false); - if (st != null) { - updateDrawable(featureId, st, fromActive); - } - } - - /** - * Called when a Drawable feature changes, for the window to update its - * graphics. - * - * @param featureId The feature being changed. - * @param drawable The new Drawable to show, or null if none. - * @param alpha The new alpha blending of the Drawable. - */ - protected void onDrawableChanged(int featureId, Drawable drawable, int alpha) { - ImageView view; - if (featureId == FEATURE_LEFT_ICON) { - view = getLeftIconView(); - } else if (featureId == FEATURE_RIGHT_ICON) { - view = getRightIconView(); - } else { - return; - } - - if (drawable != null) { - drawable.setAlpha(alpha); - view.setImageDrawable(drawable); - view.setVisibility(View.VISIBLE); - } else { - view.setVisibility(View.GONE); - } - } - - /** - * Called when an int feature changes, for the window to update its - * graphics. - * - * @param featureId The feature being changed. - * @param value The new integer value. - */ - protected void onIntChanged(int featureId, int value) { - if (featureId == FEATURE_PROGRESS || featureId == FEATURE_INDETERMINATE_PROGRESS) { - updateProgressBars(value); - } else if (featureId == FEATURE_CUSTOM_TITLE) { - FrameLayout titleContainer = (FrameLayout) findViewById(com.android.internal.R.id.title_container); - if (titleContainer != null) { - mLayoutInflater.inflate(value, titleContainer); - } - } - } - - /** - * Updates the progress bars that are shown in the title bar. - * - * @param value Can be one of {@link Window#PROGRESS_VISIBILITY_ON}, - * {@link Window#PROGRESS_VISIBILITY_OFF}, - * {@link Window#PROGRESS_INDETERMINATE_ON}, - * {@link Window#PROGRESS_INDETERMINATE_OFF}, or a value - * starting at {@link Window#PROGRESS_START} through - * {@link Window#PROGRESS_END} for setting the default - * progress (if {@link Window#PROGRESS_END} is given, - * the progress bar widgets in the title will be hidden after an - * animation), a value between - * {@link Window#PROGRESS_SECONDARY_START} - - * {@link Window#PROGRESS_SECONDARY_END} for the - * secondary progress (if - * {@link Window#PROGRESS_SECONDARY_END} is given, the - * progress bar widgets will still be shown with the secondary - * progress bar will be completely filled in.) - */ - private void updateProgressBars(int value) { - ProgressBar circularProgressBar = getCircularProgressBar(true); - ProgressBar horizontalProgressBar = getHorizontalProgressBar(true); - - final int features = getLocalFeatures(); - if (value == PROGRESS_VISIBILITY_ON) { - if ((features & (1 << FEATURE_PROGRESS)) != 0) { - int level = horizontalProgressBar.getProgress(); - int visibility = (horizontalProgressBar.isIndeterminate() || level < 10000) ? - View.VISIBLE : View.INVISIBLE; - horizontalProgressBar.setVisibility(visibility); - } - if ((features & (1 << FEATURE_INDETERMINATE_PROGRESS)) != 0) { - circularProgressBar.setVisibility(View.VISIBLE); - } - } else if (value == PROGRESS_VISIBILITY_OFF) { - if ((features & (1 << FEATURE_PROGRESS)) != 0) { - horizontalProgressBar.setVisibility(View.GONE); - } - if ((features & (1 << FEATURE_INDETERMINATE_PROGRESS)) != 0) { - circularProgressBar.setVisibility(View.GONE); - } - } else if (value == PROGRESS_INDETERMINATE_ON) { - horizontalProgressBar.setIndeterminate(true); - } else if (value == PROGRESS_INDETERMINATE_OFF) { - horizontalProgressBar.setIndeterminate(false); - } else if (PROGRESS_START <= value && value <= PROGRESS_END) { - // We want to set the progress value before testing for visibility - // so that when the progress bar becomes visible again, it has the - // correct level. - horizontalProgressBar.setProgress(value - PROGRESS_START); - - if (value < PROGRESS_END) { - showProgressBars(horizontalProgressBar, circularProgressBar); - } else { - hideProgressBars(horizontalProgressBar, circularProgressBar); - } - } else if (PROGRESS_SECONDARY_START <= value && value <= PROGRESS_SECONDARY_END) { - horizontalProgressBar.setSecondaryProgress(value - PROGRESS_SECONDARY_START); - - showProgressBars(horizontalProgressBar, circularProgressBar); - } - - } - - private void showProgressBars(ProgressBar horizontalProgressBar, ProgressBar spinnyProgressBar) { - final int features = getLocalFeatures(); - if ((features & (1 << FEATURE_INDETERMINATE_PROGRESS)) != 0 && - spinnyProgressBar.getVisibility() == View.INVISIBLE) { - spinnyProgressBar.setVisibility(View.VISIBLE); - } - // Only show the progress bars if the primary progress is not complete - if ((features & (1 << FEATURE_PROGRESS)) != 0 && - horizontalProgressBar.getProgress() < 10000) { - horizontalProgressBar.setVisibility(View.VISIBLE); - } - } - - private void hideProgressBars(ProgressBar horizontalProgressBar, ProgressBar spinnyProgressBar) { - final int features = getLocalFeatures(); - Animation anim = AnimationUtils.loadAnimation(getContext(), com.android.internal.R.anim.fade_out); - anim.setDuration(1000); - if ((features & (1 << FEATURE_INDETERMINATE_PROGRESS)) != 0 && - spinnyProgressBar.getVisibility() == View.VISIBLE) { - spinnyProgressBar.startAnimation(anim); - spinnyProgressBar.setVisibility(View.INVISIBLE); - } - if ((features & (1 << FEATURE_PROGRESS)) != 0 && - horizontalProgressBar.getVisibility() == View.VISIBLE) { - horizontalProgressBar.startAnimation(anim); - horizontalProgressBar.setVisibility(View.INVISIBLE); - } - } - - /** - * Request that key events come to this activity. Use this if your activity - * has no views with focus, but the activity still wants a chance to process - * key events. - */ - @Override - public void takeKeyEvents(boolean get) { - mDecor.setFocusable(get); - } - - @Override - public boolean superDispatchKeyEvent(KeyEvent event) { - return mDecor.superDispatchKeyEvent(event); - } - - @Override - public boolean superDispatchTouchEvent(MotionEvent event) { - return mDecor.superDispatchTouchEvent(event); - } - - @Override - public boolean superDispatchTrackballEvent(MotionEvent event) { - return mDecor.superDispatchTrackballEvent(event); - } - - /** - * A key was pressed down and not handled by anything else in the window. - * - * @see #onKeyUp - * @see android.view.KeyEvent - */ - protected boolean onKeyDown(int featureId, int keyCode, KeyEvent event) { - final KeyEvent.DispatcherState dispatcher = - mDecor != null ? mDecor.getKeyDispatcherState() : null; - //Log.i(TAG, "Key down: repeat=" + event.getRepeatCount() - // + " flags=0x" + Integer.toHexString(event.getFlags())); - - switch (keyCode) { - case KeyEvent.KEYCODE_VOLUME_UP: - case KeyEvent.KEYCODE_VOLUME_DOWN: { - AudioManager audioManager = (AudioManager) getContext().getSystemService( - Context.AUDIO_SERVICE); - if (audioManager != null) { - /* - * Adjust the volume in on key down since it is more - * responsive to the user. - */ - audioManager.adjustSuggestedStreamVolume( - keyCode == KeyEvent.KEYCODE_VOLUME_UP - ? AudioManager.ADJUST_RAISE - : AudioManager.ADJUST_LOWER, - mVolumeControlStreamType, - AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_VIBRATE); - } - return true; - } - - - case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE: - /* Suppress PLAYPAUSE 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_FAST_FORWARD: { - Intent intent = new Intent(Intent.ACTION_MEDIA_BUTTON, null); - intent.putExtra(Intent.EXTRA_KEY_EVENT, event); - getContext().sendOrderedBroadcast(intent, null); - return true; - } - - case KeyEvent.KEYCODE_CAMERA: { - if (getKeyguardManager().inKeyguardRestrictedInputMode() - || dispatcher == null) { - break; - } - if (event.getRepeatCount() == 0) { - dispatcher.startTracking(event, this); - } else if (event.isLongPress() && dispatcher.isTracking(event)) { - dispatcher.performedLongPress(event); - mDecor.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); - sendCloseSystemWindows(); - // Broadcast an intent that the Camera button was longpressed - Intent intent = new Intent(Intent.ACTION_CAMERA_BUTTON, null); - intent.putExtra(Intent.EXTRA_KEY_EVENT, event); - getContext().sendOrderedBroadcast(intent, null); - } - return true; - } - - case KeyEvent.KEYCODE_MENU: { - onKeyDownPanel((featureId < 0) ? FEATURE_OPTIONS_PANEL : featureId, event); - return true; - } - - case KeyEvent.KEYCODE_BACK: { - if (event.getRepeatCount() > 0) break; - if (featureId < 0) break; - // Currently don't do anything with long press. - dispatcher.startTracking(event, this); - return true; - } - - case KeyEvent.KEYCODE_CALL: { - if (getKeyguardManager().inKeyguardRestrictedInputMode() - || dispatcher == null) { - break; - } - if (event.getRepeatCount() == 0) { - dispatcher.startTracking(event, this); - } else if (event.isLongPress() && dispatcher.isTracking(event)) { - dispatcher.performedLongPress(event); - mDecor.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); - // launch the VoiceDialer - Intent intent = new Intent(Intent.ACTION_VOICE_COMMAND); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - try { - sendCloseSystemWindows(); - getContext().startActivity(intent); - } catch (ActivityNotFoundException e) { - startCallActivity(); - } - } - return true; - } - - case KeyEvent.KEYCODE_SEARCH: { - if (getKeyguardManager().inKeyguardRestrictedInputMode() - || dispatcher == null) { - break; - } - if (event.getRepeatCount() == 0) { - dispatcher.startTracking(event, this); - } else if (event.isLongPress() && dispatcher.isTracking(event)) { - Configuration config = getContext().getResources().getConfiguration(); - if (config.keyboard == Configuration.KEYBOARD_NOKEYS - || config.hardKeyboardHidden - == Configuration.HARDKEYBOARDHIDDEN_YES) { - // launch the search activity - Intent intent = new Intent(Intent.ACTION_SEARCH_LONG_PRESS); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - try { - mDecor.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); - sendCloseSystemWindows(); - getSearchManager().stopSearch(); - getContext().startActivity(intent); - // Only clear this if we successfully start the - // activity; otherwise we will allow the normal short - // press action to be performed. - dispatcher.performedLongPress(event); - return true; - } catch (ActivityNotFoundException e) { - // Ignore - } - } - } - break; - } - } - - return false; - } - - /** - * @return A handle to the keyguard manager. - */ - private KeyguardManager getKeyguardManager() { - if (mKeyguardManager == null) { - mKeyguardManager = (KeyguardManager) getContext().getSystemService(Context.KEYGUARD_SERVICE); - } - return mKeyguardManager; - } - - /** - * @return A handle to the search manager. - */ - private SearchManager getSearchManager() { - if (mSearchManager == null) { - mSearchManager = (SearchManager) getContext().getSystemService(Context.SEARCH_SERVICE); - } - return mSearchManager; - } - - /** - * A key was released and not handled by anything else in the window. - * - * @see #onKeyDown - * @see android.view.KeyEvent - */ - protected boolean onKeyUp(int featureId, int keyCode, KeyEvent event) { - final KeyEvent.DispatcherState dispatcher = - mDecor != null ? mDecor.getKeyDispatcherState() : null; - if (dispatcher != null) { - dispatcher.handleUpEvent(event); - } - //Log.i(TAG, "Key up: repeat=" + event.getRepeatCount() - // + " flags=0x" + Integer.toHexString(event.getFlags())); - - switch (keyCode) { - case KeyEvent.KEYCODE_VOLUME_UP: - case KeyEvent.KEYCODE_VOLUME_DOWN: { - AudioManager audioManager = (AudioManager) getContext().getSystemService( - Context.AUDIO_SERVICE); - if (audioManager != null) { - /* - * Play a sound. This is done on key up since we don't want the - * sound to play when a user holds down volume down to mute. - */ - audioManager.adjustSuggestedStreamVolume( - AudioManager.ADJUST_SAME, - mVolumeControlStreamType, - AudioManager.FLAG_PLAY_SOUND); - mVolumeKeyUpTime = SystemClock.uptimeMillis(); - } - return true; - } - - case KeyEvent.KEYCODE_MENU: { - onKeyUpPanel(featureId < 0 ? FEATURE_OPTIONS_PANEL : featureId, - event); - return true; - } - - case KeyEvent.KEYCODE_BACK: { - if (featureId < 0) break; - if (event.isTracking() && !event.isCanceled()) { - if (featureId == FEATURE_OPTIONS_PANEL) { - PanelFeatureState st = getPanelState(featureId, false); - if (st != null && st.isInExpandedMode) { - // If the user is in an expanded menu and hits back, it - // should go back to the icon menu - reopenMenu(true); - return true; - } - } - closePanel(featureId); - return true; - } - break; - } - - case KeyEvent.KEYCODE_HEADSETHOOK: - 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_FAST_FORWARD: { - Intent intent = new Intent(Intent.ACTION_MEDIA_BUTTON, null); - intent.putExtra(Intent.EXTRA_KEY_EVENT, event); - getContext().sendOrderedBroadcast(intent, null); - return true; - } - - case KeyEvent.KEYCODE_CAMERA: { - if (getKeyguardManager().inKeyguardRestrictedInputMode()) { - break; - } - if (event.isTracking() && !event.isCanceled()) { - // Add short press behavior here if desired - } - return true; - } - - case KeyEvent.KEYCODE_CALL: { - if (getKeyguardManager().inKeyguardRestrictedInputMode()) { - break; - } - if (event.isTracking() && !event.isCanceled()) { - startCallActivity(); - } - return true; - } - - case KeyEvent.KEYCODE_SEARCH: { - /* - * Do this in onKeyUp since the Search key is also used for - * chording quick launch shortcuts. - */ - if (getKeyguardManager().inKeyguardRestrictedInputMode()) { - break; - } - if (event.isTracking() && !event.isCanceled()) { - launchDefaultSearch(); - } - return true; - } - } - - return false; - } - - private void startCallActivity() { - sendCloseSystemWindows(); - Intent intent = new Intent(Intent.ACTION_CALL_BUTTON); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - getContext().startActivity(intent); - } - - @Override - protected void onActive() { - } - - @Override - public final View getDecorView() { - if (mDecor == null) { - installDecor(); - } - return mDecor; - } - - @Override - public final View peekDecorView() { - return mDecor; - } - - static private final String FOCUSED_ID_TAG = "android:focusedViewId"; - static private final String VIEWS_TAG = "android:views"; - static private final String PANELS_TAG = "android:Panels"; - - /** {@inheritDoc} */ - @Override - public Bundle saveHierarchyState() { - Bundle outState = new Bundle(); - if (mContentParent == null) { - return outState; - } - - SparseArray<Parcelable> states = new SparseArray<Parcelable>(); - mContentParent.saveHierarchyState(states); - outState.putSparseParcelableArray(VIEWS_TAG, states); - - // save the focused view id - View focusedView = mContentParent.findFocus(); - if (focusedView != null) { - if (focusedView.getId() != View.NO_ID) { - outState.putInt(FOCUSED_ID_TAG, focusedView.getId()); - } else { - if (Config.LOGD) { - Log.d(TAG, "couldn't save which view has focus because the focused view " - + focusedView + " has no id."); - } - } - } - - // save the panels - SparseArray<Parcelable> panelStates = new SparseArray<Parcelable>(); - savePanelState(panelStates); - if (panelStates.size() > 0) { - outState.putSparseParcelableArray(PANELS_TAG, panelStates); - } - - return outState; - } - - /** {@inheritDoc} */ - @Override - public void restoreHierarchyState(Bundle savedInstanceState) { - if (mContentParent == null) { - return; - } - - SparseArray<Parcelable> savedStates - = savedInstanceState.getSparseParcelableArray(VIEWS_TAG); - if (savedStates != null) { - mContentParent.restoreHierarchyState(savedStates); - } - - // restore the focused view - int focusedViewId = savedInstanceState.getInt(FOCUSED_ID_TAG, View.NO_ID); - if (focusedViewId != View.NO_ID) { - View needsFocus = mContentParent.findViewById(focusedViewId); - if (needsFocus != null) { - needsFocus.requestFocus(); - } else { - Log.w(TAG, - "Previously focused view reported id " + focusedViewId - + " during save, but can't be found during restore."); - } - } - - // restore the panels - SparseArray<Parcelable> panelStates = savedInstanceState.getSparseParcelableArray(PANELS_TAG); - if (panelStates != null) { - restorePanelState(panelStates); - } - } - - /** - * Invoked when the panels should freeze their state. - * - * @param icicles Save state into this. This is usually indexed by the - * featureId. This will be given to {@link #restorePanelState} in the - * future. - */ - private void savePanelState(SparseArray<Parcelable> icicles) { - PanelFeatureState[] panels = mPanels; - if (panels == null) { - return; - } - - for (int curFeatureId = panels.length - 1; curFeatureId >= 0; curFeatureId--) { - if (panels[curFeatureId] != null) { - icicles.put(curFeatureId, panels[curFeatureId].onSaveInstanceState()); - } - } - } - - /** - * Invoked when the panels should thaw their state from a previously frozen state. - * - * @param icicles The state saved by {@link #savePanelState} that needs to be thawed. - */ - private void restorePanelState(SparseArray<Parcelable> icicles) { - PanelFeatureState st; - for (int curFeatureId = icicles.size() - 1; curFeatureId >= 0; curFeatureId--) { - st = getPanelState(curFeatureId, false /* required */); - if (st == null) { - // The panel must not have been required, and is currently not around, skip it - continue; - } - - st.onRestoreInstanceState(icicles.get(curFeatureId)); - } - - /* - * Implementation note: call openPanelsAfterRestore later to actually open the - * restored panels. - */ - } - - /** - * Opens the panels that have had their state restored. This should be - * called sometime after {@link #restorePanelState} when it is safe to add - * to the window manager. - */ - private void openPanelsAfterRestore() { - PanelFeatureState[] panels = mPanels; - - if (panels == null) { - return; - } - - PanelFeatureState st; - for (int i = panels.length - 1; i >= 0; i--) { - st = panels[i]; - // We restore the panel if it was last open; we skip it if it - // now is open, to avoid a race condition if the user immediately - // opens it when we are resuming. - if ((st != null) && !st.isOpen && st.wasLastOpen) { - st.isInExpandedMode = st.wasLastExpanded; - openPanel(st, null); - } - } - } - - private final class DecorView extends FrameLayout implements RootViewSurfaceTaker { - /* package */int mDefaultOpacity = PixelFormat.OPAQUE; - - /** The feature ID of the panel, or -1 if this is the application's DecorView */ - private final int mFeatureId; - - private final Rect mDrawingBounds = new Rect(); - - private final Rect mBackgroundPadding = new Rect(); - - private final Rect mFramePadding = new Rect(); - - private final Rect mFrameOffsets = new Rect(); - - private boolean mChanging; - - private Drawable mMenuBackground; - private boolean mWatchingForMenu; - private int mDownY; - - public DecorView(Context context, int featureId) { - super(context); - mFeatureId = featureId; - } - - @Override - public boolean dispatchKeyEvent(KeyEvent event) { - final int keyCode = event.getKeyCode(); - final boolean isDown = event.getAction() == KeyEvent.ACTION_DOWN; - - /* - * If the user hits another key within the play sound delay, then - * cancel the sound - */ - if (keyCode != KeyEvent.KEYCODE_VOLUME_DOWN && keyCode != KeyEvent.KEYCODE_VOLUME_UP - && mVolumeKeyUpTime + VolumePanel.PLAY_SOUND_DELAY - > SystemClock.uptimeMillis()) { - /* - * The user has hit another key during the delay (e.g., 300ms) - * since the last volume key up, so cancel any sounds. - */ - AudioManager audioManager = (AudioManager) getContext().getSystemService( - Context.AUDIO_SERVICE); - if (audioManager != null) { - audioManager.adjustSuggestedStreamVolume(AudioManager.ADJUST_SAME, - mVolumeControlStreamType, AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE); - } - } - - if (isDown && (event.getRepeatCount() == 0)) { - // First handle chording of panel key: if a panel key is held - // but not released, try to execute a shortcut in it. - if ((mPanelChordingKey > 0) && (mPanelChordingKey != keyCode)) { - // Perform the shortcut (mPreparedPanel can be null since - // global shortcuts (such as search) don't rely on a - // prepared panel or menu). - boolean handled = performPanelShortcut(mPreparedPanel, keyCode, event, - Menu.FLAG_PERFORM_NO_CLOSE); - - if (!handled) { - /* - * If not handled, then pass it to the view hierarchy - * and anyone else that may be interested. - */ - handled = dispatchKeyShortcutEvent(event); - - if (handled && mPreparedPanel != null) { - mPreparedPanel.isHandled = true; - } - } - - if (handled) { - return true; - } - } - - // If a panel is open, perform a shortcut on it without the - // chorded panel key - if ((mPreparedPanel != null) && mPreparedPanel.isOpen) { - if (performPanelShortcut(mPreparedPanel, keyCode, event, 0)) { - return true; - } - } - } - - final Callback cb = getCallback(); - final boolean handled = cb != null && mFeatureId < 0 ? cb.dispatchKeyEvent(event) - : super.dispatchKeyEvent(event); - if (handled) { - return true; - } - return isDown ? PhoneWindow.this.onKeyDown(mFeatureId, event.getKeyCode(), event) - : PhoneWindow.this.onKeyUp(mFeatureId, event.getKeyCode(), event); - } - - @Override - public boolean dispatchTouchEvent(MotionEvent ev) { - final Callback cb = getCallback(); - return cb != null && mFeatureId < 0 ? cb.dispatchTouchEvent(ev) : super - .dispatchTouchEvent(ev); - } - - @Override - public boolean dispatchTrackballEvent(MotionEvent ev) { - final Callback cb = getCallback(); - return cb != null && mFeatureId < 0 ? cb.dispatchTrackballEvent(ev) : super - .dispatchTrackballEvent(ev); - } - - public boolean superDispatchKeyEvent(KeyEvent event) { - return super.dispatchKeyEvent(event); - } - - public boolean superDispatchTouchEvent(MotionEvent event) { - return super.dispatchTouchEvent(event); - } - - public boolean superDispatchTrackballEvent(MotionEvent event) { - return super.dispatchTrackballEvent(event); - } - - @Override - public boolean onTouchEvent(MotionEvent event) { - return onInterceptTouchEvent(event); - } - - private boolean isOutOfBounds(int x, int y) { - return x < -5 || y < -5 || x > (getWidth() + 5) - || y > (getHeight() + 5); - } - - @Override - public boolean onInterceptTouchEvent(MotionEvent event) { - int action = event.getAction(); - if (mFeatureId >= 0) { - if (action == MotionEvent.ACTION_DOWN) { - int x = (int)event.getX(); - int y = (int)event.getY(); - if (isOutOfBounds(x, y)) { - closePanel(mFeatureId); - return true; - } - } - } - - if (!SWEEP_OPEN_MENU) { - return false; - } - - if (mFeatureId >= 0) { - if (action == MotionEvent.ACTION_DOWN) { - Log.i(TAG, "Watchiing!"); - mWatchingForMenu = true; - mDownY = (int) event.getY(); - return false; - } - - if (!mWatchingForMenu) { - return false; - } - - int y = (int)event.getY(); - if (action == MotionEvent.ACTION_MOVE) { - if (y > (mDownY+30)) { - Log.i(TAG, "Closing!"); - closePanel(mFeatureId); - mWatchingForMenu = false; - return true; - } - } else if (action == MotionEvent.ACTION_UP) { - mWatchingForMenu = false; - } - - return false; - } - - //Log.i(TAG, "Intercept: action=" + action + " y=" + event.getY() - // + " (in " + getHeight() + ")"); - - if (action == MotionEvent.ACTION_DOWN) { - int y = (int)event.getY(); - if (y >= (getHeight()-5) && !hasChildren()) { - Log.i(TAG, "Watchiing!"); - mWatchingForMenu = true; - } - return false; - } - - if (!mWatchingForMenu) { - return false; - } - - int y = (int)event.getY(); - if (action == MotionEvent.ACTION_MOVE) { - if (y < (getHeight()-30)) { - Log.i(TAG, "Opening!"); - openPanel(FEATURE_OPTIONS_PANEL, new KeyEvent( - KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MENU)); - mWatchingForMenu = false; - return true; - } - } else if (action == MotionEvent.ACTION_UP) { - mWatchingForMenu = false; - } - - return false; - } - - @Override - public void sendAccessibilityEvent(int eventType) { - if (!AccessibilityManager.getInstance(mContext).isEnabled()) { - return; - } - - // if we are showing a feature that should be announced and one child - // make this child the event source since this is the feature itself - // otherwise the callback will take over and announce its client - if ((mFeatureId == FEATURE_OPTIONS_PANEL || - mFeatureId == FEATURE_CONTEXT_MENU || - mFeatureId == FEATURE_PROGRESS || - mFeatureId == FEATURE_INDETERMINATE_PROGRESS) - && getChildCount() == 1) { - getChildAt(0).sendAccessibilityEvent(eventType); - } else { - super.sendAccessibilityEvent(eventType); - } - } - - @Override - public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { - final Callback cb = getCallback(); - if (cb != null) { - if (cb.dispatchPopulateAccessibilityEvent(event)) { - return true; - } - } - return super.dispatchPopulateAccessibilityEvent(event); - } - - @Override - protected boolean setFrame(int l, int t, int r, int b) { - boolean changed = super.setFrame(l, t, r, b); - if (changed) { - final Rect drawingBounds = mDrawingBounds; - getDrawingRect(drawingBounds); - - Drawable fg = getForeground(); - if (fg != null) { - final Rect frameOffsets = mFrameOffsets; - drawingBounds.left += frameOffsets.left; - drawingBounds.top += frameOffsets.top; - drawingBounds.right -= frameOffsets.right; - drawingBounds.bottom -= frameOffsets.bottom; - fg.setBounds(drawingBounds); - final Rect framePadding = mFramePadding; - drawingBounds.left += framePadding.left - frameOffsets.left; - drawingBounds.top += framePadding.top - frameOffsets.top; - drawingBounds.right -= framePadding.right - frameOffsets.right; - drawingBounds.bottom -= framePadding.bottom - frameOffsets.bottom; - } - - Drawable bg = getBackground(); - if (bg != null) { - bg.setBounds(drawingBounds); - } - - if (SWEEP_OPEN_MENU) { - if (mMenuBackground == null && mFeatureId < 0 - && getAttributes().height - == WindowManager.LayoutParams.MATCH_PARENT) { - mMenuBackground = getContext().getResources().getDrawable( - com.android.internal.R.drawable.menu_background); - } - if (mMenuBackground != null) { - mMenuBackground.setBounds(drawingBounds.left, - drawingBounds.bottom-6, drawingBounds.right, - drawingBounds.bottom+20); - } - } - } - return changed; - } - - @Override - public void draw(Canvas canvas) { - super.draw(canvas); - - if (mMenuBackground != null) { - mMenuBackground.draw(canvas); - } - } - - - @Override - public boolean showContextMenuForChild(View originalView) { - // Reuse the context menu builder - if (mContextMenu == null) { - mContextMenu = new ContextMenuBuilder(getContext()); - mContextMenu.setCallback(mContextMenuCallback); - } else { - mContextMenu.clearAll(); - } - - mContextMenuHelper = mContextMenu.show(originalView, originalView.getWindowToken()); - return mContextMenuHelper != null; - } - - public void startChanging() { - mChanging = true; - } - - public void finishChanging() { - mChanging = false; - drawableChanged(); - } - - public void setWindowBackground(Drawable drawable) { - if (getBackground() != drawable) { - setBackgroundDrawable(drawable); - if (drawable != null) { - drawable.getPadding(mBackgroundPadding); - } else { - mBackgroundPadding.setEmpty(); - } - drawableChanged(); - } - } - - public void setWindowFrame(Drawable drawable) { - if (getForeground() != drawable) { - setForeground(drawable); - if (drawable != null) { - drawable.getPadding(mFramePadding); - } else { - mFramePadding.setEmpty(); - } - drawableChanged(); - } - } - - @Override - protected boolean fitSystemWindows(Rect insets) { - mFrameOffsets.set(insets); - if (getForeground() != null) { - drawableChanged(); - } - return super.fitSystemWindows(insets); - } - - private void drawableChanged() { - if (mChanging) { - return; - } - - setPadding(mFramePadding.left + mBackgroundPadding.left, mFramePadding.top - + mBackgroundPadding.top, mFramePadding.right + mBackgroundPadding.right, - mFramePadding.bottom + mBackgroundPadding.bottom); - requestLayout(); - invalidate(); - - int opacity = PixelFormat.OPAQUE; - - // Note: if there is no background, we will assume opaque. The - // common case seems to be that an application sets there to be - // no background so it can draw everything itself. For that, - // we would like to assume OPAQUE and let the app force it to - // the slower TRANSLUCENT mode if that is really what it wants. - Drawable bg = getBackground(); - Drawable fg = getForeground(); - if (bg != null) { - if (fg == null) { - opacity = bg.getOpacity(); - } else if (mFramePadding.left <= 0 && mFramePadding.top <= 0 - && mFramePadding.right <= 0 && mFramePadding.bottom <= 0) { - // If the frame padding is zero, then we can be opaque - // if either the frame -or- the background is opaque. - int fop = fg.getOpacity(); - int bop = bg.getOpacity(); - if (Config.LOGV) - Log.v(TAG, "Background opacity: " + bop + ", Frame opacity: " + fop); - if (fop == PixelFormat.OPAQUE || bop == PixelFormat.OPAQUE) { - opacity = PixelFormat.OPAQUE; - } else if (fop == PixelFormat.UNKNOWN) { - opacity = bop; - } else if (bop == PixelFormat.UNKNOWN) { - opacity = fop; - } else { - opacity = Drawable.resolveOpacity(fop, bop); - } - } else { - // For now we have to assume translucent if there is a - // frame with padding... there is no way to tell if the - // frame and background together will draw all pixels. - if (Config.LOGV) - Log.v(TAG, "Padding: " + mFramePadding); - opacity = PixelFormat.TRANSLUCENT; - } - } - - if (Config.LOGV) - Log.v(TAG, "Background: " + bg + ", Frame: " + fg); - if (Config.LOGV) - Log.v(TAG, "Selected default opacity: " + opacity); - - mDefaultOpacity = opacity; - if (mFeatureId < 0) { - setDefaultWindowFormat(opacity); - } - } - - @Override - public void onWindowFocusChanged(boolean hasWindowFocus) { - super.onWindowFocusChanged(hasWindowFocus); - - mPanelMayLongPress = false; - - // If the user is chording a menu shortcut, release the chord since - // this window lost focus - if (!hasWindowFocus && mPanelChordingKey != 0) { - closePanel(FEATURE_OPTIONS_PANEL); - } - - final Callback cb = getCallback(); - if (cb != null && mFeatureId < 0) { - cb.onWindowFocusChanged(hasWindowFocus); - } - } - - @Override - protected void onAttachedToWindow() { - super.onAttachedToWindow(); - - final Callback cb = getCallback(); - if (cb != null && mFeatureId < 0) { - cb.onAttachedToWindow(); - } - - if (mFeatureId == -1) { - /* - * The main window has been attached, try to restore any panels - * that may have been open before. This is called in cases where - * an activity is being killed for configuration change and the - * menu was open. When the activity is recreated, the menu - * should be shown again. - */ - openPanelsAfterRestore(); - } - } - - @Override - protected void onDetachedFromWindow() { - super.onDetachedFromWindow(); - - final Callback cb = getCallback(); - if (cb != null && mFeatureId < 0) { - cb.onDetachedFromWindow(); - } - } - - @Override - public void onCloseSystemDialogs(String reason) { - if (mFeatureId >= 0) { - closeAllPanels(); - } - } - - public android.view.SurfaceHolder.Callback willYouTakeTheSurface() { - return mFeatureId < 0 ? mTakeSurfaceCallback : null; - } - - public void setSurfaceType(int type) { - PhoneWindow.this.setType(type); - } - - public void setSurfaceFormat(int format) { - PhoneWindow.this.setFormat(format); - } - - public void setSurfaceKeepScreenOn(boolean keepOn) { - if (keepOn) PhoneWindow.this.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); - else PhoneWindow.this.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); - } - } - - protected DecorView generateDecor() { - return new DecorView(getContext(), -1); - } - - protected void setFeatureFromAttrs(int featureId, TypedArray attrs, - int drawableAttr, int alphaAttr) { - Drawable d = attrs.getDrawable(drawableAttr); - if (d != null) { - requestFeature(featureId); - setFeatureDefaultDrawable(featureId, d); - } - if ((getFeatures() & (1 << featureId)) != 0) { - int alpha = attrs.getInt(alphaAttr, -1); - if (alpha >= 0) { - setFeatureDrawableAlpha(featureId, alpha); - } - } - } - - protected ViewGroup generateLayout(DecorView decor) { - // Apply data from current theme. - - TypedArray a = getWindowStyle(); - - if (false) { - System.out.println("From style:"); - String s = "Attrs:"; - for (int i = 0; i < com.android.internal.R.styleable.Window.length; i++) { - s = s + " " + Integer.toHexString(com.android.internal.R.styleable.Window[i]) + "=" - + a.getString(i); - } - System.out.println(s); - } - - mIsFloating = a.getBoolean(com.android.internal.R.styleable.Window_windowIsFloating, false); - int flagsToUpdate = (FLAG_LAYOUT_IN_SCREEN|FLAG_LAYOUT_INSET_DECOR) - & (~getForcedWindowFlags()); - if (mIsFloating) { - setLayout(WRAP_CONTENT, WRAP_CONTENT); - setFlags(0, flagsToUpdate); - } else { - setFlags(FLAG_LAYOUT_IN_SCREEN|FLAG_LAYOUT_INSET_DECOR, flagsToUpdate); - } - - if (a.getBoolean(com.android.internal.R.styleable.Window_windowNoTitle, false)) { - requestFeature(FEATURE_NO_TITLE); - } - - if (a.getBoolean(com.android.internal.R.styleable.Window_windowFullscreen, false)) { - setFlags(FLAG_FULLSCREEN, FLAG_FULLSCREEN&(~getForcedWindowFlags())); - } - - if (a.getBoolean(com.android.internal.R.styleable.Window_windowShowWallpaper, false)) { - setFlags(FLAG_SHOW_WALLPAPER, FLAG_SHOW_WALLPAPER&(~getForcedWindowFlags())); - } - - WindowManager.LayoutParams params = getAttributes(); - - if (!hasSoftInputMode()) { - params.softInputMode = a.getInt( - com.android.internal.R.styleable.Window_windowSoftInputMode, - params.softInputMode); - } - - if (a.getBoolean(com.android.internal.R.styleable.Window_backgroundDimEnabled, - mIsFloating)) { - /* All dialogs should have the window dimmed */ - if ((getForcedWindowFlags()&WindowManager.LayoutParams.FLAG_DIM_BEHIND) == 0) { - params.flags |= WindowManager.LayoutParams.FLAG_DIM_BEHIND; - } - params.dimAmount = a.getFloat( - android.R.styleable.Window_backgroundDimAmount, 0.5f); - } - - if (params.windowAnimations == 0) { - params.windowAnimations = a.getResourceId( - com.android.internal.R.styleable.Window_windowAnimationStyle, 0); - } - - // The rest are only done if this window is not embedded; otherwise, - // the values are inherited from our container. - if (getContainer() == null) { - if (mBackgroundDrawable == null) { - if (mBackgroundResource == 0) { - mBackgroundResource = a.getResourceId( - com.android.internal.R.styleable.Window_windowBackground, 0); - } - if (mFrameResource == 0) { - mFrameResource = a.getResourceId(com.android.internal.R.styleable.Window_windowFrame, 0); - } - if (false) { - System.out.println("Background: " - + Integer.toHexString(mBackgroundResource) + " Frame: " - + Integer.toHexString(mFrameResource)); - } - } - mTextColor = a.getColor(com.android.internal.R.styleable.Window_textColor, 0xFF000000); - } - - // Inflate the window decor. - - int layoutResource; - int features = getLocalFeatures(); - // System.out.println("Features: 0x" + Integer.toHexString(features)); - if ((features & ((1 << FEATURE_LEFT_ICON) | (1 << FEATURE_RIGHT_ICON))) != 0) { - if (mIsFloating) { - layoutResource = com.android.internal.R.layout.dialog_title_icons; - } else { - layoutResource = com.android.internal.R.layout.screen_title_icons; - } - // System.out.println("Title Icons!"); - } else if ((features & ((1 << FEATURE_PROGRESS) | (1 << FEATURE_INDETERMINATE_PROGRESS))) != 0) { - // Special case for a window with only a progress bar (and title). - // XXX Need to have a no-title version of embedded windows. - layoutResource = com.android.internal.R.layout.screen_progress; - // System.out.println("Progress!"); - } else if ((features & (1 << FEATURE_CUSTOM_TITLE)) != 0) { - // Special case for a window with a custom title. - // If the window is floating, we need a dialog layout - if (mIsFloating) { - layoutResource = com.android.internal.R.layout.dialog_custom_title; - } else { - layoutResource = com.android.internal.R.layout.screen_custom_title; - } - } else if ((features & (1 << FEATURE_NO_TITLE)) == 0) { - // If no other features and not embedded, only need a title. - // If the window is floating, we need a dialog layout - if (mIsFloating) { - layoutResource = com.android.internal.R.layout.dialog_title; - } else { - layoutResource = com.android.internal.R.layout.screen_title; - } - // System.out.println("Title!"); - } else { - // Embedded, so no decoration is needed. - layoutResource = com.android.internal.R.layout.screen_simple; - // System.out.println("Simple!"); - } - - mDecor.startChanging(); - - View in = mLayoutInflater.inflate(layoutResource, null); - decor.addView(in, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT)); - - ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT); - if (contentParent == null) { - throw new RuntimeException("Window couldn't find content container view"); - } - - if ((features & (1 << FEATURE_INDETERMINATE_PROGRESS)) != 0) { - ProgressBar progress = getCircularProgressBar(false); - if (progress != null) { - progress.setIndeterminate(true); - } - } - - // Remaining setup -- of background and title -- that only applies - // to top-level windows. - if (getContainer() == null) { - Drawable drawable = mBackgroundDrawable; - if (mBackgroundResource != 0) { - drawable = getContext().getResources().getDrawable(mBackgroundResource); - } - mDecor.setWindowBackground(drawable); - drawable = null; - if (mFrameResource != 0) { - drawable = getContext().getResources().getDrawable(mFrameResource); - } - mDecor.setWindowFrame(drawable); - - // System.out.println("Text=" + Integer.toHexString(mTextColor) + - // " Sel=" + Integer.toHexString(mTextSelectedColor) + - // " Title=" + Integer.toHexString(mTitleColor)); - - if (mTitleColor == 0) { - mTitleColor = mTextColor; - } - - if (mTitle != null) { - setTitle(mTitle); - } - setTitleColor(mTitleColor); - } - - mDecor.finishChanging(); - - return contentParent; - } - - private void installDecor() { - if (mDecor == null) { - mDecor = generateDecor(); - mDecor.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS); - mDecor.setIsRootNamespace(true); - } - if (mContentParent == null) { - mContentParent = generateLayout(mDecor); - - mTitleView = (TextView)findViewById(com.android.internal.R.id.title); - if (mTitleView != null) { - if ((getLocalFeatures() & (1 << FEATURE_NO_TITLE)) != 0) { - View titleContainer = findViewById(com.android.internal.R.id.title_container); - if (titleContainer != null) { - titleContainer.setVisibility(View.GONE); - } else { - mTitleView.setVisibility(View.GONE); - } - if (mContentParent instanceof FrameLayout) { - ((FrameLayout)mContentParent).setForeground(null); - } - } else { - mTitleView.setText(mTitle); - } - } - } - } - - private Drawable loadImageURI(Uri uri) { - try { - return Drawable.createFromStream( - getContext().getContentResolver().openInputStream(uri), null); - } catch (Exception e) { - Log.w(TAG, "Unable to open content: " + uri); - } - return null; - } - - private DrawableFeatureState getDrawableState(int featureId, boolean required) { - if ((getFeatures() & (1 << featureId)) == 0) { - if (!required) { - return null; - } - throw new RuntimeException("The feature has not been requested"); - } - - DrawableFeatureState[] ar; - if ((ar = mDrawables) == null || ar.length <= featureId) { - DrawableFeatureState[] nar = new DrawableFeatureState[featureId + 1]; - if (ar != null) { - System.arraycopy(ar, 0, nar, 0, ar.length); - } - mDrawables = ar = nar; - } - - DrawableFeatureState st = ar[featureId]; - if (st == null) { - ar[featureId] = st = new DrawableFeatureState(featureId); - } - return st; - } - - /** - * Gets a panel's state based on its feature ID. - * - * @param featureId The feature ID of the panel. - * @param required Whether the panel is required (if it is required and it - * isn't in our features, this throws an exception). - * @return The panel state. - */ - private PanelFeatureState getPanelState(int featureId, boolean required) { - return getPanelState(featureId, required, null); - } - - /** - * Gets a panel's state based on its feature ID. - * - * @param featureId The feature ID of the panel. - * @param required Whether the panel is required (if it is required and it - * isn't in our features, this throws an exception). - * @param convertPanelState Optional: If the panel state does not exist, use - * this as the panel state. - * @return The panel state. - */ - private PanelFeatureState getPanelState(int featureId, boolean required, - PanelFeatureState convertPanelState) { - if ((getFeatures() & (1 << featureId)) == 0) { - if (!required) { - return null; - } - throw new RuntimeException("The feature has not been requested"); - } - - PanelFeatureState[] ar; - if ((ar = mPanels) == null || ar.length <= featureId) { - PanelFeatureState[] nar = new PanelFeatureState[featureId + 1]; - if (ar != null) { - System.arraycopy(ar, 0, nar, 0, ar.length); - } - mPanels = ar = nar; - } - - PanelFeatureState st = ar[featureId]; - if (st == null) { - ar[featureId] = st = (convertPanelState != null) - ? convertPanelState - : new PanelFeatureState(featureId); - } - return st; - } - - @Override - public final void setChildDrawable(int featureId, Drawable drawable) { - DrawableFeatureState st = getDrawableState(featureId, true); - st.child = drawable; - updateDrawable(featureId, st, false); - } - - @Override - public final void setChildInt(int featureId, int value) { - updateInt(featureId, value, false); - } - - @Override - public boolean isShortcutKey(int keyCode, KeyEvent event) { - PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, true); - return st.menu != null && st.menu.isShortcutKey(keyCode, event); - } - - private void updateDrawable(int featureId, DrawableFeatureState st, boolean fromResume) { - // Do nothing if the decor is not yet installed... an update will - // need to be forced when we eventually become active. - if (mContentParent == null) { - return; - } - - final int featureMask = 1 << featureId; - - if ((getFeatures() & featureMask) == 0 && !fromResume) { - return; - } - - Drawable drawable = null; - if (st != null) { - drawable = st.child; - if (drawable == null) - drawable = st.local; - if (drawable == null) - drawable = st.def; - } - if ((getLocalFeatures() & featureMask) == 0) { - if (getContainer() != null) { - if (isActive() || fromResume) { - getContainer().setChildDrawable(featureId, drawable); - } - } - } else if (st != null && (st.cur != drawable || st.curAlpha != st.alpha)) { - // System.out.println("Drawable changed: old=" + st.cur - // + ", new=" + drawable); - st.cur = drawable; - st.curAlpha = st.alpha; - onDrawableChanged(featureId, drawable, st.alpha); - } - } - - private void updateInt(int featureId, int value, boolean fromResume) { - - // Do nothing if the decor is not yet installed... an update will - // need to be forced when we eventually become active. - if (mContentParent == null) { - return; - } - - final int featureMask = 1 << featureId; - - if ((getFeatures() & featureMask) == 0 && !fromResume) { - return; - } - - if ((getLocalFeatures() & featureMask) == 0) { - if (getContainer() != null) { - getContainer().setChildInt(featureId, value); - } - } else { - onIntChanged(featureId, value); - } - } - - private ImageView getLeftIconView() { - if (mLeftIconView != null) { - return mLeftIconView; - } - if (mContentParent == null) { - installDecor(); - } - return (mLeftIconView = (ImageView)findViewById(com.android.internal.R.id.left_icon)); - } - - private ProgressBar getCircularProgressBar(boolean shouldInstallDecor) { - if (mCircularProgressBar != null) { - return mCircularProgressBar; - } - if (mContentParent == null && shouldInstallDecor) { - installDecor(); - } - mCircularProgressBar = (ProgressBar)findViewById(com.android.internal.R.id.progress_circular); - mCircularProgressBar.setVisibility(View.INVISIBLE); - return mCircularProgressBar; - } - - private ProgressBar getHorizontalProgressBar(boolean shouldInstallDecor) { - if (mHorizontalProgressBar != null) { - return mHorizontalProgressBar; - } - if (mContentParent == null && shouldInstallDecor) { - installDecor(); - } - mHorizontalProgressBar = (ProgressBar)findViewById(com.android.internal.R.id.progress_horizontal); - mHorizontalProgressBar.setVisibility(View.INVISIBLE); - return mHorizontalProgressBar; - } - - private ImageView getRightIconView() { - if (mRightIconView != null) { - return mRightIconView; - } - if (mContentParent == null) { - installDecor(); - } - return (mRightIconView = (ImageView)findViewById(com.android.internal.R.id.right_icon)); - } - - /** - * Helper method for calling the {@link Callback#onPanelClosed(int, Menu)} - * callback. This method will grab whatever extra state is needed for the - * callback that isn't given in the parameters. If the panel is not open, - * this will not perform the callback. - * - * @param featureId Feature ID of the panel that was closed. Must be given. - * @param panel Panel that was closed. Optional but useful if there is no - * menu given. - * @param menu The menu that was closed. Optional, but give if you have. - */ - private void callOnPanelClosed(int featureId, PanelFeatureState panel, Menu menu) { - final Callback cb = getCallback(); - if (cb == null) - return; - - // Try to get a menu - if (menu == null) { - // Need a panel to grab the menu, so try to get that - if (panel == null) { - if ((featureId >= 0) && (featureId < mPanels.length)) { - panel = mPanels[featureId]; - } - } - - if (panel != null) { - // menu still may be null, which is okay--we tried our best - menu = panel.menu; - } - } - - // If the panel is not open, do not callback - if ((panel != null) && (!panel.isOpen)) - return; - - cb.onPanelClosed(featureId, menu); - } - - /** - * Helper method for adding launch-search to most applications. Opens the - * search window using default settings. - * - * @return true if search window opened - */ - private boolean launchDefaultSearch() { - final Callback cb = getCallback(); - if (cb == null) { - return false; - } else { - sendCloseSystemWindows("search"); - return cb.onSearchRequested(); - } - } - - @Override - public void setVolumeControlStream(int streamType) { - mVolumeControlStreamType = streamType; - } - - @Override - public int getVolumeControlStream() { - return mVolumeControlStreamType; - } - - private static final class DrawableFeatureState { - DrawableFeatureState(int _featureId) { - featureId = _featureId; - } - - final int featureId; - - int resid; - - Uri uri; - - Drawable local; - - Drawable child; - - Drawable def; - - Drawable cur; - - int alpha = 255; - - int curAlpha = 255; - } - - private static final class PanelFeatureState { - - /** Feature ID for this panel. */ - int featureId; - - // Information pulled from the style for this panel. - - int background; - - /** The background when the panel spans the entire available width. */ - int fullBackground; - - int gravity; - - int x; - - int y; - - int windowAnimations; - - /** Dynamic state of the panel. */ - DecorView decorView; - - /** The panel that was returned by onCreatePanelView(). */ - View createdPanelView; - - /** The panel that we are actually showing. */ - View shownPanelView; - - /** Use {@link #setMenu} to set this. */ - Menu menu; - - /** - * Whether the panel has been prepared (see - * {@link PhoneWindow#preparePanel}). - */ - boolean isPrepared; - - /** - * Whether an item's action has been performed. This happens in obvious - * scenarios (user clicks on menu item), but can also happen with - * chording menu+(shortcut key). - */ - boolean isHandled; - - boolean isOpen; - - /** - * True if the menu is in expanded mode, false if the menu is in icon - * mode - */ - boolean isInExpandedMode; - - public boolean qwertyMode; - - boolean refreshDecorView; - - boolean wasLastOpen; - - boolean wasLastExpanded; - - /** - * Contains the state of the menu when told to freeze. - */ - Bundle frozenMenuState; - - PanelFeatureState(int featureId) { - this.featureId = featureId; - - refreshDecorView = false; - } - - void setStyle(Context context) { - TypedArray a = context.obtainStyledAttributes(com.android.internal.R.styleable.Theme); - background = a.getResourceId( - com.android.internal.R.styleable.Theme_panelBackground, 0); - fullBackground = a.getResourceId( - com.android.internal.R.styleable.Theme_panelFullBackground, 0); - windowAnimations = a.getResourceId( - com.android.internal.R.styleable.Theme_windowAnimationStyle, 0); - a.recycle(); - } - - void setMenu(Menu menu) { - this.menu = menu; - - if (frozenMenuState != null) { - ((MenuBuilder) menu).restoreHierarchyState(frozenMenuState); - frozenMenuState = null; - } - } - - Parcelable onSaveInstanceState() { - SavedState savedState = new SavedState(); - savedState.featureId = featureId; - savedState.isOpen = isOpen; - savedState.isInExpandedMode = isInExpandedMode; - - if (menu != null) { - savedState.menuState = new Bundle(); - ((MenuBuilder) menu).saveHierarchyState(savedState.menuState); - } - - return savedState; - } - - void onRestoreInstanceState(Parcelable state) { - SavedState savedState = (SavedState) state; - featureId = savedState.featureId; - wasLastOpen = savedState.isOpen; - wasLastExpanded = savedState.isInExpandedMode; - frozenMenuState = savedState.menuState; - - /* - * A LocalActivityManager keeps the same instance of this class around. - * The first time the menu is being shown after restoring, the - * Activity.onCreateOptionsMenu should be called. But, if it is the - * same instance then menu != null and we won't call that method. - * So, clear this. Also clear any cached views. - */ - menu = null; - createdPanelView = null; - shownPanelView = null; - decorView = null; - } - - private static class SavedState implements Parcelable { - int featureId; - boolean isOpen; - boolean isInExpandedMode; - Bundle menuState; - - public int describeContents() { - return 0; - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(featureId); - dest.writeInt(isOpen ? 1 : 0); - dest.writeInt(isInExpandedMode ? 1 : 0); - - if (isOpen) { - dest.writeBundle(menuState); - } - } - - private static SavedState readFromParcel(Parcel source) { - SavedState savedState = new SavedState(); - savedState.featureId = source.readInt(); - savedState.isOpen = source.readInt() == 1; - savedState.isInExpandedMode = source.readInt() == 1; - - if (savedState.isOpen) { - savedState.menuState = source.readBundle(); - } - - return savedState; - } - - public static final Parcelable.Creator<SavedState> CREATOR - = new Parcelable.Creator<SavedState>() { - public SavedState createFromParcel(Parcel in) { - return readFromParcel(in); - } - - public SavedState[] newArray(int size) { - return new SavedState[size]; - } - }; - } - - } - - /** - * Simple implementation of MenuBuilder.Callback that: - * <li> Opens a submenu when selected. - * <li> Calls back to the callback's onMenuItemSelected when an item is - * selected. - */ - private final class ContextMenuCallback implements MenuBuilder.Callback { - private int mFeatureId; - private MenuDialogHelper mSubMenuHelper; - - public ContextMenuCallback(int featureId) { - mFeatureId = featureId; - } - - public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) { - if (allMenusAreClosing) { - Callback callback = getCallback(); - if (callback != null) callback.onPanelClosed(mFeatureId, menu); - - if (menu == mContextMenu) { - dismissContextMenu(); - } - - // Dismiss the submenu, if it is showing - if (mSubMenuHelper != null) { - mSubMenuHelper.dismiss(); - mSubMenuHelper = null; - } - } - } - - public void onCloseSubMenu(SubMenuBuilder menu) { - Callback callback = getCallback(); - if (callback != null) callback.onPanelClosed(mFeatureId, menu.getRootMenu()); - } - - public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) { - Callback callback = getCallback(); - return (callback != null) && callback.onMenuItemSelected(mFeatureId, item); - } - - public void onMenuModeChange(MenuBuilder menu) { - } - - public boolean onSubMenuSelected(SubMenuBuilder subMenu) { - // Set a simple callback for the submenu - subMenu.setCallback(this); - - // The window manager will give us a valid window token - mSubMenuHelper = new MenuDialogHelper(subMenu); - mSubMenuHelper.show(null); - - return true; - } - } - - void sendCloseSystemWindows() { - PhoneWindowManager.sendCloseSystemWindows(getContext(), null); - } - - void sendCloseSystemWindows(String reason) { - PhoneWindowManager.sendCloseSystemWindows(getContext(), reason); - } -} diff --git a/policy/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/com/android/internal/policy/impl/PhoneWindowManager.java deleted file mode 100755 index a01e25b..0000000 --- a/policy/com/android/internal/policy/impl/PhoneWindowManager.java +++ /dev/null @@ -1,2434 +0,0 @@ -/* - * Copyright (C) 2006 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; - -import android.app.Activity; -import android.app.ActivityManagerNative; -import android.app.IActivityManager; -import android.app.IUiModeManager; -import android.app.UiModeManager; -import android.content.ActivityNotFoundException; -import android.content.BroadcastReceiver; -import android.content.ContentResolver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.pm.ActivityInfo; -import android.content.pm.PackageManager; -import android.content.res.Configuration; -import android.content.res.Resources; -import android.database.ContentObserver; -import android.graphics.PixelFormat; -import android.graphics.Rect; -import android.os.Handler; -import android.os.IBinder; -import android.os.LocalPowerManager; -import android.os.PowerManager; -import android.os.RemoteException; -import android.os.ServiceManager; -import android.os.SystemClock; -import android.os.SystemProperties; -import android.os.Vibrator; -import android.provider.Settings; - -import com.android.internal.policy.PolicyManager; -import com.android.internal.statusbar.IStatusBarService; -import com.android.internal.telephony.ITelephony; -import com.android.internal.widget.PointerLocationView; - -import android.util.Config; -import android.util.EventLog; -import android.util.Log; -import android.view.Display; -import android.view.Gravity; -import android.view.HapticFeedbackConstants; -import android.view.IWindowManager; -import android.view.KeyEvent; -import android.view.MotionEvent; -import android.view.WindowOrientationListener; -import android.view.RawInputEvent; -import android.view.Surface; -import android.view.View; -import android.view.ViewConfiguration; -import android.view.Window; -import android.view.WindowManager; -import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW; -import static android.view.WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN; -import static android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN; -import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; -import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR; -import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS; -import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED; -import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD; -import static android.view.WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON; -import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST; -import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; -import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW; -import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA; -import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY; -import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_PANEL; -import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL; -import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG; -import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD; -import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG; -import static android.view.WindowManager.LayoutParams.TYPE_PHONE; -import static android.view.WindowManager.LayoutParams.TYPE_PRIORITY_PHONE; -import static android.view.WindowManager.LayoutParams.TYPE_SEARCH_BAR; -import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR; -import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL; -import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG; -import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ALERT; -import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_ERROR; -import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; -import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG; -import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY; -import static android.view.WindowManager.LayoutParams.TYPE_TOAST; -import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; -import android.view.WindowManagerImpl; -import android.view.WindowManagerPolicy; -import android.view.animation.Animation; -import android.view.animation.AnimationUtils; -import android.media.IAudioService; -import android.media.AudioManager; - -import java.util.ArrayList; - -/** - * WindowManagerPolicy implementation for the Android phone UI. This - * introduces a new method suffix, Lp, for an internal lock of the - * PhoneWindowManager. This is used to protect some internal state, and - * can be acquired with either thw Lw and Li lock held, so has the restrictions - * of both of those when held. - */ -public class PhoneWindowManager implements WindowManagerPolicy { - static final String TAG = "WindowManager"; - static final boolean DEBUG = false; - static final boolean localLOGV = DEBUG ? Config.LOGD : Config.LOGV; - static final boolean DEBUG_LAYOUT = false; - static final boolean SHOW_STARTING_ANIMATIONS = true; - static final boolean SHOW_PROCESSES_ON_ALT_MENU = false; - - // wallpaper is at the bottom, though the window manager may move it. - static final int WALLPAPER_LAYER = 2; - static final int APPLICATION_LAYER = 2; - static final int PHONE_LAYER = 3; - static final int SEARCH_BAR_LAYER = 4; - static final int STATUS_BAR_PANEL_LAYER = 5; - static final int SYSTEM_DIALOG_LAYER = 6; - // toasts and the plugged-in battery thing - static final int TOAST_LAYER = 7; - static final int STATUS_BAR_LAYER = 8; - // SIM errors and unlock. Not sure if this really should be in a high layer. - static final int PRIORITY_PHONE_LAYER = 9; - // like the ANR / app crashed dialogs - static final int SYSTEM_ALERT_LAYER = 10; - // system-level error dialogs - static final int SYSTEM_ERROR_LAYER = 11; - // on-screen keyboards and other such input method user interfaces go here. - static final int INPUT_METHOD_LAYER = 12; - // on-screen keyboards and other such input method user interfaces go here. - static final int INPUT_METHOD_DIALOG_LAYER = 13; - // the keyguard; nothing on top of these can take focus, since they are - // responsible for power management when displayed. - static final int KEYGUARD_LAYER = 14; - static final int KEYGUARD_DIALOG_LAYER = 15; - // things in here CAN NOT take focus, but are shown on top of everything else. - static final int SYSTEM_OVERLAY_LAYER = 16; - - static final int APPLICATION_MEDIA_SUBLAYER = -2; - static final int APPLICATION_MEDIA_OVERLAY_SUBLAYER = -1; - static final int APPLICATION_PANEL_SUBLAYER = 1; - static final int APPLICATION_SUB_PANEL_SUBLAYER = 2; - - static final float SLIDE_TOUCH_EVENT_SIZE_LIMIT = 0.6f; - - // Debugging: set this to have the system act like there is no hard keyboard. - static final boolean KEYBOARD_ALWAYS_HIDDEN = false; - - static public final String SYSTEM_DIALOG_REASON_KEY = "reason"; - static public final String SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS = "globalactions"; - static public final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps"; - static public final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey"; - - final Object mLock = new Object(); - - Context mContext; - IWindowManager mWindowManager; - LocalPowerManager mPowerManager; - Vibrator mVibrator; // Vibrator for giving feedback of orientation changes - - // Vibrator pattern for haptic feedback of a long press. - long[] mLongPressVibePattern; - - // Vibrator pattern for haptic feedback of virtual key press. - long[] mVirtualKeyVibePattern; - - // Vibrator pattern for a short vibration. - long[] mKeyboardTapVibePattern; - - // Vibrator pattern for haptic feedback during boot when safe mode is disabled. - long[] mSafeModeDisabledVibePattern; - - // Vibrator pattern for haptic feedback during boot when safe mode is enabled. - long[] mSafeModeEnabledVibePattern; - - /** If true, hitting shift & menu will broadcast Intent.ACTION_BUG_REPORT */ - boolean mEnableShiftMenuBugReports = false; - - boolean mSafeMode; - WindowState mStatusBar = null; - final ArrayList<WindowState> mStatusBarPanels = new ArrayList<WindowState>(); - WindowState mKeyguard = null; - KeyguardViewMediator mKeyguardMediator; - GlobalActions mGlobalActions; - boolean mShouldTurnOffOnKeyUp; - RecentApplicationsDialog mRecentAppsDialog; - Handler mHandler; - - boolean mSystemReady; - boolean mLidOpen; - int mUiMode = Configuration.UI_MODE_TYPE_NORMAL; - int mDockMode = Intent.EXTRA_DOCK_STATE_UNDOCKED; - int mLidOpenRotation; - int mCarDockRotation; - int mDeskDockRotation; - boolean mCarDockEnablesAccelerometer; - boolean mDeskDockEnablesAccelerometer; - int mLidKeyboardAccessibility; - int mLidNavigationAccessibility; - boolean mScreenOn = false; - boolean mOrientationSensorEnabled = false; - int mCurrentAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; - static final int DEFAULT_ACCELEROMETER_ROTATION = 0; - int mAccelerometerDefault = DEFAULT_ACCELEROMETER_ROTATION; - boolean mHasSoftInput = false; - - int mPointerLocationMode = 0; - PointerLocationView mPointerLocationView = null; - - // The current size of the screen. - int mW, mH; - // During layout, the current screen borders with all outer decoration - // (status bar, input method dock) accounted for. - int mCurLeft, mCurTop, mCurRight, mCurBottom; - // During layout, the frame in which content should be displayed - // to the user, accounting for all screen decoration except for any - // space they deem as available for other content. This is usually - // the same as mCur*, but may be larger if the screen decor has supplied - // content insets. - int mContentLeft, mContentTop, mContentRight, mContentBottom; - // During layout, the current screen borders along with input method - // windows are placed. - int mDockLeft, mDockTop, mDockRight, mDockBottom; - // During layout, the layer at which the doc window is placed. - int mDockLayer; - - static final Rect mTmpParentFrame = new Rect(); - static final Rect mTmpDisplayFrame = new Rect(); - static final Rect mTmpContentFrame = new Rect(); - static final Rect mTmpVisibleFrame = new Rect(); - - WindowState mTopFullscreenOpaqueWindowState; - boolean mForceStatusBar; - boolean mHideLockScreen; - boolean mDismissKeyguard; - boolean mHomePressed; - Intent mHomeIntent; - Intent mCarDockIntent; - Intent mDeskDockIntent; - boolean mSearchKeyPressed; - boolean mConsumeSearchKeyUp; - - // support for activating the lock screen while the screen is on - boolean mAllowLockscreenWhenOn; - int mLockScreenTimeout; - boolean mLockScreenTimerActive; - - // Behavior of ENDCALL Button. (See Settings.System.END_BUTTON_BEHAVIOR.) - int mEndcallBehavior; - - // Behavior of POWER button while in-call and screen on. - // (See Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR.) - int mIncallPowerBehavior; - - int mLandscapeRotation = -1; - int mPortraitRotation = -1; - - // Nothing to see here, move along... - int mFancyRotationAnimation; - - ShortcutManager mShortcutManager; - PowerManager.WakeLock mBroadcastWakeLock; - - class SettingsObserver extends ContentObserver { - SettingsObserver(Handler handler) { - super(handler); - } - - void observe() { - ContentResolver resolver = mContext.getContentResolver(); - resolver.registerContentObserver(Settings.System.getUriFor( - Settings.System.END_BUTTON_BEHAVIOR), false, this); - resolver.registerContentObserver(Settings.Secure.getUriFor( - Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR), false, this); - resolver.registerContentObserver(Settings.System.getUriFor( - Settings.System.ACCELEROMETER_ROTATION), false, this); - resolver.registerContentObserver(Settings.System.getUriFor( - Settings.System.SCREEN_OFF_TIMEOUT), false, this); - resolver.registerContentObserver(Settings.System.getUriFor( - Settings.System.POINTER_LOCATION), false, this); - resolver.registerContentObserver(Settings.Secure.getUriFor( - Settings.Secure.DEFAULT_INPUT_METHOD), false, this); - resolver.registerContentObserver(Settings.System.getUriFor( - "fancy_rotation_anim"), false, this); - updateSettings(); - } - - @Override public void onChange(boolean selfChange) { - updateSettings(); - try { - mWindowManager.setRotation(USE_LAST_ROTATION, false, - mFancyRotationAnimation); - } catch (RemoteException e) { - // Ignore - } - } - } - - class MyOrientationListener extends WindowOrientationListener { - MyOrientationListener(Context context) { - super(context); - } - - @Override - public void onOrientationChanged(int rotation) { - // Send updates based on orientation value - if (localLOGV) Log.v(TAG, "onOrientationChanged, rotation changed to " +rotation); - try { - mWindowManager.setRotation(rotation, false, - mFancyRotationAnimation); - } catch (RemoteException e) { - // Ignore - - } - } - } - MyOrientationListener mOrientationListener; - - boolean useSensorForOrientationLp(int appOrientation) { - // The app says use the sensor. - if (appOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR) { - return true; - } - // The user preference says we can rotate, and the app is willing to rotate. - if (mAccelerometerDefault != 0 && - (appOrientation == ActivityInfo.SCREEN_ORIENTATION_USER - || appOrientation == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED)) { - return true; - } - // We're in a dock that has a rotation affinity, an the app is willing to rotate. - if ((mCarDockEnablesAccelerometer && mDockMode == Intent.EXTRA_DOCK_STATE_CAR) - || (mDeskDockEnablesAccelerometer && mDockMode == Intent.EXTRA_DOCK_STATE_DESK)) { - // Note we override the nosensor flag here. - if (appOrientation == ActivityInfo.SCREEN_ORIENTATION_USER - || appOrientation == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED - || appOrientation == ActivityInfo.SCREEN_ORIENTATION_NOSENSOR) { - return true; - } - } - // Else, don't use the sensor. - return false; - } - - /* - * We always let the sensor be switched on by default except when - * the user has explicitly disabled sensor based rotation or when the - * screen is switched off. - */ - boolean needSensorRunningLp() { - if (mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR) { - // If the application has explicitly requested to follow the - // orientation, then we need to turn the sensor or. - return true; - } - if ((mCarDockEnablesAccelerometer && mDockMode == Intent.EXTRA_DOCK_STATE_CAR) || - (mDeskDockEnablesAccelerometer && mDockMode == Intent.EXTRA_DOCK_STATE_DESK)) { - // enable accelerometer if we are docked in a dock that enables accelerometer - // orientation management, - return true; - } - if (mAccelerometerDefault == 0) { - // If the setting for using the sensor by default is enabled, then - // we will always leave it on. Note that the user could go to - // a window that forces an orientation that does not use the - // sensor and in theory we could turn it off... however, when next - // turning it on we won't have a good value for the current - // orientation for a little bit, which can cause orientation - // changes to lag, so we'd like to keep it always on. (It will - // still be turned off when the screen is off.) - return false; - } - return true; - } - - /* - * Various use cases for invoking this function - * screen turning off, should always disable listeners if already enabled - * screen turned on and current app has sensor based orientation, enable listeners - * if not already enabled - * screen turned on and current app does not have sensor orientation, disable listeners if - * already enabled - * screen turning on and current app has sensor based orientation, enable listeners if needed - * screen turning on and current app has nosensor based orientation, do nothing - */ - void updateOrientationListenerLp() { - if (!mOrientationListener.canDetectOrientation()) { - // If sensor is turned off or nonexistent for some reason - return; - } - //Could have been invoked due to screen turning on or off or - //change of the currently visible window's orientation - if (localLOGV) Log.v(TAG, "Screen status="+mScreenOn+ - ", current orientation="+mCurrentAppOrientation+ - ", SensorEnabled="+mOrientationSensorEnabled); - boolean disable = true; - if (mScreenOn) { - if (needSensorRunningLp()) { - disable = false; - //enable listener if not already enabled - if (!mOrientationSensorEnabled) { - mOrientationListener.enable(); - if(localLOGV) Log.v(TAG, "Enabling listeners"); - mOrientationSensorEnabled = true; - } - } - } - //check if sensors need to be disabled - if (disable && mOrientationSensorEnabled) { - mOrientationListener.disable(); - if(localLOGV) Log.v(TAG, "Disabling listeners"); - mOrientationSensorEnabled = false; - } - } - - Runnable mPowerLongPress = new Runnable() { - public void run() { - mShouldTurnOffOnKeyUp = false; - performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false); - sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS); - showGlobalActionsDialog(); - } - }; - - void showGlobalActionsDialog() { - if (mGlobalActions == null) { - mGlobalActions = new GlobalActions(mContext); - } - final boolean keyguardShowing = mKeyguardMediator.isShowingAndNotHidden(); - mGlobalActions.showDialog(keyguardShowing, isDeviceProvisioned()); - if (keyguardShowing) { - // since it took two seconds of long press to bring this up, - // poke the wake lock so they have some time to see the dialog. - mKeyguardMediator.pokeWakelock(); - } - } - - boolean isDeviceProvisioned() { - return Settings.Secure.getInt( - mContext.getContentResolver(), Settings.Secure.DEVICE_PROVISIONED, 0) != 0; - } - - /** - * When a home-key longpress expires, close other system windows and launch the recent apps - */ - Runnable mHomeLongPress = new Runnable() { - public void run() { - /* - * Eat the longpress so it won't dismiss the recent apps dialog when - * the user lets go of the home key - */ - mHomePressed = false; - performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false); - sendCloseSystemWindows(SYSTEM_DIALOG_REASON_RECENT_APPS); - showRecentAppsDialog(); - } - }; - - /** - * Create (if necessary) and launch the recent apps dialog - */ - void showRecentAppsDialog() { - if (mRecentAppsDialog == null) { - mRecentAppsDialog = new RecentApplicationsDialog(mContext); - } - mRecentAppsDialog.show(); - } - - /** {@inheritDoc} */ - public void init(Context context, IWindowManager windowManager, - LocalPowerManager powerManager) { - mContext = context; - mWindowManager = windowManager; - mPowerManager = powerManager; - mKeyguardMediator = new KeyguardViewMediator(context, this, powerManager); - mHandler = new Handler(); - mOrientationListener = new MyOrientationListener(mContext); - SettingsObserver settingsObserver = new SettingsObserver(mHandler); - settingsObserver.observe(); - mShortcutManager = new ShortcutManager(context, mHandler); - mShortcutManager.observe(); - mHomeIntent = new Intent(Intent.ACTION_MAIN, null); - mHomeIntent.addCategory(Intent.CATEGORY_HOME); - mHomeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK - | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); - mCarDockIntent = new Intent(Intent.ACTION_MAIN, null); - mCarDockIntent.addCategory(Intent.CATEGORY_CAR_DOCK); - mCarDockIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK - | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); - mDeskDockIntent = new Intent(Intent.ACTION_MAIN, null); - mDeskDockIntent.addCategory(Intent.CATEGORY_DESK_DOCK); - mDeskDockIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK - | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); - PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE); - mBroadcastWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, - "PhoneWindowManager.mBroadcastWakeLock"); - mEnableShiftMenuBugReports = "1".equals(SystemProperties.get("ro.debuggable")); - mLidOpenRotation = readRotation( - com.android.internal.R.integer.config_lidOpenRotation); - mCarDockRotation = readRotation( - com.android.internal.R.integer.config_carDockRotation); - mDeskDockRotation = readRotation( - com.android.internal.R.integer.config_deskDockRotation); - mCarDockEnablesAccelerometer = mContext.getResources().getBoolean( - com.android.internal.R.bool.config_carDockEnablesAccelerometer); - mDeskDockEnablesAccelerometer = mContext.getResources().getBoolean( - com.android.internal.R.bool.config_deskDockEnablesAccelerometer); - mLidKeyboardAccessibility = mContext.getResources().getInteger( - com.android.internal.R.integer.config_lidKeyboardAccessibility); - mLidNavigationAccessibility = mContext.getResources().getInteger( - com.android.internal.R.integer.config_lidNavigationAccessibility); - // register for dock events - IntentFilter filter = new IntentFilter(); - filter.addAction(UiModeManager.ACTION_ENTER_CAR_MODE); - filter.addAction(UiModeManager.ACTION_EXIT_CAR_MODE); - filter.addAction(UiModeManager.ACTION_ENTER_DESK_MODE); - filter.addAction(UiModeManager.ACTION_EXIT_DESK_MODE); - filter.addAction(Intent.ACTION_DOCK_EVENT); - Intent intent = context.registerReceiver(mDockReceiver, filter); - if (intent != null) { - // Retrieve current sticky dock event broadcast. - mDockMode = intent.getIntExtra(Intent.EXTRA_DOCK_STATE, - Intent.EXTRA_DOCK_STATE_UNDOCKED); - } - mVibrator = new Vibrator(); - mLongPressVibePattern = getLongIntArray(mContext.getResources(), - com.android.internal.R.array.config_longPressVibePattern); - mVirtualKeyVibePattern = getLongIntArray(mContext.getResources(), - com.android.internal.R.array.config_virtualKeyVibePattern); - mKeyboardTapVibePattern = getLongIntArray(mContext.getResources(), - com.android.internal.R.array.config_keyboardTapVibePattern); - mSafeModeDisabledVibePattern = getLongIntArray(mContext.getResources(), - com.android.internal.R.array.config_safeModeDisabledVibePattern); - mSafeModeEnabledVibePattern = getLongIntArray(mContext.getResources(), - com.android.internal.R.array.config_safeModeEnabledVibePattern); - } - - public void updateSettings() { - ContentResolver resolver = mContext.getContentResolver(); - boolean updateRotation = false; - View addView = null; - View removeView = null; - synchronized (mLock) { - mEndcallBehavior = Settings.System.getInt(resolver, - Settings.System.END_BUTTON_BEHAVIOR, - Settings.System.END_BUTTON_BEHAVIOR_DEFAULT); - mIncallPowerBehavior = Settings.Secure.getInt(resolver, - Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR, - Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_DEFAULT); - mFancyRotationAnimation = Settings.System.getInt(resolver, - "fancy_rotation_anim", 0) != 0 ? 0x80 : 0; - int accelerometerDefault = Settings.System.getInt(resolver, - Settings.System.ACCELEROMETER_ROTATION, DEFAULT_ACCELEROMETER_ROTATION); - if (mAccelerometerDefault != accelerometerDefault) { - mAccelerometerDefault = accelerometerDefault; - updateOrientationListenerLp(); - } - if (mSystemReady) { - int pointerLocation = Settings.System.getInt(resolver, - Settings.System.POINTER_LOCATION, 0); - if (mPointerLocationMode != pointerLocation) { - mPointerLocationMode = pointerLocation; - if (pointerLocation != 0) { - if (mPointerLocationView == null) { - mPointerLocationView = new PointerLocationView(mContext); - mPointerLocationView.setPrintCoords(false); - addView = mPointerLocationView; - } - } else { - removeView = mPointerLocationView; - mPointerLocationView = null; - } - } - } - // use screen off timeout setting as the timeout for the lockscreen - mLockScreenTimeout = Settings.System.getInt(resolver, - Settings.System.SCREEN_OFF_TIMEOUT, 0); - String imId = Settings.Secure.getString(resolver, - Settings.Secure.DEFAULT_INPUT_METHOD); - boolean hasSoftInput = imId != null && imId.length() > 0; - if (mHasSoftInput != hasSoftInput) { - mHasSoftInput = hasSoftInput; - updateRotation = true; - } - } - if (updateRotation) { - updateRotation(0); - } - if (addView != null) { - WindowManager.LayoutParams lp = new WindowManager.LayoutParams( - WindowManager.LayoutParams.MATCH_PARENT, - WindowManager.LayoutParams.MATCH_PARENT); - lp.type = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY; - lp.flags = - WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE| - WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE| - WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; - lp.format = PixelFormat.TRANSLUCENT; - lp.setTitle("PointerLocation"); - WindowManagerImpl wm = (WindowManagerImpl) - mContext.getSystemService(Context.WINDOW_SERVICE); - wm.addView(addView, lp); - } - if (removeView != null) { - WindowManagerImpl wm = (WindowManagerImpl) - mContext.getSystemService(Context.WINDOW_SERVICE); - wm.removeView(removeView); - } - } - - private int readRotation(int resID) { - try { - int rotation = mContext.getResources().getInteger(resID); - switch (rotation) { - case 0: - return Surface.ROTATION_0; - case 90: - return Surface.ROTATION_90; - case 180: - return Surface.ROTATION_180; - case 270: - return Surface.ROTATION_270; - } - } catch (Resources.NotFoundException e) { - // fall through - } - return -1; - } - - /** {@inheritDoc} */ - public int checkAddPermission(WindowManager.LayoutParams attrs) { - int type = attrs.type; - - if (type < WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW - || type > WindowManager.LayoutParams.LAST_SYSTEM_WINDOW) { - return WindowManagerImpl.ADD_OKAY; - } - String permission = null; - switch (type) { - case TYPE_TOAST: - // XXX right now the app process has complete control over - // this... should introduce a token to let the system - // monitor/control what they are doing. - break; - case TYPE_INPUT_METHOD: - case TYPE_WALLPAPER: - // The window manager will check these. - break; - case TYPE_PHONE: - case TYPE_PRIORITY_PHONE: - case TYPE_SYSTEM_ALERT: - case TYPE_SYSTEM_ERROR: - case TYPE_SYSTEM_OVERLAY: - permission = android.Manifest.permission.SYSTEM_ALERT_WINDOW; - break; - default: - permission = android.Manifest.permission.INTERNAL_SYSTEM_WINDOW; - } - if (permission != null) { - if (mContext.checkCallingOrSelfPermission(permission) - != PackageManager.PERMISSION_GRANTED) { - return WindowManagerImpl.ADD_PERMISSION_DENIED; - } - } - return WindowManagerImpl.ADD_OKAY; - } - - public void adjustWindowParamsLw(WindowManager.LayoutParams attrs) { - switch (attrs.type) { - case TYPE_SYSTEM_OVERLAY: - case TYPE_TOAST: - // These types of windows can't receive input events. - attrs.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE - | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; - break; - } - } - - void readLidState() { - try { - int sw = mWindowManager.getSwitchState(RawInputEvent.SW_LID); - if (sw >= 0) { - mLidOpen = sw == 0; - } - } catch (RemoteException e) { - // Ignore - } - } - - private int determineHiddenState(boolean lidOpen, - int mode, int hiddenValue, int visibleValue) { - switch (mode) { - case 1: - return lidOpen ? visibleValue : hiddenValue; - case 2: - return lidOpen ? hiddenValue : visibleValue; - } - return visibleValue; - } - - /** {@inheritDoc} */ - public void adjustConfigurationLw(Configuration config) { - readLidState(); - final boolean lidOpen = !KEYBOARD_ALWAYS_HIDDEN && mLidOpen; - mPowerManager.setKeyboardVisibility(lidOpen); - config.hardKeyboardHidden = determineHiddenState(lidOpen, - mLidKeyboardAccessibility, Configuration.HARDKEYBOARDHIDDEN_YES, - Configuration.HARDKEYBOARDHIDDEN_NO); - config.navigationHidden = determineHiddenState(lidOpen, - mLidNavigationAccessibility, Configuration.NAVIGATIONHIDDEN_YES, - Configuration.NAVIGATIONHIDDEN_NO); - config.keyboardHidden = (config.hardKeyboardHidden - == Configuration.HARDKEYBOARDHIDDEN_NO || mHasSoftInput) - ? Configuration.KEYBOARDHIDDEN_NO - : Configuration.KEYBOARDHIDDEN_YES; - } - - public boolean isCheekPressedAgainstScreen(MotionEvent ev) { - if(ev.getSize() > SLIDE_TOUCH_EVENT_SIZE_LIMIT) { - return true; - } - int size = ev.getHistorySize(); - for(int i = 0; i < size; i++) { - if(ev.getHistoricalSize(i) > SLIDE_TOUCH_EVENT_SIZE_LIMIT) { - return true; - } - } - return false; - } - - public void dispatchedPointerEventLw(MotionEvent ev, int targetX, int targetY) { - if (mPointerLocationView == null) { - return; - } - synchronized (mLock) { - if (mPointerLocationView == null) { - return; - } - ev.offsetLocation(targetX, targetY); - mPointerLocationView.addTouchEvent(ev); - ev.offsetLocation(-targetX, -targetY); - } - } - - /** {@inheritDoc} */ - public int windowTypeToLayerLw(int type) { - if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) { - return APPLICATION_LAYER; - } - switch (type) { - case TYPE_STATUS_BAR: - return STATUS_BAR_LAYER; - case TYPE_STATUS_BAR_PANEL: - return STATUS_BAR_PANEL_LAYER; - case TYPE_SYSTEM_DIALOG: - return SYSTEM_DIALOG_LAYER; - case TYPE_SEARCH_BAR: - return SEARCH_BAR_LAYER; - case TYPE_PHONE: - return PHONE_LAYER; - case TYPE_KEYGUARD: - return KEYGUARD_LAYER; - case TYPE_KEYGUARD_DIALOG: - return KEYGUARD_DIALOG_LAYER; - case TYPE_SYSTEM_ALERT: - return SYSTEM_ALERT_LAYER; - case TYPE_SYSTEM_ERROR: - return SYSTEM_ERROR_LAYER; - case TYPE_INPUT_METHOD: - return INPUT_METHOD_LAYER; - case TYPE_INPUT_METHOD_DIALOG: - return INPUT_METHOD_DIALOG_LAYER; - case TYPE_SYSTEM_OVERLAY: - return SYSTEM_OVERLAY_LAYER; - case TYPE_PRIORITY_PHONE: - return PRIORITY_PHONE_LAYER; - case TYPE_TOAST: - return TOAST_LAYER; - case TYPE_WALLPAPER: - return WALLPAPER_LAYER; - } - Log.e(TAG, "Unknown window type: " + type); - return APPLICATION_LAYER; - } - - /** {@inheritDoc} */ - public int subWindowTypeToLayerLw(int type) { - switch (type) { - case TYPE_APPLICATION_PANEL: - case TYPE_APPLICATION_ATTACHED_DIALOG: - return APPLICATION_PANEL_SUBLAYER; - case TYPE_APPLICATION_MEDIA: - return APPLICATION_MEDIA_SUBLAYER; - case TYPE_APPLICATION_MEDIA_OVERLAY: - return APPLICATION_MEDIA_OVERLAY_SUBLAYER; - case TYPE_APPLICATION_SUB_PANEL: - return APPLICATION_SUB_PANEL_SUBLAYER; - } - Log.e(TAG, "Unknown sub-window type: " + type); - return 0; - } - - public int getMaxWallpaperLayer() { - return STATUS_BAR_LAYER; - } - - public boolean doesForceHide(WindowState win, WindowManager.LayoutParams attrs) { - return attrs.type == WindowManager.LayoutParams.TYPE_KEYGUARD; - } - - public boolean canBeForceHidden(WindowState win, WindowManager.LayoutParams attrs) { - return attrs.type != WindowManager.LayoutParams.TYPE_STATUS_BAR - && attrs.type != WindowManager.LayoutParams.TYPE_WALLPAPER; - } - - /** {@inheritDoc} */ - public View addStartingWindow(IBinder appToken, String packageName, - int theme, CharSequence nonLocalizedLabel, - int labelRes, int icon) { - if (!SHOW_STARTING_ANIMATIONS) { - return null; - } - if (packageName == null) { - return null; - } - - try { - Context context = mContext; - boolean setTheme = false; - //Log.i(TAG, "addStartingWindow " + packageName + ": nonLocalizedLabel=" - // + nonLocalizedLabel + " theme=" + Integer.toHexString(theme)); - if (theme != 0 || labelRes != 0) { - try { - context = context.createPackageContext(packageName, 0); - if (theme != 0) { - context.setTheme(theme); - setTheme = true; - } - } catch (PackageManager.NameNotFoundException e) { - // Ignore - } - } - if (!setTheme) { - context.setTheme(com.android.internal.R.style.Theme); - } - - Window win = PolicyManager.makeNewWindow(context); - if (win.getWindowStyle().getBoolean( - com.android.internal.R.styleable.Window_windowDisablePreview, false)) { - return null; - } - - Resources r = context.getResources(); - win.setTitle(r.getText(labelRes, nonLocalizedLabel)); - - win.setType( - WindowManager.LayoutParams.TYPE_APPLICATION_STARTING); - // Force the window flags: this is a fake window, so it is not really - // touchable or focusable by the user. We also add in the ALT_FOCUSABLE_IM - // flag because we do know that the next window will take input - // focus, so we want to get the IME window up on top of us right away. - win.setFlags( - WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE| - WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE| - WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM, - WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE| - WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE| - WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); - - win.setLayout(WindowManager.LayoutParams.MATCH_PARENT, - WindowManager.LayoutParams.MATCH_PARENT); - - final WindowManager.LayoutParams params = win.getAttributes(); - params.token = appToken; - params.packageName = packageName; - params.windowAnimations = win.getWindowStyle().getResourceId( - com.android.internal.R.styleable.Window_windowAnimationStyle, 0); - params.setTitle("Starting " + packageName); - - WindowManagerImpl wm = (WindowManagerImpl) - context.getSystemService(Context.WINDOW_SERVICE); - View view = win.getDecorView(); - - if (win.isFloating()) { - // Whoops, there is no way to display an animation/preview - // of such a thing! After all that work... let's skip it. - // (Note that we must do this here because it is in - // getDecorView() where the theme is evaluated... maybe - // we should peek the floating attribute from the theme - // earlier.) - return null; - } - - if (localLOGV) Log.v( - TAG, "Adding starting window for " + packageName - + " / " + appToken + ": " - + (view.getParent() != null ? view : null)); - - wm.addView(view, params); - - // Only return the view if it was successfully added to the - // window manager... which we can tell by it having a parent. - return view.getParent() != null ? view : null; - } catch (WindowManagerImpl.BadTokenException e) { - // ignore - Log.w(TAG, appToken + " already running, starting window not displayed"); - } catch (RuntimeException e) { - // don't crash if something else bad happens, for example a - // failure loading resources because we are loading from an app - // on external storage that has been unmounted. - Log.w(TAG, appToken + " failed creating starting window", e); - } - - return null; - } - - /** {@inheritDoc} */ - public void removeStartingWindow(IBinder appToken, View window) { - // RuntimeException e = new RuntimeException(); - // Log.i(TAG, "remove " + appToken + " " + window, e); - - if (localLOGV) Log.v( - TAG, "Removing starting window for " + appToken + ": " + window); - - if (window != null) { - WindowManagerImpl wm = (WindowManagerImpl) mContext.getSystemService(Context.WINDOW_SERVICE); - wm.removeView(window); - } - } - - /** - * Preflight adding a window to the system. - * - * Currently enforces that three window types are singletons: - * <ul> - * <li>STATUS_BAR_TYPE</li> - * <li>KEYGUARD_TYPE</li> - * </ul> - * - * @param win The window to be added - * @param attrs Information about the window to be added - * - * @return If ok, WindowManagerImpl.ADD_OKAY. If too many singletons, WindowManagerImpl.ADD_MULTIPLE_SINGLETON - */ - public int prepareAddWindowLw(WindowState win, WindowManager.LayoutParams attrs) { - switch (attrs.type) { - case TYPE_STATUS_BAR: - mContext.enforceCallingOrSelfPermission( - android.Manifest.permission.STATUS_BAR_SERVICE, - "PhoneWindowManager"); - // TODO: Need to handle the race condition of the status bar proc - // dying and coming back before the removeWindowLw cleanup has happened. - if (mStatusBar != null) { - return WindowManagerImpl.ADD_MULTIPLE_SINGLETON; - } - mStatusBar = win; - break; - case TYPE_STATUS_BAR_PANEL: - mContext.enforceCallingOrSelfPermission( - android.Manifest.permission.STATUS_BAR_SERVICE, - "PhoneWindowManager"); - mStatusBarPanels.add(win); - break; - case TYPE_KEYGUARD: - if (mKeyguard != null) { - return WindowManagerImpl.ADD_MULTIPLE_SINGLETON; - } - mKeyguard = win; - break; - } - return WindowManagerImpl.ADD_OKAY; - } - - /** {@inheritDoc} */ - public void removeWindowLw(WindowState win) { - if (mStatusBar == win) { - mStatusBar = null; - } - else if (mKeyguard == win) { - mKeyguard = null; - } else { - mStatusBarPanels.remove(win); - } - } - - static final boolean PRINT_ANIM = false; - - /** {@inheritDoc} */ - public int selectAnimationLw(WindowState win, int transit) { - if (PRINT_ANIM) Log.i(TAG, "selectAnimation in " + win - + ": transit=" + transit); - if (transit == TRANSIT_PREVIEW_DONE) { - if (win.hasAppShownWindows()) { - if (PRINT_ANIM) Log.i(TAG, "**** STARTING EXIT"); - return com.android.internal.R.anim.app_starting_exit; - } - } - - return 0; - } - - public Animation createForceHideEnterAnimation() { - return AnimationUtils.loadAnimation(mContext, - com.android.internal.R.anim.lock_screen_behind_enter); - } - - static ITelephony getPhoneInterface() { - return ITelephony.Stub.asInterface(ServiceManager.checkService(Context.TELEPHONY_SERVICE)); - } - - static IAudioService getAudioInterface() { - return IAudioService.Stub.asInterface(ServiceManager.checkService(Context.AUDIO_SERVICE)); - } - - boolean keyguardOn() { - return keyguardIsShowingTq() || inKeyguardRestrictedKeyInputMode(); - } - - private static final int[] WINDOW_TYPES_WHERE_HOME_DOESNT_WORK = { - WindowManager.LayoutParams.TYPE_SYSTEM_ALERT, - WindowManager.LayoutParams.TYPE_SYSTEM_ERROR, - }; - - /** {@inheritDoc} */ - public boolean interceptKeyTi(WindowState win, int code, int metaKeys, boolean down, - int repeatCount, int flags) { - boolean keyguardOn = keyguardOn(); - - if (false) { - Log.d(TAG, "interceptKeyTi code=" + code + " down=" + down + " repeatCount=" - + repeatCount + " keyguardOn=" + keyguardOn + " mHomePressed=" + mHomePressed); - } - - // Clear a pending HOME longpress if the user releases Home - // TODO: This could probably be inside the next bit of logic, but that code - // turned out to be a bit fragile so I'm doing it here explicitly, for now. - if ((code == KeyEvent.KEYCODE_HOME) && !down) { - mHandler.removeCallbacks(mHomeLongPress); - } - - // If the HOME button is currently being held, then we do special - // chording with it. - if (mHomePressed) { - - // If we have released the home key, and didn't do anything else - // while it was pressed, then it is time to go home! - if (code == KeyEvent.KEYCODE_HOME) { - if (!down) { - mHomePressed = false; - - if ((flags&KeyEvent.FLAG_CANCELED) == 0) { - // If an incoming call is ringing, HOME is totally disabled. - // (The user is already on the InCallScreen at this point, - // and his ONLY options are to answer or reject the call.) - boolean incomingRinging = false; - try { - ITelephony phoneServ = getPhoneInterface(); - if (phoneServ != null) { - incomingRinging = phoneServ.isRinging(); - } else { - Log.w(TAG, "Unable to find ITelephony interface"); - } - } catch (RemoteException ex) { - Log.w(TAG, "RemoteException from getPhoneInterface()", ex); - } - - if (incomingRinging) { - Log.i(TAG, "Ignoring HOME; there's a ringing incoming call."); - } else { - launchHomeFromHotKey(); - } - } else { - Log.i(TAG, "Ignoring HOME; event canceled."); - } - } - } - - return true; - } - - // First we always handle the home key here, so applications - // can never break it, although if keyguard is on, we do let - // it handle it, because that gives us the correct 5 second - // timeout. - if (code == KeyEvent.KEYCODE_HOME) { - - // If a system window has focus, then it doesn't make sense - // right now to interact with applications. - WindowManager.LayoutParams attrs = win != null ? win.getAttrs() : null; - if (attrs != null) { - final int type = attrs.type; - if (type == WindowManager.LayoutParams.TYPE_KEYGUARD - || type == WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG) { - // the "app" is keyguard, so give it the key - return false; - } - final int typeCount = WINDOW_TYPES_WHERE_HOME_DOESNT_WORK.length; - for (int i=0; i<typeCount; i++) { - if (type == WINDOW_TYPES_WHERE_HOME_DOESNT_WORK[i]) { - // don't do anything, but also don't pass it to the app - return true; - } - } - } - - if (down && repeatCount == 0) { - if (!keyguardOn) { - mHandler.postDelayed(mHomeLongPress, ViewConfiguration.getGlobalActionKeyTimeout()); - } - mHomePressed = true; - } - return true; - } else if (code == KeyEvent.KEYCODE_MENU) { - // Hijack modified menu keys for debugging features - final int chordBug = KeyEvent.META_SHIFT_ON; - - if (down && repeatCount == 0) { - if (mEnableShiftMenuBugReports && (metaKeys & chordBug) == chordBug) { - Intent intent = new Intent(Intent.ACTION_BUG_REPORT); - mContext.sendOrderedBroadcast(intent, null); - return true; - } else if (SHOW_PROCESSES_ON_ALT_MENU && - (metaKeys & KeyEvent.META_ALT_ON) == KeyEvent.META_ALT_ON) { - Intent service = new Intent(); - service.setClassName(mContext, "com.android.server.LoadAverageService"); - ContentResolver res = mContext.getContentResolver(); - boolean shown = Settings.System.getInt( - res, Settings.System.SHOW_PROCESSES, 0) != 0; - if (!shown) { - mContext.startService(service); - } else { - mContext.stopService(service); - } - Settings.System.putInt( - res, Settings.System.SHOW_PROCESSES, shown ? 0 : 1); - return true; - } - } - } else if (code == KeyEvent.KEYCODE_SEARCH) { - if (down) { - if (repeatCount == 0) { - mSearchKeyPressed = true; - } - } else { - mSearchKeyPressed = false; - - if (mConsumeSearchKeyUp) { - // Consume the up-event - mConsumeSearchKeyUp = false; - return true; - } - } - } - - // Shortcuts are invoked through Search+key, so intercept those here - if (mSearchKeyPressed) { - if (down && repeatCount == 0 && !keyguardOn) { - Intent shortcutIntent = mShortcutManager.getIntent(code, metaKeys); - if (shortcutIntent != null) { - shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - mContext.startActivity(shortcutIntent); - - /* - * We launched an app, so the up-event of the search key - * should be consumed - */ - mConsumeSearchKeyUp = true; - return true; - } - } - } - - return false; - } - - /** - * A home key -> launch home action was detected. Take the appropriate action - * given the situation with the keyguard. - */ - void launchHomeFromHotKey() { - if (mKeyguardMediator.isShowingAndNotHidden()) { - // don't launch home if keyguard showing - } else if (!mHideLockScreen && mKeyguardMediator.isInputRestricted()) { - // when in keyguard restricted mode, must first verify unlock - // before launching home - mKeyguardMediator.verifyUnlock(new OnKeyguardExitResult() { - public void onKeyguardExitResult(boolean success) { - if (success) { - try { - ActivityManagerNative.getDefault().stopAppSwitches(); - } catch (RemoteException e) { - } - sendCloseSystemWindows(SYSTEM_DIALOG_REASON_HOME_KEY); - startDockOrHome(); - } - } - }); - } else { - // no keyguard stuff to worry about, just launch home! - try { - ActivityManagerNative.getDefault().stopAppSwitches(); - } catch (RemoteException e) { - } - sendCloseSystemWindows(SYSTEM_DIALOG_REASON_HOME_KEY); - startDockOrHome(); - } - } - - public void getContentInsetHintLw(WindowManager.LayoutParams attrs, Rect contentInset) { - final int fl = attrs.flags; - - if ((fl & - (FLAG_LAYOUT_IN_SCREEN | FLAG_FULLSCREEN | FLAG_LAYOUT_INSET_DECOR)) - == (FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR)) { - contentInset.set(mCurLeft, mCurTop, mW - mCurRight, mH - mCurBottom); - } else { - contentInset.setEmpty(); - } - } - - /** {@inheritDoc} */ - public void beginLayoutLw(int displayWidth, int displayHeight) { - mW = displayWidth; - mH = displayHeight; - mDockLeft = mContentLeft = mCurLeft = 0; - mDockTop = mContentTop = mCurTop = 0; - mDockRight = mContentRight = mCurRight = displayWidth; - mDockBottom = mContentBottom = mCurBottom = displayHeight; - mDockLayer = 0x10000000; - - // decide where the status bar goes ahead of time - if (mStatusBar != null) { - final Rect pf = mTmpParentFrame; - final Rect df = mTmpDisplayFrame; - final Rect vf = mTmpVisibleFrame; - pf.left = df.left = vf.left = 0; - pf.top = df.top = vf.top = 0; - pf.right = df.right = vf.right = displayWidth; - pf.bottom = df.bottom = vf.bottom = displayHeight; - - mStatusBar.computeFrameLw(pf, df, vf, vf); - if (mStatusBar.isVisibleLw()) { - // If the status bar is hidden, we don't want to cause - // windows behind it to scroll. - mDockTop = mContentTop = mCurTop = mStatusBar.getFrameLw().bottom; - if (DEBUG_LAYOUT) Log.v(TAG, "Status bar: mDockBottom=" - + mDockBottom + " mContentBottom=" - + mContentBottom + " mCurBottom=" + mCurBottom); - } - } - } - - void setAttachedWindowFrames(WindowState win, int fl, int sim, - WindowState attached, boolean insetDecors, Rect pf, Rect df, Rect cf, Rect vf) { - if (win.getSurfaceLayer() > mDockLayer && attached.getSurfaceLayer() < mDockLayer) { - // Here's a special case: if this attached window is a panel that is - // above the dock window, and the window it is attached to is below - // the dock window, then the frames we computed for the window it is - // attached to can not be used because the dock is effectively part - // of the underlying window and the attached window is floating on top - // of the whole thing. So, we ignore the attached window and explicitly - // compute the frames that would be appropriate without the dock. - df.left = cf.left = vf.left = mDockLeft; - df.top = cf.top = vf.top = mDockTop; - df.right = cf.right = vf.right = mDockRight; - df.bottom = cf.bottom = vf.bottom = mDockBottom; - } else { - // The effective display frame of the attached window depends on - // whether it is taking care of insetting its content. If not, - // we need to use the parent's content frame so that the entire - // window is positioned within that content. Otherwise we can use - // the display frame and let the attached window take care of - // positioning its content appropriately. - if ((sim & SOFT_INPUT_MASK_ADJUST) != SOFT_INPUT_ADJUST_RESIZE) { - cf.set(attached.getDisplayFrameLw()); - } else { - // If the window is resizing, then we want to base the content - // frame on our attached content frame to resize... however, - // things can be tricky if the attached window is NOT in resize - // mode, in which case its content frame will be larger. - // Ungh. So to deal with that, make sure the content frame - // we end up using is not covering the IM dock. - cf.set(attached.getContentFrameLw()); - if (attached.getSurfaceLayer() < mDockLayer) { - if (cf.left < mContentLeft) cf.left = mContentLeft; - if (cf.top < mContentTop) cf.top = mContentTop; - if (cf.right > mContentRight) cf.right = mContentRight; - if (cf.bottom > mContentBottom) cf.bottom = mContentBottom; - } - } - df.set(insetDecors ? attached.getDisplayFrameLw() : cf); - vf.set(attached.getVisibleFrameLw()); - } - // The LAYOUT_IN_SCREEN flag is used to determine whether the attached - // window should be positioned relative to its parent or the entire - // screen. - pf.set((fl & FLAG_LAYOUT_IN_SCREEN) == 0 - ? attached.getFrameLw() : df); - } - - /** {@inheritDoc} */ - public void layoutWindowLw(WindowState win, WindowManager.LayoutParams attrs, - WindowState attached) { - // we've already done the status bar - if (win == mStatusBar) { - return; - } - - if (false) { - if ("com.google.android.youtube".equals(attrs.packageName) - && attrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) { - Log.i(TAG, "GOTCHA!"); - } - } - - final int fl = attrs.flags; - final int sim = attrs.softInputMode; - - final Rect pf = mTmpParentFrame; - final Rect df = mTmpDisplayFrame; - final Rect cf = mTmpContentFrame; - final Rect vf = mTmpVisibleFrame; - - if (attrs.type == TYPE_INPUT_METHOD) { - pf.left = df.left = cf.left = vf.left = mDockLeft; - pf.top = df.top = cf.top = vf.top = mDockTop; - pf.right = df.right = cf.right = vf.right = mDockRight; - pf.bottom = df.bottom = cf.bottom = vf.bottom = mDockBottom; - // IM dock windows always go to the bottom of the screen. - attrs.gravity = Gravity.BOTTOM; - mDockLayer = win.getSurfaceLayer(); - } else { - if ((fl & - (FLAG_LAYOUT_IN_SCREEN | FLAG_FULLSCREEN | FLAG_LAYOUT_INSET_DECOR)) - == (FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR)) { - // This is the case for a normal activity window: we want it - // to cover all of the screen space, and it can take care of - // moving its contents to account for screen decorations that - // intrude into that space. - if (attached != null) { - // If this window is attached to another, our display - // frame is the same as the one we are attached to. - setAttachedWindowFrames(win, fl, sim, attached, true, pf, df, cf, vf); - } else { - pf.left = df.left = 0; - pf.top = df.top = 0; - pf.right = df.right = mW; - pf.bottom = df.bottom = mH; - if ((sim & SOFT_INPUT_MASK_ADJUST) != SOFT_INPUT_ADJUST_RESIZE) { - cf.left = mDockLeft; - cf.top = mDockTop; - cf.right = mDockRight; - cf.bottom = mDockBottom; - } else { - cf.left = mContentLeft; - cf.top = mContentTop; - cf.right = mContentRight; - cf.bottom = mContentBottom; - } - vf.left = mCurLeft; - vf.top = mCurTop; - vf.right = mCurRight; - vf.bottom = mCurBottom; - } - } else if ((fl & FLAG_LAYOUT_IN_SCREEN) != 0) { - // A window that has requested to fill the entire screen just - // gets everything, period. - pf.left = df.left = cf.left = 0; - pf.top = df.top = cf.top = 0; - pf.right = df.right = cf.right = mW; - pf.bottom = df.bottom = cf.bottom = mH; - vf.left = mCurLeft; - vf.top = mCurTop; - vf.right = mCurRight; - vf.bottom = mCurBottom; - } else if (attached != null) { - // A child window should be placed inside of the same visible - // frame that its parent had. - setAttachedWindowFrames(win, fl, sim, attached, false, pf, df, cf, vf); - } else { - // Otherwise, a normal window must be placed inside the content - // of all screen decorations. - pf.left = mContentLeft; - pf.top = mContentTop; - pf.right = mContentRight; - pf.bottom = mContentBottom; - if ((sim & SOFT_INPUT_MASK_ADJUST) != SOFT_INPUT_ADJUST_RESIZE) { - df.left = cf.left = mDockLeft; - df.top = cf.top = mDockTop; - df.right = cf.right = mDockRight; - df.bottom = cf.bottom = mDockBottom; - } else { - df.left = cf.left = mContentLeft; - df.top = cf.top = mContentTop; - df.right = cf.right = mContentRight; - df.bottom = cf.bottom = mContentBottom; - } - vf.left = mCurLeft; - vf.top = mCurTop; - vf.right = mCurRight; - vf.bottom = mCurBottom; - } - } - - if ((fl & FLAG_LAYOUT_NO_LIMITS) != 0) { - df.left = df.top = cf.left = cf.top = vf.left = vf.top = -10000; - df.right = df.bottom = cf.right = cf.bottom = vf.right = vf.bottom = 10000; - } - - if (DEBUG_LAYOUT) Log.v(TAG, "Compute frame " + attrs.getTitle() - + ": sim=#" + Integer.toHexString(sim) - + " pf=" + pf.toShortString() + " df=" + df.toShortString() - + " cf=" + cf.toShortString() + " vf=" + vf.toShortString()); - - if (false) { - if ("com.google.android.youtube".equals(attrs.packageName) - && attrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) { - if (true || localLOGV) Log.v(TAG, "Computing frame of " + win + - ": sim=#" + Integer.toHexString(sim) - + " pf=" + pf.toShortString() + " df=" + df.toShortString() - + " cf=" + cf.toShortString() + " vf=" + vf.toShortString()); - } - } - - win.computeFrameLw(pf, df, cf, vf); - - // Dock windows carve out the bottom of the screen, so normal windows - // can't appear underneath them. - if (attrs.type == TYPE_INPUT_METHOD && !win.getGivenInsetsPendingLw()) { - int top = win.getContentFrameLw().top; - top += win.getGivenContentInsetsLw().top; - if (mContentBottom > top) { - mContentBottom = top; - } - top = win.getVisibleFrameLw().top; - top += win.getGivenVisibleInsetsLw().top; - if (mCurBottom > top) { - mCurBottom = top; - } - if (DEBUG_LAYOUT) Log.v(TAG, "Input method: mDockBottom=" - + mDockBottom + " mContentBottom=" - + mContentBottom + " mCurBottom=" + mCurBottom); - } - } - - /** {@inheritDoc} */ - public int finishLayoutLw() { - return 0; - } - - /** {@inheritDoc} */ - public void beginAnimationLw(int displayWidth, int displayHeight) { - mTopFullscreenOpaqueWindowState = null; - mForceStatusBar = false; - - mHideLockScreen = false; - mAllowLockscreenWhenOn = false; - mDismissKeyguard = false; - } - - /** {@inheritDoc} */ - public void animatingWindowLw(WindowState win, - WindowManager.LayoutParams attrs) { - if (mTopFullscreenOpaqueWindowState == null && - win.isVisibleOrBehindKeyguardLw()) { - if ((attrs.flags & FLAG_FORCE_NOT_FULLSCREEN) != 0) { - mForceStatusBar = true; - } - if (attrs.type >= FIRST_APPLICATION_WINDOW - && attrs.type <= LAST_APPLICATION_WINDOW - && win.fillsScreenLw(mW, mH, false, false)) { - if (DEBUG_LAYOUT) Log.v(TAG, "Fullscreen window: " + win); - mTopFullscreenOpaqueWindowState = win; - if ((attrs.flags & FLAG_SHOW_WHEN_LOCKED) != 0) { - if (localLOGV) Log.v(TAG, "Setting mHideLockScreen to true by win " + win); - mHideLockScreen = true; - } - if ((attrs.flags & FLAG_DISMISS_KEYGUARD) != 0) { - if (localLOGV) Log.v(TAG, "Setting mDismissKeyguard to true by win " + win); - mDismissKeyguard = true; - } - if ((attrs.flags & FLAG_ALLOW_LOCK_WHILE_SCREEN_ON) != 0) { - mAllowLockscreenWhenOn = true; - } - } - } - } - - /** {@inheritDoc} */ - public int finishAnimationLw() { - int changes = 0; - - boolean hiding = false; - if (mStatusBar != null) { - if (localLOGV) Log.i(TAG, "force=" + mForceStatusBar - + " top=" + mTopFullscreenOpaqueWindowState); - if (mForceStatusBar) { - if (DEBUG_LAYOUT) Log.v(TAG, "Showing status bar"); - if (mStatusBar.showLw(true)) changes |= FINISH_LAYOUT_REDO_LAYOUT; - } else if (mTopFullscreenOpaqueWindowState != null) { - //Log.i(TAG, "frame: " + mTopFullscreenOpaqueWindowState.getFrameLw() - // + " shown frame: " + mTopFullscreenOpaqueWindowState.getShownFrameLw()); - //Log.i(TAG, "attr: " + mTopFullscreenOpaqueWindowState.getAttrs()); - WindowManager.LayoutParams lp = - mTopFullscreenOpaqueWindowState.getAttrs(); - boolean hideStatusBar = - (lp.flags & WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0; - if (hideStatusBar) { - if (DEBUG_LAYOUT) Log.v(TAG, "Hiding status bar"); - if (mStatusBar.hideLw(true)) changes |= FINISH_LAYOUT_REDO_LAYOUT; - hiding = true; - } else { - if (DEBUG_LAYOUT) Log.v(TAG, "Showing status bar"); - if (mStatusBar.showLw(true)) changes |= FINISH_LAYOUT_REDO_LAYOUT; - } - } - } - - if (changes != 0 && hiding) { - IStatusBarService sbs = IStatusBarService.Stub.asInterface(ServiceManager.getService("statusbar")); - if (sbs != null) { - try { - // Make sure the window shade is hidden. - sbs.collapse(); - } catch (RemoteException e) { - } - } - } - - // Hide the key guard if a visible window explicitly specifies that it wants to be displayed - // when the screen is locked - if (mKeyguard != null) { - if (localLOGV) Log.v(TAG, "finishLayoutLw::mHideKeyguard="+mHideLockScreen); - if (mDismissKeyguard && !mKeyguardMediator.isSecure()) { - if (mKeyguard.hideLw(true)) { - changes |= FINISH_LAYOUT_REDO_LAYOUT - | FINISH_LAYOUT_REDO_CONFIG - | FINISH_LAYOUT_REDO_WALLPAPER; - } - if (mKeyguardMediator.isShowing()) { - mHandler.post(new Runnable() { - public void run() { - mKeyguardMediator.keyguardDone(false, false); - } - }); - } - } else if (mHideLockScreen) { - if (mKeyguard.hideLw(true)) { - changes |= FINISH_LAYOUT_REDO_LAYOUT - | FINISH_LAYOUT_REDO_CONFIG - | FINISH_LAYOUT_REDO_WALLPAPER; - } - mKeyguardMediator.setHidden(true); - } else { - if (mKeyguard.showLw(true)) { - changes |= FINISH_LAYOUT_REDO_LAYOUT - | FINISH_LAYOUT_REDO_CONFIG - | FINISH_LAYOUT_REDO_WALLPAPER; - } - mKeyguardMediator.setHidden(false); - } - } - - // update since mAllowLockscreenWhenOn might have changed - updateLockScreenTimeout(); - return changes; - } - - public boolean allowAppAnimationsLw() { - if (mKeyguard != null && mKeyguard.isVisibleLw()) { - // If keyguard is currently visible, no reason to animate - // behind it. - return false; - } - if (mStatusBar != null && mStatusBar.isVisibleLw()) { - Rect rect = new Rect(mStatusBar.getShownFrameLw()); - for (int i=mStatusBarPanels.size()-1; i>=0; i--) { - WindowState w = mStatusBarPanels.get(i); - if (w.isVisibleLw()) { - rect.union(w.getShownFrameLw()); - } - } - final int insetw = mW/10; - final int inseth = mH/10; - if (rect.contains(insetw, inseth, mW-insetw, mH-inseth)) { - // All of the status bar windows put together cover the - // screen, so the app can't be seen. (Note this test doesn't - // work if the rects of these windows are at off offsets or - // sizes, causing gaps in the rect union we have computed.) - return false; - } - } - return true; - } - - /** {@inheritDoc} */ - public boolean preprocessInputEventTq(RawInputEvent event) { - switch (event.type) { - case RawInputEvent.EV_SW: - if (event.keycode == RawInputEvent.SW_LID) { - // lid changed state - mLidOpen = event.value == 0; - boolean awakeNow = mKeyguardMediator.doLidChangeTq(mLidOpen); - updateRotation(Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE); - if (awakeNow) { - // If the lid opening and we don't have to keep the - // keyguard up, then we can turn on the screen - // immediately. - mKeyguardMediator.pokeWakelock(); - } else if (keyguardIsShowingTq()) { - if (mLidOpen) { - // If we are opening the lid and not hiding the - // keyguard, then we need to have it turn on the - // screen once it is shown. - mKeyguardMediator.onWakeKeyWhenKeyguardShowingTq( - KeyEvent.KEYCODE_POWER); - } - } else { - // Light up the keyboard if we are sliding up. - if (mLidOpen) { - mPowerManager.userActivity(SystemClock.uptimeMillis(), false, - LocalPowerManager.BUTTON_EVENT); - } else { - mPowerManager.userActivity(SystemClock.uptimeMillis(), false, - LocalPowerManager.OTHER_EVENT); - } - } - } - } - return false; - } - - public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) { - // lid changed state - mLidOpen = lidOpen; - boolean awakeNow = mKeyguardMediator.doLidChangeTq(mLidOpen); - updateRotation(Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE); - if (awakeNow) { - // If the lid opening and we don't have to keep the - // keyguard up, then we can turn on the screen - // immediately. - mKeyguardMediator.pokeWakelock(); - } else if (keyguardIsShowingTq()) { - if (mLidOpen) { - // If we are opening the lid and not hiding the - // keyguard, then we need to have it turn on the - // screen once it is shown. - mKeyguardMediator.onWakeKeyWhenKeyguardShowingTq( - KeyEvent.KEYCODE_POWER); - } - } else { - // Light up the keyboard if we are sliding up. - if (mLidOpen) { - mPowerManager.userActivity(SystemClock.uptimeMillis(), false, - LocalPowerManager.BUTTON_EVENT); - } else { - mPowerManager.userActivity(SystemClock.uptimeMillis(), false, - LocalPowerManager.OTHER_EVENT); - } - } - } - - - /** {@inheritDoc} */ - public boolean isAppSwitchKeyTqTiLwLi(int keycode) { - return keycode == KeyEvent.KEYCODE_HOME - || keycode == KeyEvent.KEYCODE_ENDCALL; - } - - /** {@inheritDoc} */ - public boolean isMovementKeyTi(int keycode) { - switch (keycode) { - case KeyEvent.KEYCODE_DPAD_UP: - case KeyEvent.KEYCODE_DPAD_DOWN: - case KeyEvent.KEYCODE_DPAD_LEFT: - case KeyEvent.KEYCODE_DPAD_RIGHT: - return true; - } - return false; - } - - - /** - * @return Whether a telephone call is in progress right now. - */ - boolean isInCall() { - final ITelephony phone = getPhoneInterface(); - if (phone == null) { - Log.w(TAG, "couldn't get ITelephony reference"); - return false; - } - try { - return phone.isOffhook(); - } catch (RemoteException e) { - Log.w(TAG, "ITelephony.isOffhhook threw RemoteException " + e); - return false; - } - } - - /** - * @return Whether music is being played right now. - */ - boolean isMusicActive() { - final AudioManager am = (AudioManager)mContext.getSystemService(Context.AUDIO_SERVICE); - if (am == null) { - Log.w(TAG, "isMusicActive: couldn't get AudioManager reference"); - return false; - } - return am.isMusicActive(); - } - - /** - * Tell the audio service to adjust the volume appropriate to the event. - * @param keycode - */ - void handleVolumeKey(int stream, int keycode) { - final IAudioService audio = getAudioInterface(); - if (audio == null) { - Log.w(TAG, "handleVolumeKey: couldn't get IAudioService reference"); - return; - } - try { - // since audio is playing, we shouldn't have to hold a wake lock - // during the call, but we do it as a precaution for the rare possibility - // that the music stops right before we call this - mBroadcastWakeLock.acquire(); - audio.adjustStreamVolume(stream, - keycode == KeyEvent.KEYCODE_VOLUME_UP - ? AudioManager.ADJUST_RAISE - : AudioManager.ADJUST_LOWER, - 0); - } catch (RemoteException e) { - Log.w(TAG, "IAudioService.adjustStreamVolume() threw RemoteException " + e); - } finally { - mBroadcastWakeLock.release(); - } - } - - static boolean isMediaKey(int code) { - if (code == KeyEvent.KEYCODE_HEADSETHOOK || - code == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE || - code == KeyEvent.KEYCODE_MEDIA_STOP || - code == KeyEvent.KEYCODE_MEDIA_NEXT || - code == KeyEvent.KEYCODE_MEDIA_PREVIOUS || - code == KeyEvent.KEYCODE_MEDIA_REWIND || - code == KeyEvent.KEYCODE_MEDIA_FAST_FORWARD) { - return true; - } - return false; - } - - /** {@inheritDoc} */ - public int interceptKeyTq(RawInputEvent event, boolean screenIsOn) { - int result = ACTION_PASS_TO_USER; - final boolean isWakeKey = isWakeKeyTq(event); - // If screen is off then we treat the case where the keyguard is open but hidden - // the same as if it were open and in front. - // This will prevent any keys other than the power button from waking the screen - // when the keyguard is hidden by another activity. - final boolean keyguardActive = (screenIsOn ? - mKeyguardMediator.isShowingAndNotHidden() : - mKeyguardMediator.isShowing()); - - if (false) { - Log.d(TAG, "interceptKeyTq event=" + event + " keycode=" + event.keycode - + " screenIsOn=" + screenIsOn + " keyguardActive=" + keyguardActive); - } - - if (keyguardActive) { - if (screenIsOn) { - // when the screen is on, always give the event to the keyguard - result |= ACTION_PASS_TO_USER; - } else { - // otherwise, don't pass it to the user - result &= ~ACTION_PASS_TO_USER; - - final boolean isKeyDown = - (event.type == RawInputEvent.EV_KEY) && (event.value != 0); - if (isWakeKey && isKeyDown) { - - // tell the mediator about a wake key, it may decide to - // turn on the screen depending on whether the key is - // appropriate. - if (!mKeyguardMediator.onWakeKeyWhenKeyguardShowingTq(event.keycode) - && (event.keycode == KeyEvent.KEYCODE_VOLUME_DOWN - || event.keycode == KeyEvent.KEYCODE_VOLUME_UP)) { - // when keyguard is showing and screen off, we need - // to handle the volume key for calls and music here - if (isInCall()) { - handleVolumeKey(AudioManager.STREAM_VOICE_CALL, event.keycode); - } else if (isMusicActive()) { - handleVolumeKey(AudioManager.STREAM_MUSIC, event.keycode); - } - } - } - } - } else if (!screenIsOn) { - // If we are in-call with screen off and keyguard is not showing, - // then handle the volume key ourselves. - // This is necessary because the phone app will disable the keyguard - // when the proximity sensor is in use. - if (isInCall() && event.type == RawInputEvent.EV_KEY && - (event.keycode == KeyEvent.KEYCODE_VOLUME_DOWN - || event.keycode == KeyEvent.KEYCODE_VOLUME_UP)) { - result &= ~ACTION_PASS_TO_USER; - handleVolumeKey(AudioManager.STREAM_VOICE_CALL, event.keycode); - } - if (isWakeKey) { - // a wake key has a sole purpose of waking the device; don't pass - // it to the user - result |= ACTION_POKE_USER_ACTIVITY; - result &= ~ACTION_PASS_TO_USER; - } - } - - int type = event.type; - int code = event.keycode; - boolean down = event.value != 0; - - if (type == RawInputEvent.EV_KEY) { - if (code == KeyEvent.KEYCODE_ENDCALL - || code == KeyEvent.KEYCODE_POWER) { - if (down) { - boolean handled = false; - boolean hungUp = false; - // key repeats are generated by the window manager, and we don't see them - // here, so unless the driver is doing something it shouldn't be, we know - // this is the real press event. - ITelephony phoneServ = getPhoneInterface(); - if (phoneServ != null) { - try { - if (code == KeyEvent.KEYCODE_ENDCALL) { - handled = hungUp = phoneServ.endCall(); - } else if (code == KeyEvent.KEYCODE_POWER) { - if (phoneServ.isRinging()) { - // Pressing Power while there's a ringing incoming - // call should silence the ringer. - phoneServ.silenceRinger(); - handled = true; - } else if (phoneServ.isOffhook() && - ((mIncallPowerBehavior - & Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP) - != 0)) { - // Otherwise, if "Power button ends call" is enabled, - // the Power button will hang up any current active call. - handled = hungUp = phoneServ.endCall(); - } - } - } catch (RemoteException ex) { - Log.w(TAG, "ITelephony threw RemoteException" + ex); - } - } else { - Log.w(TAG, "!!! Unable to find ITelephony interface !!!"); - } - - if (!screenIsOn - || (handled && code != KeyEvent.KEYCODE_POWER) - || (handled && hungUp && code == KeyEvent.KEYCODE_POWER)) { - mShouldTurnOffOnKeyUp = false; - } else { - // only try to turn off the screen if we didn't already hang up - mShouldTurnOffOnKeyUp = true; - mHandler.postDelayed(mPowerLongPress, - ViewConfiguration.getGlobalActionKeyTimeout()); - result &= ~ACTION_PASS_TO_USER; - } - } else { - mHandler.removeCallbacks(mPowerLongPress); - if (mShouldTurnOffOnKeyUp) { - mShouldTurnOffOnKeyUp = false; - boolean gohome, sleeps; - if (code == KeyEvent.KEYCODE_ENDCALL) { - gohome = (mEndcallBehavior - & Settings.System.END_BUTTON_BEHAVIOR_HOME) != 0; - sleeps = (mEndcallBehavior - & Settings.System.END_BUTTON_BEHAVIOR_SLEEP) != 0; - } else { - gohome = false; - sleeps = true; - } - if (keyguardActive - || (sleeps && !gohome) - || (gohome && !goHome() && sleeps)) { - // they must already be on the keyguad or home screen, - // go to sleep instead - Log.d(TAG, "I'm tired mEndcallBehavior=0x" - + Integer.toHexString(mEndcallBehavior)); - result &= ~ACTION_POKE_USER_ACTIVITY; - result |= ACTION_GO_TO_SLEEP; - } - result &= ~ACTION_PASS_TO_USER; - } - } - } else if (isMediaKey(code)) { - // This key needs to be handled even if the screen is off. - // If others need to be handled while it's off, this is a reasonable - // pattern to follow. - if ((result & ACTION_PASS_TO_USER) == 0) { - // Only do this if we would otherwise not pass it to the user. In that - // case, the PhoneWindow class will do the same thing, except it will - // only do it if the showing app doesn't process the key on its own. - KeyEvent keyEvent = new KeyEvent(event.when, event.when, - down ? KeyEvent.ACTION_DOWN : KeyEvent.ACTION_UP, - code, 0); - mBroadcastWakeLock.acquire(); - mHandler.post(new PassHeadsetKey(keyEvent)); - } - } else if (code == KeyEvent.KEYCODE_CALL) { - // If an incoming call is ringing, answer it! - // (We handle this key here, rather than in the InCallScreen, to make - // sure we'll respond to the key even if the InCallScreen hasn't come to - // the foreground yet.) - - // We answer the call on the DOWN event, to agree with - // the "fallback" behavior in the InCallScreen. - if (down) { - try { - ITelephony phoneServ = getPhoneInterface(); - if (phoneServ != null) { - if (phoneServ.isRinging()) { - Log.i(TAG, "interceptKeyTq:" - + " CALL key-down while ringing: Answer the call!"); - phoneServ.answerRingingCall(); - - // And *don't* pass this key thru to the current activity - // (which is presumably the InCallScreen.) - result &= ~ACTION_PASS_TO_USER; - } - } else { - Log.w(TAG, "CALL button: Unable to find ITelephony interface"); - } - } catch (RemoteException ex) { - Log.w(TAG, "CALL button: RemoteException from getPhoneInterface()", ex); - } - } - } else if ((code == KeyEvent.KEYCODE_VOLUME_UP) - || (code == KeyEvent.KEYCODE_VOLUME_DOWN)) { - // If an incoming call is ringing, either VOLUME key means - // "silence ringer". We handle these keys here, rather than - // in the InCallScreen, to make sure we'll respond to them - // even if the InCallScreen hasn't come to the foreground yet. - - // Look for the DOWN event here, to agree with the "fallback" - // behavior in the InCallScreen. - if (down) { - try { - ITelephony phoneServ = getPhoneInterface(); - if (phoneServ != null) { - if (phoneServ.isRinging()) { - Log.i(TAG, "interceptKeyTq:" - + " VOLUME key-down while ringing: Silence ringer!"); - // Silence the ringer. (It's safe to call this - // even if the ringer has already been silenced.) - phoneServ.silenceRinger(); - - // And *don't* pass this key thru to the current activity - // (which is probably the InCallScreen.) - result &= ~ACTION_PASS_TO_USER; - } - } else { - Log.w(TAG, "VOLUME button: Unable to find ITelephony interface"); - } - } catch (RemoteException ex) { - Log.w(TAG, "VOLUME button: RemoteException from getPhoneInterface()", ex); - } - } - } - } - - return result; - } - - class PassHeadsetKey implements Runnable { - KeyEvent mKeyEvent; - - PassHeadsetKey(KeyEvent keyEvent) { - mKeyEvent = keyEvent; - } - - public void run() { - if (ActivityManagerNative.isSystemReady()) { - Intent intent = new Intent(Intent.ACTION_MEDIA_BUTTON, null); - intent.putExtra(Intent.EXTRA_KEY_EVENT, mKeyEvent); - mContext.sendOrderedBroadcast(intent, null, mBroadcastDone, - mHandler, Activity.RESULT_OK, null, null); - } - } - } - - BroadcastReceiver mBroadcastDone = new BroadcastReceiver() { - public void onReceive(Context context, Intent intent) { - mBroadcastWakeLock.release(); - } - }; - - BroadcastReceiver mDockReceiver = new BroadcastReceiver() { - public void onReceive(Context context, Intent intent) { - if (Intent.ACTION_DOCK_EVENT.equals(intent.getAction())) { - mDockMode = intent.getIntExtra(Intent.EXTRA_DOCK_STATE, - Intent.EXTRA_DOCK_STATE_UNDOCKED); - } else { - try { - IUiModeManager uiModeService = IUiModeManager.Stub.asInterface( - ServiceManager.getService(Context.UI_MODE_SERVICE)); - mUiMode = uiModeService.getCurrentModeType(); - } catch (RemoteException e) { - } - } - updateRotation(Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE); - updateOrientationListenerLp(); - } - }; - - /** {@inheritDoc} */ - public boolean isWakeRelMovementTq(int device, int classes, - RawInputEvent event) { - // if it's tagged with one of the wake bits, it wakes up the device - return ((event.flags & (FLAG_WAKE | FLAG_WAKE_DROPPED)) != 0); - } - - /** {@inheritDoc} */ - public boolean isWakeAbsMovementTq(int device, int classes, - RawInputEvent event) { - // if it's tagged with one of the wake bits, it wakes up the device - return ((event.flags & (FLAG_WAKE | FLAG_WAKE_DROPPED)) != 0); - } - - /** - * Given the current state of the world, should this key wake up the device? - */ - protected boolean isWakeKeyTq(RawInputEvent event) { - // There are not key maps for trackball devices, but we'd still - // like to have pressing it wake the device up, so force it here. - int keycode = event.keycode; - int flags = event.flags; - if (keycode == RawInputEvent.BTN_MOUSE) { - flags |= WindowManagerPolicy.FLAG_WAKE; - } - return (flags - & (WindowManagerPolicy.FLAG_WAKE | WindowManagerPolicy.FLAG_WAKE_DROPPED)) != 0; - } - - /** {@inheritDoc} */ - public void screenTurnedOff(int why) { - EventLog.writeEvent(70000, 0); - mKeyguardMediator.onScreenTurnedOff(why); - synchronized (mLock) { - mScreenOn = false; - updateOrientationListenerLp(); - updateLockScreenTimeout(); - } - } - - /** {@inheritDoc} */ - public void screenTurnedOn() { - EventLog.writeEvent(70000, 1); - mKeyguardMediator.onScreenTurnedOn(); - synchronized (mLock) { - mScreenOn = true; - updateOrientationListenerLp(); - updateLockScreenTimeout(); - } - } - - /** {@inheritDoc} */ - public boolean isScreenOn() { - return mScreenOn; - } - - /** {@inheritDoc} */ - public void enableKeyguard(boolean enabled) { - mKeyguardMediator.setKeyguardEnabled(enabled); - } - - /** {@inheritDoc} */ - public void exitKeyguardSecurely(OnKeyguardExitResult callback) { - mKeyguardMediator.verifyUnlock(callback); - } - - private boolean keyguardIsShowingTq() { - return mKeyguardMediator.isShowingAndNotHidden(); - } - - /** {@inheritDoc} */ - public boolean inKeyguardRestrictedKeyInputMode() { - return mKeyguardMediator.isInputRestricted(); - } - - void sendCloseSystemWindows() { - sendCloseSystemWindows(mContext, null); - } - - void sendCloseSystemWindows(String reason) { - sendCloseSystemWindows(mContext, reason); - } - - static void sendCloseSystemWindows(Context context, String reason) { - if (ActivityManagerNative.isSystemReady()) { - try { - ActivityManagerNative.getDefault().closeSystemDialogs(reason); - } catch (RemoteException e) { - } - } - } - - public int rotationForOrientationLw(int orientation, int lastRotation, - boolean displayEnabled) { - - if (mPortraitRotation < 0) { - // Initialize the rotation angles for each orientation once. - Display d = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE)) - .getDefaultDisplay(); - if (d.getWidth() > d.getHeight()) { - mPortraitRotation = Surface.ROTATION_90; - mLandscapeRotation = Surface.ROTATION_0; - } else { - mPortraitRotation = Surface.ROTATION_0; - mLandscapeRotation = Surface.ROTATION_90; - } - } - - synchronized (mLock) { - switch (orientation) { - case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE: - //always return landscape if orientation set to landscape - return mLandscapeRotation; - case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT: - //always return portrait if orientation set to portrait - return mPortraitRotation; - } - // case for nosensor meaning ignore sensor and consider only lid - // or orientation sensor disabled - //or case.unspecified - if (mLidOpen) { - return mLidOpenRotation; - } else if (mDockMode == Intent.EXTRA_DOCK_STATE_CAR && mCarDockRotation >= 0) { - return mCarDockRotation; - } else if (mDockMode == Intent.EXTRA_DOCK_STATE_DESK && mDeskDockRotation >= 0) { - return mDeskDockRotation; - } else { - if (useSensorForOrientationLp(orientation)) { - // If the user has enabled auto rotation by default, do it. - int curRotation = mOrientationListener.getCurrentRotation(); - return curRotation >= 0 ? curRotation : lastRotation; - } - return Surface.ROTATION_0; - } - } - } - - public boolean detectSafeMode() { - try { - int menuState = mWindowManager.getKeycodeState(KeyEvent.KEYCODE_MENU); - int sState = mWindowManager.getKeycodeState(KeyEvent.KEYCODE_S); - int dpadState = mWindowManager.getDPadKeycodeState(KeyEvent.KEYCODE_DPAD_CENTER); - int trackballState = mWindowManager.getTrackballScancodeState(RawInputEvent.BTN_MOUSE); - mSafeMode = menuState > 0 || sState > 0 || dpadState > 0 || trackballState > 0; - performHapticFeedbackLw(null, mSafeMode - ? HapticFeedbackConstants.SAFE_MODE_ENABLED - : HapticFeedbackConstants.SAFE_MODE_DISABLED, true); - if (mSafeMode) { - Log.i(TAG, "SAFE MODE ENABLED (menu=" + menuState + " s=" + sState - + " dpad=" + dpadState + " trackball=" + trackballState + ")"); - } else { - Log.i(TAG, "SAFE MODE not enabled"); - } - return mSafeMode; - } catch (RemoteException e) { - // Doom! (it's also local) - throw new RuntimeException("window manager dead"); - } - } - - static long[] getLongIntArray(Resources r, int resid) { - int[] ar = r.getIntArray(resid); - if (ar == null) { - return null; - } - long[] out = new long[ar.length]; - for (int i=0; i<ar.length; i++) { - out[i] = ar[i]; - } - return out; - } - - /** {@inheritDoc} */ - public void systemReady() { - // tell the keyguard - mKeyguardMediator.onSystemReady(); - android.os.SystemProperties.set("dev.bootcomplete", "1"); - synchronized (mLock) { - updateOrientationListenerLp(); - mSystemReady = true; - mHandler.post(new Runnable() { - public void run() { - updateSettings(); - } - }); - } - } - - /** {@inheritDoc} */ - public void userActivity() { - synchronized (mScreenLockTimeout) { - if (mLockScreenTimerActive) { - // reset the timer - mHandler.removeCallbacks(mScreenLockTimeout); - mHandler.postDelayed(mScreenLockTimeout, mLockScreenTimeout); - } - } - } - - Runnable mScreenLockTimeout = new Runnable() { - public void run() { - synchronized (this) { - if (localLOGV) Log.v(TAG, "mScreenLockTimeout activating keyguard"); - mKeyguardMediator.doKeyguardTimeout(); - mLockScreenTimerActive = false; - } - } - }; - - private void updateLockScreenTimeout() { - synchronized (mScreenLockTimeout) { - boolean enable = (mAllowLockscreenWhenOn && mScreenOn && mKeyguardMediator.isSecure()); - if (mLockScreenTimerActive != enable) { - if (enable) { - if (localLOGV) Log.v(TAG, "setting lockscreen timer"); - mHandler.postDelayed(mScreenLockTimeout, mLockScreenTimeout); - } else { - if (localLOGV) Log.v(TAG, "clearing lockscreen timer"); - mHandler.removeCallbacks(mScreenLockTimeout); - } - mLockScreenTimerActive = enable; - } - } - } - - /** {@inheritDoc} */ - public void enableScreenAfterBoot() { - readLidState(); - updateRotation(Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE); - } - - void updateRotation(int animFlags) { - mPowerManager.setKeyboardVisibility(mLidOpen); - int rotation = Surface.ROTATION_0; - if (mLidOpen) { - rotation = mLidOpenRotation; - } else if (mDockMode == Intent.EXTRA_DOCK_STATE_CAR && mCarDockRotation >= 0) { - rotation = mCarDockRotation; - } else if (mDockMode == Intent.EXTRA_DOCK_STATE_DESK && mDeskDockRotation >= 0) { - rotation = mDeskDockRotation; - } - //if lid is closed orientation will be portrait - try { - //set orientation on WindowManager - mWindowManager.setRotation(rotation, true, - mFancyRotationAnimation | animFlags); - } catch (RemoteException e) { - // Ignore - } - } - - /** - * Return an Intent to launch the currently active dock as home. Returns - * null if the standard home should be launched. - * @return - */ - Intent createHomeDockIntent() { - Intent intent; - - // What home does is based on the mode, not the dock state. That - // is, when in car mode you should be taken to car home regardless - // of whether we are actually in a car dock. - if (mUiMode == Configuration.UI_MODE_TYPE_CAR) { - intent = mCarDockIntent; - } else if (mUiMode == Configuration.UI_MODE_TYPE_DESK) { - intent = mDeskDockIntent; - } else { - return null; - } - - ActivityInfo ai = intent.resolveActivityInfo( - mContext.getPackageManager(), PackageManager.GET_META_DATA); - if (ai == null) { - return null; - } - - if (ai.metaData != null && ai.metaData.getBoolean(Intent.METADATA_DOCK_HOME)) { - intent = new Intent(intent); - intent.setClassName(ai.packageName, ai.name); - return intent; - } - - return null; - } - - void startDockOrHome() { - Intent dock = createHomeDockIntent(); - if (dock != null) { - try { - mContext.startActivity(dock); - return; - } catch (ActivityNotFoundException e) { - } - } - mContext.startActivity(mHomeIntent); - } - - /** - * goes to the home screen - * @return whether it did anything - */ - boolean goHome() { - if (false) { - // This code always brings home to the front. - try { - ActivityManagerNative.getDefault().stopAppSwitches(); - } catch (RemoteException e) { - } - sendCloseSystemWindows(); - startDockOrHome(); - } else { - // This code brings home to the front or, if it is already - // at the front, puts the device to sleep. - try { - if (SystemProperties.getInt("persist.sys.uts-test-mode", 0) == 1) { - /// Roll back EndcallBehavior as the cupcake design to pass P1 lab entry. - Log.d(TAG, "UTS-TEST-MODE"); - } else { - ActivityManagerNative.getDefault().stopAppSwitches(); - sendCloseSystemWindows(); - Intent dock = createHomeDockIntent(); - if (dock != null) { - int result = ActivityManagerNative.getDefault() - .startActivity(null, dock, - dock.resolveTypeIfNeeded(mContext.getContentResolver()), - null, 0, null, null, 0, true /* onlyIfNeeded*/, false); - if (result == IActivityManager.START_RETURN_INTENT_TO_CALLER) { - return false; - } - } - } - int result = ActivityManagerNative.getDefault() - .startActivity(null, mHomeIntent, - mHomeIntent.resolveTypeIfNeeded(mContext.getContentResolver()), - null, 0, null, null, 0, true /* onlyIfNeeded*/, false); - if (result == IActivityManager.START_RETURN_INTENT_TO_CALLER) { - return false; - } - } catch (RemoteException ex) { - // bummer, the activity manager, which is in this process, is dead - } - } - return true; - } - - public void setCurrentOrientationLw(int newOrientation) { - synchronized (mLock) { - if (newOrientation != mCurrentAppOrientation) { - mCurrentAppOrientation = newOrientation; - updateOrientationListenerLp(); - } - } - } - - public boolean performHapticFeedbackLw(WindowState win, int effectId, boolean always) { - final boolean hapticsDisabled = Settings.System.getInt(mContext.getContentResolver(), - Settings.System.HAPTIC_FEEDBACK_ENABLED, 0) == 0; - if (!always && (hapticsDisabled || mKeyguardMediator.isShowingAndNotHidden())) { - return false; - } - long[] pattern = null; - switch (effectId) { - case HapticFeedbackConstants.LONG_PRESS: - pattern = mLongPressVibePattern; - break; - case HapticFeedbackConstants.VIRTUAL_KEY: - pattern = mVirtualKeyVibePattern; - break; - case HapticFeedbackConstants.KEYBOARD_TAP: - pattern = mKeyboardTapVibePattern; - break; - case HapticFeedbackConstants.SAFE_MODE_DISABLED: - pattern = mSafeModeDisabledVibePattern; - break; - case HapticFeedbackConstants.SAFE_MODE_ENABLED: - pattern = mSafeModeEnabledVibePattern; - break; - default: - return false; - } - if (pattern.length == 1) { - // One-shot vibration - mVibrator.vibrate(pattern[0]); - } else { - // Pattern vibration - mVibrator.vibrate(pattern, -1); - } - return true; - } - - public void keyFeedbackFromInput(KeyEvent event) { - if (event.getAction() == KeyEvent.ACTION_DOWN - && (event.getFlags()&KeyEvent.FLAG_VIRTUAL_HARD_KEY) != 0) { - performHapticFeedbackLw(null, HapticFeedbackConstants.VIRTUAL_KEY, false); - } - } - - public void screenOnStoppedLw() { - if (!mKeyguardMediator.isShowingAndNotHidden() && mPowerManager.isScreenOn()) { - long curTime = SystemClock.uptimeMillis(); - mPowerManager.userActivity(curTime, false, LocalPowerManager.OTHER_EVENT); - } - } - - public boolean allowKeyRepeat() { - // disable key repeat when screen is off - return mScreenOn; - } -} diff --git a/policy/com/android/internal/policy/impl/Policy.java b/policy/com/android/internal/policy/impl/Policy.java deleted file mode 100644 index 17f3e91..0000000 --- a/policy/com/android/internal/policy/impl/Policy.java +++ /dev/null @@ -1,69 +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; - -import android.content.Context; -import android.util.Log; - -import com.android.internal.policy.IPolicy; -import com.android.internal.policy.impl.PhoneLayoutInflater; -import com.android.internal.policy.impl.PhoneWindow; -import com.android.internal.policy.impl.PhoneWindowManager; - -/** - * {@hide} - */ - -// Simple implementation of the policy interface that spawns the right -// set of objects -public class Policy implements IPolicy { - private static final String TAG = "PhonePolicy"; - - private static final String[] preload_classes = { - "com.android.internal.policy.impl.PhoneLayoutInflater", - "com.android.internal.policy.impl.PhoneWindow", - "com.android.internal.policy.impl.PhoneWindow$1", - "com.android.internal.policy.impl.PhoneWindow$ContextMenuCallback", - "com.android.internal.policy.impl.PhoneWindow$DecorView", - "com.android.internal.policy.impl.PhoneWindow$PanelFeatureState", - "com.android.internal.policy.impl.PhoneWindow$PanelFeatureState$SavedState", - }; - - static { - // For performance reasons, preload some policy specific classes when - // the policy gets loaded. - for (String s : preload_classes) { - try { - Class.forName(s); - } catch (ClassNotFoundException ex) { - Log.e(TAG, "Could not preload class for phone policy: " + s); - } - } - } - - public PhoneWindow makeNewWindow(Context context) { - return new PhoneWindow(context); - } - - public PhoneLayoutInflater makeNewLayoutInflater(Context context) { - return new PhoneLayoutInflater(context); - } - - public PhoneWindowManager makeNewWindowManager() { - return new PhoneWindowManager(); - } -} diff --git a/policy/com/android/internal/policy/impl/PowerDialog.java b/policy/com/android/internal/policy/impl/PowerDialog.java deleted file mode 100644 index de35bd7..0000000 --- a/policy/com/android/internal/policy/impl/PowerDialog.java +++ /dev/null @@ -1,182 +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; - -import com.android.internal.R; - -import android.app.Dialog; -import android.app.StatusBarManager; -import android.content.Context; -import android.os.Bundle; -import android.os.RemoteException; -import android.os.LocalPowerManager; -import android.os.ServiceManager; -import android.os.SystemClock; - -import com.android.internal.app.ShutdownThread; -import com.android.internal.telephony.ITelephony; -import android.view.KeyEvent; -import android.util.Log; -import android.view.View; -import android.view.WindowManager; -import android.view.View.OnClickListener; -import android.view.View.OnKeyListener; -import android.widget.Button; - -/** - * @deprecated use {@link GlobalActions} instead. - */ -public class PowerDialog extends Dialog implements OnClickListener, - OnKeyListener { - private static final String TAG = "PowerDialog"; - - static private StatusBarManager sStatusBar; - private Button mKeyguard; - private Button mPower; - private Button mRadioPower; - private Button mSilent; - - private LocalPowerManager mPowerManager; - - public PowerDialog(Context context, LocalPowerManager powerManager) { - super(context); - mPowerManager = powerManager; - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - Context context = getContext(); - - if (sStatusBar == null) { - sStatusBar = (StatusBarManager)context.getSystemService(Context.STATUS_BAR_SERVICE); - } - - setContentView(com.android.internal.R.layout.power_dialog); - - getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG); - if (!getContext().getResources().getBoolean( - com.android.internal.R.bool.config_sf_slowBlur)) { - getWindow().setFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND, - WindowManager.LayoutParams.FLAG_BLUR_BEHIND); - } - getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM, - WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); - - setTitle(context.getText(R.string.power_dialog)); - - mKeyguard = (Button) findViewById(R.id.keyguard); - mPower = (Button) findViewById(R.id.off); - mRadioPower = (Button) findViewById(R.id.radio_power); - mSilent = (Button) findViewById(R.id.silent); - - if (mKeyguard != null) { - mKeyguard.setOnKeyListener(this); - mKeyguard.setOnClickListener(this); - } - if (mPower != null) { - mPower.setOnClickListener(this); - } - if (mRadioPower != null) { - mRadioPower.setOnClickListener(this); - } - if (mSilent != null) { - mSilent.setOnClickListener(this); - // XXX: HACK for now hide the silent until we get mute support - mSilent.setVisibility(View.GONE); - } - - CharSequence text; - - // set the keyguard button's text - text = context.getText(R.string.screen_lock); - mKeyguard.setText(text); - mKeyguard.requestFocus(); - - try { - ITelephony phone = ITelephony.Stub.asInterface(ServiceManager.checkService("phone")); - if (phone != null) { - text = phone.isRadioOn() ? context - .getText(R.string.turn_off_radio) : context - .getText(R.string.turn_on_radio); - } - } catch (RemoteException ex) { - // ignore it - } - - mRadioPower.setText(text); - } - - public void onClick(View v) { - this.dismiss(); - if (v == mPower) { - // shutdown by making sure radio and power are handled accordingly. - ShutdownThread.shutdown(getContext(), true); - } else if (v == mRadioPower) { - try { - ITelephony phone = ITelephony.Stub.asInterface(ServiceManager.checkService("phone")); - if (phone != null) { - phone.toggleRadioOnOff(); - } - } catch (RemoteException ex) { - // ignore it - } - } else if (v == mSilent) { - // do something - } else if (v == mKeyguard) { - if (v.isInTouchMode()) { - // only in touch mode for the reasons explained in onKey. - this.dismiss(); - mPowerManager.goToSleep(SystemClock.uptimeMillis() + 1); - } - } - } - - public boolean onKey(View v, int keyCode, KeyEvent event) { - // The activate keyguard button needs to put the device to sleep on the - // key up event. If we try to put it to sleep on the click or down - // action - // the the up action will cause the device to wake back up. - - // Log.i(TAG, "keyCode: " + keyCode + " action: " + event.getAction()); - if (keyCode != KeyEvent.KEYCODE_DPAD_CENTER - || event.getAction() != KeyEvent.ACTION_UP) { - // Log.i(TAG, "getting out of dodge..."); - return false; - } - - // Log.i(TAG, "Clicked mKeyguard! dimissing dialog"); - this.dismiss(); - // Log.i(TAG, "onKey: turning off the screen..."); - // XXX: This is a hack for now - mPowerManager.goToSleep(event.getEventTime() + 1); - return true; - } - - public void show() { - super.show(); - Log.d(TAG, "show... disabling expand"); - sStatusBar.disable(StatusBarManager.DISABLE_EXPAND); - } - - public void dismiss() { - super.dismiss(); - Log.d(TAG, "dismiss... reenabling expand"); - sStatusBar.disable(StatusBarManager.DISABLE_NONE); - } -} diff --git a/policy/com/android/internal/policy/impl/RecentApplicationsBackground.java b/policy/com/android/internal/policy/impl/RecentApplicationsBackground.java deleted file mode 100644 index 7c99e87..0000000 --- a/policy/com/android/internal/policy/impl/RecentApplicationsBackground.java +++ /dev/null @@ -1,152 +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; - -import android.content.Context; -import android.graphics.Canvas; -import android.graphics.Rect; -import android.graphics.drawable.Drawable; -import android.util.AttributeSet; -import android.util.Log; -import android.view.Gravity; -import android.view.View; -import android.widget.LinearLayout; - -/** - * A vertical linear layout. However, instead of drawing the background - * behnd the items, it draws the background outside the items based on the - * padding. If there isn't enough room to draw both, it clips the background - * instead of the contents. - */ -public class RecentApplicationsBackground extends LinearLayout { - private static final String TAG = "RecentApplicationsBackground"; - - private boolean mBackgroundSizeChanged; - private Drawable mBackground; - private Rect mTmp0 = new Rect(); - private Rect mTmp1 = new Rect(); - - public RecentApplicationsBackground(Context context) { - this(context, null); - init(); - } - - public RecentApplicationsBackground(Context context, AttributeSet attrs) { - super(context, attrs); - init(); - } - - private void init() { - mBackground = getBackground(); - setBackgroundDrawable(null); - setPadding(0, 0, 0, 0); - setGravity(Gravity.CENTER); - } - - @Override - protected boolean setFrame(int left, int top, int right, int bottom) { - setWillNotDraw(false); - if (mLeft != left || mRight != right || mTop != top || mBottom != bottom) { - mBackgroundSizeChanged = true; - } - return super.setFrame(left, top, right, bottom); - } - - @Override - protected boolean verifyDrawable(Drawable who) { - return who == mBackground || super.verifyDrawable(who); - } - - @Override - protected void drawableStateChanged() { - Drawable d = mBackground; - if (d != null && d.isStateful()) { - d.setState(getDrawableState()); - } - super.drawableStateChanged(); - } - - @Override - public void draw(Canvas canvas) { - final Drawable background = mBackground; - if (background != null) { - if (mBackgroundSizeChanged) { - mBackgroundSizeChanged = false; - Rect chld = mTmp0; - Rect bkg = mTmp1; - mBackground.getPadding(bkg); - getChildBounds(chld); - // This doesn't clamp to this view's bounds, which is what we want, - // so that the drawing is clipped. - final int top = chld.top - bkg.top; - final int bottom = chld.bottom + bkg.bottom; - // The background here is a gradient that wants to - // extend the full width of the screen (whatever that - // may be). - int left, right; - if (false) { - // This limits the width of the drawable. - left = chld.left - bkg.left; - right = chld.right + bkg.right; - } else { - // This expands it to full width. - left = 0; - right = getRight(); - } - background.setBounds(left, top, right, bottom); - } - } - mBackground.draw(canvas); - - if (false) { - android.graphics.Paint p = new android.graphics.Paint(); - p.setColor(0x88ffff00); - canvas.drawRect(background.getBounds(), p); - } - canvas.drawARGB((int)(0.75*0xff), 0, 0, 0); - - super.draw(canvas); - } - - @Override - protected void onAttachedToWindow() { - super.onAttachedToWindow(); - mBackground.setCallback(this); - setWillNotDraw(false); - } - - @Override - protected void onDetachedFromWindow() { - super.onDetachedFromWindow(); - mBackground.setCallback(null); - } - - private void getChildBounds(Rect r) { - r.left = r.top = Integer.MAX_VALUE; - r.bottom = r.right = Integer.MIN_VALUE; - final int N = getChildCount(); - for (int i=0; i<N; i++) { - View v = getChildAt(i); - if (v.getVisibility() == View.VISIBLE) { - r.left = Math.min(r.left, v.getLeft()); - r.top = Math.min(r.top, v.getTop()); - r.right = Math.max(r.right, v.getRight()); - r.bottom = Math.max(r.bottom, v.getBottom()); - } - } - } -} diff --git a/policy/com/android/internal/policy/impl/RecentApplicationsDialog.java b/policy/com/android/internal/policy/impl/RecentApplicationsDialog.java deleted file mode 100644 index 9608b9a..0000000 --- a/policy/com/android/internal/policy/impl/RecentApplicationsDialog.java +++ /dev/null @@ -1,262 +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; - -import android.app.ActivityManager; -import android.app.Dialog; -import android.app.StatusBarManager; -import android.content.ActivityNotFoundException; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.res.Resources; -import android.content.pm.ActivityInfo; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.graphics.drawable.Drawable; -import android.os.Bundle; -import android.util.Log; -import android.view.View; -import android.view.Window; -import android.view.WindowManager; -import android.view.View.OnClickListener; -import android.widget.TextView; - -import java.util.List; - -public class RecentApplicationsDialog extends Dialog implements OnClickListener { - // Elements for debugging support -// private static final String LOG_TAG = "RecentApplicationsDialog"; - private static final boolean DBG_FORCE_EMPTY_LIST = false; - - static private StatusBarManager sStatusBar; - - private static final int NUM_BUTTONS = 8; - private static final int MAX_RECENT_TASKS = NUM_BUTTONS * 2; // allow for some discards - - final TextView[] mIcons = new TextView[NUM_BUTTONS]; - View mNoAppsText; - IntentFilter mBroadcastIntentFilter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); - - private int mIconSize; - - public RecentApplicationsDialog(Context context) { - super(context, com.android.internal.R.style.Theme_Dialog_RecentApplications); - - final Resources resources = context.getResources(); - mIconSize = (int) resources.getDimension(android.R.dimen.app_icon_size); - } - - /** - * We create the recent applications dialog just once, and it stays around (hidden) - * until activated by the user. - * - * @see PhoneWindowManager#showRecentAppsDialog - */ - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - Context context = getContext(); - - if (sStatusBar == null) { - sStatusBar = (StatusBarManager)context.getSystemService(Context.STATUS_BAR_SERVICE); - } - - Window window = getWindow(); - window.requestFeature(Window.FEATURE_NO_TITLE); - window.setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG); - window.setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM, - WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); - window.setTitle("Recents"); - - setContentView(com.android.internal.R.layout.recent_apps_dialog); - - final WindowManager.LayoutParams params = window.getAttributes(); - params.width = WindowManager.LayoutParams.MATCH_PARENT; - params.height = WindowManager.LayoutParams.MATCH_PARENT; - window.setAttributes(params); - window.setFlags(0, WindowManager.LayoutParams.FLAG_DIM_BEHIND); - - mIcons[0] = (TextView)findViewById(com.android.internal.R.id.button0); - mIcons[1] = (TextView)findViewById(com.android.internal.R.id.button1); - mIcons[2] = (TextView)findViewById(com.android.internal.R.id.button2); - mIcons[3] = (TextView)findViewById(com.android.internal.R.id.button3); - mIcons[4] = (TextView)findViewById(com.android.internal.R.id.button4); - mIcons[5] = (TextView)findViewById(com.android.internal.R.id.button5); - mIcons[6] = (TextView)findViewById(com.android.internal.R.id.button6); - mIcons[7] = (TextView)findViewById(com.android.internal.R.id.button7); - mNoAppsText = findViewById(com.android.internal.R.id.no_applications_message); - - for (TextView b: mIcons) { - b.setOnClickListener(this); - } - } - - /** - * Handler for user clicks. If a button was clicked, launch the corresponding activity. - */ - public void onClick(View v) { - - for (TextView b: mIcons) { - if (b == v) { - // prepare a launch intent and send it - Intent intent = (Intent)b.getTag(); - if (intent != null) { - intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); - try { - getContext().startActivity(intent); - } catch (ActivityNotFoundException e) { - Log.w("Recent", "Unable to launch recent task", e); - } - } - break; - } - } - dismiss(); - } - - /** - * Set up and show the recent activities dialog. - */ - @Override - public void onStart() { - super.onStart(); - reloadButtons(); - if (sStatusBar != null) { - sStatusBar.disable(StatusBarManager.DISABLE_EXPAND); - } - - // receive broadcasts - getContext().registerReceiver(mBroadcastReceiver, mBroadcastIntentFilter); - } - - /** - * Dismiss the recent activities dialog. - */ - @Override - public void onStop() { - super.onStop(); - - // dump extra memory we're hanging on to - for (TextView icon: mIcons) { - icon.setCompoundDrawables(null, null, null, null); - icon.setTag(null); - } - - if (sStatusBar != null) { - sStatusBar.disable(StatusBarManager.DISABLE_NONE); - } - - // stop receiving broadcasts - getContext().unregisterReceiver(mBroadcastReceiver); - } - - /** - * Reload the 6 buttons with recent activities - */ - private void reloadButtons() { - - final Context context = getContext(); - final PackageManager pm = context.getPackageManager(); - final ActivityManager am = (ActivityManager) - context.getSystemService(Context.ACTIVITY_SERVICE); - final List<ActivityManager.RecentTaskInfo> recentTasks = - am.getRecentTasks(MAX_RECENT_TASKS, ActivityManager.RECENT_IGNORE_UNAVAILABLE); - - ActivityInfo homeInfo = - new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME) - .resolveActivityInfo(pm, 0); - - IconUtilities iconUtilities = new IconUtilities(getContext()); - - // Performance note: Our android performance guide says to prefer Iterator when - // using a List class, but because we know that getRecentTasks() always returns - // an ArrayList<>, we'll use a simple index instead. - int index = 0; - int numTasks = recentTasks.size(); - for (int i = 0; i < numTasks && (index < NUM_BUTTONS); ++i) { - final ActivityManager.RecentTaskInfo info = recentTasks.get(i); - - // for debug purposes only, disallow first result to create empty lists - if (DBG_FORCE_EMPTY_LIST && (i == 0)) continue; - - Intent intent = new Intent(info.baseIntent); - if (info.origActivity != null) { - intent.setComponent(info.origActivity); - } - - // Skip the current home activity. - if (homeInfo != null) { - if (homeInfo.packageName.equals( - intent.getComponent().getPackageName()) - && homeInfo.name.equals( - intent.getComponent().getClassName())) { - continue; - } - } - - intent.setFlags((intent.getFlags()&~Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) - | Intent.FLAG_ACTIVITY_NEW_TASK); - final ResolveInfo resolveInfo = pm.resolveActivity(intent, 0); - if (resolveInfo != null) { - final ActivityInfo activityInfo = resolveInfo.activityInfo; - final String title = activityInfo.loadLabel(pm).toString(); - Drawable icon = activityInfo.loadIcon(pm); - - if (title != null && title.length() > 0 && icon != null) { - final TextView tv = mIcons[index]; - tv.setText(title); - icon = iconUtilities.createIconDrawable(icon); - tv.setCompoundDrawables(null, icon, null, null); - tv.setTag(intent); - tv.setVisibility(View.VISIBLE); - tv.setPressed(false); - tv.clearFocus(); - ++index; - } - } - } - - // handle the case of "no icons to show" - mNoAppsText.setVisibility((index == 0) ? View.VISIBLE : View.GONE); - - // hide the rest - for (; index < NUM_BUTTONS; ++index) { - mIcons[index].setVisibility(View.GONE); - } - } - - /** - * This is the listener for the ACTION_CLOSE_SYSTEM_DIALOGS intent. It's an indication that - * we should close ourselves immediately, in order to allow a higher-priority UI to take over - * (e.g. phone call received). - */ - private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) { - String reason = intent.getStringExtra(PhoneWindowManager.SYSTEM_DIALOG_REASON_KEY); - if (! PhoneWindowManager.SYSTEM_DIALOG_REASON_RECENT_APPS.equals(reason)) { - dismiss(); - } - } - } - }; -} diff --git a/policy/com/android/internal/policy/impl/ShortcutManager.java b/policy/com/android/internal/policy/impl/ShortcutManager.java deleted file mode 100644 index d86ac44..0000000 --- a/policy/com/android/internal/policy/impl/ShortcutManager.java +++ /dev/null @@ -1,120 +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; - -import android.content.Context; -import android.content.Intent; -import android.database.ContentObserver; -import android.database.Cursor; -import android.os.Handler; -import android.provider.Settings; -import android.util.Log; -import android.util.SparseArray; -import android.view.KeyCharacterMap; - -import java.net.URISyntaxException; - -/** - * Manages quick launch shortcuts by: - * <li> Keeping the local copy in sync with the database (this is an observer) - * <li> Returning a shortcut-matching intent to clients - */ -class ShortcutManager extends ContentObserver { - - private static final String TAG = "ShortcutManager"; - - private static final int COLUMN_SHORTCUT = 0; - private static final int COLUMN_INTENT = 1; - private static final String[] sProjection = new String[] { - Settings.Bookmarks.SHORTCUT, Settings.Bookmarks.INTENT - }; - - private Context mContext; - private Cursor mCursor; - /** Map of a shortcut to its intent. */ - private SparseArray<Intent> mShortcutIntents; - - public ShortcutManager(Context context, Handler handler) { - super(handler); - - mContext = context; - mShortcutIntents = new SparseArray<Intent>(); - } - - /** Observes the provider of shortcut+intents */ - public void observe() { - mCursor = mContext.getContentResolver().query( - Settings.Bookmarks.CONTENT_URI, sProjection, null, null, null); - mCursor.registerContentObserver(this); - updateShortcuts(); - } - - @Override - public void onChange(boolean selfChange) { - updateShortcuts(); - } - - private void updateShortcuts() { - Cursor c = mCursor; - if (!c.requery()) { - Log.e(TAG, "ShortcutObserver could not re-query shortcuts."); - return; - } - - mShortcutIntents.clear(); - while (c.moveToNext()) { - int shortcut = c.getInt(COLUMN_SHORTCUT); - if (shortcut == 0) continue; - String intentURI = c.getString(COLUMN_INTENT); - Intent intent = null; - try { - intent = Intent.getIntent(intentURI); - } catch (URISyntaxException e) { - Log.w(TAG, "Intent URI for shortcut invalid.", e); - } - if (intent == null) continue; - mShortcutIntents.put(shortcut, intent); - } - } - - /** - * Gets the shortcut intent for a given keycode+modifier. Make sure you - * strip whatever modifier is used for invoking shortcuts (for example, - * if 'Sym+A' should invoke a shortcut on 'A', you should strip the - * 'Sym' bit from the modifiers before calling this method. - * <p> - * This will first try an exact match (with modifiers), and then try a - * match without modifiers (primary character on a key). - * - * @param keyCode The keycode of the key pushed. - * @param modifiers The modifiers without any that are used for chording - * to invoke a shortcut. - * @return The intent that matches the shortcut, or null if not found. - */ - public Intent getIntent(int keyCode, int modifiers) { - KeyCharacterMap kcm = KeyCharacterMap.load(KeyCharacterMap.BUILT_IN_KEYBOARD); - // First try the exact keycode (with modifiers) - int shortcut = kcm.get(keyCode, modifiers); - Intent intent = shortcut != 0 ? mShortcutIntents.get(shortcut) : null; - if (intent != null) return intent; - - // Next try the keycode without modifiers (the primary character on that key) - shortcut = Character.toLowerCase(kcm.get(keyCode, 0)); - return shortcut != 0 ? mShortcutIntents.get(shortcut) : null; - } - -} diff --git a/policy/com/android/internal/policy/impl/SimUnlockScreen.java b/policy/com/android/internal/policy/impl/SimUnlockScreen.java deleted file mode 100644 index 5518e11..0000000 --- a/policy/com/android/internal/policy/impl/SimUnlockScreen.java +++ /dev/null @@ -1,423 +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; - -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, - KeyguardUpdateMonitor.InfoCallback { - - 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 Button mEmergencyCallButton; - - 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 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); - - mEmergencyCallButton = (Button) findViewById(R.id.emergencyCall); - mLockPatternUtils.updateEmergencyCallButtonState(mEmergencyCallButton); - mOkButton = (TextView) findViewById(R.id.ok); - - mHeaderText.setText(R.string.keyguard_password_enter_pin_code); - mPinText.setFocusable(false); - - mEmergencyCallButton.setOnClickListener(this); - mOkButton.setOnClickListener(this); - - setFocusableInTouchMode(true); - } - - /** {@inheritDoc} */ - public boolean needsInput() { - return true; - } - - /** {@inheritDoc} */ - public void 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; - - mLockPatternUtils.updateEmergencyCallButtonState(mEmergencyCallButton); - } - - /** {@inheritDoc} */ - public void cleanUp() { - // hide the dialog. - if (mSimUnlockProgressDialog != null) { - mSimUnlockProgressDialog.hide(); - } - 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 == mEmergencyCallButton) { - mCallback.takeEmergencyCallAction(); - } 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); - if (!mContext.getResources().getBoolean( - com.android.internal.R.bool.config_sf_slowBlur)) { - mSimUnlockProgressDialog.getWindow().setFlags( - WindowManager.LayoutParams.FLAG_BLUR_BEHIND, - WindowManager.LayoutParams.FLAG_BLUR_BEHIND); - } - } - 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(boolean success) { - if (mSimUnlockProgressDialog != null) { - mSimUnlockProgressDialog.hide(); - } - if (success) { - // before closing the keyguard, report back that - // the sim is unlocked so it knows right away - mUpdateMonitor.reportSimPinUnlocked(); - 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; - final boolean isKeyboardOpen = mKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO; - if (mUpdateMonitor.isKeyguardBypassEnabled() && isKeyboardOpen) { - mCallback.goToUnlockScreen(); - } - } - - } - - @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) { - 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; - } - } - - public void onPhoneStateChanged(String newState) { - mLockPatternUtils.updateEmergencyCallButtonState(mEmergencyCallButton); - } - - public void onRefreshBatteryInfo(boolean showBatteryInfo, boolean pluggedIn, int batteryLevel) { - - } - - public void onRefreshCarrierInfo(CharSequence plmn, CharSequence spn) { - - } - - public void onRingerModeChanged(int state) { - - } - - public void onTimeChanged() { - - } -} diff --git a/policy/com/android/internal/policy/impl/package.html b/policy/com/android/internal/policy/impl/package.html deleted file mode 100644 index c9f96a6..0000000 --- a/policy/com/android/internal/policy/impl/package.html +++ /dev/null @@ -1,5 +0,0 @@ -<body> - -{@hide} - -</body> |