Merge "Move tasks to fullscreen stack when dismissing docked stack."
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index e7dd5ff..620ab50 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -3330,7 +3330,6 @@
if (mN.color != COLOR_DEFAULT) {
button.setTextColor(R.id.action0, mN.color);
}
- processLegacyAction(action, button);
return button;
}
@@ -3342,14 +3341,6 @@
return getColorUtil() != null;
}
- private void processLegacyAction(Action action, RemoteViews button) {
- if (!isLegacy() || getColorUtil().isGrayscaleIcon(mContext, action.getIcon())) {
- button.setTextViewCompoundDrawablesRelativeColorFilter(R.id.action0, 0,
- mContext.getColor(R.color.notification_action_color_filter),
- PorterDuff.Mode.MULTIPLY);
- }
- }
-
private CharSequence processLegacyText(CharSequence charSequence) {
if (isLegacy()) {
return getColorUtil().invertCharSequenceColors(charSequence);
diff --git a/core/java/android/text/method/WordIterator.java b/core/java/android/text/method/WordIterator.java
index 3688cfa..664d1ea 100644
--- a/core/java/android/text/method/WordIterator.java
+++ b/core/java/android/text/method/WordIterator.java
@@ -20,7 +20,7 @@
import android.text.Selection;
import android.text.SpannableStringBuilder;
-import java.text.BreakIterator;
+import android.icu.text.BreakIterator;
import java.util.Locale;
/**
diff --git a/core/java/com/android/internal/inputmethod/InputMethodSubtypeSwitchingController.java b/core/java/com/android/internal/inputmethod/InputMethodSubtypeSwitchingController.java
index e607a3f..85cc841 100644
--- a/core/java/com/android/internal/inputmethod/InputMethodSubtypeSwitchingController.java
+++ b/core/java/com/android/internal/inputmethod/InputMethodSubtypeSwitchingController.java
@@ -175,7 +175,7 @@
}
private final TreeMap<InputMethodInfo, List<InputMethodSubtype>> mSortedImmis =
- new TreeMap<InputMethodInfo, List<InputMethodSubtype>>(
+ new TreeMap<>(
new Comparator<InputMethodInfo>() {
@Override
public int compare(InputMethodInfo imi1, InputMethodInfo imi2) {
@@ -192,14 +192,9 @@
}
});
- public List<ImeSubtypeListItem> getSortedInputMethodAndSubtypeList() {
- return getSortedInputMethodAndSubtypeList(true, false, false);
- }
-
public List<ImeSubtypeListItem> getSortedInputMethodAndSubtypeList(
- boolean showSubtypes, boolean includeAuxiliarySubtypes, boolean isScreenLocked) {
- final ArrayList<ImeSubtypeListItem> imList =
- new ArrayList<ImeSubtypeListItem>();
+ boolean includeAuxiliarySubtypes, boolean isScreenLocked) {
+ final ArrayList<ImeSubtypeListItem> imList = new ArrayList<>();
final HashMap<InputMethodInfo, List<InputMethodSubtype>> immis =
mSettings.getExplicitlyOrImplicitlyEnabledInputMethodsAndSubtypeListLocked(
mContext);
@@ -219,12 +214,12 @@
continue;
}
List<InputMethodSubtype> explicitlyOrImplicitlyEnabledSubtypeList = immis.get(imi);
- HashSet<String> enabledSubtypeSet = new HashSet<String>();
+ HashSet<String> enabledSubtypeSet = new HashSet<>();
for (InputMethodSubtype subtype : explicitlyOrImplicitlyEnabledSubtypeList) {
enabledSubtypeSet.add(String.valueOf(subtype.hashCode()));
}
final CharSequence imeLabel = imi.loadLabel(mPm);
- if (showSubtypes && enabledSubtypeSet.size() > 0) {
+ if (enabledSubtypeSet.size() > 0) {
final int subtypeCount = imi.getSubtypeCount();
if (DEBUG) {
Slog.v(TAG, "Add subtypes: " + subtypeCount + ", " + imi.getId());
@@ -532,7 +527,8 @@
public void resetCircularListLocked(Context context) {
mSubtypeList = new InputMethodAndSubtypeList(context, mSettings);
mController = ControllerImpl.createFrom(mController,
- mSubtypeList.getSortedInputMethodAndSubtypeList());
+ mSubtypeList.getSortedInputMethodAndSubtypeList(
+ false /* includeAuxiliarySubtypes */, false /* isScreenLocked */));
}
public ImeSubtypeListItem getNextInputMethodLocked(boolean onlyCurrentIme, InputMethodInfo imi,
@@ -546,10 +542,10 @@
return mController.getNextInputMethod(onlyCurrentIme, imi, subtype);
}
- public List<ImeSubtypeListItem> getSortedInputMethodAndSubtypeListLocked(boolean showSubtypes,
+ public List<ImeSubtypeListItem> getSortedInputMethodAndSubtypeListLocked(
boolean includingAuxiliarySubtypes, boolean isScreenLocked) {
return mSubtypeList.getSortedInputMethodAndSubtypeList(
- showSubtypes, includingAuxiliarySubtypes, isScreenLocked);
+ includingAuxiliarySubtypes, isScreenLocked);
}
public void dump(final Printer pw) {
diff --git a/core/res/res/layout/notification_material_action.xml b/core/res/res/layout/notification_material_action.xml
index 62602d8..398f52d 100644
--- a/core/res/res/layout/notification_material_action.xml
+++ b/core/res/res/layout/notification_material_action.xml
@@ -22,7 +22,7 @@
android:layout_height="48dp"
android:layout_gravity="center"
android:layout_marginStart="4dp"
- android:textColor="@color/secondary_text_material_light"
+ android:textColor="@color/notification_default_color"
android:singleLine="true"
android:ellipsize="end"
android:background="@drawable/notification_material_action_background"
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index af8ff2e..7711825 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -130,8 +130,8 @@
<drawable name="notification_template_divider">#29000000</drawable>
<drawable name="notification_template_divider_media">#29ffffff</drawable>
- <color name="notification_icon_default_color">#ff616161</color>
- <color name="notification_action_color_filter">@color/secondary_text_material_light</color>
+ <color name="notification_default_color">#757575</color> <!-- Gray 600 -->
+ <color name="notification_icon_default_color">@color/notification_default_color</color>
<color name="notification_progress_background_color">@color/secondary_text_material_light</color>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 530b08d..dd81f89 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1874,7 +1874,6 @@
<java-symbol type="layout" name="notification_template_material_big_text" />
<java-symbol type="layout" name="notification_template_header" />
<java-symbol type="layout" name="notification_material_media_action" />
- <java-symbol type="color" name="notification_action_color_filter" />
<java-symbol type="color" name="notification_icon_default_color" />
<java-symbol type="color" name="notification_progress_background_color" />
<java-symbol type="id" name="media_actions" />
diff --git a/graphics/java/android/graphics/FontListParser.java b/graphics/java/android/graphics/FontListParser.java
index e4494ca..2596f53 100644
--- a/graphics/java/android/graphics/FontListParser.java
+++ b/graphics/java/android/graphics/FontListParser.java
@@ -114,7 +114,8 @@
if (parser.getEventType() != XmlPullParser.START_TAG) continue;
String tag = parser.getName();
if (tag.equals("font")) {
- int ttcIndex = Integer.parseInt(parser.getAttributeValue("0", "ttcIndex"));
+ String ttcIndexStr = parser.getAttributeValue(null, "ttcIndex");
+ int ttcIndex = ttcIndexStr == null ? 0 : Integer.parseInt(ttcIndexStr);
String weightStr = parser.getAttributeValue(null, "weight");
int weight = weightStr == null ? 400 : Integer.parseInt(weightStr);
boolean isItalic = "italic".equals(parser.getAttributeValue(null, "style"));
diff --git a/packages/SystemUI/res/color/remote_input_send.xml b/packages/SystemUI/res/color/remote_input_send.xml
new file mode 100644
index 0000000..fe2ffaa
--- /dev/null
+++ b/packages/SystemUI/res/color/remote_input_send.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_enabled="true" android:color="@android:color/white" />
+ <item android:color="#4dffffff" /> <!-- 30% white -->
+</selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/color/remote_input_text.xml b/packages/SystemUI/res/color/remote_input_text.xml
new file mode 100644
index 0000000..11ce0b7
--- /dev/null
+++ b/packages/SystemUI/res/color/remote_input_text.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_enabled="true" android:color="@android:color/white" />
+ <item android:color="#99ffffff" /> <!-- 60% white -->
+</selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/recents_freeform_workspace_bg.xml b/packages/SystemUI/res/drawable/recents_freeform_workspace_bg.xml
new file mode 100644
index 0000000..5f9341c
--- /dev/null
+++ b/packages/SystemUI/res/drawable/recents_freeform_workspace_bg.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle">
+ <corners android:topLeftRadius="@dimen/recents_task_view_rounded_corners_radius"
+ android:topRightRadius="@dimen/recents_task_view_rounded_corners_radius"/>
+ <solid android:color="#00000000" />
+</shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/remote_input.xml b/packages/SystemUI/res/layout/remote_input.xml
index 74092c1..83cfc76 100644
--- a/packages/SystemUI/res/layout/remote_input.xml
+++ b/packages/SystemUI/res/layout/remote_input.xml
@@ -36,7 +36,8 @@
android:paddingEnd="12dp"
android:gravity="start|center_vertical"
android:textAppearance="?android:attr/textAppearance"
- android:textColor="#deffffff"
+ android:textColor="@color/remote_input_text"
+ android:textColorHint="@color/remote_input_hint"
android:textSize="16sp"
android:background="@null"
android:singleLine="true"
@@ -58,8 +59,8 @@
android:paddingBottom="12dp"
android:id="@+id/remote_input_send"
android:src="@drawable/ic_send"
- android:tint="@android:color/white"
- android:tintMode="src_atop"
+ android:tint="@color/remote_input_send"
+ android:tintMode="src_in"
android:background="@drawable/ripple_drawable" />
<ProgressBar
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 5618e9b..8875515 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -68,6 +68,8 @@
<color name="recents_task_view_lock_to_app_button_background_color">#ffe6e6e6</color>
<!-- The lock to task button foreground color. -->
<color name="recents_task_view_lock_to_app_button_color">#ff666666</color>
+ <!-- The background color for the freeform workspace. -->
+ <color name="recents_freeform_workspace_bg_color">#66000000</color>
<color name="keyguard_affordance">#ffffffff</color>
@@ -144,4 +146,7 @@
<color name="docked_divider_background">#ff000000</color>
<color name="docked_divider_handle">#ffffff</color>
+
+ <color name="default_remote_input_background">@*android:color/notification_default_color</color>
+ <color name="remote_input_hint">#4dffffff</color>
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/AnimateableViewBounds.java b/packages/SystemUI/src/com/android/systemui/recents/views/AnimateableViewBounds.java
index 757d2aa..f646a92 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/AnimateableViewBounds.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/AnimateableViewBounds.java
@@ -46,19 +46,6 @@
}
};
- public static final Property<AnimateableViewBounds, Integer> CLIP_RIGHT =
- new IntProperty<AnimateableViewBounds>("clipRight") {
- @Override
- public void setValue(AnimateableViewBounds object, int clip) {
- object.setClipRight(clip, false /* force */);
- }
-
- @Override
- public Integer get(AnimateableViewBounds object) {
- return object.getClipRight();
- }
- };
-
public AnimateableViewBounds(View source, int cornerRadius) {
mSourceView = source;
mCornerRadius = cornerRadius;
@@ -102,19 +89,6 @@
return mClipRect.bottom;
}
- /** Sets the right clip. */
- public void setClipRight(int right, boolean force) {
- if (right != mClipRect.right || force) {
- mClipRect.right = right;
- updateClipBounds();
- }
- }
-
- /** Returns the right clip. */
- public int getClipRight() {
- return mClipRect.right;
- }
-
private void updateClipBounds() {
mClipBounds.set(mClipRect.left, mClipRect.top,
mSourceView.getWidth() - mClipRect.right,
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/FreeformWorkspaceLayoutAlgorithm.java b/packages/SystemUI/src/com/android/systemui/recents/views/FreeformWorkspaceLayoutAlgorithm.java
index 9b9d58c..2351aa3 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/FreeformWorkspaceLayoutAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/FreeformWorkspaceLayoutAlgorithm.java
@@ -19,7 +19,6 @@
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.Log;
-import com.android.systemui.recents.misc.Utilities;
import com.android.systemui.recents.model.Task;
import java.util.Collections;
@@ -80,7 +79,6 @@
float width = normalizedTaskWidths[i] * rowScale;
if (rowWidth + width > normalizedWorkspaceWidth) {
// That is too long for this row, create new row
- rowWidth = 0f;
if ((rowCount + 1) * rowScale > normalizedWorkspaceHeight) {
// The new row is too high, so we need to try fitting again. Update the
// scale to be the smaller of the scale needed to fit the task in the
@@ -88,9 +86,11 @@
rowScale = Math.min(normalizedWorkspaceWidth / (rowWidth + width),
normalizedWorkspaceHeight / (rowCount + 1));
rowCount = 1;
+ rowWidth = 0;
i = 0;
} else {
// The new row fits, so continue
+ rowWidth = width;
rowCount++;
i++;
}
@@ -103,20 +103,20 @@
}
// Normalize each of the actual rects to that scale
- int height = (int) (rowScale * workspaceHeight);
- float rowTop = ((1f - (rowScale * rowCount)) * workspaceHeight) / 2f;
float defaultRowLeft = ((1f - (maxRowWidth / normalizedWorkspaceWidth)) *
workspaceWidth) / 2f;
float rowLeft = defaultRowLeft;
+ float rowTop = ((1f - (rowScale * rowCount)) * workspaceHeight) / 2f;
+ float rowHeight = rowScale * workspaceHeight;
for (int i = 0; i < numFreeformTasks; i++) {
Task task = freeformTasks.get(i);
- int width = (int) (height * normalizedTaskWidths[i]);
+ float width = rowHeight * normalizedTaskWidths[i];
if (rowLeft + width > workspaceWidth) {
// This goes on the next line
- rowTop += height;
+ rowTop += rowHeight;
rowLeft = defaultRowLeft;
}
- RectF rect = new RectF(rowLeft, rowTop, rowLeft + width, rowTop + height);
+ RectF rect = new RectF(rowLeft, rowTop, rowLeft + width, rowTop + rowHeight);
rowLeft += width;
mTaskRectMap.put(task.key, rect);
}
@@ -140,34 +140,29 @@
public TaskViewTransform getTransform(Task task, TaskViewTransform transformOut,
TaskStackLayoutAlgorithm stackLayout) {
if (mTaskRectMap.containsKey(task.key)) {
- Rect taskRect = stackLayout.mTaskRect;
- RectF ffRect = mTaskRectMap.get(task.key);
- float scale = Math.max(ffRect.width() / taskRect.width(),
- ffRect.height() / taskRect.height());
- int topOffset = (stackLayout.mFreeformRect.top - taskRect.top);
- int scaleXOffset = (int) (((1f - scale) * taskRect.width()) / 2);
- int scaleYOffset = (int) (((1f - scale) * taskRect.height()) / 2);
+ final Rect taskRect = stackLayout.mTaskRect;
+ final RectF ffRect = mTaskRectMap.get(task.key);
- transformOut.scale = scale * 0.95f;
- transformOut.translationX = (int) (ffRect.left - scaleXOffset);
- transformOut.translationY = (int) (topOffset + ffRect.top - scaleYOffset);
+ transformOut.scale = 1f;
+ transformOut.alpha = 1f;
transformOut.translationZ = stackLayout.mMaxTranslationZ;
- transformOut.clipBottom = (int) (taskRect.height() - (ffRect.height() / scale));
- transformOut.clipRight = (int) (taskRect.width() - (ffRect.width() / scale));
if (task.thumbnail != null) {
- transformOut.thumbnailScale = Math.min(
- ((float) taskRect.width() - transformOut.clipRight) /
- task.thumbnail.getWidth(),
- ((float) taskRect.height() - transformOut.clipBottom) /
- task.thumbnail.getHeight());
+ if (task.bounds == null) {
+ // This is a stack task that has no freeform thumbnail, so keep the same bitmap
+ // scale as it had in the stack
+ transformOut.thumbnailScale = (float) taskRect.width() /
+ task.thumbnail.getWidth();
+ } else {
+ // This is a freeform rect so fit the bitmap to the task bounds
+ transformOut.thumbnailScale = Math.min(
+ ffRect.width() / task.thumbnail.getWidth(),
+ ffRect.height() / task.thumbnail.getHeight());
+ }
} else {
transformOut.thumbnailScale = 1f;
}
- transformOut.rect.set(taskRect);
- transformOut.rect.offset(transformOut.translationX, transformOut.translationY);
- Utilities.scaleRectAboutCenter(transformOut.rect, transformOut.scale);
- transformOut.rect.right -= transformOut.clipRight * scale;
- transformOut.rect.bottom -= transformOut.clipBottom * scale;
+ transformOut.rect.set(ffRect);
+ transformOut.rect.offset(stackLayout.mFreeformRect.left, stackLayout.mFreeformRect.top);
transformOut.visible = true;
transformOut.p = 1f;
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 7d5daae..f599f52 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
@@ -507,6 +507,15 @@
}
/**
+ * Returns the task progress that would put the task just off the back of the stack.
+ */
+ public float getStackBackTaskProgress(float stackScroll) {
+ float min = mUnfocusedRange.relativeMin +
+ mFocusState * (mFocusedRange.relativeMin - mUnfocusedRange.relativeMin);
+ return stackScroll + min;
+ }
+
+ /**
* Returns the task progress that would put the task just off the front of the stack.
*/
public float getStackFrontTaskProgress(float stackScroll) {
@@ -647,6 +656,7 @@
return transformOut;
}
+ int x = (mStackRect.width() - mTaskRect.width()) / 2;
int y;
float z;
float relP;
@@ -671,16 +681,13 @@
// Fill out the transform
transformOut.scale = 1f;
- transformOut.translationX = (mStackRect.width() - mTaskRect.width()) / 2;
- transformOut.translationY = y;
+ transformOut.alpha = 1f;
transformOut.translationZ = z;
transformOut.rect.set(mTaskRect);
- transformOut.rect.offset(transformOut.translationX, transformOut.translationY);
+ transformOut.rect.offset(x, y);
Utilities.scaleRectAboutCenter(transformOut.rect, transformOut.scale);
transformOut.visible = (transformOut.rect.top < mStackRect.bottom) &&
(frontTransform == null || transformOut.rect.top != frontTransform.rect.top);
- transformOut.clipBottom = 0;
- transformOut.clipRight = 0;
transformOut.thumbnailScale = 1f;
transformOut.p = relP;
return transformOut;
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 cc5aaae..350bc2b 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -20,11 +20,12 @@
import android.animation.ValueAnimator;
import android.content.ComponentName;
import android.content.Context;
+import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.RectF;
-import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
+import android.graphics.drawable.GradientDrawable;
import android.os.Bundle;
import android.util.IntProperty;
import android.util.Log;
@@ -94,15 +95,15 @@
private static final float SHOW_HISTORY_BUTTON_SCROLL_THRESHOLD = 0.3f;
private static final float HIDE_HISTORY_BUTTON_SCROLL_THRESHOLD = 0.3f;
- public static final Property<ColorDrawable, Integer> COLOR_DRAWABLE_ALPHA =
- new IntProperty<ColorDrawable>("colorDrawableAlpha") {
+ public static final Property<Drawable, Integer> DRAWABLE_ALPHA =
+ new IntProperty<Drawable>("drawableAlpha") {
@Override
- public void setValue(ColorDrawable object, int alpha) {
+ public void setValue(Drawable object, int alpha) {
object.setAlpha(alpha);
}
@Override
- public Integer get(ColorDrawable object) {
+ public Integer get(Drawable object) {
return object.getAlpha();
}
};
@@ -118,7 +119,7 @@
TaskStackViewScroller mStackScroller;
TaskStackViewTouchHandler mTouchHandler;
TaskStackViewCallbacks mCb;
- ColorDrawable mFreeformWorkspaceBackground;
+ GradientDrawable mFreeformWorkspaceBackground;
ObjectAnimator mFreeformWorkspaceBackgroundAnimator;
ViewPool<TaskView, Task> mViewPool;
ArrayList<TaskViewTransform> mCurrentTaskTransforms = new ArrayList<>();
@@ -126,6 +127,7 @@
Task mFocusedTask;
// Optimizations
int mStackViewsAnimationDuration;
+ int mTaskCornerRadiusPx;
boolean mStackViewsDirty = true;
boolean mStackViewsClipDirty = true;
boolean mAwaitingFirstLayout = true;
@@ -174,6 +176,9 @@
public TaskStackView(Context context, TaskStack stack) {
super(context);
+ SystemServicesProxy ssp = Recents.getSystemServices();
+ Resources res = context.getResources();
+
// Set the stack first
setStack(stack);
mViewPool = new ViewPool<>(context, this);
@@ -184,6 +189,8 @@
mTouchHandler = new TaskStackViewTouchHandler(context, this, mStackScroller);
mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
com.android.internal.R.interpolator.fast_out_slow_in);
+ mTaskCornerRadiusPx = res.getDimensionPixelSize(
+ R.dimen.recents_task_view_rounded_corners_radius);
int taskBarDismissDozeDelaySeconds = getResources().getInteger(
R.integer.recents_task_bar_dismiss_delay_seconds);
@@ -201,8 +208,12 @@
});
setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
- mFreeformWorkspaceBackground = new ColorDrawable(0x33000000);
+ mFreeformWorkspaceBackground = (GradientDrawable) getContext().getDrawable(
+ R.drawable.recents_freeform_workspace_bg);
mFreeformWorkspaceBackground.setCallback(this);
+ if (ssp.hasFreeformWorkspaceSupport()) {
+ setBackgroundColor(getContext().getColor(R.color.recents_freeform_workspace_bg_color));
+ }
}
/** Sets the callbacks */
@@ -364,8 +375,7 @@
private boolean updateStackTransforms(ArrayList<TaskViewTransform> taskTransforms,
ArrayList<Task> tasks,
float stackScroll,
- int[] visibleRangeOut,
- boolean boundTranslationsToRect) {
+ int[] visibleRangeOut) {
int taskTransformCount = taskTransforms.size();
int taskCount = tasks.size();
int frontMostVisibleIndex = -1;
@@ -411,11 +421,6 @@
break;
}
}
-
- if (boundTranslationsToRect) {
- transform.translationY = Math.min(transform.translationY,
- mLayoutAlgorithm.mStackRect.bottom);
- }
frontTransform = transform;
}
if (visibleRangeOut != null) {
@@ -433,7 +438,7 @@
float stackScroll = mStackScroller.getStackScroll();
int[] visibleStackRange = mTmpVisibleRange;
boolean isValidVisibleStackRange = updateStackTransforms(mCurrentTaskTransforms, tasks,
- stackScroll, visibleStackRange, false);
+ stackScroll, visibleStackRange);
boolean hasStackBackTransform = false;
boolean hasStackFrontTransform = false;
if (DEBUG) {
@@ -490,7 +495,7 @@
}
// Animate the task into place
- tv.updateViewPropertiesToTaskTransform(transform, transform.clipBottom,
+ tv.updateViewPropertiesToTaskTransform(transform, 0,
mStackViewsAnimationDuration, mFastOutSlowInInterpolator,
mRequestUpdateClippingListener);
@@ -513,8 +518,9 @@
if (Float.compare(transform.p, 0f) <= 0) {
if (!hasStackBackTransform) {
hasStackBackTransform = true;
- mLayoutAlgorithm.getStackTransform(0f, 0f, mTmpStackBackTransform,
- null);
+ mLayoutAlgorithm.getStackTransform(
+ mLayoutAlgorithm.getStackBackTaskProgress(0f), 0f,
+ mTmpStackBackTransform, null);
}
tv.updateViewPropertiesToTaskTransform(mTmpStackBackTransform, 0, 0,
mFastOutSlowInInterpolator, mRequestUpdateClippingListener);
@@ -586,17 +592,11 @@
// stacked and we can make assumptions about the visibility of the this
// task relative to the ones in front of it.
if (frontTv != null) {
- mTmpTaskRect.set(mLayoutAlgorithm.mTaskRect);
- mTmpTaskRect.offset(0, tv.getTranslationY());
- Utilities.scaleRectAboutCenter(mTmpTaskRect, tv.getScaleX());
- float taskBottom = mTmpTaskRect.bottom;
- mTmpTaskRect.set(mLayoutAlgorithm.mTaskRect);
- mTmpTaskRect.offset(0, frontTv.getTranslationY());
- Utilities.scaleRectAboutCenter(mTmpTaskRect, frontTv.getScaleX());
- float frontTaskTop = mTmpTaskRect.top;
+ float taskBottom = tv.getBottom();
+ float frontTaskTop = frontTv.getTop();
if (frontTaskTop < taskBottom) {
// Map the stack view space coordinate (the rects) to view space
- clipBottom = (int) ((taskBottom - frontTaskTop) / tv.getScaleX()) - 1;
+ clipBottom = (int) (taskBottom - frontTaskTop) - mTaskCornerRadiusPx;
}
}
}
@@ -980,11 +980,11 @@
onFirstLayout();
}
+ requestSynchronizeStackViewsWithModel();
if (changed) {
if (mStackScroller.isScrollOutOfBounds()) {
mStackScroller.boundScroll();
}
- requestSynchronizeStackViewsWithModel();
synchronizeStackViewsWithModel();
requestUpdateStackViewsClip();
clipTaskViews(true /* forceUpdate */);
@@ -1147,8 +1147,7 @@
transformPointToViewLocal(point, tv);
x = point[0];
y = point[1];
- return (0 <= x) && (x < (tv.getMeasuredWidth() - tv.getViewBounds().getClipRight())) &&
- (0 <= y) && (y < (tv.getMeasuredHeight() - tv.getViewBounds().getClipBottom()));
+ return (0 <= x) && (x < tv.getWidth()) && (0 <= y) && (y < tv.getHeight());
}
@Override
@@ -1221,14 +1220,13 @@
} else if (pullStackForward) {
// Otherwise, offset the scroll by the movement of the anchor task
float anchorTaskScroll = mLayoutAlgorithm.getStackScrollForTask(anchorTask);
- float newStackScroll = mStackScroller.getStackScroll() +
- (anchorTaskScroll - prevAnchorTaskScroll);
+ float stackScrollOffset = (anchorTaskScroll - prevAnchorTaskScroll);
if (mLayoutAlgorithm.getFocusState() != TaskStackLayoutAlgorithm.STATE_FOCUSED) {
// If we are focused, we don't want the front task to move, but otherwise, we
// allow the back task to move up, and the front task to move back
- newStackScroll /= 2;
+ stackScrollOffset /= 2;
}
- mStackScroller.setStackScroll(newStackScroll);
+ mStackScroller.setStackScroll(mStackScroller.getStackScroll() + stackScrollOffset);
mStackScroller.boundScroll();
}
@@ -1498,6 +1496,18 @@
event.taskView.animate()
.withEndAction(event.postAnimationTrigger.decrementAsRunnable());
+ // 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();
+ int y = (int) event.taskView.getTranslationY();
+ Rect taskViewRect = new Rect(event.taskView.getLeft(), event.taskView.getTop(),
+ event.taskView.getRight(), event.taskView.getBottom());
+ taskViewRect.offset(x, y);
+ event.taskView.setTranslationX(0);
+ event.taskView.setTranslationY(0);
+ event.taskView.setLeftTopRightBottom(taskViewRect.left, taskViewRect.top,
+ taskViewRect.right, taskViewRect.bottom);
+
// Animate the tack view back into position
requestSynchronizeStackViewsWithModel(250);
}
@@ -1582,7 +1592,7 @@
Utilities.cancelAnimationWithoutCallbacks(mFreeformWorkspaceBackgroundAnimator);
mFreeformWorkspaceBackgroundAnimator = ObjectAnimator.ofInt(mFreeformWorkspaceBackground,
- COLOR_DRAWABLE_ALPHA, mFreeformWorkspaceBackground.getAlpha(), targetAlpha);
+ DRAWABLE_ALPHA, mFreeformWorkspaceBackground.getAlpha(), targetAlpha);
mFreeformWorkspaceBackgroundAnimator.setDuration(duration);
mFreeformWorkspaceBackgroundAnimator.setInterpolator(interpolator);
mFreeformWorkspaceBackgroundAnimator.start();
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 813a1fc..1e2227e 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -179,6 +179,13 @@
}
@Override
+ protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+ super.onSizeChanged(w, h, oldw, oldh);
+ mHeaderView.onTaskViewSizeChanged(w, h);
+ mThumbnailView.onTaskViewSizeChanged(w, h);
+ }
+
+ @Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
mDownTouchPos.set((int) (ev.getX() * getScaleX()), (int) (ev.getY() * getScaleY()));
@@ -232,8 +239,14 @@
mClipAnimation.playTogether(
ObjectAnimator.ofInt(mViewBounds, AnimateableViewBounds.CLIP_BOTTOM,
mViewBounds.getClipBottom(), clipBottom),
- ObjectAnimator.ofInt(mViewBounds, AnimateableViewBounds.CLIP_RIGHT,
- mViewBounds.getClipRight(), toTransform.clipRight),
+ ObjectAnimator.ofInt(this, TaskViewTransform.LEFT, getLeft(),
+ (int) toTransform.rect.left),
+ ObjectAnimator.ofInt(this, TaskViewTransform.TOP, getTop(),
+ (int) toTransform.rect.top),
+ ObjectAnimator.ofInt(this, TaskViewTransform.RIGHT, getRight(),
+ (int) toTransform.rect.right),
+ ObjectAnimator.ofInt(this, TaskViewTransform.BOTTOM, getBottom(),
+ (int) toTransform.rect.bottom),
ObjectAnimator.ofFloat(mThumbnailView, TaskViewThumbnail.BITMAP_SCALE,
mThumbnailView.getBitmapScale(), toTransform.thumbnailScale));
mClipAnimation.setStartDelay(toTransform.startDelay);
@@ -242,8 +255,9 @@
mClipAnimation.start();
} else {
mViewBounds.setClipBottom(clipBottom, false /* forceUpdate */);
- mViewBounds.setClipRight(toTransform.clipRight, false /* forceUpdate */);
mThumbnailView.setBitmapScale(toTransform.thumbnailScale);
+ setLeftTopRightBottom((int) toTransform.rect.left, (int) toTransform.rect.top,
+ (int) toTransform.rect.right, (int) toTransform.rect.bottom);
}
if (!config.useHardwareLayers) {
mThumbnailView.updateThumbnailVisibility(clipBottom - getPaddingBottom());
@@ -336,10 +350,10 @@
} else {
// Animate the task up if it was occluding the launch target
if (ctx.currentTaskOccludesLaunchTarget) {
- setTranslationY(transform.translationY + taskViewAffiliateGroupEnterOffset);
+ setTranslationY(taskViewAffiliateGroupEnterOffset);
setAlpha(0f);
animate().alpha(1f)
- .translationY(transform.translationY)
+ .translationY(0)
.setUpdateListener(null)
.setListener(new AnimatorListenerAdapter() {
private boolean hasEnded;
@@ -372,7 +386,7 @@
animate().translationZ(transform.translationZ);
}
animate()
- .translationY(transform.translationY)
+ .translationY(0)
.setStartDelay(delay)
.setUpdateListener(ctx.updateListener)
.setListener(new AnimatorListenerAdapter() {
@@ -644,7 +658,6 @@
}
SystemServicesProxy ssp = Recents.getSystemServices();
- mHeaderView.onTaskViewFocusChanged(isFocused, animated);
if (isFocused) {
if (requestViewFocus && !isFocused()) {
requestFocus();
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 78a2c7f..d8220fd 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
@@ -31,6 +31,7 @@
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.RippleDrawable;
+import android.graphics.drawable.ShapeDrawable;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewOutlineProvider;
@@ -55,8 +56,6 @@
public class TaskViewHeader extends FrameLayout
implements View.OnClickListener, View.OnLongClickListener {
- private static final float FOCUS_TRANSLATION_Z = 4f;
-
Task mTask;
// Header views
@@ -66,13 +65,13 @@
TextView mActivityDescription;
// Header drawables
+ Rect mTaskViewRect = new Rect();
int mCornerRadius;
int mHighlightHeight;
Drawable mLightDismissDrawable;
Drawable mDarkDismissDrawable;
RippleDrawable mBackground;
GradientDrawable mBackgroundColorDrawable;
- ObjectAnimator mFocusAnimator;
String mDismissContentDescription;
// Static highlight that we draw at the top of each view
@@ -99,13 +98,6 @@
public TaskViewHeader(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
setWillNotDraw(false);
- setClipToOutline(true);
- setOutlineProvider(new ViewOutlineProvider() {
- @Override
- public void getOutline(View view, Outline outline) {
- outline.setRect(0, 0, getMeasuredWidth(), getMeasuredHeight());
- }
- });
// Load the dismiss resources
mDimLayerPaint.setColor(Color.argb(0, 0, 0, 0));
@@ -148,8 +140,8 @@
mApplicationIcon.setBackground(null);
}
- mBackgroundColorDrawable = (GradientDrawable) getContext().getDrawable(R.drawable
- .recents_task_view_header_bg_color);
+ mBackgroundColorDrawable = (GradientDrawable) getContext().getDrawable(
+ R.drawable.recents_task_view_header_bg_color);
// Copy the ripple drawable since we are going to be manipulating it
mBackground = (RippleDrawable)
getContext().getDrawable(R.drawable.recents_task_view_header_bg);
@@ -159,14 +151,37 @@
setBackground(mBackground);
}
+ /**
+ * Called when the task view frame changes, allowing us to move the contents of the header
+ * to match the frame changes.
+ */
+ public void onTaskViewSizeChanged(int width, int height) {
+ mTaskViewRect.set(0, 0, width, height);
+ if (mDismissButton.getMeasuredWidth() > (width - mApplicationIcon.getMeasuredWidth())) {
+ mDismissButton.setAlpha(0f);
+ } else {
+ mDismissButton.setAlpha(1f);
+ if (mDismissButton != null) {
+ mDismissButton.setTranslationX(width - getMeasuredWidth());
+ }
+ }
+ if (mActivityDescription.getMeasuredWidth() > (width -
+ (mApplicationIcon.getMeasuredWidth() + mDismissButton.getMeasuredWidth()))) {
+ mActivityDescription.setAlpha(0f);
+ } else {
+ mActivityDescription.setAlpha(1f);
+ }
+ invalidate();
+ }
+
@Override
protected void onDraw(Canvas canvas) {
// Draw the highlight at the top edge (but put the bottom edge just out of view)
float offset = (float) Math.ceil(mHighlightHeight / 2f);
float radius = mCornerRadius;
int count = canvas.save(Canvas.CLIP_SAVE_FLAG);
- canvas.clipRect(0, 0, getMeasuredWidth(), getMeasuredHeight());
- canvas.drawRoundRect(-offset, 0f, (float) getMeasuredWidth() + offset,
+ canvas.clipRect(0, 0, mTaskViewRect.width(), getMeasuredHeight());
+ canvas.drawRoundRect(-offset, 0f, (float) mTaskViewRect.width() + offset,
getMeasuredHeight() + radius, radius, radius, sHighlightPaint);
canvas.restoreToCount(count);
}
@@ -180,12 +195,6 @@
invalidate();
}
- /** Returns the secondary color for a primary color. */
- int getSecondaryColor(int primaryColor, boolean useLightOverlayColor) {
- int overlayColor = useLightOverlayColor ? Color.WHITE : Color.BLACK;
- return Utilities.getColorWithOverlay(primaryColor, overlayColor, 0.8f);
- }
-
/** Binds the bar view to the task */
public void rebindToTask(Task t) {
mTask = t;
@@ -236,9 +245,6 @@
mApplicationIcon.setImageDrawable(null);
mApplicationIcon.setOnClickListener(null);
mMoveTaskButton.setOnClickListener(null);
-
- // Stop any focus animations
- Utilities.cancelAnimationWithoutCallbacks(mFocusAnimator);
}
/** Updates the resize task bar button. */
@@ -332,39 +338,9 @@
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
- // Draw the thumbnail with the rounded corners
- canvas.drawRoundRect(0, 0, getWidth(), getHeight(),
- mCornerRadius,
- mCornerRadius, mDimLayerPaint);
- }
-
- /** Notifies the associated TaskView has been focused. */
- void onTaskViewFocusChanged(boolean focused, boolean animateFocusedState) {
- boolean isRunning = false;
- if (mFocusAnimator != null) {
- isRunning = mFocusAnimator.isRunning();
- }
- Utilities.cancelAnimationWithoutCallbacks(mFocusAnimator);
-
- if (focused) {
- if (animateFocusedState) {
- // Bump up the translation
- mFocusAnimator = ObjectAnimator.ofFloat(this, "translationZ", FOCUS_TRANSLATION_Z);
- mFocusAnimator.setDuration(200);
- mFocusAnimator.start();
- } else {
- setTranslationZ(FOCUS_TRANSLATION_Z);
- }
- } else {
- if (isRunning) {
- // Restore the translation
- mFocusAnimator = ObjectAnimator.ofFloat(this, "translationZ", 0f);
- mFocusAnimator.setDuration(150);
- mFocusAnimator.start();
- } else {
- setTranslationZ(0f);
- }
- }
+ // Draw the dim layer with the rounded corners
+ canvas.drawRoundRect(0, 0, mTaskViewRect.width(), getHeight(),
+ mCornerRadius, mCornerRadius, mDimLayerPaint);
}
@Override
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 7bb2c7b..37d8cd6 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java
@@ -56,6 +56,7 @@
};
// Drawing
+ Rect mTaskViewRect = new Rect();
int mCornerRadius;
float mDimAlpha;
Matrix mScaleMatrix = new Matrix();
@@ -98,13 +99,22 @@
com.android.internal.R.interpolator.fast_out_slow_in);
}
+ /**
+ * Called when the task view frame changes, allowing us to move the contents of the header
+ * to match the frame changes.
+ */
+ public void onTaskViewSizeChanged(int width, int height) {
+ mTaskViewRect.set(0, 0, width, height);
+ invalidate();
+ }
+
@Override
protected void onDraw(Canvas canvas) {
if (mInvisible) {
return;
}
// Draw the thumbnail with the rounded corners
- canvas.drawRoundRect(0, 0, getWidth(), getHeight(),
+ canvas.drawRoundRect(0, 0, mTaskViewRect.width(), mTaskViewRect.height(),
mCornerRadius,
mCornerRadius, mDrawPaint);
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java
index c3e0906..3ee50ac 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java
@@ -18,6 +18,9 @@
import android.animation.ValueAnimator;
import android.graphics.RectF;
+import android.util.IntProperty;
+import android.util.Property;
+import android.view.View;
import android.view.ViewPropertyAnimator;
import android.view.animation.Interpolator;
@@ -25,26 +28,70 @@
/* The transform state for a task view */
public class TaskViewTransform {
+ public static final Property<View, Integer> LEFT =
+ new IntProperty<View>("left") {
+ @Override
+ public void setValue(View object, int v) {
+ object.setLeft(v);
+ }
+
+ @Override
+ public Integer get(View object) {
+ return object.getLeft();
+ }
+ };
+
+ public static final Property<View, Integer> TOP =
+ new IntProperty<View>("top") {
+ @Override
+ public void setValue(View object, int v) {
+ object.setTop(v);
+ }
+
+ @Override
+ public Integer get(View object) {
+ return object.getTop();
+ }
+ };
+
+ public static final Property<View, Integer> RIGHT =
+ new IntProperty<View>("right") {
+ @Override
+ public void setValue(View object, int v) {
+ object.setRight(v);
+ }
+
+ @Override
+ public Integer get(View object) {
+ return object.getRight();
+ }
+ };
+
+ public static final Property<View, Integer> BOTTOM =
+ new IntProperty<View>("bottom") {
+ @Override
+ public void setValue(View object, int v) {
+ object.setBottom(v);
+ }
+
+ @Override
+ public Integer get(View object) {
+ return object.getBottom();
+ }
+ };
+
// TODO: Move this out of the transform
public int startDelay = 0;
- public int translationX = 0;
- public int translationY = 0;
public float translationZ = 0;
public float scale = 1f;
public float alpha = 1f;
-
- // Clip and thumbnail scale are untransformed layout-space properties
- // The bottom clip is only used for freeform workspace tasks
- public int clipBottom = 0;
- public int clipRight = 0;
public float thumbnailScale = 1f;
public boolean visible = false;
float p = 0f;
- // This is a window-space rect that is purely used for coordinating the animation of an app
- // window into Recents.
+ // This is a window-space rect used for positioning the task in the stack and freeform workspace
public RectF rect = new RectF();
public TaskViewTransform() {
@@ -56,13 +103,9 @@
*/
public void reset() {
startDelay = 0;
- translationX = 0;
- translationY = 0;
translationZ = 0;
scale = 1f;
alpha = 1f;
- clipBottom = 0;
- clipRight = 0;
thumbnailScale = 1f;
visible = false;
rect.setEmpty();
@@ -76,12 +119,6 @@
public boolean hasScaleChangedFrom(float v) {
return (Float.compare(scale, v) != 0);
}
- public boolean hasTranslationXChangedFrom(float v) {
- return (Float.compare(translationX, v) != 0);
- }
- public boolean hasTranslationYChangedFrom(float v) {
- return (Float.compare(translationY, v) != 0);
- }
public boolean hasTranslationZChangedFrom(float v) {
return (Float.compare(translationZ, v) != 0);
}
@@ -95,12 +132,6 @@
boolean requiresLayers = false;
// Animate to the final state
- if (hasTranslationXChangedFrom(v.getTranslationX())) {
- anim.translationX(translationX);
- }
- if (hasTranslationYChangedFrom(v.getTranslationY())) {
- anim.translationY(translationY);
- }
if (allowShadows && hasTranslationZChangedFrom(v.getTranslationZ())) {
anim.translationZ(translationZ);
}
@@ -129,12 +160,6 @@
.start();
} else {
// Set the changed properties
- if (hasTranslationXChangedFrom(v.getTranslationX())) {
- v.setTranslationX(translationX);
- }
- if (hasTranslationYChangedFrom(v.getTranslationY())) {
- v.setTranslationY(translationY);
- }
if (allowShadows && hasTranslationZChangedFrom(v.getTranslationZ())) {
v.setTranslationZ(translationZ);
}
@@ -150,7 +175,8 @@
/** Reset the transform on a view. */
public static void reset(TaskView v) {
- // Cancel any running animations
+ // Cancel any running animations and reset the translation in case something else (like a
+ // dismiss animation) changes it
v.animate().cancel();
v.setTranslationX(0f);
v.setTranslationY(0f);
@@ -158,16 +184,15 @@
v.setScaleX(1f);
v.setScaleY(1f);
v.setAlpha(1f);
- v.getViewBounds().setClipRight(0, false /* forceUpdate */);
v.getViewBounds().setClipBottom(0, false /* forceUpdate */);
+ v.setLeftTopRightBottom(0, 0, 0, 0);
v.mThumbnailView.setBitmapScale(1f);
}
@Override
public String toString() {
- return "TaskViewTransform delay: " + startDelay +
- " x: " + translationX + " y: " + translationY + " z: " + translationZ +
- " scale: " + scale + " alpha: " + alpha + " visible: " + visible + " rect: " + rect +
- " p: " + p;
+ return "TaskViewTransform delay: " + startDelay + " z: " + translationZ +
+ " scale: " + scale + " alpha: " + alpha + " visible: " + visible +
+ " rect: " + rect + " p: " + p;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index a781585..cc6a29a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -1602,7 +1602,7 @@
private void applyRemoteInput(final Entry entry) {
if (!ENABLE_REMOTE_INPUT) return;
- RemoteInput remoteInput = null;
+ boolean hasRemoteInput = false;
Notification.Action[] actions = entry.notification.getNotification().actions;
if (actions != null) {
@@ -1610,7 +1610,7 @@
if (a.getRemoteInputs() != null) {
for (RemoteInput ri : a.getRemoteInputs()) {
if (ri.getAllowFreeFormInput()) {
- remoteInput = ri;
+ hasRemoteInput = true;
break;
}
}
@@ -1618,34 +1618,50 @@
}
}
- // See if we have somewhere to put that remote input
- if (remoteInput != null) {
- View bigContentView = entry.getExpandedContentView();
- if (bigContentView != null) {
- inflateRemoteInput(bigContentView, entry);
- }
- View headsUpContentView = entry.getHeadsUpContentView();
- if (headsUpContentView != null) {
- inflateRemoteInput(headsUpContentView, entry);
- }
+ View bigContentView = entry.getExpandedContentView();
+ if (bigContentView != null) {
+ applyRemoteInput(bigContentView, entry, hasRemoteInput);
+ }
+ View headsUpContentView = entry.getHeadsUpContentView();
+ if (headsUpContentView != null) {
+ applyRemoteInput(headsUpContentView, entry, hasRemoteInput);
}
}
- private RemoteInputView inflateRemoteInput(View view, Entry entry) {
+ private RemoteInputView applyRemoteInput(View view, Entry entry, boolean hasRemoteInput) {
View actionContainerCandidate = view.findViewById(
com.android.internal.R.id.actions_container);
if (actionContainerCandidate instanceof FrameLayout) {
- ViewGroup actionContainer = (FrameLayout) actionContainerCandidate;
- RemoteInputView riv = inflateRemoteInputView(actionContainer, entry);
- if (riv != null) {
- riv.setVisibility(View.INVISIBLE);
- actionContainer.addView(riv, new FrameLayout.LayoutParams(
- ViewGroup.LayoutParams.MATCH_PARENT,
- ViewGroup.LayoutParams.MATCH_PARENT)
- );
- riv.setBackgroundColor(entry.notification.getNotification().color);
- return riv;
+ RemoteInputView existing = (RemoteInputView)
+ view.findViewWithTag(RemoteInputView.VIEW_TAG);
+
+ if (hasRemoteInput) {
+ if (existing != null) {
+ existing.onNotificationUpdate();
+ return existing;
+ }
+
+ ViewGroup actionContainer = (FrameLayout) actionContainerCandidate;
+ RemoteInputView riv = inflateRemoteInputView(actionContainer, entry);
+ if (riv != null) {
+ riv.setVisibility(View.INVISIBLE);
+ actionContainer.addView(riv, new FrameLayout.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT)
+ );
+ int color = entry.notification.getNotification().color;
+ if (color == Notification.COLOR_DEFAULT) {
+ color = mContext.getColor(R.color.default_remote_input_background);
+ }
+ riv.setBackgroundColor(color);
+ return riv;
+ }
+ } else {
+ if (existing != null) {
+ existing.onNotificationUpdate();
+ return null;
+ }
}
}
return null;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
index 22c0cb9..65053f3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
@@ -28,6 +28,8 @@
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
+import android.text.Editable;
+import android.text.TextWatcher;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
@@ -49,7 +51,7 @@
/**
* Host for the remote input.
*/
-public class RemoteInputView extends LinearLayout implements View.OnClickListener {
+public class RemoteInputView extends LinearLayout implements View.OnClickListener, TextWatcher {
private static final String TAG = "RemoteInput";
@@ -101,6 +103,7 @@
}
});
mEditText.setOnClickListener(this);
+ mEditText.addTextChangedListener(this);
mEditText.setInnerFocusable(false);
mEditText.mDefocusListener = this;
}
@@ -115,6 +118,8 @@
mEditText.setEnabled(false);
mSendButton.setVisibility(INVISIBLE);
mProgressBar.setVisibility(VISIBLE);
+ mController.removeRemoteInput(mEntry);
+ mEditText.mShowImeOnInputConnection = false;
try {
mPendingIntent.send(mContext, 0, fillInIntent);
@@ -175,6 +180,40 @@
mEditText.setText(mEntry.remoteInputText);
mEditText.setSelection(mEditText.getText().length());
mEditText.requestFocus();
+ updateSendButton();
+ }
+
+ public void onNotificationUpdate() {
+ boolean sending = mProgressBar.getVisibility() == VISIBLE;
+
+ if (sending) {
+ // Update came in after we sent the reply, time to reset.
+ reset();
+ }
+ }
+
+ private void reset() {
+ mEditText.getText().clear();
+ mEditText.setEnabled(true);
+ mSendButton.setVisibility(VISIBLE);
+ mProgressBar.setVisibility(INVISIBLE);
+ updateSendButton();
+ onDefocus();
+ }
+
+ private void updateSendButton() {
+ mSendButton.setEnabled(mEditText.getText().length() != 0);
+ }
+
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {}
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ updateSendButton();
}
/**
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index 0282a72..ef79cfe 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -3027,7 +3027,7 @@
final List<ImeSubtypeListItem> imList =
mSwitchingController.getSortedInputMethodAndSubtypeListLocked(
- true /* showSubtypes */, showAuxSubtypes, isScreenLocked);
+ showAuxSubtypes, isScreenLocked);
if (lastInputMethodSubtypeId == NOT_A_SUBTYPE_ID) {
final InputMethodSubtype currentSubtype = getCurrentInputMethodSubtypeLocked();
diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java
index 4d7df9c..309bec8 100644
--- a/services/core/java/com/android/server/job/JobSchedulerService.java
+++ b/services/core/java/com/android/server/job/JobSchedulerService.java
@@ -88,6 +88,7 @@
static final int MSG_JOB_EXPIRED = 0;
static final int MSG_CHECK_JOB = 1;
static final int MSG_STOP_JOB = 2;
+ static final int MSG_CHECK_JOB_GREEDY = 3;
// Policy constants
/**
@@ -362,7 +363,8 @@
}
void reportActive() {
- boolean active = false;
+ // active is true if pending queue contains jobs OR some job is running.
+ boolean active = mPendingJobs.size() > 0;
if (mPendingJobs.size() <= 0) {
for (int i=0; i<mActiveServices.size(); i++) {
JobServiceContext jsc = mActiveServices.get(i);
@@ -372,9 +374,10 @@
}
}
}
- if (mLocalDeviceIdleController != null) {
- if (mReportedActive != active) {
- mReportedActive = active;
+
+ if (mReportedActive != active) {
+ mReportedActive = active;
+ if (mLocalDeviceIdleController != null) {
mLocalDeviceIdleController.setJobsActive(active);
}
}
@@ -628,7 +631,8 @@
JobStatus rescheduledPeriodic = getRescheduleJobForPeriodic(jobStatus);
startTrackingJob(rescheduledPeriodic);
}
- mHandler.obtainMessage(MSG_CHECK_JOB).sendToTarget();
+ reportActive();
+ mHandler.obtainMessage(MSG_CHECK_JOB_GREEDY).sendToTarget();
}
// StateChangedListener implementations.
@@ -676,8 +680,18 @@
break;
case MSG_CHECK_JOB:
synchronized (mJobs) {
- // Check the list of jobs and run some of them if we feel inclined.
- maybeQueueReadyJobsForExecutionLockedH();
+ if (mReportedActive) {
+ // if jobs are currently being run, queue all ready jobs for execution.
+ queueReadyJobsForExecutionLockedH();
+ } else {
+ // Check the list of jobs and run some of them if we feel inclined.
+ maybeQueueReadyJobsForExecutionLockedH();
+ }
+ }
+ break;
+ case MSG_CHECK_JOB_GREEDY:
+ synchronized (mJobs) {
+ queueReadyJobsForExecutionLockedH();
}
break;
case MSG_STOP_JOB:
@@ -709,7 +723,6 @@
stopJobOnServiceContextLocked(job);
}
}
- reportActive();
if (DEBUG) {
final int queuedJobs = mPendingJobs.size();
if (queuedJobs == 0) {
@@ -786,7 +799,6 @@
Slog.d(TAG, "maybeQueueReadyJobsForExecutionLockedH: Not running anything.");
}
}
- reportActive();
if (DEBUG) {
Slog.d(TAG, "idle=" + idleCount + " connectivity=" +
connectivityCount + " charging=" + chargingCount + " tot=" +
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java
index 26f9000..d797eec 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderDrawable.java
@@ -42,10 +42,6 @@
import java.util.Collections;
import java.util.List;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
/**
* Action to render a given Drawable provided through {@link DrawableParams#getDrawable()}.
*
@@ -72,8 +68,12 @@
BridgeContext context = getContext();
drawableResource = context.getRenderResources().resolveResValue(drawableResource);
- if (drawableResource == null ||
- drawableResource.getResourceType() != ResourceType.DRAWABLE) {
+ if (drawableResource == null) {
+ return Status.ERROR_NOT_A_DRAWABLE.createResult();
+ }
+
+ ResourceType resourceType = drawableResource.getResourceType();
+ if (resourceType != ResourceType.DRAWABLE && resourceType != ResourceType.MIPMAP) {
return Status.ERROR_NOT_A_DRAWABLE.createResult();
}