am eea0aa25: Support primitive ALT-TAB style navigation using Recent Apps. (DO NOT MERGE)

* commit 'eea0aa25870d49e381567f09abbfb41de52a5a32':
  Support primitive ALT-TAB style navigation using Recent Apps. (DO NOT MERGE)
This commit is contained in:
Jeff Brown
2011-05-25 14:43:13 -07:00
committed by Android Git Automerger
3 changed files with 98 additions and 32 deletions

View File

@ -287,8 +287,8 @@ key 9 {
key SPACE {
label: ' '
base: ' '
ctrl, alt: none
meta: fallback SEARCH
ctrl: none
alt, meta: fallback SEARCH
}
key ENTER {
@ -300,8 +300,8 @@ key ENTER {
key TAB {
label: '\t'
base: '\t'
ctrl, alt: none
meta: fallback APP_SWITCH
ctrl: none
alt, meta: fallback APP_SWITCH
}
key COMMA {
@ -542,8 +542,8 @@ key PLUS {
key ESCAPE {
base: fallback BACK
meta: fallback HOME
alt: fallback MENU
alt, meta: fallback HOME
ctrl: fallback MENU
}
### Gamepad buttons ###

View File

@ -623,7 +623,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_DIALOG) {
showRecentAppsDialog();
showRecentAppsDialog(0);
} else if (mLongPressOnHomeBehavior == LONG_PRESS_HOME_RECENT_ACTIVITY) {
try {
Intent intent = new Intent();
@ -642,12 +642,12 @@ public class PhoneWindowManager implements WindowManagerPolicy {
/**
* Create (if necessary) and launch the recent apps dialog
*/
void showRecentAppsDialog() {
void showRecentAppsDialog(final int initialModifiers) {
mHandler.post(new Runnable() {
@Override
public void run() {
if (mRecentAppsDialog == null) {
mRecentAppsDialog = new RecentApplicationsDialog(mContext);
mRecentAppsDialog = new RecentApplicationsDialog(mContext, initialModifiers);
}
mRecentAppsDialog.show();
}
@ -1433,7 +1433,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
return false;
} else if (keyCode == KeyEvent.KEYCODE_APP_SWITCH) {
if (down && repeatCount == 0) {
showRecentAppsDialog();
showRecentAppsDialog(event.getMetaState() & KeyEvent.getModifierMetaStateMask());
}
return true;
}

View File

@ -17,16 +17,13 @@
package com.android.internal.policy.impl;
import android.app.ActivityManager;
import android.app.ActivityManagerNative;
import android.app.Dialog;
import android.app.IActivityManager;
import android.app.StatusBarManager;
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Resources;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
@ -34,6 +31,8 @@ import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.KeyEvent;
import android.view.SoundEffectConstants;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
@ -72,13 +71,12 @@ public class RecentApplicationsDialog extends Dialog implements OnClickListener
}
};
private int mIconSize;
private int mInitialModifiers;
public RecentApplicationsDialog(Context context) {
public RecentApplicationsDialog(Context context, int initialModifiers) {
super(context, com.android.internal.R.style.Theme_Dialog_RecentApplications);
final Resources resources = context.getResources();
mIconSize = (int) resources.getDimension(android.R.dimen.app_icon_size);
mInitialModifiers = initialModifiers;
}
/**
@ -127,34 +125,102 @@ public class RecentApplicationsDialog extends Dialog implements OnClickListener
}
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_APP_SWITCH || keyCode == KeyEvent.KEYCODE_TAB) {
// Ignore all meta keys other than SHIFT. The app switch key could be a
// fallback action chorded with ALT, META or even CTRL depending on the key map.
// DPad navigation is handled by the ViewRoot elsewhere.
final boolean backward = event.isShiftPressed();
final int numIcons = mIcons.length;
int numButtons = 0;
while (numButtons < numIcons && mIcons[numButtons].getVisibility() == View.VISIBLE) {
numButtons += 1;
}
if (numButtons != 0) {
int nextFocus = backward ? numButtons - 1 : 0;
for (int i = 0; i < numButtons; i++) {
if (mIcons[i].hasFocus()) {
if (backward) {
nextFocus = (i + numButtons - 1) % numButtons;
} else {
nextFocus = (i + 1) % numButtons;
}
break;
}
}
final int direction = backward ? View.FOCUS_BACKWARD : View.FOCUS_FORWARD;
if (mIcons[nextFocus].requestFocus(direction)) {
mIcons[nextFocus].playSoundEffect(
SoundEffectConstants.getContantForFocusDirection(direction));
}
}
// The dialog always handles the key to prevent the ViewRoot from
// performing the default navigation itself.
return true;
}
return super.onKeyDown(keyCode, event);
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (mInitialModifiers != 0 && event.hasNoModifiers()) {
final int numIcons = mIcons.length;
RecentTag tag = null;
for (int i = 0; i < numIcons; i++) {
if (mIcons[i].getVisibility() != View.VISIBLE) {
break;
}
if (i == 0 || mIcons[i].hasFocus()) {
tag = (RecentTag) mIcons[i].getTag();
if (mIcons[i].hasFocus()) {
break;
}
}
}
if (tag != null) {
switchTo(tag);
}
dismiss();
return true;
}
return super.onKeyUp(keyCode, event);
}
/**
* Handler for user clicks. If a button was clicked, launch the corresponding activity.
*/
public void onClick(View v) {
for (TextView b: mIcons) {
if (b == v) {
RecentTag tag = (RecentTag)b.getTag();
if (tag.info.id >= 0) {
// This is an active task; it should just go to the foreground.
final ActivityManager am = (ActivityManager)
getContext().getSystemService(Context.ACTIVITY_SERVICE);
am.moveTaskToFront(tag.info.id, ActivityManager.MOVE_TASK_WITH_HOME);
} else if (tag.intent != null) {
tag.intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
| Intent.FLAG_ACTIVITY_TASK_ON_HOME);
try {
getContext().startActivity(tag.intent);
} catch (ActivityNotFoundException e) {
Log.w("Recent", "Unable to launch recent task", e);
}
}
switchTo(tag);
break;
}
}
dismiss();
}
private void switchTo(RecentTag tag) {
if (tag.info.id >= 0) {
// This is an active task; it should just go to the foreground.
final ActivityManager am = (ActivityManager)
getContext().getSystemService(Context.ACTIVITY_SERVICE);
am.moveTaskToFront(tag.info.id, ActivityManager.MOVE_TASK_WITH_HOME);
} else if (tag.intent != null) {
tag.intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
| Intent.FLAG_ACTIVITY_TASK_ON_HOME);
try {
getContext().startActivity(tag.intent);
} catch (ActivityNotFoundException e) {
Log.w("Recent", "Unable to launch recent task", e);
}
}
}
/**
* Set up and show the recent activities dialog.
*/