Merge "Remove unused DHCP timeout event tag." into nyc-dev
diff --git a/core/java/android/hardware/input/InputDeviceIdentifier.java b/core/java/android/hardware/input/InputDeviceIdentifier.java
index 5e832e3..801da88 100644
--- a/core/java/android/hardware/input/InputDeviceIdentifier.java
+++ b/core/java/android/hardware/input/InputDeviceIdentifier.java
@@ -16,8 +16,11 @@
package android.hardware.input;
+import java.util.Objects;
+
import android.os.Parcel;
import android.os.Parcelable;
+import android.text.TextUtils;
/**
* Wrapper for passing identifying information for input devices.
@@ -65,6 +68,21 @@
return mProductId;
}
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || !(o instanceof InputDeviceIdentifier)) return false;
+
+ final InputDeviceIdentifier that = (InputDeviceIdentifier) o;
+ return ((mVendorId == that.mVendorId) && (mProductId == that.mProductId)
+ && TextUtils.equals(mDescriptor, that.mDescriptor));
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mDescriptor, mVendorId, mProductId);
+ }
+
public static final Parcelable.Creator<InputDeviceIdentifier> CREATOR =
new Parcelable.Creator<InputDeviceIdentifier>() {
diff --git a/packages/DocumentsUI/src/com/android/documentsui/OpenExternalDirectoryActivity.java b/packages/DocumentsUI/src/com/android/documentsui/OpenExternalDirectoryActivity.java
index 854be0b..b0e5e4e 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/OpenExternalDirectoryActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/OpenExternalDirectoryActivity.java
@@ -212,6 +212,12 @@
break;
}
}
+ if (internalRoot == null) {
+ // Should not happen on normal circumstances, unless app crafted an invalid volume
+ // using reflection or the list of mounted volumes changed.
+ Log.e(TAG, "Didn't find right volume for '" + storageVolume.dump() + "' on " + volumes);
+ return false;
+ }
// Checks if the user has granted the permission already.
final Intent intent = getIntentForExistingPermission(activity, isRoot, internalRoot, file);
diff --git a/packages/SystemUI/res/layout/brightness_mirror.xml b/packages/SystemUI/res/layout/brightness_mirror.xml
new file mode 100644
index 0000000..bbaff6a
--- /dev/null
+++ b/packages/SystemUI/res/layout/brightness_mirror.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2016 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
+ -->
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/brightness_mirror"
+ android:layout_width="@dimen/notification_panel_width"
+ android:layout_height="wrap_content"
+ android:layout_gravity="@integer/notification_panel_layout_gravity"
+ android:visibility="invisible">
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@drawable/brightness_mirror_background"
+ android:elevation="2dp">
+ <include layout="@layout/quick_settings_brightness_dialog"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"/>
+ </FrameLayout>
+</FrameLayout>
diff --git a/packages/SystemUI/res/layout/recents_stack_action_button.xml b/packages/SystemUI/res/layout/recents_stack_action_button.xml
index 625e9c1..43b3de1 100644
--- a/packages/SystemUI/res/layout/recents_stack_action_button.xml
+++ b/packages/SystemUI/res/layout/recents_stack_action_button.xml
@@ -32,4 +32,5 @@
android:shadowRadius="5"
android:fontFamily="sans-serif-medium"
android:background="?android:selectableItemBackground"
- android:visibility="invisible" />
+ android:visibility="invisible"
+ android:forceHasOverlappingRendering="false" />
diff --git a/packages/SystemUI/res/layout/signal_cluster_view.xml b/packages/SystemUI/res/layout/signal_cluster_view.xml
index 9df5dbf..d17601c 100644
--- a/packages/SystemUI/res/layout/signal_cluster_view.xml
+++ b/packages/SystemUI/res/layout/signal_cluster_view.xml
@@ -19,6 +19,7 @@
<!-- extends LinearLayout -->
<com.android.systemui.statusbar.SignalClusterView
xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/signal_cluster"
android:layout_height="match_parent"
android:layout_width="wrap_content"
android:gravity="center_vertical"
diff --git a/packages/SystemUI/res/layout/super_status_bar.xml b/packages/SystemUI/res/layout/super_status_bar.xml
index 7c4ce15..285a8ec 100644
--- a/packages/SystemUI/res/layout/super_status_bar.xml
+++ b/packages/SystemUI/res/layout/super_status_bar.xml
@@ -62,21 +62,7 @@
android:layout_width="match_parent"
android:layout_height="@dimen/status_bar_height" />
- <FrameLayout android:id="@+id/brightness_mirror"
- android:layout_width="@dimen/notification_panel_width"
- android:layout_height="wrap_content"
- android:layout_gravity="@integer/notification_panel_layout_gravity"
- android:visibility="invisible">
- <FrameLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:elevation="2dp"
- android:background="@drawable/brightness_mirror_background">
- <include layout="@layout/quick_settings_brightness_dialog"
- android:layout_width="match_parent"
- android:layout_height="wrap_content" />
- </FrameLayout>
- </FrameLayout>
+ <include layout="@layout/brightness_mirror" />
<ViewStub android:id="@+id/fullscreen_user_switcher_stub"
android:layout="@layout/car_fullscreen_user_switcher"
diff --git a/packages/SystemUI/res/layout/system_icons.xml b/packages/SystemUI/res/layout/system_icons.xml
index e9448db..3a33992 100644
--- a/packages/SystemUI/res/layout/system_icons.xml
+++ b/packages/SystemUI/res/layout/system_icons.xml
@@ -27,7 +27,6 @@
android:orientation="horizontal"/>
<include layout="@layout/signal_cluster_view"
- android:id="@+id/signal_cluster"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/signal_cluster_margin_start"/>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 03b9837..5043610 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -640,6 +640,9 @@
<!-- The amount of overscroll allowed when flinging to the end of the stack. -->
<dimen name="recents_fling_overscroll_distance">24dp</dimen>
+ <!-- The size of the drag hint text. -->
+ <dimen name="recents_drag_hint_text_size">14sp</dimen>
+
<!-- The min alpha to apply to a task affiliation group color. -->
<item name="recents_task_affiliation_color_min_alpha_percentage" format="float" type="dimen">0.6</item>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 37b00bb..a03aa28 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -737,6 +737,8 @@
<string name="recents_stack_action_button_label">Clear all</string>
<!-- Recents: Incompatible task message. [CHAR LIMIT=NONE] -->
<string name="recents_incompatible_app_message">App doesn\'t support split screen</string>
+ <!-- Recents: Hint text that shows on the drop targets to start multiwindow. [CHAR LIMIT=NONE] -->
+ <string name="recents_drag_hint_message">Drag here to use split screen</string>
<!-- Recents: MultiStack add stack split horizontal radio button. [CHAR LIMIT=NONE] -->
<string name="recents_multistack_add_stack_dialog_split_horizontal">Split Horizontal</string>
diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
index e838191..9a6fa9c 100644
--- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
@@ -51,11 +51,9 @@
private float SWIPE_ESCAPE_VELOCITY = 100f; // dp/sec
private int DEFAULT_ESCAPE_ANIMATION_DURATION = 200; // ms
private int MAX_ESCAPE_ANIMATION_DURATION = 400; // ms
- private int MAX_DISMISS_VELOCITY = 2000; // dp/sec
+ private int MAX_DISMISS_VELOCITY = 4000; // dp/sec
private static final int SNAP_ANIM_LEN = SLOW_ANIMATIONS ? 1000 : 150; // ms
- public static float SWIPE_PROGRESS_FADE_START = 0f; // fraction of thumbnail width
- // where fade starts
static final float SWIPE_PROGRESS_FADE_END = 0.5f; // fraction of thumbnail width
// beyond which swipe progress->0
private float mMinSwipeProgress = 0f;
@@ -102,8 +100,7 @@
mFalsingThreshold = context.getResources().getDimensionPixelSize(
R.dimen.swipe_helper_falsing_threshold);
mFalsingManager = FalsingManager.getInstance(context);
- mFlingAnimationUtils = new FlingAnimationUtils(context,
- MAX_ESCAPE_ANIMATION_DURATION / 1000f /* maxLengthSeconds */);
+ mFlingAnimationUtils = new FlingAnimationUtils(context, getMaxEscapeAnimDuration() / 1000f);
}
public void setLongPressListener(LongPressListener listener) {
@@ -183,21 +180,23 @@
mMaxSwipeProgress = maxSwipeProgress;
}
- private float getSwipeProgressForOffset(View view) {
+ private float getSwipeProgressForOffset(View view, float translation) {
float viewSize = getSize(view);
- final float fadeSize = SWIPE_PROGRESS_FADE_END * viewSize;
- float result = 1.0f;
- float pos = getTranslation(view);
- if (pos >= viewSize * SWIPE_PROGRESS_FADE_START) {
- result = 1.0f - (pos - viewSize * SWIPE_PROGRESS_FADE_START) / fadeSize;
- } else if (pos < viewSize * (1.0f - SWIPE_PROGRESS_FADE_START)) {
- result = 1.0f + (viewSize * SWIPE_PROGRESS_FADE_START + pos) / fadeSize;
- }
+ float result = Math.abs(translation / viewSize);
return Math.min(Math.max(mMinSwipeProgress, result), mMaxSwipeProgress);
}
+ private float getSwipeAlpha(float progress) {
+ return Math.min(0, Math.max(1, progress / SWIPE_PROGRESS_FADE_END));
+ }
+
private void updateSwipeProgressFromOffset(View animView, boolean dismissable) {
- float swipeProgress = getSwipeProgressForOffset(animView);
+ updateSwipeProgressFromOffset(animView, dismissable, getTranslation(animView));
+ }
+
+ private void updateSwipeProgressFromOffset(View animView, boolean dismissable,
+ float translation) {
+ float swipeProgress = getSwipeProgressForOffset(animView, translation);
if (!mCallback.updateSwipeProgress(animView, dismissable, swipeProgress)) {
if (FADE_OUT_DURING_SWIPE && dismissable) {
float alpha = swipeProgress;
@@ -208,7 +207,7 @@
animView.setLayerType(View.LAYER_TYPE_NONE, null);
}
}
- animView.setAlpha(getSwipeProgressForOffset(animView));
+ animView.setAlpha(getSwipeAlpha(swipeProgress));
}
}
invalidateGlobalRegion(animView);
@@ -485,7 +484,7 @@
* view is being animated to dismiss or snap.
*/
public void onTranslationUpdate(View animView, float value, boolean canBeDismissed) {
- updateSwipeProgressFromOffset(animView, canBeDismissed);
+ updateSwipeProgressFromOffset(animView, canBeDismissed, value);
}
private void snapChildInstantly(final View view) {
@@ -600,7 +599,15 @@
}
protected float getEscapeVelocity() {
- return SWIPE_ESCAPE_VELOCITY * mDensityScale;
+ return getUnscaledEscapeVelocity() * mDensityScale;
+ }
+
+ protected float getUnscaledEscapeVelocity() {
+ return SWIPE_ESCAPE_VELOCITY;
+ }
+
+ protected long getMaxEscapeAnimDuration() {
+ return MAX_ESCAPE_ANIMATION_DURATION;
}
protected boolean swipedFarEnough() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/PageIndicator.java b/packages/SystemUI/src/com/android/systemui/qs/PageIndicator.java
index e050b0d..9239ded 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/PageIndicator.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/PageIndicator.java
@@ -120,9 +120,8 @@
}
ImageView first = (ImageView) getChildAt(firstIndex);
ImageView second = (ImageView) getChildAt(secondIndex);
- if (second == null) {
- // Weird state where number of pages must not have propagated yet.
- return;
+ if (first == null || second == null) {
+ // may happen during reInflation or other weird cases
}
// Lay the two views on top of each other.
second.setTranslationX(first.getX() - second.getX());
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index 4d69280..2040833 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -99,6 +99,7 @@
private RecentsPackageMonitor mPackageMonitor;
private long mLastTabKeyEventTime;
private int mLastDeviceOrientation = Configuration.ORIENTATION_UNDEFINED;
+ private int mLastDisplayDensity;
private boolean mFinishedOnStartup;
private boolean mIgnoreAltTabRelease;
private boolean mIsVisible;
@@ -276,7 +277,9 @@
getWindow().getAttributes().privateFlags |=
WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY;
- mLastDeviceOrientation = Utilities.getAppConfiguration(this).orientation;
+ Configuration appConfiguration = Utilities.getAppConfiguration(this);
+ mLastDeviceOrientation = appConfiguration.orientation;
+ mLastDisplayDensity = appConfiguration.densityDpi;
mFocusTimerDuration = getResources().getInteger(R.integer.recents_auto_advance_duration);
mIterateTrigger = new DozeTrigger(mFocusTimerDuration, new Runnable() {
@Override
@@ -349,7 +352,7 @@
loader.loadTasks(this, loadPlan, loadOpts);
TaskStack stack = loadPlan.getTaskStack();
mRecentsView.onReload(mIsVisible, stack.getTaskCount() == 0);
- mRecentsView.updateStack(stack);
+ mRecentsView.updateStack(stack, true /* setStackViewTasks */);
// Update the nav bar scrim, but defer the animation until the enter-window event
boolean animateNavBarScrim = !launchState.launchedViaDockGesture;
@@ -427,11 +430,13 @@
super.onConfigurationChanged(newConfig);
// Notify of the config change
- int newDeviceOrientation = Utilities.getAppConfiguration(this).orientation;
+ Configuration newDeviceConfiguration = Utilities.getAppConfiguration(this);
int numStackTasks = mRecentsView.getStack().getStackTaskCount();
EventBus.getDefault().send(new ConfigurationChangedEvent(false /* fromMultiWindow */,
- (mLastDeviceOrientation != newDeviceOrientation), numStackTasks > 0));
- mLastDeviceOrientation = newDeviceOrientation;
+ mLastDeviceOrientation != newDeviceConfiguration.orientation,
+ mLastDisplayDensity != newDeviceConfiguration.densityDpi, numStackTasks > 0));
+ mLastDeviceOrientation = newDeviceConfiguration.orientation;
+ mLastDisplayDensity = newDeviceConfiguration.densityDpi;
}
@Override
@@ -454,14 +459,9 @@
int numStackTasks = stack.getStackTaskCount();
EventBus.getDefault().send(new ConfigurationChangedEvent(true /* fromMultiWindow */,
- false /* fromDeviceOrientationChange */, numStackTasks > 0));
-
- if (mRecentsView != null) {
- mRecentsView.updateStack(stack);
- }
-
- EventBus.getDefault().send(new MultiWindowStateChangedEvent(isInMultiWindowMode,
+ false /* fromDeviceOrientationChange */, false /* fromDisplayDensityChange */,
numStackTasks > 0));
+ EventBus.getDefault().send(new MultiWindowStateChangedEvent(isInMultiWindowMode, stack));
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
index 0413bc9..3ecada9 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
@@ -560,7 +560,7 @@
com.android.internal.R.dimen.navigation_bar_height);
mNavBarWidth = res.getDimensionPixelSize(
com.android.internal.R.dimen.navigation_bar_width);
- mTaskBarHeight = TaskStackLayoutAlgorithm.getDimensionForDevice(res,
+ mTaskBarHeight = TaskStackLayoutAlgorithm.getDimensionForDevice(mContext,
R.dimen.recents_task_view_header_height,
R.dimen.recents_task_view_header_height,
R.dimen.recents_task_view_header_height,
@@ -771,8 +771,9 @@
if (icon != null) {
icon.setCallback(null);
}
- mHeaderBar.rebindToTask(toTask, false /* touchExplorationEnabled */,
+ mHeaderBar.bindToTask(toTask, false /* touchExplorationEnabled */,
disabledInSafeMode);
+ mHeaderBar.onTaskDataLoaded();
mHeaderBar.setDimAlpha(toTransform.dimAlpha);
mHeaderBar.draw(c);
c.setBitmap(null);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/ConfigurationChangedEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/ConfigurationChangedEvent.java
index 53b67cf..294c1e7 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/ConfigurationChangedEvent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/activity/ConfigurationChangedEvent.java
@@ -25,12 +25,14 @@
public final boolean fromMultiWindow;
public final boolean fromDeviceOrientationChange;
+ public final boolean fromDisplayDensityChange;
public final boolean hasStackTasks;
public ConfigurationChangedEvent(boolean fromMultiWindow, boolean fromDeviceOrientationChange,
- boolean hasStackTasks) {
+ boolean fromDisplayDensityChange, boolean hasStackTasks) {
this.fromMultiWindow = fromMultiWindow;
this.fromDeviceOrientationChange = fromDeviceOrientationChange;
+ this.fromDisplayDensityChange = fromDisplayDensityChange;
this.hasStackTasks = hasStackTasks;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/MultiWindowStateChangedEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/MultiWindowStateChangedEvent.java
index cf2a68e..11649fb 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/MultiWindowStateChangedEvent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/activity/MultiWindowStateChangedEvent.java
@@ -17,17 +17,18 @@
package com.android.systemui.recents.events.activity;
import com.android.systemui.recents.events.EventBus;
+import com.android.systemui.recents.model.TaskStack;
/**
* This is sent by the activity whenever the multi-window state has changed.
*/
-public class MultiWindowStateChangedEvent extends EventBus.Event {
+public class MultiWindowStateChangedEvent extends EventBus.AnimatedEvent {
public final boolean inMultiWindow;
- public final boolean hasStackTasks;
+ public final TaskStack stack;
- public MultiWindowStateChangedEvent(boolean inMultiWindow, boolean hasStackTasks) {
+ public MultiWindowStateChangedEvent(boolean inMultiWindow, TaskStack stack) {
this.inMultiWindow = inMultiWindow;
- this.hasStackTasks = hasStackTasks;
+ this.stack = stack;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
index 75d5ec5..6f1a69c 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -951,18 +951,6 @@
}
/**
- * Returns the current display orientation.
- */
- public int getDisplayOrientation() {
- // Because of multi-window, the configuration orientation does not necessarily reflect the
- // orientation of the display, instead we just use the display's real-size.
- Rect displayRect = getDisplayRect();
- return displayRect.width() > displayRect.height()
- ? Configuration.ORIENTATION_LANDSCAPE
- : Configuration.ORIENTATION_PORTRAIT;
- }
-
- /**
* Returns the window rect for the RecentsActivity, based on the dimensions of the home stack.
*/
public Rect getWindowRect() {
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 82c81ae..fb92971 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
@@ -353,23 +353,15 @@
/**
* Acquires the task resource data directly from the cache, loading if necessary.
- *
- * @param fetchAndInvalidateThumbnails If set, will try loading thumbnails, invalidating them
- * in the cache and loading if necessary. Otherwise, do not
- * load the thumbnail unless the icon also has to be loaded.
*/
- public void loadTaskData(Task t, boolean fetchAndInvalidateThumbnails) {
+ public void loadTaskData(Task t) {
Drawable icon = mIconCache.getAndInvalidateIfModified(t.key);
Bitmap thumbnail = null;
ActivityManager.TaskThumbnailInfo thumbnailInfo = null;
- if (fetchAndInvalidateThumbnails) {
- ThumbnailData thumbnailData = mThumbnailCache.getAndInvalidateIfModified(t.key);
- if (thumbnailData != null) {
- thumbnail = thumbnailData.thumbnail;
- thumbnailInfo = thumbnailData.thumbnailInfo;
- }
- } else {
- thumbnail = mDefaultThumbnail;
+ ThumbnailData thumbnailData = mThumbnailCache.getAndInvalidateIfModified(t.key);
+ if (thumbnailData != null) {
+ thumbnail = thumbnailData.thumbnail;
+ thumbnailInfo = thumbnailData.thumbnailInfo;
}
// Grab the thumbnail/icon from the cache, if either don't exist, then trigger a reload and
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 95e276f..47995c4 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
@@ -30,17 +30,21 @@
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
-import android.animation.RectEvaluator;
+import android.annotation.IntDef;
import android.content.ComponentName;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
+import android.graphics.Canvas;
import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.ColorDrawable;
import android.util.ArrayMap;
import android.util.ArraySet;
+import android.util.IntProperty;
import android.util.SparseArray;
import android.view.animation.Interpolator;
@@ -56,6 +60,8 @@
import com.android.systemui.recents.views.TaskStackLayoutAlgorithm;
import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@@ -240,22 +246,30 @@
*/
public static class DockState implements DropTarget {
+ // The rotation to apply to the hint text
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({HORIZONTAL, VERTICAL})
+ public @interface TextOrientation {}
+ private static final int HORIZONTAL = 0;
+ private static final int VERTICAL = 1;
+
private static final int DOCK_AREA_ALPHA = 192;
- public static final DockState NONE = new DockState(DOCKED_INVALID, -1, 80, null, null, null);
+ public static final DockState NONE = new DockState(DOCKED_INVALID, -1, 80, 255, HORIZONTAL,
+ null, null, null);
public static final DockState LEFT = new DockState(DOCKED_LEFT,
- DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT, DOCK_AREA_ALPHA,
+ DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT, DOCK_AREA_ALPHA, 0, VERTICAL,
new RectF(0, 0, 0.125f, 1), new RectF(0, 0, 0.125f, 1),
new RectF(0, 0, 0.5f, 1));
public static final DockState TOP = new DockState(DOCKED_TOP,
- DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT, DOCK_AREA_ALPHA,
+ DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT, DOCK_AREA_ALPHA, 0, HORIZONTAL,
new RectF(0, 0, 1, 0.125f), new RectF(0, 0, 1, 0.125f),
new RectF(0, 0, 1, 0.5f));
public static final DockState RIGHT = new DockState(DOCKED_RIGHT,
- DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT, DOCK_AREA_ALPHA,
+ DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT, DOCK_AREA_ALPHA, 0, VERTICAL,
new RectF(0.875f, 0, 1, 1), new RectF(0.875f, 0, 1, 1),
new RectF(0.5f, 0, 1, 1));
public static final DockState BOTTOM = new DockState(DOCKED_BOTTOM,
- DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT, DOCK_AREA_ALPHA,
+ DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT, DOCK_AREA_ALPHA, 0, HORIZONTAL,
new RectF(0, 0.875f, 1, 1), new RectF(0, 0.875f, 1, 1),
new RectF(0, 0.5f, 1, 1));
@@ -267,33 +281,109 @@
}
// Represents the view state of this dock state
- public class ViewState {
+ public static class ViewState {
+ private static final IntProperty<ViewState> HINT_ALPHA =
+ new IntProperty<ViewState>("drawableAlpha") {
+ @Override
+ public void setValue(ViewState object, int alpha) {
+ object.mHintTextAlpha = alpha;
+ object.dockAreaOverlay.invalidateSelf();
+ }
+
+ @Override
+ public Integer get(ViewState object) {
+ return object.mHintTextAlpha;
+ }
+ };
+
public final int dockAreaAlpha;
public final ColorDrawable dockAreaOverlay;
- private AnimatorSet dockAreaOverlayAnimator;
+ public final int hintTextAlpha;
+ public final int hintTextOrientation;
- private ViewState(int alpha) {
- dockAreaAlpha = alpha;
+ private final int mHintTextResId;
+ private String mHintText;
+ private Paint mHintTextPaint;
+ private Point mHintTextBounds = new Point();
+ private int mHintTextAlpha = 255;
+ private AnimatorSet mDockAreaOverlayAnimator;
+ private Rect mTmpRect = new Rect();
+
+ private ViewState(int areaAlpha, int hintAlpha, @TextOrientation int hintOrientation,
+ int hintTextResId) {
+ dockAreaAlpha = areaAlpha;
dockAreaOverlay = new ColorDrawable(0xFFffffff);
dockAreaOverlay.setAlpha(0);
+ hintTextAlpha = hintAlpha;
+ hintTextOrientation = hintOrientation;
+ mHintTextResId = hintTextResId;
+ mHintTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ mHintTextPaint.setColor(Color.WHITE);
+ }
+
+ /**
+ * Updates the view state with the given context.
+ */
+ public void update(Context context) {
+ Resources res = context.getResources();
+ mHintText = context.getString(mHintTextResId);
+ mHintTextPaint.setTextSize(res.getDimensionPixelSize(
+ R.dimen.recents_drag_hint_text_size));
+ mHintTextPaint.getTextBounds(mHintText, 0, mHintText.length(), mTmpRect);
+ mHintTextBounds.set((int) mHintTextPaint.measureText(mHintText), mTmpRect.height());
+ }
+
+ /**
+ * Draws the current view state.
+ */
+ public void draw(Canvas canvas) {
+ // Draw the overlay background
+ if (dockAreaOverlay.getAlpha() > 0) {
+ dockAreaOverlay.draw(canvas);
+ }
+
+ // Draw the hint text
+ if (mHintTextAlpha > 0) {
+ Rect bounds = dockAreaOverlay.getBounds();
+ int x = bounds.left + (bounds.width() - mHintTextBounds.x) / 2;
+ int y = bounds.top + (bounds.height() + mHintTextBounds.y) / 2;
+ mHintTextPaint.setAlpha(mHintTextAlpha);
+ if (hintTextOrientation == VERTICAL) {
+ canvas.save();
+ canvas.rotate(-90f, bounds.centerX(), bounds.centerY());
+ }
+ canvas.drawText(mHintText, x, y, mHintTextPaint);
+ if (hintTextOrientation == VERTICAL) {
+ canvas.restore();
+ }
+ }
}
/**
* Creates a new bounds and alpha animation.
*/
- public void startAnimation(Rect bounds, int alpha, int duration,
+ public void startAnimation(Rect bounds, int areaAlpha, int hintAlpha, int duration,
Interpolator interpolator, boolean animateAlpha, boolean animateBounds) {
- if (dockAreaOverlayAnimator != null) {
- dockAreaOverlayAnimator.cancel();
+ if (mDockAreaOverlayAnimator != null) {
+ mDockAreaOverlayAnimator.cancel();
}
ArrayList<Animator> animators = new ArrayList<>();
- if (dockAreaOverlay.getAlpha() != alpha) {
+ if (dockAreaOverlay.getAlpha() != areaAlpha) {
if (animateAlpha) {
animators.add(ObjectAnimator.ofInt(dockAreaOverlay,
- Utilities.DRAWABLE_ALPHA, dockAreaOverlay.getAlpha(), alpha));
+ Utilities.DRAWABLE_ALPHA, dockAreaOverlay.getAlpha(), areaAlpha));
} else {
- dockAreaOverlay.setAlpha(alpha);
+ dockAreaOverlay.setAlpha(areaAlpha);
+ }
+ }
+ if (mHintTextAlpha != hintAlpha) {
+ if (animateAlpha) {
+ animators.add(ObjectAnimator.ofInt(this, HINT_ALPHA, mHintTextAlpha,
+ hintAlpha));
+ } else {
+ mHintTextAlpha = hintAlpha;
+ dockAreaOverlay.invalidateSelf();
}
}
if (bounds != null && !dockAreaOverlay.getBounds().equals(bounds)) {
@@ -307,11 +397,11 @@
}
}
if (!animators.isEmpty()) {
- dockAreaOverlayAnimator = new AnimatorSet();
- dockAreaOverlayAnimator.playTogether(animators);
- dockAreaOverlayAnimator.setDuration(duration);
- dockAreaOverlayAnimator.setInterpolator(interpolator);
- dockAreaOverlayAnimator.start();
+ mDockAreaOverlayAnimator = new AnimatorSet();
+ mDockAreaOverlayAnimator.playTogether(animators);
+ mDockAreaOverlayAnimator.setDuration(duration);
+ mDockAreaOverlayAnimator.setInterpolator(interpolator);
+ mDockAreaOverlayAnimator.start();
}
}
}
@@ -331,17 +421,26 @@
* the initial touch area. This is also the new dock area to
* draw.
*/
- DockState(int dockSide, int createMode, int dockAreaAlpha, RectF touchArea, RectF dockArea,
+ DockState(int dockSide, int createMode, int dockAreaAlpha, int hintTextAlpha,
+ @TextOrientation int hintTextOrientation, RectF touchArea, RectF dockArea,
RectF expandedTouchDockArea) {
this.dockSide = dockSide;
this.createMode = createMode;
- this.viewState = new ViewState(dockAreaAlpha);
+ this.viewState = new ViewState(dockAreaAlpha, hintTextAlpha, hintTextOrientation,
+ R.string.recents_drag_hint_message);
this.dockArea = dockArea;
this.touchArea = touchArea;
this.expandedTouchDockArea = expandedTouchDockArea;
}
/**
+ * Updates the dock state with the given context.
+ */
+ public void update(Context context) {
+ viewState.update(context);
+ }
+
+ /**
* Returns whether {@param x} and {@param y} are contained in the area scaled to the
* given {@param width} and {@param height}.
*/
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
index db5413f..04f10ef8 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
@@ -286,10 +286,9 @@
// Calculate the offscreen task rect (for tasks that are not backed by views)
float stackScroll = stackView.getScroller().getStackScroll();
TaskView taskView = stackView.getChildViewForTask(task);
- TaskStackLayoutAlgorithm layoutAlgorithm = stackView.getStackAlgorithm();
- Rect offscreenTaskRect = new Rect(layoutAlgorithm.mTaskRect);
- offscreenTaskRect.offsetTo(offscreenTaskRect.left,
- layoutAlgorithm.mStackRect.bottom);
+ TaskStackLayoutAlgorithm stackLayout = stackView.getStackAlgorithm();
+ Rect offscreenTaskRect = new Rect();
+ stackLayout.getFrontOfStackTransform().rect.round(offscreenTaskRect);
// If this is a full screen stack, the transition will be towards the single, full screen
// task. We only need the transition spec for this task.
@@ -302,8 +301,8 @@
if (taskView == null) {
specs.add(composeOffscreenAnimationSpec(task, offscreenTaskRect));
} else {
- layoutAlgorithm.getStackTransformScreenCoordinates(task, stackScroll, mTmpTransform,
- null);
+ mTmpTransform.fillIn(taskView);
+ stackLayout.transformToScreenCoordinates(mTmpTransform);
specs.add(composeAnimationSpec(stackView, taskView, mTmpTransform,
true /* addHeaderBitmap */));
}
@@ -324,8 +323,8 @@
// never happen)
specs.add(composeOffscreenAnimationSpec(t, offscreenTaskRect));
} else {
- layoutAlgorithm.getStackTransformScreenCoordinates(t, stackScroll,
- mTmpTransform, null);
+ mTmpTransform.fillIn(taskView);
+ stackLayout.transformToScreenCoordinates(mTmpTransform);
specs.add(composeAnimationSpec(stackView, tv, mTmpTransform,
true /* addHeaderBitmap */));
}
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 d55c7d8..6ecd52d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -57,6 +57,7 @@
import com.android.systemui.recents.events.activity.EnterRecentsWindowAnimationCompletedEvent;
import com.android.systemui.recents.events.activity.HideStackActionButtonEvent;
import com.android.systemui.recents.events.activity.LaunchTaskEvent;
+import com.android.systemui.recents.events.activity.MultiWindowStateChangedEvent;
import com.android.systemui.recents.events.activity.ShowStackActionButtonEvent;
import com.android.systemui.recents.events.ui.AllTaskViewsDismissedEvent;
import com.android.systemui.recents.events.ui.DismissAllTaskViewsEvent;
@@ -91,7 +92,7 @@
private static final int DEFAULT_UPDATE_SCRIM_DURATION = 200;
private static final float DEFAULT_SCRIM_ALPHA = 0.33f;
- private static final int SHOW_STACK_ACTION_BUTTON_DURATION = 150;
+ private static final int SHOW_STACK_ACTION_BUTTON_DURATION = 134;
private static final int HIDE_STACK_ACTION_BUTTON_DURATION = 100;
private TaskStack mStack;
@@ -143,7 +144,6 @@
R.dimen.recents_task_view_rounded_corners_radius);
mStackActionButton = (TextView) inflater.inflate(R.layout.recents_stack_action_button,
this, false);
- mStackActionButton.forceHasOverlappingRendering(false);
mStackActionButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
@@ -203,9 +203,11 @@
/**
* Called from RecentsActivity when the task stack is updated.
*/
- public void updateStack(TaskStack stack) {
+ public void updateStack(TaskStack stack, boolean setStackViewTasks) {
mStack = stack;
- mTaskStackView.setTasks(stack, true /* allowNotifyStackChanges */);
+ if (setStackViewTasks) {
+ mTaskStackView.setTasks(stack, true /* allowNotifyStackChanges */);
+ }
// Update the top level view's visibilities
if (stack.getTaskCount() > 0) {
@@ -424,10 +426,7 @@
ArrayList<TaskStack.DockState> visDockStates = mTouchHandler.getVisibleDockStates();
for (int i = visDockStates.size() - 1; i >= 0; i--) {
- Drawable d = visDockStates.get(i).viewState.dockAreaOverlay;
- if (d.getAlpha() > 0) {
- d.draw(canvas);
- }
+ visDockStates.get(i).viewState.draw(canvas);
}
}
@@ -463,18 +462,29 @@
public final void onBusEvent(DragStartEvent event) {
updateVisibleDockRegions(mTouchHandler.getDockStatesForCurrentOrientation(),
true /* isDefaultDockState */, TaskStack.DockState.NONE.viewState.dockAreaAlpha,
+ TaskStack.DockState.NONE.viewState.hintTextAlpha,
true /* animateAlpha */, false /* animateBounds */);
+
+ // Temporarily hide the stack action button without changing visibility
+ if (mStackActionButton != null) {
+ mStackActionButton.animate()
+ .alpha(0f)
+ .setDuration(HIDE_STACK_ACTION_BUTTON_DURATION)
+ .setInterpolator(Interpolators.ALPHA_OUT)
+ .start();
+ }
}
public final void onBusEvent(DragDropTargetChangedEvent event) {
if (event.dropTarget == null || !(event.dropTarget instanceof TaskStack.DockState)) {
updateVisibleDockRegions(mTouchHandler.getDockStatesForCurrentOrientation(),
true /* isDefaultDockState */, TaskStack.DockState.NONE.viewState.dockAreaAlpha,
+ TaskStack.DockState.NONE.viewState.hintTextAlpha,
true /* animateAlpha */, true /* animateBounds */);
} else {
final TaskStack.DockState dockState = (TaskStack.DockState) event.dropTarget;
updateVisibleDockRegions(new TaskStack.DockState[] {dockState},
- false /* isDefaultDockState */, -1, true /* animateAlpha */,
+ false /* isDefaultDockState */, -1, -1, true /* animateAlpha */,
true /* animateBounds */);
}
if (mStackActionButton != null) {
@@ -496,13 +506,9 @@
final TaskStack.DockState dockState = (TaskStack.DockState) event.dropTarget;
// Hide the dock region
- updateVisibleDockRegions(null, false /* isDefaultDockState */, -1,
+ updateVisibleDockRegions(null, false /* isDefaultDockState */, -1, -1,
false /* animateAlpha */, false /* animateBounds */);
- TaskStackLayoutAlgorithm stackLayout = mTaskStackView.getStackAlgorithm();
- TaskStackViewScroller stackScroller = mTaskStackView.getScroller();
- TaskViewTransform tmpTransform = new TaskViewTransform();
-
// We translated the view but we need to animate it back from the current layout-space
// rect to its final layout-space rect
int x = (int) event.taskView.getTranslationX();
@@ -546,9 +552,18 @@
event.task.getTopComponent().flattenToShortString());
} else {
// Animate the overlay alpha back to 0
- updateVisibleDockRegions(null, true /* isDefaultDockState */, -1,
+ updateVisibleDockRegions(null, true /* isDefaultDockState */, -1, -1,
true /* animateAlpha */, false /* animateBounds */);
}
+
+ // Show the stack action button again without changing visibility
+ if (mStackActionButton != null) {
+ mStackActionButton.animate()
+ .alpha(1f)
+ .setDuration(SHOW_STACK_ACTION_BUTTON_DURATION)
+ .setInterpolator(Interpolators.ALPHA_IN)
+ .start();
+ }
}
private Rect getTaskRect(TaskView taskView) {
@@ -622,6 +637,10 @@
hideStackActionButton(HIDE_STACK_ACTION_BUTTON_DURATION, true /* translate */);
}
+ public final void onBusEvent(MultiWindowStateChangedEvent event) {
+ updateStack(event.stack, false /* setStackViewTasks */);
+ }
+
/**
* Shows the stack action button.
*/
@@ -704,8 +723,8 @@
* Updates the dock region to match the specified dock state.
*/
private void updateVisibleDockRegions(TaskStack.DockState[] newDockStates,
- boolean isDefaultDockState, int overrideAlpha, boolean animateAlpha,
- boolean animateBounds) {
+ boolean isDefaultDockState, int overrideAreaAlpha, int overrideHintAlpha,
+ boolean animateAlpha, boolean animateBounds) {
ArraySet<TaskStack.DockState> newDockStatesSet = Utilities.arrayToSet(newDockStates,
new ArraySet<TaskStack.DockState>());
ArrayList<TaskStack.DockState> visDockStates = mTouchHandler.getVisibleDockStates();
@@ -714,11 +733,16 @@
TaskStack.DockState.ViewState viewState = dockState.viewState;
if (newDockStates == null || !newDockStatesSet.contains(dockState)) {
// This is no longer visible, so hide it
- viewState.startAnimation(null, 0, DOCK_AREA_OVERLAY_TRANSITION_DURATION,
+ viewState.startAnimation(null, 0, 0, DOCK_AREA_OVERLAY_TRANSITION_DURATION,
Interpolators.ALPHA_OUT, animateAlpha, animateBounds);
} else {
// This state is now visible, update the bounds and show it
- int alpha = (overrideAlpha != -1 ? overrideAlpha : viewState.dockAreaAlpha);
+ int areaAlpha = overrideAreaAlpha != -1
+ ? overrideAreaAlpha
+ : viewState.dockAreaAlpha;
+ int hintAlpha = overrideHintAlpha != -1
+ ? overrideHintAlpha
+ : viewState.hintTextAlpha;
Rect bounds = isDefaultDockState
? dockState.getPreDockedBounds(getMeasuredWidth(), getMeasuredHeight())
: dockState.getDockedBounds(getMeasuredWidth(), getMeasuredHeight(),
@@ -727,8 +751,9 @@
viewState.dockAreaOverlay.setCallback(this);
viewState.dockAreaOverlay.setBounds(bounds);
}
- viewState.startAnimation(bounds, alpha, DOCK_AREA_OVERLAY_TRANSITION_DURATION,
- Interpolators.ALPHA_IN, animateAlpha, animateBounds);
+ viewState.startAnimation(bounds, areaAlpha, hintAlpha,
+ DOCK_AREA_OVERLAY_TRANSITION_DURATION, Interpolators.ALPHA_IN,
+ animateAlpha, animateBounds);
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java
index 70c4dbd..6115aa8 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java
@@ -171,6 +171,7 @@
TaskStack.DockState[] dockStates = getDockStatesForCurrentOrientation();
for (TaskStack.DockState dockState : dockStates) {
registerDropTargetForCurrentDrag(dockState);
+ dockState.update(mRv.getContext());
mVisibleDockStates.add(dockState);
}
}
@@ -192,7 +193,9 @@
}
public final void onBusEvent(ConfigurationChangedEvent event) {
- updateSnapAlgorithm();
+ if (event.fromDisplayDensityChange) {
+ updateSnapAlgorithm();
+ }
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/SystemBarScrimViews.java b/packages/SystemUI/src/com/android/systemui/recents/views/SystemBarScrimViews.java
index dce2353..2f3019c 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/SystemBarScrimViews.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/SystemBarScrimViews.java
@@ -41,7 +41,8 @@
private boolean mHasNavBarScrim;
private boolean mShouldAnimateNavBarScrim;
-
+ private boolean mHasTransposedNavBar;
+ private boolean mHasDockedTasks;
private int mNavBarScrimEnterDuration;
public SystemBarScrimViews(RecentsActivity activity) {
@@ -50,6 +51,8 @@
mNavBarScrimView.forceHasOverlappingRendering(false);
mNavBarScrimEnterDuration = activity.getResources().getInteger(
R.integer.recents_nav_bar_scrim_enter_duration);
+ mHasNavBarScrim = Recents.getSystemServices().hasTransposedNavBar();
+ mHasDockedTasks = Recents.getSystemServices().hasDockedTask();
}
/**
@@ -101,8 +104,7 @@
* @return Whether to show the nav bar scrim.
*/
private boolean isNavBarScrimRequired(boolean hasStackTasks) {
- SystemServicesProxy ssp = Recents.getSystemServices();
- return hasStackTasks && !ssp.hasTransposedNavBar() && !ssp.hasDockedTask();
+ return hasStackTasks && !mHasTransposedNavBar && !mHasDockedTasks;
}
/**** EventBus events ****/
@@ -142,11 +144,15 @@
}
public final void onBusEvent(ConfigurationChangedEvent event) {
+ if (event.fromDeviceOrientationChange) {
+ mHasNavBarScrim = Recents.getSystemServices().hasTransposedNavBar();
+ }
animateScrimToCurrentNavBarState(event.hasStackTasks);
}
public final void onBusEvent(MultiWindowStateChangedEvent event) {
- animateScrimToCurrentNavBarState(event.hasStackTasks);
+ mHasDockedTasks = event.inMultiWindow;
+ animateScrimToCurrentNavBarState(event.stack.getStackTaskCount() > 0);
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java
index 665d9ad..e79306f 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java
@@ -485,7 +485,7 @@
// Get the final set of task transforms
mStackView.getLayoutTaskTransforms(newScroll, stackLayout.getFocusState(), stackTasks,
- mTmpFinalTaskTransforms);
+ true /* ignoreTaskOverrides */, mTmpFinalTaskTransforms);
// Focus the task view
TaskView newFocusedTaskView = mStackView.getChildViewForTask(newFocusedTask);
@@ -529,7 +529,7 @@
int duration;
Interpolator interpolator;
if (willScrollToFront) {
- duration = Math.max(100, 100 + ((i - 1) * 50));
+ duration = calculateStaggeredAnimDuration(i);
interpolator = FOCUS_BEHIND_NEXT_TASK_INTERPOLATOR;
} else {
if (i < newFocusTaskViewIndex) {
@@ -553,4 +553,100 @@
}
return willScroll;
}
+
+ /**
+ * Starts the animation to go to the initial stack layout with a task focused. In addition, the
+ * previous task will be animated in after the scroll completes.
+ */
+ public void startNewStackScrollAnimation(TaskStack newStack,
+ ReferenceCountedTrigger animationTrigger) {
+ TaskStackLayoutAlgorithm stackLayout = mStackView.getStackAlgorithm();
+ TaskStackViewScroller stackScroller = mStackView.getScroller();
+
+ // Get the current set of task transforms
+ ArrayList<Task> stackTasks = newStack.getStackTasks();
+ mStackView.getCurrentTaskTransforms(stackTasks, mTmpCurrentTaskTransforms);
+
+ // Update the stack
+ mStackView.setTasks(newStack, false /* allowNotifyStackChanges */);
+ mStackView.updateLayoutAlgorithm(false /* boundScroll */);
+
+ // Pick up the newly visible views after the scroll
+ final float newScroll = stackLayout.mInitialScrollP;
+ mStackView.bindVisibleTaskViews(newScroll);
+
+ // Update the internal state
+ stackLayout.setFocusState(TaskStackLayoutAlgorithm.STATE_UNFOCUSED);
+ stackLayout.setTaskOverridesForInitialState(newStack, true /* ignoreScrollToFront */);
+ stackScroller.setStackScroll(newScroll);
+ mStackView.cancelDeferredTaskViewLayoutAnimation();
+
+ // Get the final set of task transforms
+ mStackView.getLayoutTaskTransforms(newScroll, stackLayout.getFocusState(), stackTasks,
+ false /* ignoreTaskOverrides */, mTmpFinalTaskTransforms);
+
+ // Hide the front most task view until the scroll is complete
+ Task frontMostTask = newStack.getStackFrontMostTask(false /* includeFreeform */);
+ final TaskView frontMostTaskView = mStackView.getChildViewForTask(frontMostTask);
+ final TaskViewTransform frontMostTransform = mTmpFinalTaskTransforms.get(
+ stackTasks.indexOf(frontMostTask));
+ if (frontMostTaskView != null) {
+ mStackView.updateTaskViewToTransform(frontMostTaskView,
+ stackLayout.getFrontOfStackTransform(), AnimationProps.IMMEDIATE);
+ }
+
+ // Setup the end listener to return all the hidden views to the view pool after the
+ // focus animation
+ animationTrigger.addLastDecrementRunnable(new Runnable() {
+ @Override
+ public void run() {
+ mStackView.bindVisibleTaskViews(newScroll);
+
+ // Now, animate in the front-most task
+ if (frontMostTaskView != null) {
+ mStackView.updateTaskViewToTransform(frontMostTaskView, frontMostTransform,
+ new AnimationProps(75, 200, FOCUS_BEHIND_NEXT_TASK_INTERPOLATOR));
+ }
+ }
+ });
+
+ List<TaskView> taskViews = mStackView.getTaskViews();
+ int taskViewCount = taskViews.size();
+ for (int i = 0; i < taskViewCount; i++) {
+ TaskView tv = taskViews.get(i);
+ Task task = tv.getTask();
+
+ if (mStackView.isIgnoredTask(task)) {
+ continue;
+ }
+ if (task == frontMostTask && frontMostTaskView != null) {
+ continue;
+ }
+
+ int taskIndex = stackTasks.indexOf(task);
+ TaskViewTransform fromTransform = mTmpCurrentTaskTransforms.get(taskIndex);
+ TaskViewTransform toTransform = mTmpFinalTaskTransforms.get(taskIndex);
+
+ // Update the task to the initial state (for the newly picked up tasks)
+ mStackView.updateTaskViewToTransform(tv, fromTransform, AnimationProps.IMMEDIATE);
+
+ int duration = calculateStaggeredAnimDuration(i);
+ Interpolator interpolator = FOCUS_BEHIND_NEXT_TASK_INTERPOLATOR;
+
+ AnimationProps anim = new AnimationProps()
+ .setDuration(AnimationProps.BOUNDS, duration)
+ .setInterpolator(AnimationProps.BOUNDS, interpolator)
+ .setListener(animationTrigger.decrementOnAnimationEnd());
+ animationTrigger.increment();
+ mStackView.updateTaskViewToTransform(tv, toTransform, anim);
+ }
+ }
+
+ /**
+ * Caclulates a staggered duration for {@link #startScrollToFocusedTaskAnimation} and
+ * {@link #startNewStackScrollAnimation}.
+ */
+ private int calculateStaggeredAnimDuration(int i) {
+ return Math.max(100, 100 + ((i - 1) * 50));
+ }
}
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 34d6bce..774e4e9 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
@@ -345,11 +345,11 @@
mCb = cb;
mFreeformLayoutAlgorithm = new FreeformWorkspaceLayoutAlgorithm(context);
mMinMargin = res.getDimensionPixelSize(R.dimen.recents_layout_min_margin);
- mBaseTopMargin = getDimensionForDevice(res,
+ mBaseTopMargin = getDimensionForDevice(context,
R.dimen.recents_layout_top_margin_phone,
R.dimen.recents_layout_top_margin_tablet,
R.dimen.recents_layout_top_margin_tablet_xlarge);
- mBaseSideMargin = getDimensionForDevice(res,
+ mBaseSideMargin = getDimensionForDevice(context,
R.dimen.recents_layout_side_margin_phone,
R.dimen.recents_layout_side_margin_tablet,
R.dimen.recents_layout_side_margin_tablet_xlarge);
@@ -375,14 +375,14 @@
res.getDimensionPixelSize(R.dimen.recents_layout_bottom_peek_size);
mMinTranslationZ = res.getDimensionPixelSize(R.dimen.recents_layout_z_min);
mMaxTranslationZ = res.getDimensionPixelSize(R.dimen.recents_layout_z_max);
- mBaseInitialTopOffset = getDimensionForDevice(res,
+ mBaseInitialTopOffset = getDimensionForDevice(context,
R.dimen.recents_layout_initial_top_offset_phone_port,
R.dimen.recents_layout_initial_top_offset_phone_land,
R.dimen.recents_layout_initial_top_offset_tablet,
R.dimen.recents_layout_initial_top_offset_tablet,
R.dimen.recents_layout_initial_top_offset_tablet,
R.dimen.recents_layout_initial_top_offset_tablet);
- mBaseInitialBottomOffset = getDimensionForDevice(res,
+ mBaseInitialBottomOffset = getDimensionForDevice(context,
R.dimen.recents_layout_initial_bottom_offset_phone_port,
R.dimen.recents_layout_initial_bottom_offset_phone_land,
R.dimen.recents_layout_initial_bottom_offset_tablet,
@@ -454,11 +454,8 @@
mStackActionButtonRect.set(mStackRect.left, mStackRect.top - topMargin,
mStackRect.right, mStackRect.top + mFocusedTopPeekHeight);
- // Anchor the task rect top aligned to the non-freeform stack rect
- float aspect = (float) (windowRect.width() - (mSystemInsets.left + mSystemInsets.right)) /
- (windowRect.height() - (mSystemInsets.top + mSystemInsets.bottom));
- int minHeight = mStackRect.height() - mInitialTopOffset - mStackBottomOffset;
- int height = (int) Math.min(mStackRect.width() / aspect, minHeight);
+ // Anchor the task rect top aligned to the stack rect
+ int height = mStackRect.height() - mInitialTopOffset - mStackBottomOffset;
mTaskRect.set(mStackRect.left, mStackRect.top, mStackRect.right, mStackRect.top + height);
// Short circuit here if the stack rects haven't changed so we don't do all the work below
@@ -577,7 +574,7 @@
/**
* Creates task overrides to ensure the initial stack layout if necessary.
*/
- public void setTaskOverridesForInitialState(TaskStack stack) {
+ public void setTaskOverridesForInitialState(TaskStack stack, boolean ignoreScrollToFront) {
RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
mTaskIndexOverrideMap.clear();
@@ -585,7 +582,7 @@
boolean scrollToFront = launchState.launchedFromHome ||
launchState.launchedViaDockGesture;
if (getInitialFocusState() == STATE_UNFOCUSED && mNumStackTasks > 1) {
- if (!launchState.launchedWithAltTab && !scrollToFront) {
+ if (ignoreScrollToFront || (!launchState.launchedWithAltTab && !scrollToFront)) {
// Set the initial scroll to the predefined state (which differs from the stack)
float [] initialNormX = new float[] {
getNormalizedXFromUnfocusedY(mSystemInsets.bottom + mInitialBottomOffset,
@@ -834,12 +831,19 @@
*/
public TaskViewTransform getStackTransformScreenCoordinates(Task task, float stackScroll,
TaskViewTransform transformOut, TaskViewTransform frontTransform) {
- Rect windowRect = Recents.getSystemServices().getWindowRect();
TaskViewTransform transform = getStackTransform(task, stackScroll, mFocusState,
transformOut, frontTransform, true /* forceUpdate */,
false /* ignoreTaskOverrides */);
- transform.rect.offset(windowRect.left, windowRect.top);
- return transform;
+ return transformToScreenCoordinates(transform);
+ }
+
+ /**
+ * Transforms the given {@param transformOut} to the screen coordinates.
+ */
+ public TaskViewTransform transformToScreenCoordinates(TaskViewTransform transformOut) {
+ Rect windowRect = Recents.getSystemServices().getWindowRect();
+ transformOut.rect.offset(windowRect.left, windowRect.top);
+ return transformOut;
}
/**
@@ -938,7 +942,11 @@
* stack.
*/
float getStackScrollForTask(Task t) {
- return mTaskIndexOverrideMap.get(t.key.id, (float) mTaskIndexMap.get(t.key.id, 0));
+ Float overrideP = mTaskIndexOverrideMap.get(t.key.id, null);
+ if (overrideP == null) {
+ return (float) mTaskIndexMap.get(t.key.id, 0);
+ }
+ return overrideP;
}
/**
@@ -997,7 +1005,8 @@
int sideMargin = getScaleForExtent(windowRect, displayRect, mBaseSideMargin, mMinMargin,
WIDTH);
int targetStackWidth = taskStackBounds.width() - 2 * sideMargin;
- if (ssp.getDisplayOrientation() == Configuration.ORIENTATION_LANDSCAPE) {
+ if (Utilities.getAppConfiguration(mContext).orientation
+ == Configuration.ORIENTATION_LANDSCAPE) {
// If we are in landscape, calculate the width of the stack in portrait and ensure that
// we are not larger than that size
Rect portraitDisplayRect = new Rect(0, 0,
@@ -1014,20 +1023,21 @@
/**
* Retrieves resources that are constant regardless of the current configuration of the device.
*/
- public static int getDimensionForDevice(Resources res, int phoneResId,
+ public static int getDimensionForDevice(Context ctx, int phoneResId,
int tabletResId, int xlargeTabletResId) {
- return getDimensionForDevice(res, phoneResId, phoneResId, tabletResId, tabletResId,
+ return getDimensionForDevice(ctx, phoneResId, phoneResId, tabletResId, tabletResId,
xlargeTabletResId, xlargeTabletResId);
}
/**
* Retrieves resources that are constant regardless of the current configuration of the device.
*/
- public static int getDimensionForDevice(Resources res, int phonePortResId, int phoneLandResId,
+ public static int getDimensionForDevice(Context ctx, int phonePortResId, int phoneLandResId,
int tabletPortResId, int tabletLandResId, int xlargeTabletPortResId,
int xlargeTabletLandResId) {
RecentsConfiguration config = Recents.getConfiguration();
- boolean isLandscape = Recents.getSystemServices().getDisplayOrientation() ==
+ Resources res = ctx.getResources();
+ boolean isLandscape = Utilities.getAppConfiguration(ctx).orientation ==
Configuration.ORIENTATION_LANDSCAPE;
if (config.isXLargeScreen) {
return res.getDimensionPixelSize(isLandscape
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 a75d1e1..6176d99 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -328,6 +328,7 @@
*/
public void setTasks(TaskStack stack, boolean allowNotifyStackChanges) {
boolean isInitialized = mLayoutAlgorithm.isInitialized();
+
// Only notify if we are already initialized, otherwise, everything will pick up all the
// new and old tasks when we next layout
mStack.setTasks(getContext(), stack.computeAllTasksList(),
@@ -344,7 +345,7 @@
*/
public void updateToInitialState() {
mStackScroller.setStackScrollToInitialState();
- mLayoutAlgorithm.setTaskOverridesForInitialState(mStack);
+ mLayoutAlgorithm.setTaskOverridesForInitialState(mStack, false /* ignoreScrollToFront */);
}
/** Updates the list of task views */
@@ -508,11 +509,7 @@
* Binds the visible {@link TaskView}s at the given target scroll.
*/
void bindVisibleTaskViews(float targetStackScroll) {
- bindVisibleTaskViews(targetStackScroll, mIgnoreTasks, false /* ignoreTaskOverrides */);
- }
-
- void bindVisibleTaskViews(float targetStackScroll, boolean ignoreTaskOverrides) {
- bindVisibleTaskViews(targetStackScroll, mIgnoreTasks, ignoreTaskOverrides);
+ bindVisibleTaskViews(targetStackScroll, false /* ignoreTaskOverrides */);
}
/**
@@ -525,17 +522,14 @@
* @param targetStackScroll If provided, will ensure that the set of visible {@link TaskView}s
* includes those visible at the current stack scroll, and all at the
* target stack scroll.
- * @param ignoreTasksSet The set of tasks to ignore in this rebinding of the visible
- * {@link TaskView}s
* @param ignoreTaskOverrides If set, the visible task computation will get the transforms for
* tasks at their non-overridden task progress
*/
- void bindVisibleTaskViews(float targetStackScroll, ArraySet<Task.TaskKey> ignoreTasksSet,
- boolean ignoreTaskOverrides) {
+ void bindVisibleTaskViews(float targetStackScroll, boolean ignoreTaskOverrides) {
// Get all the task transforms
ArrayList<Task> tasks = mStack.getStackTasks();
int[] visibleTaskRange = computeVisibleTaskTransforms(mCurrentTaskTransforms, tasks,
- mStackScroller.getStackScroll(), targetStackScroll, ignoreTasksSet,
+ mStackScroller.getStackScroll(), targetStackScroll, mIgnoreTasks,
ignoreTaskOverrides);
// Return all the invisible children to the pool
@@ -548,7 +542,7 @@
Task task = tv.getTask();
// Skip ignored tasks
- if (ignoreTasksSet.contains(task.key)) {
+ if (mIgnoreTasks.contains(task.key)) {
continue;
}
@@ -578,7 +572,7 @@
TaskViewTransform transform = mCurrentTaskTransforms.get(i);
// Skip ignored tasks
- if (ignoreTasksSet.contains(task.key)) {
+ if (mIgnoreTasks.contains(task.key)) {
continue;
}
@@ -626,10 +620,10 @@
}
/**
- * @see #relayoutTaskViews(AnimationProps, ArraySet<Task.TaskKey>, boolean)
+ * @see #relayoutTaskViews(AnimationProps, boolean)
*/
public void relayoutTaskViews(AnimationProps animation) {
- relayoutTaskViews(animation, mIgnoreTasks, false /* ignoreTaskOverrides */);
+ relayoutTaskViews(animation, false /* ignoreTaskOverrides */);
}
/**
@@ -637,16 +631,13 @@
* {@link TaskStackLayoutAlgorithm} with the given {@param animation}. This call cancels any
* animations that are current running on those task views, and will ensure that the children
* {@link TaskView}s will match the set of visible tasks in the stack.
- *
- * @param ignoreTasksSet the set of tasks to ignore in the relayout
*/
- private void relayoutTaskViews(AnimationProps animation, ArraySet<Task.TaskKey> ignoreTasksSet,
- boolean ignoreTaskOverrides) {
+ private void relayoutTaskViews(AnimationProps animation, boolean ignoreTaskOverrides) {
// If we had a deferred animation, cancel that
mDeferredTaskViewLayoutAnimation = null;
// Synchronize the current set of TaskViews
- bindVisibleTaskViews(mStackScroller.getStackScroll(), ignoreTasksSet,
+ bindVisibleTaskViews(mStackScroller.getStackScroll(),
ignoreTaskOverrides /* ignoreTaskOverrides */);
// Animate them to their final transforms with the given animation
@@ -657,7 +648,7 @@
int taskIndex = mStack.indexOfStackTask(tv.getTask());
TaskViewTransform transform = mCurrentTaskTransforms.get(taskIndex);
- if (ignoreTasksSet.contains(tv.getTask().key)) {
+ if (mIgnoreTasks.contains(tv.getTask().key)) {
continue;
}
@@ -715,13 +706,13 @@
* {@param stackScroll} and {@param focusState}.
*/
public void getLayoutTaskTransforms(float stackScroll, int focusState, ArrayList<Task> tasks,
- ArrayList<TaskViewTransform> transformsOut) {
+ boolean ignoreTaskOverrides, ArrayList<TaskViewTransform> transformsOut) {
Utilities.matchTaskListSize(tasks, transformsOut);
for (int i = tasks.size() - 1; i >= 0; i--) {
Task task = tasks.get(i);
TaskViewTransform transform = transformsOut.get(i);
mLayoutAlgorithm.getStackTransform(task, stackScroll, focusState, transform, null,
- true /* forceUpdate */, true /* ignoreTaskOverrides */);
+ true /* forceUpdate */, ignoreTaskOverrides);
transform.visible = true;
}
}
@@ -812,22 +803,10 @@
/**
* Updates the layout algorithm min and max virtual scroll bounds.
- *
- * @see #updateLayoutAlgorithm(boolean, ArraySet<Task.TaskKey>)
*/
public void updateLayoutAlgorithm(boolean boundScrollToNewMinMax) {
- updateLayoutAlgorithm(boundScrollToNewMinMax, mIgnoreTasks);
- }
-
- /**
- * Updates the min and max virtual scroll bounds.
- *
- * @param ignoreTasksSet the set of tasks to ignore in the relayout
- */
- private void updateLayoutAlgorithm(boolean boundScrollToNewMinMax,
- ArraySet<Task.TaskKey> ignoreTasksSet) {
// Compute the min and max scroll values
- mLayoutAlgorithm.update(mStack, ignoreTasksSet);
+ mLayoutAlgorithm.update(mStack, mIgnoreTasks);
// Update the freeform workspace background
SystemServicesProxy ssp = Recents.getSystemServices();
@@ -1195,8 +1174,7 @@
}
// Rebind all the views, including the ignore ones
- bindVisibleTaskViews(mStackScroller.getStackScroll(), mIgnoreTasks,
- false /* ignoreTaskOverrides */);
+ bindVisibleTaskViews(mStackScroller.getStackScroll(), false /* ignoreTaskOverrides */);
// Measure each of the TaskViews
mTmpTaskViews.clear();
@@ -1553,7 +1531,7 @@
tv.onTaskBound(task);
// Load the task data
- Recents.getTaskLoader().loadTaskData(task, true /* fetchAndInvalidateThumbnails */);
+ Recents.getTaskLoader().loadTaskData(task);
}
private void unbindTaskView(TaskView tv, Task task) {
@@ -1640,7 +1618,6 @@
}
if (launchTaskIndex != -1) {
// Stop all animations
- mUIDozeTrigger.stopDozing();
cancelAllTaskViewAnimations();
final Task launchTask = mStack.getStackTasks().get(launchTaskIndex);
@@ -1834,7 +1811,7 @@
updateLayoutAlgorithm(true /* boundScroll */);
addIgnoreTask(event.task);
}
- relayoutTaskViews(animation, mIgnoreTasks, ignoreTaskOverrides);
+ relayoutTaskViews(animation, ignoreTaskOverrides);
}
public final void onBusEvent(final DragEndEvent event) {
@@ -1948,26 +1925,24 @@
}
}
- public final void onBusEvent(MultiWindowStateChangedEvent event) {
- if (!event.inMultiWindow) {
+ public final void onBusEvent(final MultiWindowStateChangedEvent event) {
+ if (event.inMultiWindow) {
+ setTasks(event.stack, true /* allowNotifyStackChanges */);
+ } else {
+ // Reset the launch state before handling the multiwindow change
+ RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
+ launchState.reset();
+
// Defer until the next frame to ensure that we have received all the system insets, and
// initial layout updates
+ event.getAnimationTrigger().increment();
post(new Runnable() {
@Override
public void run() {
// Scroll the stack to the front to see the undocked task
- mStackScroller.animateScroll(mLayoutAlgorithm.mMaxScrollP, new Runnable() {
- @Override
- public void run() {
- List<TaskView> taskViews = getTaskViews();
- int taskViewCount = taskViews.size();
- for (int i = 0; i < taskViewCount; i++) {
- TaskView tv = taskViews.get(i);
- tv.getHeaderView().rebindToTask(tv.getTask(),
- tv.mTouchExplorationEnabled, tv.mIsDisabledInSafeMode);
- }
- }
- });
+ mAnimationHelper.startNewStackScrollAnimation(event.stack,
+ event.getAnimationTrigger());
+ event.getAnimationTrigger().decrement();
}
});
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
index 3cdb1fb..9edf9d6 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
@@ -60,8 +60,7 @@
class TaskStackViewTouchHandler implements SwipeHelper.Callback {
private static final int INACTIVE_POINTER_ID = -1;
- private static final Interpolator STACK_TRANSFORM_INTERPOLATOR =
- new PathInterpolator(0.73f, 0.33f, 0.42f, 0.85f);
+ private static final float CHALLENGING_SWIPE_ESCAPE_VELOCITY = 800f; // dp/sec
// The min overscroll is the amount of task progress overscroll we want / the max overscroll
// curve value below
private static final float MAX_OVERSCROLL = 0.7f / 0.3f;
@@ -125,7 +124,7 @@
mSwipeHelper = new SwipeHelper(SwipeHelper.X, this, context) {
@Override
protected float getSize(View v) {
- return mSv.getWidth();
+ return getScaledDismissSize();
}
@Override
@@ -138,6 +137,16 @@
anim.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
mSwipeHelperAnimations.put(v, anim);
}
+
+ @Override
+ protected float getUnscaledEscapeVelocity() {
+ return CHALLENGING_SWIPE_ESCAPE_VELOCITY;
+ }
+
+ @Override
+ protected long getMaxEscapeAnimDuration() {
+ return 700;
+ }
};
mSwipeHelper.setDisableHardwareLayers(true);
}
@@ -483,7 +492,7 @@
// Get the final set of task transforms (with task removed)
mSv.getLayoutTaskTransforms(newStackScroll, TaskStackLayoutAlgorithm.STATE_UNFOCUSED,
- mCurrentTasks, mFinalTaskTransforms);
+ mCurrentTasks, true /* ignoreTaskOverrides */, mFinalTaskTransforms);
// Set the target to scroll towards upon dismissal
mTargetStackScroll = newStackScroll;
@@ -500,7 +509,7 @@
@Override
public boolean updateSwipeProgress(View v, boolean dismissable, float swipeProgress) {
- updateTaskViewTransforms(getDismissFraction(v));
+ updateTaskViewTransforms(Interpolators.FAST_OUT_SLOW_IN.getInterpolation(swipeProgress));
return true;
}
@@ -616,13 +625,9 @@
}
/**
- * Returns the fraction which we should interpolate the other task views based on the dismissal
- * of this given task.
- *
- * TODO: We can interpolate this to adjust when the other tasks should respond to the dismissal
+ * Returns the scaled size used to calculate the dismiss fraction.
*/
- private float getDismissFraction(View v) {
- float fraction = Math.min(1f, Math.abs(v.getTranslationX() / mSv.getWidth()));
- return STACK_TRANSFORM_INTERPOLATOR.getInterpolation(fraction);
+ private float getScaledDismissSize() {
+ return 1.5f * Math.max(mSv.getWidth(), mSv.getHeight());
}
}
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 37f5a9f..7ea70b5 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -24,13 +24,9 @@
import android.animation.ValueAnimator;
import android.app.ActivityManager;
import android.content.Context;
-import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Outline;
-import android.graphics.Paint;
import android.graphics.Point;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuffColorFilter;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.FloatProperty;
@@ -607,6 +603,8 @@
mTask = t;
mTask.addCallback(this);
mIsDisabledInSafeMode = !mTask.isSystemApp && ssp.isInSafeMode();
+ mThumbnailView.bindToTask(mTask, mIsDisabledInSafeMode);
+ mHeaderView.bindToTask(mTask, mTouchExplorationEnabled, mIsDisabledInSafeMode);
if (!t.isDockable && ssp.hasDockedTask()) {
if (mIncompatibleAppToastView == null) {
@@ -623,15 +621,15 @@
@Override
public void onTaskDataLoaded(Task task, ActivityManager.TaskThumbnailInfo thumbnailInfo) {
- // Bind each of the views to the new task data
- mThumbnailView.rebindToTask(mTask, thumbnailInfo, mIsDisabledInSafeMode);
- mHeaderView.rebindToTask(mTask, mTouchExplorationEnabled, mIsDisabledInSafeMode);
+ // Update each of the views to the new task data
+ mThumbnailView.onTaskDataLoaded(thumbnailInfo);
+ mHeaderView.onTaskDataLoaded();
mTaskDataLoaded = true;
}
@Override
public void onTaskDataUnloaded() {
- // Unbind each of the views from the task data and remove the task callback
+ // Unbind each of the views from the task and remove the task callback
mTask.removeCallback(this);
mThumbnailView.unbindFromTask();
mHeaderView.unbindFromTask(mTouchExplorationEnabled);
@@ -640,7 +638,9 @@
@Override
public void onTaskStackIdChanged() {
- mHeaderView.rebindToTask(mTask, mTouchExplorationEnabled, mIsDisabledInSafeMode);
+ // Force rebind the header, the thumbnail does not change due to stack changes
+ mHeaderView.bindToTask(mTask, mTouchExplorationEnabled, mIsDisabledInSafeMode);
+ mHeaderView.onTaskDataLoaded();
}
/**** View.OnClickListener Implementation ****/
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
index fb0fc30..e2f2198 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
@@ -284,14 +284,14 @@
// Update the dimensions of everything in the header. We do this because we need to use
// resources for the display, and not the current configuration.
Resources res = getResources();
- int headerBarHeight = TaskStackLayoutAlgorithm.getDimensionForDevice(res,
+ int headerBarHeight = TaskStackLayoutAlgorithm.getDimensionForDevice(getContext(),
R.dimen.recents_task_view_header_height,
R.dimen.recents_task_view_header_height,
R.dimen.recents_task_view_header_height,
R.dimen.recents_task_view_header_height_tablet_land,
R.dimen.recents_task_view_header_height,
R.dimen.recents_task_view_header_height_tablet_land);
- int headerButtonPadding = TaskStackLayoutAlgorithm.getDimensionForDevice(res,
+ int headerButtonPadding = TaskStackLayoutAlgorithm.getDimensionForDevice(getContext(),
R.dimen.recents_task_view_header_button_padding,
R.dimen.recents_task_view_header_button_padding,
R.dimen.recents_task_view_header_button_padding,
@@ -438,21 +438,18 @@
}
}
- /** Binds the bar view to the task */
- public void rebindToTask(Task t, boolean touchExplorationEnabled, boolean disabledInSafeMode) {
+ /**
+ * Binds the bar view to the task.
+ */
+ public void bindToTask(Task t, boolean touchExplorationEnabled, boolean disabledInSafeMode) {
mTask = t;
- // If an activity icon is defined, then we use that as the primary icon to show in the bar,
- // otherwise, we fall back to the application icon
int primaryColor = disabledInSafeMode
? mDisabledTaskBarBackgroundColor
: t.colorPrimary;
if (mBackground.getColor() != primaryColor) {
updateBackgroundColor(primaryColor, mDimAlpha);
}
- if (t.icon != null) {
- mIconView.setImageDrawable(t.icon);
- }
if (!mTitleView.getText().toString().equals(t.title)) {
mTitleView.setText(t.title);
}
@@ -497,6 +494,16 @@
}
}
+ /**
+ * Called when the bound task's data has loaded and this view should update to reflect the
+ * changes.
+ */
+ public void onTaskDataLoaded() {
+ if (mTask.icon != null) {
+ mIconView.setImageDrawable(mTask.icon);
+ }
+ }
+
/** Unbinds the bar view from the task */
void unbindFromTask(boolean touchExplorationEnabled) {
mTask = null;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java
index 4de7713..109dc20 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java
@@ -38,6 +38,7 @@
import com.android.systemui.R;
import com.android.systemui.recents.Recents;
import com.android.systemui.recents.misc.SystemServicesProxy;
+import com.android.systemui.recents.misc.Utilities;
import com.android.systemui.recents.model.Task;
@@ -132,7 +133,7 @@
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
SystemServicesProxy ssp = Recents.getSystemServices();
- mOrientation = ssp.getDisplayOrientation();
+ mOrientation = Utilities.getAppConfiguration(mContext).orientation;
mDisplayRect = ssp.getDisplayRect();
}
@@ -302,21 +303,29 @@
updateThumbnailPaintFilter();
}
- /** Binds the thumbnail view to the task */
- void rebindToTask(Task t, ActivityManager.TaskThumbnailInfo thumbnailInfo,
- boolean disabledInSafeMode) {
+ /**
+ * Binds the thumbnail view to the task.
+ */
+ void bindToTask(Task t, boolean disabledInSafeMode) {
mTask = t;
mDisabledInSafeMode = disabledInSafeMode;
- if (t.thumbnail != null) {
- setThumbnail(t.thumbnail, thumbnailInfo);
- } else {
- setThumbnail(null, null);
- }
if (t.colorBackground != 0) {
mBgFillPaint.setColor(t.colorBackground);
}
}
+ /**
+ * Called when the bound task's data has loaded and this view should update to reflect the
+ * changes.
+ */
+ void onTaskDataLoaded(ActivityManager.TaskThumbnailInfo thumbnailInfo) {
+ if (mTask.thumbnail != null) {
+ setThumbnail(mTask.thumbnail, thumbnailInfo);
+ } else {
+ setThumbnail(null, null);
+ }
+ }
+
/** Unbinds the thumbnail view from the task */
void unbindFromTask() {
mTask = null;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 7c6c641..cb1128b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -910,7 +910,7 @@
final float fontScale = newConfig.fontScale;
final int density = newConfig.densityDpi;
if (density != mDensity || mFontScale != fontScale) {
- reInflateViews();
+ onDensityOrFontScaleChanged();
mDensity = density;
mFontScale = fontScale;
}
@@ -926,7 +926,7 @@
}
}
- protected void reInflateViews() {
+ protected void onDensityOrFontScaleChanged() {
ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications();
for (int i = 0; i < activeNotifications.size(); i++) {
Entry entry = activeNotifications.get(i);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index e4accf5..870447a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -18,6 +18,7 @@
import android.app.Notification;
import android.content.Context;
+import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Paint;
@@ -39,6 +40,7 @@
public class StatusBarIconView extends AnimatedImageView {
private static final String TAG = "StatusBarIconView";
+ private boolean mAlwaysScaleIcon;
private StatusBarIcon mIcon;
@ViewDebug.ExportedProperty private String mSlot;
@@ -49,6 +51,7 @@
private String mNumberText;
private Notification mNotification;
private final boolean mBlocked;
+ private int mDensity;
public StatusBarIconView(Context context, String slot, Notification notification) {
this(context, slot, notification, false);
@@ -57,7 +60,6 @@
public StatusBarIconView(Context context, String slot, Notification notification,
boolean blocked) {
super(context);
- final Resources res = context.getResources();
mBlocked = blocked;
mSlot = slot;
mNumberPain = new Paint();
@@ -65,18 +67,37 @@
mNumberPain.setColor(context.getColor(R.drawable.notification_number_text_color));
mNumberPain.setAntiAlias(true);
setNotification(notification);
+ maybeUpdateIconScale();
+ setScaleType(ScaleType.CENTER);
+ mDensity = context.getResources().getDisplayMetrics().densityDpi;
+ }
+ private void maybeUpdateIconScale() {
// We do not resize and scale system icons (on the right), only notification icons (on the
// left).
- if (notification != null) {
- final int outerBounds = res.getDimensionPixelSize(R.dimen.status_bar_icon_size);
- final int imageBounds = res.getDimensionPixelSize(R.dimen.status_bar_icon_drawing_size);
- final float scale = (float)imageBounds / (float)outerBounds;
- setScaleX(scale);
- setScaleY(scale);
+ if (mNotification != null || mAlwaysScaleIcon) {
+ updateIconScale();
}
+ }
- setScaleType(ScaleType.CENTER);
+ private void updateIconScale() {
+ Resources res = mContext.getResources();
+ final int outerBounds = res.getDimensionPixelSize(R.dimen.status_bar_icon_size);
+ final int imageBounds = res.getDimensionPixelSize(R.dimen.status_bar_icon_drawing_size);
+ final float scale = (float)imageBounds / (float)outerBounds;
+ setScaleX(scale);
+ setScaleY(scale);
+ }
+
+ @Override
+ protected void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ int density = newConfig.densityDpi;
+ if (density != mDensity) {
+ mDensity = density;
+ maybeUpdateIconScale();
+ updateDrawable();
+ }
}
public void setNotification(Notification notification) {
@@ -87,12 +108,9 @@
public StatusBarIconView(Context context, AttributeSet attrs) {
super(context, attrs);
mBlocked = false;
- final Resources res = context.getResources();
- final int outerBounds = res.getDimensionPixelSize(R.dimen.status_bar_icon_size);
- final int imageBounds = res.getDimensionPixelSize(R.dimen.status_bar_icon_drawing_size);
- final float scale = (float)imageBounds / (float)outerBounds;
- setScaleX(scale);
- setScaleY(scale);
+ mAlwaysScaleIcon = true;
+ updateIconScale();
+ mDensity = context.getResources().getDisplayMetrics().densityDpi;
}
private static boolean streq(String a, String b) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/IconMerger.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/IconMerger.java
index 225751a..f86badb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/IconMerger.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/IconMerger.java
@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.phone;
import android.content.Context;
+import android.content.res.Configuration;
import android.content.res.Resources;
import android.util.AttributeSet;
import android.view.View;
@@ -28,23 +29,31 @@
private static final String TAG = "IconMerger";
private static final boolean DEBUG = false;
- private final int mIconSize;
- private final int mIconHPadding;
+ private int mIconSize;
+ private int mIconHPadding;
private View mMoreView;
public IconMerger(Context context, AttributeSet attrs) {
super(context, attrs);
-
- Resources res = context.getResources();
- mIconSize = res.getDimensionPixelSize(R.dimen.status_bar_icon_size);
- mIconHPadding = res.getDimensionPixelSize(R.dimen.status_bar_icon_padding);
-
+ reloadDimens();
if (DEBUG) {
setBackgroundColor(0x800099FF);
}
}
+ private void reloadDimens() {
+ Resources res = mContext.getResources();
+ mIconSize = res.getDimensionPixelSize(R.dimen.status_bar_icon_size);
+ mIconHPadding = res.getDimensionPixelSize(R.dimen.status_bar_icon_padding);
+ }
+
+ @Override
+ protected void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ reloadDimens();
+ }
+
public void setOverflowIndicator(View v) {
mMoreView = v;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
index c4917a1..cbaab14 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
@@ -5,6 +5,7 @@
import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.Rect;
+import android.support.annotation.NonNull;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
@@ -17,7 +18,6 @@
import com.android.systemui.statusbar.notification.NotificationUtils;
import java.util.ArrayList;
-import java.util.List;
/**
* A controller for the space in the status bar to the left of the system icons. This area is
@@ -51,9 +51,7 @@
* Initializes the views that will represent the notification area.
*/
protected void initializeNotificationAreaViews(Context context) {
- Resources res = context.getResources();
- mIconSize = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_icon_size);
- mIconHPadding = res.getDimensionPixelSize(R.dimen.status_bar_icon_padding);
+ reloadDimens(context);
LayoutInflater layoutInflater = LayoutInflater.from(context);
mNotificationIconArea = inflateIconArea(layoutInflater);
@@ -68,6 +66,27 @@
}
}
+ public void onDensityOrFontScaleChanged(Context context) {
+ reloadDimens(context);
+ final LinearLayout.LayoutParams params = generateIconLayoutParams();
+ for (int i = 0; i < mNotificationIcons.getChildCount(); i++) {
+ View child = mNotificationIcons.getChildAt(i);
+ child.setLayoutParams(params);
+ }
+ }
+
+ @NonNull
+ private LinearLayout.LayoutParams generateIconLayoutParams() {
+ return new LinearLayout.LayoutParams(
+ mIconSize + 2 * mIconHPadding, getHeight());
+ }
+
+ private void reloadDimens(Context context) {
+ Resources res = context.getResources();
+ mIconSize = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_icon_size);
+ mIconHPadding = res.getDimensionPixelSize(R.dimen.status_bar_icon_padding);
+ }
+
/**
* Returns the view that represents the notification area.
*/
@@ -125,8 +144,7 @@
* Updates the notifications with the given list of notifications to display.
*/
public void updateNotificationIcons(NotificationData notificationData) {
- final LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
- mIconSize + 2 * mIconHPadding, getHeight());
+ final LinearLayout.LayoutParams params = generateIconLayoutParams();
ArrayList<NotificationData.Entry> activeNotifications =
notificationData.getActiveNotifications();
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 82806fd..b75c2916 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -86,6 +86,7 @@
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
+import android.view.ViewParent;
import android.view.ViewStub;
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
@@ -762,14 +763,7 @@
mStackScroller.setHeadsUpManager(mHeadsUpManager);
mGroupManager.setOnGroupChangeListener(mStackScroller);
- mKeyguardIconOverflowContainer =
- (NotificationOverflowContainer) LayoutInflater.from(mContext).inflate(
- R.layout.status_bar_notification_keyguard_overflow, mStackScroller, false);
- mKeyguardIconOverflowContainer.setOnActivatedListener(this);
- mKeyguardIconOverflowContainer.setOnClickListener(mOverflowClickListener);
- mStackScroller.setOverflowContainer(mKeyguardIconOverflowContainer);
-
-
+ inflateOverflowContainer();
inflateEmptyShadeView();
inflateDismissView();
mExpandedContents = mStackScroller;
@@ -950,13 +944,62 @@
return new BatteryControllerImpl(mContext);
}
+ private void inflateOverflowContainer() {
+ mKeyguardIconOverflowContainer =
+ (NotificationOverflowContainer) LayoutInflater.from(mContext).inflate(
+ R.layout.status_bar_notification_keyguard_overflow, mStackScroller, false);
+ mKeyguardIconOverflowContainer.setOnActivatedListener(this);
+ mKeyguardIconOverflowContainer.setOnClickListener(mOverflowClickListener);
+ mStackScroller.setOverflowContainer(mKeyguardIconOverflowContainer);
+ }
+
@Override
- protected void reInflateViews() {
- super.reInflateViews();
+ protected void onDensityOrFontScaleChanged() {
+ super.onDensityOrFontScaleChanged();
+ mScrimController.onDensityOrFontScaleChanged();
+ mStatusBarView.onDensityOrFontScaleChanged();
+ mBrightnessMirrorController.onDensityOrFontScaleChanged();
+ inflateSignalClusters();
+ mIconController.onDensityOrFontScaleChanged();
inflateDismissView();
updateClearAll();
inflateEmptyShadeView();
updateEmptyShadeView();
+ inflateOverflowContainer();
+ }
+
+ private void inflateSignalClusters() {
+ SignalClusterView signalClusterView = reinflateSignalCluster(mStatusBarView);
+ mIconController.setSignalCluster(signalClusterView);
+ reinflateSignalCluster(mKeyguardStatusView);
+ }
+
+ private SignalClusterView reinflateSignalCluster(View view) {
+ SignalClusterView signalCluster =
+ (SignalClusterView) view.findViewById(R.id.signal_cluster);
+ if (signalCluster != null) {
+ ViewParent parent = signalCluster.getParent();
+ if (parent instanceof ViewGroup) {
+ ViewGroup viewParent = (ViewGroup) parent;
+ int index = viewParent.indexOfChild(signalCluster);
+ viewParent.removeView(signalCluster);
+ SignalClusterView newCluster = (SignalClusterView) LayoutInflater.from(mContext)
+ .inflate(R.layout.signal_cluster_view, viewParent, false);
+ ViewGroup.MarginLayoutParams layoutParams =
+ (ViewGroup.MarginLayoutParams) viewParent.getLayoutParams();
+ layoutParams.setMarginsRelative(
+ mContext.getResources().getDimensionPixelSize(
+ R.dimen.signal_cluster_margin_start),
+ 0, 0, 0);
+ newCluster.setLayoutParams(layoutParams);
+ newCluster.setSecurityController(mSecurityController);
+ newCluster.setNetworkController(mNetworkController);
+ viewParent.addView(newCluster, index);
+ return newCluster;
+ }
+ return signalCluster;
+ }
+ return null;
}
private void inflateEmptyShadeView() {
@@ -3250,17 +3293,17 @@
// SystemUIService notifies SystemBars of configuration changes, which then calls down here
@Override
protected void onConfigurationChanged(Configuration newConfig) {
+ updateResources();
+ updateDisplaySize(); // populates mDisplayMetrics
super.onConfigurationChanged(newConfig); // calls refreshLayout
if (DEBUG) {
Log.v(TAG, "configuration changed: " + mContext.getResources().getConfiguration());
}
- updateDisplaySize(); // populates mDisplayMetrics
- updateResources();
repositionNavigationBar();
updateRowStates();
- mIconController.updateResources();
+ mIconController.defineSlots();
mScreenPinningRequest.onConfigurationChanged();
mNetworkController.onConfigurationChanged();
}
@@ -3331,7 +3374,7 @@
mMaxAllowedKeyguardNotifications = res.getInteger(
R.integer.keyguard_max_notification_count);
- if (DEBUG) Log.v(TAG, "updateResources");
+ if (DEBUG) Log.v(TAG, "defineSlots");
}
// Visibility reporting
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
index cc3b4bd..c80b3ad 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
@@ -21,10 +21,12 @@
import android.util.EventLog;
import android.view.MotionEvent;
import android.view.View;
+import android.view.ViewGroup;
import android.view.accessibility.AccessibilityEvent;
import com.android.systemui.DejankUtils;
import com.android.systemui.EventLogTags;
+import com.android.systemui.R;
public class PhoneStatusBarView extends PanelBar {
private static final String TAG = "PhoneStatusBarView";
@@ -185,4 +187,11 @@
float scrimFraction = Math.max(mPanelFraction, mMinFraction);
mScrimController.setPanelExpansion(scrimFraction);
}
+
+ public void onDensityOrFontScaleChanged() {
+ ViewGroup.LayoutParams layoutParams = getLayoutParams();
+ layoutParams.height = getResources().getDimensionPixelSize(
+ R.dimen.status_bar_height);
+ setLayoutParams(layoutParams);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index 3eda320..cf5277f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -24,6 +24,7 @@
import android.graphics.Color;
import android.graphics.Rect;
import android.view.View;
+import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
@@ -519,4 +520,11 @@
public void setScrimBehindChangeRunnable(Runnable changeRunnable) {
mScrimBehind.setChangeRunnable(changeRunnable);
}
+
+ public void onDensityOrFontScaleChanged() {
+ ViewGroup.LayoutParams layoutParams = mHeadsUpScrim.getLayoutParams();
+ layoutParams.height = mHeadsUpScrim.getResources().getDimensionPixelSize(
+ R.dimen.heads_up_scrim_height);
+ mHeadsUpScrim.setLayoutParams(layoutParams);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
index a40aa83..f415ae5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
@@ -76,6 +76,7 @@
private View mNotificationIconAreaInner;
private BatteryMeterView mBatteryMeterView;
+ private BatteryMeterView mBatteryMeterViewKeyguard;
private TextView mClock;
private int mIconSize;
@@ -129,39 +130,43 @@
mStatusIconsKeyguard = (LinearLayout) keyguardStatusBar.findViewById(R.id.statusIcons);
mBatteryMeterView = (BatteryMeterView) statusBar.findViewById(R.id.battery);
- maybeScaleBatteryMeterView(context);
+ mBatteryMeterViewKeyguard = (BatteryMeterView) keyguardStatusBar.findViewById(R.id.battery);
+ scaleBatteryMeterViews(context);
mClock = (TextView) statusBar.findViewById(R.id.clock);
mDarkModeIconColorSingleTone = context.getColor(R.color.dark_mode_icon_color_single_tone);
mLightModeIconColorSingleTone = context.getColor(R.color.light_mode_icon_color_single_tone);
mHandler = new Handler();
- updateResources();
+ defineSlots();
+ loadDimens();
TunerService.get(mContext).addTunable(this, ICON_BLACKLIST);
}
+ public void setSignalCluster(SignalClusterView signalCluster) {
+ mSignalCluster = signalCluster;
+ }
+
/**
- * Looks up the scale factor for status bar icons and scales the battery view by that amount
- * if appropriate.
+ * Looks up the scale factor for status bar icons and scales the battery view by that amount.
*/
- private void maybeScaleBatteryMeterView(Context context) {
+ private void scaleBatteryMeterViews(Context context) {
Resources res = context.getResources();
TypedValue typedValue = new TypedValue();
res.getValue(R.dimen.status_bar_icon_scale_factor, typedValue, true);
float iconScaleFactor = typedValue.getFloat();
- if (iconScaleFactor == 1.f) {
- return;
- }
-
- float batteryHeight = res.getDimension(R.dimen.status_bar_battery_icon_height);
- float batteryWidth = res.getDimension(R.dimen.status_bar_battery_icon_width);
+ int batteryHeight = res.getDimensionPixelSize(R.dimen.status_bar_battery_icon_height);
+ int batteryWidth = res.getDimensionPixelSize(R.dimen.status_bar_battery_icon_width);
+ int marginBottom = res.getDimensionPixelSize(R.dimen.battery_margin_bottom);
LinearLayout.LayoutParams scaledLayoutParams = new LinearLayout.LayoutParams(
(int) (batteryWidth * iconScaleFactor), (int) (batteryHeight * iconScaleFactor));
+ scaledLayoutParams.setMarginsRelative(0, 0, 0, marginBottom);
mBatteryMeterView.setLayoutParams(scaledLayoutParams);
+ mBatteryMeterViewKeyguard.setLayoutParams(scaledLayoutParams);
}
@Override
@@ -185,15 +190,16 @@
setIcon(views.get(i).getSlot(), views.get(i).getStatusBarIcon());
}
}
-
- public void updateResources() {
+ private void loadDimens() {
mIconSize = mContext.getResources().getDimensionPixelSize(
com.android.internal.R.dimen.status_bar_icon_size);
mIconHPadding = mContext.getResources().getDimensionPixelSize(
R.dimen.status_bar_icon_padding);
+ }
+
+ public void defineSlots() {
defineSlots(mContext.getResources().getStringArray(
com.android.internal.R.array.config_statusBarIcons));
- FontSizeUtils.updateFontSize(mClock, R.dimen.status_bar_clock_size);
}
private void addSystemIcon(int index, StatusBarIcon icon) {
@@ -571,4 +577,35 @@
}
return ret;
}
+
+ public void onDensityOrFontScaleChanged() {
+ loadDimens();
+ mNotificationIconAreaController.onDensityOrFontScaleChanged(mContext);
+ updateClock();
+ for (int i = 0; i < mStatusIcons.getChildCount(); i++) {
+ View child = mStatusIcons.getChildAt(i);
+ LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
+ ViewGroup.LayoutParams.WRAP_CONTENT, mIconSize);
+ lp.setMargins(mIconHPadding, 0, mIconHPadding, 0);
+ child.setLayoutParams(lp);
+ }
+ for (int i = 0; i < mStatusIconsKeyguard.getChildCount(); i++) {
+ View child = mStatusIconsKeyguard.getChildAt(i);
+ LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
+ ViewGroup.LayoutParams.WRAP_CONTENT, mIconSize);
+ child.setLayoutParams(lp);
+ }
+ scaleBatteryMeterViews(mContext);
+ }
+
+ private void updateClock() {
+ FontSizeUtils.updateFontSize(mClock, R.dimen.status_bar_clock_size);
+ mClock.setPaddingRelative(
+ mContext.getResources().getDimensionPixelSize(
+ R.dimen.status_bar_clock_starting_padding),
+ 0,
+ mContext.getResources().getDimensionPixelSize(
+ R.dimen.status_bar_clock_end_padding),
+ 0);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconList.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconList.java
index 62d6b76..97b31f2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconList.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconList.java
@@ -26,10 +26,13 @@
private ArrayList<StatusBarIcon> mIcons = new ArrayList<>();
public void defineSlots(String[] slots) {
+ mSlots.clear();
final int N = slots.length;
for (int i=0; i < N; i++) {
mSlots.add(slots[i]);
- mIcons.add(null);
+ if (mIcons.size() < mSlots.size()) {
+ mIcons.add(null);
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
index ab34768..7a6d080 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BrightnessMirrorController.java
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.policy;
+import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewPropertyAnimator;
import android.widget.FrameLayout;
@@ -33,12 +34,14 @@
public long TRANSITION_DURATION_OUT = 150;
public long TRANSITION_DURATION_IN = 200;
+ private final StatusBarWindowView mStatusBarWindow;
private final ScrimView mScrimBehind;
- private final View mBrightnessMirror;
private final View mNotificationPanel;
private final int[] mInt2Cache = new int[2];
+ private View mBrightnessMirror;
public BrightnessMirrorController(StatusBarWindowView statusBarWindow) {
+ mStatusBarWindow = statusBarWindow;
mScrimBehind = (ScrimView) statusBarWindow.findViewById(R.id.scrim_behind);
mBrightnessMirror = statusBarWindow.findViewById(R.id.brightness_mirror);
mNotificationPanel = statusBarWindow.findViewById(R.id.notification_panel);
@@ -56,11 +59,11 @@
inAnimation(mNotificationPanel.animate())
.withLayer()
.withEndAction(new Runnable() {
- @Override
- public void run() {
- mBrightnessMirror.setVisibility(View.INVISIBLE);
- }
- });
+ @Override
+ public void run() {
+ mBrightnessMirror.setVisibility(View.INVISIBLE);
+ }
+ });
}
private ViewPropertyAnimator outAnimation(ViewPropertyAnimator a) {
@@ -104,4 +107,12 @@
R.integer.notification_panel_layout_gravity);
mBrightnessMirror.setLayoutParams(lp);
}
+
+ public void onDensityOrFontScaleChanged() {
+ int index = mStatusBarWindow.indexOfChild(mBrightnessMirror);
+ mStatusBarWindow.removeView(mBrightnessMirror);
+ mBrightnessMirror = LayoutInflater.from(mBrightnessMirror.getContext()).inflate(
+ R.layout.brightness_mirror, mStatusBarWindow, false);
+ mStatusBarWindow.addView(mBrightnessMirror, index);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index 8b52bf6..c962606 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -747,7 +747,7 @@
public boolean updateSwipeProgress(View animView, boolean dismissable, float swipeProgress) {
if (!mIsExpanded && isPinnedHeadsUp(animView) && canChildBeDismissed(animView)) {
mScrimController.setTopHeadsUpDragAmount(animView,
- Math.min(Math.abs(swipeProgress - 1.0f), 1.0f));
+ Math.min(Math.abs(swipeProgress / 2f - 1.0f), 1.0f));
}
return true; // Don't fade out the notification
}
@@ -3116,8 +3116,13 @@
}
public void setOverflowContainer(NotificationOverflowContainer overFlowContainer) {
+ int index = -1;
+ if (mOverflowContainer != null) {
+ index = indexOfChild(mOverflowContainer);
+ removeView(mOverflowContainer);
+ }
mOverflowContainer = overFlowContainer;
- addView(mOverflowContainer);
+ addView(mOverflowContainer, index);
}
public void updateOverflowContainerVisibility(boolean visible) {
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 8f7f396..97ee744 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -2120,7 +2120,7 @@
if (onTop) {
for (int i = 0; i < size; i++) {
moveTaskToStackLocked(tasks.get(i).taskId,
- FULLSCREEN_WORKSPACE_STACK_ID, onTop, !FORCE_FOCUS,
+ FULLSCREEN_WORKSPACE_STACK_ID, onTop, onTop /*forceFocus*/,
"moveTasksToFullscreenStack", ANIMATE);
}
} else {
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
index 53377f9..612e5e8 100644
--- a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
@@ -188,13 +188,13 @@
}
// Process existing model first.
- if (model != null && model.getModelId() != soundModel.uuid) {
+ if (model != null && !model.getModelId().equals(soundModel.uuid)) {
// The existing model has a different UUID, should be replaced.
int status = cleanUpExistingKeyphraseModel(model);
- removeKeyphraseModelLocked(keyphraseId);
if (status != STATUS_OK) {
return status;
}
+ removeKeyphraseModelLocked(keyphraseId);
model = null;
}
@@ -478,8 +478,6 @@
} else {
// Clear the ModelData state if successful.
modelData.clearState();
- modelData.clearCallback();
- modelData.setRecognitionConfig(null);
}
}
return status;
@@ -498,15 +496,12 @@
// Stop all recognition models.
for (ModelData model : mModelDataMap.values()) {
if (model.isModelStarted()) {
- model.setRequested(false);
int status = stopRecognitionLocked(model,
false /* do not notify for synchronous calls */);
if (status != STATUS_OK) {
Slog.w(TAG, "Error stopping keyphrase model: " + model.getHandle());
}
model.clearState();
- model.clearCallback();
- model.setRecognitionConfig(null);
}
}
internalClearGlobalStateLocked();
@@ -849,7 +844,6 @@
private void internalClearModelStateLocked() {
for (ModelData modelData : mModelDataMap.values()) {
modelData.clearState();
- modelData.clearCallback();
}
}
@@ -1194,6 +1188,9 @@
synchronized void clearState() {
mModelState = MODEL_NOTLOADED;
mModelHandle = INVALID_VALUE;
+ mRecognitionConfig = null;
+ mRequested = false;
+ mCallback = null;
}
synchronized void clearCallback() {