Merge "Updating visuals for incompatible apps." into nyc-dev

This commit is contained in:
Winson Chung
2016-04-12 01:51:04 +00:00
committed by Android (Google) Code Review
15 changed files with 207 additions and 65 deletions

View File

@@ -14,8 +14,8 @@ Copyright (C) 2014 The Android Open Source Project
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="48.0dp"
android:height="48.0dp"
android:width="24.0dp"
android:height="24.0dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path

View File

@@ -14,8 +14,8 @@ Copyright (C) 2014 The Android Open Source Project
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="48.0dp"
android:height="48.0dp"
android:width="24.0dp"
android:height="24.0dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path

View File

@@ -25,6 +25,14 @@
android:layout_height="match_parent">
</com.android.systemui.recents.views.RecentsView>
<!-- Incompatible task overlay -->
<ViewStub android:id="@+id/incompatible_app_overlay_stub"
android:inflatedId="@+id/incompatible_app_overlay"
android:layout="@layout/recents_incompatible_app_overlay"
android:layout_width="match_parent"
android:layout_height="128dp"
android:layout_gravity="center_horizontal|top" />
<!-- Nav Bar Scrim View -->
<ImageView
android:id="@+id/nav_bar_scrim"

View File

@@ -0,0 +1,30 @@
<?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:layout_width="match_parent"
android:layout_height="match_parent"
android:alpha="0"
android:background="#88000000"
android:forceHasOverlappingRendering="false">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:drawableTop="@drawable/recents_info_light"
android:drawablePadding="8dp"
android:text="@string/recents_incompatible_app_message" />
</FrameLayout>

View File

@@ -26,7 +26,9 @@
android:id="@+id/task_view_thumbnail"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<include layout="@layout/recents_task_view_header" />
<com.android.systemui.statusbar.AlphaOptimizedFrameLayout
android:id="@+id/lock_to_app_fab"
android:layout_width="@dimen/recents_lock_to_app_size"
@@ -45,6 +47,17 @@
android:layout_gravity="center"
android:src="@drawable/recents_lock_to_app_pin" />
</com.android.systemui.statusbar.AlphaOptimizedFrameLayout>
<!-- The incompatible app toast -->
<ViewStub android:id="@+id/incompatible_app_toast_stub"
android:inflatedId="@+id/incompatible_app_toast"
android:layout="@*android:layout/transient_notification"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top|center_horizontal"
android:layout_marginTop="48dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp" />
</FrameLayout>
</com.android.systemui.recents.views.TaskView>

View File

@@ -31,40 +31,19 @@
android:paddingBottom="8dp"
android:paddingStart="16dp"
android:paddingEnd="12dp" />
<LinearLayout
android:id="@+id/title_container"
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|start"
android:orientation="vertical">
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:textSize="16sp"
android:textColor="#ffffffff"
android:text="@string/recents_empty_message"
android:fontFamily="sans-serif-medium"
android:singleLine="true"
android:maxLines="1"
android:ellipsize="marquee"
android:fadingEdge="horizontal" />
<TextView
android:id="@+id/sub_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:textSize="11sp"
android:textColor="#ffffffff"
android:text="@string/recents_launch_non_dockable_task_label"
android:fontFamily="sans-serif-medium"
android:singleLine="true"
android:maxLines="1"
android:ellipsize="marquee"
android:fadingEdge="horizontal"
android:visibility="gone" />
</LinearLayout>
android:textSize="16sp"
android:textColor="#ffffffff"
android:text="@string/recents_empty_message"
android:fontFamily="sans-serif-medium"
android:singleLine="true"
android:maxLines="1"
android:ellipsize="marquee"
android:fadingEdge="horizontal" />
<com.android.systemui.recents.views.FixedSizeImageView
android:id="@+id/move_task"
android:layout_width="wrap_content"

View File

