Snap for 7263361 from 4f7d8fc3fb to sc-release
Change-Id: I65e01da8d73c3e9b8f13f67f56fa18ac5f4128ff
This commit is contained in:
@@ -21,5 +21,5 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/recents_clear_all"
|
||||
android:textColor="?attr/workspaceTextColor"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textSize="14sp" />
|
||||
@@ -19,8 +19,7 @@
|
||||
android:id="@+id/split_placeholder"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/split_placeholder_size"
|
||||
android:background="@android:color/white"
|
||||
android:alpha=".8"
|
||||
android:background="@android:color/darker_gray"
|
||||
android:visibility="gone" />
|
||||
|
||||
<com.android.quickstep.views.LauncherRecentsView
|
||||
@@ -30,7 +29,6 @@
|
||||
android:accessibilityPaneTitle="@string/accessibility_recent_apps"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:theme="@style/HomeScreenElementTheme"
|
||||
android:visibility="invisible" />
|
||||
|
||||
<include
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
<string name="all_apps_prediction_tip">Your predicted apps</string>
|
||||
|
||||
<!-- Content description for a close button. [CHAR LIMIT=NONE] -->
|
||||
<string name="gesture_tutorial_close_button_content_description" translatable="false">Close</string>
|
||||
<string name="gesture_tutorial_close_button_content_description" translatable="false">Close</string>
|
||||
|
||||
<!-- Hotseat educational strings for users who don't qualify for migration -->
|
||||
<string name="hotseat_edu_title_migrate">Get app suggestions on the bottom row of your Home screen</string>
|
||||
@@ -91,14 +91,6 @@
|
||||
<!-- content description for hotseat items -->
|
||||
<string name="hotseat_prediction_content_description">Predicted app: <xliff:g id="title" example="Chrome">%1$s</xliff:g></string>
|
||||
|
||||
<!-- primary educational text shown for first time search users -->
|
||||
<string name="search_edu_primary">Search your phone for apps, people, settings and more!</string>
|
||||
<!-- secondary educational text shown for first time search users -->
|
||||
<string name="search_edu_secondary">Tap keyboard search button to launch the first search
|
||||
result.</string>
|
||||
|
||||
<!-- Dismiss button string for search education view -->
|
||||
<string name="search_edu_dismiss">Got it.</string>
|
||||
<!-- Feedback shown during interactive parts of Back gesture tutorial for left edge when the gesture is too far from the edge. [CHAR LIMIT=100] -->
|
||||
<string name="back_gesture_feedback_swipe_too_far_from_left_edge">Make sure you swipe from the far-left edge.</string>
|
||||
<!-- Feedback shown during interactive parts of Back gesture tutorial for left edge when the gesture is cancelled. [CHAR LIMIT=100] -->
|
||||
|
||||
@@ -92,6 +92,7 @@ public abstract class BaseQuickstepLauncher extends Launcher
|
||||
private final TaskbarStateHandler mTaskbarStateHandler = new TaskbarStateHandler(this);
|
||||
// Will be updated when dragging from taskbar.
|
||||
private @Nullable DragOptions mNextWorkspaceDragOptions = null;
|
||||
private SplitPlaceholderView mSplitPlaceholderView;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
@@ -215,12 +216,12 @@ public abstract class BaseQuickstepLauncher extends Launcher
|
||||
|
||||
SysUINavigationMode.INSTANCE.get(this).updateMode();
|
||||
mActionsView = findViewById(R.id.overview_actions_view);
|
||||
SplitPlaceholderView splitPlaceholderView = findViewById(R.id.split_placeholder);
|
||||
mSplitPlaceholderView = findViewById(R.id.split_placeholder);
|
||||
RecentsView overviewPanel = (RecentsView) getOverviewPanel();
|
||||
splitPlaceholderView.init(
|
||||
mSplitPlaceholderView.init(
|
||||
new SplitSelectStateController(SystemUiProxy.INSTANCE.get(this))
|
||||
);
|
||||
overviewPanel.init(mActionsView, splitPlaceholderView);
|
||||
overviewPanel.init(mActionsView, mSplitPlaceholderView);
|
||||
mActionsView.updateVerticalMargin(SysUINavigationMode.getMode(this));
|
||||
|
||||
mAppTransitionManager = new QuickstepTransitionManager(this);
|
||||
@@ -256,6 +257,10 @@ public abstract class BaseQuickstepLauncher extends Launcher
|
||||
return (T) mActionsView;
|
||||
}
|
||||
|
||||
public SplitPlaceholderView getSplitPlaceholderView() {
|
||||
return mSplitPlaceholderView;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void closeOpenViews(boolean animate) {
|
||||
super.closeOpenViews(animate);
|
||||
|
||||
@@ -237,7 +237,9 @@ public class PredictionRowView extends LinearLayout implements
|
||||
setTranslationY(scroll);
|
||||
}
|
||||
setAlpha(mScrolledOut ? 0 : 1);
|
||||
AlphaUpdateListener.updateVisibility(this);
|
||||
if (getVisibility() != GONE) {
|
||||
AlphaUpdateListener.updateVisibility(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -27,7 +27,6 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.anim.AlphaUpdateListener;
|
||||
import com.android.launcher3.util.TouchController;
|
||||
import com.android.launcher3.views.BaseDragLayer;
|
||||
import com.android.systemui.shared.system.ViewTreeObserverWrapper;
|
||||
@@ -83,18 +82,13 @@ public class TaskbarContainerView extends BaseDragLayer<TaskbarActivityContext>
|
||||
|
||||
private ViewTreeObserverWrapper.OnComputeInsetsListener createTaskbarInsetsComputer() {
|
||||
return insetsInfo -> {
|
||||
if (getAlpha() < AlphaUpdateListener.ALPHA_CUTOFF_THRESHOLD
|
||||
|| mTaskbarView.getVisibility() != VISIBLE || mTaskbarView.isDraggingItem()) {
|
||||
// We're invisible or dragging out of taskbar, let touches pass through us.
|
||||
if (mControllerCallbacks.isTaskbarTouchable()) {
|
||||
// Accept touches anywhere in our bounds.
|
||||
insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_FRAME);
|
||||
} else {
|
||||
// Let touches pass through us.
|
||||
insetsInfo.touchableRegion.setEmpty();
|
||||
insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION);
|
||||
// TODO(b/182234653): Shouldn't need to do this, but for the meantime, reporting
|
||||
// that visibleInsets is empty allows DragEvents through. Setting them as completely
|
||||
// empty reverts to default behavior, so set 1 px instead.
|
||||
insetsInfo.visibleInsets.set(0, 0, 0, 1);
|
||||
} else {
|
||||
// We're visible again, accept touches anywhere in our bounds.
|
||||
insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_FRAME);
|
||||
}
|
||||
|
||||
// TaskbarContainerView provides insets to other apps based on contentInsets. These
|
||||
|
||||
@@ -42,6 +42,7 @@ import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.QuickstepTransitionManager;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.anim.AlphaUpdateListener;
|
||||
import com.android.launcher3.anim.PendingAnimation;
|
||||
import com.android.launcher3.folder.Folder;
|
||||
import com.android.launcher3.folder.FolderIcon;
|
||||
@@ -88,7 +89,6 @@ public class TaskbarController {
|
||||
|
||||
private @Nullable Animator mAnimator;
|
||||
private boolean mIsAnimatingToLauncher;
|
||||
private boolean mIsAnimatingToApp;
|
||||
|
||||
public TaskbarController(BaseQuickstepLauncher launcher,
|
||||
TaskbarContainerView taskbarContainerView, TaskbarView taskbarViewOnHome) {
|
||||
@@ -141,6 +141,13 @@ public class TaskbarController {
|
||||
setTaskbarWindowFullscreen(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTaskbarTouchable() {
|
||||
return mTaskbarContainerView.getAlpha() > AlphaUpdateListener.ALPHA_CUTOFF_THRESHOLD
|
||||
&& mTaskbarViewInApp.getVisibility() == View.VISIBLE
|
||||
&& !mIsAnimatingToLauncher;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -250,7 +257,9 @@ public class TaskbarController {
|
||||
mHotseatController.init();
|
||||
mRecentsController.init();
|
||||
|
||||
updateWhichTaskbarViewIsVisible();
|
||||
setWhichTaskbarViewIsVisible(mLauncher.hasBeenResumed()
|
||||
? mTaskbarViewOnHome
|
||||
: mTaskbarViewInApp);
|
||||
}
|
||||
|
||||
private TaskbarStateHandlerCallbacks createTaskbarStateHandlerCallbacks() {
|
||||
@@ -284,6 +293,8 @@ public class TaskbarController {
|
||||
mTaskbarAnimationController.cleanup();
|
||||
mHotseatController.cleanup();
|
||||
mRecentsController.cleanup();
|
||||
|
||||
setWhichTaskbarViewIsVisible(null);
|
||||
}
|
||||
|
||||
private void removeFromWindowManager() {
|
||||
@@ -364,7 +375,7 @@ public class TaskbarController {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
mIsAnimatingToLauncher = false;
|
||||
updateWhichTaskbarViewIsVisible();
|
||||
setWhichTaskbarViewIsVisible(mTaskbarViewOnHome);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -377,14 +388,12 @@ public class TaskbarController {
|
||||
anim.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationStart(Animator animation) {
|
||||
mIsAnimatingToApp = true;
|
||||
mTaskbarViewInApp.updateHotseatItemsVisibility();
|
||||
updateWhichTaskbarViewIsVisible();
|
||||
setWhichTaskbarViewIsVisible(mTaskbarViewInApp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
mIsAnimatingToApp = false;
|
||||
}
|
||||
});
|
||||
return anim.buildAnim();
|
||||
@@ -487,18 +496,12 @@ public class TaskbarController {
|
||||
mTaskbarViewOnHome.getHeight() - hotseatBounds.bottom);
|
||||
}
|
||||
|
||||
private void updateWhichTaskbarViewIsVisible() {
|
||||
boolean isInApp = !mLauncher.hasBeenResumed() || mIsAnimatingToLauncher
|
||||
|| mIsAnimatingToApp;
|
||||
if (isInApp) {
|
||||
mTaskbarViewInApp.setVisibility(View.VISIBLE);
|
||||
mTaskbarViewOnHome.setVisibility(View.INVISIBLE);
|
||||
mLauncher.getHotseat().setIconsAlpha(0);
|
||||
} else {
|
||||
mTaskbarViewInApp.setVisibility(View.INVISIBLE);
|
||||
mTaskbarViewOnHome.setVisibility(View.VISIBLE);
|
||||
mLauncher.getHotseat().setIconsAlpha(1);
|
||||
}
|
||||
private void setWhichTaskbarViewIsVisible(@Nullable TaskbarView visibleTaskbar) {
|
||||
mTaskbarViewInApp.setVisibility(visibleTaskbar == mTaskbarViewInApp
|
||||
? View.VISIBLE : View.INVISIBLE);
|
||||
mTaskbarViewOnHome.setVisibility(visibleTaskbar == mTaskbarViewOnHome
|
||||
? View.VISIBLE : View.INVISIBLE);
|
||||
mLauncher.getHotseat().setIconsAlpha(visibleTaskbar != mTaskbarViewInApp ? 1f : 0f);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -549,6 +552,7 @@ public class TaskbarController {
|
||||
*/
|
||||
protected interface TaskbarContainerViewCallbacks {
|
||||
void onViewRemoved();
|
||||
boolean isTaskbarTouchable();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -116,6 +116,11 @@ public abstract class BaseRecentsViewStateController<T extends RecentsView>
|
||||
config.getInterpolator(ANIM_OVERVIEW_SCRIM_FADE, LINEAR));
|
||||
setter.setFloat(scrim, SCRIM_MULTIPLIER, 1f,
|
||||
config.getInterpolator(ANIM_OVERVIEW_SCRIM_FADE, LINEAR));
|
||||
if (toState.areElementsVisible(mLauncher, LauncherState.SPLIT_PLACHOLDER_VIEW)) {
|
||||
scrim.updateStableScrimmedView(mLauncher.getSplitPlaceholderView());
|
||||
} else {
|
||||
scrim.updateStableScrimmedView(mLauncher.getOverviewPanel());
|
||||
}
|
||||
|
||||
setter.setFloat(
|
||||
mRecentsView, getTaskModalnessProperty(),
|
||||
|
||||
@@ -113,7 +113,7 @@ public final class RecentsViewStateController extends
|
||||
ANIM_OVERVIEW_ACTIONS_FADE, LINEAR));
|
||||
|
||||
float splitPlaceholderAlpha = state.areElementsVisible(mLauncher, SPLIT_PLACHOLDER_VIEW) ?
|
||||
1 : 0;
|
||||
0.7f : 0;
|
||||
propertySetter.setFloat(mRecentsView.getSplitPlaceholder(), ALPHA_FLOAT,
|
||||
splitPlaceholderAlpha, LINEAR);
|
||||
}
|
||||
|
||||
+1
-1
@@ -111,7 +111,7 @@ public class NoButtonNavbarToOverviewTouchController extends PortraitStatesTouch
|
||||
float progressMultiplier = super.initCurrentAnimation();
|
||||
if (mToState == HINT_STATE) {
|
||||
// Track the drag across the entire height of the screen.
|
||||
progressMultiplier = -1 / getShiftRange();
|
||||
progressMultiplier = -1f / mLauncher.getDeviceProfile().heightPx;
|
||||
}
|
||||
return progressMultiplier;
|
||||
}
|
||||
|
||||
@@ -217,6 +217,8 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
|
||||
// Either RectFSpringAnim (if animating home) or ObjectAnimator (from mCurrentShift) otherwise
|
||||
private RunningWindowAnim mRunningWindowAnim;
|
||||
// Possible second animation running at the same time as mRunningWindowAnim
|
||||
private Animator mParallelRunningAnim;
|
||||
private boolean mIsMotionPaused;
|
||||
private boolean mHasMotionEverBeenPaused;
|
||||
|
||||
@@ -317,9 +319,9 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
mStateCallback.runOnceAtState(STATE_LAUNCHER_PRESENT | STATE_HANDLER_INVALIDATED,
|
||||
this::invalidateHandlerWithLauncher);
|
||||
mStateCallback.runOnceAtState(STATE_HANDLER_INVALIDATED | STATE_RESUME_LAST_TASK,
|
||||
this::notifyTransitionCancelled);
|
||||
this::resetStateForAnimationCancel);
|
||||
mStateCallback.runOnceAtState(STATE_HANDLER_INVALIDATED | STATE_FINISH_WITH_NO_END,
|
||||
this::notifyTransitionCancelled);
|
||||
this::resetStateForAnimationCancel);
|
||||
|
||||
if (!LIVE_TILE.get()) {
|
||||
mStateCallback.addChangeListener(STATE_APP_CONTROLLER_RECEIVED | STATE_LAUNCHER_PRESENT
|
||||
@@ -798,6 +800,13 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
mRunningWindowAnim.end();
|
||||
}
|
||||
}
|
||||
if (mParallelRunningAnim != null) {
|
||||
if (cancel) {
|
||||
mParallelRunningAnim.cancel();
|
||||
} else {
|
||||
mParallelRunningAnim.end();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void onSettledOnEndTarget() {
|
||||
@@ -1060,7 +1069,11 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
ActivityManagerWrapper.getInstance().registerTaskStackListener(
|
||||
mActivityRestartListener);
|
||||
|
||||
mActivityInterface.onAnimateToLauncher(mGestureState.getEndTarget(), duration);
|
||||
mParallelRunningAnim = mActivityInterface.getParallelAnimationToLauncher(
|
||||
mGestureState.getEndTarget(), duration);
|
||||
if (mParallelRunningAnim != null) {
|
||||
mParallelRunningAnim.start();
|
||||
}
|
||||
}
|
||||
|
||||
if (mGestureState.getEndTarget() == HOME) {
|
||||
@@ -1370,10 +1383,6 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
mActivity.getRootView().setOnApplyWindowInsetsListener(null);
|
||||
}
|
||||
|
||||
private void notifyTransitionCancelled() {
|
||||
mAnimationFactory.onTransitionCancelled();
|
||||
}
|
||||
|
||||
private void resetStateForAnimationCancel() {
|
||||
boolean wasVisible = mWasLauncherAlreadyVisible || mGestureStarted;
|
||||
mActivityInterface.onTransitionCancelled(wasVisible);
|
||||
|
||||
@@ -347,7 +347,9 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
|
||||
* Called when the gesture ends and the animation starts towards the given target. No-op by
|
||||
* default, but subclasses can override to add an additional animation with the same duration.
|
||||
*/
|
||||
public void onAnimateToLauncher(GestureState.GestureEndTarget endTarget, long duration) {
|
||||
public @Nullable Animator getParallelAnimationToLauncher(
|
||||
GestureState.GestureEndTarget endTarget, long duration) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -366,8 +368,6 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
|
||||
|
||||
void createActivityInterface(long transitionLength);
|
||||
|
||||
default void onTransitionCancelled() { }
|
||||
|
||||
/**
|
||||
* @param attached Whether to show RecentsView alongside the app window. If false, recents
|
||||
* will be hidden by some property we can animate, e.g. alpha.
|
||||
@@ -433,11 +433,6 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTransitionCancelled() {
|
||||
mActivity.getStateManager().goToState(mStartState, false /* animate */);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRecentsAttachedToAppWindow(boolean attached, boolean animate) {
|
||||
if (mIsAttachedToWindow == attached && animate) {
|
||||
|
||||
@@ -22,6 +22,7 @@ import static com.android.launcher3.LauncherState.QUICK_SWITCH;
|
||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SHOWING;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
import android.view.MotionEvent;
|
||||
@@ -267,13 +268,14 @@ public final class LauncherActivityInterface extends
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimateToLauncher(GestureEndTarget endTarget, long duration) {
|
||||
public @Nullable Animator getParallelAnimationToLauncher(GestureEndTarget endTarget,
|
||||
long duration) {
|
||||
TaskbarController taskbarController = getTaskbarController();
|
||||
if (taskbarController == null) {
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
LauncherState toState = stateFromGestureEndTarget(endTarget);
|
||||
taskbarController.createAnimToLauncher(toState, duration).start();
|
||||
return taskbarController.createAnimToLauncher(toState, duration);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -239,8 +239,9 @@ public class TouchInteractionService extends Service implements PluginListener<O
|
||||
@BinderThread
|
||||
public void onSystemUiStateChanged(int stateFlags) {
|
||||
MAIN_EXECUTOR.execute(() -> {
|
||||
int lastFlags = mDeviceState.getSystemUiStateFlags();
|
||||
mDeviceState.setSystemUiFlags(stateFlags);
|
||||
TouchInteractionService.this.onSystemUiFlagsChanged();
|
||||
TouchInteractionService.this.onSystemUiFlagsChanged(lastFlags);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -362,7 +363,7 @@ public class TouchInteractionService extends Service implements PluginListener<O
|
||||
mResetGestureInputConsumer = new ResetGestureInputConsumer(mTaskAnimationManager);
|
||||
mInputConsumer = InputConsumerController.getRecentsAnimationInputConsumer();
|
||||
mInputConsumer.registerInputConsumer();
|
||||
onSystemUiFlagsChanged();
|
||||
onSystemUiFlagsChanged(mDeviceState.getSystemUiStateFlags());
|
||||
onAssistantVisibilityChanged();
|
||||
|
||||
// Temporarily disable model preload
|
||||
@@ -414,7 +415,7 @@ public class TouchInteractionService extends Service implements PluginListener<O
|
||||
}
|
||||
|
||||
@UiThread
|
||||
private void onSystemUiFlagsChanged() {
|
||||
private void onSystemUiFlagsChanged(int lastSysUIFlags) {
|
||||
if (mDeviceState.isUserUnlocked()) {
|
||||
int systemUiStateFlags = mDeviceState.getSystemUiStateFlags();
|
||||
SystemUiProxy.INSTANCE.get(this).setLastSystemUiStateFlags(systemUiStateFlags);
|
||||
@@ -422,14 +423,17 @@ public class TouchInteractionService extends Service implements PluginListener<O
|
||||
mOverviewComponentObserver.getActivityInterface().onSystemUiFlagsChanged(
|
||||
systemUiStateFlags);
|
||||
|
||||
// Update the tracing state
|
||||
if ((systemUiStateFlags & SYSUI_STATE_TRACING_ENABLED) != 0) {
|
||||
Log.d(TAG, "Starting tracing.");
|
||||
ProtoTracer.INSTANCE.get(this).start();
|
||||
} else {
|
||||
Log.d(TAG, "Stopping tracing. Dumping to file="
|
||||
+ ProtoTracer.INSTANCE.get(this).getTraceFile());
|
||||
ProtoTracer.INSTANCE.get(this).stop();
|
||||
if ((lastSysUIFlags & SYSUI_STATE_TRACING_ENABLED) !=
|
||||
(systemUiStateFlags & SYSUI_STATE_TRACING_ENABLED)) {
|
||||
// Update the tracing state
|
||||
if ((systemUiStateFlags & SYSUI_STATE_TRACING_ENABLED) != 0) {
|
||||
Log.d(TAG, "Starting tracing.");
|
||||
ProtoTracer.INSTANCE.get(this).start();
|
||||
} else {
|
||||
Log.d(TAG, "Stopping tracing. Dumping to file="
|
||||
+ ProtoTracer.INSTANCE.get(this).getTraceFile());
|
||||
ProtoTracer.INSTANCE.get(this).stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,9 +19,12 @@ package com.android.quickstep.util;
|
||||
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
|
||||
import static android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION;
|
||||
|
||||
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
|
||||
import static com.android.launcher3.util.Executors.THREAD_POOL_EXECUTOR;
|
||||
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.ActivityOptions;
|
||||
import android.app.prediction.AppTarget;
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipDescription;
|
||||
@@ -37,11 +40,13 @@ import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.net.Uri;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.UiThread;
|
||||
import androidx.annotation.WorkerThread;
|
||||
import androidx.core.content.FileProvider;
|
||||
|
||||
import com.android.internal.app.ChooserActivity;
|
||||
import com.android.launcher3.BuildConfig;
|
||||
import com.android.quickstep.SystemUiProxy;
|
||||
import com.android.systemui.shared.recents.model.Task;
|
||||
@@ -125,6 +130,22 @@ public class ImageActionUtils {
|
||||
tag));
|
||||
}
|
||||
|
||||
/**
|
||||
* Launch the activity to share image with shared element transition.
|
||||
*/
|
||||
@UiThread
|
||||
public static void startShareActivity(Context context, Supplier<Bitmap> bitmapSupplier,
|
||||
Rect crop, Intent intent, String tag, View sharedElement) {
|
||||
if (bitmapSupplier.get() == null) {
|
||||
Log.e(tag, "No snapshot available, not starting share.");
|
||||
return;
|
||||
}
|
||||
|
||||
UI_HELPER_EXECUTOR.execute(() -> persistBitmapAndStartActivity(context,
|
||||
bitmapSupplier.get(), crop, intent, ImageActionUtils::getShareIntentForImageUri,
|
||||
tag, sharedElement));
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts activity based on given intent created from image uri.
|
||||
*/
|
||||
@@ -141,6 +162,30 @@ public class ImageActionUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts activity based on given intent created from image uri with shared element transition.
|
||||
*/
|
||||
@WorkerThread
|
||||
public static void persistBitmapAndStartActivity(Context context, Bitmap bitmap, Rect crop,
|
||||
Intent intent, BiFunction<Uri, Intent, Intent[]> uriToIntentMap, String tag,
|
||||
View scaledImage) {
|
||||
Intent[] intents = uriToIntentMap.apply(getImageUri(bitmap, crop, context, tag), intent);
|
||||
|
||||
// Work around b/159412574
|
||||
if (intents.length == 1) {
|
||||
MAIN_EXECUTOR.execute(() -> context.startActivity(intents[0],
|
||||
ActivityOptions.makeSceneTransitionAnimation((Activity) context, scaledImage,
|
||||
ChooserActivity.FIRST_IMAGE_PREVIEW_TRANSITION_NAME).toBundle()));
|
||||
|
||||
} else {
|
||||
MAIN_EXECUTOR.execute(() -> context.startActivities(intents,
|
||||
ActivityOptions.makeSceneTransitionAnimation((Activity) context, scaledImage,
|
||||
ChooserActivity.FIRST_IMAGE_PREVIEW_TRANSITION_NAME).toBundle()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Converts image bitmap to Uri by temporarily saving bitmap to cache, and creating Uri pointing
|
||||
* to that location. Used to be able to share an image with another app.
|
||||
|
||||
@@ -26,6 +26,7 @@ import static com.android.quickstep.SysUINavigationMode.Mode.NO_BUTTON;
|
||||
import android.content.SharedPreferences;
|
||||
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.Workspace;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.hybridhotseat.HotseatPredictionController;
|
||||
@@ -63,7 +64,8 @@ public class QuickstepOnboardingPrefs extends OnboardingPrefs<QuickstepLauncher>
|
||||
});
|
||||
}
|
||||
|
||||
if (!hasReachedMaxCount(HOTSEAT_DISCOVERY_TIP_COUNT)) {
|
||||
if (!Utilities.IS_RUNNING_IN_TEST_HARNESS
|
||||
&& !hasReachedMaxCount(HOTSEAT_DISCOVERY_TIP_COUNT)) {
|
||||
stateManager.addStateListener(new StateListener<LauncherState>() {
|
||||
boolean mFromAllApps = false;
|
||||
|
||||
|
||||
@@ -559,6 +559,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
.getDimension(R.dimen.recents_empty_message_text_size));
|
||||
mEmptyMessagePaint.setTypeface(Typeface.create(Themes.getDefaultBodyFont(context),
|
||||
Typeface.NORMAL));
|
||||
mEmptyMessagePaint.setAntiAlias(true);
|
||||
mEmptyMessagePadding = getResources()
|
||||
.getDimensionPixelSize(R.dimen.recents_empty_message_text_padding);
|
||||
setWillNotDraw(false);
|
||||
|
||||
@@ -36,11 +36,11 @@
|
||||
launcher:a="0"
|
||||
launcher:b="16dp"/>
|
||||
<workspaceBottomPadding
|
||||
launcher:a="0.50"
|
||||
launcher:a="0.56"
|
||||
launcher:b="0"
|
||||
launcher:c="16dp"/>
|
||||
<hotseatBottomPadding
|
||||
launcher:a="0.50"
|
||||
launcher:a="0.44"
|
||||
launcher:b="0"
|
||||
launcher:c="16dp"/>
|
||||
</device-padding>
|
||||
|
||||
@@ -60,6 +60,10 @@ import android.animation.AnimatorSet;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.appwidget.AppWidgetHostView;
|
||||
import android.appwidget.AppWidgetManager;
|
||||
import android.content.ActivityNotFoundException;
|
||||
@@ -373,6 +377,44 @@ public class Launcher extends StatefulActivity<LauncherState> implements Launche
|
||||
.build());
|
||||
}
|
||||
|
||||
if (Utilities.IS_DEBUG_DEVICE && FeatureFlags.NOTIFY_CRASHES.get()) {
|
||||
final String notificationChannelId = "com.android.launcher3.Debug";
|
||||
final String notificationChannelName = "Debug";
|
||||
final String notificationTag = "Debug";
|
||||
final int notificationId = 0;
|
||||
|
||||
NotificationManager notificationManager = getSystemService(NotificationManager.class);
|
||||
notificationManager.createNotificationChannel(new NotificationChannel(
|
||||
notificationChannelId, notificationChannelName,
|
||||
NotificationManager.IMPORTANCE_HIGH));
|
||||
|
||||
Thread.currentThread().setUncaughtExceptionHandler((thread, throwable) -> {
|
||||
String stackTrace = Log.getStackTraceString(throwable);
|
||||
|
||||
Intent shareIntent = new Intent(Intent.ACTION_SEND);
|
||||
shareIntent.setType("text/plain");
|
||||
shareIntent.putExtra(Intent.EXTRA_TEXT, stackTrace);
|
||||
shareIntent = Intent.createChooser(shareIntent, null);
|
||||
PendingIntent sharePendingIntent = PendingIntent.getActivity(
|
||||
this, 0, shareIntent, PendingIntent.FLAG_UPDATE_CURRENT
|
||||
);
|
||||
|
||||
Notification notification = new Notification.Builder(this, notificationChannelId)
|
||||
.setSmallIcon(android.R.drawable.ic_menu_close_clear_cancel)
|
||||
.setContentTitle("Launcher crash detected!")
|
||||
.setStyle(new Notification.BigTextStyle().bigText(stackTrace))
|
||||
.addAction(android.R.drawable.ic_menu_share, "Share", sharePendingIntent)
|
||||
.build();
|
||||
notificationManager.notify(notificationTag, notificationId, notification);
|
||||
|
||||
Thread.UncaughtExceptionHandler defaultUncaughtExceptionHandler =
|
||||
Thread.getDefaultUncaughtExceptionHandler();
|
||||
if (defaultUncaughtExceptionHandler != null) {
|
||||
defaultUncaughtExceptionHandler.uncaughtException(thread, throwable);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
LauncherAppState app = LauncherAppState.getInstance(this);
|
||||
|
||||
@@ -95,6 +95,10 @@ public final class FeatureFlags {
|
||||
public static final BooleanFlag ENABLE_DEVICE_SEARCH = new DeviceFlag(
|
||||
"ENABLE_DEVICE_SEARCH", true, "Allows on device search in all apps");
|
||||
|
||||
public static final BooleanFlag ENABLE_PEOPLE_TILE_PREVIEW = getDebugFlag(
|
||||
"ENABLE_PEOPLE_TILE_PREVIEW", false,
|
||||
"Experimental: Shows conversation shortcuts on home screen as search results");
|
||||
|
||||
public static final BooleanFlag FOLDER_NAME_SUGGEST = new DeviceFlag(
|
||||
"FOLDER_NAME_SUGGEST", true,
|
||||
"Suggests folder names instead of blank text.");
|
||||
@@ -218,6 +222,9 @@ public final class FeatureFlags {
|
||||
public static final BooleanFlag ENABLE_ENFORCED_ROUNDED_CORNERS = new DeviceFlag(
|
||||
"ENABLE_ENFORCED_ROUNDED_CORNERS", true, "Enforce rounded corners on all App Widgets");
|
||||
|
||||
public static final BooleanFlag NOTIFY_CRASHES = getDebugFlag("NOTIFY_CRASHES", false,
|
||||
"Sends a notification whenever launcher encounters an uncaught exception.");
|
||||
|
||||
public static void initialize(Context context) {
|
||||
synchronized (sDebugFlags) {
|
||||
for (DebugFlag flag : sDebugFlags) {
|
||||
|
||||
@@ -66,6 +66,13 @@ public class OverviewScrim extends Scrim {
|
||||
mStableScrimmedView = mCurrentScrimmedView = mLauncher.getOverviewPanel();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param view The view we want the scrim to be behind
|
||||
*/
|
||||
public void updateStableScrimmedView(View view) {
|
||||
mStableScrimmedView = view;
|
||||
}
|
||||
|
||||
public void updateCurrentScrimmedView(ViewGroup root) {
|
||||
// Find the lowest view that is at or above the view we want to show the scrim behind.
|
||||
mCurrentScrimmedView = mStableScrimmedView;
|
||||
|
||||
@@ -24,7 +24,6 @@ import static com.android.launcher3.touch.SingleAxisSwipeDetector.HORIZONTAL;
|
||||
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT;
|
||||
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT;
|
||||
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_TYPE_MAIN;
|
||||
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_TYPE_SIDE;
|
||||
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.PointF;
|
||||
@@ -45,7 +44,7 @@ import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.util.OverScroller;
|
||||
import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class LandscapePagedViewHandler implements PagedOrientationHandler {
|
||||
@@ -308,15 +307,10 @@ public class LandscapePagedViewHandler implements PagedOrientationHandler {
|
||||
|
||||
@Override
|
||||
public List<SplitPositionOption> getSplitPositionOptions(DeviceProfile dp) {
|
||||
List<SplitPositionOption> options = new ArrayList<>(2);
|
||||
// Add left/right options where left => position top, right => position bottom
|
||||
options.add(new SplitPositionOption(
|
||||
// Add "left" side of phone which is actually the top
|
||||
return Collections.singletonList(new SplitPositionOption(
|
||||
R.drawable.ic_split_screen, R.string.split_screen_position_left,
|
||||
STAGE_POSITION_TOP_OR_LEFT, STAGE_TYPE_MAIN));
|
||||
options.add(new SplitPositionOption(
|
||||
R.drawable.ic_split_screen, R.string.split_screen_position_right,
|
||||
STAGE_POSITION_BOTTOM_OR_RIGHT, STAGE_TYPE_SIDE));
|
||||
return options;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -306,16 +306,17 @@ public class PortraitPagedViewHandler implements PagedOrientationHandler {
|
||||
|
||||
@Override
|
||||
public List<SplitPositionOption> getSplitPositionOptions(DeviceProfile dp) {
|
||||
List<SplitPositionOption> options = new ArrayList<>(2);
|
||||
List<SplitPositionOption> options = new ArrayList<>(1);
|
||||
// TODO: Add in correct icons
|
||||
if (dp.isLandscape) { // or seascape
|
||||
if (dp.isSeascape()) { // or seascape
|
||||
// Add left/right options
|
||||
options.add(new SplitPositionOption(
|
||||
R.drawable.ic_split_screen, R.string.split_screen_position_right,
|
||||
STAGE_POSITION_TOP_OR_LEFT, STAGE_TYPE_MAIN));
|
||||
} else if (dp.isLandscape) {
|
||||
options.add(new SplitPositionOption(
|
||||
R.drawable.ic_split_screen, R.string.split_screen_position_left,
|
||||
STAGE_POSITION_TOP_OR_LEFT, STAGE_TYPE_MAIN));
|
||||
options.add(new SplitPositionOption(
|
||||
R.drawable.ic_split_screen, R.string.split_screen_position_right,
|
||||
STAGE_POSITION_BOTTOM_OR_RIGHT, STAGE_TYPE_SIDE));
|
||||
} else {
|
||||
// Only add top option
|
||||
options.add(new SplitPositionOption(
|
||||
|
||||
@@ -20,7 +20,6 @@ import static com.android.launcher3.touch.SingleAxisSwipeDetector.HORIZONTAL;
|
||||
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT;
|
||||
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT;
|
||||
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_TYPE_MAIN;
|
||||
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_TYPE_SIDE;
|
||||
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.PointF;
|
||||
@@ -33,7 +32,7 @@ import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class SeascapePagedViewHandler extends LandscapePagedViewHandler {
|
||||
@@ -96,15 +95,10 @@ public class SeascapePagedViewHandler extends LandscapePagedViewHandler {
|
||||
|
||||
@Override
|
||||
public List<SplitPositionOption> getSplitPositionOptions(DeviceProfile dp) {
|
||||
List<SplitPositionOption> options = new ArrayList<>(2);
|
||||
// Add left/right options where left => position bottom, right => position top
|
||||
options.add(new SplitPositionOption(
|
||||
R.drawable.ic_split_screen, R.string.split_screen_position_left,
|
||||
STAGE_POSITION_BOTTOM_OR_RIGHT, STAGE_TYPE_SIDE));
|
||||
options.add(new SplitPositionOption(
|
||||
// Add "right" option which is actually the top
|
||||
return Collections.singletonList(new SplitPositionOption(
|
||||
R.drawable.ic_split_screen, R.string.split_screen_position_right,
|
||||
STAGE_POSITION_TOP_OR_LEFT, STAGE_TYPE_MAIN));
|
||||
return options;
|
||||
}
|
||||
|
||||
/* ---------- The following are only used by TaskViewTouchHandler. ---------- */
|
||||
|
||||
@@ -216,7 +216,7 @@ public abstract class AbstractSlideInView extends AbstractFloatingView
|
||||
return mLauncher.getDragLayer();
|
||||
}
|
||||
|
||||
protected static View createColorScrim(Context context, int bgColor) {
|
||||
protected View createColorScrim(Context context, int bgColor) {
|
||||
View view = new View(context);
|
||||
view.forceHasOverlappingRendering(false);
|
||||
view.setBackgroundColor(bgColor);
|
||||
|
||||
Reference in New Issue
Block a user