diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 18:28:48 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 18:28:48 -0800 |
commit | 10bf778e493ae9ed7b0a9317bf35f00142e11cb4 (patch) | |
tree | 4b825dc642cb6eb9a060e54bf8d69288fbee4904 /policy | |
parent | fee49fc0d29f6864e8f91fcf29cc1a19c4d91ff7 (diff) | |
download | frameworks_base-10bf778e493ae9ed7b0a9317bf35f00142e11cb4.zip frameworks_base-10bf778e493ae9ed7b0a9317bf35f00142e11cb4.tar.gz frameworks_base-10bf778e493ae9ed7b0a9317bf35f00142e11cb4.tar.bz2 |
auto import from //depot/cupcake/@135843
Diffstat (limited to 'policy')
26 files changed, 0 insertions, 9768 deletions
diff --git a/policy/Android.mk b/policy/Android.mk deleted file mode 100644 index 29f62b8..0000000 --- a/policy/Android.mk +++ /dev/null @@ -1,13 +0,0 @@ -LOCAL_PATH:= $(call my-dir) - -# the library -# ============================================================ -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := \ - $(call all-subdir-java-files) - -LOCAL_MODULE := android.policy_phone -LOCAL_UNINSTALLABLE_MODULE := true - -include $(BUILD_JAVA_LIBRARY) 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 b5a144e..0000000 --- a/policy/com/android/internal/policy/impl/AccountUnlockScreen.java +++ /dev/null @@ -1,215 +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.AccountsServiceConstants; -import android.accounts.IAccountsService; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.ServiceConnection; -import android.graphics.Rect; -import android.os.IBinder; -import android.os.RemoteException; -import android.text.Editable; -import android.text.InputFilter; -import android.text.LoginFilter; -import android.text.TextWatcher; -import android.util.Log; -import android.view.KeyEvent; -import android.view.LayoutInflater; -import android.view.View; -import android.widget.Button; -import android.widget.EditText; -import android.widget.RelativeLayout; -import android.widget.TextView; - -/** - * 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). - * - * <p>This class is useful only on platforms that support the - * IAccountsService. - */ -public class AccountUnlockScreen extends RelativeLayout implements KeyguardScreen, - View.OnClickListener, ServiceConnection, 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 IAccountsService mAccountsService; - - private TextView mTopHeader; - private TextView mInstructions; - private EditText mLogin; - private EditText mPassword; - private Button mOk; - private Button mEmergencyCall; - - /** - * AccountUnlockScreen constructor. - * - * @throws IllegalStateException if the IAccountsService is not - * available on the current platform. - */ - public AccountUnlockScreen(Context context, - 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); - - 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); - - Log.v("AccountUnlockScreen", "debug: Connecting to accounts service"); - final boolean connected = mContext.bindService(AccountsServiceConstants.SERVICE_INTENT, - this, Context.BIND_AUTO_CREATE); - if (!connected) { - Log.v("AccountUnlockScreen", "debug: Couldn't connect to accounts service"); - throw new IllegalStateException("couldn't bind to accounts service"); - } - } - - 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(); - } - - /** {@inheritDoc} */ - public void cleanUp() { - mContext.unbindService(this); - } - - /** {@inheritDoc} */ - public void onClick(View v) { - mCallback.pokeWakelock(); - if (v == mOk) { - if (checkPassword()) { - // clear out forgotten password - mLockPatternUtils.setPermanentlyLocked(false); - - // 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); - - // close the keyguard - mCallback.keyguardDone(true); - } else { - mInstructions.setText(R.string.lockscreen_glogin_invalid_input); - mPassword.setText(""); - } - } - - if (v == mEmergencyCall) { - mCallback.takeEmergencyCallAction(); - } - } - - @Override - public boolean dispatchKeyEvent(KeyEvent event) { - if (event.getAction() == KeyEvent.ACTION_DOWN - && event.getKeyCode() == KeyEvent.KEYCODE_BACK) { - mCallback.goToLockScreen(); - return true; - } - return super.dispatchKeyEvent(event); - } - - private boolean checkPassword() { - final String login = mLogin.getText().toString(); - final String password = mPassword.getText().toString(); - try { - return mAccountsService.shouldUnlock(login, password); - } catch (RemoteException e) { - return false; - } - } - - /** {@inheritDoc} */ - public void onServiceConnected(ComponentName name, IBinder service) { - Log.v("AccountUnlockScreen", "debug: About to grab as interface"); - mAccountsService = IAccountsService.Stub.asInterface(service); - } - - /** {@inheritDoc} */ - public void onServiceDisconnected(ComponentName name) { - mAccountsService = null; - } -} 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 7f8e57b..0000000 --- a/policy/com/android/internal/policy/impl/GlobalActions.java +++ /dev/null @@ -1,414 +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.google.android.collect.Lists; - -import android.app.AlertDialog; -import android.app.StatusBarManager; -import android.content.Context; -import android.content.BroadcastReceiver; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.DialogInterface; -import android.media.AudioManager; -import android.os.LocalPowerManager; -import android.os.Handler; -import android.os.Message; -import android.os.SystemClock; -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.LinearLayout; -import android.widget.TextView; - -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 StatusBarManager mStatusBar; - - private final Context mContext; - private final LocalPowerManager mPowerManager; - private final AudioManager mAudioManager; - private ArrayList<Action> mItems; - private AlertDialog mDialog; - - private ToggleAction mSilentModeToggle; - - private MyAdapter mAdapter; - - private boolean mKeyguardShowing = false; - private boolean mDeviceProvisioned = false; - - /** - * @param context everything needs a context :) - * @param powerManager used to turn the screen off (the lock action). - */ - public GlobalActions(Context context, LocalPowerManager powerManager) { - mContext = context; - mPowerManager = powerManager; - mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE); - - // receive broadcasts - IntentFilter filter = new IntentFilter(); - filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); - context.registerReceiver(mBroadcastReceiver, filter); - } - - /** - * 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 onToggle(boolean on) { - mAudioManager.setRingerMode(on ? AudioManager.RINGER_MODE_SILENT - : AudioManager.RINGER_MODE_NORMAL); - } - - public boolean showDuringKeyguard() { - return true; - } - - public boolean showBeforeProvisioning() { - return false; - } - }; - - mItems = Lists.newArrayList( - /* Disabled pending bug 1304831 -- key or touch events wake up device before it - * can go to sleep. - // first: lock screen - new SinglePressAction(com.android.internal.R.drawable.ic_lock_lock, R.string.global_action_lock) { - - public void onPress() { - mPowerManager.goToSleep(SystemClock.uptimeMillis() + 1); - } - - public boolean showDuringKeyguard() { - return false; - } - - public boolean showBeforeProvisioning() { - return false; - } - }, - */ - // next: silent mode - mSilentModeToggle, - // 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.shutdownAfterDisablingRadio(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); - dialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND, - WindowManager.LayoutParams.FLAG_BLUR_BEHIND); - - dialog.setOnDismissListener(this); - - return dialog; - } - - private void prepareDialog() { - // TODO: May need another 'Vibrate' toggle button, but for now treat them the same - final boolean silentModeOn = - mAudioManager.getRingerMode() != AudioManager.RINGER_MODE_NORMAL; - mSilentModeToggle.updateState(silentModeOn); - 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; - } - - 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, (LinearLayout) convertView, 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 { - LinearLayout create(Context context, LinearLayout convertView, 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(); - } - - /** - * 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; - } - - abstract public void onPress(); - - public LinearLayout create(Context context, LinearLayout convertView, LayoutInflater inflater) { - LinearLayout v = (LinearLayout) ((convertView != null) ? - convertView : - inflater.inflate(R.layout.global_actions_item, null)); - - 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. - */ - static abstract class ToggleAction implements Action { - - private boolean mOn = false; - - // prefs - private final int mEnabledIconResId; - private final int mDisabledIconResid; - private final int mMessageResId; - private final int mEnabledStatusMessageResId; - private final 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; - } - - public LinearLayout create(Context context, LinearLayout convertView, - LayoutInflater inflater) { - LinearLayout v = (LinearLayout) ((convertView != null) ? - convertView : - inflater.inflate(R - .layout.global_actions_item, null)); - - 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); - - icon.setImageDrawable(context.getResources().getDrawable( - (mOn ? mEnabledIconResId : mDisabledIconResid))); - statusView.setText(mOn ? mEnabledStatusMessageResId : mDisabledStatusMessageResId); - statusView.setVisibility(View.VISIBLE); - - return v; - } - - public void onPress() { - updateState(!mOn); - onToggle(mOn); - } - - abstract void onToggle(boolean on); - - public void updateState(boolean on) { - mOn = on; - } - } - - private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { - 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_GLOBAL_ACTIONS.equals(reason)) { - mHandler.sendEmptyMessage(MESSAGE_DISMISS); - } - } - } - }; - - 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(); - } - } - } - }; -} 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 b46b37d..0000000 --- a/policy/com/android/internal/policy/impl/KeyguardScreenCallback.java +++ /dev/null @@ -1,66 +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; - -/** - * 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(); - - /** - * Transitino to th unlock screen. - */ - void goToUnlockScreen(); - - /** - * @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(); - - /** - * Take action to send an emergency call. - */ - void takeEmergencyCallAction(); - - /** - * Report that the user had a failed attempt unlocking via the pattern. - */ - void reportFailedPatternAttempt(); - - /** - * 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 3a25d38..0000000 --- a/policy/com/android/internal/policy/impl/KeyguardUpdateMonitor.java +++ /dev/null @@ -1,552 +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.os.Handler; -import android.os.Message; -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.SimCard; -import com.android.internal.telephony.TelephonyIntents; -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 SimCard.State mSimState = SimCard.State.READY; - private boolean mInPortrait; - private boolean mKeyboardOpen; - - private boolean mDevicePluggedIn; - - private boolean mDeviceProvisioned; - - private int mBatteryLevel; - - private CharSequence mTelephonyPlmn; - private CharSequence mTelephonySpn; - - private int mFailedAttempts = 0; - - private Handler mHandler; - - private ArrayList<ConfigurationChangeCallback> mConfigurationChangeCallbacks - = Lists.newArrayList(); - private ArrayList<InfoCallback> mInfoCallbacks = Lists.newArrayList(); - private ArrayList<SimStateCallback> mSimStateCallbacks = Lists.newArrayList(); - private ContentObserver mContentObserver; - - - // messages for the handler - private static final int MSG_CONFIGURATION_CHANGED = 300; - 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; - - - /** - * 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 SimCard.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(SimCard.INTENT_KEY_SIM_STATE); - if (SimCard.INTENT_VALUE_SIM_ABSENT.equals(stateExtra)) { - this.simState = SimCard.State.ABSENT; - } else if (SimCard.INTENT_VALUE_SIM_READY.equals(stateExtra)) { - this.simState = SimCard.State.READY; - } else if (SimCard.INTENT_VALUE_SIM_LOCKED.equals(stateExtra)) { - final String lockedReason = intent - .getStringExtra(SimCard.INTENT_KEY_LOCKED_REASON); - if (SimCard.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) { - this.simState = SimCard.State.PIN_REQUIRED; - } else if (SimCard.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) { - this.simState = SimCard.State.PUK_REQUIRED; - } else { - this.simState = SimCard.State.UNKNOWN; - } - } else if (SimCard.INTENT_VALUE_LOCKED_NETWORK.equals(stateExtra)) { - this.simState = SimCard.State.NETWORK_LOCKED; - } else { - this.simState = SimCard.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_CONFIGURATION_CHANGED: - handleConfigurationChange(); - break; - 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; - } - } - }; - - 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; - } - - mInPortrait = queryInPortrait(); - mKeyboardOpen = queryKeyboardOpen(); - - // take a guess to start - mSimState = SimCard.State.READY; - mDevicePluggedIn = true; - mBatteryLevel = 100; - - mTelephonyPlmn = getDefaultPlmn(); - - // setup receiver - final IntentFilter filter = new IntentFilter(); - filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED); - 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(SPN_STRINGS_UPDATED_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_CONFIGURATION_CHANGED.equals(action)) { - mHandler.sendMessage(mHandler.obtainMessage(MSG_CONFIGURATION_CHANGED)); - } else 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))); - } - } - }, filter); - } - - /** - * Handle {@link #MSG_CONFIGURATION_CHANGED} - */ - private void handleConfigurationChange() { - if (DEBUG) Log.d(TAG, "handleConfigurationChange"); - - final boolean inPortrait = queryInPortrait(); - if (mInPortrait != inPortrait) { - mInPortrait = inPortrait; - for (int i = 0; i < mConfigurationChangeCallbacks.size(); i++) { - mConfigurationChangeCallbacks.get(i).onOrientationChange(inPortrait); - } - } - - final boolean keyboardOpen = queryKeyboardOpen(); - if (mKeyboardOpen != keyboardOpen) { - mKeyboardOpen = keyboardOpen; - for (int i = 0; i < mConfigurationChangeCallbacks.size(); i++) { - mConfigurationChangeCallbacks.get(i).onKeyboardChange(keyboardOpen); - } - } - } - - /** - * 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); - } - } - - // shut down gracefully if our battery is critically low and we are not powered - if (batteryLevel == 0 && - pluggedInStatus != BATTERY_STATUS_CHARGING && - pluggedInStatus != BATTERY_STATUS_UNKNOWN) { - ShutdownThread.shutdownAfterDisablingRadio(mContext, false); - } - } - - /** - * 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 SimCard.State state = simArgs.simState; - - if (DEBUG) { - Log.d(TAG, "handleSimStateChange: intentValue = " + simArgs + " " - + "state resolved to " + state.toString()); - } - - if (state != SimCard.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 going below threshold - if (batteryLevel < LOW_BATTERY_THRESHOLD - && mBatteryLevel >= LOW_BATTERY_THRESHOLD) { - return true; - } - // not plugged in and going above threshold (sounds impossible, but, meh...) - if (mBatteryLevel < LOW_BATTERY_THRESHOLD - && batteryLevel >= LOW_BATTERY_THRESHOLD) { - return true; - } - } - return false; - } - - /** - * What is the current orientation? - */ - boolean queryInPortrait() { - final Configuration configuration = mContext.getResources().getConfiguration(); - return configuration.orientation == Configuration.ORIENTATION_PORTRAIT; - } - - /** - * Is the (hard) keyboard currently open? - */ - boolean queryKeyboardOpen() { - final Configuration configuration = mContext.getResources().getConfiguration(); - - return configuration.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO; - } - - /** - * @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) { - mConfigurationChangeCallbacks.remove(observer); - mInfoCallbacks.remove(observer); - mSimStateCallbacks.remove(observer); - } - - /** - * Callback for configuration changes. - */ - interface ConfigurationChangeCallback { - void onOrientationChange(boolean inPortrait); - - void onKeyboardChange(boolean isKeyboardOpen); - } - - /** - * Callback for general information releveant 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); - } - - /** - * Callback to notify of sim state change. - */ - interface SimStateCallback { - void onSimStateChanged(SimCard.State simState); - } - - /** - * Register to receive notifications about configuration changes. - * @param callback The callback. - */ - public void registerConfigurationChangeCallback(ConfigurationChangeCallback callback) { - mConfigurationChangeCallbacks.add(callback); - } - - /** - * Register to receive notifications about general keyguard information - * (see {@link InfoCallback}. - * @param callback The callback. - */ - public void registerInfoCallback(InfoCallback callback) { - mInfoCallbacks.add(callback); - } - - /** - * Register to be notified of sim state changes. - * @param callback The callback. - */ - public void registerSimStateCallback(SimStateCallback callback) { - mSimStateCallbacks.add(callback); - } - - public SimCard.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 = SimCard.State.READY; - } - - public boolean isInPortrait() { - return mInPortrait; - } - - public boolean isKeyboardOpen() { - return mKeyboardOpen; - } - - 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 a565808..0000000 --- a/policy/com/android/internal/policy/impl/KeyguardViewBase.java +++ /dev/null @@ -1,188 +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.view.KeyEvent; -import android.view.View; -import android.widget.FrameLayout; - -/** - * 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; - - public KeyguardViewBase(Context context) { - super(context); - } - - // 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 keygaurd is showing. - * The media keys should be of no interest to the actualy keygaurd 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_HEADSETHOOK: - case KeyEvent.KEYCODE_PLAYPAUSE: - case KeyEvent.KEYCODE_STOP: - case KeyEvent.KEYCODE_NEXTSONG: - case KeyEvent.KEYCODE_PREVIOUSSONG: - case KeyEvent.KEYCODE_REWIND: - case KeyEvent.KEYCODE_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_PLAYPAUSE: - case KeyEvent.KEYCODE_STOP: - case KeyEvent.KEYCODE_NEXTSONG: - case KeyEvent.KEYCODE_PREVIOUSSONG: - case KeyEvent.KEYCODE_REWIND: - case KeyEvent.KEYCODE_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 297d62f..0000000 --- a/policy/com/android/internal/policy/impl/KeyguardViewManager.java +++ /dev/null @@ -1,226 +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()"); - - if (mKeyguardHost == null) { - if (DEBUG) Log.d(TAG, "keyguard host is null, creating it..."); - - mKeyguardHost = new KeyguardViewHost(mContext, mCallback); - - final int stretch = ViewGroup.LayoutParams.FILL_PARENT; - int flags = WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN - /*| 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.OPAQUE); - 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.FILL_PARENT, - ViewGroup.LayoutParams.FILL_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 void wakeWhenReadyTq(int keyCode) { - if (DEBUG) Log.d(TAG, "wakeWhenReady(" + keyCode + ")"); - if (mKeyguardView != null) { - mKeyguardView.wakeWhenReadyTq(keyCode); - } - } - - /** - * Hides the keyguard view - */ - public synchronized void hide() { - if (DEBUG) Log.d(TAG, "hide()"); - if (mKeyguardHost != null) { - mKeyguardHost.setVisibility(View.GONE); - if (mKeyguardView != null) { - mKeyguardHost.removeView(mKeyguardView); - mKeyguardView.cleanUp(); - mKeyguardView = null; - } - } - } - - /** - * @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 e7366c2..0000000 --- a/policy/com/android/internal/policy/impl/KeyguardViewMediator.java +++ /dev/null @@ -1,915 +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.app.AlarmManager; -import android.app.PendingIntent; -import android.app.StatusBarManager; -import static android.app.StatusBarManager.DISABLE_NONE; -import static android.app.StatusBarManager.DISABLE_EXPAND; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.os.Handler; -import android.os.LocalPowerManager; -import android.os.Message; -import android.os.PowerManager; -import android.os.SystemClock; -import android.util.Config; -import android.util.Log; -import android.util.EventLog; -import android.view.KeyEvent; -import android.view.WindowManagerImpl; -import android.view.WindowManagerPolicy; -import com.android.internal.telephony.SimCard; -import com.android.internal.telephony.TelephonyIntents; -import com.android.internal.widget.LockPatternUtils; - -/** - * 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.KeyInputQueue}'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.ConfigurationChangeCallback, 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; - - /** - * 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 = 0; - - /** - * 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 boolean mSystemReady; - - /** 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; - - /** - * 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; - - /** - * Used to disable / reenable status bar expansion. - */ - private StatusBarManager mStatusBarManager; - - 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; - - /** - * 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; - - /** - * {@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); - - mWakeAndHandOff = mPM.newWakeLock( - PowerManager.PARTIAL_WAKE_LOCK, - "keyguardWakeAndHandOff"); - mWakeAndHandOff.setReferenceCounted(false); - - IntentFilter filter = new IntentFilter(); - filter.addAction(DELAYED_KEYGUARD_ACTION); - filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED); - filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED); - context.registerReceiver(mBroadCastReceiver, filter); - mAlarmManager = (AlarmManager) context - .getSystemService(Context.ALARM_SERVICE); - mCallback = callback; - - mUpdateMonitor = new KeyguardUpdateMonitor(context); - - mUpdateMonitor.registerConfigurationChangeCallback(this); - mUpdateMonitor.registerSimStateCallback(this); - - mKeyguardViewProperties = - new LockPatternKeyguardViewProperties( - new LockPatternUtils(mContext.getContentResolver()), - mUpdateMonitor); - - mKeyguardViewManager = new KeyguardViewManager( - context, WindowManagerImpl.getDefault(), this, - mKeyguardViewProperties, mUpdateMonitor); - - } - - /** - * 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} or - * {@link WindowManagerPolicy#OFF_BECAUSE_OF_TIMEOUT}. - */ - public void onScreenTurnedOff(int why) { - synchronized (this) { - 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 { - doKeyguard(); - } - } - } - - /** - * Let's us know the screen was turned on. - */ - public void onScreenTurnedOn() { - synchronized (this) { - 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; - setStatusBarExpandable(false); - hideLocked(); - } else if (enabled && mNeedToReshowWhenReenabled) { - // reenabled after previously hidden, reshow - if (DEBUG) Log.d(TAG, "previously hidden, reshowing, reenabling " - + "status bar expansion"); - mNeedToReshowWhenReenabled = false; - setStatusBarExpandable(true); - - 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(); - } - } - } - - - private void setStatusBarExpandable(boolean isExpandable) { - if (mStatusBarManager == null) { - mStatusBarManager = - (StatusBarManager) mContext.getSystemService(Context.STATUS_BAR_SERVICE); - } - mStatusBarManager.disable(isExpandable ? DISABLE_NONE : DISABLE_EXPAND); - } - - /** - * Is the keyguard currently showing? - */ - public boolean isShowing() { - return mShowing; - } - - /** - * 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(); - } - - - /** - * 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"); - 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 provisioned = mUpdateMonitor.isDeviceProvisioned(); - final SimCard.State state = mUpdateMonitor.getSimState(); - final boolean lockedOrMissing = state.isPinLocked() || (state == SimCard.State.ABSENT); - 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"); - 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); - } - - /** - * {@link KeyguardUpdateMonitor} callbacks. - */ - - /** {@inheritDoc} */ - public void onOrientationChange(boolean inPortrait) { - - } - - /** {@inheritDoc} */ - public void onKeyboardChange(boolean isKeyboardOpen) { - mKeyboardOpen = isKeyboardOpen; - - if (mKeyboardOpen && !mKeyguardViewProperties.isSecure() - && mKeyguardViewManager.isShowing()) { - if (DEBUG) Log.d(TAG, "bypassing keyguard on sliding open of keyboard with non-secure keyguard"); - keyguardDone(true); - } - } - - /** {@inheritDoc} */ - public void onSimStateChanged(SimCard.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_SIM_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_SIM_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; - } - } - - 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) { - 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_PLAYPAUSE: - case KeyEvent.KEYCODE_STOP: - case KeyEvent.KEYCODE_NEXTSONG: - case KeyEvent.KEYCODE_PREVIOUSSONG: - case KeyEvent.KEYCODE_REWIND: - case KeyEvent.KEYCODE_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) { - synchronized (this) { - EventLog.writeEvent(70000, 2); - if (DEBUG) Log.d(TAG, "keyguardDone(" + authenticated + ")"); - Message msg = mHandler.obtainMessage(KEYGUARD_DONE); - 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; - setStatusBarExpandable(true); - } - } - } - } - - /** - * {@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(); - return; - case KEYGUARD_DONE_DRAWING: - handleKeyguardDoneDrawing(); - } - } - }; - - /** - * @see #keyguardDone - * @see #KEYGUARD_DONE - */ - private void handleKeyguardDone() { - if (DEBUG) Log.d(TAG, "handleKeyguardDone"); - handleHide(); - mPM.userActivity(SystemClock.uptimeMillis(), true); - mWakeLock.release(); - } - - /** - * @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(); - } - } - } - - /** - * Handle message sent by {@link #showLocked}. - * @see #SHOW - */ - private void handleShow() { - synchronized (KeyguardViewMediator.this) { - if (DEBUG) Log.d(TAG, "handleShow"); - if (!mSystemReady) return; - - // while we're showing, we control the wake state, so ask the power - // manager not to honor request for userActivity. - mRealPowerManager.enableUserActivity(false); - - mCallback.onKeyguardShow(); - mKeyguardViewManager.show(); - mShowing = true; - } - } - - /** - * Handle message sent by {@link #hideLocked()} - * @see #HIDE - */ - private void handleHide() { - synchronized (KeyguardViewMediator.this) { - if (DEBUG) Log.d(TAG, "handleHide"); - // When we go away, tell the poewr manager to honor requests from userActivity. - mRealPowerManager.enableUserActivity(true); - - mKeyguardViewManager.hide(); - mShowing = false; - } - } - - /** - * 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 - mKeyguardViewManager.wakeWhenReadyTq(keyCode); - - /** - * 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, "mKeyguardViewManager.wakeWhenReadyTq did not poke wake lock"); - } - } - } - - /** - * 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 1ec7e15..0000000 --- a/policy/com/android/internal/policy/impl/LockPatternKeyguardView.java +++ /dev/null @@ -1,570 +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.accounts.AccountsServiceConstants; -import android.accounts.IAccountsService; -import android.app.AlertDialog; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.ServiceConnection; -import android.os.IBinder; -import android.os.RemoteException; -import android.os.SystemProperties; -import com.android.internal.telephony.SimCard; -import android.text.TextUtils; -import android.util.Log; -import android.view.KeyEvent; -import android.view.View; -import android.view.WindowManager; -import com.android.internal.R; -import com.android.internal.widget.LockPatternUtils; - -/** - * 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 { - - // 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 mHasAccount = false; // assume they don't have an account 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 - } - - /** - * The current mode. - */ - private Mode mMode = Mode.LockScreen; - - /** - * Keeps track of what mode the current unlock screen is - */ - private UnlockMode mUnlockScreenMode; - - /** - * 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; - - /** - * Used to fetch accounts from GLS. - */ - private ServiceConnection mServiceConnection; - - /** - * @return Whether we are stuck on the lock screen because the sim is - * missing. - */ - private boolean stuckOnLockScreenBecauseSimMissing() { - return mRequiresSim - && (!mUpdateMonitor.isDeviceProvisioned()) - && (mUpdateMonitor.getSimState() == SimCard.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); - - asyncCheckForAccount(); - - mRequiresSim = - TextUtils.isEmpty(SystemProperties.get("keyguard.no_require_sim")); - - mUpdateMonitor = updateMonitor; - mLockPatternUtils = lockPatternUtils; - mWindowController = controller; - - mMode = getInitialMode(); - - mKeyguardScreenCallback = new KeyguardScreenCallback() { - - public void goToLockScreen() { - 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 SimCard.State simState = mUpdateMonitor.getSimState(); - if (stuckOnLockScreenBecauseSimMissing() - || (simState == SimCard.State.PUK_REQUIRED)){ - // stuck on lock screen when sim missing or puk'd - return; - } - if (!isSecure()) { - getCallback().keyguardDone(true); - } else { - updateScreen(Mode.UnlockScreen); - } - } - - public boolean isSecure() { - return LockPatternKeyguardView.this.isSecure(); - } - - public boolean isVerifyUnlockOnly() { - return mIsVerifyUnlockOnly; - } - - public void recreateMe() { - recreateScreens(); - } - - public void takeEmergencyCallAction() { - 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 reportFailedPatternAttempt() { - mUpdateMonitor.reportFailedAttempt(); - final int failedAttempts = mUpdateMonitor.getFailedAttempts(); - if (mHasAccount && failedAttempts == - (LockPatternUtils.FAILED_ATTEMPTS_BEFORE_RESET - - LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT)) { - showAlmostAtAccountLoginDialog(); - } else if (mHasAccount && failedAttempts >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_RESET) { - mLockPatternUtils.setPermanentlyLocked(true); - updateScreen(mMode); - } else if ((failedAttempts % LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT) - == 0) { - showTimeoutDialog(); - } - } - - public boolean doesFallbackUnlockScreenExist() { - return mHasAccount; - } - }; - - /** - * 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(); - mUnlockScreen = createUnlockScreenFor(unlockMode); - mUnlockScreenMode = unlockMode; - addView(mUnlockScreen); - updateScreen(mMode); - } - - /** - * Asynchronously checks for at least one account. This will set mHasAccount - * to true if an account is found. - */ - private void asyncCheckForAccount() { - - mServiceConnection = new ServiceConnection() { - public void onServiceConnected(ComponentName className, IBinder service) { - try { - IAccountsService accountsService = IAccountsService.Stub.asInterface(service); - String accounts[] = accountsService.getAccounts(); - mHasAccount = (accounts.length > 0); - } catch (RemoteException e) { - // Not much we can do here... - Log.e(TAG, "Gls died while attempting to get accounts: " + e); - } finally { - getContext().unbindService(mServiceConnection); - mServiceConnection = null; - } - } - - public void onServiceDisconnected(ComponentName className) { - // nothing to do here - } - }; - boolean status = getContext().bindService(AccountsServiceConstants.SERVICE_INTENT, - mServiceConnection, Context.BIND_AUTO_CREATE); - if (!status) Log.e(TAG, "Failed to bind to GLS while checking for account"); - } - - @Override - public void reset() { - mIsVerifyUnlockOnly = false; - updateScreen(getInitialMode()); - } - - @Override - public void onScreenTurnedOff() { - mScreenOn = 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 recreateScreens() { - if (mLockScreen.getVisibility() == View.VISIBLE) { - ((KeyguardScreen) mLockScreen).onPause(); - } - ((KeyguardScreen) mLockScreen).cleanUp(); - removeViewInLayout(mLockScreen); - - mLockScreen = createLockScreen(); - mLockScreen.setVisibility(View.INVISIBLE); - addView(mLockScreen); - - if (mUnlockScreen.getVisibility() == View.VISIBLE) { - ((KeyguardScreen) mUnlockScreen).onPause(); - } - ((KeyguardScreen) mUnlockScreen).cleanUp(); - removeViewInLayout(mUnlockScreen); - - final UnlockMode unlockMode = getUnlockMode(); - mUnlockScreen = createUnlockScreenFor(unlockMode); - mUnlockScreen.setVisibility(View.INVISIBLE); - mUnlockScreenMode = unlockMode; - addView(mUnlockScreen); - - 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() != SimCard.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(); - if (unlockMode == UnlockMode.Pattern) { - return mLockPatternUtils.isLockPatternEnabled(); - } else if (unlockMode == UnlockMode.SimPin) { - return mUpdateMonitor.getSimState() == SimCard.State.PIN_REQUIRED - || mUpdateMonitor.getSimState() == SimCard.State.PUK_REQUIRED; - } else if (unlockMode == UnlockMode.Account) { - return true; - } else { - throw new IllegalStateException("unknown unlock mode " + unlockMode); - } - } - - private void updateScreen(final Mode mode) { - - mMode = mode; - - final View goneScreen = (mode == Mode.LockScreen) ? mUnlockScreen : mLockScreen; - final View visibleScreen = (mode == Mode.LockScreen) - ? mLockScreen : getUnlockScreenForCurrentUnlockMode(); - - - 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); - - mWindowController.setNeedsInput(((KeyguardScreen)visibleScreen).needsInput()); - - 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, - mLockPatternUtils, - mUpdateMonitor, - mKeyguardScreenCallback); - } - - View createUnlockScreenFor(UnlockMode unlockMode) { - if (unlockMode == UnlockMode.Pattern) { - return new UnlockScreen( - mContext, - mLockPatternUtils, - mUpdateMonitor, - mKeyguardScreenCallback, - mUpdateMonitor.getFailedAttempts()); - } else if (unlockMode == UnlockMode.SimPin) { - return new SimUnlockScreen( - mContext, - mUpdateMonitor, - mKeyguardScreenCallback); - } else if (unlockMode == UnlockMode.Account) { - try { - return new AccountUnlockScreen( - mContext, - 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.) - return createUnlockScreenFor(UnlockMode.Pattern); - } - } else { - throw new IllegalArgumentException("unknown unlock mode " + unlockMode); - } - } - - private View getUnlockScreenForCurrentUnlockMode() { - final UnlockMode unlockMode = getUnlockMode(); - - // if a screen exists for the correct mode, we're done - if (unlockMode == mUnlockScreenMode) { - return mUnlockScreen; - } - - // remember the mode - mUnlockScreenMode = unlockMode; - - // unlock mode has changed and we have an existing old unlock screen - // to clean up - if (mScreenOn && (mUnlockScreen.getVisibility() == View.VISIBLE)) { - ((KeyguardScreen) mUnlockScreen).onPause(); - } - ((KeyguardScreen) mUnlockScreen).cleanUp(); - removeViewInLayout(mUnlockScreen); - - // create the new one - mUnlockScreen = createUnlockScreenFor(unlockMode); - mUnlockScreen.setVisibility(View.INVISIBLE); - addView(mUnlockScreen); - return mUnlockScreen; - } - - /** - * Given the current state of things, what should be the initial mode of - * the lock screen (lock or unlock). - */ - private Mode getInitialMode() { - final SimCard.State simState = mUpdateMonitor.getSimState(); - if (stuckOnLockScreenBecauseSimMissing() || (simState == SimCard.State.PUK_REQUIRED)) { - return Mode.LockScreen; - } else if (mUpdateMonitor.isKeyboardOpen() && isSecure()) { - return Mode.UnlockScreen; - } else { - return Mode.LockScreen; - } - } - - /** - * Given the current state of things, what should the unlock screen be? - */ - private UnlockMode getUnlockMode() { - final SimCard.State simState = mUpdateMonitor.getSimState(); - if (simState == SimCard.State.PIN_REQUIRED || simState == SimCard.State.PUK_REQUIRED) { - return UnlockMode.SimPin; - } else { - return mLockPatternUtils.isPermanentlyLocked() ? - UnlockMode.Account: - UnlockMode.Pattern; - } - } - - 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); - 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); - dialog.getWindow().setFlags( - WindowManager.LayoutParams.FLAG_BLUR_BEHIND, - WindowManager.LayoutParams.FLAG_BLUR_BEHIND); - dialog.show(); - } -} 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 4e0cf09..0000000 --- a/policy/com/android/internal/policy/impl/LockPatternKeyguardViewProperties.java +++ /dev/null @@ -1,67 +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.SimCard; - -/** - * 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 isLockPatternSecure() || isSimPinSecure(); - } - - private boolean isLockPatternSecure() { - return mLockPatternUtils.isLockPatternEnabled() && mLockPatternUtils - .savedPatternExists(); - } - - private boolean isSimPinSecure() { - final SimCard.State simState = mUpdateMonitor.getSimState(); - return (simState == SimCard.State.PIN_REQUIRED || simState == SimCard.State.PUK_REQUIRED - || simState == SimCard.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 82a52f9..0000000 --- a/policy/com/android/internal/policy/impl/LockScreen.java +++ /dev/null @@ -1,371 +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.content.Context; -import android.text.format.DateFormat; -import android.view.KeyEvent; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.TextView; -import com.android.internal.telephony.SimCard; - -import java.util.Date; - -/** - * 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, KeyguardUpdateMonitor.ConfigurationChangeCallback { - private final LockPatternUtils mLockPatternUtils; - private final KeyguardUpdateMonitor mUpdateMonitor; - private final KeyguardScreenCallback mCallback; - - private TextView mHeaderSimOk1; - private TextView mHeaderSimOk2; - - private TextView mHeaderSimBad1; - private TextView mHeaderSimBad2; - - private TextView mTime; - private TextView mDate; - - private ViewGroup mBatteryInfoGroup; - private ImageView mBatteryInfoIcon; - private TextView mBatteryInfoText; - private View mBatteryInfoSpacer; - - private ViewGroup mNextAlarmGroup; - private TextView mAlarmText; - private View mAlarmSpacer; - - private ViewGroup mScreenLockedMessageGroup; - - private TextView mLockInstructions; - - private Button mEmergencyCallButton; - - /** - * false means sim is missing or PUK'd - */ - private boolean mSimOk = true; - - // 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 View[] mOnlyVisibleWhenSimOk; - - private View[] mOnlyVisibleWhenSimNotOk; - - /** - * @param context Used to setup the view. - * @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, LockPatternUtils lockPatternUtils, - KeyguardUpdateMonitor updateMonitor, - KeyguardScreenCallback callback) { - super(context); - mLockPatternUtils = lockPatternUtils; - mUpdateMonitor = updateMonitor; - mCallback = callback; - - final LayoutInflater inflater = LayoutInflater.from(context); - inflater.inflate(R.layout.keyguard_screen_lock, this, true); - - mSimOk = isSimOk(updateMonitor.getSimState()); - mShowingBatteryInfo = updateMonitor.shouldShowBatteryInfo(); - mPluggedIn = updateMonitor.isDevicePluggedIn(); - mBatteryLevel = updateMonitor.getBatteryLevel(); - - mHeaderSimOk1 = (TextView) findViewById(R.id.headerSimOk1); - mHeaderSimOk2 = (TextView) findViewById(R.id.headerSimOk2); - - mHeaderSimBad1 = (TextView) findViewById(R.id.headerSimBad1); - mHeaderSimBad2 = (TextView) findViewById(R.id.headerSimBad2); - - mTime = (TextView) findViewById(R.id.time); - mDate = (TextView) findViewById(R.id.date); - - mBatteryInfoGroup = (ViewGroup) findViewById(R.id.batteryInfo); - mBatteryInfoIcon = (ImageView) findViewById(R.id.batteryInfoIcon); - mBatteryInfoText = (TextView) findViewById(R.id.batteryInfoText); - mBatteryInfoSpacer = findViewById(R.id.batteryInfoSpacer); - - mNextAlarmGroup = (ViewGroup) findViewById(R.id.nextAlarmInfo); - mAlarmText = (TextView) findViewById(R.id.nextAlarmText); - mAlarmSpacer = findViewById(R.id.nextAlarmSpacer); - - mScreenLockedMessageGroup = (ViewGroup) findViewById(R.id.screenLockedInfo); - - mLockInstructions = (TextView) findViewById(R.id.lockInstructions); - - mEmergencyCallButton = (Button) findViewById(R.id.emergencyCallButton); - - mEmergencyCallButton.setOnClickListener(new View.OnClickListener() { - public void onClick(View v) { - mCallback.takeEmergencyCallAction(); - } - }); - - mOnlyVisibleWhenSimOk = new View[] { - mHeaderSimOk1, - mHeaderSimOk2, - mBatteryInfoGroup, - mBatteryInfoSpacer, - mNextAlarmGroup, - mAlarmSpacer, - mScreenLockedMessageGroup, - mLockInstructions - }; - - mOnlyVisibleWhenSimNotOk = new View[] { - mHeaderSimBad1, - mHeaderSimBad2, - mEmergencyCallButton - }; - - setFocusable(true); - setFocusableInTouchMode(true); - setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS); - - refreshBatteryDisplay(); - refreshAlarmDisplay(); - refreshTimeAndDateDisplay(); - refreshUnlockIntructions(); - refreshViewsWRTSimOk(); - refreshSimOkHeaders(mUpdateMonitor.getTelephonyPlmn(), mUpdateMonitor.getTelephonySpn()); - - updateMonitor.registerInfoCallback(this); - updateMonitor.registerSimStateCallback(this); - updateMonitor.registerConfigurationChangeCallback(this); - } - - - @Override - public boolean onKeyDown(int keyCode, KeyEvent event) { - if (keyCode == KeyEvent.KEYCODE_MENU) { - mCallback.goToUnlockScreen(); - } - return false; - } - - private void refreshViewsWRTSimOk() { - if (mSimOk) { - for (int i = 0; i < mOnlyVisibleWhenSimOk.length; i++) { - final View view = mOnlyVisibleWhenSimOk[i]; - if (view == null) throw new RuntimeException("index " + i + " null"); - view.setVisibility(View.VISIBLE); - } - for (int i = 0; i < mOnlyVisibleWhenSimNotOk.length; i++) { - final View view = mOnlyVisibleWhenSimNotOk[i]; - view.setVisibility(View.GONE); - } - refreshSimOkHeaders(mUpdateMonitor.getTelephonyPlmn(), mUpdateMonitor.getTelephonySpn()); - refreshAlarmDisplay(); - refreshBatteryDisplay(); - } else { - for (int i = 0; i < mOnlyVisibleWhenSimOk.length; i++) { - final View view = mOnlyVisibleWhenSimOk[i]; - view.setVisibility(View.GONE); - } - for (int i = 0; i < mOnlyVisibleWhenSimNotOk.length; i++) { - final View view = mOnlyVisibleWhenSimNotOk[i]; - view.setVisibility(View.VISIBLE); - } - refreshSimBadInfo(); - } - } - - private void refreshSimBadInfo() { - final SimCard.State simState = mUpdateMonitor.getSimState(); - if (simState == SimCard.State.PUK_REQUIRED) { - mHeaderSimBad1.setText(R.string.lockscreen_sim_puk_locked_message); - mHeaderSimBad2.setText(R.string.lockscreen_sim_puk_locked_instructions); - } else if (simState == SimCard.State.ABSENT) { - mHeaderSimBad1.setText(R.string.lockscreen_missing_sim_message); - mHeaderSimBad2.setVisibility(View.GONE); - //mHeaderSimBad2.setText(R.string.lockscreen_missing_sim_instructions); - } else { - mHeaderSimBad1.setVisibility(View.GONE); - mHeaderSimBad2.setVisibility(View.GONE); - } - } - - private void refreshUnlockIntructions() { - if (mLockPatternUtils.isLockPatternEnabled() - || mUpdateMonitor.getSimState() == SimCard.State.PIN_REQUIRED) { - mLockInstructions.setText(R.string.lockscreen_instructions_when_pattern_enabled); - } else { - mLockInstructions.setText(R.string.lockscreen_instructions_when_pattern_disabled); - } - } - - private void refreshAlarmDisplay() { - String nextAlarmText = mLockPatternUtils.getNextAlarm(); - if (nextAlarmText != null && mSimOk) { - setAlarmInfoVisible(true); - mAlarmText.setText(nextAlarmText); - } else { - setAlarmInfoVisible(false); - } - } - - private void setAlarmInfoVisible(boolean visible) { - final int visibilityFlag = visible ? View.VISIBLE : View.GONE; - mNextAlarmGroup.setVisibility(visibilityFlag); - mAlarmSpacer.setVisibility(visibilityFlag); - } - - - public void onRefreshBatteryInfo(boolean showBatteryInfo, boolean pluggedIn, - int batteryLevel) { - mShowingBatteryInfo = showBatteryInfo; - mPluggedIn = pluggedIn; - mBatteryLevel = batteryLevel; - - refreshBatteryDisplay(); - } - - private void refreshBatteryDisplay() { - if (!mShowingBatteryInfo || !mSimOk) { - mBatteryInfoGroup.setVisibility(View.GONE); - mBatteryInfoSpacer.setVisibility(View.GONE); - return; - } - mBatteryInfoGroup.setVisibility(View.VISIBLE); - mBatteryInfoSpacer.setVisibility(View.VISIBLE); - - if (mPluggedIn) { - mBatteryInfoIcon.setImageResource(R.drawable.ic_lock_idle_charging); - mBatteryInfoText.setText( - getContext().getString(R.string.lockscreen_plugged_in, mBatteryLevel)); - } else { - mBatteryInfoIcon.setImageResource(R.drawable.ic_lock_idle_low_battery); - mBatteryInfoText.setText(R.string.lockscreen_low_battery); - } - } - - public void onTimeChanged() { - refreshTimeAndDateDisplay(); - } - - private void refreshTimeAndDateDisplay() { - Date now = new Date(); - mTime.setText(DateFormat.getTimeFormat(getContext()).format(now)); - mDate.setText(DateFormat.getDateFormat(getContext()).format(now)); - } - - public void onRefreshCarrierInfo(CharSequence plmn, CharSequence spn) { - refreshSimOkHeaders(plmn, spn); - } - - private void refreshSimOkHeaders(CharSequence plmn, CharSequence spn) { - final SimCard.State simState = mUpdateMonitor.getSimState(); - if (simState == SimCard.State.READY) { - if (plmn != null) { - mHeaderSimOk1.setVisibility(View.VISIBLE); - mHeaderSimOk1.setText(plmn); - } else { - mHeaderSimOk1.setVisibility(View.GONE); - } - - if (spn != null) { - mHeaderSimOk2.setVisibility(View.VISIBLE); - mHeaderSimOk2.setText(spn); - } else { - mHeaderSimOk2.setVisibility(View.GONE); - } - } else if (simState == SimCard.State.PIN_REQUIRED) { - mHeaderSimOk1.setVisibility(View.VISIBLE); - mHeaderSimOk1.setText(R.string.lockscreen_sim_locked_message); - mHeaderSimOk2.setVisibility(View.GONE); - } else if (simState == SimCard.State.ABSENT) { - mHeaderSimOk1.setVisibility(View.VISIBLE); - mHeaderSimOk1.setText(R.string.lockscreen_missing_sim_message_short); - mHeaderSimOk2.setVisibility(View.GONE); - } else if (simState == SimCard.State.NETWORK_LOCKED) { - mHeaderSimOk1.setVisibility(View.VISIBLE); - mHeaderSimOk1.setText(R.string.lockscreen_network_locked_message); - mHeaderSimOk2.setVisibility(View.GONE); - } - } - - public void onSimStateChanged(SimCard.State simState) { - mSimOk = isSimOk(simState); - refreshViewsWRTSimOk(); - } - - /** - * @return Whether the sim state is ok, meaning we don't need to show - * a special screen with the emergency call button and keep them from - * doing anything else. - */ - private boolean isSimOk(SimCard.State simState) { - boolean missingAndNotProvisioned = (!mUpdateMonitor.isDeviceProvisioned() - && simState == SimCard.State.ABSENT); - return !(missingAndNotProvisioned || simState == SimCard.State.PUK_REQUIRED); - } - - public void onOrientationChange(boolean inPortrait) { - } - - public void onKeyboardChange(boolean isKeyboardOpen) { - if (isKeyboardOpen) { - mCallback.goToUnlockScreen(); - } - } - - - /** {@inheritDoc} */ - public boolean needsInput() { - return false; - } - - /** {@inheritDoc} */ - public void onPause() { - - } - - /** {@inheritDoc} */ - public void onResume() { - - } - - /** {@inheritDoc} */ - public void cleanUp() { - mUpdateMonitor.removeCallback(this); - } -} 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 9fa59e4..0000000 --- a/policy/com/android/internal/policy/impl/PhoneWindow.java +++ /dev/null @@ -1,2656 +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 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.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.Paint; -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.Handler; -import android.os.Message; -import android.os.Parcel; -import android.os.Parcelable; -import android.os.SystemClock; -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.View; -import android.view.ViewConfiguration; -import android.view.ViewGroup; -import static android.view.ViewGroup.LayoutParams.FILL_PARENT; -import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; -import android.view.ViewManager; -import android.view.VolumePanel; -import android.view.Window; -import android.view.WindowManager; -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 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; - - 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 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 boolean mSearchKeyDownReceived; - - private boolean mKeycodeCallTimeoutActive = false; - - private boolean mKeycodeCameraTimeoutActive = false; - - static final int MSG_MENU_LONG_PRESS = 1; - static final int MSG_CALL_LONG_PRESS = 2; - static final int MSG_CAMERA_LONG_PRESS = 3; - - private final Handler mKeycodeMenuTimeoutHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case MSG_MENU_LONG_PRESS: { - if (mPanelChordingKey == 0) return; - mPanelChordingKey = 0; - mDecor.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); - InputMethodManager imm = (InputMethodManager) - getContext().getSystemService(Context.INPUT_METHOD_SERVICE); - if (imm != null) { - imm.showSoftInputUnchecked(InputMethodManager.SHOW_FORCED); - } - } break; - case MSG_CALL_LONG_PRESS: { - if (!mKeycodeCallTimeoutActive) return; - mKeycodeCallTimeoutActive = false; - 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(); - } - } break; - case MSG_CAMERA_LONG_PRESS: { - if (!mKeycodeCameraTimeoutActive) return; - mKeycodeCameraTimeoutActive = false; - mDecor.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); - // Broadcast an intent that the Camera button was longpressed - Intent intent = new Intent(Intent.ACTION_CAMERA_BUTTON, null); - intent.putExtra(Intent.EXTRA_KEY_EVENT, (KeyEvent) msg.obj); - getContext().sendOrderedBroadcast(intent, null); - } break; - } - } - }; - - 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"); - } - /* FEATURE_OPENGL disabled for 1.0 - 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(FILL_PARENT, FILL_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 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.FILL_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_PANEL, - 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) { - // The panel key was pushed, so set the chording key - mPanelChordingKey = event.getKeyCode(); - - PanelFeatureState st = getPanelState(featureId, true); - if (!st.isOpen) { - if (getContext().getResources().getConfiguration().keyboard - == Configuration.KEYBOARD_NOKEYS) { - mKeycodeMenuTimeoutHandler.removeMessages(MSG_MENU_LONG_PRESS); - mKeycodeMenuTimeoutHandler.sendMessageDelayed( - mKeycodeMenuTimeoutHandler.obtainMessage(MSG_MENU_LONG_PRESS), - ViewConfiguration.getLongPressTimeout()); - } - return preparePanel(st, event); - } - - 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; - mKeycodeMenuTimeoutHandler.removeMessages(MSG_MENU_LONG_PRESS); - - 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; - 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) { - 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_MUTE: - case KeyEvent.KEYCODE_HEADSETHOOK: - case KeyEvent.KEYCODE_PLAYPAUSE: - case KeyEvent.KEYCODE_STOP: - case KeyEvent.KEYCODE_NEXTSONG: - case KeyEvent.KEYCODE_PREVIOUSSONG: - case KeyEvent.KEYCODE_REWIND: - case KeyEvent.KEYCODE_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.getRepeatCount() > 0) break; - mKeycodeCameraTimeoutActive = true; - mKeycodeMenuTimeoutHandler.removeMessages(MSG_CAMERA_LONG_PRESS); - Message message = mKeycodeMenuTimeoutHandler.obtainMessage(MSG_CAMERA_LONG_PRESS); - message.obj = event; - mKeycodeMenuTimeoutHandler.sendMessageDelayed(message, - ViewConfiguration.getLongPressTimeout()); - return true; - } - - case KeyEvent.KEYCODE_MENU: { - if (event.getRepeatCount() > 0) break; - onKeyDownPanel((featureId < 0) ? FEATURE_OPTIONS_PANEL : featureId, event); - return true; - } - - case KeyEvent.KEYCODE_BACK: { - if (event.getRepeatCount() > 0) break; - if (featureId < 0) break; - 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; - } - - case KeyEvent.KEYCODE_CALL: { - if (getKeyguardManager().inKeyguardRestrictedInputMode()) { - break; - } - if (event.getRepeatCount() > 0) break; - mKeycodeCallTimeoutActive = true; - mKeycodeMenuTimeoutHandler.removeMessages(MSG_CALL_LONG_PRESS); - mKeycodeMenuTimeoutHandler.sendMessageDelayed( - mKeycodeMenuTimeoutHandler.obtainMessage(MSG_CALL_LONG_PRESS), - ViewConfiguration.getLongPressTimeout()); - return true; - } - - case KeyEvent.KEYCODE_SEARCH: { - if (event.getRepeatCount() == 0) { - mSearchKeyDownReceived = true; - } - 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; - } - - /** - * 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) { - 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_HEADSETHOOK: - case KeyEvent.KEYCODE_PLAYPAUSE: - case KeyEvent.KEYCODE_STOP: - case KeyEvent.KEYCODE_NEXTSONG: - case KeyEvent.KEYCODE_PREVIOUSSONG: - case KeyEvent.KEYCODE_REWIND: - case KeyEvent.KEYCODE_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.getRepeatCount() > 0) break; // Can a key up event repeat? - mKeycodeMenuTimeoutHandler.removeMessages(MSG_CAMERA_LONG_PRESS); - if (!mKeycodeCameraTimeoutActive) break; - mKeycodeCameraTimeoutActive = false; - // Add short press behavior here if desired - return true; - } - - case KeyEvent.KEYCODE_CALL: { - if (getKeyguardManager().inKeyguardRestrictedInputMode()) { - break; - } - if (event.getRepeatCount() > 0) break; - mKeycodeMenuTimeoutHandler.removeMessages(MSG_CALL_LONG_PRESS); - if (!mKeycodeCallTimeoutActive) break; - mKeycodeCallTimeoutActive = false; - 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() || - !mSearchKeyDownReceived) { - break; - } - mSearchKeyDownReceived = false; - 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]; - if ((st != null) && st.isOpen) { - // Clear st.isOpen (openPanel will not open if it's already open) - st.isOpen = false; - openPanel(st, null); - } - } - } - - private final class DecorView extends FrameLayout { - /* 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 final Paint mBlackPaint = new Paint(); - - private boolean mChanging; - - private Drawable mMenuBackground; - private boolean mWatchingForMenu; - private int mDownY; - - public DecorView(Context context, int featureId) { - super(context); - mFeatureId = featureId; - mBlackPaint.setColor(0xFF000000); - } - - @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 - 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.FILL_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); - - // no KEYCODE_CALL events active across focus changes - mKeycodeMenuTimeoutHandler.removeMessages(MSG_MENU_LONG_PRESS); - mKeycodeMenuTimeoutHandler.removeMessages(MSG_CALL_LONG_PRESS); - mKeycodeMenuTimeoutHandler.removeMessages(MSG_CAMERA_LONG_PRESS); - mKeycodeCallTimeoutActive = false; - mKeycodeCameraTimeoutActive = 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(); - - 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(); - } - } - } - - 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())); - } - - 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(FILL_PARENT, FILL_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.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 { - 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; - - /** - * 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; - isOpen = savedState.isOpen; - isInExpandedMode = 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 100644 index 0fa8ff5..0000000 --- a/policy/com/android/internal/policy/impl/PhoneWindowManager.java +++ /dev/null @@ -1,1800 +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.IStatusBar; -import android.content.BroadcastReceiver; -import android.content.ContentQueryMap; -import android.content.ContentResolver; -import android.content.Context; -import android.content.Intent; -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.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.telephony.ITelephony; -import android.util.Config; -import android.util.EventLog; -import android.util.Log; -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.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_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_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 android.view.WindowManagerImpl; -import android.view.WindowManagerPolicy; -import android.view.WindowManagerPolicy.WindowState; -import android.media.IAudioService; -import android.media.AudioManager; - -/** - * WindowManagerPolicy implementation for the Android phone UI. - */ -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 SHOW_STARTING_ANIMATIONS = true; - static final boolean SHOW_PROCESSES_ON_ALT_MENU = false; - - static final int APPLICATION_LAYER = 1; - static final int PHONE_LAYER = 2; - static final int SEARCH_BAR_LAYER = 3; - static final int STATUS_BAR_PANEL_LAYER = 4; - // toasts and the plugged-in battery thing - static final int TOAST_LAYER = 5; - static final int STATUS_BAR_LAYER = 6; - // SIM errors and unlock. Not sure if this really should be in a high layer. - static final int PRIORITY_PHONE_LAYER = 7; - // like the ANR / app crashed dialogs - static final int SYSTEM_ALERT_LAYER = 8; - // system-level error dialogs - static final int SYSTEM_ERROR_LAYER = 9; - // on-screen keyboards and other such input method user interfaces go here. - static final int INPUT_METHOD_LAYER = 10; - // on-screen keyboards and other such input method user interfaces go here. - static final int INPUT_METHOD_DIALOG_LAYER = 11; - // the keyguard; nothing on top of these can take focus, since they are - // responsible for power management when displayed. - static final int KEYGUARD_LAYER = 12; - static final int KEYGUARD_DIALOG_LAYER = 13; - // things in here CAN NOT take focus, but are shown on top of everything else. - static final int SYSTEM_OVERLAY_LAYER = 14; - - static final int APPLICATION_PANEL_SUBLAYER = 1; - static final int APPLICATION_MEDIA_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"; - - // Vibrator pattern for haptic feedback of a long press. - private static final long[] LONG_PRESS_VIBE_PATTERN = {0, 1, 40, 41}; - // Vibrator pattern for haptic feedback of a zoom ring tick - private static final long[] ZOOM_RING_TICK_VIBE_PATTERN = {0, 10}; - - Context mContext; - IWindowManager mWindowManager; - LocalPowerManager mPowerManager; - Vibrator mVibrator; // Vibrator for giving feedback of orientation changes - - /** If true, hitting shift & menu will broadcast Intent.ACTION_BUG_REPORT */ - boolean mEnableShiftMenuBugReports = false; - - boolean mSafeMode; - WindowState mStatusBar = null; - WindowState mSearchBar = null; - WindowState mKeyguard = null; - KeyguardViewMediator mKeyguardMediator; - GlobalActions mGlobalActions; - boolean mShouldTurnOffOnKeyUp; - RecentApplicationsDialog mRecentAppsDialog; - Handler mHandler; - - boolean mLidOpen; - int mSensorRotation = -1; - 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; - - // 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 mHomePressed; - Intent mHomeIntent; - boolean mSearchKeyPressed; - boolean mConsumeSearchKeyUp; - - static final int ENDCALL_HOME = 0x1; - static final int ENDCALL_SLEEPS = 0x2; - static final int DEFAULT_ENDCALL_BEHAVIOR = ENDCALL_SLEEPS; - int mEndcallBehavior; - - ShortcutManager mShortcutManager; - PowerManager.WakeLock mBroadcastWakeLock; - - class SettingsObserver extends ContentObserver { - private ContentQueryMap mSettings; - - 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.System.getUriFor( - Settings.System.ACCELEROMETER_ROTATION), false, this); - resolver.registerContentObserver(Settings.Secure.getUriFor( - Settings.Secure.DEFAULT_INPUT_METHOD), false, this); - update(); - } - - @Override public void onChange(boolean selfChange) { - update(); - try { - mWindowManager.setRotation(USE_LAST_ROTATION, false); - } catch (RemoteException e) { - // Ignore - } - } - - public void update() { - ContentResolver resolver = mContext.getContentResolver(); - mEndcallBehavior = Settings.System.getInt(resolver, - Settings.System.END_BUTTON_BEHAVIOR, DEFAULT_ENDCALL_BEHAVIOR); - int accelerometerDefault = Settings.System.getInt(resolver, - Settings.System.ACCELEROMETER_ROTATION, DEFAULT_ACCELEROMETER_ROTATION); - if (mAccelerometerDefault != accelerometerDefault) { - mAccelerometerDefault = accelerometerDefault; - updateOrientationListener(); - } - String imId = Settings.Secure.getString(resolver, - Settings.Secure.DEFAULT_INPUT_METHOD); - boolean hasSoftInput = imId != null && imId.length() > 0; - if (mHasSoftInput != hasSoftInput) { - mHasSoftInput = hasSoftInput; - updateRotation(); - } - } - } - - class MyOrientationListener extends WindowOrientationListener { - private static final int _LOWER_THRESHOLD = 30; - private static final int _UPPER_THRESHOLD = 60; - - MyOrientationListener(Context context) { - super(context); - } - - @Override - public void onOrientationChanged(int orientation) { - // ignore orientation changes unless the value is in a range - // When switching from portrait to landscape try to use a lower threshold limit - // Use upper threshold limit when switching from landscape to portrait - // this is to delay the switch as much as we can - int rotation; - int threshold = (mSensorRotation == Surface.ROTATION_90) ? _UPPER_THRESHOLD : - _LOWER_THRESHOLD; - - if ((orientation >= 0 && orientation <= _UPPER_THRESHOLD) || - (orientation >= 270 - _LOWER_THRESHOLD)) { - rotation = (orientation >= 270 - _LOWER_THRESHOLD - && orientation <= 270 + threshold) - ? Surface.ROTATION_90 : Surface.ROTATION_0; - } else if (orientation == WindowOrientationListener.ORIENTATION_FLAT) { - // return portrait - rotation = Surface.ROTATION_0; - } else { - // ignore orientation value - return; - } - // Send updates based on orientation value - if (rotation != mSensorRotation) { - if(localLOGV) Log.i(TAG, "onOrientationChanged, rotation changed from "+rotation+" to "+mSensorRotation); - // Update window manager. The lid rotation hasn't changed, - // but we want it to re-evaluate the final rotation in case - // it needs to call back and get the sensor orientation. - mSensorRotation = rotation; - try { - mWindowManager.setRotation(rotation, false); - } catch (RemoteException e) { - // Ignore - } - } - } - } - MyOrientationListener mOrientationListener; - - boolean useSensorForOrientation() { - if(mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR) { - return true; - } - if (mAccelerometerDefault != 0 && ( - mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_USER || - mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED)) { - return true; - } - return false; - } - - boolean needSensorRunning() { - 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 (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 true; - } - return false; - } - - /* - * 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 updateOrientationListener() { - 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.i(TAG, "Screen status="+mScreenOn+ - ", current orientation="+mCurrentAppOrientation+ - ", SensorEnabled="+mOrientationSensorEnabled); - boolean disable = true; - if(mScreenOn) { - if(needSensorRunning()) { - disable = false; - //enable listener if not already enabled - if(!mOrientationSensorEnabled) { - mOrientationListener.enable(); - if(localLOGV) Log.i(TAG, "Enabling listeners"); - // We haven't had the sensor on, so don't yet know - // the rotation. - mSensorRotation = -1; - mOrientationSensorEnabled = true; - } - } - } - //check if sensors need to be disabled - if(disable && mOrientationSensorEnabled) { - mOrientationListener.disable(); - if(localLOGV) Log.i(TAG, "Disabling listeners"); - mSensorRotation = -1; - mOrientationSensorEnabled = false; - } - } - - Runnable mEndCallLongPress = new Runnable() { - public void run() { - mShouldTurnOffOnKeyUp = false; - performHapticFeedback(null, HapticFeedbackConstants.LONG_PRESS, false); - sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS); - showGlobalActionsDialog(); - } - }; - - void showGlobalActionsDialog() { - if (mGlobalActions == null) { - mGlobalActions = new GlobalActions(mContext, mPowerManager); - } - final boolean keyguardShowing = mKeyguardMediator.isShowing(); - 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; - performHapticFeedback(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); - PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE); - mBroadcastWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, - "PhoneWindowManager.mBroadcastWakeLock"); - mEnableShiftMenuBugReports = "1".equals(SystemProperties.get("ro.debuggable")); - } - - /** {@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: - // The window manager will check this. - 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(0); - if (sw >= 0) { - mLidOpen = sw == 0; - } - } catch (RemoteException e) { - // Ignore - } - } - - /** {@inheritDoc} */ - public void adjustConfigurationLw(Configuration config) { - readLidState(); - final boolean lidOpen = !KEYBOARD_ALWAYS_HIDDEN && mLidOpen; - mPowerManager.setKeyboardVisibility(lidOpen); - config.keyboardHidden = (lidOpen || mHasSoftInput) - ? Configuration.KEYBOARDHIDDEN_NO - : Configuration.KEYBOARDHIDDEN_YES; - config.hardKeyboardHidden = lidOpen - ? 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; - } - - /** {@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_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; - } - 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_SUB_PANEL: - return APPLICATION_SUB_PANEL_SUBLAYER; - } - Log.e(TAG, "Unknown sub-window type: " + type); - return 0; - } - - /** {@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; - } - - 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.FILL_PARENT, - WindowManager.LayoutParams.FILL_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); - - try { - 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"); - } - - 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>SEARCH_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: - if (mStatusBar != null) { - return WindowManagerImpl.ADD_MULTIPLE_SINGLETON; - } - mStatusBar = win; - break; - case TYPE_SEARCH_BAR: - if (mSearchBar != null) { - return WindowManagerImpl.ADD_MULTIPLE_SINGLETON; - } - mSearchBar = 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 (mSearchBar == win) { - mSearchBar = null; - } - else if (mKeyguard == win) { - mKeyguard = null; - } - } - - 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; - } - - 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) { - 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 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(); - } - } - } - - 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_NOTIFICATION) { - if (down) { - // this key doesn't exist on current hardware, but if a device - // didn't have a touchscreen, it would want one of these to open - // the status bar. - IStatusBar sbs = IStatusBar.Stub.asInterface(ServiceManager.getService("statusbar")); - if (sbs != null) { - try { - sbs.toggle(); - } catch (RemoteException e) { - // we're screwed anyway, since it's in this process - throw new RuntimeException(e); - } - } - } - 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.isShowing()) { - // don't launch home if keyguard showing - } else if (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) { - mContext.startActivity(mHomeIntent); - sendCloseSystemWindows(); - } - } - }); - } else { - // no keyguard stuff to worry about, just launch home! - mContext.startActivity(mHomeIntent); - sendCloseSystemWindows(); - } - } - - 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; - } - } - } - - 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 (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 + - ": 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; - } - } - } - - /** {@inheritDoc} */ - public void finishLayoutLw() { - } - - /** {@inheritDoc} */ - public void beginAnimationLw(int displayWidth, int displayHeight) { - mTopFullscreenOpaqueWindowState = null; - mForceStatusBar = false; - } - - /** {@inheritDoc} */ - public void animatingWindowLw(WindowState win, - WindowManager.LayoutParams attrs) { - if (win.isVisibleLw()) { - if ((attrs.flags & FLAG_FORCE_NOT_FULLSCREEN) != 0) { - mForceStatusBar = true; - } else if (mTopFullscreenOpaqueWindowState == null - && attrs.type >= FIRST_APPLICATION_WINDOW - && attrs.type <= LAST_APPLICATION_WINDOW - && win.fillsScreenLw(mW, mH, true, false) - && win.isVisibleLw()) { - mTopFullscreenOpaqueWindowState = win; - } - } - } - - /** {@inheritDoc} */ - public boolean finishAnimationLw() { - boolean changed = false; - if (mStatusBar != null) { - //Log.i(TAG, "force=" + mForceStatusBar - // + " top=" + mTopFullscreenOpaqueWindowState); - if (mForceStatusBar) { - changed |= mStatusBar.showLw(true); - } 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) { - changed |= mStatusBar.hideLw(true); - } else { - changed |= mStatusBar.showLw(true); - } - } - } - return changed; - } - - /** {@inheritDoc} */ - public boolean preprocessInputEventTq(RawInputEvent event) { - switch (event.type) { - case RawInputEvent.EV_SW: - if (event.keycode == 0) { - // lid changed state - mLidOpen = event.value == 0; - updateRotation(); - if (keyguardIsShowingTq()) { - if (mLidOpen) { - // only do this if it's opening -- closing the device shouldn't turn it - // off, but it also shouldn't turn it on. - mKeyguardMediator.pokeWakelock(); - } - } 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; - } - - - /** {@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 IAudioService audio = getAudioInterface(); - if (audio == null) { - Log.w(TAG, "isMusicActive: couldn't get IAudioService reference"); - return false; - } - try { - return audio.isMusicActive(); - } catch (RemoteException e) { - Log.w(TAG, "IAudioService.isMusicActive() threw RemoteException " + e); - return false; - } - } - - /** - * Tell the audio service to adjust the volume appropriate to the event. - * @param keycode - */ - void sendVolToMusic(int keycode) { - final IAudioService audio = getAudioInterface(); - if (audio == null) { - Log.w(TAG, "sendVolToMusic: 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( - AudioManager.STREAM_MUSIC, - 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_PLAYPAUSE || - code == KeyEvent.KEYCODE_STOP || - code == KeyEvent.KEYCODE_NEXTSONG || - code == KeyEvent.KEYCODE_PREVIOUSSONG || - code == KeyEvent.KEYCODE_PREVIOUSSONG || - code == KeyEvent.KEYCODE_FORWARD) { - return true; - } - return false; - } - - /** {@inheritDoc} */ - public int interceptKeyTq(RawInputEvent event, boolean screenIsOn) { - int result = ACTION_PASS_TO_USER; - final boolean isWakeKey = isWakeKeyTq(event); - final boolean keyguardShowing = keyguardIsShowingTq(); - - if (false) { - Log.d(TAG, "interceptKeyTq event=" + event + " keycode=" + event.keycode - + " screenIsOn=" + screenIsOn + " keyguardShowing=" + keyguardShowing); - } - - if (keyguardShowing) { - 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)) { - if (isInCall()) { - // if the keyguard didn't wake the device, we are in call, and - // it is a volume key, turn on the screen so that the user - // can more easily adjust the in call volume. - mKeyguardMediator.pokeWakelock(); - } else if (isMusicActive()) { - // when keyguard is showing and screen off, we need - // to handle the volume key for music here - sendVolToMusic(event.keycode); - } - } - } - } - } else if (!screenIsOn) { - 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) { - if (down) { - 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. - try { - ITelephony phoneServ = getPhoneInterface(); - if (phoneServ != null) { - hungUp = phoneServ.endCall(); - } else { - Log.w(TAG, "!!! Unable to find ITelephony interface !!!"); - } - } catch (RemoteException ex) { - Log.w(TAG, "ITelephony.endCall() threw RemoteException" + ex); - } - if (hungUp || !screenIsOn) { - mShouldTurnOffOnKeyUp = false; - } else { - // only try to turn off the screen if we didn't already hang up - mShouldTurnOffOnKeyUp = true; - mHandler.postDelayed(mEndCallLongPress, - ViewConfiguration.getGlobalActionKeyTimeout()); - result &= ~ACTION_PASS_TO_USER; - } - } else { - mHandler.removeCallbacks(mEndCallLongPress); - if (mShouldTurnOffOnKeyUp) { - mShouldTurnOffOnKeyUp = false; - boolean gohome = (mEndcallBehavior & ENDCALL_HOME) != 0; - boolean sleeps = (mEndcallBehavior & ENDCALL_SLEEPS) != 0; - if (keyguardShowing - || (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(); - } - }; - - /** {@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); - mScreenOn = false; - updateOrientationListener(); - } - - /** {@inheritDoc} */ - public void screenTurnedOn() { - EventLog.writeEvent(70000, 1); - mKeyguardMediator.onScreenTurnedOn(); - mScreenOn = true; - updateOrientationListener(); - } - - /** {@inheritDoc} */ - public void enableKeyguard(boolean enabled) { - mKeyguardMediator.setKeyguardEnabled(enabled); - } - - /** {@inheritDoc} */ - public void exitKeyguardSecurely(OnKeyguardExitResult callback) { - mKeyguardMediator.verifyUnlock(callback); - } - - /** {@inheritDoc} */ - public boolean keyguardIsShowingTq() { - return mKeyguardMediator.isShowing(); - } - - /** {@inheritDoc} */ - public boolean inKeyguardRestrictedKeyInputMode() { - return mKeyguardMediator.isInputRestricted(); - } - - /** - * Callback from {@link KeyguardViewMediator} - */ - public void onKeyguardShow() { - sendCloseSystemWindows(); - } - - void sendCloseSystemWindows() { - sendCloseSystemWindows(mContext, null); - } - - void sendCloseSystemWindows(String reason) { - sendCloseSystemWindows(mContext, reason); - } - - static void sendCloseSystemWindows(Context context, String reason) { - if (ActivityManagerNative.isSystemReady()) { - Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); - if (reason != null) { - intent.putExtra(SYSTEM_DIALOG_REASON_KEY, reason); - } - context.sendBroadcast(intent); - } - } - - public int rotationForOrientation(int orientation, int lastRotation, - boolean displayEnabled) { - switch (orientation) { - case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE: - //always return landscape if orientation set to landscape - return Surface.ROTATION_90; - case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT: - //always return portrait if orientation set to portrait - return Surface.ROTATION_0; - } - // case for nosensor meaning ignore sensor and consider only lid - // or orientation sensor disabled - //or case.unspecified - if (mLidOpen) { - return Surface.ROTATION_90; - } else { - if (useSensorForOrientation()) { - // If the user has enabled auto rotation by default, do it. - return mSensorRotation >= 0 ? mSensorRotation : lastRotation; - } - return Surface.ROTATION_0; - } - } - - public boolean detectSafeMode() { - try { - int menuState = mWindowManager.getKeycodeState(KeyEvent.KEYCODE_MENU); - mSafeMode = menuState > 0; - Log.i(TAG, "Menu key state: " + menuState + " safeMode=" + mSafeMode); - return mSafeMode; - } catch (RemoteException e) { - // Doom! (it's also local) - throw new RuntimeException("window manager dead"); - } - } - - /** {@inheritDoc} */ - public void systemReady() { - try { - if (mSafeMode) { - // If the user is holding the menu key code, then we are - // going to boot into safe mode. - ActivityManagerNative.getDefault().enterSafeMode(); - } - // tell the keyguard - mKeyguardMediator.onSystemReady(); - android.os.SystemProperties.set("dev.bootcomplete", "1"); - updateOrientationListener(); - mVibrator = new Vibrator(); - } catch (RemoteException e) { - // Ignore - } - } - - - /** {@inheritDoc} */ - public void enableScreenAfterBoot() { - readLidState(); - updateRotation(); - } - - void updateRotation() { - mPowerManager.setKeyboardVisibility(mLidOpen); - int rotation= Surface.ROTATION_0; - if (mLidOpen) { - // always use landscape if lid is open - rotation = Surface.ROTATION_90; - } - //if lid is closed orientation will be portrait - try { - //set orientation on WindowManager - mWindowManager.setRotation(rotation, true); - } catch (RemoteException e) { - // Ignore - } - } - - /** - * goes to the home screen - * @return whether it did anything - */ - boolean goHome() { - if (false) { - // This code always brings home to the front. - mContext.startActivity(mHomeIntent); - } else { - // This code brings home to the front or, if it is already - // at the front, puts the device to sleep. - try { - 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 - } - } - sendCloseSystemWindows(); - return true; - } - - public void setCurrentOrientation(int newOrientation) { - if(newOrientation != mCurrentAppOrientation) { - mCurrentAppOrientation = newOrientation; - updateOrientationListener(); - } - } - - public boolean performHapticFeedback(WindowState win, int effectId, boolean always) { - if (!always && Settings.System.getInt(mContext.getContentResolver(), - Settings.System.HAPTIC_FEEDBACK_ENABLED, 0) == 0) { - return false; - } - switch (effectId) { - case HapticFeedbackConstants.LONG_PRESS: - mVibrator.vibrate(LONG_PRESS_VIBE_PATTERN, -1); - return true; - case HapticFeedbackConstants.ZOOM_RING_TICK: - mVibrator.vibrate(ZOOM_RING_TICK_VIBE_PATTERN, -1); - } - return false; - } - - public void screenOnStopped() { - if (!mKeyguardMediator.isShowing()) { - long curTime = SystemClock.uptimeMillis(); - mPowerManager.userActivity(curTime, false, LocalPowerManager.OTHER_EVENT); - } - } -} 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 77c42ab..0000000 --- a/policy/com/android/internal/policy/impl/PowerDialog.java +++ /dev/null @@ -1,179 +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.IServiceManager; -import android.os.LocalPowerManager; -import android.os.ServiceManager; -import android.os.ServiceManagerNative; -import android.os.SystemClock; -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); - 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.shutdownAfterDisablingRadio(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/RecentApplicationsDialog.java b/policy/com/android/internal/policy/impl/RecentApplicationsDialog.java deleted file mode 100644 index 5442dd4..0000000 --- a/policy/com/android/internal/policy/impl/RecentApplicationsDialog.java +++ /dev/null @@ -1,255 +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.BroadcastReceiver; -import android.content.ComponentName; -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.pm.ResolveInfo; -import android.graphics.drawable.Drawable; -import android.os.Bundle; -import android.os.Handler; -import android.os.Message; -import android.view.View; -import android.view.Window; -import android.view.WindowManager; -import android.view.View.OnClickListener; -import android.widget.ImageView; -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 = 6; - private static final int MAX_RECENT_TASKS = NUM_BUTTONS * 2; // allow for some discards - - final View[] mButtons = new View[NUM_BUTTONS]; - View mNoAppsText; - IntentFilter mBroadcastIntentFilter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); - - public RecentApplicationsDialog(Context context) { - super(context); - } - - /** - * 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 theWindow = getWindow(); - theWindow.requestFeature(Window.FEATURE_NO_TITLE); - theWindow.setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG); - theWindow.setFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND, - WindowManager.LayoutParams.FLAG_BLUR_BEHIND); - theWindow.setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM, - WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); - - setContentView(com.android.internal.R.layout.recent_apps_dialog); - - mButtons[0] = findViewById(com.android.internal.R.id.button1); - mButtons[1] = findViewById(com.android.internal.R.id.button2); - mButtons[2] = findViewById(com.android.internal.R.id.button3); - mButtons[3] = findViewById(com.android.internal.R.id.button4); - mButtons[4] = findViewById(com.android.internal.R.id.button5); - mButtons[5] = findViewById(com.android.internal.R.id.button6); - mNoAppsText = findViewById(com.android.internal.R.id.no_applications_message); - - for (View b : mButtons) { - b.setOnClickListener(this); - } - } - - /** - * Handler for user clicks. If a button was clicked, launch the corresponding activity. - */ - public void onClick(View v) { - - for (View b : mButtons) { - if (b == v) { - // prepare a launch intent and send it - Intent intent = (Intent)b.getTag(); - intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); - getContext().startActivity(intent); - } - } - 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 (View b : mButtons) { - setButtonAppearance(b, null, null); - b.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, 0); - - ResolveInfo homeInfo = pm.resolveActivity( - new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME), - 0); - - // 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 button = 0; - int numTasks = recentTasks.size(); - for (int i = 0; i < numTasks && (button < 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.activityInfo.packageName.equals( - intent.getComponent().getPackageName()) - && homeInfo.activityInfo.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(); - final Drawable icon = activityInfo.loadIcon(pm); - - if (title != null && title.length() > 0 && icon != null) { - final View b = mButtons[button]; - setButtonAppearance(b, title, icon); - b.setTag(intent); - b.setVisibility(View.VISIBLE); - b.setPressed(false); - b.clearFocus(); - ++button; - } - } - } - - // handle the case of "no icons to show" - mNoAppsText.setVisibility((button == 0) ? View.VISIBLE : View.GONE); - - // hide the rest - for ( ; button < NUM_BUTTONS; ++button) { - mButtons[button].setVisibility(View.GONE); - } - } - - /** - * Adjust appearance of each icon-button - */ - private void setButtonAppearance(View theButton, final String theTitle, final Drawable icon) { - TextView tv = (TextView) theButton.findViewById(com.android.internal.R.id.label); - tv.setText(theTitle); - ImageView iv = (ImageView) theButton.findViewById(com.android.internal.R.id.icon); - iv.setImageDrawable(icon); - } - - /** - * 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). - * - * TODO: This is a really heavyweight solution for something that should be so simple. - * For example, we already have a handler, in our superclass, why aren't we sharing that? - * I think we need to investigate simplifying this entire methodology, or perhaps boosting - * it up into the Dialog class. - */ - 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/ShutdownThread.java b/policy/com/android/internal/policy/impl/ShutdownThread.java deleted file mode 100644 index 994b1d5..0000000 --- a/policy/com/android/internal/policy/impl/ShutdownThread.java +++ /dev/null @@ -1,138 +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.ProgressDialog; -import android.app.AlertDialog; -import android.content.Context; -import android.content.DialogInterface; -import android.os.RemoteException; -import android.os.Power; -import android.os.ServiceManager; -import android.os.SystemClock; -import com.android.internal.telephony.ITelephony; -import android.util.Log; -import android.view.WindowManager; - - -final class ShutdownThread extends Thread { - // constants - private static final String TAG = "ShutdownThread"; - private static final int MAX_NUM_PHONE_STATE_READS = 16; - private static final int PHONE_STATE_POLL_SLEEP_MSEC = 500; - private static final ITelephony sPhone = - ITelephony.Stub.asInterface(ServiceManager.checkService("phone")); - - // state tracking - private static Object sIsStartedGuard = new Object(); - private static boolean sIsStarted = false; - - // static instance of this thread - private static final ShutdownThread sInstance = new ShutdownThread(); - - private ShutdownThread() { - } - - /** - * request a shutdown. - * - * @param context Context used to display the shutdown progress dialog. - */ - public static void shutdownAfterDisablingRadio(final Context context, boolean confirm){ - // ensure that only one thread is trying to power down. - // any additional calls are just returned - synchronized (sIsStartedGuard){ - if (sIsStarted) { - Log.d(TAG, "Request to shutdown already running, returning."); - return; - } - } - - Log.d(TAG, "Notifying thread to start radio shutdown"); - - if (confirm) { - final AlertDialog dialog = new AlertDialog.Builder(context) - .setIcon(android.R.drawable.ic_dialog_alert) - .setTitle(com.android.internal.R.string.power_off) - .setMessage(com.android.internal.R.string.shutdown_confirm) - .setPositiveButton(com.android.internal.R.string.yes, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - beginShutdownSequence(context); - } - }) - .setNegativeButton(com.android.internal.R.string.no, null) - .create(); - dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG); - dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND); - dialog.show(); - } else { - beginShutdownSequence(context); - } - } - - private static void beginShutdownSequence(Context context) { - synchronized (sIsStartedGuard) { - sIsStarted = true; - } - - // throw up an indeterminate system dialog to indicate radio is - // shutting down. - ProgressDialog pd = new ProgressDialog(context); - pd.setTitle(context.getText(com.android.internal.R.string.power_off)); - pd.setMessage(context.getText(com.android.internal.R.string.shutdown_progress)); - pd.setIndeterminate(true); - pd.setCancelable(false); - pd.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG); - pd.getWindow().addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND); - - pd.show(); - - // start the thread that initiates shutdown - sInstance.start(); - } - - /** - * Makes sure we handle the shutdown gracefully. - * Shuts off power regardless of radio state if the alloted time has passed. - */ - public void run() { - //shutdown the phone radio if possible. - if (sPhone != null) { - try { - //shutdown radio - sPhone.setRadio(false); - - for (int i = 0; i < MAX_NUM_PHONE_STATE_READS; i++){ - // poll radio up to 64 times, with a 0.5 sec delay between each call, - // totaling 32 sec. - if (!sPhone.isRadioOn()) { - Log.d(TAG, "Radio shutdown complete."); - break; - } - SystemClock.sleep(PHONE_STATE_POLL_SLEEP_MSEC); - } - } catch (RemoteException ex) { - Log.e(TAG, "RemoteException caught from failed radio shutdown.", ex); - } - } - - //shutdown power - Log.d(TAG, "Shutting down power."); - Power.shutdown(); - } -} 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 9453212..0000000 --- a/policy/com/android/internal/policy/impl/SimUnlockScreen.java +++ /dev/null @@ -1,366 +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.os.RemoteException; -import android.os.ServiceManager; -import com.android.internal.telephony.ITelephony; -import android.text.Editable; -import android.view.KeyEvent; -import android.view.LayoutInflater; -import android.view.View; -import android.view.WindowManager; -import android.widget.EditText; -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.ConfigurationChangeCallback { - - private static final int DIGIT_PRESS_WAKE_MILLIS = 5000; - - private final KeyguardUpdateMonitor mUpdateMonitor; - private final KeyguardScreenCallback mCallback; - - private final boolean mCreatedWithKeyboardOpen; - - private TextView mHeaderText; - private EditText mPinText; - - private TextView mOkButton; - private TextView 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 static final char[] DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}; - - public SimUnlockScreen(Context context, KeyguardUpdateMonitor updateMonitor, - KeyguardScreenCallback callback) { - super(context); - mUpdateMonitor = updateMonitor; - mCallback = callback; - mCreatedWithKeyboardOpen = mUpdateMonitor.isKeyboardOpen(); - - if (mCreatedWithKeyboardOpen) { - LayoutInflater.from(context).inflate(R.layout.keyguard_screen_sim_pin_landscape, this, true); - } else { - LayoutInflater.from(context).inflate(R.layout.keyguard_screen_sim_pin_portrait, this, true); - new TouchInput(); - } - - mHeaderText = (TextView) findViewById(R.id.headerText); - mPinText = (EditText) findViewById(R.id.pinDisplay); - mBackSpaceButton = findViewById(R.id.backspace); - mBackSpaceButton.setOnClickListener(this); - - mEmergencyCallButton = (TextView) findViewById(R.id.emergencyCall); - mOkButton = (TextView) findViewById(R.id.ok); - - mHeaderText.setText(R.string.keyguard_password_enter_pin_code); - mPinText.setFocusable(false); - - mEmergencyCallButton.setOnClickListener(this); - mOkButton.setOnClickListener(this); - - mUpdateMonitor.registerConfigurationChangeCallback(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; - } - - /** {@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.getText(); - 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); - 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; - } - - public void onOrientationChange(boolean inPortrait) {} - - public void onKeyboardChange(boolean isKeyboardOpen) { - if (isKeyboardOpen != mCreatedWithKeyboardOpen) { - mCallback.recreateMe(); - } - } - - /** - * 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; - } - } -} diff --git a/policy/com/android/internal/policy/impl/UnlockScreen.java b/policy/com/android/internal/policy/impl/UnlockScreen.java deleted file mode 100644 index 51e3621..0000000 --- a/policy/com/android/internal/policy/impl/UnlockScreen.java +++ /dev/null @@ -1,341 +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.ServiceConnection; -import android.os.CountDownTimer; -import android.os.SystemClock; -import android.view.KeyEvent; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.view.MotionEvent; -import android.widget.Button; -import android.widget.ImageView; -import android.widget.TextView; -import com.android.internal.R; -import com.android.internal.widget.LinearLayoutWithDefaultTouchRecepient; -import com.android.internal.widget.LockPatternUtils; -import com.android.internal.widget.LockPatternView; - -import java.util.List; - -/** - * This is the screen that shows the 9 circle unlock widget and instructs - * the user how to unlock their device, or make an emergency call. - */ -class UnlockScreen extends LinearLayoutWithDefaultTouchRecepient - implements KeyguardScreen, KeyguardUpdateMonitor.ConfigurationChangeCallback { - - 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 once the user is ready to enter a pattern - private static final int UNLOCK_PATTERN_WAKE_INTERVAL_MS = 7000; - - private int mFailedPatternAttemptsSinceLastTimeout = 0; - private int mTotalFailedPatternAttempts = 0; - private CountDownTimer mCountdownTimer = null; - - private final LockPatternUtils mLockPatternUtils; - private final KeyguardUpdateMonitor mUpdateMonitor; - private final KeyguardScreenCallback mCallback; - - private boolean mCreatedInPortrait; - - private ImageView mUnlockIcon; - private TextView mUnlockHeader; - 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 ServiceConnection mServiceConnection; - - - 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); - break; - case VerifyUnlocked: - mFooterNormal.setVisibility(View.GONE); - mFooterForgotPattern.setVisibility(View.GONE); - } - } - - /** - * @param context The context. - * @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. - */ - UnlockScreen(Context context, - 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 (mUpdateMonitor.isInPortrait()) { - LayoutInflater.from(context).inflate(R.layout.keyguard_screen_unlock_portrait, this, true); - } else { - LayoutInflater.from(context).inflate(R.layout.keyguard_screen_unlock_landscape, this, true); - } - - mUnlockIcon = (ImageView) findViewById(R.id.unlockLockIcon); - - mLockPatternView = (LockPatternView) findViewById(R.id.lockPattern); - mUnlockHeader = (TextView) findViewById(R.id.headerText); - - mUnlockHeader.setText(R.string.lockscreen_pattern_instructions); - - 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(); - } - }; - Button emergencyAlone = (Button) findViewById(R.id.emergencyCallAlone); - emergencyAlone.setFocusable(false); // touch only! - emergencyAlone.setOnClickListener(emergencyClick); - Button emergencyTogether = (Button) findViewById(R.id.emergencyCallTogether); - emergencyTogether.setFocusable(false); - emergencyTogether.setOnClickListener(emergencyClick); - - mForgotPatternButton = (Button) findViewById(R.id.forgotPattern); - mForgotPatternButton.setText(R.string.lockscreen_forgot_pattern_button_text); - mForgotPatternButton.setOnClickListener(new OnClickListener() { - - public void onClick(View v) { - mLockPatternUtils.setPermanentlyLocked(true); - mCallback.goToUnlockScreen(); - } - }); - - // 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); - - mCreatedInPortrait = updateMonitor.isInPortrait(); - updateMonitor.registerConfigurationChangeCallback(this); - setFocusableInTouchMode(true); - } - - @Override - public boolean onKeyDown(int keyCode, KeyEvent event) { - if (keyCode == KeyEvent.KEYCODE_BACK) { - mCallback.goToLockScreen(); - return true; - } - return false; - } - - @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(); - mCallback.pokeWakelock(UNLOCK_PATTERN_WAKE_INTERVAL_MS); - } - return result; - } - - /** {@inheritDoc} */ - public void onOrientationChange(boolean inPortrait) { - if (inPortrait != mCreatedInPortrait) { - mCallback.recreateMe(); - } - } - - /** {@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 - mUnlockHeader.setText(R.string.lockscreen_pattern_instructions); - mUnlockIcon.setVisibility(View.VISIBLE); - - // 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 (mTotalFailedPatternAttempts < LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT) { - updateFooter(FooterMode.Normal); - } else { - updateFooter(FooterMode.ForgotLockPattern); - } - } - - /** {@inheritDoc} */ - public void cleanUp() { - mUpdateMonitor.removeCallback(this); - } - - private class UnlockPatternListener - implements LockPatternView.OnPatternListener { - - public void onPatternStart() { - mLockPatternView.removeCallbacks(mCancelPatternRunnable); - } - - public void onPatternCleared() { - } - - public void onPatternDetected(List<LockPatternView.Cell> pattern) { - if (mLockPatternUtils.checkPattern(pattern)) { - mLockPatternView - .setDisplayMode(LockPatternView.DisplayMode.Correct); - mUnlockIcon.setVisibility(View.GONE); - mUnlockHeader.setText(R.string.lockscreen_pattern_correct); - mCallback.keyguardDone(true); - } else { - mCallback.pokeWakelock(UNLOCK_PATTERN_WAKE_INTERVAL_MS); - mLockPatternView.setDisplayMode(LockPatternView.DisplayMode.Wrong); - if (pattern.size() >= LockPatternUtils.MIN_PATTERN_REGISTER_FAIL) { - mTotalFailedPatternAttempts++; - mFailedPatternAttemptsSinceLastTimeout++; - mCallback.reportFailedPatternAttempt(); - } - if (mFailedPatternAttemptsSinceLastTimeout >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT) { - long deadline = mLockPatternUtils.setLockoutAttemptDeadline(); - handleAttemptLockout(deadline); - return; - } - mUnlockIcon.setVisibility(View.VISIBLE); - mUnlockHeader.setText(R.string.lockscreen_pattern_wrong); - 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); - mUnlockHeader.setText(getContext().getString( - R.string.lockscreen_too_many_failed_attempts_countdown, - secondsRemaining)); - } - - @Override - public void onFinish() { - mLockPatternView.setEnabled(true); - mUnlockHeader.setText(R.string.lockscreen_pattern_instructions); - mUnlockIcon.setVisibility(View.VISIBLE); - mFailedPatternAttemptsSinceLastTimeout = 0; - updateFooter(FooterMode.ForgotLockPattern); - } - }.start(); - } - -} 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> |