@@ -735,10 +735,8 @@
<string name="recents_launch_disabled_message"><xliff:g id="app" example="Calendar">%s</xliff:g> is disabled in safe-mode.</string>
<!-- Recents: Stack action button string. [CHAR LIMIT=NONE] -->
<string name="recents_stack_action_button_label">Clear all</string>
<!-- Recents: Non-dockable task drag message. [CHAR LIMIT=NONE] -->
<string name="recents_drag_non_dockable_task_message">This app does not support multi-window</string>
<!-- Recents: Non-dockable task launch sub header. [CHAR LIMIT=NONE] -->
<string name="recents_launch_non_dockable_task_label">App does not support multi-window</string>
<!-- Recents: Incompatible task message. [CHAR LIMIT=NONE] -->
<string name="recents_incompatible_app_message">App doesn\'t support 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>

View File

@@ -435,7 +435,7 @@ public class Recents extends SystemUI
mDraggingInRecentsCurrentUser = currentUser;
return true;
} else {
Toast.makeText(mContext, R.string.recents_drag_non_dockable_task_message,
Toast.makeText(mContext, R.string.recents_incompatible_app_message,
Toast.LENGTH_SHORT).show();
return false;
}

View File

@@ -38,6 +38,7 @@ import android.view.WindowManager.LayoutParams;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.MetricsProto.MetricsEvent;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
import com.android.systemui.recents.events.EventBus;
import com.android.systemui.recents.events.activity.CancelEnterRecentsWindowAnimationEvent;
@@ -58,8 +59,10 @@ import com.android.systemui.recents.events.component.RecentsVisibilityChangedEve
import com.android.systemui.recents.events.component.ScreenPinningRequestEvent;
import com.android.systemui.recents.events.ui.AllTaskViewsDismissedEvent;
import com.android.systemui.recents.events.ui.DeleteTaskDataEvent;
import com.android.systemui.recents.events.ui.HideIncompatibleAppOverlayEvent;
import com.android.systemui.recents.events.ui.RecentsDrawnEvent;
import com.android.systemui.recents.events.ui.ShowApplicationInfoEvent;
import com.android.systemui.recents.events.ui.ShowIncompatibleAppOverlayEvent;
import com.android.systemui.recents.events.ui.StackViewScrolledEvent;
import com.android.systemui.recents.events.ui.UpdateFreeformTaskViewVisibilityEvent;
import com.android.systemui.recents.events.ui.UserInteractionEvent;
@@ -68,12 +71,12 @@ import com.android.systemui.recents.events.ui.focus.FocusNextTaskViewEvent;
import com.android.systemui.recents.events.ui.focus.FocusPreviousTaskViewEvent;
import com.android.systemui.recents.misc.DozeTrigger;
import com.android.systemui.recents.misc.SystemServicesProxy;
import com.android.systemui.recents.misc.Utilities;
import com.android.systemui.recents.model.RecentsPackageMonitor;
import com.android.systemui.recents.model.RecentsTaskLoadPlan;
import com.android.systemui.recents.model.RecentsTaskLoader;
import com.android.systemui.recents.model.Task;
import com.android.systemui.recents.model.TaskStack;
import com.android.systemui.recents.views.AnimationProps;
import com.android.systemui.recents.views.RecentsView;
import com.android.systemui.recents.views.SystemBarScrimViews;
import com.android.systemui.statusbar.BaseStatusBar;
@@ -90,6 +93,7 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
private final static boolean DEBUG = false;
public final static int EVENT_BUS_PRIORITY = Recents.EVENT_BUS_PRIORITY + 1;
public final static int INCOMPATIBLE_APP_ALPHA_DURATION = 150;
private RecentsPackageMonitor mPackageMonitor;
private long mLastTabKeyEventTime;
@@ -101,6 +105,7 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
// Top level views
private RecentsView mRecentsView;
private SystemBarScrimViews mScrimViews;
private View mIncompatibleAppOverlay;
// Runnables to finish the Recents activity
private Intent mHomeIntent;
@@ -674,6 +679,30 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
MetricsLogger.count(this, "overview_app_info", 1);
}
public final void onBusEvent(ShowIncompatibleAppOverlayEvent event) {
if (mIncompatibleAppOverlay == null) {
mIncompatibleAppOverlay = Utilities.findViewStubById(this,
R.id.incompatible_app_overlay_stub).inflate();
mIncompatibleAppOverlay.setWillNotDraw(false);
mIncompatibleAppOverlay.setVisibility(View.VISIBLE);
}
mIncompatibleAppOverlay.animate()
.alpha(1f)
.setDuration(INCOMPATIBLE_APP_ALPHA_DURATION)
.setInterpolator(Interpolators.ALPHA_IN)
.start();
}
public final void onBusEvent(HideIncompatibleAppOverlayEvent event) {
if (mIncompatibleAppOverlay != null) {
mIncompatibleAppOverlay.animate()
.alpha(0f)
.setDuration(INCOMPATIBLE_APP_ALPHA_DURATION)
.setInterpolator(Interpolators.ALPHA_OUT)
.start();
}
}
public final void onBusEvent(DeleteTaskDataEvent event) {
// Remove any stored data from the loader
RecentsTaskLoader loader = Recents.getTaskLoader();

View File

@@ -0,0 +1,26 @@
/*
* 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.
*/
package com.android.systemui.recents.events.ui;
import com.android.systemui.recents.events.EventBus;
/**
* This is sent when a user stops draggin an incompatible app task.
*/
public class HideIncompatibleAppOverlayEvent extends EventBus.Event {
// Simple event
}

View File

@@ -0,0 +1,26 @@
/*
* 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.
*/
package com.android.systemui.recents.events.ui;
import com.android.systemui.recents.events.EventBus;
/**
* This is sent when a user starts dragging an incompatible app task.
*/
public class ShowIncompatibleAppOverlayEvent extends EventBus.Event {
// Simple event
}

View File

@@ -19,6 +19,7 @@ package com.android.systemui.recents.misc;
import android.animation.Animator;
import android.animation.AnimatorSet;
import android.annotation.FloatRange;
import android.app.Activity;
import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.Rect;
@@ -30,6 +31,7 @@ import android.util.Property;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewParent;
import android.view.ViewStub;
import com.android.systemui.recents.model.Task;
import com.android.systemui.recents.views.TaskViewTransform;
@@ -219,6 +221,20 @@ public class Utilities {
animator.removeAllListeners();
}
/**
* Returns a view stub for the given view id.
*/
public static ViewStub findViewStubById(View v, int stubId) {
return (ViewStub) v.findViewById(stubId);
}
/**
* Returns a view stub for the given view id.
*/
public static ViewStub findViewStubById(Activity a, int stubId) {
return (ViewStub) a.findViewById(stubId);
}
/**
* Updates {@param transforms} to be the same size as {@param tasks}.
*/

View File

@@ -20,19 +20,17 @@ import android.app.ActivityManager;
import android.content.res.Configuration;
import android.graphics.Point;
import android.graphics.Rect;
import android.provider.Settings;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
import android.view.ViewDebug;
import android.widget.Toast;
import com.android.internal.policy.DividerSnapAlgorithm;
import com.android.systemui.R;
import com.android.systemui.recents.Recents;
import com.android.systemui.recents.RecentsConfiguration;
import com.android.systemui.recents.RecentsImpl;
import com.android.systemui.recents.events.EventBus;
import com.android.systemui.recents.events.activity.ConfigurationChangedEvent;
import com.android.systemui.recents.events.ui.HideIncompatibleAppOverlayEvent;
import com.android.systemui.recents.events.ui.ShowIncompatibleAppOverlayEvent;
import com.android.systemui.recents.events.ui.dragndrop.DragDropTargetChangedEvent;
import com.android.systemui.recents.events.ui.dragndrop.DragEndEvent;
import com.android.systemui.recents.events.ui.dragndrop.DragStartEvent;
@@ -166,8 +164,7 @@ public class RecentsViewTouchHandler {
if (ActivityManager.supportsMultiWindow() && !ssp.hasDockedTask()
&& mDividerSnapAlgorithm.isSplitScreenFeasible()) {
if (!event.task.isDockable) {
Toast.makeText(mRv.getContext(), R.string.recents_drag_non_dockable_task_message,
Toast.LENGTH_SHORT).show();
EventBus.getDefault().send(new ShowIncompatibleAppOverlayEvent());
} else {
// Add the dock state drop targets (these take priority)
TaskStack.DockState[] dockStates = getDockStatesForCurrentOrientation();
@@ -184,6 +181,9 @@ public class RecentsViewTouchHandler {
}
public final void onBusEvent(DragEndEvent event) {
if (!mDragTask.isDockable) {
EventBus.getDefault().send(new HideIncompatibleAppOverlayEvent());
}
mDragRequested = false;
mDragTask = null;
mTaskView = null;

View File

@@ -39,6 +39,7 @@ import android.view.MotionEvent;
import android.view.View;
import android.view.ViewDebug;
import android.view.ViewOutlineProvider;
import android.widget.TextView;
import android.widget.Toast;
import com.android.internal.logging.MetricsLogger;
@@ -157,6 +158,7 @@ public class TaskView extends FixedSizeFrameLayout implements Task.TaskCallbacks
@ViewDebug.ExportedProperty(deepExport=true, prefix="header_")
TaskViewHeader mHeaderView;
View mActionButtonView;
View mIncompatibleAppToastView;
TaskViewCallbacks mCb;
@ViewDebug.ExportedProperty(category="recents")
@@ -345,6 +347,9 @@ public class TaskView extends FixedSizeFrameLayout implements Task.TaskCallbacks
mActionButtonView.setScaleY(1f);
mActionButtonView.setAlpha(0f);
mActionButtonView.setTranslationZ(mActionButtonTranslationZ);
if (mIncompatibleAppToastView != null) {
mIncompatibleAppToastView.setVisibility(View.INVISIBLE);
}
}
/**
@@ -536,6 +541,10 @@ public class TaskView extends FixedSizeFrameLayout implements Task.TaskCallbacks
// These values will be animated in when onStartLaunchTargetEnterAnimation() is called
setDimAlphaWithoutHeader(0);
mActionButtonView.setAlpha(0f);
if (mIncompatibleAppToastView != null &&
mIncompatibleAppToastView.getVisibility() == View.VISIBLE) {
mIncompatibleAppToastView.setAlpha(0f);
}
}
@Override
@@ -554,6 +563,15 @@ public class TaskView extends FixedSizeFrameLayout implements Task.TaskCallbacks
if (screenPinningEnabled) {
showActionButton(true /* fadeIn */, duration /* fadeInDuration */);
}
if (mIncompatibleAppToastView != null &&
mIncompatibleAppToastView.getVisibility() == View.VISIBLE) {
mIncompatibleAppToastView.animate()
.alpha(1f)
.setDuration(duration)
.setInterpolator(Interpolators.ALPHA_IN)
.start();
}
}
@Override
@@ -587,6 +605,18 @@ public class TaskView extends FixedSizeFrameLayout implements Task.TaskCallbacks
mTask = t;
mTask.addCallback(this);
mIsDisabledInSafeMode = !mTask.isSystemApp && ssp.isInSafeMode();
if (!t.isDockable && ssp.hasDockedTask()) {
if (mIncompatibleAppToastView == null) {
mIncompatibleAppToastView = Utilities.findViewStubById(this,
R.id.incompatible_app_toast_stub).inflate();
TextView msg = (TextView) findViewById(com.android.internal.R.id.message);
msg.setText(R.string.recents_incompatible_app_message);
}
mIncompatibleAppToastView.setVisibility(View.VISIBLE);
} else if (mIncompatibleAppToastView != null) {
mIncompatibleAppToastView.setVisibility(View.INVISIBLE);
}
}
@Override

