diff options
17 files changed, 318 insertions, 31 deletions
diff --git a/docs/html/sdk/installing/studio-tips.jd b/docs/html/sdk/installing/studio-tips.jd index 12d252710a28..03e29ca52d8a 100644 --- a/docs/html/sdk/installing/studio-tips.jd +++ b/docs/html/sdk/installing/studio-tips.jd @@ -52,6 +52,12 @@ Plugin User Guide</a>.</p> <p>The following topics describe how to perform some basic development tasks with Android Studio.</p> +<p class="note"><strong>Note:</strong> This section lists Android Studio keyboard shortcuts +for the default keymap. To change the default keymap on Windows and Linux, go to +<strong>File</strong> > <strong>Settings</strong> > <strong>Keymap</strong>. To change +the default keymap on Mac OS X, go to <strong>Android Studio</strong> > +<strong>Preferences</strong> > <strong>Keymap</strong>.</p> + <h3>Creating virtual devices</h3> <p>All the capabilities of the <a href="{@docRoot}tools/devices/managing-avds.html">Android @@ -75,10 +81,11 @@ for updates.</p> <h3>Creating new files</h3> <p>You can quickly add new code and resource files by clicking the appropriate directory in the -<strong>Project</strong> pane and pressing CTRL + N (CMD + N, on Mac). Based on the type of -directory selected, Android Studio offers to create the appropriate file type.</p> +<strong>Project</strong> pane and pressing ALT + INSERT on Windows and Linux or COMMAND + N on Mac. +Based on the type of directory selected, Android Studio offers to create the appropriate file +type.</p> -<p>For example, if you select a layout directory, press CTRL + N, and select +<p>For example, if you select a layout directory, press ALT + INSERT on Windows, and select <strong>Layout resource file</strong>, a dialog opens so you can name the file (you can exclude the {@code .xml} suffix) and choose a root view element. The editor then switches to the layout design editor so you can begin designing your layout.</p> diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index 5ce35792b384..e48aef19c337 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -193,6 +193,7 @@ <!-- Alternate Recents --> <activity android:name=".recents.RecentsActivity" + android:label="@string/accessibility_desc_recent_apps" android:launchMode="singleInstance" android:excludeFromRecents="true" android:theme="@style/RecentsTheme"> diff --git a/packages/SystemUI/res/layout/recents_empty.xml b/packages/SystemUI/res/layout/recents_empty.xml index 21d1711c965b..1ef9cad670da 100644 --- a/packages/SystemUI/res/layout/recents_empty.xml +++ b/packages/SystemUI/res/layout/recents_empty.xml @@ -20,7 +20,7 @@ android:layout_height="match_parent" android:layout_gravity="center" android:gravity="center" - android:textSize="20sp" + android:textSize="16sp" android:textColor="#ffffffff" android:text="@string/recents_empty_message" android:fontFamily="sans-serif-light" diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml index 3d712b7bdb45..26e5ce397473 100644 --- a/packages/SystemUI/res/values/config.xml +++ b/packages/SystemUI/res/values/config.xml @@ -145,6 +145,8 @@ <integer name="recents_animate_task_view_remove_duration">250</integer> <!-- The minimum alpha for the dim applied to cards that go deeper into the stack. --> <integer name="recents_max_task_stack_view_dim">96</integer> + <!-- The number of tasks that RecentsTaskLoader should load. --> + <integer name="recents_max_num_tasks_to_load">50</integer> <!-- Transposes the recents layout in landscape. --> <bool name="recents_transpose_layout_with_orientation">true</bool> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 029aa91f0034..93ed231d79ef 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -32,7 +32,7 @@ <!-- Message shown in the middle of the screen after clicking on the recent apps button when there are no recent apps to show. Also used for accessibility. [CHAR LIMIT=45]--> - <string name="status_bar_no_recent_apps">No recent apps</string> + <string name="status_bar_no_recent_apps">Your recent screens appear here</string> <!-- Content description for the button to dismiss Recent Apps (only present on large devices) --> @@ -206,7 +206,7 @@ <!-- Content description of the menu button for accessibility (not shown on the screen). [CHAR LIMIT=NONE] --> <string name="accessibility_menu">Menu</string> <!-- Content description of the recents button for accessibility (not shown on the screen). [CHAR LIMIT=NONE] --> - <string name="accessibility_recent">Recent apps</string> + <string name="accessibility_recent">Recent screens</string> <!-- Content description of the search button for accessibility. [CHAR LIMIT=NONE] --> <string name="accessibility_search_light">Search</string> <!-- Content description of the camera button for accessibility (not shown on the screen). [CHAR LIMIT=NONE] --> @@ -391,7 +391,7 @@ <!-- Content description for the quick settings panel (not shown on the screen). [CHAR LIMIT=NONE] --> <string name="accessibility_desc_quick_settings">Quick settings.</string> <!-- Content description for the recent apps panel (not shown on the screen). [CHAR LIMIT=NONE] --> - <string name="accessibility_desc_recent_apps">Recent apps.</string> + <string name="accessibility_desc_recent_apps">Recent screens.</string> <!-- Content description of the user tile in quick settings (not shown on the screen). [CHAR LIMIT=NONE] --> <string name="accessibility_quick_settings_user">User <xliff:g id="user" example="John Doe">%s</xliff:g>.</string> @@ -581,7 +581,7 @@ <string name="quick_settings_cellular_detail_data_warning"><xliff:g id="data_limit" example="2.0 GB">%s</xliff:g> warning</string> <!-- Recents: The empty recents string. [CHAR LIMIT=NONE] --> - <string name="recents_empty_message">No recent apps</string> + <string name="recents_empty_message">Your recent screens appear here</string> <!-- Recents: The info panel app info button string. [CHAR LIMIT=NONE] --> <string name="recents_app_info_button_label">Application Info</string> <!-- Recents: The lock-to-app button. [CHAR LIMIT=NONE] --> diff --git a/packages/SystemUI/src/com/android/systemui/RecentsComponent.java b/packages/SystemUI/src/com/android/systemui/RecentsComponent.java index 41d598462bdc..dd93389880b0 100644 --- a/packages/SystemUI/src/com/android/systemui/RecentsComponent.java +++ b/packages/SystemUI/src/com/android/systemui/RecentsComponent.java @@ -29,5 +29,7 @@ public interface RecentsComponent { void toggleRecents(Display display, int layoutDirection, View statusBarView); void preloadRecents(); void cancelPreloadingRecents(); + void showNextAffiliatedTask(); + void showPrevAffiliatedTask(); void setCallback(Callbacks cb); } diff --git a/packages/SystemUI/src/com/android/systemui/recent/Recents.java b/packages/SystemUI/src/com/android/systemui/recent/Recents.java index 4cf5fe1fe6a2..9a5559035d63 100644 --- a/packages/SystemUI/src/com/android/systemui/recent/Recents.java +++ b/packages/SystemUI/src/com/android/systemui/recent/Recents.java @@ -274,6 +274,20 @@ public class Recents extends SystemUI implements RecentsComponent { } @Override + public void showNextAffiliatedTask() { + if (mUseAlternateRecents) { + mAlternateRecents.onShowNextAffiliatedTask(); + } + } + + @Override + public void showPrevAffiliatedTask() { + if (mUseAlternateRecents) { + mAlternateRecents.onShowPrevAffiliatedTask(); + } + } + + @Override public void setCallback(Callbacks cb) { if (mUseAlternateRecents) { mAlternateRecents.setRecentsComponentCallback(cb); diff --git a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java index bb5fe541d815..efb7a2c7f538 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java +++ b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java @@ -34,8 +34,10 @@ import com.android.systemui.R; import com.android.systemui.RecentsComponent; import com.android.systemui.recents.misc.Console; import com.android.systemui.recents.misc.SystemServicesProxy; +import com.android.systemui.recents.misc.Utilities; import com.android.systemui.recents.model.RecentsTaskLoader; import com.android.systemui.recents.model.Task; +import com.android.systemui.recents.model.TaskGrouping; import com.android.systemui.recents.model.TaskStack; import com.android.systemui.recents.views.TaskStackView; import com.android.systemui.recents.views.TaskStackViewLayoutAlgorithm; @@ -165,6 +167,77 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta // Do nothing } + void showRelativeAffiliatedTask(boolean showNextTask) { + TaskStack stack = RecentsTaskLoader.getShallowTaskStack(mSystemServicesProxy, + Integer.MAX_VALUE); + // Return early if there are no tasks + if (stack.getTaskCount() == 0) return; + + ActivityManager.RunningTaskInfo runningTask = getTopMostTask(); + // Return early if the running task is in the home stack (optimization) + if (mSystemServicesProxy.isInHomeStack(runningTask.id)) return; + + // Find the task in the recents list + ArrayList<Task> tasks = stack.getTasks(); + Task toTask = null; + ActivityOptions launchOpts = null; + int taskCount = tasks.size(); + for (int i = 0; i < taskCount; i++) { + Task task = tasks.get(i); + if (task.key.id == runningTask.id) { + TaskGrouping group = task.group; + Task.TaskKey toTaskKey; + if (showNextTask) { + toTaskKey = group.getNextTaskInGroup(task); + // XXX: We will actually set the appropriate launch animations here + } else { + toTaskKey = group.getPrevTaskInGroup(task); + // XXX: We will actually set the appropriate launch animations here + } + if (toTaskKey != null) { + toTask = stack.findTaskWithId(toTaskKey.id); + } + break; + } + } + + // Return early if there is no next task + if (toTask == null) { + // XXX: We will actually show a bounce animation here + return; + } + + // Launch the task + if (toTask.isActive) { + // Bring an active task to the foreground + mSystemServicesProxy.moveTaskToFront(toTask.key.id, launchOpts); + } else { + // Launch the activity anew with the desired animation + boolean isDocument = Utilities.isDocument(toTask.key.baseIntent); + Intent intent = new Intent(toTask.key.baseIntent); + intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY + | Intent.FLAG_ACTIVITY_TASK_ON_HOME); + if (!isDocument) { + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + } + try { + mSystemServicesProxy.startActivityFromRecents(toTask.key.id, launchOpts); + } catch (ActivityNotFoundException anfe) {} + + // Remove the old task from activity manager + RecentsTaskLoader.getInstance().getSystemServicesProxy().removeTask(toTask.key.id, + isDocument); + } + } + + public void onShowNextAffiliatedTask() { + showRelativeAffiliatedTask(true); + } + + public void onShowPrevAffiliatedTask() { + showRelativeAffiliatedTask(false); + } + public void onConfigurationChanged(Configuration newConfig) { mConfig = RecentsConfiguration.reinitialize(mContext, mSystemServicesProxy); mConfig.updateOnConfigurationChange(); @@ -318,7 +391,7 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta /** Returns the transition rect for the given task id. */ Rect getThumbnailTransitionRect(int runningTaskId) { // Get the stack of tasks that we are animating into - TaskStack stack = RecentsTaskLoader.getShallowTaskStack(mSystemServicesProxy); + TaskStack stack = RecentsTaskLoader.getShallowTaskStack(mSystemServicesProxy, -1); if (stack.getTaskCount() == 0) { return new Rect(); } diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java index dabeadf40508..65e7076e7e84 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java @@ -58,6 +58,9 @@ public class RecentsConfiguration { boolean isLandscape; boolean transposeRecentsLayoutWithOrientation; + /** Loading */ + public int maxNumTasksToLoad; + /** Search bar */ int searchBarAppWidgetId = -1; public int searchBarSpaceHeightPx; @@ -162,8 +165,7 @@ public class RecentsConfiguration { } // Layout - isLandscape = res.getConfiguration().orientation == - Configuration.ORIENTATION_LANDSCAPE; + isLandscape = res.getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE; transposeRecentsLayoutWithOrientation = res.getBoolean(R.bool.recents_transpose_layout_with_orientation); @@ -180,6 +182,9 @@ public class RecentsConfiguration { filteringNewViewsAnimDuration = res.getInteger(R.integer.recents_filter_animate_new_views_duration); + // Loading + maxNumTasksToLoad = res.getInteger(R.integer.recents_max_num_tasks_to_load); + // Search Bar searchBarSpaceHeightPx = res.getDimensionPixelSize(R.dimen.recents_search_bar_space_height); searchBarAppWidgetId = settings.getInt(Constants.Values.App.Key_SearchAppWidgetId, -1); diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java index 8716184bcbec..0e2f37038283 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java +++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java @@ -295,9 +295,15 @@ public class RecentsTaskLoader { } /** Gets the list of recent tasks, ordered from back to front. */ - private static List<ActivityManager.RecentTaskInfo> getRecentTasks(SystemServicesProxy ssp) { + private static List<ActivityManager.RecentTaskInfo> getRecentTasks(SystemServicesProxy ssp, + int numTasks) { + // Set a default number of tasks to query if none is provided + if (numTasks < 0) { + RecentsConfiguration config = RecentsConfiguration.getInstance(); + numTasks = config.maxNumTasksToLoad; + } List<ActivityManager.RecentTaskInfo> tasks = - ssp.getRecentTasks(50, UserHandle.CURRENT.getIdentifier()); + ssp.getRecentTasks(numTasks, UserHandle.CURRENT.getIdentifier()); Collections.reverse(tasks); return tasks; } @@ -313,7 +319,7 @@ public class RecentsTaskLoader { // Get the recent tasks SystemServicesProxy ssp = mSystemServicesProxy; - List<ActivityManager.RecentTaskInfo> tasks = getRecentTasks(ssp); + List<ActivityManager.RecentTaskInfo> tasks = getRecentTasks(ssp, -1); // From back to front, add each task to the task stack int taskCount = tasks.size(); @@ -395,9 +401,9 @@ public class RecentsTaskLoader { } /** Creates a lightweight stack of the current recent tasks, without thumbnails and icons. */ - public static TaskStack getShallowTaskStack(SystemServicesProxy ssp) { + public static TaskStack getShallowTaskStack(SystemServicesProxy ssp, int numTasks) { RecentsConfiguration config = RecentsConfiguration.getInstance(); - List<ActivityManager.RecentTaskInfo> tasks = getRecentTasks(ssp); + List<ActivityManager.RecentTaskInfo> tasks = getRecentTasks(ssp, numTasks); TaskStack stack = new TaskStack(); int taskCount = tasks.size(); diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/TaskGrouping.java b/packages/SystemUI/src/com/android/systemui/recents/model/TaskGrouping.java index 326485e81706..288f07c8d68b 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/model/TaskGrouping.java +++ b/packages/SystemUI/src/com/android/systemui/recents/model/TaskGrouping.java @@ -43,6 +43,24 @@ public class TaskGrouping { updateTaskIndices(); } + /** Returns the key of the next task in the group. */ + public Task.TaskKey getNextTaskInGroup(Task t) { + int i = indexOf(t); + if ((i + 1) < getTaskCount()) { + return mTaskKeys.get(i + 1); + } + return null; + } + + /** Returns the key of the previous task in the group. */ + public Task.TaskKey getPrevTaskInGroup(Task t) { + int i = indexOf(t); + if ((i - 1) >= 0) { + return mTaskKeys.get(i - 1); + } + return null; + } + /** Gets the front task */ public boolean isFrontMostTask(Task t) { return (t.key == mFrontMostTaskKey); diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java index 435eb4289bde..0269141a1cf6 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java +++ b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java @@ -266,6 +266,19 @@ public class TaskStack { return mTaskList.indexOf(t); } + /** Finds the task with the specified task id. */ + public Task findTaskWithId(int taskId) { + ArrayList<Task> tasks = mTaskList.getTasks(); + int taskCount = tasks.size(); + for (int i = 0; i < taskCount; i++) { + Task task = tasks.get(i); + if (task.key.id == taskId) { + return task; + } + } + return null; + } + /******** Filtering ********/ /** Filters the stack into tasks similar to the one specified */ diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java index 8319f4103f7b..2df173e839ba 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java @@ -109,12 +109,14 @@ public abstract class BaseStatusBar extends SystemUI implements protected static final int MSG_TOGGLE_RECENTS_APPS = 1021; protected static final int MSG_PRELOAD_RECENT_APPS = 1022; protected static final int MSG_CANCEL_PRELOAD_RECENT_APPS = 1023; - protected static final int MSG_OPEN_SEARCH_PANEL = 1024; - protected static final int MSG_CLOSE_SEARCH_PANEL = 1025; - protected static final int MSG_SHOW_HEADS_UP = 1026; - protected static final int MSG_HIDE_HEADS_UP = 1027; - protected static final int MSG_ESCALATE_HEADS_UP = 1028; - protected static final int MSG_DECAY_HEADS_UP = 1029; + protected static final int MSG_SHOW_NEXT_AFFILIATED_TASK = 1024; + protected static final int MSG_SHOW_PREV_AFFILIATED_TASK = 1025; + protected static final int MSG_OPEN_SEARCH_PANEL = 1026; + protected static final int MSG_CLOSE_SEARCH_PANEL = 1027; + protected static final int MSG_SHOW_HEADS_UP = 1028; + protected static final int MSG_HIDE_HEADS_UP = 1029; + protected static final int MSG_ESCALATE_HEADS_UP = 1030; + protected static final int MSG_DECAY_HEADS_UP = 1031; protected static final boolean ENABLE_HEADS_UP = true; // scores above this threshold should be displayed in heads up mode. @@ -689,6 +691,20 @@ public abstract class BaseStatusBar extends SystemUI implements mHandler.sendEmptyMessage(msg); } + /** Jumps to the next affiliated task in the group. */ + public void showNextAffiliatedTask() { + int msg = MSG_SHOW_NEXT_AFFILIATED_TASK; + mHandler.removeMessages(msg); + mHandler.sendEmptyMessage(msg); + } + + /** Jumps to the previous affiliated task in the group. */ + public void showPreviousAffiliatedTask() { + int msg = MSG_SHOW_PREV_AFFILIATED_TASK; + mHandler.removeMessages(msg); + mHandler.sendEmptyMessage(msg); + } + @Override public void showSearchPanel() { int msg = MSG_OPEN_SEARCH_PANEL; @@ -800,6 +816,18 @@ public abstract class BaseStatusBar extends SystemUI implements } } + protected void showRecentsNextAffiliatedTask() { + if (mRecents != null) { + mRecents.showNextAffiliatedTask(); + } + } + + protected void showRecentsPreviousAffiliatedTask() { + if (mRecents != null) { + mRecents.showPrevAffiliatedTask(); + } + } + @Override public void onVisibilityChanged(boolean visible) { // Do nothing @@ -884,6 +912,12 @@ public abstract class BaseStatusBar extends SystemUI implements case MSG_CANCEL_PRELOAD_RECENT_APPS: cancelPreloadingRecents(); break; + case MSG_SHOW_NEXT_AFFILIATED_TASK: + showRecentsNextAffiliatedTask(); + break; + case MSG_SHOW_PREV_AFFILIATED_TASK: + showRecentsPreviousAffiliatedTask(); + break; case MSG_OPEN_SEARCH_PANEL: if (DEBUG) Log.d(TAG, "opening search panel"); if (mSearchPanelView != null && mSearchPanelView.isAssistantAvailable()) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java index 95cb9a116172..35929716c243 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java @@ -37,12 +37,9 @@ import android.view.Surface; import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; -import android.view.accessibility.AccessibilityManager; -import android.view.accessibility.AccessibilityManager.TouchExplorationStateChangeListener; import android.view.inputmethod.InputMethodManager; import android.widget.ImageView; import android.widget.LinearLayout; - import com.android.systemui.R; import com.android.systemui.statusbar.BaseStatusBar; import com.android.systemui.statusbar.DelegateViewHelper; @@ -77,6 +74,7 @@ public class NavigationBarView extends LinearLayout { private Drawable mRecentIcon; private Drawable mRecentLandIcon; + private NavigationBarViewTaskSwitchHelper mTaskSwitchHelper; private DelegateViewHelper mDelegateHelper; private DeadZone mDeadZone; private final NavigationBarTransitions mBarTransitions; @@ -177,6 +175,7 @@ public class NavigationBarView extends LinearLayout { mVertical = false; mShowMenu = false; mDelegateHelper = new DelegateViewHelper(this); + mTaskSwitchHelper = new NavigationBarViewTaskSwitchHelper(context); getIcons(res); @@ -192,6 +191,7 @@ public class NavigationBarView extends LinearLayout { } public void setBar(BaseStatusBar phoneStatusBar) { + mTaskSwitchHelper.setBar(phoneStatusBar); mDelegateHelper.setBar(phoneStatusBar); } @@ -201,6 +201,9 @@ public class NavigationBarView extends LinearLayout { @Override public boolean onTouchEvent(MotionEvent event) { + if (mTaskSwitchHelper.onTouchEvent(event)) { + return true; + } if (mDeadZone != null && event.getAction() == MotionEvent.ACTION_OUTSIDE) { mDeadZone.poke(event); } @@ -213,7 +216,8 @@ public class NavigationBarView extends LinearLayout { @Override public boolean onInterceptTouchEvent(MotionEvent event) { - return mDelegateHelper.onInterceptTouchEvent(event); + return mTaskSwitchHelper.onInterceptTouchEvent(event) || + mDelegateHelper.onInterceptTouchEvent(event); } private H mHandler = new H(); @@ -421,6 +425,8 @@ public class NavigationBarView extends LinearLayout { if (mDelegateHelper != null) { mDelegateHelper.setSwapXY(mVertical); } + boolean isRTL = (getLayoutDirection() == View.LAYOUT_DIRECTION_RTL); + mTaskSwitchHelper.setBarState(mVertical, isRTL); setNavigationIconHints(mNavigationIconHints, true); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarViewTaskSwitchHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarViewTaskSwitchHelper.java new file mode 100644 index 000000000000..3c20d1f32b8f --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarViewTaskSwitchHelper.java @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2014 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.systemui.statusbar.phone; + +import android.content.Context; +import android.view.GestureDetector; +import android.view.MotionEvent; +import android.view.ViewConfiguration; +import com.android.systemui.statusbar.BaseStatusBar; + +public class NavigationBarViewTaskSwitchHelper extends GestureDetector.SimpleOnGestureListener { + + private BaseStatusBar mBar; + private boolean mIsVertical; + private boolean mIsRTL; + + private final GestureDetector mTaskSwitcherDetector; + private final int mScrollTouchSlop; + private final int mMinFlingVelocity; + private boolean mInterceptTouches; + private int mTouchDownX; + + public NavigationBarViewTaskSwitchHelper(Context context) { + ViewConfiguration configuration = ViewConfiguration.get(context); + mScrollTouchSlop = configuration.getScaledTouchSlop(); + mMinFlingVelocity = configuration.getScaledMinimumFlingVelocity(); + mTaskSwitcherDetector = new GestureDetector(context, this); + } + + public void setBar(BaseStatusBar phoneStatusBar) { + mBar = phoneStatusBar; + } + + public void setBarState(boolean isVertical, boolean isRTL) { + mIsVertical = isVertical; + mIsRTL = isRTL; + } + + public boolean onInterceptTouchEvent(MotionEvent event) { + // If we move more than a fixed amount, then start capturing for the + // task switcher detector + mTaskSwitcherDetector.onTouchEvent(event); + int action = event.getAction(); + switch (action & MotionEvent.ACTION_MASK) { + case MotionEvent.ACTION_DOWN: { + mTouchDownX = (int) event.getX(); + mInterceptTouches = false; + break; + } + case MotionEvent.ACTION_MOVE: { + int x = (int) event.getX(); + if (Math.abs(x - mTouchDownX) > mScrollTouchSlop) { + mInterceptTouches = true; + return true; + } + break; + } + case MotionEvent.ACTION_CANCEL: + case MotionEvent.ACTION_UP: + mInterceptTouches = false; + break; + } + return mInterceptTouches; + } + + public boolean onTouchEvent(MotionEvent event) { + if (!mInterceptTouches) return false; + return mTaskSwitcherDetector.onTouchEvent(event); + } + + @Override + public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { + float absVelX = Math.abs(velocityX); + float absVelY = Math.abs(velocityY); + boolean isValidFling = absVelX > mMinFlingVelocity && + mIsVertical ? (absVelY > absVelX) : (absVelX > absVelY); + if (isValidFling) { + boolean showNext; + if (!mIsRTL) { + showNext = mIsVertical ? (velocityY < 0) : (velocityX < 0); + } else { + // In RTL, vertical is still the same, but horizontal is flipped + showNext = mIsVertical ? (velocityY < 0) : (velocityX > 0); + } + if (showNext) { + mBar.showNextAffiliatedTask(); + } else { + mBar.showPreviousAffiliatedTask(); + } + } + return true; + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index a2f893157d4e..6fff6c3b04c8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -183,7 +183,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, private static final int MSG_OPEN_NOTIFICATION_PANEL = 1000; private static final int MSG_CLOSE_PANELS = 1001; private static final int MSG_OPEN_SETTINGS_PANEL = 1002; - // 1020-1030 reserved for BaseStatusBar + // 1020-1040 reserved for BaseStatusBar private static final boolean CLOSE_PANEL_WHEN_EMPTIED = true; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java index 18583ee401c0..8f0000fd4d88 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcher.java @@ -49,10 +49,10 @@ public class KeyguardUserSwitcher { private final ViewGroup mUserSwitcher; private final KeyguardStatusBarView mStatusBarView; private final Adapter mAdapter; - private final boolean mSimpleUserSwitcher; private final AppearAnimationUtils mAppearAnimationUtils; private final KeyguardUserSwitcherScrim mBackground; private ObjectAnimator mBgAnimator; + private UserSwitcherController mUserSwitcherController; public KeyguardUserSwitcher(Context context, ViewStub userSwitcher, KeyguardStatusBarView statusBarView, NotificationPanelView panelView, @@ -66,7 +66,7 @@ public class KeyguardUserSwitcher { panelView.setKeyguardUserSwitcher(this); mAdapter = new Adapter(context, userSwitcherController); mAdapter.registerDataSetObserver(mDataSetObserver); - mSimpleUserSwitcher = userSwitcherController.isSimpleUserSwitcher(); + mUserSwitcherController = userSwitcherController; mAppearAnimationUtils = new AppearAnimationUtils(context, 400, -0.5f, 0.5f, AnimationUtils.loadInterpolator( context, android.R.interpolator.fast_out_slow_in)); @@ -74,7 +74,6 @@ public class KeyguardUserSwitcher { mUserSwitcher = null; mStatusBarView = null; mAdapter = null; - mSimpleUserSwitcher = false; mAppearAnimationUtils = null; mBackground = null; } @@ -95,7 +94,7 @@ public class KeyguardUserSwitcher { * @see android.os.UserManager#isUserSwitcherEnabled() */ private boolean shouldExpandByDefault() { - return mSimpleUserSwitcher; + return (mUserSwitcherController != null) && mUserSwitcherController.isSimpleUserSwitcher(); } public void show(boolean animate) { |