Merge "Update animations for TM-QPR: Overview > OverviewSplitSelect transition" into tm-qpr-dev
diff --git a/go/quickstep/res/values-or/strings.xml b/go/quickstep/res/values-or/strings.xml
index 36de437..6a3c5dc 100644
--- a/go/quickstep/res/values-or/strings.xml
+++ b/go/quickstep/res/values-or/strings.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_share_drop_target_label" msgid="5804774105974539508">"ଆପ୍ ସେୟାର୍ କରନ୍ତୁ"</string>
+ <string name="app_share_drop_target_label" msgid="5804774105974539508">"ଆପ ସେୟାର କରନ୍ତୁ"</string>
<string name="action_listen" msgid="2370304050784689486">"ଶୁଣନ୍ତୁ"</string>
<string name="action_translate" msgid="8028378961867277746">"ଅନୁବାଦ କରନ୍ତୁ"</string>
<string name="action_search" msgid="6269564710943755464">"Lens"</string>
diff --git a/proguard.flags b/proguard.flags
index a450183..53a68de 100644
--- a/proguard.flags
+++ b/proguard.flags
@@ -2,10 +2,6 @@
*;
}
--keep class com.android.launcher3.graphics.ShadowDrawable {
- public <init>(...);
-}
-
# The support library contains references to newer platform versions.
# Don't warn about those in case this app is linking against an older
# platform version. We know about them, and they are safe.
diff --git a/quickstep/res/values-land/dimens.xml b/quickstep/res/values-land/dimens.xml
index 8368069..905fbda 100644
--- a/quickstep/res/values-land/dimens.xml
+++ b/quickstep/res/values-land/dimens.xml
@@ -77,7 +77,7 @@
<!-- Taskbar 3 button spacing -->
<dimen name="taskbar_button_margin_5_5">94.5dp</dimen>
- <dimen name="taskbar_button_margin_6_5">94.5dp</dimen>
+ <dimen name="taskbar_button_margin_6_5">219.6dp</dimen>
<dimen name="taskbar_button_margin_4_5">84dp</dimen>
<dimen name="taskbar_button_margin_4_4">79dp</dimen>
</resources>
\ No newline at end of file
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index cfe602e..c85e71c 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -277,8 +277,9 @@
<!-- Taskbar 3 button spacing -->
<dimen name="taskbar_button_space_inbetween">24dp</dimen>
+ <dimen name="taskbar_button_space_inbetween_phone">40dp</dimen>
<dimen name="taskbar_button_margin_5_5">26dp</dimen>
- <dimen name="taskbar_button_margin_6_5">26dp</dimen>
+ <dimen name="taskbar_button_margin_6_5">75dp</dimen>
<dimen name="taskbar_button_margin_4_5">47dp</dimen>
<dimen name="taskbar_button_margin_4_4">47dp</dimen>
<dimen name="taskbar_button_margin_default">47dp</dimen>
diff --git a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
index e21dcba..c2e8658 100644
--- a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
@@ -110,7 +110,7 @@
*/
public abstract class BaseQuickstepLauncher extends Launcher {
- private DepthController mDepthController = new DepthController(this);
+ private DepthController mDepthController;
private QuickstepTransitionManager mAppTransitionManager;
/**
@@ -247,7 +247,6 @@
@Override
public void onScrollChanged(float progress) {
super.onScrollChanged(progress);
- mDepthController.onOverlayScrollChanged(progress);
onTaskbarInAppDisplayProgressUpdate(progress, MINUS_ONE_PAGE_PROGRESS_INDEX);
}
@@ -345,6 +344,7 @@
mAppTransitionManager.registerRemoteTransitions();
mTISBindHelper = new TISBindHelper(this, this::onTISConnected);
+ mDepthController = new DepthController(this);
}
private void onTISConnected(TISBinder binder) {
diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
index c089d1b..d348cc3 100644
--- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
+++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
@@ -78,6 +78,7 @@
import android.provider.Settings;
import android.util.Pair;
import android.util.Size;
+import android.view.CrossWindowBlurListeners;
import android.view.SurfaceControl;
import android.view.View;
import android.view.ViewRootImpl;
@@ -93,6 +94,7 @@
import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
import com.android.launcher3.LauncherAnimationRunner.RemoteAnimationFactory;
import com.android.launcher3.anim.AnimationSuccessListener;
+import com.android.launcher3.anim.AnimatorListeners;
import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.icons.FastBitmapDrawable;
import com.android.launcher3.shortcuts.DeepShortcutView;
@@ -143,8 +145,6 @@
*/
public class QuickstepTransitionManager implements OnDeviceProfileChangeListener {
- private static final String TAG = "QuickstepTransition";
-
private static final boolean ENABLE_SHELL_STARTING_SURFACE =
SystemProperties.getBoolean("persist.debug.shell_starting_surface", true);
@@ -517,6 +517,7 @@
appsView.setAlpha(startAlpha);
SCALE_PROPERTY.set(appsView, startScale);
appsView.setLayerType(View.LAYER_TYPE_NONE, null);
+ mLauncher.resumeExpensiveViewUpdates();
};
} else if (mLauncher.isInState(OVERVIEW)) {
endListener = composeViewContentAnimator(launcherAnimator, alphas, scales);
@@ -634,6 +635,7 @@
overview.setFreezeViewVisibility(false);
SCALE_PROPERTY.set(overview, 1f);
mLauncher.getStateManager().reapplyState();
+ mLauncher.resumeExpensiveViewUpdates();
};
}
@@ -1044,54 +1046,37 @@
private ObjectAnimator getBackgroundAnimator() {
// When launching an app from overview that doesn't map to a task, we still want to just
// blur the wallpaper instead of the launcher surface as well
- boolean allowBlurringLauncher = mLauncher.getStateManager().getState() != OVERVIEW;
- DepthController depthController = mLauncher.getDepthController();
+ boolean allowBlurringLauncher = mLauncher.getStateManager().getState() != OVERVIEW
+ && BlurUtils.supportsBlursOnWindows();
+
+ MyDepthController depthController = new MyDepthController(mLauncher);
ObjectAnimator backgroundRadiusAnim = ObjectAnimator.ofFloat(depthController, DEPTH,
- BACKGROUND_APP.getDepth(mLauncher))
+ BACKGROUND_APP.getDepth(mLauncher))
.setDuration(APP_LAUNCH_DURATION);
+
if (allowBlurringLauncher) {
- final SurfaceControl dimLayer;
- if (BlurUtils.supportsBlursOnWindows()) {
- // Create a temporary effect layer, that lives on top of launcher, so we can apply
- // the blur to it. The EffectLayer will be fullscreen, which will help with caching
- // optimizations on the SurfaceFlinger side:
- // - Results would be able to be cached as a texture
- // - There won't be texture allocation overhead, because EffectLayers don't have
- // buffers
- ViewRootImpl viewRootImpl = mLauncher.getDragLayer().getViewRootImpl();
- SurfaceControl parent = viewRootImpl != null
- ? viewRootImpl.getSurfaceControl()
- : null;
- dimLayer = new SurfaceControl.Builder()
- .setName("Blur layer")
- .setParent(parent)
- .setOpaque(false)
- .setHidden(false)
- .setEffectLayer()
- .build();
- } else {
- dimLayer = null;
- }
+ // Create a temporary effect layer, that lives on top of launcher, so we can apply
+ // the blur to it. The EffectLayer will be fullscreen, which will help with caching
+ // optimizations on the SurfaceFlinger side:
+ // - Results would be able to be cached as a texture
+ // - There won't be texture allocation overhead, because EffectLayers don't have
+ // buffers
+ ViewRootImpl viewRootImpl = mLauncher.getDragLayer().getViewRootImpl();
+ SurfaceControl parent = viewRootImpl != null
+ ? viewRootImpl.getSurfaceControl()
+ : null;
+ SurfaceControl dimLayer = new SurfaceControl.Builder()
+ .setName("Blur layer")
+ .setParent(parent)
+ .setOpaque(false)
+ .setHidden(false)
+ .setEffectLayer()
+ .build();
- depthController.setSurface(dimLayer);
- backgroundRadiusAnim.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationStart(Animator animation) {
- depthController.setIsInLaunchTransition(true);
- }
-
- @Override
- public void onAnimationEnd(Animator animation) {
- depthController.setIsInLaunchTransition(false);
- depthController.setSurface(null);
- if (dimLayer != null) {
- new SurfaceControl.Transaction()
- .remove(dimLayer)
- .apply();
- }
- }
- });
+ backgroundRadiusAnim.addListener(AnimatorListeners.forEndCallback(() ->
+ new SurfaceControl.Transaction().remove(dimLayer).apply()));
}
+
return backgroundRadiusAnim;
}
@@ -1433,7 +1418,7 @@
animation.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
- anim.start(mLauncher, velocityPxPerS);
+ anim.start(mLauncher, mDeviceProfile, velocityPxPerS);
}
});
return anim;
@@ -1936,4 +1921,17 @@
return Utilities.mapToRange(progress, start, end, 1, 0, ACCEL_1_5);
}
}
+
+ private static class MyDepthController extends DepthController {
+ MyDepthController(Launcher l) {
+ super(l);
+ setCrossWindowBlursEnabled(
+ CrossWindowBlurListeners.getInstance().isCrossWindowBlurEnabled());
+ }
+
+ @Override
+ public void setSurface(SurfaceControl surface) {
+ super.setSurface(surface);
+ }
+ }
}
diff --git a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
index eda0823..1311b1d 100644
--- a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
+++ b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
@@ -23,13 +23,8 @@
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
-import android.app.WallpaperManager;
-import android.os.IBinder;
-import android.os.SystemProperties;
import android.util.FloatProperty;
-import android.view.AttachedSurfaceControl;
import android.view.CrossWindowBlurListeners;
-import android.view.SurfaceControl;
import android.view.View;
import android.view.ViewRootImpl;
import android.view.ViewTreeObserver;
@@ -37,12 +32,11 @@
import com.android.launcher3.BaseActivity;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
-import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.statemanager.StateManager.StateHandler;
import com.android.launcher3.states.StateAnimationConfig;
-import com.android.systemui.shared.system.BlurUtils;
+import com.android.quickstep.util.BaseDepthController;
import java.io.PrintWriter;
import java.util.function.Consumer;
@@ -50,23 +44,9 @@
/**
* Controls blur and wallpaper zoom, for the Launcher surface only.
*/
-public class DepthController implements StateHandler<LauncherState>,
+public class DepthController extends BaseDepthController implements StateHandler<LauncherState>,
BaseActivity.MultiWindowModeChangedListener {
- private static final boolean OVERLAY_SCROLL_ENABLED = false;
- public static final FloatProperty<DepthController> DEPTH =
- new FloatProperty<DepthController>("depth") {
- @Override
- public void setValue(DepthController depthController, float depth) {
- depthController.setDepth(depth);
- }
-
- @Override
- public Float get(DepthController depthController) {
- return depthController.mDepth;
- }
- };
-
/**
* A property that updates the background blur within a given range of values (ie. even if the
* animator goes beyond 0..1, the interpolated value will still be bounded).
@@ -92,96 +72,46 @@
}
}
- private final ViewTreeObserver.OnDrawListener mOnDrawListener =
- new ViewTreeObserver.OnDrawListener() {
- @Override
- public void onDraw() {
- View view = mLauncher.getDragLayer();
- ViewRootImpl viewRootImpl = view.getViewRootImpl();
- boolean applied = setSurface(
- viewRootImpl != null ? viewRootImpl.getSurfaceControl() : null);
- if (!applied) {
- dispatchTransactionSurface(mDepth);
- }
- view.post(() -> view.getViewTreeObserver().removeOnDrawListener(this));
- }
- };
+ private final ViewTreeObserver.OnDrawListener mOnDrawListener = this::onLauncherDraw;
- private final Consumer<Boolean> mCrossWindowBlurListener = new Consumer<Boolean>() {
- @Override
- public void accept(Boolean enabled) {
- mCrossWindowBlursEnabled = enabled;
- dispatchTransactionSurface(mDepth);
- }
- };
+ private final Consumer<Boolean> mCrossWindowBlurListener = this::setCrossWindowBlursEnabled;
- private final Runnable mOpaquenessListener = new Runnable() {
- @Override
- public void run() {
- dispatchTransactionSurface(mDepth);
- }
- };
+ private final Runnable mOpaquenessListener = this::applyDepthAndBlur;
- private final Launcher mLauncher;
- /**
- * Blur radius when completely zoomed out, in pixels.
- */
- private int mMaxBlurRadius;
- private boolean mCrossWindowBlursEnabled;
- private WallpaperManager mWallpaperManager;
- private SurfaceControl mSurface;
- /**
- * How visible the -1 overlay is, from 0 to 1.
- */
- private float mOverlayScrollProgress;
- /**
- * Ratio from 0 to 1, where 0 is fully zoomed out, and 1 is zoomed in.
- * @see android.service.wallpaper.WallpaperService.Engine#onZoomChanged(float)
- */
- private float mDepth;
- /**
- * Last blur value, in pixels, that was applied.
- * For debugging purposes.
- */
- private int mCurrentBlur;
/**
* If we're launching and app and should not be blurring the screen for performance reasons.
*/
private boolean mBlurDisabledForAppLaunch;
- /**
- * If we requested early wake-up offsets to SurfaceFlinger.
- */
- private boolean mInEarlyWakeUp;
+
// Workaround for animating the depth when multiwindow mode changes.
private boolean mIgnoreStateChangesDuringMultiWindowAnimation = false;
- // Hints that there is potentially content behind Launcher and that we shouldn't optimize by
- // marking the launcher surface as opaque. Only used in certain Launcher states.
- private boolean mHasContentBehindLauncher;
-
private View.OnAttachStateChangeListener mOnAttachListener;
public DepthController(Launcher l) {
- mLauncher = l;
+ super(l);
+ }
+
+ private void onLauncherDraw() {
+ View view = mLauncher.getDragLayer();
+ ViewRootImpl viewRootImpl = view.getViewRootImpl();
+ setSurface(viewRootImpl != null ? viewRootImpl.getSurfaceControl() : null);
+ view.post(() -> view.getViewTreeObserver().removeOnDrawListener(mOnDrawListener));
}
private void ensureDependencies() {
- if (mWallpaperManager == null) {
- mMaxBlurRadius = mLauncher.getResources().getInteger(R.integer.max_depth_blur_radius);
- mWallpaperManager = mLauncher.getSystemService(WallpaperManager.class);
- }
-
if (mLauncher.getRootView() != null && mOnAttachListener == null) {
+ View rootView = mLauncher.getRootView();
mOnAttachListener = new View.OnAttachStateChangeListener() {
@Override
public void onViewAttachedToWindow(View view) {
+ CrossWindowBlurListeners.getInstance().addListener(mLauncher.getMainExecutor(),
+ mCrossWindowBlurListener);
+ mLauncher.getScrimView().addOpaquenessListener(mOpaquenessListener);
+
// To handle the case where window token is invalid during last setDepth call.
- IBinder windowToken = mLauncher.getRootView().getWindowToken();
- if (windowToken != null) {
- mWallpaperManager.setWallpaperZoomOut(windowToken, mDepth);
- }
- onAttached();
+ applyDepthAndBlur();
}
@Override
@@ -190,23 +120,13 @@
mLauncher.getScrimView().removeOpaquenessListener(mOpaquenessListener);
}
};
- mLauncher.getRootView().addOnAttachStateChangeListener(mOnAttachListener);
- if (mLauncher.getRootView().isAttachedToWindow()) {
- onAttached();
+ rootView.addOnAttachStateChangeListener(mOnAttachListener);
+ if (rootView.isAttachedToWindow()) {
+ mOnAttachListener.onViewAttachedToWindow(rootView);
}
}
}
- private void onAttached() {
- CrossWindowBlurListeners.getInstance().addListener(mLauncher.getMainExecutor(),
- mCrossWindowBlurListener);
- mLauncher.getScrimView().addOpaquenessListener(mOpaquenessListener);
- }
-
- public void setHasContentBehindLauncher(boolean hasContentBehindLauncher) {
- mHasContentBehindLauncher = hasContentBehindLauncher;
- }
-
/**
* Sets if the underlying activity is started or not
*/
@@ -219,26 +139,6 @@
}
}
- /**
- * Sets the specified app target surface to apply the blur to.
- * @return true when surface was valid and transaction was dispatched.
- */
- public boolean setSurface(SurfaceControl surface) {
- // Set launcher as the SurfaceControl when we don't need an external target anymore.
- if (surface == null) {
- ViewRootImpl viewRootImpl = mLauncher.getDragLayer().getViewRootImpl();
- surface = viewRootImpl != null ? viewRootImpl.getSurfaceControl() : null;
- }
- if (mSurface != surface) {
- mSurface = surface;
- if (surface != null) {
- dispatchTransactionSurface(mDepth);
- return true;
- }
- }
- return false;
- }
-
@Override
public void setState(LauncherState toState) {
if (mSurface == null || mIgnoreStateChangesDuringMultiWindowAnimation) {
@@ -249,7 +149,7 @@
if (Float.compare(mDepth, toDepth) != 0) {
setDepth(toDepth);
} else if (toState == LauncherState.OVERVIEW) {
- dispatchTransactionSurface(mDepth);
+ applyDepthAndBlur();
} else if (toState == LauncherState.BACKGROUND_APP) {
mLauncher.getDragLayer().getViewTreeObserver().addOnDrawListener(mOnDrawListener);
}
@@ -269,90 +169,10 @@
}
}
- /**
- * If we're launching an app from the home screen.
- */
- public void setIsInLaunchTransition(boolean inLaunchTransition) {
- boolean blurEnabled = SystemProperties.getBoolean("ro.launcher.blur.appLaunch", true);
- mBlurDisabledForAppLaunch = inLaunchTransition && !blurEnabled;
- if (!inLaunchTransition) {
- // Reset depth at the end of the launch animation, so the wallpaper won't be
- // zoomed out if an app crashes.
- setDepth(0f);
- }
- }
-
- private void setDepth(float depth) {
- depth = Utilities.boundToRange(depth, 0, 1);
- // Round out the depth to dedupe frequent, non-perceptable updates
- int depthI = (int) (depth * 256);
- float depthF = depthI / 256f;
- if (Float.compare(mDepth, depthF) == 0) {
- return;
- }
- dispatchTransactionSurface(depthF);
- mDepth = depthF;
- }
-
- public void onOverlayScrollChanged(float progress) {
- if (!OVERLAY_SCROLL_ENABLED) {
- return;
- }
- // Add some padding to the progress, such we don't change the depth on the last frames of
- // the animation. It's possible that a user flinging the feed quickly would scroll
- // horizontally by accident, causing the device to enter client composition unnecessarily.
- progress = Math.min(progress * 1.1f, 1f);
-
- // Round out the progress to dedupe frequent, non-perceptable updates
- int progressI = (int) (progress * 256);
- float progressF = Utilities.boundToRange(progressI / 256f, 0f, 1f);
- if (Float.compare(mOverlayScrollProgress, progressF) == 0) {
- return;
- }
- mOverlayScrollProgress = progressF;
- dispatchTransactionSurface(mDepth);
- }
-
- private boolean dispatchTransactionSurface(float depth) {
- boolean supportsBlur = BlurUtils.supportsBlursOnWindows();
- if (supportsBlur && (mSurface == null || !mSurface.isValid())) {
- return false;
- }
+ @Override
+ protected void applyDepthAndBlur() {
ensureDependencies();
- depth = Math.max(depth, mOverlayScrollProgress);
- IBinder windowToken = mLauncher.getRootView().getWindowToken();
- if (windowToken != null) {
- mWallpaperManager.setWallpaperZoomOut(windowToken, depth);
- }
-
- if (supportsBlur) {
- boolean hasOpaqueBg = mLauncher.getScrimView().isFullyOpaque();
- boolean isSurfaceOpaque = !mHasContentBehindLauncher && hasOpaqueBg;
-
- mCurrentBlur = !mCrossWindowBlursEnabled || mBlurDisabledForAppLaunch || hasOpaqueBg
- ? 0 : (int) (depth * mMaxBlurRadius);
- SurfaceControl.Transaction transaction = new SurfaceControl.Transaction()
- .setBackgroundBlurRadius(mSurface, mCurrentBlur)
- .setOpaque(mSurface, isSurfaceOpaque);
-
- // Set early wake-up flags when we know we're executing an expensive operation, this way
- // SurfaceFlinger will adjust its internal offsets to avoid jank.
- boolean wantsEarlyWakeUp = depth > 0 && depth < 1;
- if (wantsEarlyWakeUp && !mInEarlyWakeUp) {
- transaction.setEarlyWakeupStart();
- mInEarlyWakeUp = true;
- } else if (!wantsEarlyWakeUp && mInEarlyWakeUp) {
- transaction.setEarlyWakeupEnd();
- mInEarlyWakeUp = false;
- }
-
- AttachedSurfaceControl rootSurfaceControl =
- mLauncher.getRootView().getRootSurfaceControl();
- if (rootSurfaceControl != null) {
- rootSurfaceControl.applyTransactionOnDraw(transaction);
- }
- }
- return true;
+ super.applyDepthAndBlur();
}
@Override
@@ -377,7 +197,6 @@
writer.println(prefix + "\tmMaxBlurRadius=" + mMaxBlurRadius);
writer.println(prefix + "\tmCrossWindowBlursEnabled=" + mCrossWindowBlursEnabled);
writer.println(prefix + "\tmSurface=" + mSurface);
- writer.println(prefix + "\tmOverlayScrollProgress=" + mOverlayScrollProgress);
writer.println(prefix + "\tmDepth=" + mDepth);
writer.println(prefix + "\tmCurrentBlur=" + mCurrentBlur);
writer.println(prefix + "\tmBlurDisabledForAppLaunch=" + mBlurDisabledForAppLaunch);
diff --git a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
index b01168d..f1f18c1 100644
--- a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
@@ -15,15 +15,20 @@
*/
package com.android.launcher3.taskbar;
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+
import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_X;
import static com.android.launcher3.Utilities.getDescendantCoordRelativeToAncestor;
import static com.android.launcher3.taskbar.LauncherTaskbarUIController.SYSUI_SURFACE_PROGRESS_INDEX;
+import static com.android.launcher3.taskbar.TaskbarManager.isPhoneButtonNavMode;
+import static com.android.launcher3.taskbar.TaskbarManager.isPhoneMode;
import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_A11Y;
import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_BACK;
import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_HOME;
import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_IME_SWITCH;
import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_RECENTS;
import static com.android.launcher3.taskbar.TaskbarViewController.ALPHA_INDEX_KEYGUARD;
+import static com.android.launcher3.taskbar.TaskbarViewController.ALPHA_INDEX_SMALL_SCREEN;
import static com.android.launcher3.taskbar.Utilities.appendFlag;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_CLICKABLE;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE;
@@ -109,6 +114,7 @@
private static final int FLAG_NOTIFICATION_SHADE_EXPANDED = 1 << 10;
private static final int FLAG_SCREEN_PINNING_ACTIVE = 1 << 11;
private static final int FLAG_VOICE_INTERACTION_WINDOW_SHOWING = 1 << 12;
+ private static final int FLAG_SMALL_SCREEN = 1 << 13;
private static final String NAV_BUTTONS_SEPARATE_WINDOW_TITLE = "Taskbar Nav Buttons";
@@ -122,7 +128,7 @@
private final TaskbarActivityContext mContext;
private final FrameLayout mNavButtonsView;
- private final ViewGroup mNavButtonContainer;
+ private final LinearLayout mNavButtonContainer;
// Used for IME+A11Y buttons
private final ViewGroup mEndContextualContainer;
private final ViewGroup mStartContextualContainer;
@@ -180,9 +186,13 @@
*/
public void init(TaskbarControllers controllers) {
mControllers = controllers;
- mNavButtonsView.getLayoutParams().height = mContext.getDeviceProfile().taskbarSize;
-
boolean isThreeButtonNav = mContext.isThreeButtonNav();
+ DeviceProfile deviceProfile = mContext.getDeviceProfile();
+ Resources resources = mContext.getResources();
+ mNavButtonsView.getLayoutParams().height = !isPhoneMode(deviceProfile) ?
+ deviceProfile.taskbarSize :
+ resources.getDimensionPixelSize(R.dimen.taskbar_size);
+
mIsImeRenderingNavButtons =
InputMethodService.canImeRenderGesturalNavButtons() && mContext.imeDrawsImeNavBar();
if (!mIsImeRenderingNavButtons) {
@@ -201,6 +211,11 @@
flags -> (flags & FLAG_KEYGUARD_VISIBLE) == 0
&& (flags & FLAG_SCREEN_PINNING_ACTIVE) == 0));
+ mPropertyHolders.add(new StatePropertyHolder(
+ mControllers.taskbarViewController.getTaskbarIconAlpha()
+ .getProperty(ALPHA_INDEX_SMALL_SCREEN),
+ flags -> (flags & FLAG_SMALL_SCREEN) == 0));
+
mPropertyHolders.add(new StatePropertyHolder(mControllers.taskbarDragLayerController
.getKeyguardBgTaskbar(), flags -> (flags & FLAG_KEYGUARD_VISIBLE) == 0));
@@ -231,7 +246,7 @@
initButtons(mNavButtonContainer, mEndContextualContainer,
mControllers.navButtonController);
updateButtonLayoutSpacing();
-
+ updateStateForFlag(FLAG_SMALL_SCREEN, isPhoneButtonNavMode(mContext));
if (isInSetup) {
// Since setup wizard only has back button enabled, it looks strange to be
// end-aligned, so start-align instead.
@@ -244,18 +259,18 @@
// TODO(b/210906568) Dark intensity is currently not propagated during setup, so set
// it based on dark theme for now.
- int mode = mContext.getResources().getConfiguration().uiMode
+ int mode = resources.getConfiguration().uiMode
& Configuration.UI_MODE_NIGHT_MASK;
boolean isDarkTheme = mode == Configuration.UI_MODE_NIGHT_YES;
mTaskbarNavButtonDarkIntensity.updateValue(isDarkTheme ? 0 : 1);
} else if (isInKidsMode) {
- int iconSize = mContext.getResources().getDimensionPixelSize(
+ int iconSize = resources.getDimensionPixelSize(
R.dimen.taskbar_icon_size_kids);
- int buttonWidth = mContext.getResources().getDimensionPixelSize(
+ int buttonWidth = resources.getDimensionPixelSize(
R.dimen.taskbar_nav_buttons_width_kids);
- int buttonHeight = mContext.getResources().getDimensionPixelSize(
+ int buttonHeight = resources.getDimensionPixelSize(
R.dimen.taskbar_nav_buttons_height_kids);
- int buttonRadius = mContext.getResources().getDimensionPixelSize(
+ int buttonRadius = resources.getDimensionPixelSize(
R.dimen.taskbar_nav_buttons_corner_radius_kids);
int paddingleft = (buttonWidth - iconSize) / 2;
int paddingRight = paddingleft;
@@ -277,7 +292,7 @@
buttonWidth,
buttonHeight
);
- int homeButtonLeftMargin = mContext.getResources().getDimensionPixelSize(
+ int homeButtonLeftMargin = resources.getDimensionPixelSize(
R.dimen.taskbar_home_button_left_margin_kids);
homeLayoutparams.setMargins(homeButtonLeftMargin, 0, 0, 0);
mHomeButton.setLayoutParams(homeLayoutparams);
@@ -287,7 +302,7 @@
buttonWidth,
buttonHeight
);
- int backButtonLeftMargin = mContext.getResources().getDimensionPixelSize(
+ int backButtonLeftMargin = resources.getDimensionPixelSize(
R.dimen.taskbar_back_button_left_margin_kids);
backLayoutParams.setMargins(backButtonLeftMargin, 0, 0, 0);
mBackButton.setLayoutParams(backLayoutParams);
@@ -342,7 +357,7 @@
if (!mIsImeRenderingNavButtons) {
View imeDownButton = addButton(R.drawable.ic_sysbar_back, BUTTON_BACK,
mStartContextualContainer, mControllers.navButtonController, R.id.back);
- imeDownButton.setRotation(Utilities.isRtl(mContext.getResources()) ? 90 : -90);
+ imeDownButton.setRotation(Utilities.isRtl(resources) ? 90 : -90);
// Only show when IME is visible.
mPropertyHolders.add(new StatePropertyHolder(imeDownButton,
flags -> (flags & FLAG_IME_VISIBLE) != 0));
@@ -614,6 +629,9 @@
}
private void updateNavButtonTranslationY() {
+ if (isPhoneButtonNavMode(mContext)) {
+ return;
+ }
final float normalTranslationY = mTaskbarNavButtonTranslationY.value;
final float imeAdjustmentTranslationY = mTaskbarNavButtonTranslationYForIme.value;
TaskbarUIController uiController = mControllers.uiController;
@@ -676,17 +694,29 @@
updateButtonLayoutSpacing();
}
- /** Adds the correct spacing to 3 button nav container. No-op if using gesture nav */
+ /**
+ * Adds the correct spacing to 3 button nav container. No-op if using gesture nav or kids mode.
+ */
private void updateButtonLayoutSpacing() {
- if (!mContext.isThreeButtonNav()) {
+ if (!mContext.isThreeButtonNav() || mContext.isNavBarKidsModeActive()) {
return;
}
+
+ if (isPhoneButtonNavMode(mContext)) {
+ updatePhoneButtonSpacing();
+ return;
+ }
+
DeviceProfile dp = mContext.getDeviceProfile();
Resources res = mContext.getResources();
// Add spacing after the end of the last nav button
FrameLayout.LayoutParams navButtonParams =
(FrameLayout.LayoutParams) mNavButtonContainer.getLayoutParams();
+ navButtonParams.gravity = Gravity.END;
+ navButtonParams.width = FrameLayout.LayoutParams.WRAP_CONTENT;
+ navButtonParams.height = MATCH_PARENT;
+
int navMarginEnd = (int) res.getDimension(dp.inv.inlineNavButtonsEndSpacing);
int contextualWidth = mEndContextualContainer.getWidth();
// If contextual buttons are showing, we check if the end margin is enough for the
@@ -704,6 +734,39 @@
View navButton = mNavButtonContainer.getChildAt(i);
LinearLayout.LayoutParams buttonLayoutParams =
(LinearLayout.LayoutParams) navButton.getLayoutParams();
+ buttonLayoutParams.weight = 0;
+ if (i == 0) {
+ buttonLayoutParams.setMarginEnd(spaceInBetween / 2);
+ } else if (i == mNavButtonContainer.getChildCount() - 1) {
+ buttonLayoutParams.setMarginStart(spaceInBetween / 2);
+ } else {
+ buttonLayoutParams.setMarginStart(spaceInBetween / 2);
+ buttonLayoutParams.setMarginEnd(spaceInBetween / 2);
+ }
+ }
+ }
+
+ /** Uniformly spaces out the 3 button nav for smaller phone screens */
+ private void updatePhoneButtonSpacing() {
+ DeviceProfile dp = mContext.getDeviceProfile();
+ Resources res = mContext.getResources();
+
+ // TODO: Polish pending, this is just to make it usable
+ FrameLayout.LayoutParams navContainerParams =
+ (FrameLayout.LayoutParams) mNavButtonContainer.getLayoutParams();
+ int endStartMargins = res.getDimensionPixelSize(R.dimen.taskbar_nav_buttons_size);
+ navContainerParams.gravity = Gravity.CENTER;
+ navContainerParams.setMarginEnd(endStartMargins);
+ navContainerParams.setMarginStart(endStartMargins);
+ mNavButtonContainer.setLayoutParams(navContainerParams);
+
+ // Add the spaces in between the nav buttons
+ int spaceInBetween = res.getDimensionPixelSize(R.dimen.taskbar_button_space_inbetween_phone);
+ for (int i = 0; i < mNavButtonContainer.getChildCount(); i++) {
+ View navButton = mNavButtonContainer.getChildAt(i);
+ LinearLayout.LayoutParams buttonLayoutParams =
+ (LinearLayout.LayoutParams) navButton.getLayoutParams();
+ buttonLayoutParams.weight = 1;
if (i == 0) {
buttonLayoutParams.setMarginEnd(spaceInBetween / 2);
} else if (i == mNavButtonContainer.getChildCount() - 1) {
@@ -723,6 +786,8 @@
}
moveNavButtonsBackToTaskbarWindow();
+ mNavButtonContainer.removeAllViews();
+ mAllButtons.clear();
}
/**
diff --git a/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java b/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java
index 0652463..6b67b50 100644
--- a/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java
@@ -15,8 +15,6 @@
*/
package com.android.launcher3.taskbar;
-import static com.android.launcher3.taskbar.TaskbarManager.isPhoneMode;
-
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
@@ -96,7 +94,7 @@
mControllers = controllers;
DeviceProfile deviceProfile = mActivity.getDeviceProfile();
Resources resources = mActivity.getResources();
- if (isPhoneMode(mActivity.getDeviceProfile())) {
+ if (isPhoneGestureNavMode(mActivity.getDeviceProfile())) {
mStashedHandleView.getLayoutParams().height =
resources.getDimensionPixelSize(R.dimen.taskbar_size);
mStashedHandleWidth =
@@ -108,7 +106,7 @@
}
mTaskbarStashedHandleAlpha.getProperty(ALPHA_INDEX_STASHED).setValue(
- isPhoneMode(deviceProfile) ? 1 : 0);
+ isPhoneGestureNavMode(deviceProfile) ? 1 : 0);
mTaskbarStashedHandleHintScale.updateValue(1f);
final int stashedTaskbarHeight = mControllers.taskbarStashController.getStashedHeight();
@@ -136,7 +134,7 @@
view.setPivotY(stashedCenterY);
});
initRegionSampler();
- if (isPhoneMode(deviceProfile)) {
+ if (isPhoneGestureNavMode(deviceProfile)) {
onIsStashedChanged(true);
}
}
@@ -164,6 +162,10 @@
mRegionSamplingHelper = null;
}
+ private boolean isPhoneGestureNavMode(DeviceProfile deviceProfile) {
+ return TaskbarManager.isPhoneMode(deviceProfile) && !mActivity.isThreeButtonNav();
+ }
+
public MultiValueAlpha getStashedHandleAlpha() {
return mTaskbarStashedHandleAlpha;
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index f5fe77a..e1bcbe2 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -119,7 +119,7 @@
// The size we should return to when we call setTaskbarWindowFullscreen(false)
private int mLastRequestedNonFullscreenHeight;
- private final NavigationMode mNavMode;
+ private NavigationMode mNavMode;
private final boolean mImeDrawsImeNavBar;
private final ViewCache mViewCache = new ViewCache();
@@ -235,7 +235,8 @@
}
/** Updates {@link DeviceProfile} instances for any Taskbar windows. */
- public void updateDeviceProfile(DeviceProfile dp) {
+ public void updateDeviceProfile(DeviceProfile dp, NavigationMode navMode) {
+ mNavMode = navMode;
mControllers.taskbarAllAppsController.updateDeviceProfile(dp);
mDeviceProfile = dp.copy(this);
updateIconSize(getResources());
@@ -608,7 +609,10 @@
*/
public int getDefaultTaskbarWindowHeight() {
if (FLAG_HIDE_NAVBAR_WINDOW && mDeviceProfile.isPhone) {
- return getResources().getDimensionPixelSize(R.dimen.taskbar_stashed_size);
+ Resources resources = getResources();
+ return isThreeButtonNav() ?
+ resources.getDimensionPixelSize(R.dimen.taskbar_size) :
+ resources.getDimensionPixelSize(R.dimen.taskbar_stashed_size);
}
return mDeviceProfile.taskbarSize + Math.max(getLeftCornerRadius(), getRightCornerRadius());
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java
index 77ef83c..ec9760c 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java
@@ -18,6 +18,7 @@
import android.content.res.Resources;
import android.graphics.Rect;
+import com.android.launcher3.DeviceProfile;
import com.android.launcher3.R;
import com.android.launcher3.util.TouchController;
import com.android.quickstep.AnimatedFloat;
@@ -173,7 +174,15 @@
* Returns how tall the background should be drawn at the bottom of the screen.
*/
public int getTaskbarBackgroundHeight() {
- return mActivity.getDeviceProfile().taskbarSize;
+ DeviceProfile deviceProfile = mActivity.getDeviceProfile();
+ if (TaskbarManager.isPhoneMode(deviceProfile)) {
+ Resources resources = mActivity.getResources();
+ return mActivity.isThreeButtonNav() ?
+ resources.getDimensionPixelSize(R.dimen.taskbar_size) :
+ resources.getDimensionPixelSize(R.dimen.taskbar_stashed_size);
+ } else {
+ return deviceProfile.taskbarSize;
+ }
}
/**
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
index 85e76b2..0bda3cd 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
@@ -32,6 +32,7 @@
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.BaseQuickstepLauncher;
+import com.android.launcher3.DeviceProfile;
import com.android.launcher3.LauncherState;
import com.android.launcher3.QuickstepTransitionManager;
import com.android.launcher3.Utilities;
@@ -48,6 +49,7 @@
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.StringJoiner;
+import java.util.function.Consumer;
import java.util.function.Supplier;
/**
@@ -92,6 +94,15 @@
// We skip any view synchronizations during init/destroy.
private boolean mCanSyncViews;
+ private final Consumer<Float> mIconAlphaForHomeConsumer = alpha -> {
+ mLauncher.getHotseat().setIconsAlpha(alpha > 0 ? 0 : 1);
+ mLauncher.getHotseat().setQsbAlpha(
+ mLauncher.getDeviceProfile().isQsbInline && alpha > 0 ? 0 : 1);
+ };
+
+ private final DeviceProfile.OnDeviceProfileChangeListener mOnDeviceProfileChangeListener =
+ dp -> mIconAlphaForHomeConsumer.accept(mIconAlphaForHome.getValue());
+
private final StateManager.StateListener<LauncherState> mStateListener =
new StateManager.StateListener<LauncherState>() {
@@ -131,13 +142,7 @@
.getTaskbarBackgroundAlpha();
MultiValueAlpha taskbarIconAlpha = mControllers.taskbarViewController.getTaskbarIconAlpha();
mIconAlphaForHome = taskbarIconAlpha.getProperty(ALPHA_INDEX_HOME);
- mIconAlphaForHome.setConsumer(
- alpha -> {
- mLauncher.getHotseat().setIconsAlpha(alpha > 0 ? 0 : 1);
- if (mLauncher.getDeviceProfile().isQsbInline) {
- mLauncher.getHotseat().setQsbAlpha(alpha > 0 ? 0 : 1);
- }
- });
+ mIconAlphaForHome.setConsumer(mIconAlphaForHomeConsumer);
mIconAlignmentForResumedState.finishAnimation();
onIconAlignmentRatioChangedForAppAndHomeTransition();
@@ -150,6 +155,7 @@
applyState(0);
mCanSyncViews = true;
+ mLauncher.addOnDeviceProfileChangeListener(mOnDeviceProfileChangeListener);
}
public void onDestroy() {
@@ -164,6 +170,7 @@
mLauncher.getStateManager().removeStateListener(mStateListener);
mCanSyncViews = true;
+ mLauncher.removeOnDeviceProfileChangeListener(mOnDeviceProfileChangeListener);
}
public Animator createAnimToLauncher(@NonNull LauncherState toState,
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
index 353bf89..1212c61 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java
@@ -82,6 +82,7 @@
// It's destruction/creation will be managed by the activity.
private final ScopedUnfoldTransitionProgressProvider mUnfoldProgressProvider =
new NonDestroyableScopedUnfoldTransitionProgressProvider();
+ private DisplayController.NavigationMode mNavMode;
private TaskbarActivityContext mTaskbarActivityContext;
private StatefulActivity mActivity;
@@ -132,9 +133,11 @@
| ActivityInfo.CONFIG_SCREEN_SIZE;
boolean requiresRecreate = (configDiff & configsRequiringRecreate) != 0;
if ((configDiff & ActivityInfo.CONFIG_SCREEN_SIZE) != 0
- && mTaskbarActivityContext != null && dp != null) {
+ && mTaskbarActivityContext != null && dp != null
+ && !isPhoneMode(dp)) {
// Additional check since this callback gets fired multiple times w/o
// screen size changing, or when simply rotating the device.
+ // In the case of phone device rotation, we do want to call recreateTaskbar()
DeviceProfile oldDp = mTaskbarActivityContext.getDeviceProfile();
boolean isOrientationChange =
(configDiff & ActivityInfo.CONFIG_ORIENTATION) != 0;
@@ -152,7 +155,7 @@
// Config change might be handled without re-creating the taskbar
if (mTaskbarActivityContext != null) {
if (dp != null && isTaskbarPresent(dp)) {
- mTaskbarActivityContext.updateDeviceProfile(dp);
+ mTaskbarActivityContext.updateDeviceProfile(dp, mNavMode);
}
mTaskbarActivityContext.onConfigurationChanged(configDiff);
}
@@ -167,9 +170,11 @@
destroyExistingTaskbar());
mDispInfoChangeListener = (context, info, flags) -> {
if ((flags & CHANGE_FLAGS) != 0) {
+ mNavMode = info.navigationMode;
recreateTaskbar();
}
};
+ mNavMode = mDisplayController.getInfo().navigationMode;
mDisplayController.addChangeListener(mDispInfoChangeListener);
SettingsCache.INSTANCE.get(mContext).register(USER_SETUP_COMPLETE_URI,
mUserSetupCompleteListener);
@@ -289,7 +294,7 @@
mTaskbarActivityContext = new TaskbarActivityContext(mContext, dp, mNavButtonController,
mUnfoldProgressProvider);
} else {
- mTaskbarActivityContext.updateDeviceProfile(dp);
+ mTaskbarActivityContext.updateDeviceProfile(dp, mNavMode);
}
mTaskbarActivityContext.init(mSharedState);
@@ -324,6 +329,14 @@
return TaskbarManager.FLAG_HIDE_NAVBAR_WINDOW && deviceProfile.isPhone;
}
+ /**
+ * @return {@code true} if {@link #isPhoneMode(DeviceProfile)} is true and we're using
+ * 3 button-nav
+ */
+ public static boolean isPhoneButtonNavMode(TaskbarActivityContext context) {
+ return isPhoneMode(context.getDeviceProfile()) && context.isThreeButtonNav();
+ }
+
private boolean isTaskbarPresent(DeviceProfile deviceProfile) {
return FLAG_HIDE_NAVBAR_WINDOW || deviceProfile.isTaskbarPresent;
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
index 114ab4e..3ea9173 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
@@ -20,7 +20,6 @@
import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_LONGPRESS_HIDE;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_LONGPRESS_SHOW;
-import static com.android.launcher3.taskbar.TaskbarManager.isPhoneMode;
import static com.android.launcher3.taskbar.Utilities.appendFlag;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SHOWING;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SWITCHER_SHOWING;
@@ -180,7 +179,7 @@
mActivity = activity;
mPrefs = Utilities.getPrefs(mActivity);
mSystemUiProxy = SystemUiProxy.INSTANCE.get(activity);
- if (isPhoneMode(mActivity.getDeviceProfile())) {
+ if (isPhoneMode()) {
// DeviceProfile's taskbar vars aren't initialized w/ the flag off
Resources resources = mActivity.getResources();
mUnstashedHeight = resources.getDimensionPixelSize(R.dimen.taskbar_size);
@@ -217,7 +216,8 @@
updateStateForFlag(FLAG_STASHED_IN_APP_MANUAL, isManuallyStashedInApp);
updateStateForFlag(FLAG_STASHED_IN_APP_SETUP, isInSetup);
updateStateForFlag(FLAG_IN_SETUP, isInSetup);
- updateStateForFlag(FLAG_STASHED_SMALL_SCREEN, isPhoneMode(mActivity.getDeviceProfile()));
+ updateStateForFlag(FLAG_STASHED_SMALL_SCREEN, isPhoneMode()
+ && !mActivity.isThreeButtonNav());
applyState();
notifyStashChange(/* visible */ false, /* stashed */ isStashedInApp());
@@ -229,7 +229,7 @@
*/
public boolean supportsVisualStashing() {
return mControllers.uiController.supportsVisualStashing() ||
- isPhoneMode(mActivity.getDeviceProfile());
+ (isPhoneMode() && !mActivity.isThreeButtonNav());
}
/**
@@ -286,6 +286,13 @@
return (hasAnyFlag(FLAG_IN_STASHED_LAUNCHER_STATE) && supportsVisualStashing());
}
+ /**
+ * @return {@code true} if we're not on a large screen AND using gesture nav
+ */
+ private boolean isPhoneMode() {
+ return TaskbarManager.isPhoneMode(mActivity.getDeviceProfile());
+ }
+
private boolean hasAnyFlag(int flagMask) {
return hasAnyFlag(mState, flagMask);
}
@@ -312,7 +319,7 @@
* @see WindowInsets.Type#systemBars()
*/
public int getContentHeightToReportToApps() {
- if (isPhoneMode(mActivity.getDeviceProfile())) {
+ if (isPhoneMode() && !mActivity.isThreeButtonNav()) {
return getStashedHeight();
}
@@ -431,7 +438,7 @@
}
mAnimator = new AnimatorSet();
addJankMonitorListener(mAnimator, /* appearing= */ !mIsStashed);
- final float stashTranslation = isPhoneMode(mActivity.getDeviceProfile()) ? 0 :
+ final float stashTranslation = isPhoneMode() ? 0 :
(mUnstashedHeight - mStashedHeight) / 2f;
if (!supportsVisualStashing()) {
@@ -477,7 +484,7 @@
firstHalfAnimatorSet.playTogether(
mIconAlphaForStash.animateToValue(0),
- mIconScaleForStash.animateToValue(isPhoneMode(mActivity.getDeviceProfile()) ?
+ mIconScaleForStash.animateToValue(isPhoneMode() ?
0 : STASHED_TASKBAR_SCALE)
);
secondHalfAnimatorSet.playTogether(
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
index ea15acb..dbf9759 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
@@ -314,10 +314,10 @@
int qsbEnd;
if (layoutRtl) {
qsbStart = iconEnd + mItemMarginLeftRight;
- qsbEnd = qsbStart + deviceProfile.qsbWidth;
+ qsbEnd = qsbStart + deviceProfile.hotseatQsbWidth;
} else {
qsbEnd = iconEnd - mItemMarginLeftRight;
- qsbStart = qsbEnd - deviceProfile.qsbWidth;
+ qsbStart = qsbEnd - deviceProfile.hotseatQsbWidth;
}
int qsbTop = (bottom - top - deviceProfile.hotseatQsbHeight) / 2;
int qsbBottom = qsbTop + deviceProfile.hotseatQsbHeight;
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
index 0f6de73..992aa4b 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
@@ -71,7 +71,8 @@
public static final int ALPHA_INDEX_NOTIFICATION_EXPANDED = 4;
public static final int ALPHA_INDEX_ASSISTANT_INVOKED = 5;
public static final int ALPHA_INDEX_IME_BUTTON_NAV = 6;
- private static final int NUM_ALPHA_CHANNELS = 7;
+ public static final int ALPHA_INDEX_SMALL_SCREEN = 7;
+ private static final int NUM_ALPHA_CHANNELS = 8;
private final TaskbarActivityContext mActivity;
private final TaskbarView mTaskbarView;
@@ -295,10 +296,11 @@
boolean isRtl = Utilities.isRtl(child.getResources());
float hotseatIconCenter = isRtl
? launcherDp.widthPx - hotseatPadding.right + borderSpacing
- + launcherDp.qsbWidth / 2f
- : hotseatPadding.left - borderSpacing - launcherDp.qsbWidth / 2f;
+ + launcherDp.hotseatQsbWidth / 2f
+ : hotseatPadding.left - borderSpacing - launcherDp.hotseatQsbWidth / 2f;
float childCenter = (child.getLeft() + child.getRight()) / 2f;
- float halfQsbIconWidthDiff = (launcherDp.qsbWidth - taskbarDp.iconSizePx) / 2f;
+ float halfQsbIconWidthDiff =
+ (launcherDp.hotseatQsbWidth - taskbarDp.iconSizePx) / 2f;
setter.addFloat(child, ICON_TRANSLATE_X,
isRtl ? -halfQsbIconWidthDiff : halfQsbIconWidthDiff,
hotseatIconCenter - childCenter, LINEAR);
@@ -312,7 +314,7 @@
: Interpolators.clampToProgress(LINEAR, 0.84f, 1f));
setter.addOnFrameListener(animator -> AlphaUpdateListener.updateVisibility(child));
- float qsbInsetFraction = halfQsbIconWidthDiff / launcherDp.qsbWidth;
+ float qsbInsetFraction = halfQsbIconWidthDiff / launcherDp.hotseatQsbWidth;
if (child instanceof HorizontalInsettableView) {
setter.addFloat((HorizontalInsettableView) child,
HorizontalInsettableView.HORIZONTAL_INSETS, qsbInsetFraction, 0,
@@ -389,7 +391,8 @@
"ALPHA_INDEX_RECENTS_DISABLED",
"ALPHA_INDEX_NOTIFICATION_EXPANDED",
"ALPHA_INDEX_ASSISTANT_INVOKED",
- "ALPHA_INDEX_IME_BUTTON_NAV");
+ "ALPHA_INDEX_IME_BUTTON_NAV",
+ "ALPHA_INDEX_SMALL_SCREEN");
mModelCallbacks.dumpLogs(prefix + "\t", pw);
}
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index 8f1872b..8dee10a 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -1330,7 +1330,8 @@
if (windowAnimation == null) {
continue;
}
- windowAnimation.start(mContext, velocityPxPerMs);
+ DeviceProfile dp = mActivity == null ? null : mActivity.getDeviceProfile();
+ windowAnimation.start(mContext, dp, velocityPxPerMs);
mRunningWindowAnim[i] = RunningWindowAnim.wrap(windowAnimation);
}
homeAnimFactory.setSwipeVelocity(velocityPxPerMs.y);
diff --git a/quickstep/src/com/android/quickstep/RecentsActivity.java b/quickstep/src/com/android/quickstep/RecentsActivity.java
index 4435eda..3e3a431 100644
--- a/quickstep/src/com/android/quickstep/RecentsActivity.java
+++ b/quickstep/src/com/android/quickstep/RecentsActivity.java
@@ -15,9 +15,6 @@
*/
package com.android.quickstep;
-import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION;
-import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE;
-
import static com.android.launcher3.QuickstepTransitionManager.RECENTS_LAUNCH_DURATION;
import static com.android.launcher3.QuickstepTransitionManager.STATUS_BAR_TRANSITION_DURATION;
import static com.android.launcher3.QuickstepTransitionManager.STATUS_BAR_TRANSITION_PRE_DELAY;
@@ -110,8 +107,6 @@
private @Nullable TaskbarManager mTaskbarManager;
private @Nullable FallbackTaskbarUIController mTaskbarUIController;
- private Configuration mOldConfig;
-
private StateManager<RecentsState> mStateManager;
// Strong refs to runners which are cleared when the activity is destroyed
@@ -163,7 +158,7 @@
@Override
public void onMultiWindowModeChanged(boolean isInMultiWindowMode, Configuration newConfig) {
- onHandleConfigChanged();
+ onHandleConfigurationChanged();
super.onMultiWindowModeChanged(isInMultiWindowMode, newConfig);
}
@@ -173,11 +168,8 @@
ACTIVITY_TRACKER.handleNewIntent(this);
}
- /**
- * Logic for when device configuration changes (rotation, screen size change, multi-window,
- * etc.)
- */
- protected void onHandleConfigChanged() {
+ @Override
+ protected void onHandleConfigurationChanged() {
initDeviceProfile();
AbstractFloatingView.closeOpenViews(this, true,
@@ -338,7 +330,6 @@
mStateManager = new StateManager<>(this, RecentsState.BG_LAUNCHER);
- mOldConfig = new Configuration(getResources().getConfiguration());
initDeviceProfile();
setupViews();
@@ -348,16 +339,6 @@
}
@Override
- public void onConfigurationChanged(Configuration newConfig) {
- int diff = newConfig.diff(mOldConfig);
- if ((diff & (CONFIG_ORIENTATION | CONFIG_SCREEN_SIZE)) != 0) {
- onHandleConfigChanged();
- }
- mOldConfig.setTo(newConfig);
- super.onConfigurationChanged(newConfig);
- }
-
- @Override
public void onStateSetEnd(RecentsState state) {
super.onStateSetEnd(state);
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java b/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java
index 51ae56b..c602324 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java
@@ -16,7 +16,6 @@
package com.android.quickstep;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
-import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME;
import android.graphics.Rect;
import android.util.ArraySet;
@@ -97,18 +96,6 @@
RemoteAnimationTargetCompat[] appTargets,
RemoteAnimationTargetCompat[] wallpaperTargets,
Rect homeContentInsets, Rect minimizedHomeBounds) {
- // Convert appTargets to type RemoteAnimationTarget for all apps except Home app
- RemoteAnimationTarget[] nonHomeApps = Arrays.stream(appTargets)
- .filter(remoteAnimationTarget ->
- remoteAnimationTarget.activityType != ACTIVITY_TYPE_HOME)
- .map(RemoteAnimationTargetCompat::unwrap)
- .toArray(RemoteAnimationTarget[]::new);
-
- RemoteAnimationTarget[] nonAppTargets = mSystemUiProxy.onGoingToRecentsLegacy(nonHomeApps);
-
- RecentsAnimationTargets targets = new RecentsAnimationTargets(appTargets,
- wallpaperTargets, RemoteAnimationTargetCompat.wrap(nonAppTargets),
- homeContentInsets, minimizedHomeBounds);
mController = new RecentsAnimationController(animationController,
mAllowMinimizeSplitScreen, this::onAnimationFinished);
@@ -116,6 +103,13 @@
Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(),
mController::finishAnimationToApp);
} else {
+ final RemoteAnimationTarget[] nonAppTargets = mSystemUiProxy.onGoingToRecentsLegacy(
+ Arrays.stream(appTargets).map(RemoteAnimationTargetCompat::unwrap)
+ .toArray(RemoteAnimationTarget[]::new));
+ final RecentsAnimationTargets targets = new RecentsAnimationTargets(appTargets,
+ wallpaperTargets, RemoteAnimationTargetCompat.wrap(nonAppTargets),
+ homeContentInsets, minimizedHomeBounds);
+
Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(), () -> {
for (RecentsAnimationListener listener : getListeners()) {
listener.onRecentsAnimationStart(mController, targets);
diff --git a/quickstep/src/com/android/quickstep/TaskAnimationManager.java b/quickstep/src/com/android/quickstep/TaskAnimationManager.java
index fd7e367..0314761 100644
--- a/quickstep/src/com/android/quickstep/TaskAnimationManager.java
+++ b/quickstep/src/com/android/quickstep/TaskAnimationManager.java
@@ -45,7 +45,7 @@
import com.android.systemui.shared.system.TaskStackChangeListener;
import com.android.systemui.shared.system.TaskStackChangeListeners;
-import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashMap;
public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAnimationListener {
@@ -156,30 +156,21 @@
public void onTasksAppeared(RemoteAnimationTargetCompat[] appearedTaskTargets) {
RemoteAnimationTargetCompat appearedTaskTarget = appearedTaskTargets[0];
BaseActivityInterface activityInterface = mLastGestureState.getActivityInterface();
- // Convert appTargets to type RemoteAnimationTarget for all apps except Home app
- final ArrayList<RemoteAnimationTargetCompat> tmpNonHomeApps = new ArrayList<>();
- final ArrayList<RemoteAnimationTargetCompat> tmpHomeApps = new ArrayList<>();
+
for (RemoteAnimationTargetCompat compat : appearedTaskTargets) {
- if (compat.activityType != ACTIVITY_TYPE_HOME) {
- tmpNonHomeApps.add(compat);
- } else {
- tmpHomeApps.add(compat);
+ if (compat.activityType == ACTIVITY_TYPE_HOME
+ && activityInterface.getCreatedActivity() instanceof RecentsActivity) {
+ // When receive opening home activity while recents is running, enter home
+ // and dismiss recents.
+ ((RecentsActivity) activityInterface.getCreatedActivity()).startHome();
+ return;
}
}
- RemoteAnimationTarget[] nonHomeApps = tmpNonHomeApps.stream()
- .map(RemoteAnimationTargetCompat::unwrap)
- .toArray(RemoteAnimationTarget[]::new);
- RemoteAnimationTarget[] homeApps = tmpHomeApps.stream()
- .map(RemoteAnimationTargetCompat::unwrap)
- .toArray(RemoteAnimationTarget[]::new);
- if (homeApps.length > 0
- && activityInterface.getCreatedActivity() instanceof RecentsActivity) {
- ((RecentsActivity) activityInterface.getCreatedActivity()).startHome();
- return;
- }
- RemoteAnimationTarget[] nonAppTargets =
- SystemUiProxy.INSTANCE.getNoCreate().onStartingSplitLegacy(nonHomeApps);
+ RemoteAnimationTarget[] nonAppTargets = SystemUiProxy.INSTANCE.getNoCreate()
+ .onStartingSplitLegacy(Arrays.stream(appearedTaskTargets)
+ .map(RemoteAnimationTargetCompat::unwrap)
+ .toArray(RemoteAnimationTarget[]::new));
if (ENABLE_QUICKSTEP_LIVE_TILE.get() && activityInterface.isInLiveTileMode()
&& activityInterface.getCreatedActivity() != null) {
diff --git a/quickstep/src/com/android/quickstep/TaskViewUtils.java b/quickstep/src/com/android/quickstep/TaskViewUtils.java
index fa30b8f..3bd72fe 100644
--- a/quickstep/src/com/android/quickstep/TaskViewUtils.java
+++ b/quickstep/src/com/android/quickstep/TaskViewUtils.java
@@ -389,10 +389,39 @@
* device is considered in multiWindowMode and things like insets and stuff change
* and calculations have to be adjusted in the animations for that
*/
- public static void composeRecentsSplitLaunchAnimator(int initialTaskId,
- @Nullable PendingIntent initialTaskPendingIntent, int secondTaskId,
+ public static void composeRecentsSplitLaunchAnimator(GroupedTaskView launchingTaskView,
+ @NonNull StateManager stateManager, @Nullable DepthController depthController,
+ int initialTaskId, @Nullable PendingIntent initialTaskPendingIntent, int secondTaskId,
@NonNull TransitionInfo transitionInfo, SurfaceControl.Transaction t,
@NonNull Runnable finishCallback) {
+ if (launchingTaskView != null) {
+ AnimatorSet animatorSet = new AnimatorSet();
+ animatorSet.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ finishCallback.run();
+ }
+ });
+
+ final RemoteAnimationTargetCompat[] appTargets =
+ RemoteAnimationTargetCompat.wrapApps(transitionInfo, t, null /* leashMap */);
+ final RemoteAnimationTargetCompat[] wallpaperTargets =
+ RemoteAnimationTargetCompat.wrapNonApps(
+ transitionInfo, true /* wallpapers */, t, null /* leashMap */);
+ final RemoteAnimationTargetCompat[] nonAppTargets =
+ RemoteAnimationTargetCompat.wrapNonApps(
+ transitionInfo, false /* wallpapers */, t, null /* leashMap */);
+ final RecentsView recentsView = launchingTaskView.getRecentsView();
+ composeRecentsLaunchAnimator(animatorSet, launchingTaskView,
+ appTargets, wallpaperTargets, nonAppTargets,
+ true, stateManager,
+ recentsView, depthController);
+
+ t.apply();
+ animatorSet.start();
+ return;
+ }
+
// TODO: consider initialTaskPendingIntent
TransitionInfo.Change splitRoot1 = null;
TransitionInfo.Change splitRoot2 = null;
@@ -657,6 +686,7 @@
public void onAnimationStart(Animator animation) {
if (shown) {
for (SurfaceControl leash : auxiliarySurfaces) {
+ t.setLayer(leash, Integer.MAX_VALUE);
t.setAlpha(leash, 0);
t.show(leash);
}
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index 52a37c5..c46926e 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -270,6 +270,18 @@
MAIN_EXECUTOR.execute(ProxyScreenStatusProvider.INSTANCE::onScreenTurnedOn);
}
+ @BinderThread
+ @Override
+ public void onScreenTurningOn() {
+ MAIN_EXECUTOR.execute(ProxyScreenStatusProvider.INSTANCE::onScreenTurningOn);
+ }
+
+ @BinderThread
+ @Override
+ public void onScreenTurningOff() {
+ MAIN_EXECUTOR.execute(ProxyScreenStatusProvider.INSTANCE::onScreenTurningOff);
+ }
+
/**
* Preloads the Overview activity.
*
diff --git a/quickstep/src/com/android/quickstep/ViewUtils.java b/quickstep/src/com/android/quickstep/ViewUtils.java
index 1fef544..1bb95b9 100644
--- a/quickstep/src/com/android/quickstep/ViewUtils.java
+++ b/quickstep/src/com/android/quickstep/ViewUtils.java
@@ -17,6 +17,7 @@
import android.graphics.HardwareRenderer;
import android.os.Handler;
+import android.view.SurfaceControl;
import android.view.View;
import android.view.ViewRootImpl;
@@ -45,23 +46,43 @@
return new FrameHandler(view, onFinishRunnable, canceled).schedule();
}
- private static class FrameHandler implements HardwareRenderer.FrameDrawingCallback {
+ private static class FrameHandler implements HardwareRenderer.FrameDrawingCallback,
+ ViewRootImpl.SurfaceChangedCallback {
final ViewRootImpl mViewRoot;
final Runnable mFinishCallback;
final BooleanSupplier mCancelled;
final Handler mHandler;
+ boolean mFinished;
int mDeferFrameCount = 1;
FrameHandler(View view, Runnable finishCallback, BooleanSupplier cancelled) {
mViewRoot = view.getViewRootImpl();
+ mViewRoot.addSurfaceChangedCallback(this);
mFinishCallback = finishCallback;
mCancelled = cancelled;
mHandler = new Handler();
}
@Override
+ public void surfaceCreated(SurfaceControl.Transaction t) {
+ // Do nothing
+ }
+
+ @Override
+ public void surfaceReplaced(SurfaceControl.Transaction t) {
+ // Do nothing
+ }
+
+ @Override
+ public void surfaceDestroyed() {
+ // If the root view is detached, then the app won't get any scheduled frames so we need
+ // to force-run any pending callbacks
+ finish();
+ }
+
+ @Override
public void onFrameDraw(long frame) {
Utilities.postAsyncCallback(mHandler, this::onFrame);
}
@@ -77,9 +98,7 @@
return;
}
- if (mFinishCallback != null) {
- mFinishCallback.run();
- }
+ finish();
}
private boolean schedule() {
@@ -90,5 +109,17 @@
}
return false;
}
+
+ private void finish() {
+ if (mFinished) {
+ return;
+ }
+ mFinished = true;
+ mDeferFrameCount = 0;
+ if (mFinishCallback != null) {
+ mFinishCallback.run();
+ }
+ mViewRoot.removeSurfaceChangedCallback(this);
+ }
}
}
diff --git a/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java
index b70c411..fa7bc04 100644
--- a/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java
+++ b/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java
@@ -358,7 +358,7 @@
};
RectFSpringAnim windowAnim = createWindowAnimationToHome(startShift,
homeAnimFactory)[0];
- windowAnim.start(mContext, velocityPxPerMs);
+ windowAnim.start(mContext, mDp, velocityPxPerMs);
return windowAnim;
}
}
diff --git a/quickstep/src/com/android/quickstep/util/BaseDepthController.java b/quickstep/src/com/android/quickstep/util/BaseDepthController.java
new file mode 100644
index 0000000..4030630
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/util/BaseDepthController.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2022 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.quickstep.util;
+
+import android.app.WallpaperManager;
+import android.os.IBinder;
+import android.util.FloatProperty;
+import android.view.AttachedSurfaceControl;
+import android.view.SurfaceControl;
+
+import com.android.launcher3.Launcher;
+import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
+import com.android.systemui.shared.system.BlurUtils;
+
+/**
+ * Utility class for applying depth effect
+ */
+public class BaseDepthController {
+
+ public static final FloatProperty<BaseDepthController> DEPTH =
+ new FloatProperty<BaseDepthController>("depth") {
+ @Override
+ public void setValue(BaseDepthController depthController, float depth) {
+ depthController.setDepth(depth);
+ }
+
+ @Override
+ public Float get(BaseDepthController depthController) {
+ return depthController.mDepth;
+ }
+ };
+
+ protected final Launcher mLauncher;
+
+ /**
+ * Blur radius when completely zoomed out, in pixels.
+ */
+ protected final int mMaxBlurRadius;
+ protected final WallpaperManager mWallpaperManager;
+ protected boolean mCrossWindowBlursEnabled;
+
+ /**
+ * Ratio from 0 to 1, where 0 is fully zoomed out, and 1 is zoomed in.
+ * @see android.service.wallpaper.WallpaperService.Engine#onZoomChanged(float)
+ */
+ protected float mDepth;
+
+ protected SurfaceControl mSurface;
+
+ // Hints that there is potentially content behind Launcher and that we shouldn't optimize by
+ // marking the launcher surface as opaque. Only used in certain Launcher states.
+ private boolean mHasContentBehindLauncher;
+ /**
+ * Last blur value, in pixels, that was applied.
+ * For debugging purposes.
+ */
+ protected int mCurrentBlur;
+ /**
+ * If we requested early wake-up offsets to SurfaceFlinger.
+ */
+ protected boolean mInEarlyWakeUp;
+
+ public BaseDepthController(Launcher activity) {
+ mLauncher = activity;
+ mMaxBlurRadius = activity.getResources().getInteger(R.integer.max_depth_blur_radius);
+ mWallpaperManager = activity.getSystemService(WallpaperManager.class);
+ }
+
+ protected void setCrossWindowBlursEnabled(boolean isEnabled) {
+ mCrossWindowBlursEnabled = isEnabled;
+ applyDepthAndBlur();
+ }
+
+ public void setHasContentBehindLauncher(boolean hasContentBehindLauncher) {
+ mHasContentBehindLauncher = hasContentBehindLauncher;
+ }
+
+ protected void applyDepthAndBlur() {
+ float depth = mDepth;
+ IBinder windowToken = mLauncher.getRootView().getWindowToken();
+ if (windowToken != null) {
+ mWallpaperManager.setWallpaperZoomOut(windowToken, depth);
+ }
+
+ if (!BlurUtils.supportsBlursOnWindows()) {
+ return;
+ }
+ if (mSurface == null || !mSurface.isValid()) {
+ return;
+ }
+ boolean hasOpaqueBg = mLauncher.getScrimView().isFullyOpaque();
+ boolean isSurfaceOpaque = !mHasContentBehindLauncher && hasOpaqueBg;
+
+ mCurrentBlur = !mCrossWindowBlursEnabled || hasOpaqueBg
+ ? 0 : (int) (depth * mMaxBlurRadius);
+ SurfaceControl.Transaction transaction = new SurfaceControl.Transaction()
+ .setBackgroundBlurRadius(mSurface, mCurrentBlur)
+ .setOpaque(mSurface, isSurfaceOpaque);
+
+ // Set early wake-up flags when we know we're executing an expensive operation, this way
+ // SurfaceFlinger will adjust its internal offsets to avoid jank.
+ boolean wantsEarlyWakeUp = depth > 0 && depth < 1;
+ if (wantsEarlyWakeUp && !mInEarlyWakeUp) {
+ transaction.setEarlyWakeupStart();
+ mInEarlyWakeUp = true;
+ } else if (!wantsEarlyWakeUp && mInEarlyWakeUp) {
+ transaction.setEarlyWakeupEnd();
+ mInEarlyWakeUp = false;
+ }
+
+ AttachedSurfaceControl rootSurfaceControl =
+ mLauncher.getRootView().getRootSurfaceControl();
+ if (rootSurfaceControl != null) {
+ rootSurfaceControl.applyTransactionOnDraw(transaction);
+ }
+ }
+
+ protected void setDepth(float depth) {
+ depth = Utilities.boundToRange(depth, 0, 1);
+ // Round out the depth to dedupe frequent, non-perceptable updates
+ int depthI = (int) (depth * 256);
+ float depthF = depthI / 256f;
+ if (Float.compare(mDepth, depthF) == 0) {
+ return;
+ }
+ mDepth = depthF;
+ applyDepthAndBlur();
+ }
+
+ /**
+ * Sets the specified app target surface to apply the blur to.
+ */
+ protected void setSurface(SurfaceControl surface) {
+ if (mSurface != surface) {
+ mSurface = surface;
+ applyDepthAndBlur();
+ }
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/util/ProxyScreenStatusProvider.java b/quickstep/src/com/android/quickstep/util/ProxyScreenStatusProvider.java
index 3777c65..8f79ccf 100644
--- a/quickstep/src/com/android/quickstep/util/ProxyScreenStatusProvider.java
+++ b/quickstep/src/com/android/quickstep/util/ProxyScreenStatusProvider.java
@@ -39,6 +39,16 @@
mListeners.forEach(ScreenListener::onScreenTurnedOn);
}
+ /** Called when the screen is starting to turn on. */
+ public void onScreenTurningOn() {
+ mListeners.forEach(ScreenListener::onScreenTurningOn);
+ }
+
+ /** Called when the screen is starting to turn off. */
+ public void onScreenTurningOff() {
+ mListeners.forEach(ScreenListener::onScreenTurningOff);
+ }
+
@Override
public void addCallback(@NonNull ScreenListener listener) {
mListeners.add(listener);
diff --git a/quickstep/src/com/android/quickstep/util/RectFSpringAnim.java b/quickstep/src/com/android/quickstep/util/RectFSpringAnim.java
index c4909de..68739ba 100644
--- a/quickstep/src/com/android/quickstep/util/RectFSpringAnim.java
+++ b/quickstep/src/com/android/quickstep/util/RectFSpringAnim.java
@@ -214,7 +214,7 @@
* @param context The activity context.
* @param velocityPxPerMs Velocity of swipe in px/ms.
*/
- public void start(Context context, PointF velocityPxPerMs) {
+ public void start(Context context, @Nullable DeviceProfile profile, PointF velocityPxPerMs) {
// Only tell caller that we ended if both x and y animations have ended.
OnAnimationEndListener onXEndListener = ((animation, canceled, centerX, velocityX) -> {
mRectXAnimEnded = true;
@@ -252,7 +252,13 @@
float minVisibleChange = Math.abs(1f / mStartRect.height());
ResourceProvider rp = DynamicResource.provider(context);
float damping = rp.getFloat(R.dimen.swipe_up_rect_scale_damping_ratio);
- float stiffness = rp.getFloat(R.dimen.swipe_up_rect_scale_stiffness);
+
+ // Increase the stiffness for devices where we want the window size to transform quicker.
+ boolean shouldUseHigherStiffness = profile != null
+ && (profile.isLandscape || profile.isTablet);
+ float stiffness = shouldUseHigherStiffness
+ ? rp.getFloat(R.dimen.swipe_up_rect_scale_higher_stiffness)
+ : rp.getFloat(R.dimen.swipe_up_rect_scale_stiffness);
mRectScaleAnim = new SpringAnimation(this, RECT_SCALE_PROGRESS)
.setSpring(new SpringForce(1f)
diff --git a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
index d2a2f36..0ca5574 100644
--- a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
+++ b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
@@ -242,8 +242,9 @@
@Override
public void startAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
@NonNull SurfaceControl.Transaction t, @NonNull Runnable finishCallback) {
- TaskViewUtils.composeRecentsSplitLaunchAnimator(mInitialTaskId,
- mInitialTaskPendingIntent, mSecondTaskId, info, t, () -> {
+ TaskViewUtils.composeRecentsSplitLaunchAnimator(mLaunchingTaskView, mStateManager,
+ mDepthController, mInitialTaskId, mInitialTaskPendingIntent, mSecondTaskId,
+ info, t, () -> {
finishCallback.run();
if (mSuccessCallback != null) {
mSuccessCallback.accept(true);
diff --git a/quickstep/tests/src/com/android/quickstep/DeviceProfileTest.kt b/quickstep/tests/src/com/android/quickstep/DeviceProfileTest.kt
index 1208a2a..45a342a 100644
--- a/quickstep/tests/src/com/android/quickstep/DeviceProfileTest.kt
+++ b/quickstep/tests/src/com/android/quickstep/DeviceProfileTest.kt
@@ -110,7 +110,7 @@
"\tnumShownHotseatIcons: 4\n" +
"\thotseatBorderSpace: 95.0px (36.190475dp)\n" +
"\tisQsbInline: false\n" +
- "\tqsbWidth: 913.0px (347.8095dp)\n" +
+ "\thotseatQsbWidth: 913.0px (347.8095dp)\n" +
"\tisTaskbarPresent:false\n" +
"\tisTaskbarPresentInApps:false\n" +
"\ttaskbarSize: 0.0px (0.0dp)\n" +
@@ -229,7 +229,7 @@
"\tnumShownHotseatIcons: 4\n" +
"\thotseatBorderSpace: 95.0px (36.190475dp)\n" +
"\tisQsbInline: false\n" +
- "\tqsbWidth: 913.0px (347.8095dp)\n" +
+ "\thotseatQsbWidth: 913.0px (347.8095dp)\n" +
"\tisTaskbarPresent:false\n" +
"\tisTaskbarPresentInApps:false\n" +
"\ttaskbarSize: 0.0px (0.0dp)\n" +
@@ -338,18 +338,18 @@
"\thotseatBarBottomSpacePx: 80.0px (40.0dp)\n" +
"\thotseatBarSidePaddingStartPx: 0.0px (0.0dp)\n" +
"\thotseatBarSidePaddingEndPx: 0.0px (0.0dp)\n" +
- "\thotseatBarEndOffset: 597.0px (298.5dp)\n" +
+ "\thotseatBarEndOffset: 705.0px (352.5dp)\n" +
"\thotseatQsbSpace: 64.0px (32.0dp)\n" +
"\thotseatQsbHeight: 126.0px (63.0dp)\n" +
"\tspringLoadedHotseatBarTopMarginPx: 128.0px (64.0dp)\n" +
"\tgetHotseatLayoutPadding(context).top: -8.0px (-4.0dp)\n" +
"\tgetHotseatLayoutPadding(context).bottom: 73.0px (36.5dp)\n" +
- "\tgetHotseatLayoutPadding(context).left: 959.0px (479.5dp)\n" +
- "\tgetHotseatLayoutPadding(context).right: 597.0px (298.5dp)\n" +
- "\tnumShownHotseatIcons: 5\n" +
- "\thotseatBorderSpace: 101.0px (50.5dp)\n" +
+ "\tgetHotseatLayoutPadding(context).left: 954.0px (477.0dp)\n" +
+ "\tgetHotseatLayoutPadding(context).right: 705.0px (352.5dp)\n" +
+ "\tnumShownHotseatIcons: 6\n" +
+ "\thotseatBorderSpace: 36.0px (18.0dp)\n" +
"\tisQsbInline: true\n" +
- "\tqsbWidth: 855.0px (427.5dp)\n" +
+ "\thotseatQsbWidth: 619.0px (309.5dp)\n" +
"\tisTaskbarPresent:true\n" +
"\tisTaskbarPresentInApps:true\n" +
"\ttaskbarSize: 120.0px (60.0dp)\n" +
@@ -469,7 +469,7 @@
"\tnumShownHotseatIcons: 6\n" +
"\thotseatBorderSpace: 100.0px (50.0dp)\n" +
"\tisQsbInline: true\n" +
- "\tqsbWidth: 640.0px (320.0dp)\n" +
+ "\thotseatQsbWidth: 640.0px (320.0dp)\n" +
"\tisTaskbarPresent:true\n" +
"\tisTaskbarPresentInApps:true\n" +
"\ttaskbarSize: 120.0px (60.0dp)\n" +
@@ -560,8 +560,8 @@
"\tfolderCellLayoutBorderSpacePx Horizontal: 0.0px (0.0dp)\n" +
"\tfolderCellLayoutBorderSpacePx Vertical: 0.0px (0.0dp)\n" +
"\tbottomSheetTopPadding: 704.0px (352.0dp)\n" +
- "\tallAppsShiftRange: 1856.0px (928.0dp)\n" +
- "\tallAppsTopPadding: 704.0px (352.0dp)\n" +
+ "\tallAppsShiftRange: 1936.0px (968.0dp)\n" +
+ "\tallAppsTopPadding: 624.0px (312.0dp)\n" +
"\tallAppsIconSizePx: 120.0px (60.0dp)\n" +
"\tallAppsIconTextSizePx: 28.0px (14.0dp)\n" +
"\tallAppsIconDrawablePaddingPx: 14.0px (7.0dp)\n" +
@@ -578,18 +578,18 @@
"\thotseatBarBottomSpacePx: 72.0px (36.0dp)\n" +
"\thotseatBarSidePaddingStartPx: 0.0px (0.0dp)\n" +
"\thotseatBarSidePaddingEndPx: 0.0px (0.0dp)\n" +
- "\thotseatBarEndOffset: 460.0px (230.0dp)\n" +
+ "\thotseatBarEndOffset: 558.0px (279.0dp)\n" +
"\thotseatQsbSpace: 64.0px (32.0dp)\n" +
"\thotseatQsbHeight: 126.0px (63.0dp)\n" +
"\tspringLoadedHotseatBarTopMarginPx: 216.0px (108.0dp)\n" +
"\tgetHotseatLayoutPadding(context).top: 158.0px (79.0dp)\n" +
"\tgetHotseatLayoutPadding(context).bottom: 65.0px (32.5dp)\n" +
- "\tgetHotseatLayoutPadding(context).left: 76.0px (38.0dp)\n" +
- "\tgetHotseatLayoutPadding(context).right: 460.0px (230.0dp)\n" +
+ "\tgetHotseatLayoutPadding(context).left: 150.0px (75.0dp)\n" +
+ "\tgetHotseatLayoutPadding(context).right: 558.0px (279.0dp)\n" +
"\tnumShownHotseatIcons: 5\n" +
- "\thotseatBorderSpace: 116.0px (58.0dp)\n" +
+ "\thotseatBorderSpace: 73.0px (36.5dp)\n" +
"\tisQsbInline: false\n" +
- "\tqsbWidth: 1300.0px (650.0dp)\n" +
+ "\thotseatQsbWidth: 1300.0px (650.0dp)\n" +
"\tisTaskbarPresent:true\n" +
"\tisTaskbarPresentInApps:true\n" +
"\ttaskbarSize: 120.0px (60.0dp)\n" +
@@ -680,8 +680,8 @@
"\tfolderCellLayoutBorderSpacePx Horizontal: 0.0px (0.0dp)\n" +
"\tfolderCellLayoutBorderSpacePx Vertical: 0.0px (0.0dp)\n" +
"\tbottomSheetTopPadding: 704.0px (352.0dp)\n" +
- "\tallAppsShiftRange: 1856.0px (928.0dp)\n" +
- "\tallAppsTopPadding: 704.0px (352.0dp)\n" +
+ "\tallAppsShiftRange: 1936.0px (968.0dp)\n" +
+ "\tallAppsTopPadding: 624.0px (312.0dp)\n" +
"\tallAppsIconSizePx: 120.0px (60.0dp)\n" +
"\tallAppsIconTextSizePx: 28.0px (14.0dp)\n" +
"\tallAppsIconDrawablePaddingPx: 14.0px (7.0dp)\n" +
@@ -709,7 +709,7 @@
"\tnumShownHotseatIcons: 6\n" +
"\thotseatBorderSpace: 116.0px (58.0dp)\n" +
"\tisQsbInline: false\n" +
- "\tqsbWidth: 1300.0px (650.0dp)\n" +
+ "\thotseatQsbWidth: 1300.0px (650.0dp)\n" +
"\tisTaskbarPresent:true\n" +
"\tisTaskbarPresentInApps:true\n" +
"\ttaskbarSize: 120.0px (60.0dp)\n" +
@@ -824,12 +824,12 @@
"\tspringLoadedHotseatBarTopMarginPx: 116.0px (44.190475dp)\n" +
"\tgetHotseatLayoutPadding(context).top: 197.0px (75.04762dp)\n" +
"\tgetHotseatLayoutPadding(context).bottom: 43.0px (16.380953dp)\n" +
- "\tgetHotseatLayoutPadding(context).left: 216.0px (82.28571dp)\n" +
+ "\tgetHotseatLayoutPadding(context).left: 106.0px (40.38095dp)\n" +
"\tgetHotseatLayoutPadding(context).right: 744.0px (283.42856dp)\n" +
"\tnumShownHotseatIcons: 6\n" +
- "\thotseatBorderSpace: 61.0px (23.238094dp)\n" +
+ "\thotseatBorderSpace: 83.0px (31.619047dp)\n" +
"\tisQsbInline: false\n" +
- "\tqsbWidth: 1467.0px (558.8571dp)\n" +
+ "\thotseatQsbWidth: 1467.0px (558.8571dp)\n" +
"\tisTaskbarPresent:true\n" +
"\tisTaskbarPresentInApps:true\n" +
"\ttaskbarSize: 158.0px (60.190475dp)\n" +
@@ -949,7 +949,7 @@
"\tnumShownHotseatIcons: 6\n" +
"\thotseatBorderSpace: 105.0px (40.0dp)\n" +
"\tisQsbInline: false\n" +
- "\tqsbWidth: 1467.0px (558.8571dp)\n" +
+ "\thotseatQsbWidth: 1467.0px (558.8571dp)\n" +
"\tisTaskbarPresent:true\n" +
"\tisTaskbarPresentInApps:true\n" +
"\ttaskbarSize: 158.0px (60.190475dp)\n" +
@@ -1064,12 +1064,12 @@
"\tspringLoadedHotseatBarTopMarginPx: 171.0px (65.14286dp)\n" +
"\tgetHotseatLayoutPadding(context).top: 219.0px (83.42857dp)\n" +
"\tgetHotseatLayoutPadding(context).bottom: 87.0px (33.142857dp)\n" +
- "\tgetHotseatLayoutPadding(context).left: 128.0px (48.761906dp)\n" +
+ "\tgetHotseatLayoutPadding(context).left: 78.0px (29.714285dp)\n" +
"\tgetHotseatLayoutPadding(context).right: 660.0px (251.42857dp)\n" +
"\tnumShownHotseatIcons: 6\n" +
- "\thotseatBorderSpace: 47.0px (17.904762dp)\n" +
+ "\thotseatBorderSpace: 57.0px (21.714285dp)\n" +
"\tisQsbInline: false\n" +
- "\tqsbWidth: 1236.0px (470.85715dp)\n" +
+ "\thotseatQsbWidth: 1236.0px (470.85715dp)\n" +
"\tisTaskbarPresent:true\n" +
"\tisTaskbarPresentInApps:true\n" +
"\ttaskbarSize: 158.0px (60.190475dp)\n" +
@@ -1189,7 +1189,7 @@
"\tnumShownHotseatIcons: 6\n" +
"\thotseatBorderSpace: 84.0px (32.0dp)\n" +
"\tisQsbInline: false\n" +
- "\tqsbWidth: 1236.0px (470.85715dp)\n" +
+ "\thotseatQsbWidth: 1236.0px (470.85715dp)\n" +
"\tisTaskbarPresent:true\n" +
"\tisTaskbarPresentInApps:true\n" +
"\ttaskbarSize: 158.0px (60.190475dp)\n" +
@@ -1308,7 +1308,7 @@
"\tnumShownHotseatIcons: 4\n" +
"\thotseatBorderSpace: 0.0px (0.0dp)\n" +
"\tisQsbInline: false\n" +
- "\tqsbWidth: 1525.0px (580.9524dp)\n" +
+ "\thotseatQsbWidth: 1525.0px (580.9524dp)\n" +
"\tisTaskbarPresent:false\n" +
"\tisTaskbarPresentInApps:false\n" +
"\ttaskbarSize: 0.0px (0.0dp)\n" +
@@ -1427,7 +1427,7 @@
"\tnumShownHotseatIcons: 4\n" +
"\thotseatBorderSpace: 0.0px (0.0dp)\n" +
"\tisQsbInline: false\n" +
- "\tqsbWidth: 1621.0px (617.5238dp)\n" +
+ "\thotseatQsbWidth: 1621.0px (617.5238dp)\n" +
"\tisTaskbarPresent:false\n" +
"\tisTaskbarPresentInApps:false\n" +
"\ttaskbarSize: 0.0px (0.0dp)\n" +
diff --git a/quickstep/tests/src/com/android/quickstep/HotseatWidthCalculationTest.kt b/quickstep/tests/src/com/android/quickstep/HotseatWidthCalculationTest.kt
new file mode 100644
index 0000000..3967f75
--- /dev/null
+++ b/quickstep/tests/src/com/android/quickstep/HotseatWidthCalculationTest.kt
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2022 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.quickstep
+
+import android.graphics.Rect
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.launcher3.DeviceProfileBaseTest
+import com.android.launcher3.util.WindowBounds
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class HotseatWidthCalculationTest : DeviceProfileBaseTest() {
+
+ /**
+ * This is a case when after setting the hotseat, the space needs to be recalculated
+ * but it doesn't need to change QSB width or remove icons
+ */
+ @Test
+ fun distribute_border_space_when_space_is_enough_portrait() {
+ initializeVarsForTablet(isGestureMode = false)
+ windowBounds = WindowBounds(Rect(0, 0, 1800, 2560), Rect(0, 104, 0, 0))
+ val dp = newDP()
+ dp.isTaskbarPresentInApps = true
+
+ assertThat(dp.hotseatBarEndOffset).isEqualTo(558)
+ assertThat(dp.numShownHotseatIcons).isEqualTo(6)
+ assertThat(dp.hotseatBorderSpace).isEqualTo(69)
+
+ assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(176)
+ assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(558)
+
+ assertThat(dp.isQsbInline).isFalse()
+ assertThat(dp.hotseatQsbWidth).isEqualTo(1445)
+ }
+
+ /**
+ * This is a case when after setting the hotseat, and recalculating spaces
+ * it still needs to remove icons for everything to fit
+ */
+ @Test
+ fun decrease_num_of_icons_when_not_enough_space_portrait() {
+ initializeVarsForTablet(isGestureMode = false)
+ windowBounds = WindowBounds(Rect(0, 0, 1300, 2560), Rect(0, 104, 0, 0))
+ val dp = newDP()
+ dp.isTaskbarPresentInApps = true
+
+ assertThat(dp.hotseatBarEndOffset).isEqualTo(558)
+ assertThat(dp.numShownHotseatIcons).isEqualTo(4)
+ assertThat(dp.hotseatBorderSpace).isEqualTo(76)
+
+ assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(122)
+ assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(558)
+
+ assertThat(dp.isQsbInline).isFalse()
+ assertThat(dp.hotseatQsbWidth).isEqualTo(1058)
+ }
+
+ /**
+ * This is a case when after setting the hotseat, the space needs to be recalculated
+ * but it doesn't need to change QSB width or remove icons
+ */
+ @Test
+ fun distribute_border_space_when_space_is_enough_landscape() {
+ initializeVarsForTwoPanel(isGestureMode = false, isLandscape = true)
+ val dp = newDP()
+ dp.isTaskbarPresentInApps = true
+
+ assertThat(dp.hotseatBarEndOffset).isEqualTo(744)
+ assertThat(dp.numShownHotseatIcons).isEqualTo(6)
+ assertThat(dp.hotseatBorderSpace).isEqualTo(83)
+
+ assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(106)
+ assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(744)
+
+ assertThat(dp.isQsbInline).isFalse()
+ assertThat(dp.hotseatQsbWidth).isEqualTo(1467)
+ }
+
+ /**
+ * This is a case when the hotseat spans a certain amount of columns
+ * and the nav buttons push the hotseat to the side, but not enough to change the border space.
+ */
+ @Test
+ fun nav_buttons_dont_interfere_with_required_hotseat_width() {
+ initializeVarsForTablet(isGestureMode = false, isLandscape = true)
+ inv?.apply {
+ hotseatColumnSpan = IntArray(4) { 4 }
+ inlineQsb = BooleanArray(4) { false }
+ }
+ val dp = newDP()
+ dp.isTaskbarPresentInApps = true
+
+ assertThat(dp.hotseatBarEndOffset).isEqualTo(705)
+ assertThat(dp.numShownHotseatIcons).isEqualTo(6)
+ assertThat(dp.hotseatBorderSpace).isEqualTo(108)
+
+ assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(631)
+ assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(705)
+
+ assertThat(dp.isQsbInline).isFalse()
+ assertThat(dp.hotseatQsbWidth).isEqualTo(1227)
+ }
+
+ /**
+ * This is a case when after setting the hotseat, the QSB width needs to be changed to fit
+ */
+ @Test
+ fun decrease_qsb_when_not_enough_space_landscape() {
+ initializeVarsForTablet(isGestureMode = false, isLandscape = true)
+ windowBounds = WindowBounds(Rect(0, 0, 2460, 1600), Rect(0, 104, 0, 0))
+ val dp = newDP()
+ dp.isTaskbarPresentInApps = true
+
+ assertThat(dp.hotseatBarEndOffset).isEqualTo(705)
+ assertThat(dp.numShownHotseatIcons).isEqualTo(6)
+ assertThat(dp.hotseatBorderSpace).isEqualTo(36)
+
+ assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(884)
+ assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(705)
+
+ assertThat(dp.isQsbInline).isTrue()
+ assertThat(dp.hotseatQsbWidth).isEqualTo(559)
+ }
+
+ /**
+ * This is a case when after setting the hotseat, changing QSB width, and recalculating spaces
+ * it still needs to remove icons for everything to fit
+ */
+ @Test
+ fun decrease_num_of_icons_when_not_enough_space_landscape() {
+ initializeVarsForTablet(isGestureMode = false, isLandscape = true)
+ windowBounds = WindowBounds(Rect(0, 0, 2260, 1600), Rect(0, 104, 0, 0))
+ val dp = newDP()
+ dp.isTaskbarPresentInApps = true
+
+ assertThat(dp.hotseatBarEndOffset).isEqualTo(705)
+ assertThat(dp.numShownHotseatIcons).isEqualTo(5)
+ assertThat(dp.hotseatBorderSpace).isEqualTo(56)
+
+ assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(801)
+ assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(705)
+
+ assertThat(dp.isQsbInline).isTrue()
+ assertThat(dp.hotseatQsbWidth).isEqualTo(480)
+ }
+}
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
index 4bd627a..159b65f 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
@@ -181,6 +181,21 @@
@Test
@PortraitLandscape
+ public void testSplitFromOverview() {
+ assumeTrue(!mLauncher.isTablet());
+
+ startTestActivity(2);
+ startTestActivity(3);
+
+ mLauncher.goHome().switchToOverview().getCurrentTask()
+ .tapMenu()
+ .tapSplitMenuItem()
+ .getTestActivityTask(2)
+ .open();
+ }
+
+ @Test
+ @PortraitLandscape
public void testSplitFromOverviewForTablet() {
assumeTrue(mLauncher.isTablet());
diff --git a/res/drawable/ic_block_shadow.xml b/res/drawable/ic_block_shadow.xml
deleted file mode 100644
index 045fe8d..0000000
--- a/res/drawable/ic_block_shadow.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2020 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<com.android.launcher3.graphics.ShadowDrawable
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:src="@drawable/ic_block_no_shadow"
- android:elevation="@dimen/drop_target_shadow_elevation" />
diff --git a/res/drawable/ic_remove_shadow.xml b/res/drawable/ic_remove_shadow.xml
deleted file mode 100644
index 48abc10..0000000
--- a/res/drawable/ic_remove_shadow.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<com.android.launcher3.graphics.ShadowDrawable
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:src="@drawable/ic_remove_no_shadow"
- android:elevation="@dimen/drop_target_shadow_elevation" />
diff --git a/res/drawable/ic_setup_shadow.xml b/res/drawable/ic_setup_shadow.xml
deleted file mode 100644
index 10aeee6..0000000
--- a/res/drawable/ic_setup_shadow.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<com.android.launcher3.graphics.ShadowDrawable
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:src="@drawable/ic_setting"
- android:elevation="@dimen/drop_target_shadow_elevation" />
diff --git a/res/drawable/ic_uninstall_shadow.xml b/res/drawable/ic_uninstall_shadow.xml
deleted file mode 100644
index b441b0e..0000000
--- a/res/drawable/ic_uninstall_shadow.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<com.android.launcher3.graphics.ShadowDrawable
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:src="@drawable/ic_uninstall_no_shadow"
- android:elevation="@dimen/drop_target_shadow_elevation" />
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index 445bfda..a699667 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Deursoek programme"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Laai tans programme …"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Kon geen programme kry wat by \"<xliff:g id="QUERY">%1$s</xliff:g>\" pas nie"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Soek meer programme"</string>
<string name="label_application" msgid="8531721983832654978">"Program"</string>
<string name="all_apps_label" msgid="5015784846527570951">"Alle programme"</string>
<string name="notifications_header" msgid="1404149926117359025">"Kennisgewings"</string>
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index 474cd9f..b7d4a7d 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"መተግበሪያዎችን ፈልግ"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"መተግበሪያዎችን በመጫን ላይ…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"ከ«<xliff:g id="QUERY">%1$s</xliff:g>» ጋር የሚዛመዱ ምንም መተግበሪያዎች አልተገኙም"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"ተጨማሪ መተግበሪያዎች ይፈልጉ"</string>
<string name="label_application" msgid="8531721983832654978">"መተግበሪያ"</string>
<string name="all_apps_label" msgid="5015784846527570951">"ሁሉም መተግበሪያዎች"</string>
<string name="notifications_header" msgid="1404149926117359025">"ማሳወቂያዎች"</string>
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index a4f7c03..e075559 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"بحث في التطبيقات"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"جارٍ تحميل التطبيقات…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"لم يتم العثور على أي تطبيقات تتطابق مع \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"البحث عن مزيد من التطبيقات"</string>
<string name="label_application" msgid="8531721983832654978">"تطبيق"</string>
<string name="all_apps_label" msgid="5015784846527570951">"جميع التطبيقات"</string>
<string name="notifications_header" msgid="1404149926117359025">"الإشعارات"</string>
diff --git a/res/values-as/strings.xml b/res/values-as/strings.xml
index beb9619..ba14e97 100644
--- a/res/values-as/strings.xml
+++ b/res/values-as/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"এপসমূহ সন্ধান কৰক"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"এপসমূহ ল’ড কৰি থকা হৈছে…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\"ৰ সৈতে মিলা কোনো এপ্ বিচাৰি পোৱা নগ\'ল"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"আৰু অধিক এপবোৰ সন্ধান কৰক"</string>
<string name="label_application" msgid="8531721983832654978">"এপ্"</string>
<string name="all_apps_label" msgid="5015784846527570951">"আটাইবোৰ এপ্"</string>
<string name="notifications_header" msgid="1404149926117359025">"জাননীসমূহ"</string>
@@ -73,7 +72,7 @@
<string name="all_apps_button_work_label" msgid="7270707118948892488">"কৰ্মস্থানৰ এপৰ তালিকা"</string>
<string name="remove_drop_target_label" msgid="7812859488053230776">"আঁতৰাওক"</string>
<string name="uninstall_drop_target_label" msgid="4722034217958379417">"আনইনষ্টল কৰক"</string>
- <string name="app_info_drop_target_label" msgid="692894985365717661">"এপ সম্পৰ্কীয় তথ্য"</string>
+ <string name="app_info_drop_target_label" msgid="692894985365717661">"এপ্ সম্পৰ্কীয় তথ্য"</string>
<string name="install_drop_target_label" msgid="2539096853673231757">"ইনষ্টল কৰক"</string>
<string name="dismiss_prediction_label" msgid="3357562989568808658">"এপৰ পৰামৰ্শ নিদিব"</string>
<string name="pin_prediction" msgid="4196423321649756498">"পূৰ্বানুমান কৰা এপ্টো পিন কৰক"</string>
diff --git a/res/values-az/strings.xml b/res/values-az/strings.xml
index 93e6f08..2e07405 100644
--- a/res/values-az/strings.xml
+++ b/res/values-az/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Tətbiqləri axtarın"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Tətbiqlər yüklənir…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"<xliff:g id="QUERY">%1$s</xliff:g> sorğusuna uyğun tətbiq tapılmadı"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Daha çox tətbiq üçün axtarış edin"</string>
<string name="label_application" msgid="8531721983832654978">"Tətbiq"</string>
<string name="all_apps_label" msgid="5015784846527570951">"Bütün tətbiqlər"</string>
<string name="notifications_header" msgid="1404149926117359025">"Bildirişlər"</string>
diff --git a/res/values-b+sr+Latn/strings.xml b/res/values-b+sr+Latn/strings.xml
index ded4dc9..cc6e908 100644
--- a/res/values-b+sr+Latn/strings.xml
+++ b/res/values-b+sr+Latn/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Pretražite aplikacije"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Aplikacije se učitavaju…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Nije pronađena nijedna aplikacija za „<xliff:g id="QUERY">%1$s</xliff:g>“"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Pretraži još aplikacija"</string>
<string name="label_application" msgid="8531721983832654978">"Aplikacija"</string>
<string name="all_apps_label" msgid="5015784846527570951">"Sve aplikacije"</string>
<string name="notifications_header" msgid="1404149926117359025">"Obaveštenja"</string>
diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml
index 7fa8341..69a16ba 100644
--- a/res/values-be/strings.xml
+++ b/res/values-be/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Пошук праграм"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Праграмы загружаюцца…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Праграм, якія адпавядаюць запыту \"<xliff:g id="QUERY">%1$s</xliff:g>\", не знойдзена"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Шукаць іншыя праграмы"</string>
<string name="label_application" msgid="8531721983832654978">"Праграма"</string>
<string name="all_apps_label" msgid="5015784846527570951">"Усе праграмы"</string>
<string name="notifications_header" msgid="1404149926117359025">"Апавяшчэнні"</string>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index 62b7796..549c8ea 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Търсене в приложенията"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Приложенията се зареждат…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Няма намерени приложения, съответстващи на „<xliff:g id="QUERY">%1$s</xliff:g>“"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Търсене на още приложения"</string>
<string name="label_application" msgid="8531721983832654978">"Приложение"</string>
<string name="all_apps_label" msgid="5015784846527570951">"Всички приложения"</string>
<string name="notifications_header" msgid="1404149926117359025">"Известия"</string>
diff --git a/res/values-bn/strings.xml b/res/values-bn/strings.xml
index 1be272b..9683182 100644
--- a/res/values-bn/strings.xml
+++ b/res/values-bn/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"অ্যাপ খুঁজুন"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"অ্যাপ লোড হচ্ছে…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" এর সাথে মেলে এমন কোনো অ্যাপ পাওয়া যায়নি"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"আরও অ্যাপ্লিকেশানের জন্য খুঁজুন"</string>
<string name="label_application" msgid="8531721983832654978">"অ্যাপ"</string>
<string name="all_apps_label" msgid="5015784846527570951">"সব অ্যাপ"</string>
<string name="notifications_header" msgid="1404149926117359025">"বিজ্ঞপ্তি"</string>
diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml
index 639b6b3..f99525f 100644
--- a/res/values-bs/strings.xml
+++ b/res/values-bs/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Pretražite aplikacije"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Aplikacije se učitavaju…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Nije pronađena nijedna aplikacija za upit \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Pretraži više aplikacija"</string>
<string name="label_application" msgid="8531721983832654978">"Aplikacija"</string>
<string name="all_apps_label" msgid="5015784846527570951">"Sve aplikacije"</string>
<string name="notifications_header" msgid="1404149926117359025">"Obavještenja"</string>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index ee35fd3..d8ede15 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Cerca aplicacions"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"S\'estan carregant les aplicacions…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"No s\'ha trobat cap aplicació que coincideixi amb \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Cerca més aplicacions"</string>
<string name="label_application" msgid="8531721983832654978">"Aplicació"</string>
<string name="all_apps_label" msgid="5015784846527570951">"Totes les aplicacions"</string>
<string name="notifications_header" msgid="1404149926117359025">"Notificacions"</string>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index 1b418c6..e4d46e4 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Hledat v aplikacích"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Načítání aplikací…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Dotazu „<xliff:g id="QUERY">%1$s</xliff:g>“ neodpovídají žádné aplikace"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Vyhledat další aplikace"</string>
<string name="label_application" msgid="8531721983832654978">"Aplikace"</string>
<string name="all_apps_label" msgid="5015784846527570951">"Všechny aplikace"</string>
<string name="notifications_header" msgid="1404149926117359025">"Oznámení"</string>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index 5cdadcd..4da7b84 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Søg efter apps"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Indlæser apps…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Der blev ikke fundet nogen apps, som matcher \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Søg efter flere apps"</string>
<string name="label_application" msgid="8531721983832654978">"App"</string>
<string name="all_apps_label" msgid="5015784846527570951">"Alle apps"</string>
<string name="notifications_header" msgid="1404149926117359025">"Notifikationer"</string>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index b75ef9d..3c2514f 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Apps finden"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Apps werden geladen…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Keine Apps für \"<xliff:g id="QUERY">%1$s</xliff:g>\" gefunden"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Weitere Apps suchen"</string>
<string name="label_application" msgid="8531721983832654978">"App"</string>
<string name="all_apps_label" msgid="5015784846527570951">"Alle Apps"</string>
<string name="notifications_header" msgid="1404149926117359025">"Benachrichtigungen"</string>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index 99c9e23..ae9a8fd 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Αναζήτηση εφαρμογών"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Φόρτωση εφαρμογών…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Δεν βρέθηκαν εφαρμογές αντιστοίχισης για \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Αναζήτηση περισσότερων εφαρμογών"</string>
<string name="label_application" msgid="8531721983832654978">"Εφαρμογή"</string>
<string name="all_apps_label" msgid="5015784846527570951">"Όλες οι εφαρμογές"</string>
<string name="notifications_header" msgid="1404149926117359025">"Ειδοποιήσεις"</string>
diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml
index 97f0528..4f15eb5 100644
--- a/res/values-en-rAU/strings.xml
+++ b/res/values-en-rAU/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Search apps"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Loading apps…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"No apps found matching \'<xliff:g id="QUERY">%1$s</xliff:g>\'"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Search for more apps"</string>
<string name="label_application" msgid="8531721983832654978">"App"</string>
<string name="all_apps_label" msgid="5015784846527570951">"All apps"</string>
<string name="notifications_header" msgid="1404149926117359025">"Notifications"</string>
diff --git a/res/values-en-rCA/strings.xml b/res/values-en-rCA/strings.xml
index 97f0528..4f15eb5 100644
--- a/res/values-en-rCA/strings.xml
+++ b/res/values-en-rCA/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Search apps"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Loading apps…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"No apps found matching \'<xliff:g id="QUERY">%1$s</xliff:g>\'"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Search for more apps"</string>
<string name="label_application" msgid="8531721983832654978">"App"</string>
<string name="all_apps_label" msgid="5015784846527570951">"All apps"</string>
<string name="notifications_header" msgid="1404149926117359025">"Notifications"</string>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index 97f0528..4f15eb5 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Search apps"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Loading apps…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"No apps found matching \'<xliff:g id="QUERY">%1$s</xliff:g>\'"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Search for more apps"</string>
<string name="label_application" msgid="8531721983832654978">"App"</string>
<string name="all_apps_label" msgid="5015784846527570951">"All apps"</string>
<string name="notifications_header" msgid="1404149926117359025">"Notifications"</string>
diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml
index 97f0528..4f15eb5 100644
--- a/res/values-en-rIN/strings.xml
+++ b/res/values-en-rIN/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Search apps"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Loading apps…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"No apps found matching \'<xliff:g id="QUERY">%1$s</xliff:g>\'"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Search for more apps"</string>
<string name="label_application" msgid="8531721983832654978">"App"</string>
<string name="all_apps_label" msgid="5015784846527570951">"All apps"</string>
<string name="notifications_header" msgid="1404149926117359025">"Notifications"</string>
diff --git a/res/values-en-rXC/strings.xml b/res/values-en-rXC/strings.xml
index 4977beb..e644c23 100644
--- a/res/values-en-rXC/strings.xml
+++ b/res/values-en-rXC/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Search apps"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Loading apps…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"No apps found matching \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Search for more apps"</string>
<string name="label_application" msgid="8531721983832654978">"App"</string>
<string name="all_apps_label" msgid="5015784846527570951">"All apps"</string>
<string name="notifications_header" msgid="1404149926117359025">"Notifications"</string>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index 3ed312b..0bc8f4f 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Buscar apps"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Cargando apps…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"No hay apps que coincidan con \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Buscar más apps"</string>
<string name="label_application" msgid="8531721983832654978">"App"</string>
<string name="all_apps_label" msgid="5015784846527570951">"Todas las apps"</string>
<string name="notifications_header" msgid="1404149926117359025">"Notificaciones"</string>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index 567ff0d..4045ad3 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Buscar aplicaciones"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Cargando aplicaciones…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"No se han encontrado aplicaciones que contengan \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Buscar más aplicaciones"</string>
<string name="label_application" msgid="8531721983832654978">"Aplicación"</string>
<string name="all_apps_label" msgid="5015784846527570951">"Todas las aplicaciones"</string>
<string name="notifications_header" msgid="1404149926117359025">"Notificaciones"</string>
diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml
index c34a003..effd140 100644
--- a/res/values-et/strings.xml
+++ b/res/values-et/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Otsige rakendusi"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Rakenduste laadimine …"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Päringule „<xliff:g id="QUERY">%1$s</xliff:g>” ei vastanud ükski rakendus"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Otsi rohkem rakendusi"</string>
<string name="label_application" msgid="8531721983832654978">"Rakendus"</string>
<string name="all_apps_label" msgid="5015784846527570951">"Kõik rakendused"</string>
<string name="notifications_header" msgid="1404149926117359025">"Märguanded"</string>
diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml
index 55e0c3c..9e2d9a4 100644
--- a/res/values-eu/strings.xml
+++ b/res/values-eu/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Bilatu aplikazioetan"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Aplikazioak kargatzen…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Ez da aurkitu \"<xliff:g id="QUERY">%1$s</xliff:g>\" bilaketaren emaitzarik"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Bilatu aplikazio gehiago"</string>
<string name="label_application" msgid="8531721983832654978">"Aplikazioa"</string>
<string name="all_apps_label" msgid="5015784846527570951">"Aplikazio guztiak"</string>
<string name="notifications_header" msgid="1404149926117359025">"Jakinarazpenak"</string>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index 12db5bd..a1acda0 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"جستجوی برنامهها"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"درحال بارگیری برنامهها…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"هیچ برنامهای در مطابقت با «<xliff:g id="QUERY">%1$s</xliff:g>» پیدا نشد"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"جستجوی برنامههای بیشتر"</string>
<string name="label_application" msgid="8531721983832654978">"برنامه"</string>
<string name="all_apps_label" msgid="5015784846527570951">"همه برنامهها"</string>
<string name="notifications_header" msgid="1404149926117359025">"اعلانها"</string>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index 135c452..89e4106 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Hae sovelluksia"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Ladataan sovelluksia…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"<xliff:g id="QUERY">%1$s</xliff:g> ei palauttanut sovelluksia."</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Hae lisää sovelluksia"</string>
<string name="label_application" msgid="8531721983832654978">"Sovellus"</string>
<string name="all_apps_label" msgid="5015784846527570951">"Kaikki sovellukset"</string>
<string name="notifications_header" msgid="1404149926117359025">"Ilmoitukset"</string>
diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml
index 446a507..448569d 100644
--- a/res/values-fr-rCA/strings.xml
+++ b/res/values-fr-rCA/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Rechercher dans les applications"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Chargement des applications en cours…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Aucune application trouvée correspondant à « <xliff:g id="QUERY">%1$s</xliff:g> »"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Rechercher plus d\'applications"</string>
<string name="label_application" msgid="8531721983832654978">"Application"</string>
<string name="all_apps_label" msgid="5015784846527570951">"Toutes les applications"</string>
<string name="notifications_header" msgid="1404149926117359025">"Notifications"</string>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index 1d623b1..a6856fc 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Rechercher dans les applications"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Chargement des applications…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Aucune application ne correspond à la requête \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Rechercher plus d\'applications"</string>
<string name="label_application" msgid="8531721983832654978">"Application"</string>
<string name="all_apps_label" msgid="5015784846527570951">"Toutes les applis"</string>
<string name="notifications_header" msgid="1404149926117359025">"Notifications"</string>
diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml
index 256c4d3..045d8d7 100644
--- a/res/values-gl/strings.xml
+++ b/res/values-gl/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Buscar aplicacións"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Cargando aplicacións…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Non se atoparon aplicacións que coincidan con \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Buscar máis aplicacións"</string>
<string name="label_application" msgid="8531721983832654978">"Aplicación"</string>
<string name="all_apps_label" msgid="5015784846527570951">"Todas as aplicacións"</string>
<string name="notifications_header" msgid="1404149926117359025">"Notificacións"</string>
diff --git a/res/values-gu/strings.xml b/res/values-gu/strings.xml
index f1e1996..7288570 100644
--- a/res/values-gu/strings.xml
+++ b/res/values-gu/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"શોધ ઍપ્લિકેશનો"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"ઍપ્લિકેશનો લોડ કરી રહ્યું છે…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\"થી મેળ ખાતી કોઈ ઍપ્લિકેશનો મળી નથી"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"વધુ ઍપ્લિકેશનો શોધો"</string>
<string name="label_application" msgid="8531721983832654978">"ઍપ"</string>
<string name="all_apps_label" msgid="5015784846527570951">"બધી ઍપ"</string>
<string name="notifications_header" msgid="1404149926117359025">"નોટિફિકેશન"</string>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index 1b05040..5e71f33 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ऐप सर्च करें"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"ऐप्लिकेशन लोड हो रहे हैं…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" से मिलता-जुलता कोई ऐप्लिकेशन नहीं मिला"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"और ऐप सर्च करें"</string>
<string name="label_application" msgid="8531721983832654978">"ऐप्लिकेशन"</string>
<string name="all_apps_label" msgid="5015784846527570951">"सभी ऐप्लिकेशन"</string>
<string name="notifications_header" msgid="1404149926117359025">"सूचनाएं"</string>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index 4a0fbe8..a1369e8 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Pretraži aplikacije"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Učitavanje aplikacija…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Nema aplikacija podudarnih s upitom \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Traži više aplikacija"</string>
<string name="label_application" msgid="8531721983832654978">"Aplikacija"</string>
<string name="all_apps_label" msgid="5015784846527570951">"Sve aplikacije"</string>
<string name="notifications_header" msgid="1404149926117359025">"Obavijesti"</string>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index c1e527d..a5d4835 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Alkalmazások keresése"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Alkalmazások betöltése…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Nem található alkalmazás a(z) „<xliff:g id="QUERY">%1$s</xliff:g>” lekérdezésre"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"További alkalmazások keresése"</string>
<string name="label_application" msgid="8531721983832654978">"Alkalmazás"</string>
<string name="all_apps_label" msgid="5015784846527570951">"Összes alkalmazás"</string>
<string name="notifications_header" msgid="1404149926117359025">"Értesítések"</string>
diff --git a/res/values-hy/strings.xml b/res/values-hy/strings.xml
index f0d01f1..44c3a96 100644
--- a/res/values-hy/strings.xml
+++ b/res/values-hy/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Որոնել հավելվածներ"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Հավելվածների բեռնում…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"«<xliff:g id="QUERY">%1$s</xliff:g>» հարցմանը համապատասխանող հավելվածներ չեն գտնվել"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Որոնել այլ հավելվածներ"</string>
<string name="label_application" msgid="8531721983832654978">"Հավելված"</string>
<string name="all_apps_label" msgid="5015784846527570951">"Բոլոր հավելվածները"</string>
<string name="notifications_header" msgid="1404149926117359025">"Ծանուցումներ"</string>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index 1a97a45..e46026e 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Telusuri aplikasi"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Memuat aplikasi…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Tidak ditemukan aplikasi yang cocok dengan \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Telusuri aplikasi lainnya"</string>
<string name="label_application" msgid="8531721983832654978">"Aplikasi"</string>
<string name="all_apps_label" msgid="5015784846527570951">"Semua aplikasi"</string>
<string name="notifications_header" msgid="1404149926117359025">"Notifikasi"</string>
diff --git a/res/values-is/strings.xml b/res/values-is/strings.xml
index a1959f8..92be25b 100644
--- a/res/values-is/strings.xml
+++ b/res/values-is/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Leita í forritum"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Hleður forrit…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Ekki fundust forrit sem samsvara „<xliff:g id="QUERY">%1$s</xliff:g>“"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Leita að fleiri forritum"</string>
<string name="label_application" msgid="8531721983832654978">"Forrit"</string>
<string name="all_apps_label" msgid="5015784846527570951">"Öll forrit"</string>
<string name="notifications_header" msgid="1404149926117359025">"Tilkynningar"</string>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index 302efcb..b5b7add 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Cerca nelle app"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Caricamento delle app…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Nessuna app trovata corrispondente a \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Cerca altre app"</string>
<string name="label_application" msgid="8531721983832654978">"App"</string>
<string name="all_apps_label" msgid="5015784846527570951">"Tutte le app"</string>
<string name="notifications_header" msgid="1404149926117359025">"Notifiche"</string>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index 15e200f..6b4d129 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"חיפוש אפליקציות"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"טעינת אפליקציות מתבצעת…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"לא נמצאו אפליקציות התואמות ל-\"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"חיפוש אפליקציות נוספות"</string>
<string name="label_application" msgid="8531721983832654978">"אפליקציה"</string>
<string name="all_apps_label" msgid="5015784846527570951">"כל האפליקציות"</string>
<string name="notifications_header" msgid="1404149926117359025">"התראות"</string>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index 2fd3ab5..484be1f 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"アプリを検索"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"アプリを読み込んでいます…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"「<xliff:g id="QUERY">%1$s</xliff:g>」に一致するアプリは見つかりませんでした"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"他のアプリを検索"</string>
<string name="label_application" msgid="8531721983832654978">"アプリ"</string>
<string name="all_apps_label" msgid="5015784846527570951">"すべてのアプリ"</string>
<string name="notifications_header" msgid="1404149926117359025">"通知"</string>
diff --git a/res/values-ka/strings.xml b/res/values-ka/strings.xml
index 24f95dd..8437dd8 100644
--- a/res/values-ka/strings.xml
+++ b/res/values-ka/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"აპების ძიება"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"აპები იტვირთება…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"„<xliff:g id="QUERY">%1$s</xliff:g>“-ის თანხვედრი აპები არ მოიძებნა"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"მეტი აპის პოვნა"</string>
<string name="label_application" msgid="8531721983832654978">"აპი"</string>
<string name="all_apps_label" msgid="5015784846527570951">"ყველა აპი"</string>
<string name="notifications_header" msgid="1404149926117359025">"შეტყობინებები"</string>
diff --git a/res/values-kk/strings.xml b/res/values-kk/strings.xml
index 8ed7ec5..ec3ee18 100644
--- a/res/values-kk/strings.xml
+++ b/res/values-kk/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Қолданбаларды іздеу"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Қолданбалар жүктелуде…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" сұрауына сәйкес келетін қолданбалар жоқ"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Қосымша қолданбалар іздеу"</string>
<string name="label_application" msgid="8531721983832654978">"Қолданба"</string>
<string name="all_apps_label" msgid="5015784846527570951">"Барлық қолданба"</string>
<string name="notifications_header" msgid="1404149926117359025">"Хабарландырулар"</string>
diff --git a/res/values-km/strings.xml b/res/values-km/strings.xml
index 306449c..f1c1d08 100644
--- a/res/values-km/strings.xml
+++ b/res/values-km/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ស្វែងរកកម្មវិធី"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"កំពុងផ្ទុកកម្មវិធី…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"រកមិនឃើញកម្មវិធីដែលត្រូវគ្នាជាមួយ \"<xliff:g id="QUERY">%1$s</xliff:g>\" ទេ"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"ស្វែងរកកម្មវិធីច្រើនទៀត"</string>
<string name="label_application" msgid="8531721983832654978">"កម្មវិធី"</string>
<string name="all_apps_label" msgid="5015784846527570951">"កម្មវិធីទាំងអស់"</string>
<string name="notifications_header" msgid="1404149926117359025">"ការជូនដំណឹង"</string>
diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml
index a9b89b5..72eaeac 100644
--- a/res/values-kn/strings.xml
+++ b/res/values-kn/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ಹುಡುಕಿ"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ಲೋಡ್ ಮಾಡಲಾಗುತ್ತಿದೆ..."</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" ಹೊಂದಿಕೆಯ ಯಾವುದೇ ಅಪ್ಲಿಕೇಶನ್ಗಳು ಕಂಡುಬಂದಿಲ್ಲ"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"ಮತ್ತಷ್ಟು ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ಹುಡುಕಿ"</string>
<string name="label_application" msgid="8531721983832654978">"ಆ್ಯಪ್"</string>
<string name="all_apps_label" msgid="5015784846527570951">"ಎಲ್ಲಾ ಆ್ಯಪ್ಗಳು"</string>
<string name="notifications_header" msgid="1404149926117359025">"ಅಧಿಸೂಚನೆಗಳು"</string>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index 0935aa1..f6b8ff7 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"앱 검색"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"앱 로드 중…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"\'<xliff:g id="QUERY">%1$s</xliff:g>\'과(와) 일치하는 앱이 없습니다."</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"더 많은 앱 검색"</string>
<string name="label_application" msgid="8531721983832654978">"앱"</string>
<string name="all_apps_label" msgid="5015784846527570951">"모든 앱"</string>
<string name="notifications_header" msgid="1404149926117359025">"알림"</string>
diff --git a/res/values-ky/strings.xml b/res/values-ky/strings.xml
index 755e274..84b7993 100644
--- a/res/values-ky/strings.xml
+++ b/res/values-ky/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Колдонмолорду издөө"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Колдонмолор жүктөлүүдө…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" сурамына дал келген колдонмолор табылган жок"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Көбүрөөк колдонмолорду издөө"</string>
<string name="label_application" msgid="8531721983832654978">"Колдонмо"</string>
<string name="all_apps_label" msgid="5015784846527570951">"Бардык колдонмолор"</string>
<string name="notifications_header" msgid="1404149926117359025">"Билдирмелер"</string>
diff --git a/res/values-lo/strings.xml b/res/values-lo/strings.xml
index 9e75492..d8b55f8 100644
--- a/res/values-lo/strings.xml
+++ b/res/values-lo/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ຊອກຫາແອັບ"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"ກໍາລັງໂຫຼດແອັບ…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"ບໍ່ພົບແອັບທີ່ກົງກັບ \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"ຊອກຫາແອັບເພີ່ມເຕີມ"</string>
<string name="label_application" msgid="8531721983832654978">"ແອັບ"</string>
<string name="all_apps_label" msgid="5015784846527570951">"ແອັບທັງໝົດ"</string>
<string name="notifications_header" msgid="1404149926117359025">"ການແຈ້ງເຕືອນ"</string>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index bbe0cfa..e68362d 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Paieškos programos"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Įkeliamos programos…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Nerasta jokių užklausą „<xliff:g id="QUERY">%1$s</xliff:g>“ atitinkančių programų"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Ieškoti daugiau programų"</string>
<string name="label_application" msgid="8531721983832654978">"Programa"</string>
<string name="all_apps_label" msgid="5015784846527570951">"Visos programos"</string>
<string name="notifications_header" msgid="1404149926117359025">"Pranešimai"</string>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index b5836ef..75f6d1a 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Meklēt lietotnes"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Notiek lietotņu ielāde…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Vaicājumam “<xliff:g id="QUERY">%1$s</xliff:g>” neatbilda neviena lietotne"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Meklēt citas lietotnes"</string>
<string name="label_application" msgid="8531721983832654978">"Lietotne"</string>
<string name="all_apps_label" msgid="5015784846527570951">"Visas lietotnes"</string>
<string name="notifications_header" msgid="1404149926117359025">"Paziņojumi"</string>
diff --git a/res/values-mk/strings.xml b/res/values-mk/strings.xml
index d452eba..fef9bbe 100644
--- a/res/values-mk/strings.xml
+++ b/res/values-mk/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Пребарувајте апликации"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Се вчитуваат апликации…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Не се најдени апликации што одговараат на „<xliff:g id="QUERY">%1$s</xliff:g>“"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Пребарај други апликации"</string>
<string name="label_application" msgid="8531721983832654978">"Апликација"</string>
<string name="all_apps_label" msgid="5015784846527570951">"Сите апликации"</string>
<string name="notifications_header" msgid="1404149926117359025">"Известувања"</string>
diff --git a/res/values-ml/strings.xml b/res/values-ml/strings.xml
index df532c0..802ea81 100644
--- a/res/values-ml/strings.xml
+++ b/res/values-ml/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ആപ്പുകൾ തിരയുക"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"ആപ്പുകൾ ലോഡുചെയ്യുന്നു..."</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" എന്നതുമായി പൊരുത്തപ്പെടുന്ന ആപ്പുകളൊന്നും കണ്ടെത്തിയില്ല"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"കൂടുതൽ ആപ്പുകൾക്ക് തിരയുക"</string>
<string name="label_application" msgid="8531721983832654978">"ആപ്പ്"</string>
<string name="all_apps_label" msgid="5015784846527570951">"എല്ലാ ആപ്പുകളും"</string>
<string name="notifications_header" msgid="1404149926117359025">"അറിയിപ്പുകൾ"</string>
diff --git a/res/values-mn/strings.xml b/res/values-mn/strings.xml
index c71aaff..f091cb8 100644
--- a/res/values-mn/strings.xml
+++ b/res/values-mn/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Апп хайх"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Аппыг ачаалж байна..."</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\"-д тохирох апп олдсонгүй"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Бусад апп-г хайх"</string>
<string name="label_application" msgid="8531721983832654978">"Апп"</string>
<string name="all_apps_label" msgid="5015784846527570951">"Бүх апп"</string>
<string name="notifications_header" msgid="1404149926117359025">"Мэдэгдэл"</string>
diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml
index e871073..d6535ce 100644
--- a/res/values-mr/strings.xml
+++ b/res/values-mr/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"अॅप्स शोधा"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"अॅप्स लोड करत आहे…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" शी जुळणारे कोणतेही अॅप्स आढळले नाहीत"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"अधिक अॅप्स शोधा"</string>
<string name="label_application" msgid="8531721983832654978">"ॲप"</string>
<string name="all_apps_label" msgid="5015784846527570951">"सर्व अॅप्स"</string>
<string name="notifications_header" msgid="1404149926117359025">"सूचना"</string>
diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml
index cbfb551..edd0530 100644
--- a/res/values-ms/strings.xml
+++ b/res/values-ms/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Cari apl"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Memuatkan apl…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Tiada apl yang ditemui sepadan dengan \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Cari lagi apl"</string>
<string name="label_application" msgid="8531721983832654978">"Apl"</string>
<string name="all_apps_label" msgid="5015784846527570951">"Semua apl"</string>
<string name="notifications_header" msgid="1404149926117359025">"Pemberitahuan"</string>
diff --git a/res/values-my/strings.xml b/res/values-my/strings.xml
index 984ec4c..bf66399 100644
--- a/res/values-my/strings.xml
+++ b/res/values-my/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ရှာဖွေမှု အက်ပ်များ"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"အက်ပ်များကို ဖွင့်နေသည်…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" နှင့်ကိုက်ညီသည့် အပ်ပ်များကို မတွေ့ပါ"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"နောက်ထပ် အက်ပ်များကို ရှာပါ"</string>
<string name="label_application" msgid="8531721983832654978">"အက်ပ်"</string>
<string name="all_apps_label" msgid="5015784846527570951">"အက်ပ်အားလုံး"</string>
<string name="notifications_header" msgid="1404149926117359025">"အကြောင်းကြားချက်များ"</string>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index b29ee77..3e08d10 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Søk etter apper"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Laster inn appene …"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Fant ingen apper som samsvarer med «<xliff:g id="QUERY">%1$s</xliff:g>»"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Søk etter flere apper"</string>
<string name="label_application" msgid="8531721983832654978">"App"</string>
<string name="all_apps_label" msgid="5015784846527570951">"Alle apper"</string>
<string name="notifications_header" msgid="1404149926117359025">"Varsler"</string>
diff --git a/res/values-ne/strings.xml b/res/values-ne/strings.xml
index fcc1ece..8cef63d 100644
--- a/res/values-ne/strings.xml
+++ b/res/values-ne/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"खोजसम्बन्धी एपहरू"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"एपहरू लोड गर्दै…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" सँग मिल्दो कुनै एप भेटिएन"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"थप एपहरू खोज्नुहोस्"</string>
<string name="label_application" msgid="8531721983832654978">"एप"</string>
<string name="all_apps_label" msgid="5015784846527570951">"सबै एप"</string>
<string name="notifications_header" msgid="1404149926117359025">"सूचनाहरू"</string>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index bd41952..4b203b7 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Apps zoeken"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Apps laden…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Er zijn geen apps gevonden die overeenkomen met \'<xliff:g id="QUERY">%1$s</xliff:g>\'"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Zoeken naar meer apps"</string>
<string name="label_application" msgid="8531721983832654978">"App"</string>
<string name="all_apps_label" msgid="5015784846527570951">"Alle apps"</string>
<string name="notifications_header" msgid="1404149926117359025">"Meldingen"</string>
diff --git a/res/values-or/strings.xml b/res/values-or/strings.xml
index 95fa000..dd5561d 100644
--- a/res/values-or/strings.xml
+++ b/res/values-or/strings.xml
@@ -38,7 +38,7 @@
<string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d ଓସାର ଓ %2$d ଉଚ୍ଚ"</string>
<string name="widget_preview_context_description" msgid="9045841361655787574">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g> ୱିଜେଟ୍"</string>
<string name="add_item_request_drag_hint" msgid="8730547755622776606">"ମୂଳସ୍କ୍ରିନର ଆଖପାଖରେ ୱିଜେଟକୁ ମୁଭ କରିବା ପାଇଁ ଏହାକୁ ସ୍ପର୍ଶ କରି ଧରି ରଖନ୍ତୁ"</string>
- <string name="add_to_home_screen" msgid="9168649446635919791">"ମୂଳସ୍କ୍ରିନରେ ଯୋଗ କରନ୍ତୁ"</string>
+ <string name="add_to_home_screen" msgid="9168649446635919791">"ହୋମ ସ୍କ୍ରିନରେ ଯୋଗ କରନ୍ତୁ"</string>
<string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"<xliff:g id="WIDGET_NAME">%1$s</xliff:g>ର ୱିଜେଟ୍ ମୂଳସ୍କ୍ରିନରେ ଯୋଡ଼ାଗଲା"</string>
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{#ଟି ୱିଜେଟ୍}other{#ଟି ୱିଜେଟ୍}}"</string>
<string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{#ଟି ସର୍ଟକଟ୍}other{#ଟି ସର୍ଟକଟ୍}}"</string>
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ଆପ୍ ଖୋଜନ୍ତୁ"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"ଆପ୍ ଲୋଡ୍ ହେଉଛି..."</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" ସହିତ ମେଳ ହେଉଥିବା କୌଣସି ଆପ୍ ମିଳିଲା ନାହିଁ"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"ଅଧିକ ଆପ୍ ଖୋଜନ୍ତୁ"</string>
<string name="label_application" msgid="8531721983832654978">"ଆପ୍"</string>
<string name="all_apps_label" msgid="5015784846527570951">"ସବୁ ଆପ"</string>
<string name="notifications_header" msgid="1404149926117359025">"ବିଜ୍ଞପ୍ତି"</string>
@@ -131,7 +130,7 @@
<string name="dialog_remove" msgid="6510806469849709407">"କାଢ଼ି ଦିଅନ୍ତୁ"</string>
<string name="widgets_list" msgid="796804551140113767">"ୱିଜେଟ୍ ତାଲିକା"</string>
<string name="widgets_list_closed" msgid="6141506579418771922">"ୱିଜେଟ୍ ତାଲିକା ବନ୍ଦ ହୋଇଛି"</string>
- <string name="action_add_to_workspace" msgid="215894119683164916">"ମୂଳସ୍କ୍ରିନରେ ଯୋଗ କରନ୍ତୁ"</string>
+ <string name="action_add_to_workspace" msgid="215894119683164916">"ହୋମ ସ୍କ୍ରିନରେ ଯୋଗ କରନ୍ତୁ"</string>
<string name="action_move_here" msgid="2170188780612570250">"ଆଇଟମ୍କୁ ଏଠାକୁ ଘୁଞ୍ଚାନ୍ତୁ"</string>
<string name="item_added_to_workspace" msgid="4211073925752213539">"ହୋମ୍ ସ୍କ୍ରୀନରେ ଆଇଟମ୍ ଯୋଡ଼ାଗଲା"</string>
<string name="item_removed" msgid="851119963877842327">"ଆଇଟମକୁ କାଢ଼ି ଦିଆଯାଇଛି"</string>
diff --git a/res/values-pa/strings.xml b/res/values-pa/strings.xml
index 01fbee0..a291a92 100644
--- a/res/values-pa/strings.xml
+++ b/res/values-pa/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ਐਪਾਂ ਖੋਜੋ"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"ਐਪਾਂ ਨੂੰ ਲੋਡ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ..."</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" ਨਾਲ ਮੇਲ ਖਾਂਦੀਆਂ ਕੋਈ ਐਪਾਂ ਨਹੀਂ ਮਿਲੀਆਂ"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"ਹੋਰ ਐਪਾਂ ਖੋਜੋ"</string>
<string name="label_application" msgid="8531721983832654978">"ਐਪ"</string>
<string name="all_apps_label" msgid="5015784846527570951">"ਸਾਰੀਆਂ ਐਪਾਂ"</string>
<string name="notifications_header" msgid="1404149926117359025">"ਸੂਚਨਾਵਾਂ"</string>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index 4b46f0b..448a56b 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Wyszukaj aplikacje"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Ładuję aplikacje…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Nie znaleziono aplikacji pasujących do zapytania „<xliff:g id="QUERY">%1$s</xliff:g>”"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Wyszukaj więcej aplikacji"</string>
<string name="label_application" msgid="8531721983832654978">"Aplikacja"</string>
<string name="all_apps_label" msgid="5015784846527570951">"Wszystkie aplikacje"</string>
<string name="notifications_header" msgid="1404149926117359025">"Powiadomienia"</string>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index dbfa0cb..e2d8c9d 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Pesquisar aplicações"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"A carregar aplicações…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Nenhuma app correspondente a \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Pesquisar mais aplicações"</string>
<string name="label_application" msgid="8531721983832654978">"Aplicação"</string>
<string name="all_apps_label" msgid="5015784846527570951">"Todas as apps"</string>
<string name="notifications_header" msgid="1404149926117359025">"Notificações"</string>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index 3a5ed5b..98e8607 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Pesquisar apps"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Carregando apps…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Nenhum app encontrado que corresponda a \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Pesquisar mais apps"</string>
<string name="label_application" msgid="8531721983832654978">"App"</string>
<string name="all_apps_label" msgid="5015784846527570951">"Todos os apps"</string>
<string name="notifications_header" msgid="1404149926117359025">"Notificações"</string>
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index 6061ea5..794609e 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Caută aplicații"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Se încarcă aplicații…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Nu s-a găsit nicio aplicație pentru „<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Caută mai multe aplicații"</string>
<string name="label_application" msgid="8531721983832654978">"Aplicație"</string>
<string name="all_apps_label" msgid="5015784846527570951">"Toate aplicațiile"</string>
<string name="notifications_header" msgid="1404149926117359025">"Notificări"</string>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index 0ad12bd..5987321 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Поиск приложений"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Загрузка приложений…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"По запросу \"<xliff:g id="QUERY">%1$s</xliff:g>\" ничего не найдено"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Искать другие приложения"</string>
<string name="label_application" msgid="8531721983832654978">"Приложение"</string>
<string name="all_apps_label" msgid="5015784846527570951">"Все приложения"</string>
<string name="notifications_header" msgid="1404149926117359025">"Уведомления"</string>
diff --git a/res/values-si/strings.xml b/res/values-si/strings.xml
index cf3dc64..e030432 100644
--- a/res/values-si/strings.xml
+++ b/res/values-si/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"යෙදුම් සොයන්න"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"යෙදුම් පූරණය වෙමින්…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" සමග ගැළපෙන යෙදුම් හමු නොවිණි"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"තව යෙදුම් සඳහා සොයන්න"</string>
<string name="label_application" msgid="8531721983832654978">"යෙදුම"</string>
<string name="all_apps_label" msgid="5015784846527570951">"සියලු යෙදුම්"</string>
<string name="notifications_header" msgid="1404149926117359025">"දැනුම්දීම්"</string>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index e3bcc52..ff2c226 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Hľadať aplikácie"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Načítavajú sa aplikácie…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Nenašli sa žiadne aplikácie zodpovedajúce dopytu <xliff:g id="QUERY">%1$s</xliff:g>"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Hľadať ďalšie aplikácie"</string>
<string name="label_application" msgid="8531721983832654978">"Aplikácia"</string>
<string name="all_apps_label" msgid="5015784846527570951">"Všetky aplikácie"</string>
<string name="notifications_header" msgid="1404149926117359025">"Upozornenia"</string>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index 5f952cf..b1f93e8 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Iskanje programov"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Nalaganje aplikacij …"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Ni aplikacij, ki bi ustrezale poizvedbi »<xliff:g id="QUERY">%1$s</xliff:g>«"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Iskanje več aplikacij"</string>
<string name="label_application" msgid="8531721983832654978">"Aplikacija"</string>
<string name="all_apps_label" msgid="5015784846527570951">"Vse aplikacije"</string>
<string name="notifications_header" msgid="1404149926117359025">"Obvestila"</string>
diff --git a/res/values-sq/strings.xml b/res/values-sq/strings.xml
index 9f29a87..99bcbaa 100644
--- a/res/values-sq/strings.xml
+++ b/res/values-sq/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Kërko për aplikacione"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Po ngarkon aplikacionet..."</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Nuk u gjet asnjë aplikacion që përputhet me \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Kërko për më shumë aplikacione"</string>
<string name="label_application" msgid="8531721983832654978">"Aplikacioni"</string>
<string name="all_apps_label" msgid="5015784846527570951">"Të gjitha aplikacionet"</string>
<string name="notifications_header" msgid="1404149926117359025">"Njoftimet"</string>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index 948d9b6..460a73e 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Претражите апликације"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Апликације се учитавају…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Није пронађена ниједна апликација за „<xliff:g id="QUERY">%1$s</xliff:g>“"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Претражи још апликација"</string>
<string name="label_application" msgid="8531721983832654978">"Апликација"</string>
<string name="all_apps_label" msgid="5015784846527570951">"Све апликације"</string>
<string name="notifications_header" msgid="1404149926117359025">"Обавештења"</string>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index c35adb0..6ec274b 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Sök efter appar"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Läser in appar …"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Inga appar som matchar <xliff:g id="QUERY">%1$s</xliff:g> hittades"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Sök efter fler appar"</string>
<string name="label_application" msgid="8531721983832654978">"App"</string>
<string name="all_apps_label" msgid="5015784846527570951">"Alla appar"</string>
<string name="notifications_header" msgid="1404149926117359025">"Aviseringar"</string>
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index c233cc4..147c6e1 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Tafuta programu"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Inapakia programu..."</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Haikupata programu zozote zinazolingana na \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Tafuta programu zaidi"</string>
<string name="label_application" msgid="8531721983832654978">"Programu"</string>
<string name="all_apps_label" msgid="5015784846527570951">"Programu zote"</string>
<string name="notifications_header" msgid="1404149926117359025">"Arifa"</string>
diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml
index bfec460..d8eacf5 100644
--- a/res/values-ta/strings.xml
+++ b/res/values-ta/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ஆப்ஸில் தேடுக"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"ஆப்ஸை ஏற்றுகிறது…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" உடன் பொருந்தும் ஆப்ஸ் இல்லை"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"கூடுதல் பயன்பாடுகளைத் தேடு"</string>
<string name="label_application" msgid="8531721983832654978">"ஆப்ஸ்"</string>
<string name="all_apps_label" msgid="5015784846527570951">"அனைத்து ஆப்ஸும்"</string>
<string name="notifications_header" msgid="1404149926117359025">"அறிவிப்புகள்"</string>
diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml
index 1d25371..08bccad 100644
--- a/res/values-te/strings.xml
+++ b/res/values-te/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"యాప్ల కోసం సెర్చ్ చేయండి"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"అప్లికేషన్లను లోడ్ చేస్తోంది…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\"కి సరిపోలే అప్లికేషన్లేవీ కనుగొనబడలేదు"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"మరిన్ని యాప్ల కోసం సెర్చ్ చేయండి"</string>
<string name="label_application" msgid="8531721983832654978">"యాప్"</string>
<string name="all_apps_label" msgid="5015784846527570951">"అన్ని యాప్లు"</string>
<string name="notifications_header" msgid="1404149926117359025">"నోటిఫికేషన్లు"</string>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index f633b5f..deb4834 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ค้นหาแอป"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"กำลังโหลดแอป…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"ไม่พบแอปที่ตรงกับ \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"ค้นหาแอปเพิ่มเติม"</string>
<string name="label_application" msgid="8531721983832654978">"แอป"</string>
<string name="all_apps_label" msgid="5015784846527570951">"แอปทั้งหมด"</string>
<string name="notifications_header" msgid="1404149926117359025">"การแจ้งเตือน"</string>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index de4f952..a4cd808 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Maghanap ng mga app"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Naglo-load ng mga app…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Walang nahanap na app na tumutugma sa \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Maghanap ng higit pang mga app"</string>
<string name="label_application" msgid="8531721983832654978">"App"</string>
<string name="all_apps_label" msgid="5015784846527570951">"Lahat ng app"</string>
<string name="notifications_header" msgid="1404149926117359025">"Mga Notification"</string>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index f41284b..c30c2e5 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Uygulamalarda ara"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Uygulamalar yükleniyor…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" ile eşleşen uygulama bulunamadı"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Başka uygulamalar ara"</string>
<string name="label_application" msgid="8531721983832654978">"Uygulama"</string>
<string name="all_apps_label" msgid="5015784846527570951">"Tüm uygulamalar"</string>
<string name="notifications_header" msgid="1404149926117359025">"Bildirimler"</string>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index 360950e..70f8e95 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Пошук додатків"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Завантаження додатків…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Немає додатків для запиту \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Шукати ще додатки"</string>
<string name="label_application" msgid="8531721983832654978">"Додаток"</string>
<string name="all_apps_label" msgid="5015784846527570951">"Усі додатки"</string>
<string name="notifications_header" msgid="1404149926117359025">"Сповіщення"</string>
diff --git a/res/values-ur/strings.xml b/res/values-ur/strings.xml
index e68e43e..3d90187 100644
--- a/res/values-ur/strings.xml
+++ b/res/values-ur/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ایپس تلاش کریں"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"ایپس لوڈ کی جا رہی ہیں…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" سے مماثل کوئی ایپس نہیں ملیں"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"مزید ایپس تلاش کریں"</string>
<string name="label_application" msgid="8531721983832654978">"ایپ"</string>
<string name="all_apps_label" msgid="5015784846527570951">"سبھی ایپس"</string>
<string name="notifications_header" msgid="1404149926117359025">"اطلاعات"</string>
diff --git a/res/values-uz/strings.xml b/res/values-uz/strings.xml
index 9c7ed56..04d07ec 100644
--- a/res/values-uz/strings.xml
+++ b/res/values-uz/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Ilovalarni qidirish"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Ilovalar yuklanmoqda…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"“<xliff:g id="QUERY">%1$s</xliff:g>” bilan mos hech qanday ilova topilmadi"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Boshqa ilovalarni qidirish"</string>
<string name="label_application" msgid="8531721983832654978">"Ilova"</string>
<string name="all_apps_label" msgid="5015784846527570951">"Barcha ilovalar"</string>
<string name="notifications_header" msgid="1404149926117359025">"Bildirishnomalar"</string>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index 30167fa..2329992 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Tìm kiếm ứng dụng"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Đang tải ứng dụng…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Không tìm thấy ứng dụng nào phù hợp với \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Tìm kiếm thêm ứng dụng"</string>
<string name="label_application" msgid="8531721983832654978">"Ứng dụng"</string>
<string name="all_apps_label" msgid="5015784846527570951">"Tất cả ứng dụng"</string>
<string name="notifications_header" msgid="1404149926117359025">"Thông báo"</string>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index 141d165..929cffa 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"搜索应用"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"正在加载应用…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"未找到与“<xliff:g id="QUERY">%1$s</xliff:g>”相符的应用"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"搜索更多应用"</string>
<string name="label_application" msgid="8531721983832654978">"应用"</string>
<string name="all_apps_label" msgid="5015784846527570951">"所有应用"</string>
<string name="notifications_header" msgid="1404149926117359025">"通知"</string>
diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml
index 2ff233b..1aea757 100644
--- a/res/values-zh-rHK/strings.xml
+++ b/res/values-zh-rHK/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"搜尋應用程式"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"正在載入應用程式…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"找不到與「<xliff:g id="QUERY">%1$s</xliff:g>」相符的應用程式"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"搜尋更多應用程式"</string>
<string name="label_application" msgid="8531721983832654978">"應用程式"</string>
<string name="all_apps_label" msgid="5015784846527570951">"所有應用程式"</string>
<string name="notifications_header" msgid="1404149926117359025">"通知"</string>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index 91cfd82..25a7d21 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"搜尋應用程式"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"正在載入應用程式…"</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"找不到與「<xliff:g id="QUERY">%1$s</xliff:g>」相符的應用程式"</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"搜尋更多應用程式"</string>
<string name="label_application" msgid="8531721983832654978">"應用程式"</string>
<string name="all_apps_label" msgid="5015784846527570951">"所有應用程式"</string>
<string name="notifications_header" msgid="1404149926117359025">"通知"</string>
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index 12e8568..151ce27 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -59,7 +59,6 @@
<string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Sesha izinhlelo zokusebenza"</string>
<string name="all_apps_loading_message" msgid="5813968043155271636">"Ilayisha izinhlelo zokusebenza..."</string>
<string name="all_apps_no_search_results" msgid="3200346862396363786">"Azikho izinhlelo zokusebenza ezitholiwe ezifana ne-\"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
- <string name="all_apps_search_market_message" msgid="1366263386197059176">"Sesha izinhlelo zokusebenza eziningi"</string>
<string name="label_application" msgid="8531721983832654978">"Uhlelo lokusebenza"</string>
<string name="all_apps_label" msgid="5015784846527570951">"Zonke izinhlelo zokusebenza"</string>
<string name="notifications_header" msgid="1404149926117359025">"Izaziso"</string>
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 3b71585..df1ca14 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -158,9 +158,6 @@
<!-- numHotseatIcons defaults to numColumns, if not specified -->
<attr name="numHotseatIcons" format="integer" />
- <!-- Number of icons to use when shrinking the hotseat size,
- defaults to numHotseatIcons / 2 -->
- <attr name="numShrunkenHotseatIcons" format="integer" />
<!-- Number of icons to use when extending the hotseat size,
defaults to 2 * numHotseatIcons -->
<attr name="numExtendedHotseatIcons" format="integer" />
@@ -284,6 +281,8 @@
<!-- defaults to iconImageSize, if not specified -->
<attr name="allAppsIconSize" format="float" />
<!-- defaults to allAppsIconSize, if not specified -->
+ <attr name="allAppsIconSizeLandscape" format="float" />
+ <!-- defaults to allAppsIconSize, if not specified -->
<attr name="allAppsIconSizeTwoPanelPortrait" format="float" />
<!-- defaults to allAppsIconSize, if not specified -->
<attr name="allAppsIconSizeTwoPanelLandscape" format="float" />
@@ -328,15 +327,6 @@
if not specified -->
<attr name="allAppsBorderSpaceTwoPanelLandscapeVertical" format="float" />
- <!-- defaults to borderSpaceDps, if not specified -->
- <attr name="hotseatBorderSpace" format="float" />
- <!-- defaults to hotseatBorderSpace, if not specified -->
- <attr name="hotseatBorderSpaceLandscape" format="float" />
- <!-- defaults to hotseatBorderSpace, if not specified -->
- <attr name="hotseatBorderSpaceTwoPanelLandscape" format="float" />
- <!-- defaults to hotseatBorderSpace, if not specified -->
- <attr name="hotseatBorderSpaceTwoPanelPortrait" format="float" />
-
<!-- defaults to res.hotseat_bar_bottom_space_default, if not specified -->
<attr name="hotseatBarBottomSpace" format="float" />
<!-- defaults to hotseatBarBottomSpace, if not specified -->
diff --git a/res/values/config.xml b/res/values/config.xml
index 3f94c34..1415ed0 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -156,6 +156,7 @@
<item name="swipe_up_rect_scale_damping_ratio" type="dimen" format="float">0.75</item>
<item name="swipe_up_rect_scale_stiffness" type="dimen" format="float">200</item>
+ <item name="swipe_up_rect_scale_higher_stiffness" type="dimen" format="float">400</item>
<item name="swipe_up_rect_xy_fling_friction" type="dimen" format="float">1.5</item>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index c8554ec..546ee35 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -354,6 +354,8 @@
<dimen name="taskbar_stashed_size">0dp</dimen>
<dimen name="qsb_widget_height">0dp</dimen>
<dimen name="qsb_shadow_height">0dp</dimen>
+ <dimen name="min_hotseat_icon_space">18dp</dimen>
+ <dimen name="min_hotseat_qsb_width">0dp</dimen>
<dimen name="taskbar_icon_size">44dp</dimen>
<!-- Note that this applies to both sides of all icons, so visible space is double this. -->
<dimen name="taskbar_icon_spacing">8dp</dimen>
diff --git a/res/xml/device_profiles.xml b/res/xml/device_profiles.xml
index 0238e7d..407f217 100644
--- a/res/xml/device_profiles.xml
+++ b/res/xml/device_profiles.xml
@@ -200,8 +200,6 @@
launcher:allAppsBorderSpaceHorizontal="8"
launcher:allAppsBorderSpaceVertical="16"
launcher:allAppsBorderSpaceLandscape="16"
- launcher:hotseatBorderSpace="58"
- launcher:hotseatBorderSpaceLandscape="50.4"
launcher:hotseatBarBottomSpace="76"
launcher:hotseatBarBottomSpaceLandscape="40"
launcher:canBeDefault="true" />
diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java
index 52960a9..9f3e1fa 100644
--- a/src/com/android/launcher3/CellLayout.java
+++ b/src/com/android/launcher3/CellLayout.java
@@ -496,8 +496,8 @@
// Draw reorder drag target.
debugPaint.setColor(Color.RED);
- canvas.drawCircle(cellCenter[0], cellCenter[1], getReorderRadius(targetCell),
- debugPaint);
+ canvas.drawCircle(cellCenter[0], cellCenter[1],
+ getReorderRadius(targetCell, 1, 1), debugPaint);
// Draw folder creation drag target.
if (canCreateFolder) {
@@ -912,18 +912,18 @@
DeviceProfile grid = mActivity.getDeviceProfile();
float iconVisibleRadius = ICON_VISIBLE_AREA_FACTOR * grid.iconSizePx / 2;
// Halfway between reorder radius and icon.
- return (getReorderRadius(targetCell) + iconVisibleRadius) / 2;
+ return (getReorderRadius(targetCell, 1, 1) + iconVisibleRadius) / 2;
}
/**
* Returns the max distance from the center of a cell that will start to reorder on drag over.
*/
- public float getReorderRadius(int[] targetCell) {
+ public float getReorderRadius(int[] targetCell, int spanX, int spanY) {
int[] centerPoint = mTmpPoint;
getWorkspaceCellVisualCenter(targetCell[0], targetCell[1], centerPoint);
Rect cellBoundsWithSpacing = mTempRect;
- cellToRect(targetCell[0], targetCell[1], 1, 1, cellBoundsWithSpacing);
+ cellToRect(targetCell[0], targetCell[1], spanX, spanY, cellBoundsWithSpacing);
cellBoundsWithSpacing.inset(-mBorderSpace.x / 2, -mBorderSpace.y / 2);
if (canCreateFolder(getChildAt(targetCell[0], targetCell[1]))) {
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 366d372..418df37 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -23,24 +23,25 @@
import static com.android.launcher3.Utilities.dpiFromPx;
import static com.android.launcher3.Utilities.pxFromSp;
import static com.android.launcher3.folder.ClippedFolderIconLayoutRule.ICON_OVERLAP_FACTOR;
+import static com.android.launcher3.icons.GraphicsUtils.getShapePath;
import static com.android.launcher3.testing.shared.ResourceUtils.pxFromDp;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
-import android.graphics.Path;
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
import android.util.DisplayMetrics;
+import android.util.SparseArray;
import android.view.Surface;
+import androidx.annotation.NonNull;
+
import com.android.launcher3.CellLayout.ContainerType;
import com.android.launcher3.DevicePaddings.DevicePadding;
-import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.icons.DotRenderer;
-import com.android.launcher3.icons.GraphicsUtils;
import com.android.launcher3.icons.IconNormalizer;
import com.android.launcher3.uioverrides.ApiWrapper;
import com.android.launcher3.util.DisplayController;
@@ -54,6 +55,8 @@
public class DeviceProfile {
private static final int DEFAULT_DOT_SIZE = 100;
+ private static final float ALL_APPS_TABLET_MAX_ROWS = 5.5f;
+
// Ratio of empty space, qsb should take up to appear visually centered.
private final float mQsbCenterFactor;
@@ -155,7 +158,7 @@
public int folderChildDrawablePaddingPx;
// Hotseat
- public final int numShownHotseatIcons;
+ public int numShownHotseatIcons;
public int hotseatCellHeightPx;
public final boolean areNavButtonsInline;
// In portrait: size = height, in landscape: size = width
@@ -167,13 +170,12 @@
// Start is the side next to the nav bar, end is the side next to the workspace
public final int hotseatBarSidePaddingStartPx;
public final int hotseatBarSidePaddingEndPx;
+ public int hotseatQsbWidth; // only used when isQsbInline
public final int hotseatQsbHeight;
public final int hotseatQsbVisualHeight;
private final int hotseatQsbShadowHeight;
public int hotseatBorderSpace;
- public int qsbWidth; // only used when isQsbInline
-
// All apps
public Point allAppsBorderSpacePx;
public int allAppsShiftRange;
@@ -222,8 +224,8 @@
private boolean mIsSeascape;
// Notification dots
- public DotRenderer mDotRendererWorkSpace;
- public DotRenderer mDotRendererAllApps;
+ public final DotRenderer mDotRendererWorkSpace;
+ public final DotRenderer mDotRendererAllApps;
// Taskbar
public boolean isTaskbarPresent;
@@ -237,8 +239,8 @@
/** TODO: Once we fully migrate to staged split, remove "isMultiWindowMode" */
DeviceProfile(Context context, InvariantDeviceProfile inv, Info info, WindowBounds windowBounds,
- boolean isMultiWindowMode, boolean transposeLayoutWithOrientation,
- boolean useTwoPanels, boolean isGestureMode) {
+ SparseArray<DotRenderer> dotRendererCache, boolean isMultiWindowMode,
+ boolean transposeLayoutWithOrientation, boolean useTwoPanels, boolean isGestureMode) {
this.inv = inv;
this.isLandscape = windowBounds.isLandscape();
@@ -309,10 +311,6 @@
+ res.getDimensionPixelSize(R.dimen.bottom_sheet_extra_top_padding)
+ (isTablet ? 0 : edgeMarginPx); // phones need edgeMarginPx additional padding
- allAppsTopPadding = isTablet ? bottomSheetTopPadding : 0;
- allAppsShiftRange = isTablet
- ? heightPx - allAppsTopPadding
- : res.getDimensionPixelSize(R.dimen.all_apps_starting_vertical_translate);
folderLabelTextScale = res.getFloat(R.dimen.folder_label_text_scale);
folderContentPaddingLeftRight =
res.getDimensionPixelSize(R.dimen.folder_content_padding_left_right);
@@ -364,15 +362,9 @@
&& hotseatQsbHeight > 0;
isQsbInline = inv.inlineQsb[mTypeIndex] && canQsbInline;
- // We shrink hotseat sizes regardless of orientation, if nav buttons are inline and QSB
- // might be inline in either orientations, to keep hotseat size consistent across rotation.
areNavButtonsInline = isTaskbarPresent && !isGestureMode;
- if (areNavButtonsInline && canQsbInline) {
- numShownHotseatIcons = inv.numShrunkenHotseatIcons;
- } else {
- numShownHotseatIcons =
- isTwoPanels ? inv.numDatabaseHotseatIcons : inv.numShownHotseatIcons;
- }
+ numShownHotseatIcons =
+ isTwoPanels ? inv.numDatabaseHotseatIcons : inv.numShownHotseatIcons;
numShownAllAppsColumns =
isTwoPanels ? inv.numDatabaseAllAppsColumns : inv.numAllAppsColumns;
@@ -407,7 +399,7 @@
// Add a bit of space between nav bar and hotseat in vertical bar layout.
hotseatBarSidePaddingStartPx = isVerticalBarLayout() ? workspacePageIndicatorHeight : 0;
updateHotseatSizes(pxFromDp(inv.iconSize[INDEX_DEFAULT], mMetrics));
- if (areNavButtonsInline) {
+ if (areNavButtonsInline && !isPhone) {
/*
* 3 nav buttons +
* Spacing between nav buttons +
@@ -462,24 +454,45 @@
updateWorkspacePadding();
// Hotseat and QSB width depends on updated cellSize and workspace padding
- hotseatBorderSpace = calculateHotseatBorderSpace();
- qsbWidth = calculateQsbWidth();
+ recalculateHotseatWidthAndBorderSpace(res);
+
+ // AllApps height calculation depends on updated cellSize
+ if (isTablet) {
+ int collapseHandleHeight =
+ res.getDimensionPixelOffset(R.dimen.bottom_sheet_handle_area_height);
+ int contentHeight = heightPx - collapseHandleHeight - hotseatQsbHeight;
+ int targetContentHeight = (int) (allAppsCellHeightPx * ALL_APPS_TABLET_MAX_ROWS);
+ allAppsTopPadding = Math.max(mInsets.top, contentHeight - targetContentHeight);
+ allAppsShiftRange = heightPx - allAppsTopPadding;
+ } else {
+ allAppsTopPadding = 0;
+ allAppsShiftRange =
+ res.getDimensionPixelSize(R.dimen.all_apps_starting_vertical_translate);
+ }
flingToDeleteThresholdVelocity = res.getDimensionPixelSize(
R.dimen.drag_flingToDeleteMinVelocity);
// This is done last, after iconSizePx is calculated above.
- Path dotPath = GraphicsUtils.getShapePath(DEFAULT_DOT_SIZE);
- mDotRendererWorkSpace = new DotRenderer(iconSizePx, dotPath, DEFAULT_DOT_SIZE);
- mDotRendererAllApps = iconSizePx == allAppsIconSizePx ? mDotRendererWorkSpace :
- new DotRenderer(allAppsIconSizePx, dotPath, DEFAULT_DOT_SIZE);
+ mDotRendererWorkSpace = createDotRenderer(iconSizePx, dotRendererCache);
+ mDotRendererAllApps = createDotRenderer(allAppsIconSizePx, dotRendererCache);
+ }
+
+ private static DotRenderer createDotRenderer(
+ int size, @NonNull SparseArray<DotRenderer> cache) {
+ DotRenderer renderer = cache.get(size);
+ if (renderer == null) {
+ renderer = new DotRenderer(size, getShapePath(DEFAULT_DOT_SIZE), DEFAULT_DOT_SIZE);
+ cache.put(size, renderer);
+ }
+ return renderer;
}
/**
* QSB width is always calculated because when in 3 button nav the width doesn't follow the
* width of the hotseat.
*/
- private int calculateQsbWidth() {
+ private int calculateQsbWidth(int hotseatBorderSpace) {
if (isQsbInline) {
int columns = getPanelCount() * inv.numColumns;
return getIconToIconWidthForColumns(columns)
@@ -526,6 +539,70 @@
}
}
+ private void recalculateHotseatWidthAndBorderSpace(Resources res) {
+ hotseatBorderSpace = calculateHotseatBorderSpace();
+ hotseatQsbWidth = calculateQsbWidth(hotseatBorderSpace);
+ // Spaces should be correct when there nav buttons are not inline
+ if (!areNavButtonsInline) {
+ return;
+ }
+
+ // Get the maximum width that the hotseat can be
+ int columns = getPanelCount() * inv.numColumns;
+ int maxHotseatWidth = getIconToIconWidthForColumns(columns);
+ int sideSpace = (availableWidthPx - maxHotseatWidth) / 2;
+ int inlineButtonsOverlap = Math.max(0, hotseatBarEndOffset - sideSpace);
+ // decrease how much the nav buttons go "inside" the hotseat
+ maxHotseatWidth -= inlineButtonsOverlap;
+
+ // Get how much space is required to show the hotseat with QSB
+ int requiredWidth = getHotseatRequiredWidth();
+
+ // If spaces are fine, use them
+ if (requiredWidth <= maxHotseatWidth) {
+ return;
+ }
+
+ // Calculate the difference of widths and remove a little from each space between icons
+ // and QSB if it's inline
+ int spaceDiff = requiredWidth - maxHotseatWidth;
+ int numOfSpaces = numShownHotseatIcons - (isQsbInline ? 0 : 1);
+ hotseatBorderSpace -= (spaceDiff / numOfSpaces);
+
+ int minHotseatIconSpaceDp = res.getDimensionPixelSize(R.dimen.min_hotseat_icon_space);
+ int minHotseatQsbWidthDp = res.getDimensionPixelSize(R.dimen.min_hotseat_qsb_width);
+
+ if (hotseatBorderSpace >= minHotseatIconSpaceDp) {
+ return;
+ }
+
+ // Border space can't be less than the minimum
+ hotseatBorderSpace = minHotseatIconSpaceDp;
+ requiredWidth = getHotseatRequiredWidth();
+
+ // If there is an inline qsb, change its size
+ if (isQsbInline) {
+ hotseatQsbWidth -= requiredWidth - maxHotseatWidth;
+ if (hotseatQsbWidth >= minHotseatQsbWidthDp) {
+ return;
+ }
+
+ // QSB can't be less than the minimum
+ hotseatQsbWidth = minHotseatQsbWidthDp;
+ }
+
+ // If it still doesn't fit, start removing icons
+ do {
+ numShownHotseatIcons--;
+ requiredWidth = getHotseatRequiredWidth();
+ } while (requiredWidth > maxHotseatWidth && numShownHotseatIcons > 1);
+
+ // Add back some space between the icons
+ spaceDiff = maxHotseatWidth - requiredWidth;
+ numOfSpaces = numShownHotseatIcons - (isQsbInline ? 0 : 1);
+ hotseatBorderSpace += (spaceDiff / numOfSpaces);
+ }
+
private Point getCellLayoutBorderSpace(InvariantDeviceProfile idp) {
return getCellLayoutBorderSpace(idp, 1f);
}
@@ -566,10 +643,16 @@
widthPx, heightPx, availableWidthPx, availableHeightPx, rotationHint);
bounds.bounds.offsetTo(windowX, windowY);
bounds.insets.set(mInsets);
+
+ SparseArray<DotRenderer> dotRendererCache = new SparseArray<>();
+ dotRendererCache.put(iconSizePx, mDotRendererWorkSpace);
+ dotRendererCache.put(allAppsIconSizePx, mDotRendererAllApps);
+
return new Builder(context, inv, mInfo)
.setWindowBounds(bounds)
.setUseTwoPanels(isTwoPanels)
.setMultiWindowMode(isMultiWindowMode)
+ .setDotRendererCache(dotRendererCache)
.setGestureMode(isGestureMode);
}
@@ -752,15 +835,10 @@
*/
private int calculateHotseatBorderSpace() {
if (!isScalableGrid) return 0;
- //TODO(http://b/228998082) remove this when 3 button spaces are fixed
- if (areNavButtonsInline) {
- return pxFromDp(inv.hotseatBorderSpaces[mTypeIndex], mMetrics);
- } else {
- int columns = inv.hotseatColumnSpan[mTypeIndex];
- float hotseatWidthPx = getIconToIconWidthForColumns(columns);
- float hotseatIconsTotalPx = iconSizePx * numShownHotseatIcons;
- return (int) (hotseatWidthPx - hotseatIconsTotalPx) / (numShownHotseatIcons - 1);
- }
+ int columns = inv.hotseatColumnSpan[mTypeIndex];
+ float hotseatWidthPx = getIconToIconWidthForColumns(columns);
+ float hotseatIconsTotalPx = iconSizePx * numShownHotseatIcons;
+ return (int) (hotseatWidthPx - hotseatIconsTotalPx) / (numShownHotseatIcons - 1);
}
@@ -1052,10 +1130,7 @@
hotseatBarSizePx - hotseatBarBottomPadding - hotseatCellHeightPx;
// Push icons to the side
- int additionalQsbSpace = isQsbInline ? qsbWidth + hotseatBorderSpace : 0;
- int requiredWidth = iconSizePx * numShownHotseatIcons
- + hotseatBorderSpace * (numShownHotseatIcons - 1)
- + additionalQsbSpace;
+ int requiredWidth = getHotseatRequiredWidth();
int hotseatWidth = Math.min(requiredWidth, availableWidthPx - hotseatBarEndOffset);
int sideSpacing = (availableWidthPx - hotseatWidth) / 2;
@@ -1064,9 +1139,9 @@
boolean isRtl = Utilities.isRtl(context.getResources());
if (isRtl) {
- hotseatBarPadding.right += additionalQsbSpace;
+ hotseatBarPadding.right += getAdditionalQsbSpace();
} else {
- hotseatBarPadding.left += additionalQsbSpace;
+ hotseatBarPadding.left += getAdditionalQsbSpace();
}
if (hotseatBarEndOffset > sideSpacing) {
@@ -1077,7 +1152,7 @@
hotseatBarPadding.right += diff;
}
} else if (isScalableGrid) {
- int sideSpacing = (availableWidthPx - qsbWidth) / 2;
+ int sideSpacing = (availableWidthPx - hotseatQsbWidth) / 2;
hotseatBarPadding.set(sideSpacing,
0,
sideSpacing,
@@ -1101,6 +1176,20 @@
return hotseatBarPadding;
}
+ private int getAdditionalQsbSpace() {
+ return isQsbInline ? hotseatQsbWidth + hotseatBorderSpace : 0;
+ }
+
+ /**
+ * Calculate how much space the hotseat needs to be shown completely
+ */
+ private int getHotseatRequiredWidth() {
+ int additionalQsbSpace = getAdditionalQsbSpace();
+ return iconSizePx * numShownHotseatIcons
+ + hotseatBorderSpace * (numShownHotseatIcons - 1)
+ + additionalQsbSpace;
+ }
+
/**
* Returns the number of pixels the QSB is translated from the bottom of the screen.
*/
@@ -1350,7 +1439,7 @@
writer.println(prefix + "\tnumShownHotseatIcons: " + numShownHotseatIcons);
writer.println(prefix + pxToDpStr("hotseatBorderSpace", hotseatBorderSpace));
writer.println(prefix + "\tisQsbInline: " + isQsbInline);
- writer.println(prefix + pxToDpStr("qsbWidth", qsbWidth));
+ writer.println(prefix + pxToDpStr("hotseatQsbWidth", hotseatQsbWidth));
writer.println(prefix + "\tisTaskbarPresent:" + isTaskbarPresent);
writer.println(prefix + "\tisTaskbarPresentInApps:" + isTaskbarPresentInApps);
@@ -1474,6 +1563,8 @@
private Boolean mTransposeLayoutWithOrientation;
private Boolean mIsGestureMode;
+ private SparseArray<DotRenderer> mDotRendererCache;
+
public Builder(Context context, InvariantDeviceProfile inv, Info info) {
mContext = context;
mInv = inv;
@@ -1490,6 +1581,10 @@
return this;
}
+ public Builder setDotRendererCache(SparseArray<DotRenderer> dotRendererCache) {
+ mDotRendererCache = dotRendererCache;
+ return this;
+ }
public Builder setWindowBounds(WindowBounds bounds) {
mWindowBounds = bounds;
@@ -1516,8 +1611,12 @@
if (mIsGestureMode == null) {
mIsGestureMode = DisplayController.getNavigationMode(mContext).hasGestures;
}
- return new DeviceProfile(mContext, mInv, mInfo, mWindowBounds, mIsMultiWindowMode,
- mTransposeLayoutWithOrientation, mUseTwoPanels, mIsGestureMode);
+ if (mDotRendererCache == null) {
+ mDotRendererCache = new SparseArray<>();
+ }
+ return new DeviceProfile(mContext, mInv, mInfo, mWindowBounds, mDotRendererCache,
+ mIsMultiWindowMode, mTransposeLayoutWithOrientation, mUseTwoPanels,
+ mIsGestureMode);
}
}
diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java
index 05ed319..bf492a9 100644
--- a/src/com/android/launcher3/Hotseat.java
+++ b/src/com/android/launcher3/Hotseat.java
@@ -47,7 +47,6 @@
private Consumer<Boolean> mOnVisibilityAggregatedCallback;
private final View mQsb;
- private final int mQsbHeight;
public Hotseat(Context context) {
this(context, null);
@@ -62,8 +61,6 @@
mQsb = LayoutInflater.from(context).inflate(R.layout.search_container_hotseat, this, false);
addView(mQsb);
-
- mQsbHeight = getResources().getDimensionPixelSize(R.dimen.qsb_widget_height);
}
/**
@@ -171,29 +168,29 @@
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- int qsbWidth = mActivity.getDeviceProfile().qsbWidth;
-
- mQsb.measure(MeasureSpec.makeMeasureSpec(qsbWidth, MeasureSpec.EXACTLY),
- MeasureSpec.makeMeasureSpec(mQsbHeight, MeasureSpec.EXACTLY));
+ DeviceProfile dp = mActivity.getDeviceProfile();
+ mQsb.measure(MeasureSpec.makeMeasureSpec(dp.hotseatQsbWidth, MeasureSpec.EXACTLY),
+ MeasureSpec.makeMeasureSpec(dp.hotseatQsbHeight, MeasureSpec.EXACTLY));
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
- int qsbWidth = mQsb.getMeasuredWidth();
+ int qsbMeasuredWidth = mQsb.getMeasuredWidth();
int left;
- if (mActivity.getDeviceProfile().isQsbInline) {
- int qsbSpace = mActivity.getDeviceProfile().hotseatBorderSpace;
+ DeviceProfile dp = mActivity.getDeviceProfile();
+ if (dp.isQsbInline) {
+ int qsbSpace = dp.hotseatBorderSpace;
left = Utilities.isRtl(getResources()) ? r - getPaddingRight() + qsbSpace
- : l + getPaddingLeft() - qsbWidth - qsbSpace;
+ : l + getPaddingLeft() - qsbMeasuredWidth - qsbSpace;
} else {
- left = (r - l - qsbWidth) / 2;
+ left = (r - l - qsbMeasuredWidth) / 2;
}
- int right = left + qsbWidth;
+ int right = left + qsbMeasuredWidth;
- int bottom = b - t - mActivity.getDeviceProfile().getQsbOffsetY();
- int top = bottom - mQsbHeight;
+ int bottom = b - t - dp.getQsbOffsetY();
+ int top = bottom - dp.hotseatQsbHeight;
mQsb.layout(left, top, right, bottom);
}
diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index 9b01734..cf2a3f8 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -48,6 +48,7 @@
import androidx.annotation.VisibleForTesting;
import androidx.core.content.res.ResourcesCompat;
+import com.android.launcher3.icons.DotRenderer;
import com.android.launcher3.model.DeviceGridState;
import com.android.launcher3.provider.RestoreDbTask;
import com.android.launcher3.testing.shared.ResourceUtils;
@@ -127,7 +128,6 @@
public PointF[] borderSpaces;
public float folderBorderSpace;
- public float[] hotseatBorderSpaces;
public int inlineNavButtonsEndSpacing;
public float[] horizontalMargin;
@@ -145,11 +145,6 @@
public int numShownHotseatIcons;
/**
- * Number of icons inside the hotseat area when using 3 buttons navigation.
- */
- public int numShrunkenHotseatIcons;
-
- /**
* Number of icons inside the hotseat area that is stored in the database. This is greater than
* or equal to numnShownHotseatIcons, allowing for a seamless transition between two hotseat
* sizes that share the same DB.
@@ -175,7 +170,7 @@
public String dbFile;
public int defaultLayoutId;
int demoModeLayoutId;
- boolean[] inlineQsb = new boolean[COUNT_SIZES];
+ public boolean[] inlineQsb = new boolean[COUNT_SIZES];
/**
* An immutable list of supported profiles.
@@ -363,11 +358,9 @@
horizontalMargin = displayOption.horizontalMargin;
numShownHotseatIcons = closestProfile.numHotseatIcons;
- numShrunkenHotseatIcons = closestProfile.numShrunkenHotseatIcons;
numDatabaseHotseatIcons = deviceType == TYPE_MULTI_DISPLAY
? closestProfile.numDatabaseHotseatIcons : closestProfile.numHotseatIcons;
hotseatColumnSpan = closestProfile.hotseatColumnSpan;
- hotseatBorderSpaces = displayOption.hotseatBorderSpaces;
hotseatBarBottomSpace = displayOption.hotseatBarBottomSpace;
hotseatQsbSpace = displayOption.hotseatQsbSpace;
@@ -396,10 +389,12 @@
final List<DeviceProfile> localSupportedProfiles = new ArrayList<>();
defaultWallpaperSize = new Point(displayInfo.currentSize);
+ SparseArray<DotRenderer> dotRendererCache = new SparseArray<>();
for (WindowBounds bounds : displayInfo.supportedBounds) {
localSupportedProfiles.add(new DeviceProfile.Builder(context, this, displayInfo)
.setUseTwoPanels(deviceType == TYPE_MULTI_DISPLAY)
.setWindowBounds(bounds)
+ .setDotRendererCache(dotRendererCache)
.build());
// Wallpaper size should be the maximum of the all possible sizes Launcher expects
@@ -734,7 +729,6 @@
private final int numAllAppsColumns;
private final int numDatabaseAllAppsColumns;
private final int numHotseatIcons;
- private final int numShrunkenHotseatIcons;
private final int numDatabaseHotseatIcons;
private final int[] hotseatColumnSpan = new int[COUNT_SIZES];
@@ -774,8 +768,6 @@
numHotseatIcons = a.getInt(
R.styleable.GridDisplayOption_numHotseatIcons, numColumns);
- numShrunkenHotseatIcons = a.getInt(
- R.styleable.GridDisplayOption_numShrunkenHotseatIcons, numHotseatIcons / 2);
numDatabaseHotseatIcons = a.getInt(
R.styleable.GridDisplayOption_numExtendedHotseatIcons, 2 * numHotseatIcons);
@@ -839,8 +831,6 @@
private float folderBorderSpace;
private final PointF[] borderSpaces = new PointF[COUNT_SIZES];
private final float[] horizontalMargin = new float[COUNT_SIZES];
- //TODO(http://b/228998082) remove this when 3 button spaces are fixed
- private final float[] hotseatBorderSpaces = new float[COUNT_SIZES];
private final float[] hotseatBarBottomSpace = new float[COUNT_SIZES];
private final float[] hotseatQsbSpace = new float[COUNT_SIZES];
@@ -1014,7 +1004,9 @@
allAppsIconSizes[INDEX_DEFAULT] = a.getFloat(
R.styleable.ProfileDisplayOption_allAppsIconSize, iconSizes[INDEX_DEFAULT]);
- allAppsIconSizes[INDEX_LANDSCAPE] = allAppsIconSizes[INDEX_DEFAULT];
+ allAppsIconSizes[INDEX_LANDSCAPE] = a.getFloat(
+ R.styleable.ProfileDisplayOption_allAppsIconSizeLandscape,
+ iconSizes[INDEX_DEFAULT]);
allAppsIconSizes[INDEX_TWO_PANEL_PORTRAIT] = a.getFloat(
R.styleable.ProfileDisplayOption_allAppsIconSizeTwoPanelPortrait,
allAppsIconSizes[INDEX_DEFAULT]);
@@ -1056,18 +1048,6 @@
R.styleable.ProfileDisplayOption_horizontalMarginTwoPanelPortrait,
horizontalMargin[INDEX_DEFAULT]);
- hotseatBorderSpaces[INDEX_DEFAULT] = a.getFloat(
- R.styleable.ProfileDisplayOption_hotseatBorderSpace, borderSpace);
- hotseatBorderSpaces[INDEX_LANDSCAPE] = a.getFloat(
- R.styleable.ProfileDisplayOption_hotseatBorderSpaceLandscape,
- hotseatBorderSpaces[INDEX_DEFAULT]);
- hotseatBorderSpaces[INDEX_TWO_PANEL_LANDSCAPE] = a.getFloat(
- R.styleable.ProfileDisplayOption_hotseatBorderSpaceTwoPanelLandscape,
- hotseatBorderSpaces[INDEX_DEFAULT]);
- hotseatBorderSpaces[INDEX_TWO_PANEL_PORTRAIT] = a.getFloat(
- R.styleable.ProfileDisplayOption_hotseatBorderSpaceTwoPanelPortrait,
- hotseatBorderSpaces[INDEX_DEFAULT]);
-
hotseatBarBottomSpace[INDEX_DEFAULT] = a.getFloat(
R.styleable.ProfileDisplayOption_hotseatBarBottomSpace,
ResourcesCompat.getFloat(context.getResources(),
@@ -1130,7 +1110,6 @@
minCellSize[i].x *= w;
minCellSize[i].y *= w;
horizontalMargin[i] *= w;
- hotseatBorderSpaces[i] *= w;
hotseatBarBottomSpace[i] *= w;
hotseatQsbSpace[i] *= w;
allAppsCellSize[i].x *= w;
@@ -1155,7 +1134,6 @@
minCellSize[i].x += p.minCellSize[i].x;
minCellSize[i].y += p.minCellSize[i].y;
horizontalMargin[i] += p.horizontalMargin[i];
- hotseatBorderSpaces[i] += p.hotseatBorderSpaces[i];
hotseatBarBottomSpace[i] += p.hotseatBarBottomSpace[i];
hotseatQsbSpace[i] += p.hotseatQsbSpace[i];
allAppsCellSize[i].x += p.allAppsCellSize[i].x;
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 38b46b0..761f198 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -18,8 +18,6 @@
import static android.app.PendingIntent.FLAG_IMMUTABLE;
import static android.app.PendingIntent.FLAG_UPDATE_CURRENT;
-import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION;
-import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE;
import static android.content.pm.ActivityInfo.CONFIG_UI_MODE;
import static android.view.View.IMPORTANT_FOR_ACCESSIBILITY_NO;
import static android.view.accessibility.AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED;
@@ -310,8 +308,6 @@
private static final FloatProperty<Hotseat> HOTSEAT_WIDGET_SCALE =
HOTSEAT_SCALE_PROPERTY_FACTORY.get(SCALE_INDEX_WIDGET_TRANSITION);
- private Configuration mOldConfig;
-
@Thunk
Workspace<?> mWorkspace;
@Thunk
@@ -466,7 +462,6 @@
super.onCreate(savedInstanceState);
LauncherAppState app = LauncherAppState.getInstance(this);
- mOldConfig = new Configuration(getResources().getConfiguration());
mModel = app.getModel();
mRotationHelper = new RotationHelper(this);
@@ -614,17 +609,6 @@
dispatchDeviceProfileChanged();
}
- @Override
- public void onConfigurationChanged(Configuration newConfig) {
- int diff = newConfig.diff(mOldConfig);
- if ((diff & (CONFIG_ORIENTATION | CONFIG_SCREEN_SIZE)) != 0) {
- onIdpChanged(false);
- }
-
- mOldConfig.setTo(newConfig);
- super.onConfigurationChanged(newConfig);
- }
-
/**
* Initializes the drag controller.
*/
@@ -634,6 +618,11 @@
@Override
public void onIdpChanged(boolean modelPropertiesChanged) {
+ onHandleConfigurationChanged();
+ }
+
+ @Override
+ protected void onHandleConfigurationChanged() {
if (!initDeviceProfile(mDeviceProfile.inv)) {
return;
}
@@ -1505,7 +1494,7 @@
root.getViewTreeObserver().removeOnDrawListener(mViewCapture);
}
mViewCapture = new ViewCapture(root);
- root.getViewTreeObserver().addOnDrawListener(mViewCapture);
+ mViewCapture.attach();
}
}
@@ -3027,7 +3016,10 @@
writer.println(prefix + "\tmAppWidgetHost.isListening: " + mAppWidgetHost.isListening());
if (mViewCapture != null) {
- writer.println(prefix + "\tmViewCapture: " + mViewCapture.dumpToString());
+ writer.print(prefix + "\tmViewCapture: ");
+ writer.flush();
+ mViewCapture.dump(fd);
+ writer.println();
}
// Extra logging for general debugging
diff --git a/src/com/android/launcher3/LauncherRootView.java b/src/com/android/launcher3/LauncherRootView.java
index a5c5c02..1592154 100644
--- a/src/com/android/launcher3/LauncherRootView.java
+++ b/src/com/android/launcher3/LauncherRootView.java
@@ -55,6 +55,8 @@
@Override
public WindowInsets onApplyWindowInsets(WindowInsets insets) {
+ mActivity.handleConfigurationChanged(mActivity.getResources().getConfiguration());
+
insets = WindowManagerProxy.INSTANCE.get(getContext())
.normalizeWindowInsets(getContext(), insets, mTempRect);
handleSystemWindowInsets(mTempRect);
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 83d0752..4c9542d 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -2122,7 +2122,8 @@
final ItemInfo info = (ItemInfo) cell.getTag();
boolean isWidget = info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET
|| info.itemType == LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET;
- if (isWidget) {
+ if (isWidget && dropTargetLayout != null) {
+ // animate widget to a valid place
int animationType = resizeOnDrop ? ANIMATE_INTO_POSITION_AND_RESIZE :
ANIMATE_INTO_POSITION_AND_DISAPPEAR;
animateWidgetDrop(info, parent, d.dragView, null, animationType, cell, false);
@@ -2424,7 +2425,8 @@
} else if ((mDragMode == DRAG_MODE_NONE || mDragMode == DRAG_MODE_REORDER)
&& !mReorderAlarm.alarmPending()
&& (mLastReorderX != reorderX || mLastReorderY != reorderY)
- && targetCellDistance < mDragTargetLayout.getReorderRadius(mTargetCell)) {
+ && targetCellDistance < mDragTargetLayout.getReorderRadius(mTargetCell, item.spanX,
+ item.spanY)) {
int[] resultSpan = new int[2];
mDragTargetLayout.performReorder((int) mDragViewVisualCenter[0],
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index bdab03f..ecc9d7e 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -232,7 +232,15 @@
// Reset pull back progress and alpha after switching states.
ALL_APPS_PULL_BACK_TRANSLATION.set(this, 0f);
ALL_APPS_PULL_BACK_ALPHA.set(this, 1f);
- mLauncher.getAppsView().getSearchUiManager().getEditText().hideKeyboard();
+
+ // We only want to close the keyboard if the animation has completed successfully.
+ // The reason is that with keyboard sync, if the user swipes down from All Apps with
+ // the keyboard open and then changes their mind and swipes back up, we want the
+ // keyboard to remain open. However an onCancel signal is sent to the listeners
+ // (success = false), so we need to check for that.
+ if (success) {
+ mLauncher.getAppsView().getSearchUiManager().getEditText().hideKeyboard();
+ }
});
}
diff --git a/src/com/android/launcher3/allapps/WorkModeSwitch.java b/src/com/android/launcher3/allapps/WorkModeSwitch.java
index aee7c4c..fedc91f 100644
--- a/src/com/android/launcher3/allapps/WorkModeSwitch.java
+++ b/src/com/android/launcher3/allapps/WorkModeSwitch.java
@@ -91,12 +91,12 @@
MarginLayoutParams lp = (MarginLayoutParams) getLayoutParams();
if (lp != null) {
int bottomMargin = getResources().getDimensionPixelSize(R.dimen.work_fab_margin_bottom);
+ DeviceProfile dp = ActivityContext.lookupContext(getContext()).getDeviceProfile();
if (FeatureFlags.ENABLE_FLOATING_SEARCH_BAR.get()) {
bottomMargin <<= 1; // Double margin to add space above search bar.
- bottomMargin += getResources().getDimensionPixelSize(R.dimen.qsb_widget_height);
+ bottomMargin += dp.hotseatQsbHeight;
}
- DeviceProfile dp = ActivityContext.lookupContext(getContext()).getDeviceProfile();
if (!dp.isGestureMode) {
if (dp.isTaskbarPresent) {
bottomMargin += dp.taskbarSize;
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 4fd13b2..f5683d1 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -265,6 +265,11 @@
public static final BooleanFlag ENABLE_ONE_SEARCH_MOTION = new DeviceFlag(
"ENABLE_ONE_SEARCH_MOTION", true, "Enables animations in OneSearch.");
+ public static final BooleanFlag ENABLE_KEYBOARD_TRANSITION_SYNC = new DeviceFlag(
+ "ENABLE_KEYBOARD_TRANSITION_SYNC", false,
+ "Enable option to synchronize the keyboard open and close animations when transitioning"
+ + " between home and all apps");
+
public static final BooleanFlag ENABLE_SHOW_KEYBOARD_OPTION_IN_ALL_APPS = new DeviceFlag(
"ENABLE_SHOW_KEYBOARD_OPTION_IN_ALL_APPS", true,
"Enable option to show keyboard when going to all-apps");
diff --git a/src/com/android/launcher3/graphics/ShadowDrawable.java b/src/com/android/launcher3/graphics/ShadowDrawable.java
deleted file mode 100644
index d8a7070..0000000
--- a/src/com/android/launcher3/graphics/ShadowDrawable.java
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * Copyright (C) 2017 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.launcher3.graphics;
-
-import android.annotation.TargetApi;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.graphics.Bitmap;
-import android.graphics.BlurMaskFilter;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.ColorFilter;
-import android.graphics.Paint;
-import android.graphics.PixelFormat;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.os.Build;
-import android.util.AttributeSet;
-
-import com.android.launcher3.R;
-import com.android.launcher3.icons.BitmapRenderer;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.IOException;
-
-/**
- * A drawable which adds shadow around a child drawable.
- */
-@TargetApi(Build.VERSION_CODES.O)
-public class ShadowDrawable extends Drawable {
-
- private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
-
- private final ShadowDrawableState mState;
-
- @SuppressWarnings("unused")
- public ShadowDrawable() {
- this(new ShadowDrawableState());
- }
-
- private ShadowDrawable(ShadowDrawableState state) {
- mState = state;
- }
-
- @Override
- public void draw(Canvas canvas) {
- Rect bounds = getBounds();
- if (bounds.isEmpty()) {
- return;
- }
- if (mState.mLastDrawnBitmap == null) {
- regenerateBitmapCache();
- }
- canvas.drawBitmap(mState.mLastDrawnBitmap, null, bounds, mPaint);
- }
-
- @Override
- public void setAlpha(int alpha) {
- mPaint.setAlpha(alpha);
- invalidateSelf();
- }
-
- @Override
- public void setColorFilter(ColorFilter colorFilter) {
- mPaint.setColorFilter(colorFilter);
- invalidateSelf();
- }
-
- @Override
- public ConstantState getConstantState() {
- return mState;
- }
-
- @Override
- public int getOpacity() {
- return PixelFormat.TRANSLUCENT;
- }
-
- @Override
- public int getIntrinsicHeight() {
- return mState.mIntrinsicHeight;
- }
-
- @Override
- public int getIntrinsicWidth() {
- return mState.mIntrinsicWidth;
- }
-
- @Override
- public boolean canApplyTheme() {
- return mState.canApplyTheme();
- }
-
- @Override
- public void applyTheme(Resources.Theme t) {
- TypedArray ta = t.obtainStyledAttributes(new int[] {R.attr.isWorkspaceDarkText});
- boolean isDark = ta.getBoolean(0, false);
- ta.recycle();
- if (mState.mIsDark != isDark) {
- mState.mIsDark = isDark;
- mState.mLastDrawnBitmap = null;
- invalidateSelf();
- }
- }
-
- private void regenerateBitmapCache() {
- // Call mutate, so that the pixel allocation by the underlying vector drawable is cleared.
- Drawable d = mState.mChildState.newDrawable().mutate();
- d.setBounds(mState.mShadowSize, mState.mShadowSize,
- mState.mIntrinsicWidth - mState.mShadowSize,
- mState.mIntrinsicHeight - mState.mShadowSize);
- d.setTint(mState.mIsDark ? mState.mDarkTintColor : Color.WHITE);
-
- if (mState.mIsDark) {
- // Dark text do not have any shadow, but just the bitmap
- mState.mLastDrawnBitmap = BitmapRenderer.createHardwareBitmap(
- mState.mIntrinsicWidth, mState.mIntrinsicHeight, d::draw);
- } else {
- Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
- paint.setMaskFilter(new BlurMaskFilter(mState.mShadowSize, BlurMaskFilter.Blur.NORMAL));
-
- // Generate the shadow bitmap
- int[] offset = new int[2];
- Bitmap shadow = BitmapRenderer.createSoftwareBitmap(
- mState.mIntrinsicWidth, mState.mIntrinsicHeight, d::draw)
- .extractAlpha(paint, offset);
-
- paint.setMaskFilter(null);
- paint.setColor(mState.mShadowColor);
- mState.mLastDrawnBitmap = BitmapRenderer.createHardwareBitmap(
- mState.mIntrinsicWidth, mState.mIntrinsicHeight, c -> {
- c.drawBitmap(shadow, offset[0], offset[1], paint);
- d.draw(c);
- });
- }
- }
-
- @Override
- public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs,
- Resources.Theme theme) throws XmlPullParserException, IOException {
- super.inflate(r, parser, attrs, theme);
-
- final TypedArray a = theme == null
- ? r.obtainAttributes(attrs, R.styleable.ShadowDrawable)
- : theme.obtainStyledAttributes(attrs, R.styleable.ShadowDrawable, 0, 0);
- try {
- Drawable d = a.getDrawable(R.styleable.ShadowDrawable_android_src);
- if (d == null) {
- throw new XmlPullParserException("missing src attribute");
- }
- mState.mShadowColor = a.getColor(
- R.styleable.ShadowDrawable_android_shadowColor, Color.BLACK);
- mState.mShadowSize = a.getDimensionPixelSize(
- R.styleable.ShadowDrawable_android_elevation, 0);
- mState.mDarkTintColor = a.getColor(
- R.styleable.ShadowDrawable_darkTintColor, Color.BLACK);
-
- mState.mIntrinsicHeight = d.getIntrinsicHeight() + 2 * mState.mShadowSize;
- mState.mIntrinsicWidth = d.getIntrinsicWidth() + 2 * mState.mShadowSize;
- mState.mChangingConfigurations = d.getChangingConfigurations();
-
- mState.mChildState = d.getConstantState();
- } finally {
- a.recycle();
- }
- }
-
- private static class ShadowDrawableState extends ConstantState {
-
- int mChangingConfigurations;
- int mIntrinsicWidth;
- int mIntrinsicHeight;
-
- int mShadowColor;
- int mShadowSize;
- int mDarkTintColor;
-
- boolean mIsDark;
- Bitmap mLastDrawnBitmap;
- ConstantState mChildState;
-
- @Override
- public Drawable newDrawable() {
- return new ShadowDrawable(this);
- }
-
- @Override
- public int getChangingConfigurations() {
- return mChangingConfigurations;
- }
-
- @Override
- public boolean canApplyTheme() {
- return true;
- }
- }
-}
diff --git a/src/com/android/launcher3/statemanager/StatefulActivity.java b/src/com/android/launcher3/statemanager/StatefulActivity.java
index 2158dea..2a890c3 100644
--- a/src/com/android/launcher3/statemanager/StatefulActivity.java
+++ b/src/com/android/launcher3/statemanager/StatefulActivity.java
@@ -15,9 +15,14 @@
*/
package com.android.launcher3.statemanager;
+import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION;
+import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE;
+
import static com.android.launcher3.LauncherState.FLAG_CLOSE_POPUPS;
import static com.android.launcher3.LauncherState.FLAG_NON_INTERACTIVE;
+import android.content.res.Configuration;
+import android.os.Bundle;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.View;
@@ -30,6 +35,7 @@
import com.android.launcher3.Utilities;
import com.android.launcher3.statemanager.StateManager.AtomicAnimationFactory;
import com.android.launcher3.statemanager.StateManager.StateHandler;
+import com.android.launcher3.util.window.WindowManagerProxy;
import com.android.launcher3.views.BaseDragLayer;
import java.util.List;
@@ -47,6 +53,17 @@
private LauncherRootView mRootView;
+ protected Configuration mOldConfig;
+ private int mOldRotation;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ mOldConfig = new Configuration(getResources().getConfiguration());
+ mOldRotation = WindowManagerProxy.INSTANCE.get(this).getRotation(this);
+ }
+
/**
* Create handlers to control the property changes for this activity
*/
@@ -186,4 +203,32 @@
public void runOnBindToTouchInteractionService(Runnable r) {
r.run();
}
+
+ @Override
+ public void onConfigurationChanged(Configuration newConfig) {
+ handleConfigurationChanged(newConfig);
+ super.onConfigurationChanged(newConfig);
+ }
+
+ /**
+ * Handles configuration change when system calls {@link #onConfigurationChanged}, or on other
+ * situations that configuration might change.
+ */
+ public void handleConfigurationChanged(Configuration newConfig) {
+ int diff = newConfig.diff(mOldConfig);
+ int rotation = WindowManagerProxy.INSTANCE.get(this).getRotation(this);
+ if ((diff & (CONFIG_ORIENTATION | CONFIG_SCREEN_SIZE)) != 0
+ || rotation != mOldRotation) {
+ onHandleConfigurationChanged();
+ }
+
+ mOldConfig.setTo(newConfig);
+ mOldRotation = rotation;
+ }
+
+ /**
+ * Logic for when device configuration changes (rotation, screen size change, multi-window,
+ * etc.)
+ */
+ protected abstract void onHandleConfigurationChanged();
}
diff --git a/src/com/android/launcher3/states/SpringLoadedState.java b/src/com/android/launcher3/states/SpringLoadedState.java
index 3ca8ba2..b63715c 100644
--- a/src/com/android/launcher3/states/SpringLoadedState.java
+++ b/src/com/android/launcher3/states/SpringLoadedState.java
@@ -58,7 +58,7 @@
float myCenter = ws.getTop() + halfHeight;
float cellTopFromCenter = halfHeight - ws.getChildAt(0).getTop();
float actualCellTop = myCenter - cellTopFromCenter * scale;
- return new ScaleAndTranslation(scale, 0, (shrunkTop - actualCellTop) / scale);
+ return new ScaleAndTranslation(scale, 0, shrunkTop - actualCellTop);
}
@Override
diff --git a/src/com/android/launcher3/util/ViewCapture.java b/src/com/android/launcher3/util/ViewCapture.java
index 140971b..cf4e84a 100644
--- a/src/com/android/launcher3/util/ViewCapture.java
+++ b/src/com/android/launcher3/util/ViewCapture.java
@@ -15,24 +15,30 @@
*/
package com.android.launcher3.util;
+import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
+
import android.content.res.Resources;
import android.os.Handler;
-import android.os.Looper;
-import android.os.SystemClock;
+import android.os.Message;
import android.os.Trace;
import android.util.Base64;
+import android.util.Base64OutputStream;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver.OnDrawListener;
import androidx.annotation.UiThread;
+import androidx.annotation.WorkerThread;
import com.android.launcher3.view.ViewCaptureData.ExportedData;
import com.android.launcher3.view.ViewCaptureData.FrameData;
import com.android.launcher3.view.ViewCaptureData.ViewNode;
-import java.util.concurrent.FutureTask;
+import java.io.FileDescriptor;
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.util.concurrent.Future;
/**
* Utility class for capturing view data every frame
@@ -41,122 +47,191 @@
private static final String TAG = "ViewCapture";
+ // Number of frames to keep in memory
private static final int MEMORY_SIZE = 2000;
+ // Initial size of the reference pool. This is at least be 5 * total number of views in
+ // Launcher. This allows the first free frames avoid object allocation during view capture.
+ private static final int INIT_POOL_SIZE = 300;
private final View mRoot;
- private final long[] mFrameTimes = new long[MEMORY_SIZE];
- private final Node[] mNodes = new Node[MEMORY_SIZE];
+ private final Resources mResources;
- private int mFrameIndex = -1;
+ private final Handler mHandler;
+ private final ViewRef mViewRef = new ViewRef();
+
+ private int mFrameIndexBg = -1;
+ private final long[] mFrameTimesBg = new long[MEMORY_SIZE];
+ private final ViewPropertyRef[] mNodesBg = new ViewPropertyRef[MEMORY_SIZE];
+
+ // Pool used for capturing view tree on the UI thread.
+ private ViewRef mPool = new ViewRef();
/**
* @param root the root view for the capture data
*/
public ViewCapture(View root) {
mRoot = root;
+ mResources = root.getResources();
+ mHandler = new Handler(UI_HELPER_EXECUTOR.getLooper(), this::captureViewPropertiesBg);
+ }
+
+ /**
+ * Attaches the ViewCapture to the root
+ */
+ public void attach() {
+ mHandler.post(this::initPool);
}
@Override
public void onDraw() {
Trace.beginSection("view_capture");
- long now = SystemClock.elapsedRealtimeNanos();
-
- mFrameIndex++;
- if (mFrameIndex >= MEMORY_SIZE) {
- mFrameIndex = 0;
- }
- mFrameTimes[mFrameIndex] = now;
- mNodes[mFrameIndex] = captureView(mRoot, mNodes[mFrameIndex]);
+ captureViewTree(mRoot, mViewRef);
+ Message m = Message.obtain(mHandler);
+ m.obj = mViewRef.next;
+ mHandler.sendMessage(m);
Trace.endSection();
}
/**
+ * Captures the View property on the background thread, and transfer all the ViewRef objects
+ * back to the pool
+ */
+ @WorkerThread
+ private boolean captureViewPropertiesBg(Message msg) {
+ ViewRef start = (ViewRef) msg.obj;
+ long time = msg.getWhen();
+ if (start == null) {
+ return false;
+ }
+ mFrameIndexBg++;
+ if (mFrameIndexBg >= MEMORY_SIZE) {
+ mFrameIndexBg = 0;
+ }
+ mFrameTimesBg[mFrameIndexBg] = time;
+
+ ViewPropertyRef recycle = mNodesBg[mFrameIndexBg];
+
+ ViewPropertyRef result = null;
+ ViewPropertyRef resultEnd = null;
+
+ ViewRef current = start;
+ ViewRef last = start;
+ while (current != null) {
+ ViewPropertyRef propertyRef = recycle;
+ if (propertyRef == null) {
+ propertyRef = new ViewPropertyRef();
+ } else {
+ recycle = recycle.next;
+ propertyRef.next = null;
+ }
+
+ propertyRef.transfer(current);
+ last = current;
+ current = current.next;
+
+ if (result == null) {
+ result = propertyRef;
+ resultEnd = result;
+ } else {
+ resultEnd.next = propertyRef;
+ resultEnd = propertyRef;
+ }
+ }
+ mNodesBg[mFrameIndexBg] = result;
+ ViewRef end = last;
+ Executors.MAIN_EXECUTOR.execute(() -> addToPool(start, end));
+ return true;
+ }
+
+ @UiThread
+ private void addToPool(ViewRef start, ViewRef end) {
+ end.next = mPool;
+ mPool = start;
+ }
+
+ @WorkerThread
+ private void initPool() {
+ ViewRef start = new ViewRef();
+ ViewRef current = start;
+
+ for (int i = 0; i < INIT_POOL_SIZE; i++) {
+ current.next = new ViewRef();
+ current = current.next;
+ }
+
+ ViewRef end = current;
+ Executors.MAIN_EXECUTOR.execute(() -> {
+ addToPool(start, end);
+ if (mRoot.isAttachedToWindow()) {
+ mRoot.getViewTreeObserver().addOnDrawListener(this);
+ }
+ });
+ }
+
+ /**
* Creates a proto of all the data captured so far.
*/
- public String dumpToString() {
- Handler handler = mRoot.getHandler();
- if (handler == null) {
- handler = Executors.MAIN_EXECUTOR.getHandler();
- }
- FutureTask<ExportedData> task = new FutureTask<>(this::dumpToProtoUI);
- if (Looper.myLooper() == handler.getLooper()) {
- task.run();
- } else {
- handler.post(task);
- }
- try {
- return Base64.encodeToString(task.get().toByteArray(),
+ public void dump(FileDescriptor out) {
+ Future<ExportedData> task = UI_HELPER_EXECUTOR.submit(this::dumpToProto);
+ try (OutputStream os = new FileOutputStream(out)) {
+ ExportedData data = task.get();
+ Base64OutputStream encodedOS = new Base64OutputStream(os,
Base64.NO_CLOSE | Base64.NO_PADDING | Base64.NO_WRAP);
+ data.writeTo(encodedOS);
+ encodedOS.close();
+ os.flush();
} catch (Exception e) {
Log.e(TAG, "Error capturing proto", e);
- return "--error--";
}
}
- @UiThread
- private ExportedData dumpToProtoUI() {
+ @WorkerThread
+ private ExportedData dumpToProto() {
ExportedData.Builder dataBuilder = ExportedData.newBuilder();
- Resources res = mRoot.getResources();
+ Resources res = mResources;
- int size = (mNodes[MEMORY_SIZE - 1] == null) ? mFrameIndex + 1 : MEMORY_SIZE;
+ int size = (mNodesBg[MEMORY_SIZE - 1] == null) ? mFrameIndexBg + 1 : MEMORY_SIZE;
for (int i = size - 1; i >= 0; i--) {
- int index = (MEMORY_SIZE + mFrameIndex - i) % MEMORY_SIZE;
+ int index = (MEMORY_SIZE + mFrameIndexBg - i) % MEMORY_SIZE;
+ ViewNode.Builder nodeBuilder = ViewNode.newBuilder();
+ mNodesBg[index].toProto(res, nodeBuilder);
dataBuilder.addFrameData(FrameData.newBuilder()
- .setNode(mNodes[index].toProto(res))
- .setTimestamp(mFrameTimes[index]));
+ .setNode(nodeBuilder)
+ .setTimestamp(mFrameTimesBg[index]));
}
return dataBuilder.build();
}
- private Node captureView(View view, Node recycle) {
- Node result = recycle == null ? new Node() : recycle;
-
- result.clazz = view.getClass();
- result.hashCode = view.hashCode();
- result.id = view.getId();
- result.left = view.getLeft();
- result.top = view.getTop();
- result.right = view.getRight();
- result.bottom = view.getBottom();
- result.scrollX = view.getScrollX();
- result.scrollY = view.getScrollY();
-
- result.translateX = view.getTranslationX();
- result.translateY = view.getTranslationY();
- result.scaleX = view.getScaleX();
- result.scaleY = view.getScaleY();
- result.alpha = view.getAlpha();
-
- result.visibility = view.getVisibility();
- result.willNotDraw = view.willNotDraw();
-
- if (view instanceof ViewGroup) {
- ViewGroup parent = (ViewGroup) view;
- result.clipChildren = parent.getClipChildren();
- int childCount = parent.getChildCount();
- if (childCount == 0) {
- result.children = null;
- } else {
- result.children = captureView(parent.getChildAt(0), result.children);
- Node lastChild = result.children;
- for (int i = 1; i < childCount; i++) {
- lastChild.sibling = captureView(parent.getChildAt(i), lastChild.sibling);
- lastChild = lastChild.sibling;
- }
- lastChild.sibling = null;
- }
+ private ViewRef captureViewTree(View view, ViewRef start) {
+ ViewRef ref;
+ if (mPool != null) {
+ ref = mPool;
+ mPool = mPool.next;
+ ref.next = null;
} else {
- result.clipChildren = false;
- result.children = null;
+ ref = new ViewRef();
}
- return result;
+ ref.view = view;
+ start.next = ref;
+ if (view instanceof ViewGroup) {
+ ViewRef result = ref;
+ ViewGroup parent = (ViewGroup) view;
+ int childCount = ref.childCount = parent.getChildCount();
+ for (int i = 0; i < childCount; i++) {
+ result = captureViewTree(parent.getChildAt(i), result);
+ }
+ return result;
+ } else {
+ ref.childCount = 0;
+ return ref;
+ }
}
- private static class Node {
-
+ private static class ViewPropertyRef {
// We store reference in memory to avoid generating and storing too many strings
public Class clazz;
public int hashCode;
+ public int childCount = 0;
public int id;
public int left, top, right, bottom;
@@ -170,10 +245,41 @@
public boolean willNotDraw;
public boolean clipChildren;
- public Node sibling;
- public Node children;
+ public ViewPropertyRef next;
- public ViewNode toProto(Resources res) {
+ public void transfer(ViewRef viewRef) {
+ childCount = viewRef.childCount;
+
+ View view = viewRef.view;
+ viewRef.view = null;
+
+ clazz = view.getClass();
+ hashCode = view.hashCode();
+ id = view.getId();
+ left = view.getLeft();
+ top = view.getTop();
+ right = view.getRight();
+ bottom = view.getBottom();
+ scrollX = view.getScrollX();
+ scrollY = view.getScrollY();
+
+ translateX = view.getTranslationX();
+ translateY = view.getTranslationY();
+ scaleX = view.getScaleX();
+ scaleY = view.getScaleY();
+ alpha = view.getAlpha();
+
+ visibility = view.getVisibility();
+ willNotDraw = view.willNotDraw();
+ }
+
+ /**
+ * Converts the data to the proto representation and returns the next property ref
+ * at the end of the iteration.
+ * @param res
+ * @return
+ */
+ public ViewPropertyRef toProto(Resources res, ViewNode.Builder outBuilder) {
String resolvedId;
if (id >= 0) {
try {
@@ -184,9 +290,7 @@
} else {
resolvedId = "NO_ID";
}
-
- ViewNode.Builder result = ViewNode.newBuilder()
- .setClassname(clazz.getName() + "@" + hashCode)
+ outBuilder.setClassname(clazz.getName() + "@" + hashCode)
.setId(resolvedId)
.setLeft(left)
.setTop(top)
@@ -200,13 +304,20 @@
.setVisibility(visibility)
.setWillNotDraw(willNotDraw)
.setClipChildren(clipChildren);
- Node child = children;
- while (child != null) {
- result.addChildren(child.toProto(res));
- child = child.sibling;
- }
- return result.build();
- }
+ ViewPropertyRef result = next;
+ for (int i = 0; (i < childCount) && (result != null); i++) {
+ ViewNode.Builder childBuilder = ViewNode.newBuilder();
+ result = result.toProto(res, childBuilder);
+ outBuilder.addChildren(childBuilder);
+ }
+ return result;
+ }
+ }
+
+ private static class ViewRef {
+ public View view;
+ public int childCount = 0;
+ public ViewRef next;
}
}
diff --git a/tests/Android.bp b/tests/Android.bp
index 54cded0..1584308 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -24,6 +24,18 @@
"src/**/*.java",
"src/**/*.kt"
],
+ exclude_srcs: [
+ ":launcher-non-quickstep-tests-src"
+ ],
+}
+
+// Source code used for non-quickstep tests
+filegroup {
+ name: "launcher-non-quickstep-tests-src",
+ srcs: [
+ "src/com/android/launcher3/nonquickstep/**/*.java",
+ "src/com/android/launcher3/nonquickstep/**/*.kt",
+ ],
}
// Source code used for oop test helpers
@@ -84,6 +96,7 @@
name: "Launcher3Tests",
srcs: [
":launcher-tests-src",
+ ":launcher-non-quickstep-tests-src",
],
static_libs: ["Launcher3TestLib"],
libs: [
diff --git a/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt b/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt
index 4732fc1..cf6be7f 100644
--- a/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt
+++ b/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt
@@ -18,6 +18,7 @@
import android.content.Context
import android.graphics.PointF
import android.graphics.Rect
+import android.util.SparseArray
import androidx.test.core.app.ApplicationProvider
import com.android.launcher3.util.DisplayController.Info
import com.android.launcher3.util.WindowBounds
@@ -56,6 +57,7 @@
inv,
info,
windowBounds,
+ SparseArray(),
isMultiWindowMode,
transposeLayoutWithOrientation,
useTwoPanels,
@@ -112,7 +114,6 @@
PointF(16f, 16f)
).toTypedArray()
folderBorderSpace = 16f
- hotseatBorderSpaces = FloatArray(4) { 16f }
inlineNavButtonsEndSpacing = R.dimen.taskbar_button_margin_4_5
horizontalMargin = FloatArray(4) { 22f }
@@ -134,8 +135,6 @@
numShownHotseatIcons = 4
- numShrunkenHotseatIcons = 4
-
numDatabaseHotseatIcons = 4
hotseatColumnSpan = IntArray(4) { 4 }
@@ -198,7 +197,6 @@
PointF(16f, 64f),
PointF(16f, 64f)
).toTypedArray()
- hotseatBorderSpaces = floatArrayOf(58f, 50.4f, 58f, 58f)
inlineNavButtonsEndSpacing = R.dimen.taskbar_button_margin_6_5
horizontalMargin = floatArrayOf(54f, 120f, 54f, 54f)
@@ -220,8 +218,6 @@
numShownHotseatIcons = 6
- numShrunkenHotseatIcons = 5
-
numDatabaseHotseatIcons = 6
hotseatColumnSpan = intArrayOf(6, 4, 6, 6)
@@ -295,7 +291,6 @@
PointF(20f, 20f)
).toTypedArray()
folderBorderSpace = 16f
- hotseatBorderSpaces = floatArrayOf(36f, 36f, 18f, 23.3f)
inlineNavButtonsEndSpacing = R.dimen.taskbar_button_margin_4_4
horizontalMargin = floatArrayOf(21.5f, 21.5f, 22.5f, 30.5f)
@@ -317,8 +312,6 @@
numShownHotseatIcons = 6
- numShrunkenHotseatIcons = 6
-
numDatabaseHotseatIcons = 6
hotseatColumnSpan = IntArray(4) { 6 }
diff --git a/tests/src/com/android/launcher3/HotseatShownIconsTest.kt b/tests/src/com/android/launcher3/HotseatShownIconsTest.kt
deleted file mode 100644
index 95651ca..0000000
--- a/tests/src/com/android/launcher3/HotseatShownIconsTest.kt
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * Copyright (C) 2022 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.launcher3
-
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.SmallTest
-import com.android.launcher3.InvariantDeviceProfile.TYPE_MULTI_DISPLAY
-import com.android.launcher3.InvariantDeviceProfile.TYPE_PHONE
-import com.android.launcher3.InvariantDeviceProfile.TYPE_TABLET
-import com.google.common.truth.Truth.assertThat
-import org.junit.Test
-import org.junit.runner.RunWith
-
-/**
- * Test for [DeviceProfile]
- */
-@SmallTest
-@RunWith(AndroidJUnit4::class)
-class HotseatShownIconsTest : DeviceProfileBaseTest() {
-
- @Test
- fun hotseat_size_is_shrunk_if_needed_when_large_screen() {
- initializeVarsForTablet(isLandscape = true)
- inv = inv!!.apply {
- deviceType = TYPE_MULTI_DISPLAY
- inlineQsb = booleanArrayOf(
- false,
- false,
- false,
- true // two panels landscape
- )
- }
- useTwoPanels = true
-
- isGestureMode = false
- val dp = newDP()
-
- if (dp.hotseatQsbHeight > 0) {
- assertThat(dp.isQsbInline).isTrue()
- assertThat(dp.numShownHotseatIcons).isEqualTo(5)
- } else { // Launcher3 doesn't have QSB height
- assertThat(dp.isQsbInline).isFalse()
- assertThat(dp.numShownHotseatIcons).isEqualTo(6)
- }
- }
-
- /**
- * For consistency, the hotseat should shrink if any orientation on the device type has an
- * inline qsb
- */
- @Test
- fun hotseat_size_is_shrunk_even_in_portrait_when_large_screen() {
- initializeVarsForTablet()
- inv = inv!!.apply {
- deviceType = TYPE_MULTI_DISPLAY
- inlineQsb = booleanArrayOf(
- false,
- false,
- false,
- true // two panels landscape
- )
- }
- useTwoPanels = true
-
- isGestureMode = false
- val dp = newDP()
-
- if (dp.hotseatQsbHeight > 0) {
- assertThat(dp.isQsbInline).isFalse()
- assertThat(dp.numShownHotseatIcons).isEqualTo(5)
- } else { // Launcher3 doesn't have QSB height
- assertThat(dp.isQsbInline).isFalse()
- assertThat(dp.numShownHotseatIcons).isEqualTo(6)
- }
- }
-
- @Test
- fun hotseat_size_is_default_when_small_screen() {
- initializeVarsForPhone()
- inv = inv!!.apply {
- deviceType = TYPE_MULTI_DISPLAY
- }
- useTwoPanels = true
-
- val dp = newDP()
-
- assertThat(dp.numShownHotseatIcons).isEqualTo(4)
- }
-
- @Test
- fun hotseat_size_is_not_shrunk_on_gesture_tablet() {
- initializeVarsForTablet(isLandscape = true)
- inv = inv!!.apply {
- deviceType = TYPE_TABLET
- inlineQsb = booleanArrayOf(
- false,
- true, // landscape
- false,
- false
- )
- numShownHotseatIcons = 6
- }
-
- isGestureMode = true
- val dp = newDP()
-
- if (dp.hotseatQsbHeight > 0) {
- assertThat(dp.isQsbInline).isTrue()
- assertThat(dp.numShownHotseatIcons).isEqualTo(6)
- } else { // Launcher3 doesn't have QSB height
- assertThat(dp.isQsbInline).isFalse()
- assertThat(dp.numShownHotseatIcons).isEqualTo(6)
- }
- }
-
- @Test
- fun hotseat_size_is_shrunk_if_needed_on_tablet() {
- initializeVarsForTablet(isLandscape = true)
- inv = inv!!.apply {
- deviceType = TYPE_TABLET
- inlineQsb = booleanArrayOf(
- false,
- true, // landscape
- false,
- false
- )
- numShownHotseatIcons = 6
- }
-
- isGestureMode = false
- val dp = newDP()
-
- if (dp.hotseatQsbHeight > 0) {
- assertThat(dp.isQsbInline).isTrue()
- assertThat(dp.numShownHotseatIcons).isEqualTo(5)
- } else { // Launcher3 doesn't have QSB height
- assertThat(dp.isQsbInline).isFalse()
- assertThat(dp.numShownHotseatIcons).isEqualTo(6)
- }
- }
-
- /**
- * For consistency, the hotseat should shrink if any orientation on the device type has an
- * inline qsb
- */
- @Test
- fun hotseat_size_is_shrunk_even_in_portrait_on_tablet() {
- initializeVarsForTablet()
- inv = inv!!.apply {
- deviceType = TYPE_TABLET
- inlineQsb = booleanArrayOf(
- false,
- true, // landscape
- false,
- false
- )
- numShownHotseatIcons = 6
- }
-
- isGestureMode = false
- val dp = newDP()
-
- if (dp.hotseatQsbHeight > 0) {
- assertThat(dp.isQsbInline).isFalse()
- assertThat(dp.numShownHotseatIcons).isEqualTo(5)
- } else { // Launcher3 doesn't have QSB height
- assertThat(dp.isQsbInline).isFalse()
- assertThat(dp.numShownHotseatIcons).isEqualTo(6)
- }
- }
-
-}
\ No newline at end of file
diff --git a/tests/src/com/android/launcher3/celllayout/testcases/FullReorderCase.java b/tests/src/com/android/launcher3/celllayout/testcases/FullReorderCase.java
index ff03a50..1326389 100644
--- a/tests/src/com/android/launcher3/celllayout/testcases/FullReorderCase.java
+++ b/tests/src/com/android/launcher3/celllayout/testcases/FullReorderCase.java
@@ -20,46 +20,65 @@
import java.util.Map;
public class FullReorderCase {
+
+ /** 5x5 Test
+ **/
private static final String START_BOARD_STR_5x5 = ""
+ "xxxxx\n"
+ "222mm\n"
+ "222mm\n"
+ "ad111\n"
+ "bc111";
-
private static final Point MOVE_TO_5x5 = new Point(0, 4);
-
private static final String END_BOARD_STR_5x5 = ""
+ "xxxxx\n"
+ "222ad\n"
+ "222bc\n"
+ "mm111\n"
+ "mm111";
-
private static final ReorderTestCase TEST_CASE_5x5 = new ReorderTestCase(START_BOARD_STR_5x5,
MOVE_TO_5x5,
END_BOARD_STR_5x5);
+ /** 6x5 Test
+ **/
private static final String START_BOARD_STR_6x5 = ""
+ "xxxxxx\n"
+ "2222mm\n"
+ "2222mm\n"
+ "ad1111\n"
+ "bc1111";
-
private static final Point MOVE_TO_6x5 = new Point(0, 4);
-
private static final String END_BOARD_STR_6x5 = ""
+ "xxxxxx\n"
+ "2222ad\n"
+ "2222bc\n"
+ "mm1111\n"
+ "mm1111";
-
private static final ReorderTestCase TEST_CASE_6x5 = new ReorderTestCase(START_BOARD_STR_6x5,
MOVE_TO_6x5,
END_BOARD_STR_6x5);
+ /** 4x4 Test
+ **/
+ private static final String START_BOARD_STR_4x4 = ""
+ + "xxxx\n"
+ + "22mm\n"
+ + "admm\n"
+ + "bc11";
+ private static final Point MOVE_TO_4x4 = new Point(0, 3);
+ private static final String END_BOARD_STR_4x4 = ""
+ + "xxxx\n"
+ + "22ad\n"
+ + "mmbc\n"
+ + "mm11";
+
+ private static final ReorderTestCase TEST_CASE_4x4 = new ReorderTestCase(START_BOARD_STR_4x4,
+ MOVE_TO_4x4,
+ END_BOARD_STR_4x4);
+
public static final Map<Point, ReorderTestCase> TEST_BY_GRID_SIZE =
- Map.of(new Point(5, 5), TEST_CASE_5x5, new Point(6, 5), TEST_CASE_6x5);
+ Map.of(new Point(5, 5), TEST_CASE_5x5,
+ new Point(6, 5), TEST_CASE_6x5,
+ new Point(4, 4), TEST_CASE_4x4);
}
diff --git a/tests/src/com/android/launcher3/celllayout/testcases/MoveOutReorderCase.java b/tests/src/com/android/launcher3/celllayout/testcases/MoveOutReorderCase.java
index 32bf05a..1701390 100644
--- a/tests/src/com/android/launcher3/celllayout/testcases/MoveOutReorderCase.java
+++ b/tests/src/com/android/launcher3/celllayout/testcases/MoveOutReorderCase.java
@@ -20,47 +20,64 @@
import java.util.Map;
public class MoveOutReorderCase {
+
+ /** 5x5 Test
+ **/
private static final String START_BOARD_STR_5x5 = ""
+ "xxxxx\n"
+ "34-m-\n"
+ "35111\n"
+ "32111\n"
+ "32111";
-
private static final Point MOVE_TO_5x5 = new Point(1, 2);
-
private static final String END_BOARD_STR_5x5 = ""
+ "xxxxx\n"
+ "345--\n"
+ "3m111\n"
+ "32111\n"
+ "32111";
-
private static final ReorderTestCase TEST_CASE_5x5 = new ReorderTestCase(START_BOARD_STR_5x5,
MOVE_TO_5x5,
END_BOARD_STR_5x5);
-
+ /** 6x5 Test
+ **/
private static final String START_BOARD_STR_6x5 = ""
+ "xxxxxx\n"
+ "34-m--\n"
+ "351111\n"
+ "321111\n"
+ "321111";
-
private static final Point MOVE_TO_6x5 = new Point(1, 2);
-
private static final String END_BOARD_STR_6x5 = ""
+ "xxxxxx\n"
+ "345---\n"
+ "3m1111\n"
+ "321111\n"
+ "321111";
-
private static final ReorderTestCase TEST_CASE_6x5 = new ReorderTestCase(START_BOARD_STR_6x5,
MOVE_TO_6x5,
END_BOARD_STR_6x5);
+ /** 4x4 Test
+ **/
+ private static final String START_BOARD_STR_4x4 = ""
+ + "xxxx\n"
+ + "34-m\n"
+ + "3511\n"
+ + "3211";
+ private static final Point MOVE_TO_4x4 = new Point(1, 2);
+ private static final String END_BOARD_STR_4x4 = ""
+ + "xxxx\n"
+ + "345-\n"
+ + "3m11\n"
+ + "3211";
+ private static final ReorderTestCase TEST_CASE_4x4 = new ReorderTestCase(START_BOARD_STR_4x4,
+ MOVE_TO_4x4,
+ END_BOARD_STR_4x4);
+
public static final Map<Point, ReorderTestCase> TEST_BY_GRID_SIZE =
- Map.of(new Point(5, 5), TEST_CASE_5x5, new Point(6, 5), TEST_CASE_6x5);
+ Map.of(new Point(5, 5), TEST_CASE_5x5,
+ new Point(6, 5), TEST_CASE_6x5,
+ new Point(4, 4), TEST_CASE_4x4);
}
diff --git a/tests/src/com/android/launcher3/celllayout/testcases/PushReorderCase.java b/tests/src/com/android/launcher3/celllayout/testcases/PushReorderCase.java
index b386946..bb8d5e9 100644
--- a/tests/src/com/android/launcher3/celllayout/testcases/PushReorderCase.java
+++ b/tests/src/com/android/launcher3/celllayout/testcases/PushReorderCase.java
@@ -17,60 +17,68 @@
import android.graphics.Point;
-import com.android.launcher3.celllayout.CellLayoutBoard;
-
import java.util.Map;
public class PushReorderCase {
+
+ /** 5x5 Test
+ **/
private static final String START_BOARD_STR_5x5 = ""
+ "xxxxx\n"
+ "222m-\n"
+ "--111\n"
+ "--333\n"
+ "-----";
- private static final CellLayoutBoard START_BOARD_5x5 = CellLayoutBoard.boardFromString(
- START_BOARD_STR_5x5);
-
private static final Point MOVE_TO_5x5 = new Point(2, 1);
-
private static final String END_BOARD_STR_5x5 = ""
+ "xxxxx\n"
+ "--m--\n"
+ "222--\n"
+ "--111\n"
+ "--333";
- private static final CellLayoutBoard END_BOARD_5x5 = CellLayoutBoard.boardFromString(
+ private static final ReorderTestCase TEST_CASE_5x5 = new ReorderTestCase(START_BOARD_STR_5x5,
+ MOVE_TO_5x5,
END_BOARD_STR_5x5);
- private static final ReorderTestCase TEST_CASE_5x5 = new ReorderTestCase(START_BOARD_5x5,
- MOVE_TO_5x5,
- END_BOARD_5x5);
-
+ /** 6x5 Test
+ **/
private static final String START_BOARD_STR_6x5 = ""
+ "xxxxxx\n"
+ "2222m-\n"
+ "--111-\n"
+ "--333-\n"
+ "------";
- private static final CellLayoutBoard START_BOARD_6x5 = CellLayoutBoard.boardFromString(
- START_BOARD_STR_6x5);
-
private static final Point MOVE_TO_6x5 = new Point(2, 1);
-
private static final String END_BOARD_STR_6x5 = ""
+ "xxxxxx\n"
+ "--m---\n"
+ "2222--\n"
+ "--111-\n"
+ "--333-";
- private static final CellLayoutBoard END_BOARD_6x5 = CellLayoutBoard.boardFromString(
+ private static final ReorderTestCase TEST_CASE_6x5 = new ReorderTestCase(START_BOARD_STR_6x5,
+ MOVE_TO_6x5,
END_BOARD_STR_6x5);
- private static final ReorderTestCase TEST_CASE_6x5 = new ReorderTestCase(START_BOARD_6x5,
- MOVE_TO_6x5,
- END_BOARD_6x5);
+ /** 4x4 Test
+ **/
+ private static final String START_BOARD_STR_4x4 = ""
+ + "xxxx\n"
+ + "222m\n"
+ + "-111\n"
+ + "----";
+ private static final Point MOVE_TO_4x4 = new Point(2, 1);
+ private static final String END_BOARD_STR_4x4 = ""
+ + "xxxx\n"
+ + "--m-\n"
+ + "222-\n"
+ + "-111";
+ private static final ReorderTestCase TEST_CASE_4x4 = new ReorderTestCase(START_BOARD_STR_4x4,
+ MOVE_TO_4x4,
+ END_BOARD_STR_4x4);
public static final Map<Point, ReorderTestCase> TEST_BY_GRID_SIZE =
- Map.of(new Point(5, 5), TEST_CASE_5x5, new Point(6, 5), TEST_CASE_6x5);
+ Map.of(new Point(5, 5), TEST_CASE_5x5,
+ new Point(6, 5), TEST_CASE_6x5,
+ new Point(4, 4), TEST_CASE_4x4);
}
diff --git a/tests/src/com/android/launcher3/celllayout/testcases/SimpleReorderCase.java b/tests/src/com/android/launcher3/celllayout/testcases/SimpleReorderCase.java
index 57e1398..30269a0 100644
--- a/tests/src/com/android/launcher3/celllayout/testcases/SimpleReorderCase.java
+++ b/tests/src/com/android/launcher3/celllayout/testcases/SimpleReorderCase.java
@@ -17,35 +17,47 @@
import android.graphics.Point;
-import com.android.launcher3.celllayout.CellLayoutBoard;
-
import java.util.Map;
public class SimpleReorderCase {
- private static final String START_BOARD_STR = ""
+
+ /** 5x5 Test
+ **/
+ private static final String START_BOARD_STR_5x5 = ""
+ "xxxxx\n"
+ "--mm-\n"
+ "--mm-\n"
+ "-----\n"
+ "-----";
- private static final CellLayoutBoard START_BOARD_5x5 = CellLayoutBoard.boardFromString(
- START_BOARD_STR);
-
private static final Point MOVE_TO_5x5 = new Point(4, 4);
-
private static final String END_BOARD_STR_5x5 = ""
+ "xxxxx\n"
+ "-----\n"
+ "-----\n"
+ "---mm\n"
+ "---mm";
- private static final CellLayoutBoard END_BOARD_5x5 = CellLayoutBoard.boardFromString(
+ private static final ReorderTestCase TEST_CASE_5x5 = new ReorderTestCase(START_BOARD_STR_5x5,
+ MOVE_TO_5x5,
END_BOARD_STR_5x5);
- private static final ReorderTestCase TEST_CASE_5x5 = new ReorderTestCase(START_BOARD_5x5,
- MOVE_TO_5x5,
- END_BOARD_5x5);
+ /** 4x4 Test
+ **/
+ private static final String START_BOARD_STR_4x4 = ""
+ + "xxxx\n"
+ + "--mm\n"
+ + "--mm\n"
+ + "----";
+ private static final Point MOVE_TO_4x4 = new Point(3, 3);
+ private static final String END_BOARD_STR_4x4 = ""
+ + "xxxx\n"
+ + "----\n"
+ + "--mm\n"
+ + "--mm";
+ private static final ReorderTestCase TEST_CASE_4x4 = new ReorderTestCase(START_BOARD_STR_4x4,
+ MOVE_TO_4x4,
+ END_BOARD_STR_4x4);
public static final Map<Point, ReorderTestCase> TEST_BY_GRID_SIZE =
- Map.of(new Point(5, 5), TEST_CASE_5x5);
+ Map.of(new Point(5, 5), TEST_CASE_5x5,
+ new Point(4, 4), TEST_CASE_4x4);
}
diff --git a/tests/src/com/android/launcher3/nonquickstep/HotseatWidthCalculationTest.kt b/tests/src/com/android/launcher3/nonquickstep/HotseatWidthCalculationTest.kt
new file mode 100644
index 0000000..55520e8
--- /dev/null
+++ b/tests/src/com/android/launcher3/nonquickstep/HotseatWidthCalculationTest.kt
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2022 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.launcher3.nonquickstep
+
+import android.graphics.Rect
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.launcher3.DeviceProfileBaseTest
+import com.android.launcher3.util.WindowBounds
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class HotseatWidthCalculationTest : DeviceProfileBaseTest() {
+
+ /**
+ * This is a case when after setting the hotseat, the space needs to be recalculated
+ * but it doesn't need to change QSB width or remove icons
+ */
+ @Test
+ fun distribute_border_space_when_space_is_enough_portrait() {
+ initializeVarsForTablet(isGestureMode = false)
+ windowBounds = WindowBounds(Rect(0, 0, 1800, 2560), Rect(0, 104, 0, 0))
+ val dp = newDP()
+ dp.isTaskbarPresentInApps = true
+
+ assertThat(dp.hotseatBarEndOffset).isEqualTo(0)
+ assertThat(dp.numShownHotseatIcons).isEqualTo(6)
+ assertThat(dp.hotseatBorderSpace).isEqualTo(145)
+
+ assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(177)
+ assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(177)
+
+ assertThat(dp.isQsbInline).isFalse()
+ assertThat(dp.hotseatQsbWidth).isEqualTo(1445)
+ }
+
+ /**
+ * This is a case when after setting the hotseat, and recalculating spaces
+ * it still needs to remove icons for everything to fit
+ */
+ @Test
+ fun decrease_num_of_icons_when_not_enough_space_portrait() {
+ initializeVarsForTablet(isGestureMode = false)
+ windowBounds = WindowBounds(Rect(0, 0, 1300, 2560), Rect(0, 104, 0, 0))
+ val dp = newDP()
+ dp.isTaskbarPresentInApps = true
+
+ assertThat(dp.hotseatBarEndOffset).isEqualTo(0)
+ assertThat(dp.numShownHotseatIcons).isEqualTo(6)
+ assertThat(dp.hotseatBorderSpace).isEqualTo(94)
+
+ assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(121)
+ assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(121)
+
+ assertThat(dp.isQsbInline).isFalse()
+ assertThat(dp.hotseatQsbWidth).isEqualTo(1058)
+ }
+
+ /**
+ * This is a case when after setting the hotseat, the space needs to be recalculated
+ * but it doesn't need to change QSB width or remove icons
+ */
+ @Test
+ fun distribute_border_space_when_space_is_enough_landscape() {
+ initializeVarsForTwoPanel(isGestureMode = false, isLandscape = true)
+ val dp = newDP()
+ dp.isTaskbarPresentInApps = true
+
+ assertThat(dp.hotseatBarEndOffset).isEqualTo(0)
+ assertThat(dp.numShownHotseatIcons).isEqualTo(6)
+ assertThat(dp.hotseatBorderSpace).isEqualTo(105)
+
+ assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(370)
+ assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(370)
+
+ assertThat(dp.isQsbInline).isFalse()
+ assertThat(dp.hotseatQsbWidth).isEqualTo(1467)
+ }
+
+ /**
+ * This is a case when the hotseat spans a certain amount of columns
+ * and the nav buttons push the hotseat to the side, but not enough to change the border space.
+ */
+ @Test
+ fun nav_buttons_dont_interfere_with_required_hotseat_width() {
+ initializeVarsForTablet(isGestureMode = false, isLandscape = true)
+ inv?.apply {
+ hotseatColumnSpan = IntArray(4) { 4 }
+ inlineQsb = BooleanArray(4) { false }
+ }
+ val dp = newDP()
+ dp.isTaskbarPresentInApps = true
+
+ assertThat(dp.hotseatBarEndOffset).isEqualTo(0)
+ assertThat(dp.numShownHotseatIcons).isEqualTo(6)
+ assertThat(dp.hotseatBorderSpace).isEqualTo(100)
+
+ assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(668)
+ assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(668)
+
+ assertThat(dp.isQsbInline).isFalse()
+ assertThat(dp.hotseatQsbWidth).isEqualTo(1224)
+ }
+
+ /**
+ * This is a case when after setting the hotseat, the QSB width needs to be changed to fit
+ */
+ @Test
+ fun decrease_qsb_when_not_enough_space_landscape() {
+ initializeVarsForTablet(isGestureMode = false, isLandscape = true)
+ windowBounds = WindowBounds(Rect(0, 0, 2460, 1600), Rect(0, 104, 0, 0))
+ val dp = newDP()
+ dp.isTaskbarPresentInApps = true
+
+ assertThat(dp.hotseatBarEndOffset).isEqualTo(0)
+ assertThat(dp.numShownHotseatIcons).isEqualTo(6)
+ assertThat(dp.hotseatBorderSpace).isEqualTo(96)
+
+ assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(643)
+ assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(643)
+
+ assertThat(dp.isQsbInline).isFalse()
+ assertThat(dp.hotseatQsbWidth).isEqualTo(1174)
+ }
+
+ /**
+ * This is a case when after setting the hotseat, changing QSB width, and recalculating spaces
+ * it still needs to remove icons for everything to fit
+ */
+ @Test
+ fun decrease_num_of_icons_when_not_enough_space_landscape() {
+ initializeVarsForTablet(isGestureMode = false, isLandscape = true)
+ windowBounds = WindowBounds(Rect(0, 0, 2260, 1600), Rect(0, 104, 0, 0))
+ val dp = newDP()
+ dp.isTaskbarPresentInApps = true
+
+ assertThat(dp.hotseatBarEndOffset).isEqualTo(0)
+ assertThat(dp.numShownHotseatIcons).isEqualTo(6)
+ assertThat(dp.hotseatBorderSpace).isEqualTo(89)
+
+ assertThat(dp.getHotseatLayoutPadding(context).left).isEqualTo(589)
+ assertThat(dp.getHotseatLayoutPadding(context).right).isEqualTo(589)
+
+ assertThat(dp.isQsbInline).isFalse()
+ assertThat(dp.hotseatQsbWidth).isEqualTo(1081)
+ }
+}
diff --git a/tests/tapl/com/android/launcher3/tapl/BaseOverview.java b/tests/tapl/com/android/launcher3/tapl/BaseOverview.java
index 6a11336..f47f710 100644
--- a/tests/tapl/com/android/launcher3/tapl/BaseOverview.java
+++ b/tests/tapl/com/android/launcher3/tapl/BaseOverview.java
@@ -247,8 +247,16 @@
return mLauncher.hasLauncherObject(mLauncher.getOverviewObjectSelector("clear_all"));
}
+ protected boolean isActionsViewVisible() {
+ OverviewTask task = mLauncher.isTablet() ? getFocusedTaskForTablet() : getCurrentTask();
+ if (task == null) {
+ return false;
+ }
+ return !task.isTaskSplit();
+ }
+
private void verifyActionsViewVisibility() {
- if (!hasTasks()) {
+ if (!hasTasks() || !isActionsViewVisible()) {
return;
}
try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
@@ -265,13 +273,11 @@
* Returns if focused task is currently snapped task in tablet grid overview.
*/
private boolean isOverviewSnappedToFocusedTaskForTablet() {
- UiObject2 focusedTask = getFocusedTaskForTablet();
+ OverviewTask focusedTask = getFocusedTaskForTablet();
if (focusedTask == null) {
return false;
}
- return Math.abs(
- focusedTask.getVisibleBounds().exactCenterX() - mLauncher.getExactScreenCenterX())
- < 1;
+ return Math.abs(focusedTask.getExactCenterX() - mLauncher.getExactScreenCenterX()) < 1;
}
/**
@@ -279,7 +285,7 @@
*
* @throws IllegalStateException if not run on a tablet device.
*/
- UiObject2 getFocusedTaskForTablet() {
+ OverviewTask getFocusedTaskForTablet() {
if (!mLauncher.isTablet()) {
throw new IllegalStateException("Must be run on tablet device.");
}
@@ -290,9 +296,9 @@
int focusedTaskHeight = mLauncher.getFocusedTaskHeightForTablet();
for (UiObject2 task : taskViews) {
if (task.getVisibleBounds().height() == focusedTaskHeight) {
- return task;
+ return new OverviewTask(mLauncher, task, this);
}
}
return null;
}
-}
\ No newline at end of file
+}
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index caaeef8..fa7e8e9 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -169,6 +169,7 @@
private static final String WIDGETS_RES_ID = "primary_widgets_list_view";
private static final String CONTEXT_MENU_RES_ID = "popup_container";
private static final String TASKBAR_RES_ID = "taskbar_view";
+ private static final String SPLIT_PLACEHOLDER_RES_ID = "split_placeholder";
public static final int WAIT_TIME_MS = 30000;
private static final String SYSTEMUI_PACKAGE = "com.android.systemui";
private static final String ANDROID_PACKAGE = "android";
@@ -724,6 +725,7 @@
waitUntilLauncherObjectGone(OVERVIEW_RES_ID);
waitUntilLauncherObjectGone(WIDGETS_RES_ID);
waitUntilLauncherObjectGone(TASKBAR_RES_ID);
+ waitUntilLauncherObjectGone(SPLIT_PLACEHOLDER_RES_ID);
return waitForLauncherObject(WORKSPACE_RES_ID);
}
@@ -732,6 +734,7 @@
waitUntilLauncherObjectGone(APPS_RES_ID);
waitUntilLauncherObjectGone(OVERVIEW_RES_ID);
waitUntilLauncherObjectGone(TASKBAR_RES_ID);
+ waitUntilLauncherObjectGone(SPLIT_PLACEHOLDER_RES_ID);
return waitForLauncherObject(WIDGETS_RES_ID);
}
@@ -741,16 +744,26 @@
waitUntilLauncherObjectGone(OVERVIEW_RES_ID);
waitUntilLauncherObjectGone(WIDGETS_RES_ID);
waitUntilLauncherObjectGone(TASKBAR_RES_ID);
+ waitUntilLauncherObjectGone(SPLIT_PLACEHOLDER_RES_ID);
return waitForLauncherObject(APPS_RES_ID);
}
- case OVERVIEW:
+ case OVERVIEW: {
+ waitUntilLauncherObjectGone(APPS_RES_ID);
+ waitUntilLauncherObjectGone(WORKSPACE_RES_ID);
+ waitUntilLauncherObjectGone(WIDGETS_RES_ID);
+ waitUntilLauncherObjectGone(TASKBAR_RES_ID);
+ waitUntilLauncherObjectGone(SPLIT_PLACEHOLDER_RES_ID);
+
+ return waitForLauncherObject(OVERVIEW_RES_ID);
+ }
case SPLIT_SCREEN_SELECT: {
waitUntilLauncherObjectGone(APPS_RES_ID);
waitUntilLauncherObjectGone(WORKSPACE_RES_ID);
waitUntilLauncherObjectGone(WIDGETS_RES_ID);
waitUntilLauncherObjectGone(TASKBAR_RES_ID);
+ waitForLauncherObject(SPLIT_PLACEHOLDER_RES_ID);
return waitForLauncherObject(OVERVIEW_RES_ID);
}
case FALLBACK_OVERVIEW: {
@@ -758,6 +771,7 @@
waitUntilLauncherObjectGone(WORKSPACE_RES_ID);
waitUntilLauncherObjectGone(WIDGETS_RES_ID);
waitUntilLauncherObjectGone(TASKBAR_RES_ID);
+ waitUntilLauncherObjectGone(SPLIT_PLACEHOLDER_RES_ID);
return waitForFallbackLauncherObject(OVERVIEW_RES_ID);
}
@@ -766,6 +780,7 @@
waitUntilLauncherObjectGone(APPS_RES_ID);
waitUntilLauncherObjectGone(OVERVIEW_RES_ID);
waitUntilLauncherObjectGone(WIDGETS_RES_ID);
+ waitUntilLauncherObjectGone(SPLIT_PLACEHOLDER_RES_ID);
if (isTablet() && !isFallbackOverview()) {
waitForLauncherObject(TASKBAR_RES_ID);
@@ -1109,6 +1124,16 @@
}
@Nullable
+ UiObject2 findObjectInContainer(UiObject2 container, String resName) {
+ try {
+ return container.findObject(getLauncherObjectSelector(resName));
+ } catch (StaleObjectException e) {
+ fail("The container disappeared from screen");
+ return null;
+ }
+ }
+
+ @Nullable
UiObject2 findObjectInContainer(UiObject2 container, BySelector selector) {
try {
return container.findObject(selector);
diff --git a/tests/tapl/com/android/launcher3/tapl/OverviewTask.java b/tests/tapl/com/android/launcher3/tapl/OverviewTask.java
index 72a39df..adc993d 100644
--- a/tests/tapl/com/android/launcher3/tapl/OverviewTask.java
+++ b/tests/tapl/com/android/launcher3/tapl/OverviewTask.java
@@ -20,6 +20,7 @@
import android.graphics.Rect;
+import androidx.annotation.NonNull;
import androidx.test.uiautomator.By;
import androidx.test.uiautomator.BySelector;
import androidx.test.uiautomator.UiObject2;
@@ -67,6 +68,10 @@
return mTask.getVisibleCenter().x;
}
+ float getExactCenterX() {
+ return mTask.getVisibleBounds().exactCenterX();
+ }
+
/**
* Dismisses the task by swiping up.
*/
@@ -159,4 +164,24 @@
}
}
}
+
+ /** Taps the task menu. */
+ @NonNull
+ public OverviewTaskMenu tapMenu() {
+ try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
+ LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
+ "want to tap the task menu")) {
+ mLauncher.clickLauncherObject(
+ mLauncher.waitForObjectInContainer(mTask.getParent(), "icon"));
+
+ try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer(
+ "tapped the task menu")) {
+ return new OverviewTaskMenu(mLauncher);
+ }
+ }
+ }
+
+ boolean isTaskSplit() {
+ return mLauncher.findObjectInContainer(mTask.getParent(), "bottomright_snapshot") != null;
+ }
}
diff --git a/tests/tapl/com/android/launcher3/tapl/OverviewTaskMenu.java b/tests/tapl/com/android/launcher3/tapl/OverviewTaskMenu.java
new file mode 100644
index 0000000..8cdc8a0
--- /dev/null
+++ b/tests/tapl/com/android/launcher3/tapl/OverviewTaskMenu.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2022 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.launcher3.tapl;
+
+import androidx.annotation.NonNull;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.UiObject2;
+
+/** Represents the menu of an overview task. */
+public class OverviewTaskMenu {
+
+ private final LauncherInstrumentation mLauncher;
+ private final UiObject2 mMenu;
+
+ OverviewTaskMenu(LauncherInstrumentation launcher) {
+ mLauncher = launcher;
+
+ mMenu = mLauncher.waitForLauncherObject("menu_option_layout");
+ mLauncher.assertTrue("The overview task menus is not visible",
+ !mMenu.getVisibleBounds().isEmpty());
+ }
+
+ /** Taps the split menu item from the overview task menu. */
+ @NonNull
+ public SplitScreenSelect tapSplitMenuItem() {
+ try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck();
+ LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
+ "tap split menu item")) {
+ mLauncher.clickLauncherObject(
+ mLauncher.findObjectInContainer(mMenu, By.textStartsWith("Split")));
+
+ try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer(
+ "tapped split menu item")) {
+ return new SplitScreenSelect(mLauncher);
+ }
+ }
+ }
+}
diff --git a/tests/tapl/com/android/launcher3/tapl/SplitScreenSelect.java b/tests/tapl/com/android/launcher3/tapl/SplitScreenSelect.java
index 3cf3ed6..9fa74e4 100644
--- a/tests/tapl/com/android/launcher3/tapl/SplitScreenSelect.java
+++ b/tests/tapl/com/android/launcher3/tapl/SplitScreenSelect.java
@@ -32,4 +32,10 @@
protected ContainerType getContainerType() {
return ContainerType.SPLIT_SCREEN_SELECT;
}
+
+ @Override
+ protected boolean isActionsViewVisible() {
+ // We don't show overview actions in split select state.
+ return false;
+ }
}