View File

@@ -39,7 +39,6 @@ import android.view.View;
import android.view.ViewAnimationUtils;
import android.view.ViewDebug;
import android.view.ViewGroup;
import android.view.ViewStub;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ProgressBar;
@@ -141,15 +140,12 @@ public class TaskViewHeader extends FrameLayout
// Header views
ImageView mIconView;
TextView mTitleView;
TextView mSubTitleView;
ImageView mMoveTaskButton;
ImageView mDismissButton;
ViewStub mAppOverlayViewStub;
FrameLayout mAppOverlayView;
ImageView mAppIconView;
ImageView mAppInfoView;
TextView mAppTitleView;
ViewStub mFocusTimerIndicatorStub;
ProgressBar mFocusTimerIndicator;
// Header drawables
@@ -242,13 +238,10 @@ public class TaskViewHeader extends FrameLayout
mIconView.setClickable(false);
mIconView.setOnLongClickListener(this);
mTitleView = (TextView) findViewById(R.id.title);
mSubTitleView = (TextView) findViewById(R.id.sub_title);
mDismissButton = (ImageView) findViewById(R.id.dismiss_task);
if (ssp.hasFreeformWorkspaceSupport()) {
mMoveTaskButton = (ImageView) findViewById(R.id.move_task);
}
mFocusTimerIndicatorStub = (ViewStub) findViewById(R.id.focus_timer_indicator_stub);
mAppOverlayViewStub = (ViewStub) findViewById(R.id.app_overlay_stub);
onConfigurationChanged();
}
@@ -305,8 +298,7 @@ public class TaskViewHeader extends FrameLayout
R.dimen.recents_task_view_header_button_padding_tablet_land,
R.dimen.recents_task_view_header_button_padding,
R.dimen.recents_task_view_header_button_padding_tablet_land);
updateLayoutParams(mIconView, findViewById(R.id.title_container), mMoveTaskButton,
mDismissButton);
updateLayoutParams(mIconView, mTitleView, mMoveTaskButton, mDismissButton);
if (mAppOverlayView != null) {
updateLayoutParams(mAppIconView, mAppTitleView, null, mAppInfoView);
}
@@ -462,13 +454,6 @@ public class TaskViewHeader extends FrameLayout
mTitleView.setContentDescription(t.titleDescription);
mTitleView.setTextColor(t.useLightOnPrimaryColor ?
mTaskBarViewLightTextColor : mTaskBarViewDarkTextColor);
if (!t.isDockable && ssp.hasDockedTask()) {
mSubTitleView.setVisibility(View.VISIBLE);
mSubTitleView.setTextColor(t.useLightOnPrimaryColor ?
mTaskBarViewLightTextColor : mTaskBarViewDarkTextColor);
} else {
mSubTitleView.setVisibility(View.GONE);
}
mDismissButton.setImageDrawable(t.useLightOnPrimaryColor ?
mLightDismissDrawable : mDarkDismissDrawable);
mDismissButton.setContentDescription(t.dismissDescription);
@@ -491,7 +476,8 @@ public class TaskViewHeader extends FrameLayout
if (Recents.getDebugFlags().isFastToggleRecentsEnabled()) {
if (mFocusTimerIndicator == null) {
mFocusTimerIndicator = (ProgressBar) mFocusTimerIndicatorStub.inflate();
mFocusTimerIndicator = (ProgressBar) Utilities.findViewStubById(this,
R.id.focus_timer_indicator_stub).inflate();
}
mFocusTimerIndicator.getProgressDrawable()
.setColorFilter(
@@ -637,7 +623,8 @@ public class TaskViewHeader extends FrameLayout
// Inflate the overlay if necessary
if (mAppOverlayView == null) {
mAppOverlayView = (FrameLayout) mAppOverlayViewStub.inflate();
mAppOverlayView = (FrameLayout) Utilities.findViewStubById(this,
R.id.app_overlay_stub).inflate();
mAppOverlayView.setBackground(mOverlayBackground);
mAppIconView = (ImageView) mAppOverlayView.findViewById(R.id.app_icon);
mAppIconView.setOnClickListener(this);