diff --git a/policy/com/android/internal/policy/impl/KeyguardViewMediator.java b/policy/com/android/internal/policy/impl/KeyguardViewMediator.java index 682ea9f3102d5..adcd86b9a0223 100644 --- a/policy/com/android/internal/policy/impl/KeyguardViewMediator.java +++ b/policy/com/android/internal/policy/impl/KeyguardViewMediator.java @@ -104,7 +104,7 @@ public class KeyguardViewMediator implements KeyguardViewCallback, private static final int WAKE_WHEN_READY = 8; private static final int KEYGUARD_DONE = 9; private static final int KEYGUARD_DONE_DRAWING = 10; - private static final int HIDE_KEYGUARD = 11; + private static final int KEYGUARD_DONE_AUTHENTICATING = 11; /** * The default amount of time we stay awake (used for all key input) @@ -444,7 +444,7 @@ public class KeyguardViewMediator implements KeyguardViewCallback, if (mUpdateMonitor.isKeyguardBypassEnabled() && mKeyboardOpen && !mKeyguardViewProperties.isSecure() && mKeyguardViewManager.isShowing()) { if (DEBUG) Log.d(TAG, "bypassing keyguard on sliding open of keyboard with non-secure keyguard"); - mHandler.sendEmptyMessage(HIDE_KEYGUARD); + mHandler.sendEmptyMessage(KEYGUARD_DONE_AUTHENTICATING); return true; } return false; @@ -793,7 +793,7 @@ public class KeyguardViewMediator implements KeyguardViewCallback, case KEYGUARD_DONE_DRAWING: handleKeyguardDoneDrawing(); return; - case HIDE_KEYGUARD: + case KEYGUARD_DONE_AUTHENTICATING: keyguardDone(true); return; } diff --git a/policy/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/com/android/internal/policy/impl/PhoneWindowManager.java index 41d76e8b28991..032e1f41d34c6 100644 --- a/policy/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/com/android/internal/policy/impl/PhoneWindowManager.java @@ -20,6 +20,7 @@ import android.app.Activity; import android.app.ActivityManagerNative; import android.app.IActivityManager; import android.app.IStatusBar; +import android.content.ActivityNotFoundException; import android.content.BroadcastReceiver; import android.content.ContentResolver; import android.content.Context; @@ -68,6 +69,7 @@ import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR; import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS; import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED; +import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD; import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST; import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW; @@ -218,9 +220,12 @@ public class PhoneWindowManager implements WindowManagerPolicy { WindowState mTopFullscreenOpaqueWindowState; boolean mForceStatusBar; - boolean mHideKeyguard; + boolean mHideLockScreen; + boolean mDismissKeyguard; boolean mHomePressed; Intent mHomeIntent; + Intent mCarDockIntent; + Intent mDeskDockIntent; boolean mSearchKeyPressed; boolean mConsumeSearchKeyUp; @@ -472,6 +477,14 @@ public class PhoneWindowManager implements WindowManagerPolicy { mHomeIntent.addCategory(Intent.CATEGORY_HOME); mHomeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); + mCarDockIntent = new Intent(Intent.ACTION_MAIN, null); + mCarDockIntent.addCategory(Intent.CATEGORY_CAR_DOCK); + mCarDockIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK + | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); + mDeskDockIntent = new Intent(Intent.ACTION_MAIN, null); + mDeskDockIntent.addCategory(Intent.CATEGORY_DESK_DOCK); + mDeskDockIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK + | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE); mBroadcastWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "PhoneWindowManager.mBroadcastWakeLock"); @@ -1050,9 +1063,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { * given the situation with the keyguard. */ void launchHomeFromHotKey() { - if (!mHideKeyguard && mKeyguardMediator.isShowing()) { + if (!mHideLockScreen && mKeyguardMediator.isShowing()) { // don't launch home if keyguard showing - } else if (!mHideKeyguard && mKeyguardMediator.isInputRestricted()) { + } else if (!mHideLockScreen && mKeyguardMediator.isInputRestricted()) { // when in keyguard restricted mode, must first verify unlock // before launching home mKeyguardMediator.verifyUnlock(new OnKeyguardExitResult() { @@ -1063,7 +1076,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { } catch (RemoteException e) { } sendCloseSystemWindows(); - mContext.startActivity(mHomeIntent); + startDockOrHome(); } } }); @@ -1074,7 +1087,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { } catch (RemoteException e) { } sendCloseSystemWindows(); - mContext.startActivity(mHomeIntent); + startDockOrHome(); } } @@ -1102,7 +1115,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { mTopFullscreenOpaqueWindowState = null; mForceStatusBar = false; - mHideKeyguard = false; + mHideLockScreen = false; + mDismissKeyguard = false; // decide where the status bar goes ahead of time if (mStatusBar != null) { @@ -1309,11 +1323,14 @@ public class PhoneWindowManager implements WindowManagerPolicy { && win.fillsScreenLw(mW, mH, false, false)) { if (DEBUG_LAYOUT) Log.v(TAG, "Fullscreen window: " + win); mTopFullscreenOpaqueWindowState = win; + if ((attrs.flags & FLAG_SHOW_WHEN_LOCKED) != 0) { + if (localLOGV) Log.i(TAG, "Setting mHideLockScreen to true by win " + win); + mHideLockScreen = true; + } } - if ((attrs.flags & FLAG_SHOW_WHEN_LOCKED) != 0) { - // TODO Add a check for the window to be full screen - if (localLOGV) Log.i(TAG, "Setting mHideKeyguard to true by win " + win); - mHideKeyguard = true; + if ((attrs.flags & FLAG_DISMISS_KEYGUARD) != 0) { + if (localLOGV) Log.i(TAG, "Setting mDismissKeyguard to true by win " + win); + mDismissKeyguard = true; } } @@ -1337,15 +1354,15 @@ public class PhoneWindowManager implements WindowManagerPolicy { } /** {@inheritDoc} */ - public boolean finishLayoutLw() { - boolean changed = false; + public int finishLayoutLw() { + int changes = 0; boolean hiding = false; if (mStatusBar != null) { //Log.i(TAG, "force=" + mForceStatusBar // + " top=" + mTopFullscreenOpaqueWindowState); if (mForceStatusBar) { if (DEBUG_LAYOUT) Log.v(TAG, "Showing status bar"); - changed |= mStatusBar.showLw(true); + if (mStatusBar.showLw(true)) changes |= FINISH_LAYOUT_REDO_LAYOUT; } else if (mTopFullscreenOpaqueWindowState != null) { //Log.i(TAG, "frame: " + mTopFullscreenOpaqueWindowState.getFrameLw() // + " shown frame: " + mTopFullscreenOpaqueWindowState.getShownFrameLw()); @@ -1356,33 +1373,48 @@ public class PhoneWindowManager implements WindowManagerPolicy { (lp.flags & WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0; if (hideStatusBar) { if (DEBUG_LAYOUT) Log.v(TAG, "Hiding status bar"); - changed |= mStatusBar.hideLw(true); + if (mStatusBar.hideLw(true)) changes |= FINISH_LAYOUT_REDO_LAYOUT; hiding = true; } else { if (DEBUG_LAYOUT) Log.v(TAG, "Showing status bar"); - changed |= mStatusBar.showLw(true); + if (mStatusBar.showLw(true)) changes |= FINISH_LAYOUT_REDO_LAYOUT; } } } // Hide the key guard if a visible window explicitly specifies that it wants to be displayed // when the screen is locked if (mKeyguard != null) { - if (localLOGV) Log.i(TAG, "finishLayoutLw::mHideKeyguard="+mHideKeyguard); - if (mHideKeyguard) { - changed |= mKeyguard.hideLw(true); - if (!mKeyguardMediator.isShowing()) { + if (localLOGV) Log.i(TAG, "finishLayoutLw::mHideKeyguard="+mHideLockScreen); + if (mDismissKeyguard && mKeyguardMediator.isShowing() + && !mKeyguardMediator.isSecure()) { + if (mKeyguard.hideLw(true)) { + changes |= FINISH_LAYOUT_REDO_LAYOUT + | FINISH_LAYOUT_REDO_CONFIG + | FINISH_LAYOUT_REDO_WALLPAPER; + } + if (!mKeyguardMediator.isSecure()) { mHandler.post(new Runnable() { public void run() { mKeyguardMediator.keyguardDone(true); } }); } + } else if (mHideLockScreen && mKeyguardMediator.isShowing()) { + if (mKeyguard.hideLw(true)) { + changes |= FINISH_LAYOUT_REDO_LAYOUT + | FINISH_LAYOUT_REDO_CONFIG + | FINISH_LAYOUT_REDO_WALLPAPER; + } } else { - changed |= mKeyguard.showLw(true); + if (mKeyguard.showLw(false)) { + changes |= FINISH_LAYOUT_REDO_LAYOUT + | FINISH_LAYOUT_REDO_CONFIG + | FINISH_LAYOUT_REDO_WALLPAPER; + } } } - if (changed && hiding) { + if (changes != 0 && hiding) { IStatusBar sbs = IStatusBar.Stub.asInterface(ServiceManager.getService("statusbar")); if (sbs != null) { try { @@ -1393,7 +1425,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { } } - return changed; + return changes; } /** {@inheritDoc} */ @@ -1991,6 +2023,53 @@ public class PhoneWindowManager implements WindowManagerPolicy { } } + /** + * Return an Intent to launch the currently active dock as home. Returns + * null if the standard home should be launched. + * @return + */ + Intent createHomeDockIntent() { + if (mDockState == Intent.EXTRA_DOCK_STATE_UNDOCKED) { + return null; + } + + Intent intent; + if (mDockState == Intent.EXTRA_DOCK_STATE_CAR) { + intent = mCarDockIntent; + } else if (mDockState == Intent.EXTRA_DOCK_STATE_DESK) { + intent = mDeskDockIntent; + } else { + Log.w(TAG, "Unknown dock state: " + mDockState); + return null; + } + + ActivityInfo ai = intent.resolveActivityInfo( + mContext.getPackageManager(), PackageManager.GET_META_DATA); + if (ai == null) { + return null; + } + + if (ai.metaData != null && ai.metaData.getBoolean(Intent.METADATA_DOCK_HOME)) { + intent = new Intent(intent); + intent.setClassName(ai.packageName, ai.name); + return intent; + } + + return null; + } + + void startDockOrHome() { + Intent dock = createHomeDockIntent(); + if (dock != null) { + try { + mContext.startActivity(dock); + return; + } catch (ActivityNotFoundException e) { + } + } + mContext.startActivity(mHomeIntent); + } + /** * goes to the home screen * @return whether it did anything @@ -2003,13 +2082,23 @@ public class PhoneWindowManager implements WindowManagerPolicy { } catch (RemoteException e) { } sendCloseSystemWindows(); - mContext.startActivity(mHomeIntent); + startDockOrHome(); } else { // This code brings home to the front or, if it is already // at the front, puts the device to sleep. try { ActivityManagerNative.getDefault().stopAppSwitches(); sendCloseSystemWindows(); + Intent dock = createHomeDockIntent(); + if (dock != null) { + int result = ActivityManagerNative.getDefault() + .startActivity(null, dock, + dock.resolveTypeIfNeeded(mContext.getContentResolver()), + null, 0, null, null, 0, true /* onlyIfNeeded*/, false); + if (result == IActivityManager.START_RETURN_INTENT_TO_CALLER) { + return false; + } + } int result = ActivityManagerNative.getDefault() .startActivity(null, mHomeIntent, mHomeIntent.resolveTypeIfNeeded(mContext.getContentResolver()),