Merge "Import translations. DO NOT MERGE ANYWHERE" into tm-dev
diff --git a/protos/launcher_atom.proto b/protos/launcher_atom.proto
index 4127650..cf854ed 100644
--- a/protos/launcher_atom.proto
+++ b/protos/launcher_atom.proto
@@ -121,7 +121,7 @@
optional int32 cardinality = 2;
}
-// Next value 39
+// Next value 40
enum Attribute {
UNKNOWN = 0;
DEFAULT_LAYOUT = 1; // icon automatically placed in workspace, folder, hotseat
@@ -166,6 +166,9 @@
ALL_APPS_SEARCH_RESULT_LEGACY_SHORTCUT = 30;
ALL_APPS_SEARCH_RESULT_ASSISTANT_MEMORY = 31;
+ // Web suggestions provided by AGA
+ ALL_APPS_SEARCH_RESULT_WEB_SUGGEST = 39;
+
// Suggestion Type provided by AGA
WEB_SEARCH_RESULT_QUERY = 32;
WEB_SEARCH_RESULT_TRENDING = 33;
diff --git a/quickstep/src/com/android/launcher3/model/AppEventProducer.java b/quickstep/src/com/android/launcher3/model/AppEventProducer.java
index 3f29e43..5c66944 100644
--- a/quickstep/src/com/android/launcher3/model/AppEventProducer.java
+++ b/quickstep/src/com/android/launcher3/model/AppEventProducer.java
@@ -18,6 +18,7 @@
import static android.app.prediction.AppTargetEvent.ACTION_DISMISS;
import static android.app.prediction.AppTargetEvent.ACTION_LAUNCH;
import static android.app.prediction.AppTargetEvent.ACTION_PIN;
+import static android.app.prediction.AppTargetEvent.ACTION_UNDISMISS;
import static android.app.prediction.AppTargetEvent.ACTION_UNPIN;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION;
@@ -25,6 +26,7 @@
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_WIDGETS_PREDICTION;
import static com.android.launcher3.logger.LauncherAtomExtensions.ExtendedContainers.ContainerCase.DEVICE_SEARCH_RESULT_CONTAINER;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_APP_LAUNCH_TAP;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_DISMISS_PREDICTION_UNDO;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_FOLDER_CONVERTED_TO_ICON;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_HOTSEAT_PREDICTION_PINNED;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ITEM_DRAG_STARTED;
@@ -176,6 +178,8 @@
mContext.getPackageName(), Process.myUserHandle())
.build();
sendEvent(target, atomInfo, ACTION_LAUNCH, CONTAINER_PREDICTION);
+ } else if (event == LAUNCHER_DISMISS_PREDICTION_UNDO) {
+ sendEvent(atomInfo, ACTION_UNDISMISS, CONTAINER_HOTSEAT_PREDICTION);
}
}
diff --git a/quickstep/src/com/android/launcher3/search/SearchSessionManager.java b/quickstep/src/com/android/launcher3/search/SearchSessionManager.java
new file mode 100644
index 0000000..da85793
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/search/SearchSessionManager.java
@@ -0,0 +1,84 @@
+/*
+ * 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.search;
+
+import android.app.search.SearchSession;
+import android.content.Context;
+
+import androidx.annotation.IntDef;
+import androidx.annotation.UiThread;
+
+import com.android.launcher3.R;
+import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.util.ResourceBasedOverride;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.List;
+
+/** Manages an all apps search session. */
+public class SearchSessionManager implements ResourceBasedOverride {
+
+ /** Entry state for the search session (e.g. from all apps). */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(value = {ZERO_ALLAPPS, ZERO_QSB})
+ public @interface ZeroEntryState {}
+ public static final int ZERO_ALLAPPS = 1;
+ public static final int ZERO_QSB = 2;
+
+ /** Creates a {@link SearchSessionManager} instance. */
+ public static SearchSessionManager newInstance(Context context) {
+ return Overrides.getObject(
+ SearchSessionManager.class, context, R.string.search_session_manager_class);
+ }
+
+ /** The current {@link SearchSession}. */
+ @UiThread
+ public void setSearchSession(SearchSession session) {}
+
+ /** {@code true} if IME is shown. */
+ public void setIsImeShown(boolean value) {}
+
+ /** Returns {@code true} if IME is enabled. */
+ public boolean getIsImeEnabled() {
+ return false;
+ }
+
+ /** The current entry state for search. */
+ public @ZeroEntryState int getEntryState() {
+ return ZERO_ALLAPPS;
+ }
+
+ /**
+ * When user enters all apps surface via tap on home widget, set the state to
+ * {@code #ZERO_QSB}. When user exits, reset to {@code #ZERO_ALLAPPS}
+ */
+ public void setEntryState(@ZeroEntryState int state) {}
+
+ /** This will be called before opening all apps, to prepare zero state suggestions. */
+ public void prepareZeroState() {}
+
+ /** Apply predicted items for the search zero state. */
+ public void setZeroStatePredictedItems(List<ItemInfo> items) {}
+
+ /** Returns {@code true} if the session is valid and should be enabled. */
+ public boolean isValidSession() {
+ return false;
+ }
+
+ /** Called when the search session is destroyed. */
+ public void onDestroy() {}
+}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index 1c6d4a2..296000b 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -785,5 +785,6 @@
pw.println(String.format(
"%s\tmBindInProgress=%b", prefix, mBindingItems));
mControllers.dumpLogs(prefix + "\t", pw);
+ mDeviceProfile.dump(prefix, pw);
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
index 06107b8..7abe6d4 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
@@ -65,6 +65,9 @@
| FLAG_STASHED_IN_APP_PINNED | FLAG_STASHED_IN_APP_EMPTY | FLAG_STASHED_IN_APP_SETUP
| FLAG_STASHED_IN_APP_IME | FLAG_STASHED_IN_APP_ALL_APPS;
+ private static final int FLAGS_STASHED_IN_APP_IGNORING_IME =
+ FLAGS_STASHED_IN_APP & ~FLAG_STASHED_IN_APP_IME;
+
// If any of these flags are enabled, inset apps by our stashed height instead of our unstashed
// height. This way the reported insets are consistent even during transitions out of the app.
// Currently any flag that causes us to stash in an app is included, except for IME or All Apps
@@ -239,6 +242,13 @@
}
/**
+ * Returns whether the taskbar should be stashed in apps regardless of the IME visibility.
+ */
+ public boolean isStashedInAppIgnoringIme() {
+ return hasAnyFlag(FLAGS_STASHED_IN_APP_IGNORING_IME);
+ }
+
+ /**
* Returns whether the taskbar should be stashed in the current LauncherState.
*/
public boolean isInStashedLauncherState() {
@@ -586,7 +596,11 @@
private void notifyStashChange(boolean visible, boolean stashed) {
mSystemUiProxy.notifyTaskbarStatus(visible, stashed);
- mControllers.taskbarActivityContext.updateInsetRoundedCornerFrame(visible && !stashed);
+ // If stashing taskbar is caused by IME visibility, we could just skip updating rounded
+ // corner insets since the rounded corners will be covered by IME during IME is showing and
+ // taskbar will be restored back to unstashed when IME is hidden.
+ mControllers.taskbarActivityContext.updateInsetRoundedCornerFrame(
+ visible && !isStashedInAppIgnoringIme());
mControllers.rotationButtonController.onTaskbarStateChange(visible, stashed);
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java
index f93917f..27a55c3 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java
@@ -25,11 +25,8 @@
import static com.android.launcher3.anim.Interpolators.DEACCEL;
import static com.android.launcher3.anim.Interpolators.FINAL_FRAME;
import static com.android.launcher3.anim.Interpolators.INSTANT;
-import static com.android.launcher3.anim.Interpolators.LINEAR;
-import static com.android.launcher3.anim.Interpolators.LINEAR_TELEPORT;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_FADE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_SCRIM_FADE;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_VERTICAL_PROGRESS;
import android.view.MotionEvent;
@@ -140,7 +137,6 @@
builder.setInterpolator(ANIM_SCRIM_FADE, Interpolators.clampToProgress(ACCEL,
ALL_APPS_SCRIM_VISIBLE_THRESHOLD,
ALL_APPS_SCRIM_OPAQUE_THRESHOLD));
- builder.setInterpolator(ANIM_VERTICAL_PROGRESS, isTablet ? LINEAR_TELEPORT : LINEAR);
return builder;
}
@@ -155,7 +151,6 @@
builder.setInterpolator(ANIM_SCRIM_FADE, Interpolators.clampToProgress(DEACCEL,
1 - ALL_APPS_SCRIM_OPAQUE_THRESHOLD,
1 - ALL_APPS_SCRIM_VISIBLE_THRESHOLD));
- builder.setInterpolator(ANIM_VERTICAL_PROGRESS, isTablet ? LINEAR_TELEPORT : LINEAR);
return builder;
}
diff --git a/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java b/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java
index a62e9d1..ed81d7e 100644
--- a/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java
+++ b/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java
@@ -21,8 +21,10 @@
import static com.android.launcher3.GestureNavContract.EXTRA_GESTURE_CONTRACT;
import static com.android.launcher3.GestureNavContract.EXTRA_ICON_POSITION;
import static com.android.launcher3.GestureNavContract.EXTRA_ICON_SURFACE;
+import static com.android.launcher3.GestureNavContract.EXTRA_ON_FINISH_CALLBACK;
import static com.android.launcher3.GestureNavContract.EXTRA_REMOTE_CALLBACK;
import static com.android.launcher3.Utilities.createHomeIntent;
+import static com.android.launcher3.anim.AnimatorListeners.forEndCallback;
import static com.android.launcher3.anim.Interpolators.ACCEL;
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME;
@@ -44,7 +46,9 @@
import android.os.Message;
import android.os.Messenger;
import android.os.ParcelUuid;
+import android.os.RemoteException;
import android.os.UserHandle;
+import android.util.Log;
import android.view.Surface;
import android.view.SurfaceControl;
import android.view.SurfaceControl.Transaction;
@@ -82,6 +86,8 @@
public class FallbackSwipeHandler extends
AbsSwipeUpHandler<RecentsActivity, FallbackRecentsView, RecentsState> {
+ private static final String TAG = "FallbackSwipeHandler";
+
/**
* Message used for receiving gesture nav contract information. We use a static messenger to
* avoid leaking too make binders in case the receiving launcher does not handle the contract
@@ -224,7 +230,8 @@
}
}
- private class FallbackHomeAnimationFactory extends HomeAnimationFactory {
+ private class FallbackHomeAnimationFactory extends HomeAnimationFactory
+ implements Consumer<Message> {
private final Rect mTempRect = new Rect();
private final TransformParams mHomeAlphaParams = new TransformParams();
private final AnimatedFloat mHomeAlpha;
@@ -235,6 +242,9 @@
private final RectF mTargetRect = new RectF();
private SurfaceControl mSurfaceControl;
+ private boolean mAnimationFinished;
+ private Message mOnFinishCallback;
+
private final long mDuration;
private RectFSpringAnim mSpringAnim;
@@ -336,9 +346,26 @@
@Override
public void setAnimation(RectFSpringAnim anim) {
mSpringAnim = anim;
+ mSpringAnim.addAnimatorListener(forEndCallback(this::onRectAnimationEnd));
}
- private void onMessageReceived(Message msg) {
+ private void onRectAnimationEnd() {
+ mAnimationFinished = true;
+ maybeSendEndMessage();
+ }
+
+ private void maybeSendEndMessage() {
+ if (mAnimationFinished && mOnFinishCallback != null) {
+ try {
+ mOnFinishCallback.replyTo.send(mOnFinishCallback);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error sending icon position", e);
+ }
+ }
+ }
+
+ @Override
+ public void accept(Message msg) {
try {
Bundle data = msg.getData();
RectF position = data.getParcelable(EXTRA_ICON_POSITION);
@@ -348,7 +375,9 @@
if (mSpringAnim != null) {
mSpringAnim.onTargetPositionChanged();
}
+ mOnFinishCallback = data.getParcelable(EXTRA_ON_FINISH_CALLBACK);
}
+ maybeSendEndMessage();
} catch (Exception e) {
// Ignore
}
@@ -382,8 +411,8 @@
Bundle gestureNavContract = new Bundle();
gestureNavContract.putParcelable(EXTRA_COMPONENT_NAME, key.getComponent());
gestureNavContract.putParcelable(EXTRA_USER, UserHandle.of(key.userId));
- gestureNavContract.putParcelable(EXTRA_REMOTE_CALLBACK,
- sMessageReceiver.newCallback(this::onMessageReceived));
+ gestureNavContract.putParcelable(
+ EXTRA_REMOTE_CALLBACK, sMessageReceiver.newCallback(this));
intent.putExtra(EXTRA_GESTURE_CONTRACT, gestureNavContract);
}
}
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
index f1ace49..7ad60bb 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
@@ -63,7 +63,6 @@
import android.provider.Settings;
import android.text.TextUtils;
import android.view.MotionEvent;
-import android.view.Surface;
import androidx.annotation.BinderThread;
@@ -557,8 +556,7 @@
if (mIsOneHandedModeEnabled) {
final Info displayInfo = mDisplayController.getInfo();
return (mRotationTouchHelper.touchInOneHandedModeRegion(ev)
- && displayInfo.rotation != Surface.ROTATION_90
- && displayInfo.rotation != Surface.ROTATION_270);
+ && (displayInfo.currentSize.x < displayInfo.currentSize.y));
}
return false;
}
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index a38728a..3206825 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -71,6 +71,7 @@
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.provider.RestoreDbTask;
import com.android.launcher3.statemanager.StatefulActivity;
+import com.android.launcher3.taskbar.TaskbarActivityContext;
import com.android.launcher3.taskbar.TaskbarManager;
import com.android.launcher3.testing.TestLogging;
import com.android.launcher3.testing.TestProtocol;
@@ -688,11 +689,9 @@
}
// If Taskbar is present, we listen for long press to unstash it.
- BaseActivityInterface activityInterface = newGestureState.getActivityInterface();
- StatefulActivity activity = activityInterface.getCreatedActivity();
- if (activity != null && activity.getDeviceProfile().isTaskbarPresent) {
- base = new TaskbarStashInputConsumer(this, base, mInputMonitorCompat,
- mTaskbarManager.getCurrentActivityContext());
+ TaskbarActivityContext tac = mTaskbarManager.getCurrentActivityContext();
+ if (tac != null) {
+ base = new TaskbarStashInputConsumer(this, base, mInputMonitorCompat, tac);
}
// If Bubbles is expanded, use the overlay input consumer, which will close Bubbles
@@ -963,10 +962,10 @@
RecentsModel.INSTANCE.get(this).dump("", pw);
pw.println("ProtoTrace:");
pw.println(" file=" + ProtoTracer.INSTANCE.get(this).getTraceFile());
- mTaskbarManager.dumpLogs("", pw);
if (createdOverviewActivity != null) {
createdOverviewActivity.getDeviceProfile().dump("", pw);
}
+ mTaskbarManager.dumpLogs("", pw);
}
}
diff --git a/quickstep/src/com/android/quickstep/interaction/EdgeBackGestureHandler.java b/quickstep/src/com/android/quickstep/interaction/EdgeBackGestureHandler.java
index c532f8e..d059d82 100644
--- a/quickstep/src/com/android/quickstep/interaction/EdgeBackGestureHandler.java
+++ b/quickstep/src/com/android/quickstep/interaction/EdgeBackGestureHandler.java
@@ -31,6 +31,7 @@
import com.android.launcher3.ResourceUtils;
import com.android.launcher3.Utilities;
+import com.android.launcher3.util.DisplayController;
/**
* Utility class to handle edge swipes for back gestures.
@@ -115,10 +116,9 @@
// Add a nav bar panel window.
mEdgeBackPanel = new EdgeBackGesturePanel(mContext, parent, createLayoutParams());
mEdgeBackPanel.setBackCallback(mBackCallback);
- if (mContext.getDisplay() != null) {
- mContext.getDisplay().getRealSize(mDisplaySize);
- mEdgeBackPanel.setDisplaySize(mDisplaySize);
- }
+ Point currentSize = DisplayController.INSTANCE.get(mContext).getInfo().currentSize;
+ mDisplaySize.set(currentSize.x, currentSize.y);
+ mEdgeBackPanel.setDisplaySize(mDisplaySize);
}
}
diff --git a/quickstep/src/com/android/quickstep/interaction/NavBarGestureHandler.java b/quickstep/src/com/android/quickstep/interaction/NavBarGestureHandler.java
index a8163af..f981860 100644
--- a/quickstep/src/com/android/quickstep/interaction/NavBarGestureHandler.java
+++ b/quickstep/src/com/android/quickstep/interaction/NavBarGestureHandler.java
@@ -37,7 +37,6 @@
import android.view.Display;
import android.view.GestureDetector;
import android.view.MotionEvent;
-import android.view.Surface;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewConfiguration;
@@ -47,6 +46,7 @@
import com.android.launcher3.R;
import com.android.launcher3.ResourceUtils;
import com.android.launcher3.anim.Interpolators;
+import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.DisplayController.NavigationMode;
import com.android.quickstep.util.MotionPauseDetector;
import com.android.quickstep.util.NavBarPosition;
@@ -92,13 +92,10 @@
NavBarGestureHandler(Context context) {
mContext = context;
final Display display = mContext.getDisplay();
- final int displayRotation;
- if (display == null) {
- displayRotation = Surface.ROTATION_0;
- } else {
- displayRotation = display.getRotation();
- display.getRealSize(mDisplaySize);
- }
+ DisplayController.Info displayInfo = DisplayController.INSTANCE.get(mContext).getInfo();
+ final int displayRotation = displayInfo.rotation;
+ Point currentSize = displayInfo.currentSize;
+ mDisplaySize.set(currentSize.x, currentSize.y);
mSwipeUpTouchTracker =
new TriggerSwipeUpTouchTracker(context, true /*disableHorizontalSwipe*/,
new NavBarPosition(NavigationMode.NO_BUTTON, displayRotation),
diff --git a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
index ae00d82..ca6712f 100644
--- a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
+++ b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
@@ -58,7 +58,6 @@
import com.android.launcher3.util.Wait;
import com.android.launcher3.util.rule.FailureWatcher;
import com.android.launcher3.util.rule.ScreenRecordRule;
-import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord;
import com.android.quickstep.views.RecentsView;
import org.junit.After;
@@ -79,6 +78,8 @@
@RunWith(AndroidJUnit4.class)
public class FallbackRecentsTest {
+ private static final String FALLBACK_LAUNCHER_TITLE = "Test launcher";
+
private final UiDevice mDevice;
private final LauncherInstrumentation mLauncher;
private final ActivityInfo mOtherLauncherActivity;
@@ -165,11 +166,10 @@
// b/143488140
//@NavigationModeSwitch
@Test
- @ScreenRecord // b/223278795
public void goToOverviewFromHome() {
mDevice.pressHome();
assertTrue("Fallback Launcher not visible", mDevice.wait(Until.hasObject(By.pkg(
- mOtherLauncherActivity.packageName)), WAIT_TIME_MS));
+ mOtherLauncherActivity.packageName).text(FALLBACK_LAUNCHER_TITLE)), WAIT_TIME_MS));
mLauncher.getLaunchedAppState().switchToOverview();
}
@@ -258,7 +258,7 @@
// Test dismissing all tasks.
pressHomeAndGoToOverview().dismissAllTasks();
assertTrue("Fallback Launcher not visible", TestHelpers.wait(Until.hasObject(By.pkg(
- mOtherLauncherActivity.packageName)), WAIT_TIME_MS));
+ mOtherLauncherActivity.packageName).text(FALLBACK_LAUNCHER_TITLE)), WAIT_TIME_MS));
}
private int getCurrentOverviewPage(RecentsActivity recents) {
diff --git a/res/drawable/drop_target_frame.xml b/res/drawable/drop_target_frame.xml
index 666a96e..9f04103 100644
--- a/res/drawable/drop_target_frame.xml
+++ b/res/drawable/drop_target_frame.xml
@@ -17,6 +17,6 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@android:color/transparent" />
- <corners android:radius="28dp" />
+ <corners android:radius="80dp" />
<stroke android:width="2dp" android:color="?attr/workspaceAccentColor" />
</shape>
\ No newline at end of file
diff --git a/res/layout/work_apps_edu.xml b/res/layout/work_apps_edu.xml
index 1517087..73200de 100644
--- a/res/layout/work_apps_edu.xml
+++ b/res/layout/work_apps_edu.xml
@@ -19,37 +19,49 @@
android:layout_marginTop="8dp"
android:gravity="center">
- <LinearLayout
+ <RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:orientation="vertical"
- android:paddingHorizontal="@dimen/work_card_padding_horizontal"
- android:paddingVertical="@dimen/work_card_padding_horizontal"
+ android:orientation="horizontal"
android:background="@drawable/work_card"
android:layout_gravity="center_horizontal"
- android:gravity="center"
+ android:paddingEnd="@dimen/work_card_margin"
+ android:paddingStart="@dimen/work_card_margin"
+ android:paddingTop="@dimen/work_card_margin"
android:id="@+id/wrapper">
-
<TextView
style="@style/PrimaryHeadline"
android:textColor="?android:attr/textColorPrimary"
android:id="@+id/work_apps_paused_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginBottom="@dimen/work_card_padding_horizontal"
+ android:layout_marginBottom="@dimen/work_card_margin"
+ android:layout_marginRight="@dimen/work_card_margin"
android:text="@string/work_profile_edu_work_apps"
- android:textAlignment="center"
- android:textSize="20sp" />
-
- <Button
+ android:textSize="18sp" />
+ <RelativeLayout
android:layout_width="match_parent"
- android:layout_height="@dimen/work_card_button_height"
- android:id="@+id/action_btn"
- android:textColor="?attr/workProfileOverlayTextColor"
- android:text="@string/work_profile_edu_accept"
- android:textAlignment="center"
- android:background="@drawable/rounded_action_button"
+ android:layout_height="@dimen/padded_rounded_button_height"
+ android:orientation="horizontal"
+ >
+ <FrameLayout
+ android:layout_width="@dimen/rounded_button_width"
+ android:layout_height="@dimen/rounded_button_width"
+ android:background="@drawable/rounded_action_button"
+ android:padding="@dimen/rounded_button_padding"
+ android:layout_alignParentRight="true">
+ <ImageButton
+ android:layout_width="@dimen/x_icon_size"
+ android:layout_height="@dimen/x_icon_size"
+ android:id="@+id/action_btn"
+ android:src="@drawable/ic_remove_no_shadow"
+ android:layout_gravity="center"
+ android:padding="@dimen/x_icon_padding" />
+ </FrameLayout>
+ </RelativeLayout>
- android:textSize="14sp" />
- </LinearLayout>
+ </RelativeLayout>
+
+
+
</com.android.launcher3.allapps.WorkEduCard>
\ No newline at end of file
diff --git a/res/layout/work_mode_fab.xml b/res/layout/work_mode_fab.xml
index 04faa15..c536d77 100644
--- a/res/layout/work_mode_fab.xml
+++ b/res/layout/work_mode_fab.xml
@@ -29,4 +29,6 @@
android:drawableStart="@drawable/ic_corp_off"
android:layout_marginBottom="@dimen/work_fab_margin"
android:layout_marginEnd="@dimen/work_fab_margin"
+ android:paddingLeft="@dimen/work_mode_fab_padding"
+ android:paddingRight="@dimen/work_mode_fab_padding"
android:text="@string/work_apps_pause_btn_text" />
\ No newline at end of file
diff --git a/res/values-land/dimens.xml b/res/values-land/dimens.xml
index 662b86e..652a61c 100644
--- a/res/values-land/dimens.xml
+++ b/res/values-land/dimens.xml
@@ -22,8 +22,19 @@
<dimen name="fastscroll_popup_text_size">24dp</dimen>
<!-- Dynamic grid -->
+ <dimen name="dynamic_grid_edge_margin">15.28dp</dimen>
<dimen name="dynamic_grid_icon_drawable_padding">4dp</dimen>
+ <dimen name="dynamic_grid_drop_target_size">36dp</dimen>
+ <dimen name="cell_layout_padding">20dp</dimen>
<!-- Hotseat -->
<dimen name="dynamic_grid_hotseat_side_padding">16dp</dimen>
+ <dimen name="spring_loaded_hotseat_top_margin">45dp</dimen>
+
+ <!-- Dragging -->
+ <dimen name="drop_target_button_gap">28dp</dimen>
+ <dimen name="drop_target_button_drawable_horizontal_padding">16dp</dimen>
+ <dimen name="drop_target_button_drawable_vertical_padding">2dp</dimen>
+ <dimen name="drop_target_top_margin">6dp</dimen>
+ <dimen name="drop_target_bottom_margin">6dp</dimen>
</resources>
diff --git a/res/values-sw600dp-land/dimens.xml b/res/values-sw600dp-land/dimens.xml
new file mode 100644
index 0000000..dce09e3
--- /dev/null
+++ b/res/values-sw600dp-land/dimens.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ 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.
+ -->
+
+<resources>
+<!-- Hotseat -->
+ <dimen name="spring_loaded_hotseat_top_margin">44dp</dimen>
+
+<!-- Dragging -->
+ <dimen name="drop_target_top_margin">0dp</dimen>
+ <dimen name="drop_target_bottom_margin">16dp</dimen>
+
+<!-- Dynamic grid -->
+ <dimen name="dynamic_grid_edge_margin">11.33dp</dimen>
+ <dimen name="cell_layout_padding">11.33dp</dimen>
+
+<!-- AllApps -->
+ <dimen name="all_apps_bottom_sheet_horizontal_padding">52dp</dimen>
+</resources>
diff --git a/res/values-sw600dp/dimens.xml b/res/values-sw600dp/dimens.xml
index 4a10e56..27b13d7 100644
--- a/res/values-sw600dp/dimens.xml
+++ b/res/values-sw600dp/dimens.xml
@@ -32,8 +32,18 @@
<dimen name="fastscroll_popup_text_size">32dp</dimen>
<!-- Dynamic grid -->
+ <dimen name="dynamic_grid_edge_margin">9dp</dimen>
<dimen name="dynamic_grid_icon_drawable_padding">7dp</dimen>
+ <dimen name="cell_layout_padding">9dp</dimen>
<!-- Hotseat -->
<dimen name="dynamic_grid_hotseat_side_padding">0dp</dimen>
+ <dimen name="spring_loaded_hotseat_top_margin">97dp</dimen>
+
+<!-- Dragging -->
+ <dimen name="drop_target_top_margin">34dp</dimen>
+ <dimen name="drop_target_bottom_margin">16dp</dimen>
+ <dimen name="drop_target_button_drawable_horizontal_padding">16dp</dimen>
+ <dimen name="drop_target_button_drawable_vertical_padding">16dp</dimen>
+ <dimen name="dynamic_grid_drop_target_size">56dp</dimen>
</resources>
diff --git a/res/values-sw720dp-land/dimens.xml b/res/values-sw720dp-land/dimens.xml
index 9821526..439ea93 100644
--- a/res/values-sw720dp-land/dimens.xml
+++ b/res/values-sw720dp-land/dimens.xml
@@ -15,9 +15,23 @@
-->
<resources>
- <!-- Widget picker-->
+<!-- Dynamic grid -->
+ <dimen name="dynamic_grid_edge_margin">21.93dp</dimen>
+ <dimen name="cell_layout_padding">29.33dp</dimen>
+
+<!-- AllApps -->
+ <dimen name="all_apps_bottom_sheet_horizontal_padding">32dp</dimen>
+
+<!-- Dragging-->
+ <dimen name="drop_target_top_margin">0dp</dimen>
+ <dimen name="drop_target_bottom_margin">32dp</dimen>
+
+<!-- Hotseat -->
+ <dimen name="spring_loaded_hotseat_top_margin">64dp</dimen>
+
+<!-- Widget picker-->
<dimen name="widget_list_horizontal_margin">49dp</dimen>
- <!-- Bottom sheet-->
+<!-- Bottom sheet-->
<dimen name="bottom_sheet_extra_top_padding">0dp</dimen>
</resources>
diff --git a/res/values-sw720dp/dimens.xml b/res/values-sw720dp/dimens.xml
index 7ebc3f8..3ec211a 100644
--- a/res/values-sw720dp/dimens.xml
+++ b/res/values-sw720dp/dimens.xml
@@ -16,7 +16,23 @@
<resources>
<!-- AllApps -->
- <dimen name="all_apps_bottom_sheet_horizontal_padding">65dp</dimen>
+ <dimen name="all_apps_bottom_sheet_horizontal_padding">28dp</dimen>
+
+<!-- Dynamic grid -->
+ <dimen name="dynamic_grid_edge_margin">27.59dp</dimen>
+ <dimen name="cell_layout_padding">36dp</dimen>
+
+<!-- Dragging -->
+ <dimen name="drop_target_text_size">20sp</dimen>
+ <dimen name="dynamic_grid_drop_target_size">72dp</dimen>
+ <dimen name="drop_target_button_drawable_horizontal_padding">24dp</dimen>
+ <dimen name="drop_target_button_drawable_vertical_padding">20dp</dimen>
+ <dimen name="drop_target_button_gap">32dp</dimen>
+ <dimen name="drop_target_top_margin">32dp</dimen>
+ <dimen name="drop_target_bottom_margin">32dp</dimen>
+
+<!-- Hotseat -->
+ <dimen name="spring_loaded_hotseat_top_margin">164dp</dimen>
<!-- Widget picker-->
<dimen name="widget_list_horizontal_margin">30dp</dimen>
diff --git a/res/values/config.xml b/res/values/config.xml
index e2fd0e3..0ed2d85 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -22,9 +22,6 @@
<item type="id" name="drag_event_parity" />
<!-- AllApps & Launcher transitions -->
- <!-- Out of 100, the percent to shrink the workspace during spring loaded mode. -->
- <integer name="config_workspaceSpringLoadShrinkPercentage">85</integer>
-
<!-- The duration of the animation from search hint to text entry -->
<integer name="config_searchHintAnimationDuration">50</integer>
@@ -91,6 +88,7 @@
<string name="custom_activity_picker" translatable="false">
com.android.customization.picker.CustomizationPickerActivity</string>
<string name="local_colors_extraction_class" translatable="false"></string>
+ <string name="search_session_manager_class" translatable="false"></string>
<!-- Accessibility actions -->
<item type="id" name="action_remove" />
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index ce54565..b320bb2 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -19,14 +19,14 @@
<dimen name="click_shadow_elevation">4dp</dimen>
<!-- Dynamic Grid -->
- <dimen name="dynamic_grid_edge_margin">8dp</dimen>
+ <dimen name="dynamic_grid_edge_margin">10.77dp</dimen>
<dimen name="dynamic_grid_left_right_margin">8dp</dimen>
<dimen name="dynamic_grid_icon_drawable_padding">7dp</dimen>
<!-- Minimum space between workspace and hotseat in spring loaded mode -->
<dimen name="dynamic_grid_min_spring_loaded_space">8dp</dimen>
<dimen name="dynamic_grid_cell_border_spacing">16dp</dimen>
- <dimen name="dynamic_grid_cell_layout_padding">5.5dp</dimen>
+ <dimen name="cell_layout_padding">10.77dp</dimen>
<dimen name="dynamic_grid_cell_padding_x">8dp</dimen>
<!-- Hotseat -->
@@ -34,6 +34,7 @@
<dimen name="dynamic_grid_hotseat_bottom_padding">2dp</dimen>
<dimen name="dynamic_grid_hotseat_bottom_tall_padding">0dp</dimen>
<dimen name="inline_qsb_bottom_margin">0dp</dimen>
+ <dimen name="spring_loaded_hotseat_top_margin">76dp</dimen>
<!-- Qsb -->
<!-- Used for adjusting the position of QSB when placed in hotseat. This is a ratio and a higher
@@ -55,8 +56,10 @@
<dimen name="workspace_page_indicator_overlap_workspace">0dp</dimen>
<!-- Drop target bar -->
- <dimen name="dynamic_grid_drop_target_size">52dp</dimen>
+ <dimen name="dynamic_grid_drop_target_size">56dp</dimen>
<dimen name="drop_target_vertical_gap">20dp</dimen>
+ <dimen name="drop_target_top_margin">36dp</dimen>
+ <dimen name="drop_target_bottom_margin">16dp</dimen>
<!-- App Widget resize frame -->
<dimen name="widget_handle_margin">13dp</dimen>
@@ -134,18 +137,25 @@
<!-- Floating action button inside work tab to toggle work profile -->
<dimen name="work_fab_height">56dp</dimen>
- <dimen name="work_fab_radius">28dp</dimen>
- <dimen name="work_card_padding_horizontal">24dp</dimen>
+ <dimen name="work_fab_radius">16dp</dimen>
+ <dimen name="work_card_padding_horizontal">10dp</dimen>
<dimen name="work_card_button_height">52dp</dimen>
<dimen name="work_fab_margin">16dp</dimen>
+ <dimen name="work_mode_fab_padding">16dp</dimen>
<dimen name="work_profile_footer_padding">20dp</dimen>
<dimen name="work_edu_card_margin">16dp</dimen>
- <dimen name="work_edu_card_radius">28dp</dimen>
+ <dimen name="work_edu_card_radius">16dp</dimen>
+
+ <dimen name="work_card_margin">24dp</dimen>
+ <!-- (x) icon button inside work edu card -->
+ <dimen name="rounded_button_width">24dp</dimen>
+ <dimen name="x_icon_size">16dp</dimen>
+ <dimen name="x_icon_padding">4dp</dimen>
<!-- rounded button shown inside card views, and snack bars -->
<dimen name="padded_rounded_button_height">48dp</dimen>
- <dimen name="rounded_button_height">32dp</dimen>
- <dimen name="rounded_button_radius">16dp</dimen>
+ <dimen name="rounded_button_height">48dp</dimen>
+ <dimen name="rounded_button_radius">200dp</dimen>
<dimen name="rounded_button_padding">8dp</dimen>
@@ -207,6 +217,9 @@
<dimen name="drop_target_shadow_elevation">2dp</dimen>
<dimen name="drop_target_bar_margin_horizontal">4dp</dimen>
<dimen name="drop_target_button_drawable_padding">8dp</dimen>
+ <dimen name="drop_target_button_drawable_horizontal_padding">16dp</dimen>
+ <dimen name="drop_target_button_drawable_vertical_padding">8dp</dimen>
+ <dimen name="drop_target_button_gap">22dp</dimen>
<!-- the distance an icon must be dragged before button drop targets accept it -->
<dimen name="drag_distanceThreshold">30dp</dimen>
diff --git a/res/xml/device_profiles.xml b/res/xml/device_profiles.xml
index dd201e5..f1af348 100644
--- a/res/xml/device_profiles.xml
+++ b/res/xml/device_profiles.xml
@@ -145,22 +145,39 @@
launcher:numFolderColumns="3"
launcher:numHotseatIcons="6"
launcher:numAllAppsColumns="6"
+ launcher:isScalable="true"
+ launcher:devicePaddingId="@xml/paddings_6x5"
launcher:dbFile="launcher_6_by_5.db"
launcher:defaultLayoutId="@xml/default_workspace_6x5"
- launcher:deviceCategory="tablet" >
+ launcher:deviceCategory="tablet">
<display-option
launcher:name="Tablet"
launcher:minWidthDps="900"
launcher:minHeightDps="820"
- launcher:minCellHeight="104"
- launcher:minCellWidth="80"
+ launcher:minCellHeight="120"
+ launcher:minCellWidth="102"
+ launcher:minCellHeightLandscape="104"
+ launcher:minCellWidthLandscape="120"
launcher:iconImageSize="60"
launcher:iconTextSize="14"
- launcher:borderSpace="16"
+ launcher:borderSpaceHorizontal="16"
+ launcher:borderSpaceVertical="64"
+ launcher:borderSpaceLandscapeHorizontal="64"
+ launcher:borderSpaceLandscapeVertical="16"
+ launcher:horizontalMargin="54"
+ launcher:horizontalMarginLandscape="120"
+ launcher:allAppsCellWidth="96"
+ launcher:allAppsCellHeight="142"
+ launcher:allAppsCellWidthLandscape="126"
+ launcher:allAppsCellHeightLandscape="126"
launcher:allAppsIconSize="60"
launcher:allAppsIconTextSize="14"
- launcher:allAppsBorderSpace="16"
+ launcher:allAppsBorderSpaceHorizontal="8"
+ launcher:allAppsBorderSpaceVertical="16"
+ launcher:allAppsBorderSpaceLandscape="16"
+ launcher:hotseatBorderSpace="58"
+ launcher:hotseatBorderSpaceLandscape="50.4"
launcher:canBeDefault="true" />
</grid-option>
diff --git a/res/xml/paddings_6x5.xml b/res/xml/paddings_6x5.xml
new file mode 100644
index 0000000..a958ec7
--- /dev/null
+++ b/res/xml/paddings_6x5.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ 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.
+ -->
+
+<device-paddings xmlns:launcher="http://schemas.android.com/apk/res-auto" >
+
+ <!-- Some non default screen sizes -->
+ <device-padding
+ launcher:maxEmptySpace="30dp">
+ <workspaceTopPadding
+ launcher:a="0.34"
+ launcher:b="0"/>
+ <workspaceBottomPadding
+ launcher:a="0.26"
+ launcher:b="0"/>
+ <hotseatBottomPadding
+ launcher:a="0.4"
+ launcher:b="0"/>
+ </device-padding>
+
+ <device-padding
+ launcher:maxEmptySpace="80dp">
+ <workspaceTopPadding
+ launcher:a="0"
+ launcher:b="20dp"/>
+ <workspaceBottomPadding
+ launcher:a="0.4"
+ launcher:b="0"
+ launcher:c="20dp"/>
+ <hotseatBottomPadding
+ launcher:a="0.6"
+ launcher:b="0"
+ launcher:c="20dp"/>
+ </device-padding>
+
+ <device-padding
+ launcher:maxEmptySpace="280dp">
+ <workspaceTopPadding
+ launcher:a="0"
+ launcher:b="112dp"/>
+ <workspaceBottomPadding
+ launcher:a="0.4"
+ launcher:b="0"
+ launcher:c="112dp"/>
+ <hotseatBottomPadding
+ launcher:a="0.6"
+ launcher:b="0"
+ launcher:c="112dp"/>
+ </device-padding>
+
+ <device-padding
+ launcher:maxEmptySpace="9999dp">
+ <workspaceTopPadding
+ launcher:a="0.40"
+ launcher:c="36dp"/>
+ <workspaceBottomPadding
+ launcher:a="0.60"
+ launcher:c="36dp"/>
+ <hotseatBottomPadding
+ launcher:a="0"
+ launcher:b="36dp"/>
+ </device-padding>
+</device-paddings>
\ No newline at end of file
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 3489c31..72d0f59 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -97,18 +97,16 @@
private static final float TALL_DEVICE_EXTRA_SPACE_THRESHOLD_DP = 252;
private static final float TALL_DEVICE_MORE_EXTRA_SPACE_THRESHOLD_DP = 268;
- // To evenly space the icons, increase the left/right margins for tablets in portrait mode.
- private static final int PORTRAIT_TABLET_LEFT_RIGHT_PADDING_MULTIPLIER = 4;
-
// Workspace
public final int desiredWorkspaceHorizontalMarginOriginalPx;
public int desiredWorkspaceHorizontalMarginPx;
public Point cellLayoutBorderSpaceOriginalPx;
public Point cellLayoutBorderSpacePx;
- public final int cellLayoutPaddingLeftRightPx;
- public final int cellLayoutBottomPaddingPx;
+ public Rect cellLayoutPaddingPx = new Rect();
+
public final int edgeMarginPx;
- public float workspaceSpringLoadShrinkFactor;
+ public float workspaceSpringLoadShrunkTop;
+ public float workspaceSpringLoadShrunkBottom;
public final int workspaceSpringLoadedBottomSpace;
private final int extraSpace;
@@ -164,6 +162,7 @@
public int hotseatBarSizePx;
public int hotseatBarTopPaddingPx;
public final int hotseatBarBottomPaddingPx;
+ public int springLoadedHotseatBarTopMarginPx;
// 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;
@@ -209,8 +208,13 @@
// Drop Target
public int dropTargetBarSizePx;
+ public int dropTargetBarTopMarginPx;
+ public int dropTargetBarBottomMarginPx;
public int dropTargetDragPaddingPx;
public int dropTargetTextSizePx;
+ public int dropTargetHorizontalPaddingPx;
+ public int dropTargetVerticalPaddingPx;
+ public int dropTargetGapPx;
// Insets
private final Rect mInsets = new Rect();
@@ -246,6 +250,7 @@
windowX = windowBounds.bounds.left;
windowY = windowBounds.bounds.top;
this.rotationHint = windowBounds.rotationHint;
+ mInsets.set(windowBounds.insets);
isScalableGrid = inv.isScalable && !isVerticalBarLayout() && !isMultiWindowMode;
@@ -298,7 +303,7 @@
desiredWorkspaceHorizontalMarginPx = getHorizontalMarginPx(inv, res);
desiredWorkspaceHorizontalMarginOriginalPx = desiredWorkspaceHorizontalMarginPx;
- bottomSheetTopPadding = windowBounds.insets.top // statusbar height
+ bottomSheetTopPadding = mInsets.top // statusbar height
+ res.getDimensionPixelSize(R.dimen.bottom_sheet_extra_top_padding)
+ (isTablet ? 0 : edgeMarginPx); // phones need edgeMarginPx additional padding
@@ -321,23 +326,6 @@
folderCellLayoutBorderSpacePx = new Point(folderCellLayoutBorderSpaceOriginalPx,
folderCellLayoutBorderSpaceOriginalPx);
- int cellLayoutPaddingLeftRightMultiplier = !isVerticalBarLayout() && isTablet
- ? PORTRAIT_TABLET_LEFT_RIGHT_PADDING_MULTIPLIER : 1;
- int cellLayoutPadding = isScalableGrid
- ? 0
- : res.getDimensionPixelSize(R.dimen.dynamic_grid_cell_layout_padding);
-
- if (isTwoPanels) {
- cellLayoutPaddingLeftRightPx = 0;
- cellLayoutBottomPaddingPx = 0;
- } else if (isLandscape) {
- cellLayoutPaddingLeftRightPx = 0;
- cellLayoutBottomPaddingPx = cellLayoutPadding;
- } else {
- cellLayoutPaddingLeftRightPx = cellLayoutPaddingLeftRightMultiplier * cellLayoutPadding;
- cellLayoutBottomPaddingPx = 0;
- }
-
workspacePageIndicatorHeight = res.getDimensionPixelSize(
R.dimen.workspace_page_indicator_height);
mWorkspacePageIndicatorOverlapWorkspace =
@@ -347,8 +335,15 @@
res.getDimensionPixelSize(R.dimen.dynamic_grid_icon_drawable_padding);
dropTargetBarSizePx = res.getDimensionPixelSize(R.dimen.dynamic_grid_drop_target_size);
+ dropTargetBarTopMarginPx = res.getDimensionPixelSize(R.dimen.drop_target_top_margin);
+ dropTargetBarBottomMarginPx = res.getDimensionPixelSize(R.dimen.drop_target_bottom_margin);
dropTargetDragPaddingPx = res.getDimensionPixelSize(R.dimen.drop_target_drag_padding);
dropTargetTextSizePx = res.getDimensionPixelSize(R.dimen.drop_target_text_size);
+ dropTargetHorizontalPaddingPx = res.getDimensionPixelSize(
+ R.dimen.drop_target_button_drawable_horizontal_padding);
+ dropTargetVerticalPaddingPx = res.getDimensionPixelSize(
+ R.dimen.drop_target_button_drawable_vertical_padding);
+ dropTargetGapPx = res.getDimensionPixelSize(R.dimen.drop_target_button_gap);
workspaceSpringLoadedBottomSpace =
res.getDimensionPixelSize(R.dimen.dynamic_grid_min_spring_loaded_space);
@@ -389,6 +384,8 @@
+ res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_bottom_padding);
qsbWidth = 0;
}
+ springLoadedHotseatBarTopMarginPx = res.getDimensionPixelSize(
+ R.dimen.spring_loaded_hotseat_top_margin);
hotseatBarSidePaddingEndPx =
res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_side_padding);
// Add a bit of space between nav bar and hotseat in vertical bar layout.
@@ -482,6 +479,12 @@
// Recalculate the available dimensions using the new hotseat size.
updateAvailableDimensions(res);
}
+
+ int cellLayoutPadding =
+ isTwoPanels ? cellLayoutBorderSpacePx.x / 2 : res.getDimensionPixelSize(
+ R.dimen.cell_layout_padding);
+ cellLayoutPaddingPx = new Rect(cellLayoutPadding, cellLayoutPadding, cellLayoutPadding,
+ cellLayoutPadding);
updateWorkspacePadding();
flingToDeleteThresholdVelocity = res.getDimensionPixelSize(
@@ -567,6 +570,7 @@
WindowBounds bounds = new WindowBounds(
widthPx, heightPx, availableWidthPx, availableHeightPx, rotationHint);
bounds.bounds.offsetTo(windowX, windowY);
+ bounds.insets.set(mInsets);
return new Builder(context, inv, mInfo)
.setWindowBounds(bounds)
.setUseTwoPanels(isTwoPanels)
@@ -594,7 +598,6 @@
float appWidgetScaleX = (float) profile.getCellSize().x / getCellSize().x;
float appWidgetScaleY = (float) profile.getCellSize().y / getCellSize().y;
profile.appWidgetScale.set(appWidgetScaleX, appWidgetScaleY);
- profile.updateWorkspacePadding();
return profile;
}
@@ -629,18 +632,19 @@
}
private void updateAllAppsContainerWidth(Resources res) {
-
+ int cellLayoutHorizontalPadding =
+ (cellLayoutPaddingPx.left + cellLayoutPaddingPx.right) / 2;
if (isTablet) {
allAppsLeftRightPadding =
- res.getDimensionPixelSize(R.dimen.all_apps_bottom_sheet_horizontal_padding)
- + cellLayoutPaddingLeftRightPx;
+ res.getDimensionPixelSize(R.dimen.all_apps_bottom_sheet_horizontal_padding);
+
int usedWidth = (allAppsCellWidthPx * numShownAllAppsColumns)
+ (allAppsBorderSpacePx.x * (numShownAllAppsColumns - 1))
+ allAppsLeftRightPadding * 2;
allAppsLeftRightMargin = Math.max(1, (availableWidthPx - usedWidth) / 2);
} else {
allAppsLeftRightPadding =
- desiredWorkspaceHorizontalMarginPx + cellLayoutPaddingLeftRightPx;
+ desiredWorkspaceHorizontalMarginPx + cellLayoutHorizontalPadding;
}
}
@@ -650,11 +654,12 @@
private int updateAvailableDimensions(Resources res) {
updateIconSize(1f, res);
+ updateWorkspacePadding();
Point workspacePadding = getTotalWorkspacePadding();
// Check to see if the icons fit within the available height.
float usedHeight = getCellLayoutHeight();
- final int maxHeight = availableHeightPx - workspacePadding.y;
+ final int maxHeight = getWorkspaceHeight(workspacePadding);
float extraHeight = Math.max(0, maxHeight - usedHeight);
float scaleY = maxHeight / usedHeight;
boolean shouldScale = scaleY < 1f;
@@ -664,10 +669,7 @@
// We scale to fit the cellWidth and cellHeight in the available space.
// The benefit of scalable grids is that we can get consistent aspect ratios between
// devices.
- int numColumns = isTwoPanels ? inv.numColumns * 2 : inv.numColumns;
- float usedWidth = (cellWidthPx * numColumns)
- + (cellLayoutBorderSpacePx.x * (numColumns - 1))
- + (desiredWorkspaceHorizontalMarginPx * 2);
+ float usedWidth = getCellLayoutWidth() + (desiredWorkspaceHorizontalMarginPx * 2);
// We do not subtract padding here, as we also scale the workspace padding if needed.
scaleX = availableWidthPx / usedWidth;
shouldScale = true;
@@ -684,7 +686,14 @@
}
private int getCellLayoutHeight() {
- return (cellHeightPx * inv.numRows) + (cellLayoutBorderSpacePx.y * (inv.numRows - 1));
+ return (cellHeightPx * inv.numRows) + (cellLayoutBorderSpacePx.y * (inv.numRows - 1))
+ + cellLayoutPaddingPx.top + cellLayoutPaddingPx.bottom;
+ }
+
+ private int getCellLayoutWidth() {
+ int numColumns = isTwoPanels ? inv.numColumns * 2 : inv.numColumns;
+ return (cellWidthPx * numColumns) + (cellLayoutBorderSpacePx.x * (numColumns - 1))
+ + cellLayoutPaddingPx.left + cellLayoutPaddingPx.right;
}
/**
@@ -744,18 +753,6 @@
}
updateHotseatIconSize(iconSizePx);
- if (!isVerticalLayout) {
- int expectedWorkspaceHeight = availableHeightPx - hotseatBarSizePx
- - workspacePageIndicatorHeight - edgeMarginPx;
- float minRequiredHeight = dropTargetBarSizePx + workspaceSpringLoadedBottomSpace;
- workspaceSpringLoadShrinkFactor = Math.min(
- res.getInteger(R.integer.config_workspaceSpringLoadShrinkPercentage) / 100.0f,
- 1 - (minRequiredHeight / expectedWorkspaceHeight));
- } else {
- workspaceSpringLoadShrinkFactor =
- res.getInteger(R.integer.config_workspaceSpringLoadShrinkPercentage) / 100.0f;
- }
-
// Folder icon
folderIconSizePx = IconNormalizer.getNormalizedCircleSize(iconSizePx);
folderIconOffsetYPx = (iconSizePx - folderIconSizePx) / 2;
@@ -865,7 +862,6 @@
public void updateInsets(Rect insets) {
mInsets.set(insets);
- updateWorkspacePadding();
}
/**
@@ -892,23 +888,62 @@
int numColumns = isTwoPanels ? inv.numColumns * 2 : inv.numColumns;
int screenWidthPx = getWorkspaceWidth(padding);
result.x = calculateCellWidth(screenWidthPx, cellLayoutBorderSpacePx.x, numColumns);
- result.y = calculateCellHeight(availableHeightPx - padding.y
- - cellLayoutBottomPaddingPx, cellLayoutBorderSpacePx.y, inv.numRows);
+ int screenHeightPx = getWorkspaceHeight(padding);
+ result.y = calculateCellHeight(screenHeightPx, cellLayoutBorderSpacePx.y, inv.numRows);
return result;
}
+ /**
+ * Gets the space in px from the bottom of last item in the vertical-bar hotseat to the
+ * bottom of the screen.
+ */
+ public int getVerticalHotseatLastItemBottomOffset() {
+ int cellHeight = calculateCellHeight(
+ heightPx - mHotseatPadding.top - mHotseatPadding.bottom, hotseatBorderSpace,
+ numShownHotseatIcons);
+ int hotseatSize = (cellHeight * numShownHotseatIcons)
+ + (hotseatBorderSpace * (numShownHotseatIcons - 1));
+ int extraHotseatEndSpacing = (heightPx - hotseatSize) / 2;
+ int extraIconEndSpacing = (cellHeight - iconSizePx) / 2;
+ return extraHotseatEndSpacing + extraIconEndSpacing + mHotseatPadding.bottom;
+ }
+
+ /**
+ * Gets the scaled top of the workspace in px for the spring-loaded edit state.
+ */
+ public float getWorkspaceSpringLoadShrunkTop() {
+ workspaceSpringLoadShrunkTop = mInsets.top + dropTargetBarTopMarginPx + dropTargetBarSizePx
+ + dropTargetBarBottomMarginPx;
+ return workspaceSpringLoadShrunkTop;
+ }
+
+ /**
+ * Gets the scaled bottom of the workspace in px for the spring-loaded edit state.
+ */
+ public float getWorkspaceSpringLoadShrunkBottom() {
+ int topOfHotseat = hotseatBarSizePx + springLoadedHotseatBarTopMarginPx;
+ workspaceSpringLoadShrunkBottom =
+ heightPx - (isVerticalBarLayout() ? getVerticalHotseatLastItemBottomOffset()
+ : topOfHotseat);
+ return workspaceSpringLoadShrunkBottom;
+ }
+
public int getWorkspaceWidth() {
return getWorkspaceWidth(getTotalWorkspacePadding());
}
public int getWorkspaceWidth(Point workspacePadding) {
int cellLayoutTotalPadding =
- isTwoPanels ? 4 * cellLayoutPaddingLeftRightPx : 2 * cellLayoutPaddingLeftRightPx;
+ (isTwoPanels ? 2 : 1) * (cellLayoutPaddingPx.left + cellLayoutPaddingPx.right);
return availableWidthPx - workspacePadding.x - cellLayoutTotalPadding;
}
+ private int getWorkspaceHeight(Point workspacePadding) {
+ return availableHeightPx - workspacePadding.y - (cellLayoutPaddingPx.top
+ + cellLayoutPaddingPx.bottom);
+ }
+
public Point getTotalWorkspacePadding() {
- updateWorkspacePadding();
return new Point(workspacePadding.left + workspacePadding.right,
workspacePadding.top + workspacePadding.bottom);
}
@@ -934,12 +969,26 @@
int hotseatTop = hotseatBarSizePx;
int paddingBottom = hotseatTop + workspacePageIndicatorHeight
+ workspaceBottomPadding - mWorkspacePageIndicatorOverlapWorkspace;
+ int paddingTop = workspaceTopPadding + (isScalableGrid ? 0 : edgeMarginPx);
+ int paddingSide = desiredWorkspaceHorizontalMarginPx;
- padding.set(desiredWorkspaceHorizontalMarginPx,
- workspaceTopPadding + (isScalableGrid ? 0 : edgeMarginPx),
- desiredWorkspaceHorizontalMarginPx,
- paddingBottom);
+ padding.set(paddingSide, paddingTop, paddingSide, paddingBottom);
}
+ insetPadding(workspacePadding, cellLayoutPaddingPx);
+ }
+
+ private void insetPadding(Rect paddings, Rect insets) {
+ insets.left = Math.min(insets.left, paddings.left);
+ paddings.left -= insets.left;
+
+ insets.top = Math.min(insets.top, paddings.top);
+ paddings.top -= insets.top;
+
+ insets.right = Math.min(insets.right, paddings.right);
+ paddings.right -= insets.right;
+
+ insets.bottom = Math.min(insets.bottom, paddings.bottom);
+ paddings.bottom -= insets.bottom;
}
/**
@@ -953,16 +1002,17 @@
// Workspace icons are moved up by a small factor. The variable diffOverlapFactor
// is set to account for that difference.
float diffOverlapFactor = iconSizePx * (ICON_OVERLAP_FACTOR - 1) / 2;
- int paddingTop = Math.max((int) (mInsets.top - diffOverlapFactor), 0);
- int paddingBottom = Math.max((int) (mInsets.bottom + cellLayoutBottomPaddingPx
+ int paddingTop = Math.max((int) (mInsets.top + cellLayoutPaddingPx.top
+ - diffOverlapFactor), 0);
+ int paddingBottom = Math.max((int) (mInsets.bottom + cellLayoutPaddingPx.bottom
+ diffOverlapFactor), 0);
if (isSeascape()) {
- mHotseatPadding.set(mInsets.left + hotseatBarSidePaddingStartPx,
- mInsets.top, hotseatBarSidePaddingEndPx, mInsets.bottom);
+ mHotseatPadding.set(mInsets.left + hotseatBarSidePaddingStartPx, paddingTop,
+ hotseatBarSidePaddingEndPx, paddingBottom);
} else {
- mHotseatPadding.set(hotseatBarSidePaddingEndPx, mInsets.top,
- mInsets.right + hotseatBarSidePaddingStartPx, mInsets.bottom);
+ mHotseatPadding.set(hotseatBarSidePaddingEndPx, paddingTop,
+ mInsets.right + hotseatBarSidePaddingStartPx, paddingBottom);
}
} else if (isTaskbarPresent) {
int hotseatHeight = workspacePadding.bottom;
@@ -1001,14 +1051,12 @@
float workspaceCellWidth = (float) widthPx / inv.numColumns;
float hotseatCellWidth = (float) widthPx / numShownHotseatIcons;
int hotseatAdjustment = Math.round((workspaceCellWidth - hotseatCellWidth) / 2);
- mHotseatPadding.set(
- hotseatAdjustment + workspacePadding.left + cellLayoutPaddingLeftRightPx
- + mInsets.left,
- hotseatBarTopPaddingPx,
- hotseatAdjustment + workspacePadding.right + cellLayoutPaddingLeftRightPx
+ mHotseatPadding.set(hotseatAdjustment + workspacePadding.left + cellLayoutPaddingPx.left
+ + mInsets.left, hotseatBarTopPaddingPx,
+ hotseatAdjustment + workspacePadding.right + cellLayoutPaddingPx.right
+ mInsets.right,
hotseatBarSizePx - hotseatCellHeightPx - hotseatBarTopPaddingPx
- + cellLayoutBottomPaddingPx + mInsets.bottom);
+ + mInsets.bottom);
}
return mHotseatPadding;
}
@@ -1092,6 +1140,8 @@
.getInfo().rotation == Surface.ROTATION_270;
if (mIsSeascape != isSeascape) {
mIsSeascape = isSeascape;
+ // Hotseat changing sides requires updating workspace left/right paddings
+ updateWorkspacePadding();
return true;
}
}
@@ -1144,9 +1194,12 @@
writer.println(prefix + pxToDpStr("windowY", windowY));
writer.println(prefix + pxToDpStr("widthPx", widthPx));
writer.println(prefix + pxToDpStr("heightPx", heightPx));
-
writer.println(prefix + pxToDpStr("availableWidthPx", availableWidthPx));
writer.println(prefix + pxToDpStr("availableHeightPx", availableHeightPx));
+ writer.println(prefix + pxToDpStr("mInsets.left", mInsets.left));
+ writer.println(prefix + pxToDpStr("mInsets.top", mInsets.top));
+ writer.println(prefix + pxToDpStr("mInsets.right", mInsets.right));
+ writer.println(prefix + pxToDpStr("mInsets.bottom", mInsets.bottom));
writer.println(prefix + "\taspectRatio:" + aspectRatio);
@@ -1169,6 +1222,11 @@
cellLayoutBorderSpacePx.x));
writer.println(prefix + pxToDpStr("cellLayoutBorderSpacePx Vertical",
cellLayoutBorderSpacePx.y));
+ writer.println(prefix + pxToDpStr("cellLayoutPaddingPx.left", cellLayoutPaddingPx.left));
+ writer.println(prefix + pxToDpStr("cellLayoutPaddingPx.top", cellLayoutPaddingPx.top));
+ writer.println(prefix + pxToDpStr("cellLayoutPaddingPx.right", cellLayoutPaddingPx.right));
+ writer.println(
+ prefix + pxToDpStr("cellLayoutPaddingPx.bottom", cellLayoutPaddingPx.bottom));
writer.println(prefix + pxToDpStr("iconSizePx", iconSizePx));
writer.println(prefix + pxToDpStr("iconTextSizePx", iconTextSizePx));
@@ -1187,6 +1245,10 @@
writer.println(prefix + pxToDpStr("folderCellLayoutBorderSpacePx Vertical",
folderCellLayoutBorderSpacePx.y));
+ writer.println(prefix + pxToDpStr("bottomSheetTopPadding", bottomSheetTopPadding));
+
+ writer.println(prefix + pxToDpStr("allAppsShiftRange", allAppsShiftRange));
+ writer.println(prefix + pxToDpStr("allAppsTopPadding", allAppsTopPadding));
writer.println(prefix + pxToDpStr("allAppsIconSizePx", allAppsIconSizePx));
writer.println(prefix + pxToDpStr("allAppsIconTextSizePx", allAppsIconTextSizePx));
writer.println(prefix + pxToDpStr("allAppsIconDrawablePaddingPx",
@@ -1206,6 +1268,12 @@
hotseatBarSidePaddingStartPx));
writer.println(prefix + pxToDpStr("hotseatBarSidePaddingEndPx",
hotseatBarSidePaddingEndPx));
+ writer.println(prefix + pxToDpStr("springLoadedHotseatBarTopMarginPx",
+ springLoadedHotseatBarTopMarginPx));
+ writer.println(prefix + pxToDpStr("mHotseatPadding.top", mHotseatPadding.top));
+ writer.println(prefix + pxToDpStr("mHotseatPadding.bottom", mHotseatPadding.bottom));
+ writer.println(prefix + pxToDpStr("mHotseatPadding.left", mHotseatPadding.left));
+ writer.println(prefix + pxToDpStr("mHotseatPadding.right", mHotseatPadding.right));
writer.println(prefix + "\tnumShownHotseatIcons: " + numShownHotseatIcons);
writer.println(prefix + pxToDpStr("hotseatBorderSpace", hotseatBorderSpace));
writer.println(prefix + "\tisQsbInline: " + isQsbInline);
@@ -1256,6 +1324,16 @@
writer.println(prefix + pxToDpStr("overviewPageSpacing", overviewPageSpacing));
writer.println(prefix + pxToDpStr("overviewRowSpacing", overviewRowSpacing));
writer.println(prefix + pxToDpStr("overviewGridSideMargin", overviewGridSideMargin));
+
+ writer.println(prefix + pxToDpStr("dropTargetBarTopMarginPx", dropTargetBarTopMarginPx));
+ writer.println(prefix + pxToDpStr("dropTargetBarSizePx", dropTargetBarSizePx));
+ writer.println(
+ prefix + pxToDpStr("dropTargetBarBottomMarginPx", dropTargetBarBottomMarginPx));
+
+ writer.println(
+ prefix + pxToDpStr("workspaceSpringLoadShrunkTop", workspaceSpringLoadShrunkTop));
+ writer.println(prefix + pxToDpStr("workspaceSpringLoadShrunkBottom",
+ workspaceSpringLoadShrunkBottom));
}
private static Context getContext(Context c, Info info, int orientation, WindowBounds bounds) {
diff --git a/src/com/android/launcher3/DropTargetBar.java b/src/com/android/launcher3/DropTargetBar.java
index 9fb14f6..73289fb 100644
--- a/src/com/android/launcher3/DropTargetBar.java
+++ b/src/com/android/launcher3/DropTargetBar.java
@@ -17,8 +17,6 @@
package com.android.launcher3;
import static com.android.launcher3.ButtonDropTarget.TOOLTIP_DEFAULT;
-import static com.android.launcher3.ButtonDropTarget.TOOLTIP_LEFT;
-import static com.android.launcher3.ButtonDropTarget.TOOLTIP_RIGHT;
import static com.android.launcher3.anim.AlphaUpdateListener.updateVisibility;
import android.animation.TimeInterpolator;
@@ -41,6 +39,8 @@
import com.android.launcher3.dragndrop.DragOptions;
import com.android.launcher3.testing.TestProtocol;
+import java.util.Arrays;
+
/*
* The top bar containing various drop targets: Delete/App Info/Uninstall.
*/
@@ -94,30 +94,28 @@
lp.rightMargin = insets.right;
int tooltipLocation = TOOLTIP_DEFAULT;
- if (grid.isVerticalBarLayout()) {
- lp.width = grid.dropTargetBarSizePx;
- lp.height = grid.availableHeightPx - 2 * grid.edgeMarginPx;
- lp.gravity = grid.isSeascape() ? Gravity.RIGHT : Gravity.LEFT;
- tooltipLocation = grid.isSeascape() ? TOOLTIP_LEFT : TOOLTIP_RIGHT;
+ int horizontalMargin;
+ if (grid.isTablet) {
+ // XXX: If the icon size changes across orientations, we will have to take
+ // that into account here too.
+ horizontalMargin = ((grid.widthPx - 2 * grid.edgeMarginPx
+ - (grid.inv.numColumns * grid.cellWidthPx))
+ / (2 * (grid.inv.numColumns + 1)))
+ + grid.edgeMarginPx;
} else {
- int gap;
- if (grid.isTablet) {
- // XXX: If the icon size changes across orientations, we will have to take
- // that into account here too.
- gap = ((grid.widthPx - 2 * grid.edgeMarginPx
- - (grid.inv.numColumns * grid.cellWidthPx))
- / (2 * (grid.inv.numColumns + 1)))
- + grid.edgeMarginPx;
- } else {
- gap = getContext().getResources()
- .getDimensionPixelSize(R.dimen.drop_target_bar_margin_horizontal);
- }
- lp.width = grid.availableWidthPx - 2 * gap;
-
- lp.topMargin += grid.edgeMarginPx;
- lp.height = grid.dropTargetBarSizePx;
- lp.gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP;
+ horizontalMargin = getContext().getResources()
+ .getDimensionPixelSize(R.dimen.drop_target_bar_margin_horizontal);
}
+ lp.topMargin += grid.dropTargetBarTopMarginPx;
+ lp.bottomMargin += grid.dropTargetBarBottomMarginPx;
+ lp.width = grid.availableWidthPx - 2 * horizontalMargin;
+ if (mIsVertical) {
+ lp.leftMargin = (grid.widthPx - lp.width) / 2;
+ lp.rightMargin = (grid.widthPx - lp.width) / 2;
+ }
+ lp.height = grid.dropTargetBarSizePx;
+ lp.gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP;
+
setLayoutParams(lp);
for (ButtonDropTarget button : mDropTargets) {
button.setTextSize(TypedValue.COMPLEX_UNIT_PX, grid.dropTargetTextSizePx);
@@ -139,19 +137,7 @@
int height = MeasureSpec.getSize(heightMeasureSpec);
int visibleCount = getVisibleButtonsCount();
- if (visibleCount == 0) {
- // do nothing
- } else if (mIsVertical) {
- int widthSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);
- int heightSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST);
-
- for (ButtonDropTarget button : mDropTargets) {
- if (button.getVisibility() != GONE) {
- button.setTextVisible(false);
- button.measure(widthSpec, heightSpec);
- }
- }
- } else {
+ if (visibleCount > 0) {
int availableWidth = width / visibleCount;
boolean textVisible = true;
for (ButtonDropTarget buttons : mDropTargets) {
@@ -176,31 +162,91 @@
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
int visibleCount = getVisibleButtonsCount();
if (visibleCount == 0) {
- // do nothing
- } else if (mIsVertical) {
- int gap = getResources().getDimensionPixelSize(R.dimen.drop_target_vertical_gap);
- int start = gap;
- int end;
+ return;
+ }
- for (ButtonDropTarget button : mDropTargets) {
- if (button.getVisibility() != GONE) {
- end = start + button.getMeasuredHeight();
- button.layout(0, start, button.getMeasuredWidth(), end);
- start = end + gap;
- }
- }
- } else {
- int frameSize = (right - left) / visibleCount;
+ Launcher launcher = Launcher.getLauncher(getContext());
+ Workspace workspace = launcher.getWorkspace();
+ DeviceProfile dp = launcher.getDeviceProfile();
+ int buttonHorizontalPadding = dp.dropTargetHorizontalPaddingPx;
+ int buttonVerticalPadding = dp.dropTargetVerticalPaddingPx;
+ int barCenter = (right - left) / 2;
- int start = frameSize / 2;
- int halfWidth;
- for (ButtonDropTarget button : mDropTargets) {
- if (button.getVisibility() != GONE) {
- halfWidth = button.getMeasuredWidth() / 2;
- button.layout(start - halfWidth, 0,
- start + halfWidth, button.getMeasuredHeight());
- start = start + frameSize;
+ ButtonDropTarget[] visibleButtons = Arrays.stream(mDropTargets)
+ .filter(b -> b.getVisibility() != GONE)
+ .toArray(ButtonDropTarget[]::new);
+ Arrays.stream(visibleButtons).forEach(
+ b -> b.setPadding(buttonHorizontalPadding, buttonVerticalPadding,
+ buttonHorizontalPadding, buttonVerticalPadding));
+
+ if (visibleCount == 1) {
+ ButtonDropTarget button = visibleButtons[0];
+ button.layout(barCenter - (button.getMeasuredWidth() / 2), 0,
+ barCenter + (button.getMeasuredWidth() / 2), button.getMeasuredHeight());
+ } else if (visibleCount == 2) {
+ int buttonGap = dp.dropTargetGapPx;
+
+ if (dp.isTwoPanels) {
+ ButtonDropTarget leftButton = visibleButtons[0];
+ leftButton.layout(barCenter - leftButton.getMeasuredWidth() - (buttonGap / 2), 0,
+ barCenter - (buttonGap / 2), leftButton.getMeasuredHeight());
+
+ ButtonDropTarget rightButton = visibleButtons[1];
+ rightButton.layout(barCenter + (buttonGap / 2), 0,
+ barCenter + rightButton.getMeasuredWidth() + (buttonGap / 2),
+ rightButton.getMeasuredHeight());
+ } else if (dp.isTablet) {
+ int numberOfMargins = visibleCount - 1;
+ int buttonWidths = Arrays.stream(mDropTargets)
+ .filter(b -> b.getVisibility() != GONE)
+ .mapToInt(ButtonDropTarget::getMeasuredWidth)
+ .sum();
+ int totalWidth = buttonWidths + (numberOfMargins * buttonGap);
+ int buttonsStartMargin = barCenter - (totalWidth / 2);
+
+ int start = buttonsStartMargin;
+ for (ButtonDropTarget button : visibleButtons) {
+ int margin = (start != buttonsStartMargin) ? buttonGap : 0;
+ button.layout(start + margin, 0, start + margin + button.getMeasuredWidth(),
+ button.getMeasuredHeight());
+ start += button.getMeasuredWidth() + margin;
}
+ } else if (mIsVertical) {
+ // Center buttons over workspace, not screen.
+ int verticalCenter = (workspace.getRight() - workspace.getLeft()) / 2;
+ ButtonDropTarget leftButton = visibleButtons[0];
+ leftButton.layout(verticalCenter - leftButton.getMeasuredWidth() - (buttonGap / 2),
+ 0, verticalCenter - (buttonGap / 2), leftButton.getMeasuredHeight());
+
+ ButtonDropTarget rightButton = visibleButtons[1];
+ rightButton.layout(verticalCenter + (buttonGap / 2), 0,
+ verticalCenter + rightButton.getMeasuredWidth() + (buttonGap / 2),
+ rightButton.getMeasuredHeight());
+ } else if (dp.isPhone) {
+ // Buttons aligned to outer edges of scaled workspace.
+ float shrunkTop = dp.getWorkspaceSpringLoadShrunkTop();
+ float shrunkBottom = dp.getWorkspaceSpringLoadShrunkBottom();
+ float scale =
+ (shrunkBottom - shrunkTop) / launcher.getWorkspace().getNormalChildHeight();
+ int workspaceWidth = (int) (launcher.getWorkspace().getNormalChildWidth() * scale);
+ int start = barCenter - (workspaceWidth / 2);
+ int end = barCenter + (workspaceWidth / 2);
+
+ ButtonDropTarget leftButton = visibleButtons[0];
+ ButtonDropTarget rightButton = visibleButtons[1];
+
+ // If the text within the buttons is too long, the buttons can overlap
+ int overlap = start + leftButton.getMeasuredWidth() + rightButton.getMeasuredWidth()
+ - end;
+ if (overlap > 0) {
+ start -= overlap / 2;
+ end += overlap / 2;
+ }
+
+ leftButton.layout(start, 0, start + leftButton.getMeasuredWidth(),
+ leftButton.getMeasuredHeight());
+ rightButton.layout(end - rightButton.getMeasuredWidth(), 0, end,
+ rightButton.getMeasuredHeight());
}
}
}
diff --git a/src/com/android/launcher3/GestureNavContract.java b/src/com/android/launcher3/GestureNavContract.java
index 2a7e629..c782dca 100644
--- a/src/com/android/launcher3/GestureNavContract.java
+++ b/src/com/android/launcher3/GestureNavContract.java
@@ -18,20 +18,30 @@
import static android.content.Intent.EXTRA_COMPONENT_NAME;
import static android.content.Intent.EXTRA_USER;
+import static com.android.launcher3.AbstractFloatingView.TYPE_ICON_SURFACE;
+
import android.annotation.TargetApi;
import android.content.ComponentName;
import android.content.Intent;
import android.graphics.RectF;
import android.os.Build;
import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
import android.os.Message;
+import android.os.Messenger;
import android.os.RemoteException;
import android.os.UserHandle;
import android.util.Log;
import android.view.SurfaceControl;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import com.android.launcher3.views.ActivityContext;
+
+import java.lang.ref.WeakReference;
+
/**
* Class to encapsulate the handshake protocol between Launcher and gestureNav.
*/
@@ -43,6 +53,7 @@
public static final String EXTRA_ICON_POSITION = "gesture_nav_contract_icon_position";
public static final String EXTRA_ICON_SURFACE = "gesture_nav_contract_surface_control";
public static final String EXTRA_REMOTE_CALLBACK = "android.intent.extra.REMOTE_CALLBACK";
+ public static final String EXTRA_ON_FINISH_CALLBACK = "gesture_nav_contract_finish_callback";
public final ComponentName componentName;
public final UserHandle user;
@@ -59,10 +70,15 @@
* Sends the position information to the receiver
*/
@TargetApi(Build.VERSION_CODES.R)
- public void sendEndPosition(RectF position, @Nullable SurfaceControl surfaceControl) {
+ public void sendEndPosition(RectF position, ActivityContext context,
+ @Nullable SurfaceControl surfaceControl) {
Bundle result = new Bundle();
result.putParcelable(EXTRA_ICON_POSITION, position);
result.putParcelable(EXTRA_ICON_SURFACE, surfaceControl);
+ if (sMessageReceiver == null) {
+ sMessageReceiver = new StaticMessageReceiver();
+ }
+ result.putParcelable(EXTRA_ON_FINISH_CALLBACK, sMessageReceiver.setCurrentContext(context));
Message callback = Message.obtain();
callback.copyFrom(mCallback);
@@ -98,4 +114,42 @@
}
return null;
}
+
+ /**
+ * Message used for receiving gesture nav contract information. We use a static messenger to
+ * avoid leaking too make binders in case the receiving launcher does not handle the contract
+ * properly.
+ */
+ private static StaticMessageReceiver sMessageReceiver = null;
+
+ private static class StaticMessageReceiver implements Handler.Callback {
+
+ private static final int MSG_CLOSE_LAST_TARGET = 0;
+
+ private final Messenger mMessenger =
+ new Messenger(new Handler(Looper.getMainLooper(), this));
+
+ private WeakReference<ActivityContext> mLastTarget = new WeakReference<>(null);
+
+ public Message setCurrentContext(ActivityContext context) {
+ mLastTarget = new WeakReference<>(context);
+
+ Message msg = Message.obtain();
+ msg.replyTo = mMessenger;
+ msg.what = MSG_CLOSE_LAST_TARGET;
+ return msg;
+ }
+
+ @Override
+ public boolean handleMessage(@NonNull Message message) {
+ if (message.what == MSG_CLOSE_LAST_TARGET) {
+ ActivityContext lastContext = mLastTarget.get();
+ if (lastContext != null) {
+ AbstractFloatingView.closeOpenViews(lastContext, false, TYPE_ICON_SURFACE);
+ }
+ return true;
+ }
+ return false;
+ }
+ }
}
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 1cead11..2636d55 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -604,7 +604,13 @@
public void onEnterAnimationComplete() {
super.onEnterAnimationComplete();
mRotationHelper.setCurrentTransitionRequest(REQUEST_NONE);
- AbstractFloatingView.closeOpenViews(this, false, TYPE_ICON_SURFACE);
+ // Starting with Android S, onEnterAnimationComplete is sent immediately
+ // causing the surface to get removed before the animation completed (b/175345344).
+ // Instead we rely on next user touch event to remove the view and optionally a callback
+ // from system from Android T onwards.
+ if (!Utilities.ATLEAST_S) {
+ AbstractFloatingView.closeOpenViews(this, false, TYPE_ICON_SURFACE);
+ }
}
@Override
diff --git a/src/com/android/launcher3/LauncherAnimUtils.java b/src/com/android/launcher3/LauncherAnimUtils.java
index c43172c..4f3ae59 100644
--- a/src/com/android/launcher3/LauncherAnimUtils.java
+++ b/src/com/android/launcher3/LauncherAnimUtils.java
@@ -38,6 +38,7 @@
// Progress after which the transition is assumed to be a success
public static final float SUCCESS_TRANSITION_PROGRESS = 0.5f;
+ public static final float TABLET_BOTTOM_SHEET_SUCCESS_TRANSITION_PROGRESS = 0.3f;
public static final IntProperty<Drawable> DRAWABLE_ALPHA =
new IntProperty<Drawable>("drawableAlpha") {
diff --git a/src/com/android/launcher3/SecondaryDropTarget.java b/src/com/android/launcher3/SecondaryDropTarget.java
index cd06414..5b037e4 100644
--- a/src/com/android/launcher3/SecondaryDropTarget.java
+++ b/src/com/android/launcher3/SecondaryDropTarget.java
@@ -8,6 +8,7 @@
import static com.android.launcher3.accessibility.LauncherAccessibilityDelegate.DISMISS_PREDICTION;
import static com.android.launcher3.accessibility.LauncherAccessibilityDelegate.RECONFIGURE;
import static com.android.launcher3.accessibility.LauncherAccessibilityDelegate.UNINSTALL;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_DISMISS_PREDICTION_UNDO;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ITEM_DROPPED_ON_DONT_SUGGEST;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ITEM_DROPPED_ON_UNINSTALL;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ITEM_UNINSTALL_CANCELLED;
@@ -46,6 +47,7 @@
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
import com.android.launcher3.util.PackageManagerHelper;
import com.android.launcher3.util.PendingRequestArgs;
+import com.android.launcher3.views.Snackbar;
import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
import java.net.URISyntaxException;
@@ -220,7 +222,8 @@
@Override
public void completeDrop(final DragObject d) {
- ComponentName target = performDropAction(getViewUnderDrag(d.dragInfo), d.dragInfo);
+ ComponentName target = performDropAction(getViewUnderDrag(d.dragInfo), d.dragInfo,
+ d.logInstanceId);
if (d.dragSource instanceof DeferredOnComplete) {
DeferredOnComplete deferred = (DeferredOnComplete) d.dragSource;
if (target != null) {
@@ -264,7 +267,7 @@
* Performs the drop action and returns the target component for the dragObject or null if
* the action was not performed.
*/
- protected ComponentName performDropAction(View view, ItemInfo info) {
+ protected ComponentName performDropAction(View view, ItemInfo info, InstanceId instanceId) {
if (mCurrentAccessibilityAction == RECONFIGURE) {
int widgetId = getReconfigurableWidgetId(view);
if (widgetId != INVALID_APPWIDGET_ID) {
@@ -276,7 +279,16 @@
return null;
}
if (mCurrentAccessibilityAction == DISMISS_PREDICTION) {
- // We sent the log event, nothing else left to do
+ if (FeatureFlags.ENABLE_DISMISS_PREDICTION_UNDO.get()) {
+ mLauncher.getDragLayer()
+ .announceForAccessibility(getContext().getString(R.string.item_removed));
+ Snackbar.show(mLauncher, R.string.item_removed, R.string.undo, () -> { }, () -> {
+ mStatsLogManager.logger()
+ .withInstanceId(instanceId)
+ .withItemInfo(info)
+ .log(LAUNCHER_DISMISS_PREDICTION_UNDO);
+ });
+ }
return null;
}
// else: mCurrentAccessibilityAction == UNINSTALL
@@ -303,8 +315,9 @@
@Override
public void onAccessibilityDrop(View view, ItemInfo item) {
- doLog(new InstanceIdSequence().newInstanceId(), item);
- performDropAction(view, item);
+ InstanceId instanceId = new InstanceIdSequence().newInstanceId();
+ doLog(instanceId, item);
+ performDropAction(view, item, instanceId);
}
/**
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 6a136d4..ea9b69c 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -325,37 +325,14 @@
setPageSpacing(Math.max(maxInsets, maxPadding));
}
- updateWorkspaceScreensPadding();
+ updateCellLayoutPadding();
updateWorkspaceWidgetsSizes();
}
- private void updateWorkspaceScreensPadding() {
- DeviceProfile grid = mLauncher.getDeviceProfile();
- int paddingLeftRight = grid.cellLayoutPaddingLeftRightPx;
- int paddingBottom = grid.cellLayoutBottomPaddingPx;
-
- int panelCount = getPanelCount();
- int rightPanelModulus = mIsRtl ? 0 : panelCount - 1;
- int leftPanelModulus = mIsRtl ? panelCount - 1 : 0;
- int numberOfScreens = mScreenOrder.size();
- for (int i = 0; i < numberOfScreens; i++) {
- int paddingLeft = paddingLeftRight;
- int paddingRight = paddingLeftRight;
- // Add missing cellLayout border in-between panels.
- if (panelCount > 1) {
- if (i % panelCount == leftPanelModulus) {
- paddingRight += grid.cellLayoutBorderSpacePx.x / 2;
- } else if (i % panelCount == rightPanelModulus) { // right side panel
- paddingLeft += grid.cellLayoutBorderSpacePx.x / 2;
- } else { // middle panel
- paddingLeft += grid.cellLayoutBorderSpacePx.x / 2;
- paddingRight += grid.cellLayoutBorderSpacePx.x / 2;
- }
- }
- // SparseArrayMap doesn't keep the order
- mWorkspaceScreens.get(mScreenOrder.get(i))
- .setPadding(paddingLeft, 0, paddingRight, paddingBottom);
- }
+ private void updateCellLayoutPadding() {
+ Rect padding = mLauncher.getDeviceProfile().cellLayoutPaddingPx;
+ mWorkspaceScreens.forEach(
+ s -> s.setPadding(padding.left, padding.top, padding.right, padding.bottom));
}
private void updateWorkspaceWidgetsSizes() {
@@ -653,7 +630,7 @@
mLauncher.getStateManager().getState(), newScreen, insertIndex);
updatePageScrollValues();
- updateWorkspaceScreensPadding();
+ updateCellLayoutPadding();
return newScreen;
}
diff --git a/src/com/android/launcher3/allapps/WorkAdapterProvider.java b/src/com/android/launcher3/allapps/WorkAdapterProvider.java
index f52a21f..ce44958 100644
--- a/src/com/android/launcher3/allapps/WorkAdapterProvider.java
+++ b/src/com/android/launcher3/allapps/WorkAdapterProvider.java
@@ -92,8 +92,6 @@
TextView title = view.findViewById(R.id.work_apps_paused_title);
title.setText(cache.workProfileEdu);
- Button button = view.findViewById(R.id.action_btn);
- button.setText(cache.workProfileEduAccept);
}
/**
diff --git a/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java b/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java
index a6a47a7..886460e 100644
--- a/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java
+++ b/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java
@@ -16,6 +16,7 @@
package com.android.launcher3.allapps.search;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_FOCUSED_ITEM_SELECTED_WITH_IME;
+import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_QUICK_SEARCH_WITH_IME;
import android.text.Editable;
import android.text.SpannableStringBuilder;
@@ -122,7 +123,9 @@
if (actionId == EditorInfo.IME_ACTION_SEARCH || actionId == EditorInfo.IME_ACTION_GO) {
mLauncher.getStatsLogManager().logger()
- .log(LAUNCHER_ALLAPPS_FOCUSED_ITEM_SELECTED_WITH_IME);
+ .log(actionId == EditorInfo.IME_ACTION_SEARCH
+ ? LAUNCHER_ALLAPPS_QUICK_SEARCH_WITH_IME
+ : LAUNCHER_ALLAPPS_FOCUSED_ITEM_SELECTED_WITH_IME);
// selectFocusedView should return SearchTargetEvent that is passed onto onClick
return mLauncher.getAppsView().getMainAdapterProvider().launchHighlightedItem();
}
diff --git a/src/com/android/launcher3/anim/Interpolators.java b/src/com/android/launcher3/anim/Interpolators.java
index 9c12abd..1e7b224 100644
--- a/src/com/android/launcher3/anim/Interpolators.java
+++ b/src/com/android/launcher3/anim/Interpolators.java
@@ -130,23 +130,6 @@
}
};
- public static final Interpolator LINEAR_TELEPORT = t -> {
- float startTeleport = 0.2f;
- float endTeleport = 0.4f;
- float teleportProgress = 0.5f;
- float v;
- if (t < startTeleport) {
- v = LINEAR.getInterpolation(t);
- } else if (t < endTeleport) {
- v = Utilities.mapToRange(t, startTeleport, endTeleport, startTeleport,
- endTeleport + teleportProgress, ACCEL_DEACCEL);
- } else {
- v = LINEAR.getInterpolation(t) + teleportProgress;
- }
- v = Utilities.boundToRange(v, 0f, 1f);
- return v;
- };
-
private static final float FAST_FLING_PX_MS = 10;
public static Interpolator scrollInterpolatorForVelocity(float velocity) {
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 420180b..626e15c 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -265,6 +265,10 @@
"USE_LOCAL_ICON_OVERRIDES", true,
"Use inbuilt monochrome icons if app doesn't provide one");
+ public static final BooleanFlag ENABLE_DISMISS_PREDICTION_UNDO = getDebugFlag(
+ "ENABLE_DISMISS_PREDICTION_UNDO", false,
+ "Show an 'Undo' snackbar when users dismiss a predicted hotseat item");
+
public static void initialize(Context context) {
synchronized (sDebugFlags) {
for (DebugFlag flag : sDebugFlags) {
diff --git a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
index cc17064..3dfece7 100644
--- a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
+++ b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
@@ -225,21 +225,21 @@
mHotseat.resetLayout(false);
CellLayout firstScreen = mRootView.findViewById(R.id.workspace);
- firstScreen.setPadding(mDp.workspacePadding.left + mDp.cellLayoutPaddingLeftRightPx,
- mDp.workspacePadding.top,
+ firstScreen.setPadding(mDp.workspacePadding.left + mDp.cellLayoutPaddingPx.left,
+ mDp.workspacePadding.top + mDp.cellLayoutPaddingPx.top,
(mDp.isTwoPanels ? mDp.cellLayoutBorderSpacePx.x / 2
- : mDp.workspacePadding.right) + mDp.cellLayoutPaddingLeftRightPx,
- mDp.workspacePadding.bottom
+ : mDp.workspacePadding.right) + mDp.cellLayoutPaddingPx.right,
+ mDp.workspacePadding.bottom + mDp.cellLayoutPaddingPx.bottom
);
mWorkspaceScreens.put(FIRST_SCREEN_ID, firstScreen);
if (mDp.isTwoPanels) {
CellLayout rightPanel = mRootView.findViewById(R.id.workspace_right);
rightPanel.setPadding(
- mDp.cellLayoutBorderSpacePx.x / 2 + mDp.cellLayoutPaddingLeftRightPx,
- mDp.workspacePadding.top,
- mDp.workspacePadding.right + mDp.cellLayoutPaddingLeftRightPx,
- mDp.workspacePadding.bottom
+ mDp.cellLayoutBorderSpacePx.x / 2 + mDp.cellLayoutPaddingPx.left,
+ mDp.workspacePadding.top + mDp.cellLayoutPaddingPx.top,
+ mDp.workspacePadding.right + mDp.cellLayoutPaddingPx.right,
+ mDp.workspacePadding.bottom + mDp.cellLayoutPaddingPx.bottom
);
mWorkspaceScreens.put(Workspace.SECOND_SCREEN_ID, rightPanel);
}
diff --git a/src/com/android/launcher3/logging/StatsLogManager.java b/src/com/android/launcher3/logging/StatsLogManager.java
index b8ecec1..9af72c3 100644
--- a/src/com/android/launcher3/logging/StatsLogManager.java
+++ b/src/com/android/launcher3/logging/StatsLogManager.java
@@ -579,7 +579,14 @@
LAUNCHER_TASKBAR_OVERVIEW_BUTTON_LONGPRESS(1010),
@UiEvent(doc = "User tapped taskbar a11y button")
- LAUNCHER_TASKBAR_A11Y_BUTTON_LONGPRESS(1011);
+ LAUNCHER_TASKBAR_A11Y_BUTTON_LONGPRESS(1011),
+
+ @UiEvent(doc = "Show an 'Undo' snackbar when users dismiss a predicted hotseat item")
+ LAUNCHER_DISMISS_PREDICTION_UNDO(1035),
+
+ @UiEvent(doc = "User clicked on IME quicksearch button.")
+ LAUNCHER_ALLAPPS_QUICK_SEARCH_WITH_IME(1047),
+ ;
// ADD MORE
diff --git a/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java b/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java
index 967f2c8..9201006 100644
--- a/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java
+++ b/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java
@@ -113,13 +113,17 @@
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
if (child == mAppsView) {
- int padding = 2 * (grid.desiredWorkspaceHorizontalMarginPx
- + grid.cellLayoutPaddingLeftRightPx);
+ int horizontalPadding = (2 * grid.desiredWorkspaceHorizontalMarginPx)
+ + grid.cellLayoutPaddingPx.left + grid.cellLayoutPaddingPx.right;
+ int verticalPadding =
+ grid.cellLayoutPaddingPx.top + grid.cellLayoutPaddingPx.bottom;
- int maxWidth = grid.allAppsCellWidthPx * grid.numShownAllAppsColumns + padding;
+ int maxWidth =
+ grid.allAppsCellWidthPx * grid.numShownAllAppsColumns + horizontalPadding;
int appsWidth = Math.min(width, maxWidth);
- int maxHeight = grid.allAppsCellHeightPx * grid.numShownAllAppsColumns + padding;
+ int maxHeight =
+ grid.allAppsCellHeightPx * grid.numShownAllAppsColumns + verticalPadding;
int appsHeight = Math.min(height, maxHeight);
mAppsView.measure(
diff --git a/src/com/android/launcher3/states/SpringLoadedState.java b/src/com/android/launcher3/states/SpringLoadedState.java
index d52594e..9be3cc5 100644
--- a/src/com/android/launcher3/states/SpringLoadedState.java
+++ b/src/com/android/launcher3/states/SpringLoadedState.java
@@ -18,7 +18,6 @@
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_HOME;
import android.content.Context;
-import android.graphics.Rect;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
@@ -52,28 +51,15 @@
return super.getWorkspaceScaleAndTranslation(launcher);
}
- if (grid.isVerticalBarLayout()) {
- float scale = grid.workspaceSpringLoadShrinkFactor;
- return new ScaleAndTranslation(scale, 0, 0);
- }
-
- float scale = grid.workspaceSpringLoadShrinkFactor;
- Rect insets = launcher.getDragLayer().getInsets();
-
- float scaledHeight = scale * ws.getNormalChildHeight();
- float shrunkTop = insets.top + grid.dropTargetBarSizePx;
- float shrunkBottom = ws.getMeasuredHeight() - insets.bottom
- - grid.workspacePadding.bottom
- - grid.workspaceSpringLoadedBottomSpace;
- float totalShrunkSpace = shrunkBottom - shrunkTop;
-
- float desiredCellTop = shrunkTop + (totalShrunkSpace - scaledHeight) / 2;
+ float shrunkTop = grid.getWorkspaceSpringLoadShrunkTop();
+ float shrunkBottom = grid.getWorkspaceSpringLoadShrunkBottom();
+ float scale = (shrunkBottom - shrunkTop) / ws.getNormalChildHeight();
float halfHeight = ws.getHeight() / 2;
float myCenter = ws.getTop() + halfHeight;
float cellTopFromCenter = halfHeight - ws.getChildAt(0).getTop();
float actualCellTop = myCenter - cellTopFromCenter * scale;
- return new ScaleAndTranslation(scale, 0, (desiredCellTop - actualCellTop) / scale);
+ return new ScaleAndTranslation(scale, 0, (shrunkTop - actualCellTop) / scale);
}
@Override
diff --git a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
index c00e174..a125fbe 100644
--- a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
+++ b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
@@ -16,6 +16,7 @@
package com.android.launcher3.touch;
import static com.android.launcher3.LauncherAnimUtils.SUCCESS_TRANSITION_PROGRESS;
+import static com.android.launcher3.LauncherAnimUtils.TABLET_BOTTOM_SHEET_SUCCESS_TRANSITION_PROGRESS;
import static com.android.launcher3.LauncherAnimUtils.newCancelListener;
import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.NORMAL;
@@ -285,8 +286,13 @@
? mToState : mFromState;
// snap to top or bottom using the release velocity
} else {
+ float successTransitionProgress =
+ mLauncher.getDeviceProfile().isTablet
+ && (mToState == ALL_APPS || mFromState == ALL_APPS)
+ ? TABLET_BOTTOM_SHEET_SUCCESS_TRANSITION_PROGRESS
+ : SUCCESS_TRANSITION_PROGRESS;
targetState =
- (interpolatedProgress > SUCCESS_TRANSITION_PROGRESS) ? mToState : mFromState;
+ (interpolatedProgress > successTransitionProgress) ? mToState : mFromState;
}
final float endProgress;
diff --git a/src/com/android/launcher3/touch/AllAppsSwipeController.java b/src/com/android/launcher3/touch/AllAppsSwipeController.java
index f7d3492..5aac3f3 100644
--- a/src/com/android/launcher3/touch/AllAppsSwipeController.java
+++ b/src/com/android/launcher3/touch/AllAppsSwipeController.java
@@ -20,10 +20,8 @@
import static com.android.launcher3.anim.Interpolators.FINAL_FRAME;
import static com.android.launcher3.anim.Interpolators.INSTANT;
import static com.android.launcher3.anim.Interpolators.LINEAR;
-import static com.android.launcher3.anim.Interpolators.LINEAR_TELEPORT;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_FADE;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_SCRIM_FADE;
-import static com.android.launcher3.states.StateAnimationConfig.ANIM_VERTICAL_PROGRESS;
import android.view.MotionEvent;
import android.view.animation.Interpolator;
@@ -113,7 +111,6 @@
config.setInterpolator(ANIM_SCRIM_FADE, ALLAPPS_STAGGERED_FADE_LATE_RESPONDER);
config.setInterpolator(ANIM_ALL_APPS_FADE, isTablet
? FINAL_FRAME : ALLAPPS_STAGGERED_FADE_EARLY_RESPONDER);
- config.setInterpolator(ANIM_VERTICAL_PROGRESS, isTablet ? LINEAR_TELEPORT : LINEAR);
}
/**
@@ -125,7 +122,6 @@
config.setInterpolator(ANIM_SCRIM_FADE, ALLAPPS_STAGGERED_FADE_EARLY_RESPONDER);
config.setInterpolator(ANIM_ALL_APPS_FADE, isTablet
? INSTANT : ALLAPPS_STAGGERED_FADE_LATE_RESPONDER);
- config.setInterpolator(ANIM_VERTICAL_PROGRESS, isTablet ? LINEAR_TELEPORT : LINEAR);
}
diff --git a/src/com/android/launcher3/views/AbstractSlideInView.java b/src/com/android/launcher3/views/AbstractSlideInView.java
index 5d88884..ed31e8d 100644
--- a/src/com/android/launcher3/views/AbstractSlideInView.java
+++ b/src/com/android/launcher3/views/AbstractSlideInView.java
@@ -17,6 +17,8 @@
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+import static com.android.launcher3.LauncherAnimUtils.SUCCESS_TRANSITION_PROGRESS;
+import static com.android.launcher3.LauncherAnimUtils.TABLET_BOTTOM_SHEET_SUCCESS_TRANSITION_PROGRESS;
import static com.android.launcher3.anim.Interpolators.scrollInterpolatorForVelocity;
import android.animation.Animator;
@@ -184,7 +186,10 @@
@Override
public void onDragEnd(float velocity) {
- if ((mSwipeDetector.isFling(velocity) && velocity > 0) || mTranslationShift > 0.5f) {
+ float successfulShiftThreshold = mActivityContext.getDeviceProfile().isTablet
+ ? TABLET_BOTTOM_SHEET_SUCCESS_TRANSITION_PROGRESS : SUCCESS_TRANSITION_PROGRESS;
+ if ((mSwipeDetector.isFling(velocity) && velocity > 0)
+ || mTranslationShift > successfulShiftThreshold) {
mScrollInterpolator = scrollInterpolatorForVelocity(velocity);
mOpenCloseAnimator.setDuration(BaseSwipeDetector.calculateDuration(
velocity, TRANSLATION_SHIFT_CLOSED - mTranslationShift));
diff --git a/src/com/android/launcher3/views/FloatingSurfaceView.java b/src/com/android/launcher3/views/FloatingSurfaceView.java
index 19c28b4..bfb75f0 100644
--- a/src/com/android/launcher3/views/FloatingSurfaceView.java
+++ b/src/com/android/launcher3/views/FloatingSurfaceView.java
@@ -62,7 +62,6 @@
private final SurfaceView mSurfaceView;
-
private View mIcon;
private GestureNavContract mContract;
@@ -103,7 +102,13 @@
private void removeViewFromParent() {
mPicture.beginRecording(1, 1);
mPicture.endRecording();
- mLauncher.getDragLayer().removeView(this);
+ mLauncher.getDragLayer().removeViewInLayout(this);
+ }
+
+ private void removeViewImmediate() {
+ // Cancel any pending remove
+ Executors.MAIN_EXECUTOR.getHandler().removeCallbacks(mRemoveViewRunnable);
+ removeViewFromParent();
}
/**
@@ -115,9 +120,7 @@
view.mContract = contract;
view.mIsOpen = true;
- // Cancel any pending remove
- Executors.MAIN_EXECUTOR.getHandler().removeCallbacks(view.mRemoveViewRunnable);
- view.removeViewFromParent();
+ view.removeViewImmediate();
launcher.getDragLayer().addView(view);
}
@@ -129,6 +132,7 @@
@Override
public boolean onControllerInterceptTouchEvent(MotionEvent ev) {
close(false);
+ removeViewImmediate();
return false;
}
@@ -197,7 +201,7 @@
private void sendIconInfo() {
if (mContract != null && !mIconPosition.isEmpty()) {
- mContract.sendEndPosition(mIconPosition, mSurfaceView.getSurfaceControl());
+ mContract.sendEndPosition(mIconPosition, mLauncher, mSurfaceView.getSurfaceControl());
}
}