diff options
| author | 2015-11-20 16:00:45 -0800 | |
|---|---|---|
| committer | 2015-11-25 11:42:19 -0800 | |
| commit | c29ff0025bf0b1f43b34fe3e2dd6f043b61421ef (patch) | |
| tree | 93ea71128ecb6fb945c7144678babf4771072cc0 | |
| parent | 7afe8c900244e37e70863f56a86bb27ead45f9a1 (diff) | |
Adding history view.
- Initial changes to show a history view within Overview (behind tuner
flag)
- Restoring the task view dim in the stack
Change-Id: I0503d11768736c86f3145942404391dfacd0ddd6
23 files changed, 853 insertions, 41 deletions
diff --git a/packages/SystemUI/Android.mk b/packages/SystemUI/Android.mk index 0cc2a67a3be3..ece34fb8fb63 100644 --- a/packages/SystemUI/Android.mk +++ b/packages/SystemUI/Android.mk @@ -6,7 +6,9 @@ LOCAL_MODULE_TAGS := optional LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-proto-files-under,src) $(call all-Iaidl-files-under, src) \ src/com/android/systemui/EventLogTags.logtags -LOCAL_STATIC_JAVA_LIBRARIES := Keyguard +LOCAL_STATIC_JAVA_LIBRARIES := \ + Keyguard \ + android-support-v7-recyclerview LOCAL_JAVA_LIBRARIES := telephony-common LOCAL_PACKAGE_NAME := SystemUI diff --git a/packages/SystemUI/res/layout/recents.xml b/packages/SystemUI/res/layout/recents.xml index 064d2258150f..2c010ddc6bdd 100644 --- a/packages/SystemUI/res/layout/recents.xml +++ b/packages/SystemUI/res/layout/recents.xml @@ -39,6 +39,12 @@ android:layout_width="match_parent" android:layout_height="match_parent" /> + <!-- History View --> + <ViewStub android:id="@+id/history_view_stub" + android:layout="@layout/recents_history" + android:layout_width="match_parent" + android:layout_height="match_parent" /> + <!-- Nav Bar Scrim View --> <ImageView android:id="@+id/nav_bar_scrim" diff --git a/packages/SystemUI/res/layout/recents_history.xml b/packages/SystemUI/res/layout/recents_history.xml new file mode 100644 index 000000000000..de70d303f199 --- /dev/null +++ b/packages/SystemUI/res/layout/recents_history.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2015 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. +--> +<com.android.systemui.recents.history.RecentsHistoryView + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="#99000000" + android:orientation="vertical"> + <TextView + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:padding="14dp" + android:gravity="start" + android:text="@string/recents_history_label" + android:textSize="24sp" + android:textColor="#FFFFFF" + android:fontFamily="sans-serif-medium" /> + <android.support.v7.widget.RecyclerView + android:id="@+id/list" + android:layout_width="match_parent" + android:layout_height="match_parent" /> +</com.android.systemui.recents.history.RecentsHistoryView>
\ No newline at end of file diff --git a/packages/SystemUI/res/layout/recents_history_button.xml b/packages/SystemUI/res/layout/recents_history_button.xml new file mode 100644 index 000000000000..38457c7b2a61 --- /dev/null +++ b/packages/SystemUI/res/layout/recents_history_button.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2015 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. +--> +<TextView + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="@dimen/recents_history_button_height" + android:gravity="start|center_vertical" + android:text="@string/recents_show_history_button_label" + android:textSize="14sp" + android:textColor="#FFFFFF" + android:textAllCaps="true" + android:fontFamily="sans-serif-medium" + android:visibility="invisible" />
\ No newline at end of file diff --git a/packages/SystemUI/res/layout/recents_history_date.xml b/packages/SystemUI/res/layout/recents_history_date.xml new file mode 100644 index 000000000000..6d6a9eed6187 --- /dev/null +++ b/packages/SystemUI/res/layout/recents_history_date.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2015 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. +--> +<TextView + xmlns:android="http://schemas.android.com/apk/res/android" + android:theme="@android:style/Theme.Material" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:padding="12dp" + android:gravity="start" + android:textSize="14sp" + android:textColor="#009688" + android:textAllCaps="true" + android:fontFamily="sans-serif-medium" + android:background="?android:selectableItemBackground" + android:alpha="1" />
\ No newline at end of file diff --git a/packages/SystemUI/res/layout/recents_history_task.xml b/packages/SystemUI/res/layout/recents_history_task.xml new file mode 100644 index 000000000000..b9de15606bfb --- /dev/null +++ b/packages/SystemUI/res/layout/recents_history_task.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2015 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. +--> +<TextView + xmlns:android="http://schemas.android.com/apk/res/android" + android:theme="@android:style/Theme.Material" + android:layout_width="match_parent" + android:layout_height="48dp" + android:paddingLeft="32dp" + android:gravity="start|center_vertical" + android:textSize="14sp" + android:textColor="#FFFFFF" + android:fontFamily="sans-serif-medium" + android:background="?android:selectableItemBackground" + android:alpha="1" />
\ No newline at end of file diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml index d8193abfa2dc..902db26d21fa 100644 --- a/packages/SystemUI/res/values/config.xml +++ b/packages/SystemUI/res/values/config.xml @@ -177,6 +177,9 @@ <!-- The animation duration for scrolling the stack to a particular item. --> <integer name="recents_animate_task_stack_scroll_duration">225</integer> + <!-- The animation duration for entering and exiting the history. --> + <integer name="recents_history_transition_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> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index e0c0f6a5bb1b..04233ba064bd 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -698,6 +698,10 @@ <string name="recents_search_bar_label">search</string> <!-- Recents: Launch error string. [CHAR LIMIT=NONE] --> <string name="recents_launch_error_message">Could not start <xliff:g id="app" example="Calendar">%s</xliff:g>.</string> + <!-- Recents: Show history string. [CHAR LIMIT=NONE] --> + <string name="recents_show_history_button_label">More</string> + <!-- Recents: The history of recents. [CHAR LIMIT=NONE] --> + <string name="recents_history_label">History</string> <!-- Recents: MultiStack add stack split horizontal radio button. [CHAR LIMIT=NONE] --> <string name="recents_multistack_add_stack_dialog_split_horizontal">Split Horizontal</string> @@ -1157,21 +1161,26 @@ <!-- Option to use new paging layout in quick settings [CHAR LIMIT=60] --> <string name="qs_paging" translatable="false">Use the new Quick Settings</string> - <!-- Toggles paging recents via the recents button --> + <!-- Toggles paging recents via the recents button. DO NOT TRANSLATE --> <string name="overview_page_on_toggle">Enable paging</string> - <!-- Description for the toggle for fast-toggling recents via the recents button --> + <!-- Description for the toggle for fast-toggling recents via the recents button. DO NOT TRANSLATE --> <string name="overview_page_on_toggle_desc">Enable paging via the Overview button</string> - <!-- Toggles fast-toggling recents via the recents button --> + <!-- Toggles fast-toggling recents via the recents button. DO NOT TRANSLATE --> <string name="overview_fast_toggle_via_button">Enable fast toggle</string> - <!-- Description for the toggle for fast-toggling recents via the recents button --> + <!-- Description for the toggle for fast-toggling recents via the recents button. DO NOT TRANSLATE --> <string name="overview_fast_toggle_via_button_desc">Enable launch timeout while paging</string> - <!-- Toggles fullscreen screenshots --> + <!-- Toggles fullscreen screenshots. DO NOT TRANSLATE --> <string name="overview_fullscreen_thumbnails">Enable fullscreen screenshots</string> - <!-- Description for the toggle for fullscreen screenshots --> + <!-- Description for the toggle for fullscreen screenshots. DO NOT TRANSLATE --> <string name="overview_fullscreen_thumbnails_desc">Enable fullscreen screenshots in Overview</string> + <!-- Toggle to show the history view in Overview. DO NOT TRANSLATE --> + <string name="overview_show_history">Show History</string> + <!-- Description for the toggle to show the history view in Overview. DO NOT TRANSLATE --> + <string name="overview_show_history_desc">Enables the history view to see more recent tasks</string> + <!-- Category in the System UI Tuner settings, where new/experimental settings are --> <string name="experimental">Experimental</string> diff --git a/packages/SystemUI/res/xml/tuner_prefs.xml b/packages/SystemUI/res/xml/tuner_prefs.xml index 4d07d5f2c9a3..f398af3d04c9 100644 --- a/packages/SystemUI/res/xml/tuner_prefs.xml +++ b/packages/SystemUI/res/xml/tuner_prefs.xml @@ -102,6 +102,11 @@ android:title="@string/overview_fullscreen_thumbnails" android:summary="@string/overview_fullscreen_thumbnails_desc" /> + <com.android.systemui.tuner.TunerSwitch + android:key="overview_show_history" + android:title="@string/overview_show_history" + android:summary="@string/overview_show_history_desc" /> + </PreferenceScreen> <SwitchPreference diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java index 16b159250f7e..66a5106502fc 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java @@ -27,6 +27,7 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.ActivityInfo; +import android.graphics.Rect; import android.net.Uri; import android.os.Bundle; import android.os.SystemClock; @@ -46,10 +47,12 @@ import com.android.systemui.recents.events.activity.CancelEnterRecentsWindowAnim import com.android.systemui.recents.events.activity.DebugFlagsChangedEvent; import com.android.systemui.recents.events.activity.EnterRecentsWindowAnimationCompletedEvent; import com.android.systemui.recents.events.activity.EnterRecentsWindowLastAnimationFrameEvent; +import com.android.systemui.recents.events.activity.HideHistoryEvent; import com.android.systemui.recents.events.activity.HideRecentsEvent; import com.android.systemui.recents.events.activity.IterateRecentsEvent; import com.android.systemui.recents.events.activity.LaunchTaskFailedEvent; import com.android.systemui.recents.events.activity.LaunchTaskSucceededEvent; +import com.android.systemui.recents.events.activity.ShowHistoryEvent; import com.android.systemui.recents.events.activity.ToggleRecentsEvent; import com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent; import com.android.systemui.recents.events.component.ScreenPinningRequestEvent; @@ -65,6 +68,7 @@ import com.android.systemui.recents.events.ui.dragndrop.DragStartEvent; import com.android.systemui.recents.events.ui.focus.DismissFocusedTaskViewEvent; import com.android.systemui.recents.events.ui.focus.FocusNextTaskViewEvent; import com.android.systemui.recents.events.ui.focus.FocusPreviousTaskViewEvent; +import com.android.systemui.recents.history.RecentsHistoryView; import com.android.systemui.recents.misc.DozeTrigger; import com.android.systemui.recents.misc.ReferenceCountedTrigger; import com.android.systemui.recents.misc.SystemServicesProxy; @@ -99,6 +103,8 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD private SystemBarScrimViews mScrimViews; private ViewStub mEmptyViewStub; private View mEmptyView; + private ViewStub mHistoryViewStub; + private RecentsHistoryView mHistoryView; // Resize task debug private RecentsResizeTaskDialog mResizeTaskDebugDialog; @@ -260,6 +266,18 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD } /** + * Dismisses the history view back into the stack view. + */ + boolean dismissHistory() { + // Try and hide the history view first + if (mHistoryView != null && mHistoryView.isVisible()) { + EventBus.getDefault().send(new HideHistoryEvent(true /* animate */)); + return true; + } + return false; + } + + /** * Dismisses recents if we are already visible and the intent is to toggle the recents view. */ boolean dismissRecentsToFocusedTask() { @@ -349,6 +367,7 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); mEmptyViewStub = (ViewStub) findViewById(R.id.empty_view_stub); + mHistoryViewStub = (ViewStub) findViewById(R.id.history_view_stub); mScrimViews = new SystemBarScrimViews(this); getWindow().getAttributes().privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY; @@ -432,6 +451,9 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD // Reset some states mIgnoreAltTabRelease = false; + if (mHistoryView != null) { + EventBus.getDefault().send(new HideHistoryEvent(false /* animate */)); + } // Notify that recents is now hidden SystemServicesProxy ssp = Recents.getSystemServices(); @@ -550,8 +572,9 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD @Override public void onBackPressed() { - // Dismiss Recents to the focused Task or Home - dismissRecentsToFocusedTaskOrHome(); + if (!dismissHistory()) { + dismissRecentsToFocusedTaskOrHome(); + } } /**** RecentsResizeTaskDialog ****/ @@ -566,7 +589,9 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD /**** EventBus events ****/ public final void onBusEvent(ToggleRecentsEvent event) { - dismissRecentsToFocusedTaskOrHome(); + if (!dismissHistory()) { + dismissRecentsToFocusedTaskOrHome(); + } } public final void onBusEvent(IterateRecentsEvent event) { @@ -596,7 +621,21 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD } } else if (event.triggeredFromHomeKey) { // Otherwise, dismiss Recents to Home - dismissRecentsToHome(true /* animated */); + if (mHistoryView != null && mHistoryView.isVisible()) { + ReferenceCountedTrigger t = new ReferenceCountedTrigger(this, null, null, null); + t.increment(); + t.addLastDecrementRunnable(new Runnable() { + @Override + public void run() { + dismissRecentsToHome(true /* animated */); + } + }); + EventBus.getDefault().send(new HideHistoryEvent(true, t)); + t.decrement(); + + } else { + dismissRecentsToHome(true /* animated */); + } } else { // Do nothing } @@ -726,6 +765,23 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD mIgnoreAltTabRelease = true; } + public final void onBusEvent(ShowHistoryEvent event) { + if (mHistoryView == null) { + mHistoryView = (RecentsHistoryView) mHistoryViewStub.inflate(); + // Since this history view is inflated by a view stub after the insets have already + // been applied, we have to set them ourselves initial from the insets that were last + // provided. + mHistoryView.setSystemInsets(mRecentsView.getSystemInsets()); + } + mHistoryView.show(mRecentsView.getTaskStack()); + } + + public final void onBusEvent(HideHistoryEvent event) { + if (mHistoryView != null) { + mHistoryView.hide(event.animate, event.postAnimationTrigger); + } + } + private void refreshSearchWidgetView() { if (mSearchWidgetInfo != null) { SystemServicesProxy ssp = Recents.getSystemServices(); diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsDebugFlags.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsDebugFlags.java index 67d711587885..e8b88165721c 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsDebugFlags.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsDebugFlags.java @@ -29,6 +29,7 @@ public class RecentsDebugFlags implements TunerService.Tunable { private static final String KEY_FAST_TOGGLE = "overview_fast_toggle"; private static final String KEY_PAGE_ON_TOGGLE = "overview_page_on_toggle"; private static final String KEY_FULLSCREEN_THUMBNAILS = "overview_fullscreen_thumbnails"; + private static final String KEY_SHOW_HISTORY = "overview_show_history"; public static class Static { // Enables debug drawing for the transition thumbnail @@ -52,6 +53,7 @@ public class RecentsDebugFlags implements TunerService.Tunable { private boolean mFastToggleRecents; private boolean mPageOnToggle; private boolean mUseFullscreenThumbnails; + private boolean mShowHistory; /** * We read the prefs once when we start the activity, then update them as the tuner changes @@ -61,7 +63,7 @@ public class RecentsDebugFlags implements TunerService.Tunable { // Register all our flags, this will also call onTuningChanged() for each key, which will // initialize the current state of each flag TunerService.get(context).addTunable(this, KEY_FAST_TOGGLE, KEY_PAGE_ON_TOGGLE, - KEY_FULLSCREEN_THUMBNAILS); + KEY_FULLSCREEN_THUMBNAILS, KEY_SHOW_HISTORY); } /** @@ -85,6 +87,13 @@ public class RecentsDebugFlags implements TunerService.Tunable { return mUseFullscreenThumbnails; } + /** + * @return whether we should show the history + */ + public boolean isHistoryEnabled() { + return mShowHistory; + } + @Override public void onTuningChanged(String key, String newValue) { switch (key) { @@ -100,6 +109,10 @@ public class RecentsDebugFlags implements TunerService.Tunable { mUseFullscreenThumbnails = (newValue != null) && (Integer.parseInt(newValue) != 0); break; + case KEY_SHOW_HISTORY: + mShowHistory = (newValue != null) && + (Integer.parseInt(newValue) != 0); + break; } EventBus.getDefault().send(new DebugFlagsChangedEvent()); } diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/HideHistoryButtonEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/HideHistoryButtonEvent.java new file mode 100644 index 000000000000..6c767e414450 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/recents/events/activity/HideHistoryButtonEvent.java @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2015 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.recents.events.activity; + +import com.android.systemui.recents.events.EventBus; + +/** + * This is sent when the history view button should be hidden. + */ +public class HideHistoryButtonEvent extends EventBus.Event { + // Simple event +} diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/HideHistoryEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/HideHistoryEvent.java new file mode 100644 index 000000000000..34c35a7be4fc --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/recents/events/activity/HideHistoryEvent.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2015 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.recents.events.activity; + +import com.android.systemui.recents.events.EventBus; +import com.android.systemui.recents.misc.ReferenceCountedTrigger; + +/** + * This is sent when the history view will be closed. + */ +public class HideHistoryEvent extends EventBus.Event { + + public final boolean animate; + public final ReferenceCountedTrigger postAnimationTrigger; + + public HideHistoryEvent(boolean animate) { + this(animate, null); + } + + public HideHistoryEvent(boolean animate, ReferenceCountedTrigger postAnimationTrigger) { + this.animate = animate; + this.postAnimationTrigger = postAnimationTrigger; + } +} diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/ShowHistoryButtonEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/ShowHistoryButtonEvent.java new file mode 100644 index 000000000000..7042537ea7a6 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/recents/events/activity/ShowHistoryButtonEvent.java @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2015 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.recents.events.activity; + +import com.android.systemui.recents.events.EventBus; + +/** + * This is sent when the history view button should be shown. + */ +public class ShowHistoryButtonEvent extends EventBus.Event { + // Simple event +} diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/ShowHistoryEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/ShowHistoryEvent.java new file mode 100644 index 000000000000..870119d59d2e --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/recents/events/activity/ShowHistoryEvent.java @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2015 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.recents.events.activity; + +import com.android.systemui.recents.events.EventBus; + +/** + * This is sent when the history view button is clicked. + */ +public class ShowHistoryEvent extends EventBus.Event { + // Simple event +} diff --git a/packages/SystemUI/src/com/android/systemui/recents/history/RecentsHistoryAdapter.java b/packages/SystemUI/src/com/android/systemui/recents/history/RecentsHistoryAdapter.java new file mode 100644 index 000000000000..273f7bf705df --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/recents/history/RecentsHistoryAdapter.java @@ -0,0 +1,192 @@ +/* + * Copyright (C) 2015 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.recents.history; + +import android.app.ActivityOptions; +import android.content.Context; +import android.content.res.Resources; +import android.support.v7.widget.RecyclerView; +import android.text.format.DateFormat; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; +import com.android.systemui.R; +import com.android.systemui.recents.Recents; +import com.android.systemui.recents.misc.SystemServicesProxy; +import com.android.systemui.recents.model.Task; +import com.android.systemui.recents.model.TaskStack; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collections; +import java.util.List; +import java.util.Locale; +import java.util.Objects; + + +/** + * An adapter for the list of recent tasks in the history view. + */ +public class RecentsHistoryAdapter extends RecyclerView.Adapter<RecentsHistoryAdapter.ViewHolder> { + + private static final String TAG = "RecentsHistoryView"; + private static final boolean DEBUG = false; + + static final int DATE_ROW_VIEW_TYPE = 0; + static final int TASK_ROW_VIEW_TYPE = 1; + + /** + * View holder implementation. + */ + public static class ViewHolder extends RecyclerView.ViewHolder { + public View mContent; + + public ViewHolder(View v) { + super(v); + mContent = v; + } + } + + /** + * A single row of content. + */ + private interface Row { + int getViewType(); + } + + /** + * A date row. + */ + private static class DateRow implements Row { + + public final String date; + + public DateRow(String date) { + this.date = date; + } + + @Override + public int getViewType() { + return RecentsHistoryAdapter.DATE_ROW_VIEW_TYPE; + } + } + + /** + * A task row. + */ + private static class TaskRow implements Row, View.OnClickListener { + + public final String description; + private final int mTaskId; + + public TaskRow(Task task) { + mTaskId = task.key.id; + description = task.activityLabel; + } + + @Override + public void onClick(View v) { + SystemServicesProxy ssp = Recents.getSystemServices(); + ssp.startActivityFromRecents(v.getContext(), mTaskId, description, + ActivityOptions.makeBasic()); + } + + @Override + public int getViewType() { + return RecentsHistoryAdapter.TASK_ROW_VIEW_TYPE; + } + } + + private LayoutInflater mLayoutInflater; + private final List<Row> mRows = new ArrayList<>(); + + public RecentsHistoryAdapter(Context context, TaskStack stack) { + mLayoutInflater = LayoutInflater.from(context); + updateTasks(context, stack.getTasks()); + } + + /** + * Updates this adapter with the given tasks. + */ + public void updateTasks(Context context, List<Task> tasks) { + final Locale l = context.getResources().getConfiguration().locale; + final String dateFormatStr = DateFormat.getBestDateTimePattern(l, "EEEEMMMMd"); + final List<Task> tasksMostRecent = new ArrayList<>(tasks); + Collections.reverse(tasksMostRecent); + int prevDayKey = -1; + mRows.clear(); + for (Task task : tasksMostRecent) { + if (SystemServicesProxy.isFreeformStack(task.key.stackId)) { + continue; + } + + Calendar cal = Calendar.getInstance(l); + cal.setTimeInMillis(task.key.lastActiveTime); + int dayKey = Objects.hash(cal.get(Calendar.YEAR), cal.get(Calendar.DAY_OF_YEAR)); + if (dayKey != prevDayKey) { + prevDayKey = dayKey; + mRows.add(new DateRow(DateFormat.format(dateFormatStr, cal).toString())); + } + mRows.add(new TaskRow(task)); + } + } + + @Override + public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + switch (viewType) { + case DATE_ROW_VIEW_TYPE: + return new ViewHolder(mLayoutInflater.inflate(R.layout.recents_history_date, parent, + false)); + case TASK_ROW_VIEW_TYPE: + return new ViewHolder(mLayoutInflater.inflate(R.layout.recents_history_task, parent, + false)); + default: + return new ViewHolder(null); + } + } + + @Override + public void onBindViewHolder(ViewHolder holder, int position) { + Row row = mRows.get(position); + int viewType = mRows.get(position).getViewType(); + switch (viewType) { + case DATE_ROW_VIEW_TYPE: { + TextView tv = (TextView) holder.mContent; + tv.setText(((DateRow) row).date); + break; + } + case TASK_ROW_VIEW_TYPE: { + TextView tv = (TextView) holder.mContent; + TaskRow taskRow = (TaskRow) row; + tv.setText(taskRow.description); + tv.setOnClickListener(taskRow); + break; + } + } + } + + @Override + public int getItemCount() { + return mRows.size(); + } + + @Override + public int getItemViewType(int position) { + return mRows.get(position).getViewType(); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/recents/history/RecentsHistoryView.java b/packages/SystemUI/src/com/android/systemui/recents/history/RecentsHistoryView.java new file mode 100644 index 000000000000..1ad79aea56a9 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/recents/history/RecentsHistoryView.java @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2015 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.recents.history; + +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Rect; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.util.AttributeSet; +import android.view.View; +import android.view.WindowInsets; +import android.view.animation.AnimationUtils; +import android.view.animation.Interpolator; +import android.widget.LinearLayout; + +import com.android.systemui.R; +import com.android.systemui.recents.RecentsActivity; +import com.android.systemui.recents.events.EventBus; +import com.android.systemui.recents.misc.ReferenceCountedTrigger; +import com.android.systemui.recents.model.TaskStack; + +/** + * A list of the recent tasks that are not in the stack. + */ +public class RecentsHistoryView extends LinearLayout { + + private static final String TAG = "RecentsHistoryView"; + private static final boolean DEBUG = false; + + private RecyclerView mRecyclerView; + private boolean mIsVisible; + + private Interpolator mFastOutSlowInInterpolator; + private Interpolator mFastOutLinearInInterpolator; + private int mHistoryTransitionDuration; + + public RecentsHistoryView(Context context) { + super(context); + } + + public RecentsHistoryView(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public RecentsHistoryView(Context context, AttributeSet attrs, int defStyleAttr) { + this(context, attrs, defStyleAttr, 0); + } + + public RecentsHistoryView(Context context, AttributeSet attrs, int defStyleAttr, + int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + Resources res = context.getResources(); + mHistoryTransitionDuration = res.getInteger(R.integer.recents_history_transition_duration); + mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(context, + com.android.internal.R.interpolator.fast_out_slow_in); + mFastOutLinearInInterpolator = AnimationUtils.loadInterpolator(context, + com.android.internal.R.interpolator.fast_out_linear_in); + } + + /** + * Updates this history view with the recent tasks, and then shows it. + */ + public void show(TaskStack stack) { + setVisibility(View.VISIBLE); + setAlpha(0f); + animate() + .alpha(1f) + .setDuration(mHistoryTransitionDuration) + .setInterpolator(mFastOutSlowInInterpolator) + .withLayer() + .start(); + + mRecyclerView.setAdapter(new RecentsHistoryAdapter(getContext(), stack)); + mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext())); + mIsVisible = true; + } + + /** + * Hides this history view. + */ + public void hide(boolean animate, final ReferenceCountedTrigger postAnimationTrigger) { + if (animate) { + animate() + .alpha(0f) + .setDuration(mHistoryTransitionDuration) + .setInterpolator(mFastOutLinearInInterpolator) + .withEndAction(new Runnable() { + @Override + public void run() { + setVisibility(View.INVISIBLE); + if (postAnimationTrigger != null) { + postAnimationTrigger.decrement(); + } + } + }) + .withLayer() + .start(); + if (postAnimationTrigger != null) { + postAnimationTrigger.increment(); + } + } else { + setAlpha(0f); + setVisibility(View.INVISIBLE); + } + mIsVisible = false; + } + + /** + * Updates the system insets of this history view to the provided values. + */ + public void setSystemInsets(Rect systemInsets) { + setPadding(systemInsets.left, systemInsets.top, systemInsets.right, systemInsets.bottom); + } + + /** + * Returns whether this view is visible. + */ + public boolean isVisible() { + return mIsVisible; + } + + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + mRecyclerView = (RecyclerView) findViewById(R.id.list); + } + + @Override + public WindowInsets onApplyWindowInsets(WindowInsets insets) { + setSystemInsets(insets.getSystemWindowInsets()); + return insets; + } +} diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java index 90456c0838d7..d700786086b0 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java @@ -17,6 +17,7 @@ package com.android.systemui.recents.views; import android.content.Context; +import android.content.res.Resources; import android.graphics.Canvas; import android.graphics.Rect; import android.graphics.drawable.Drawable; @@ -25,20 +26,26 @@ import android.util.ArraySet; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.MotionEvent; +import android.view.View; import android.view.WindowInsets; import android.view.animation.AnimationUtils; import android.view.animation.Interpolator; import android.widget.FrameLayout; -import com.android.internal.logging.MetricsLogger; import com.android.systemui.R; import com.android.systemui.recents.Recents; import com.android.systemui.recents.RecentsActivity; import com.android.systemui.recents.RecentsActivityLaunchState; import com.android.systemui.recents.RecentsAppWidgetHostView; import com.android.systemui.recents.RecentsConfiguration; +import com.android.systemui.recents.RecentsDebugFlags; import com.android.systemui.recents.events.EventBus; import com.android.systemui.recents.events.activity.CancelEnterRecentsWindowAnimationEvent; +import com.android.systemui.recents.events.activity.DebugFlagsChangedEvent; import com.android.systemui.recents.events.activity.DismissRecentsToHomeAnimationStarted; +import com.android.systemui.recents.events.activity.HideHistoryButtonEvent; +import com.android.systemui.recents.events.activity.HideHistoryEvent; +import com.android.systemui.recents.events.activity.ShowHistoryButtonEvent; +import com.android.systemui.recents.events.activity.ShowHistoryEvent; import com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent; import com.android.systemui.recents.events.ui.DraggingInRecentsEndedEvent; import com.android.systemui.recents.events.ui.DraggingInRecentsEvent; @@ -63,11 +70,12 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV private static final String TAG = "RecentsView"; private static final boolean DEBUG = false; - LayoutInflater mInflater; Handler mHandler; + TaskStack mStack; TaskStackView mTaskStackView; RecentsAppWidgetHostView mSearchBar; + View mHistoryButton; boolean mAwaitingFirstLayout = true; boolean mLastTaskLaunchedWasFreeform; @@ -81,7 +89,9 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV TaskStack.DockState.BOTTOM, }; - Interpolator mFastOutSlowInInterpolator; + private Interpolator mFastOutSlowInInterpolator; + private Interpolator mFastOutLinearInInterpolator; + private int mHistoryTransitionDuration; Rect mSystemInsets = new Rect(); @@ -99,18 +109,31 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV public RecentsView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); + Resources res = context.getResources(); setWillNotDraw(false); - mInflater = LayoutInflater.from(context); mHandler = new Handler(); mTransitionHelper = new RecentsTransitionHelper(getContext(), mHandler); mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(context, com.android.internal.R.interpolator.fast_out_slow_in); + mFastOutLinearInInterpolator = AnimationUtils.loadInterpolator(context, + com.android.internal.R.interpolator.fast_out_linear_in); + mHistoryTransitionDuration = res.getInteger(R.integer.recents_history_transition_duration); mTouchHandler = new RecentsViewTouchHandler(this); + + LayoutInflater inflater = LayoutInflater.from(context); + mHistoryButton = inflater.inflate(R.layout.recents_history_button, this, false); + mHistoryButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + EventBus.getDefault().send(new ShowHistoryEvent()); + } + }); } /** Set/get the bsp root node */ public void setTaskStack(TaskStack stack) { RecentsConfiguration config = Recents.getConfiguration(); + mStack = stack; if (config.getLaunchState().launchedReuseTaskStackViews) { if (mTaskStackView != null) { // If onRecentsHidden is not triggered, we need to the stack view again here @@ -129,6 +152,11 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV mTaskStackView.setCallbacks(this); addView(mTaskStackView); } + if (indexOfChild(mHistoryButton) == -1) { + addView(mHistoryButton); + } else { + mHistoryButton.bringToFront(); + } // Trigger a new layout requestLayout(); @@ -141,6 +169,13 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV return mLastTaskLaunchedWasFreeform; } + /** + * Returns the currently set task stack. + */ + public TaskStack getTaskStack() { + return mStack; + } + /** Gets the next task in the stack - or if the last - the top task */ public Task getNextTaskOrTopTask(Task taskToSearch) { Task returnTask = null; @@ -219,10 +254,15 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV } ctx.postAnimationTrigger.decrement(); + // Hide the history button + int taskViewExitToHomeDuration = getResources().getInteger( + R.integer.recents_task_exit_to_home_duration); + hideHistoryButton(taskViewExitToHomeDuration); + // If we are going home, cancel the previous task's window transition EventBus.getDefault().send(new CancelEnterRecentsWindowAnimationEvent(null)); - // Notify of the exit animation + // Notify sof the exit animation EventBus.getDefault().send(new DismissRecentsToHomeAnimationStarted()); } @@ -253,6 +293,13 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV } } + /** + * Returns the last known system insets. + */ + public Rect getSystemInsets() { + return mSystemInsets; + } + @Override protected void onAttachedToWindow() { EventBus.getDefault().register(this, RecentsActivity.EVENT_BUS_PRIORITY + 1); @@ -301,6 +348,10 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV MeasureSpec.makeMeasureSpec(taskRect.height(), MeasureSpec.AT_MOST)); } + Rect stackRect = mTaskStackView.mLayoutAlgorithm.mCurrentStackRect; + measureChild(mHistoryButton, + MeasureSpec.makeMeasureSpec(stackRect.width(), MeasureSpec.EXACTLY), + heightMeasureSpec); setMeasuredDimension(width, height); } @@ -330,6 +381,11 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV top + mDragView.getMeasuredHeight()); } + Rect stackRect = mTaskStackView.mLayoutAlgorithm.mCurrentStackRect; + mHistoryButton.layout(stackRect.left, stackRect.top, + stackRect.left + mHistoryButton.getMeasuredWidth(), + stackRect.top + mHistoryButton.getMeasuredHeight()); + if (mAwaitingFirstLayout) { mAwaitingFirstLayout = false; @@ -346,7 +402,7 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV public WindowInsets onApplyWindowInsets(WindowInsets insets) { mSystemInsets.set(insets.getSystemWindowInsets()); requestLayout(); - return insets.consumeSystemWindowInsets(); + return insets; } @Override @@ -492,6 +548,67 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV animate().translationY(0f); } + public final void onBusEvent(ShowHistoryEvent event) { + // Hide the history button when the history view is shown + hideHistoryButton(mHistoryTransitionDuration); + } + + public final void onBusEvent(HideHistoryEvent event) { + // Show the history button when the history view is hidden + showHistoryButton(mHistoryTransitionDuration); + } + + public final void onBusEvent(ShowHistoryButtonEvent event) { + showHistoryButton(150); + } + + public final void onBusEvent(HideHistoryButtonEvent event) { + hideHistoryButton(100); + } + + public final void onBusEvent(DebugFlagsChangedEvent event) { + RecentsDebugFlags debugFlags = Recents.getDebugFlags(); + if (!debugFlags.isHistoryEnabled()) { + hideHistoryButton(100); + } + } + + /** + * Shows the history button. + */ + private void showHistoryButton(int duration) { + RecentsDebugFlags debugFlags = Recents.getDebugFlags(); + if (!debugFlags.isHistoryEnabled()) { + return; + } + + mHistoryButton.setVisibility(View.VISIBLE); + mHistoryButton.animate() + .alpha(1f) + .setDuration(duration) + .setInterpolator(mFastOutSlowInInterpolator) + .withLayer() + .start(); + } + + /** + * Hides the history button. + */ + private void hideHistoryButton(int duration) { + mHistoryButton.animate() + .alpha(0f) + .setDuration(duration) + .setInterpolator(mFastOutLinearInInterpolator) + .withEndAction(new Runnable() { + @Override + public void run() { + mHistoryButton.setVisibility(View.INVISIBLE); + } + }) + .withLayer() + .start(); + } + /** * Updates the dock region to match the specified dock state. */ diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java index 5d091b19e4e6..1acc9433b9fa 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java @@ -573,7 +573,7 @@ public class TaskStackLayoutAlgorithm { (mCurrentStackRect.height() - mTaskRect.height()) / 2; y = centerYOffset + getYForDeltaP(p, 0); z = mMaxTranslationZ; - relP = p; + relP = 1f; } else { // Otherwise, update the task to the stack layout diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java index 67710bfd6294..04a14e4d31f3 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java @@ -42,8 +42,12 @@ import com.android.systemui.recents.RecentsDebugFlags; import com.android.systemui.recents.events.EventBus; import com.android.systemui.recents.events.activity.CancelEnterRecentsWindowAnimationEvent; import com.android.systemui.recents.events.activity.EnterRecentsWindowAnimationCompletedEvent; +import com.android.systemui.recents.events.activity.HideHistoryButtonEvent; +import com.android.systemui.recents.events.activity.HideHistoryEvent; import com.android.systemui.recents.events.activity.IterateRecentsEvent; import com.android.systemui.recents.events.activity.PackagesChangedEvent; +import com.android.systemui.recents.events.activity.ShowHistoryButtonEvent; +import com.android.systemui.recents.events.activity.ShowHistoryEvent; import com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent; import com.android.systemui.recents.events.ui.AllTaskViewsDismissedEvent; import com.android.systemui.recents.events.ui.DismissTaskViewEvent; @@ -82,6 +86,10 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal private final static String TAG = "TaskStackView"; private final static boolean DEBUG = false; + // The thresholds at which to show/hide the history button. + private static final float SHOW_HISTORY_BUTTON_SCROLL_THRESHOLD = 0.3f; + private static final float HIDE_HISTORY_BUTTON_SCROLL_THRESHOLD = 0.3f; + /** The TaskView callbacks */ interface TaskStackViewCallbacks { public void onTaskViewClicked(TaskStackView stackView, TaskView tv, TaskStack stack, Task t, @@ -1017,6 +1025,11 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal false /* requestViewFocus */); } + // Update the history button visibility + if (mStackScroller.getStackScroll() < SHOW_HISTORY_BUTTON_SCROLL_THRESHOLD) { + EventBus.getDefault().send(new ShowHistoryButtonEvent()); + } + // Start dozing mUIDozeTrigger.startDozing(); } @@ -1333,10 +1346,18 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal /**** TaskStackViewScroller.TaskStackViewScrollerCallbacks ****/ @Override - public void onScrollChanged(float p) { + public void onScrollChanged(float prevScroll, float curScroll) { mUIDozeTrigger.poke(); requestSynchronizeStackViewsWithModel(); postInvalidateOnAnimation(); + + if (prevScroll > SHOW_HISTORY_BUTTON_SCROLL_THRESHOLD && + curScroll <= SHOW_HISTORY_BUTTON_SCROLL_THRESHOLD) { + EventBus.getDefault().send(new ShowHistoryButtonEvent()); + } else if (prevScroll < HIDE_HISTORY_BUTTON_SCROLL_THRESHOLD && + curScroll >= HIDE_HISTORY_BUTTON_SCROLL_THRESHOLD) { + EventBus.getDefault().send(new HideHistoryButtonEvent()); + } } /**** EventBus Events ****/ @@ -1496,15 +1517,30 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal } } + public final void onBusEvent(ShowHistoryEvent event) { + List<TaskView> taskViews = getTaskViews(); + int taskViewCount = taskViews.size(); + for (int i = taskViewCount - 1; i >= 0; i--) { + TaskView tv = taskViews.get(i); + tv.animate().alpha(0f).setDuration(200).start(); + } + } + + public final void onBusEvent(HideHistoryEvent event) { + List<TaskView> taskViews = getTaskViews(); + int taskViewCount = taskViews.size(); + for (int i = taskViewCount - 1; i >= 0; i--) { + TaskView tv = taskViews.get(i); + tv.animate().alpha(1f).setDuration(200).start(); + } + } + /** * Removes the task from the stack, and updates the focus to the next task in the stack if the * removed TaskView was focused. */ private void removeTaskViewFromStack(TaskView tv) { - SystemServicesProxy ssp = Recents.getSystemServices(); Task task = tv.getTask(); - int taskIndex = mStack.indexOfTask(task); - boolean taskWasFocused = tv.isFocusedTask(); // Reset the previously focused task before it is removed from the stack resetFocusedTask(); diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java index 62b640ee36f9..90b73fe2757d 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java @@ -35,7 +35,7 @@ public class TaskStackViewScroller { private static final boolean DEBUG = false; public interface TaskStackViewScrollerCallbacks { - void onScrollChanged(float p); + void onScrollChanged(float prevScroll, float curScroll); } Context mContext; @@ -78,9 +78,10 @@ public class TaskStackViewScroller { /** Sets the current stack scroll */ public void setStackScroll(float s) { + float prevStackScroll = mStackScrollP; mStackScrollP = s; if (mCb != null) { - mCb.onScrollChanged(mStackScrollP); + mCb.onScrollChanged(prevStackScroll, mStackScrollP); } } diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java index 523f84f4adb7..44985d44fc0f 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java @@ -71,7 +71,7 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, ObjectAnimator mTaskProgressAnimator; float mMaxDimScale; int mDimAlpha; - AccelerateInterpolator mDimInterpolator = new AccelerateInterpolator(1f); + AccelerateInterpolator mDimInterpolator = new AccelerateInterpolator(3f); PorterDuffColorFilter mDimColorFilter = new PorterDuffColorFilter(0, PorterDuff.Mode.SRC_ATOP); Paint mDimLayerPaint = new Paint(); float mActionButtonTranslationZ; @@ -265,15 +265,6 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, toTransform.translationZ = 0; } - /** - * When we are un/filtering, this method will setup the transform that we are animating from, - * in order to show the task. - */ - void prepareTaskTransformForFilterTaskVisible(TaskViewTransform fromTransform) { - // Fade the view in - fromTransform.alpha = 0f; - } - /** Prepares this task view for the enter-recents animations. This is called earlier in the * first layout because the actual animation into recents may take a long time. */ void prepareEnterRecentsAnimation(boolean isTaskViewLaunchTargetTask, boolean hideTask, @@ -617,12 +608,9 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, /** Compute the dim as a function of the scale of this view. */ int getDimFromTaskProgress() { - // TODO: Temporarily disable the dim on the stack - /* - float dim = mMaxDimScale * mDimInterpolator.getInterpolation(1f - mTaskProgress); + float x = mTaskProgress < 0 ? 1f : mDimInterpolator.getInterpolation(1f - mTaskProgress); + float dim = mMaxDimScale * x; return (int) (dim * 255); - */ - return 0; } /** Update the dim as a function of the scale of this view. */ diff --git a/packages/SystemUI/tests/Android.mk b/packages/SystemUI/tests/Android.mk index fdc254312157..9cf64d347e4a 100644 --- a/packages/SystemUI/tests/Android.mk +++ b/packages/SystemUI/tests/Android.mk @@ -37,7 +37,10 @@ LOCAL_JAVA_LIBRARIES := android.test.runner telephony-common LOCAL_PACKAGE_NAME := SystemUITests -LOCAL_STATIC_JAVA_LIBRARIES := mockito-target Keyguard +LOCAL_STATIC_JAVA_LIBRARIES := \ + mockito-target \ + Keyguard \ + android-support-v7-recyclerview # sign this with platform cert, so this test is allowed to inject key events into # UI it doesn't own. This is necessary to allow screenshots to be taken |