Merge "Measure WidgetsBottomPicker again when the number of spans changes" into sc-dev
diff --git a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
index e6333d1..4503e30 100644
--- a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
+++ b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
@@ -25,6 +25,7 @@
import android.animation.ObjectAnimator;
import android.os.IBinder;
import android.util.FloatProperty;
+import android.view.CrossWindowBlurListeners;
import android.view.SurfaceControl;
import android.view.View;
import android.view.ViewRootImpl;
@@ -41,6 +42,8 @@
import com.android.systemui.shared.system.BlurUtils;
import com.android.systemui.shared.system.WallpaperManagerCompat;
+import java.util.function.Consumer;
+
/**
* Controls blur and wallpaper zoom, for the Launcher surface only.
*/
@@ -96,11 +99,17 @@
}
};
+ private final Consumer<Boolean> mCrossWindowBlurListener = (enabled) -> {
+ mCrossWindowBlursEnabled = enabled;
+ dispatchTransactionSurface();
+ };
+
private final Launcher mLauncher;
/**
* Blur radius when completely zoomed out, in pixels.
*/
private int mMaxBlurRadius;
+ private boolean mCrossWindowBlursEnabled;
private WallpaperManagerCompat mWallpaperManager;
private SurfaceControl mSurface;
/**
@@ -123,6 +132,7 @@
mMaxBlurRadius = mLauncher.getResources().getInteger(R.integer.max_depth_blur_radius);
mWallpaperManager = new WallpaperManagerCompat(mLauncher);
}
+
if (mLauncher.getRootView() != null && mOnAttachListener == null) {
mOnAttachListener = new View.OnAttachStateChangeListener() {
@Override
@@ -132,13 +142,20 @@
if (windowToken != null) {
mWallpaperManager.setWallpaperZoomOut(windowToken, mDepth);
}
+ CrossWindowBlurListeners.getInstance().addListener(mLauncher.getMainExecutor(),
+ mCrossWindowBlurListener);
}
@Override
public void onViewDetachedFromWindow(View view) {
+ CrossWindowBlurListeners.getInstance().removeListener(mCrossWindowBlurListener);
}
};
mLauncher.getRootView().addOnAttachStateChangeListener(mOnAttachListener);
+ if (mLauncher.getRootView().isAttachedToWindow()) {
+ CrossWindowBlurListeners.getInstance().addListener(mLauncher.getMainExecutor(),
+ mCrossWindowBlurListener);
+ }
}
}
@@ -220,7 +237,8 @@
boolean isOverview = mLauncher.isInState(LauncherState.OVERVIEW);
boolean opaque = mLauncher.getScrimView().isFullyOpaque() && !isOverview;
- int blur = opaque || isOverview ? 0 : (int) (mDepth * mMaxBlurRadius);
+ int blur = opaque || isOverview || !mCrossWindowBlursEnabled
+ ? 0 : (int) (mDepth * mMaxBlurRadius);
new SurfaceControl.Transaction()
.setBackgroundBlurRadius(mSurface, blur)
.setOpaque(mSurface, opaque)
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index 4d47ef1..d511e6d 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -230,6 +230,7 @@
// Used to control launcher components throughout the swipe gesture.
private AnimatorControllerWithResistance mLauncherTransitionController;
+ private boolean mHasEndedLauncherTransition;
private AnimationFactory mAnimationFactory = (t) -> { };
@@ -603,11 +604,11 @@
/**
* We don't want to change mLauncherTransitionController if mGestureState.getEndTarget() == HOME
- * (it has its own animation).
+ * (it has its own animation) or if we explicitly ended the controller already.
* @return Whether we can create the launcher controller or update its progress.
*/
private boolean canCreateNewOrUpdateExistingLauncherTransitionController() {
- return mGestureState.getEndTarget() != HOME;
+ return mGestureState.getEndTarget() != HOME && !mHasEndedLauncherTransition;
}
@Override
@@ -1421,6 +1422,8 @@
}
private void endLauncherTransitionController() {
+ mHasEndedLauncherTransition = true;
+
if (mLauncherTransitionController != null) {
// End the animation, but stay at the same visual progress.
mLauncherTransitionController.getNormalController().dispatchSetInterpolator(
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index c9b68df..84f7e83 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -64,6 +64,7 @@
import android.view.accessibility.AccessibilityManager;
import androidx.annotation.BinderThread;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
import androidx.annotation.WorkerThread;
@@ -303,10 +304,10 @@
private RecentsAnimationDeviceState mDeviceState;
private TaskAnimationManager mTaskAnimationManager;
- private InputConsumer mUncheckedConsumer = InputConsumer.NO_OP;
- private InputConsumer mConsumer = InputConsumer.NO_OP;
+ private @NonNull InputConsumer mUncheckedConsumer = InputConsumer.NO_OP;
+ private @NonNull InputConsumer mConsumer = InputConsumer.NO_OP;
private Choreographer mMainChoreographer;
- private InputConsumer mResetGestureInputConsumer;
+ private @Nullable ResetGestureInputConsumer mResetGestureInputConsumer;
private GestureState mGestureState = DEFAULT_STATE;
private InputMonitorCompat mInputMonitorCompat;
@@ -635,7 +636,7 @@
// launched while device is locked even after exiting direct boot mode (e.g. camera).
return createDeviceLockedInputConsumer(newGestureState);
} else {
- return mResetGestureInputConsumer;
+ return getDefaultInputConsumer();
}
}
@@ -644,7 +645,7 @@
InputConsumer base = canStartSystemGesture
|| previousGestureState.isRecentsAnimationRunning()
? newBaseConsumer(previousGestureState, newGestureState, event)
- : mResetGestureInputConsumer;
+ : getDefaultInputConsumer();
if (mDeviceState.isGesturalNavMode()) {
handleOrientationSetup(base);
}
@@ -698,7 +699,7 @@
}
} else {
if (mDeviceState.isScreenPinningActive()) {
- base = mResetGestureInputConsumer;
+ base = getDefaultInputConsumer();
}
if (mDeviceState.canTriggerOneHandedAction(event)) {
@@ -740,14 +741,14 @@
return createOverviewInputConsumer(
previousGestureState, gestureState, event, forceOverviewInputConsumer);
} else if (gestureState.getRunningTask() == null) {
- return mResetGestureInputConsumer;
+ return getDefaultInputConsumer();
} else if (previousGestureState.isRunningAnimationToLauncher()
|| gestureState.getActivityInterface().isResumed()
|| forceOverviewInputConsumer) {
return createOverviewInputConsumer(
previousGestureState, gestureState, event, forceOverviewInputConsumer);
} else if (mDeviceState.isGestureBlockedActivity(gestureState.getRunningTask())) {
- return mResetGestureInputConsumer;
+ return getDefaultInputConsumer();
} else {
return createOtherActivityInputConsumer(gestureState, event);
}
@@ -775,7 +776,7 @@
return new DeviceLockedInputConsumer(this, mDeviceState, mTaskAnimationManager,
gestureState, mInputMonitorCompat);
} else {
- return mResetGestureInputConsumer;
+ return getDefaultInputConsumer();
}
}
@@ -784,7 +785,7 @@
boolean forceOverviewInputConsumer) {
StatefulActivity activity = gestureState.getActivityInterface().getCreatedActivity();
if (activity == null) {
- return mResetGestureInputConsumer;
+ return getDefaultInputConsumer();
}
if (activity.getRootView().hasWindowFocus()
@@ -813,13 +814,7 @@
}
private void reset() {
- if (mResetGestureInputConsumer != null) {
- mConsumer = mUncheckedConsumer = mResetGestureInputConsumer;
- } else {
- // mResetGestureInputConsumer isn't initialized until onUserUnlocked(), so reset to
- // NO_OP until then (we never want these to be null).
- mConsumer = mUncheckedConsumer = InputConsumer.NO_OP;
- }
+ mConsumer = mUncheckedConsumer = getDefaultInputConsumer();
mGestureState = DEFAULT_STATE;
// By default, use batching of the input events, but check receiver before using in the rare
// case that the monitor was disposed before the swipe settled
@@ -828,6 +823,19 @@
}
}
+ /**
+ * Returns the {@link ResetGestureInputConsumer} if user is unlocked, else NO_OP.
+ */
+ private @NonNull InputConsumer getDefaultInputConsumer() {
+ if (mResetGestureInputConsumer != null) {
+ return mResetGestureInputConsumer;
+ } else {
+ // mResetGestureInputConsumer isn't initialized until onUserUnlocked(), so reset to
+ // NO_OP until then (we never want these to be null).
+ return InputConsumer.NO_OP;
+ }
+ }
+
private void preloadOverview(boolean fromInit) {
if (!mDeviceState.isUserUnlocked()) {
return;
diff --git a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
index 719cb0a..b1c9ed0 100644
--- a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
+++ b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java
@@ -151,6 +151,7 @@
private Optional<ToState> mToState = Optional.empty();
private Optional<String> mEditText = Optional.empty();
private SliceItem mSliceItem;
+ private LauncherAtom.Slice mSlice;
StatsCompatLogger(Context context) {
mContext = context;
@@ -193,7 +194,7 @@
@Override
public StatsLogger withContainerInfo(ContainerInfo containerInfo) {
checkState(mItemInfo == DEFAULT_ITEM_INFO,
- "ItemInfo and ContainerInfo are mutual exclusive; cannot log both.");
+ "ItemInfo and ContainerInfo are mutual exclusive; cannot log both.");
this.mContainerInfo = Optional.of(containerInfo);
return this;
}
@@ -218,9 +219,21 @@
@Override
public StatsLogger withSliceItem(@NonNull SliceItem sliceItem) {
+ checkState(mItemInfo == DEFAULT_ITEM_INFO && mSlice == null,
+ "ItemInfo, Slice and SliceItem are mutual exclusive; cannot set more than one"
+ + " of them.");
this.mSliceItem = checkNotNull(sliceItem, "expected valid sliceItem but received null");
- checkState(mItemInfo == DEFAULT_ITEM_INFO,
- "ItemInfo and SliceItem are mutual exclusive; cannot log both.");
+ return this;
+ }
+
+ @Override
+ public StatsLogger withSlice(LauncherAtom.Slice slice) {
+ checkState(mItemInfo == DEFAULT_ITEM_INFO && mSliceItem == null,
+ "ItemInfo, Slice and SliceItem are mutual exclusive; cannot set more than one"
+ + " of them.");
+ checkNotNull(slice, "expected valid slice but received null");
+ checkNotNull(slice.getUri(), "expected valid slice uri but received null");
+ this.mSlice = slice;
return this;
}
@@ -231,13 +244,16 @@
}
LauncherAppState appState = LauncherAppState.getInstanceNoCreate();
- if (mSliceItem != null) {
+ if (mSlice == null && mSliceItem != null) {
+ mSlice = LauncherAtom.Slice.newBuilder().setUri(
+ mSliceItem.getSlice().getUri().toString()).build();
+ }
+
+ if (mSlice != null) {
Executors.MODEL_EXECUTOR.execute(
() -> {
LauncherAtom.ItemInfo.Builder itemInfoBuilder =
- LauncherAtom.ItemInfo.newBuilder().setSlice(
- LauncherAtom.Slice.newBuilder().setUri(
- mSliceItem.getSlice().getUri().toString()));
+ LauncherAtom.ItemInfo.newBuilder().setSlice(mSlice);
mContainerInfo.ifPresent(itemInfoBuilder::setContainerInfo);
write(event, applyOverwrites(itemInfoBuilder.build()));
});
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 97e09dd..8b7af04 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -1251,7 +1251,9 @@
private void updateOrientationHandler() {
// Handle orientation changes.
+ PagedOrientationHandler oldOrientationHandler = mOrientationHandler;
mOrientationHandler = mOrientationState.getOrientationHandler();
+
mIsRtl = mOrientationHandler.getRecentsRtlSetting(getResources());
setLayoutDirection(mIsRtl
? View.LAYOUT_DIRECTION_RTL
@@ -1260,7 +1262,12 @@
? View.LAYOUT_DIRECTION_LTR
: View.LAYOUT_DIRECTION_RTL);
mClearAllButton.setRotation(mOrientationHandler.getDegreesRotated());
- mActivity.getDragLayer().recreateControllers();
+
+ if (!mOrientationHandler.equals(oldOrientationHandler)) {
+ // Changed orientations, update controllers so they intercept accordingly.
+ mActivity.getDragLayer().recreateControllers();
+ }
+
boolean isInLandscape = mOrientationState.getTouchRotation() != ROTATION_0
|| mOrientationState.getRecentsActivityRotation() != ROTATION_0;
mActionsView.updateHiddenFlags(HIDDEN_NON_ZERO_ROTATION,
@@ -2372,13 +2379,12 @@
if (success) {
if (shouldRemoveTask) {
if (taskView.getTask() != null) {
- finishRecentsAnimation(true /* toRecents */, false /* shouldPip */,
- () -> {
- UI_HELPER_EXECUTOR.getHandler().postDelayed(() ->
- ActivityManagerWrapper.getInstance().removeTask(
- taskView.getTask().key.id),
- REMOVE_TASK_WAIT_FOR_APP_STOP_MS);
- });
+ if (LIVE_TILE.get() && taskView.isRunningTask()) {
+ finishRecentsAnimation(true /* toRecents */, false /* shouldPip */,
+ () -> removeTaskInternal(taskView));
+ } else {
+ removeTaskInternal(taskView);
+ }
mActivity.getStatsLogManager().logger()
.withItemInfo(taskView.getItemInfo())
.log(LAUNCHER_TASK_DISMISS_SWIPE_UP);
@@ -2424,6 +2430,13 @@
return anim;
}
+ private void removeTaskInternal(TaskView taskView) {
+ UI_HELPER_EXECUTOR.getHandler().postDelayed(() ->
+ ActivityManagerWrapper.getInstance().removeTask(
+ taskView.getTask().key.id),
+ REMOVE_TASK_WAIT_FOR_APP_STOP_MS);
+ }
+
/**
* @return {@code true} if one of the task thumbnails would intersect/overlap with the
* {@link #mSplitPlaceholderView}
diff --git a/res/color-night-v31/folder_background_dark.xml b/res/color-night-v31/folder_background_dark.xml
new file mode 100644
index 0000000..a5bd636
--- /dev/null
+++ b/res/color-night-v31/folder_background_dark.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android" >
+ <item
+ android:color="@android:color/system_neutral2_50"
+ android:lStar="30" />
+</selector>
diff --git a/res/color-night-v31/popup_color_first.xml b/res/color-night-v31/popup_color_first.xml
new file mode 100644
index 0000000..ba74128
--- /dev/null
+++ b/res/color-night-v31/popup_color_first.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android" >
+ <item
+ android:color="?attr/popupColorPrimary"
+ android:lStar="20" />
+</selector>
diff --git a/res/color-night-v31/popup_color_second.xml b/res/color-night-v31/popup_color_second.xml
new file mode 100644
index 0000000..efc6205
--- /dev/null
+++ b/res/color-night-v31/popup_color_second.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android" >
+ <item
+ android:color="?attr/popupColorPrimary"
+ android:lStar="15" />
+</selector>
diff --git a/res/color-night-v31/popup_color_third.xml b/res/color-night-v31/popup_color_third.xml
new file mode 100644
index 0000000..591c7ed
--- /dev/null
+++ b/res/color-night-v31/popup_color_third.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android" >
+ <item
+ android:color="?attr/popupColorPrimary"
+ android:lStar="10" />
+</selector>
diff --git a/res/color-v31/folder_background_light.xml b/res/color-v31/folder_background_light.xml
new file mode 100644
index 0000000..e3c7e7d
--- /dev/null
+++ b/res/color-v31/folder_background_light.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android" >
+ <item
+ android:color="@android:color/system_neutral1_50"
+ android:lStar="98" />
+</selector>
diff --git a/res/color-v31/popup_color_first.xml b/res/color-v31/popup_color_first.xml
new file mode 100644
index 0000000..28d9155
--- /dev/null
+++ b/res/color-v31/popup_color_first.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android" >
+ <item
+ android:color="?attr/popupColorPrimary"
+ android:lStar="98" />
+</selector>
diff --git a/res/color-v31/popup_color_second.xml b/res/color-v31/popup_color_second.xml
new file mode 100644
index 0000000..dec562c
--- /dev/null
+++ b/res/color-v31/popup_color_second.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android" >
+ <item
+ android:color="?attr/popupColorPrimary"
+ android:lStar="95" />
+</selector>
diff --git a/res/color-v31/popup_color_third.xml b/res/color-v31/popup_color_third.xml
new file mode 100644
index 0000000..582232c
--- /dev/null
+++ b/res/color-v31/popup_color_third.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android" >
+ <item
+ android:color="?attr/popupColorPrimary"
+ android:lStar="90" />
+</selector>
diff --git a/res/color/popup_color_first.xml b/res/color/popup_color_first.xml
new file mode 100644
index 0000000..d9999a2
--- /dev/null
+++ b/res/color/popup_color_first.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android" >
+ <item android:color="?attr/popupColorPrimary" />
+</selector>
diff --git a/res/color/popup_color_second.xml b/res/color/popup_color_second.xml
new file mode 100644
index 0000000..d9999a2
--- /dev/null
+++ b/res/color/popup_color_second.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android" >
+ <item android:color="?attr/popupColorPrimary" />
+</selector>
diff --git a/res/color/popup_color_third.xml b/res/color/popup_color_third.xml
new file mode 100644
index 0000000..d7e9e79
--- /dev/null
+++ b/res/color/popup_color_third.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android" >
+ <item android:color="?attr/popupColorPrimary" />
+</selector>
\ No newline at end of file
diff --git a/res/drawable/work_apps_toggle_background.xml b/res/drawable/work_apps_toggle_background.xml
index b7115f8..a47c8fe 100644
--- a/res/drawable/work_apps_toggle_background.xml
+++ b/res/drawable/work_apps_toggle_background.xml
@@ -18,14 +18,18 @@
<shape android:shape="rectangle">
<corners android:radius="@dimen/work_fab_radius" />
<solid android:color="?android:attr/colorControlHighlight" />
- <padding android:left="@dimen/work_fab_radius" android:right="@dimen/work_fab_radius" />
+ <padding
+ android:left="@dimen/work_profile_footer_padding"
+ android:right="@dimen/work_profile_footer_padding" />
</shape>
</item>
<item>
<shape android:shape="rectangle">
<corners android:radius="@dimen/work_fab_radius" />
<solid android:color="@color/all_apps_tab_background_selected" />
- <padding android:left="@dimen/work_fab_radius" android:right="@dimen/work_fab_radius" />
+ <padding
+ android:left="@dimen/work_profile_footer_padding"
+ android:right="@dimen/work_profile_footer_padding" />
</shape>
</item>
</selector>
diff --git a/res/layout/work_apps_edu.xml b/res/layout/work_apps_edu.xml
index 97feb23..919f1b2 100644
--- a/res/layout/work_apps_edu.xml
+++ b/res/layout/work_apps_edu.xml
@@ -42,7 +42,7 @@
<Button
android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_height="@dimen/rounded_button_height"
android:id="@+id/action_btn"
android:textColor="?attr/workProfileOverlayTextColor"
android:text="@string/work_profile_edu_accept"
diff --git a/res/layout/work_apps_paused.xml b/res/layout/work_apps_paused.xml
index 3819256..02a50ca 100644
--- a/res/layout/work_apps_paused.xml
+++ b/res/layout/work_apps_paused.xml
@@ -17,7 +17,7 @@
android:layout_height="wrap_content"
android:padding="@dimen/work_edu_card_margin"
android:orientation="vertical"
- android:gravity="center">
+ android:gravity="center_horizontal">
<TextView
style="@style/PrimaryHeadline"
@@ -25,8 +25,7 @@
android:id="@+id/work_apps_paused_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginTop="8dp"
- android:layout_marginBottom="8dp"
+ android:layout_marginTop="40dp"
android:text="@string/work_apps_paused_title"
android:textAlignment="center"
android:textSize="20sp" />
@@ -38,12 +37,13 @@
android:textColor="?attr/workProfileOverlayTextColor"
android:text="@string/work_apps_paused_body"
android:textAlignment="center"
- android:layout_marginBottom="8dp"
+ android:layout_marginTop="16dp"
+ android:layout_marginBottom="24dp"
android:textSize="16sp" />
<Button
android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_height="@dimen/rounded_button_height"
android:id="@+id/enable_work_apps"
android:textColor="?attr/workProfileOverlayTextColor"
android:text="@string/work_apps_enable_btn_text"
diff --git a/res/layout/work_mode_fab.xml b/res/layout/work_mode_fab.xml
index 1771d37..7183817 100644
--- a/res/layout/work_mode_fab.xml
+++ b/res/layout/work_mode_fab.xml
@@ -13,6 +13,7 @@
limitations under the License.
-->
<com.android.launcher3.allapps.WorkModeSwitch xmlns:android="http://schemas.android.com/apk/res/android"
+ style="@style/TextHeadline"
android:id="@+id/work_mode_toggle"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
@@ -22,6 +23,7 @@
android:includeFontPadding="false"
android:drawableTint="@color/all_apps_tab_text"
android:textColor="@color/all_apps_tab_text"
+ android:textSize="14sp"
android:background="@drawable/work_apps_toggle_background"
android:drawablePadding="16dp"
android:drawableStart="@drawable/ic_corp_off"
diff --git a/res/values-v29/styles.xml b/res/values-v29/styles.xml
index 8254d48..5370b79 100644
--- a/res/values-v29/styles.xml
+++ b/res/values-v29/styles.xml
@@ -26,8 +26,6 @@
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowShowWallpaper">true</item>
- <item name="folderTextColor">?attr/workspaceTextColor</item>
- <item name="isFolderDarkText">?attr/isWorkspaceDarkText</item>
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
<item name="android:enforceStatusBarContrast">false</item>
<item name="android:enforceNavigationBarContrast">false</item>
diff --git a/res/values-v30/styles.xml b/res/values-v30/styles.xml
index a144363..ec5c113 100644
--- a/res/values-v30/styles.xml
+++ b/res/values-v30/styles.xml
@@ -26,8 +26,6 @@
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowShowWallpaper">true</item>
- <item name="folderTextColor">?attr/workspaceTextColor</item>
- <item name="isFolderDarkText">?attr/isWorkspaceDarkText</item>
<item name="android:windowLayoutInDisplayCutoutMode">always</item>
<item name="android:enforceStatusBarContrast">false</item>
<item name="android:enforceNavigationBarContrast">false</item>
diff --git a/res/values-v31/colors.xml b/res/values-v31/colors.xml
index 1785623..71eaa9e 100644
--- a/res/values-v31/colors.xml
+++ b/res/values-v31/colors.xml
@@ -39,8 +39,6 @@
<color name="text_color_tertiary_dark">@android:color/system_neutral2_400</color>
<color name="wallpaper_popup_scrim">@android:color/system_neutral1_900</color>
- <color name="folder_background_light" android:lstar="98">@android:color/system_neutral1_50</color>
- <color name="folder_background_dark" android:lstar="30">@android:color/system_neutral2_800</color>
-
+
<color name="folder_dot_color">@android:color/system_accent2_50</color>
</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 3dbd760..4f4a389 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -140,8 +140,8 @@
<string name="long_accessible_way_to_add_shortcut">Double-tap & hold to move a shortcut or use custom actions.</string>
<skip />
- <!-- Error message when user has filled a home screen -->
- <string name="out_of_space">No more room on this Home screen.</string>
+ <!-- Error message when a user can't add more apps, widgets, or shortcuts to a Home screen. -->
+ <string name="out_of_space">No room on this Home screen</string>
<!-- Error message when user has filled the hotseat -->
<string name="hotseat_out_of_space">No more room in the Favorites tray</string>
@@ -394,7 +394,7 @@
<string name="work_profile_edu_accept">Got it</string>
<!--- heading shown when user opens work apps tab while work apps are paused -->
- <string name="work_apps_paused_title">Work apps are off</string>
+ <string name="work_apps_paused_title">Work apps are paused</string>
<!--- body shown when user opens work apps tab while work apps are paused -->
<string name="work_apps_paused_body">Your work apps can’t send you notifications, use your battery, or access your location</string>
<!-- content description for paused work apps list -->
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 1cacc28..871214f 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -26,8 +26,6 @@
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowShowWallpaper">true</item>
- <item name="folderTextColor">?attr/workspaceTextColor</item>
- <item name="isFolderDarkText">?attr/isWorkspaceDarkText</item>
</style>
<style name="LauncherTheme" parent="@style/BaseLauncherTheme">
@@ -72,10 +70,6 @@
</style>
<style name="LauncherTheme.DarkMainColor" parent="@style/LauncherTheme">
- <item name="folderFillColor">@color/folder_background_dark</item>
- <item name="folderTextColor">@color/workspace_text_color_light</item>
- <item name="isFolderDarkText">false</item>
- <item name="folderHintColor">@color/folder_hint_text_color_light</item>
<item name="disabledIconAlpha">.254</item>
</style>
@@ -87,12 +81,6 @@
<item name="workspaceKeyShadowColor">@android:color/transparent</item>
<item name="isWorkspaceDarkText">true</item>
<item name="workspaceStatusBarScrim">@null</item>
- <item name="folderDotColor">@color/folder_dot_color</item>
- <item name="folderFillColor">@color/folder_background_light</item>
- <item name="folderIconBorderColor">#FF80868B</item>
- <item name="folderTextColor">@color/workspace_text_color_dark</item>
- <item name="isFolderDarkText">true</item>
- <item name="folderHintColor">@color/folder_hint_text_color_dark</item>
</style>
<style name="LauncherTheme.Dark" parent="@style/LauncherTheme">
@@ -125,25 +113,17 @@
</style>
<style name="LauncherTheme.Dark.DarkMainColor" parent="@style/LauncherTheme.Dark">
- <item name="folderFillColor">@color/folder_background_dark</item>
- <item name="folderTextColor">@color/workspace_text_color_light</item>
- <item name="isFolderDarkText">false</item>
- <item name="folderHintColor">@color/folder_hint_text_color_light</item>
<item name="disabledIconAlpha">.54</item>
</style>
<style name="LauncherTheme.Dark.DarkText" parent="@style/LauncherTheme.Dark">
<item name="android:colorControlHighlight">#19212121</item>
- <item name="folderFillColor">@color/folder_background_light</item>
<item name="workspaceTextColor">@color/workspace_text_color_dark</item>
<item name="workspaceShadowColor">@android:color/transparent</item>
<item name="workspaceAmbientShadowColor">@android:color/transparent</item>
<item name="workspaceKeyShadowColor">@android:color/transparent</item>
<item name="isWorkspaceDarkText">true</item>
<item name="workspaceStatusBarScrim">@null</item>
- <item name="folderTextColor">@color/workspace_text_color_dark</item>
- <item name="isFolderDarkText">true</item>
- <item name="folderHintColor">@color/folder_hint_text_color_dark</item>
</style>
<!-- A derivative project can extend these themes to customize the application theme without
diff --git a/robolectric_tests/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfoTest.java b/robolectric_tests/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfoTest.java
index 2d87957..a6f892c 100644
--- a/robolectric_tests/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfoTest.java
+++ b/robolectric_tests/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfoTest.java
@@ -122,6 +122,8 @@
@Test
public void initSpans_minResizeWidthSmallerThanCellWidth_shouldInitializeMinSpansToOne() {
LauncherAppWidgetProviderInfo info = new LauncherAppWidgetProviderInfo();
+ info.minWidth = 100;
+ info.minHeight = 100;
info.minResizeWidth = 20;
info.minResizeHeight = 20;
InvariantDeviceProfile idp = createIDP();
@@ -135,6 +137,8 @@
@Test
public void initSpans_minResizeWidthLargerThanCellWidth_shouldInitializeMinSpans() {
LauncherAppWidgetProviderInfo info = new LauncherAppWidgetProviderInfo();
+ info.minWidth = 100;
+ info.minHeight = 100;
info.minResizeWidth = 80;
info.minResizeHeight = 80;
InvariantDeviceProfile idp = createIDP();
@@ -157,6 +161,8 @@
Mockito.when(dp.shouldInsetWidgets()).thenReturn(true);
LauncherAppWidgetProviderInfo info = new LauncherAppWidgetProviderInfo();
+ info.minWidth = CELL_SIZE * 3;
+ info.minHeight = CELL_SIZE * 3;
info.minResizeWidth = CELL_SIZE * 2 + maxPadding;
info.minResizeHeight = CELL_SIZE * 2 + maxPadding;
@@ -177,6 +183,8 @@
dp.cellLayoutBorderSpacingPx = maxPadding - 1;
Mockito.when(dp.shouldInsetWidgets()).thenReturn(false);
LauncherAppWidgetProviderInfo info = new LauncherAppWidgetProviderInfo();
+ info.minWidth = CELL_SIZE * 3;
+ info.minHeight = CELL_SIZE * 3;
info.minResizeWidth = CELL_SIZE * 2 + maxPadding;
info.minResizeHeight = CELL_SIZE * 2 + maxPadding;
@@ -187,6 +195,22 @@
}
@Test
+ public void
+ initSpans_minResizeWidthHeightLargerThanMinWidth_shouldUseMinWidthHeightAsMinSpans() {
+ LauncherAppWidgetProviderInfo info = new LauncherAppWidgetProviderInfo();
+ info.minWidth = 20;
+ info.minHeight = 20;
+ info.minResizeWidth = 80;
+ info.minResizeHeight = 80;
+ InvariantDeviceProfile idp = createIDP();
+
+ info.initSpans(mContext, idp);
+
+ assertThat(info.minSpanX).isEqualTo(1);
+ assertThat(info.minSpanY).isEqualTo(1);
+ }
+
+ @Test
public void isMinSizeFulfilled_minWidthAndHeightWithinGridSize_shouldReturnTrue() {
LauncherAppWidgetProviderInfo info = new LauncherAppWidgetProviderInfo();
info.minWidth = 80;
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index e9245b0..d301787 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -149,10 +149,11 @@
// Hotseat
public final int numShownHotseatIcons;
public int hotseatCellHeightPx;
+ private final int hotseatExtraVerticalSize;
// In portrait: size = height, in landscape: size = width
public int hotseatBarSizePx;
public final int hotseatBarTopPaddingPx;
- public int hotseatBarBottomPaddingPx;
+ public final int hotseatBarBottomPaddingPx;
// 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;
@@ -326,13 +327,9 @@
res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_side_padding);
// Add a bit of space between nav bar and hotseat in vertical bar layout.
hotseatBarSidePaddingStartPx = isVerticalBarLayout() ? workspacePageIndicatorHeight : 0;
- int hotseatExtraVerticalSize =
+ hotseatExtraVerticalSize =
res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_extra_vertical_size);
- hotseatBarSizePx = pxFromDp(inv.iconSize, mMetrics, 1f)
- + (isVerticalBarLayout()
- ? (hotseatBarSidePaddingStartPx + hotseatBarSidePaddingEndPx)
- : (hotseatBarTopPaddingPx + hotseatBarBottomPaddingPx
- + (isScalableGrid ? 0 : hotseatExtraVerticalSize)));
+ updateHotseatIconSize(pxFromDp(inv.iconSize, mMetrics, 1f));
overviewTaskMarginPx = res.getDimensionPixelSize(R.dimen.overview_task_margin);
overviewTaskIconSizePx =
@@ -362,7 +359,6 @@
extraHotseatBottomPadding = Math.round(paddingHotseatBottom * iconScale);
hotseatBarSizePx += extraHotseatBottomPadding;
- hotseatBarBottomPaddingPx += extraHotseatBottomPadding;
} else if (!isVerticalBarLayout() && isPhone && isTallDevice) {
// We increase the hotseat size when there is extra space.
// ie. For a display with a large aspect ratio, we can keep the icons on the workspace
@@ -371,7 +367,6 @@
int extraSpace = getCellSize().y - iconSizePx - iconDrawablePaddingPx * 2
- workspacePageIndicatorHeight;
hotseatBarSizePx += extraSpace;
- hotseatBarBottomPaddingPx += extraSpace;
// Recalculate the available dimensions using the new hotseat size.
updateAvailableDimensions(res);
@@ -388,6 +383,17 @@
new DotRenderer(allAppsIconSizePx, dotPath, DEFAULT_DOT_SIZE);
}
+ private void updateHotseatIconSize(int hotseatIconSizePx) {
+ hotseatCellHeightPx = hotseatIconSizePx;
+ if (isVerticalBarLayout()) {
+ hotseatBarSizePx = hotseatIconSizePx + hotseatBarSidePaddingStartPx
+ + hotseatBarSidePaddingEndPx;
+ } else {
+ hotseatBarSizePx = hotseatIconSizePx + hotseatBarTopPaddingPx
+ + hotseatBarBottomPaddingPx + (isScalableGrid ? 0 : hotseatExtraVerticalSize);
+ }
+ }
+
private void setCellLayoutBorderSpacing(int borderSpacing) {
cellLayoutBorderSpacingPx = isScalableGrid ? borderSpacing : 0;
}
@@ -573,11 +579,7 @@
}
// Hotseat
- if (isVerticalLayout) {
- hotseatBarSizePx = iconSizePx + hotseatBarSidePaddingStartPx
- + hotseatBarSidePaddingEndPx;
- }
- hotseatCellHeightPx = iconSizePx;
+ updateHotseatIconSize(iconSizePx);
if (!isVerticalLayout) {
int expectedWorkspaceHeight = availableHeightPx - hotseatBarSizePx
@@ -763,7 +765,8 @@
hotseatBarTopPaddingPx,
hotseatAdjustment + workspacePadding.right + cellLayoutPaddingLeftRightPx
+ mInsets.right,
- hotseatBarBottomPaddingPx + mInsets.bottom + cellLayoutBottomPaddingPx);
+ hotseatBarSizePx - hotseatCellHeightPx - hotseatBarTopPaddingPx
+ + cellLayoutBottomPaddingPx + mInsets.bottom);
}
return mHotseatPadding;
}
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index c5d280d..11ddafb 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -1079,7 +1079,7 @@
if (ALL_APPS.equals(mPrevLauncherState) && !ALL_APPS.equals(state)
// Making sure mAllAppsSessionLogId is not null to avoid double logging.
&& mAllAppsSessionLogId != null) {
- getAppsView().getSearchUiManager().resetSearch();
+ getAppsView().reset(false);
getStatsLogManager().logger()
.withContainerInfo(LauncherAtom.ContainerInfo.newBuilder()
.setWorkspace(
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 303bb01..f28f54a 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -2792,7 +2792,7 @@
}
} else if (mDragInfo != null) {
// When drag is cancelled, reattach content view back to its original parent.
- if (mDragInfo.cell instanceof LauncherAppWidgetHostView) {
+ if (mDragInfo.cell instanceof LauncherAppWidgetHostView && d.dragView != null) {
d.dragView.detachContentView(/* reattachToPreviousParent= */ true);
}
final CellLayout cellLayout = mLauncher.getCellLayout(
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index aabbe65..ab3ea0a 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -255,7 +255,6 @@
mWorkModeSwitch.updateCurrentState(isEnabled);
}
mWorkAdapterProvider.updateCurrentState(isEnabled);
- mAH[AdapterHolder.WORK].applyPadding();
}
private void hideInput() {
@@ -509,7 +508,10 @@
R.layout.work_mode_fab, this, false);
this.addView(mWorkModeSwitch);
mWorkModeSwitch.setInsets(mInsets);
- mWorkModeSwitch.post(this::resetWorkProfile);
+ mWorkModeSwitch.post(() -> {
+ mAH[AdapterHolder.WORK].applyPadding();
+ resetWorkProfile();
+ });
}
}
@@ -633,6 +635,7 @@
mSearchModeWhileUsingTabs = true;
rebindAdapters(false); // hide tabs
}
+ mHeader.setCollapsed(true);
}
public void onClearSearchResult() {
@@ -715,7 +718,7 @@
if (mHeaderPaint.getColor() != mScrimColor && mHeaderPaint.getColor() != 0) {
int bottom = mUsingTabs && mHeader.mHeaderCollapsed ? mHeader.getVisibleBottomBound()
: mSearchContainer.getBottom();
- canvas.drawRect(0, 0, getWidth(), bottom + getTranslationY(),
+ canvas.drawRect(0, 0, canvas.getWidth(), bottom + getTranslationY(),
mHeaderPaint);
if (FeatureFlags.ENABLE_DEVICE_SEARCH.get() && getTranslationY() == 0) {
@@ -787,7 +790,6 @@
int bottomOffset = mWorkModeSwitch != null && mIsWork ? switchH : 0;
recyclerView.setPadding(padding.left, padding.top, padding.right,
padding.bottom + bottomOffset);
- recyclerView.scrollToTop();
}
}
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index d65eb22..66f5c87 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -78,6 +78,9 @@
public static final BooleanFlag UNSTABLE_SPRINGS = getDebugFlag(
"UNSTABLE_SPRINGS", false, "Enable unstable springs for quickstep animations");
+ public static final BooleanFlag ENABLE_LOCAL_COLOR_POPUPS = getDebugFlag(
+ "ENABLE_LOCAL_COLOR_POPUPS", false, "Enable local color extraction for popups.");
+
public static final BooleanFlag KEYGUARD_ANIMATION = getDebugFlag(
"KEYGUARD_ANIMATION", false, "Enable animation for keyguard going away on wallpaper");
diff --git a/src/com/android/launcher3/logging/StatsLogManager.java b/src/com/android/launcher3/logging/StatsLogManager.java
index ddff338..79e5b5d 100644
--- a/src/com/android/launcher3/logging/StatsLogManager.java
+++ b/src/com/android/launcher3/logging/StatsLogManager.java
@@ -27,6 +27,7 @@
import androidx.slice.SliceItem;
import com.android.launcher3.R;
+import com.android.launcher3.logger.LauncherAtom;
import com.android.launcher3.logger.LauncherAtom.ContainerInfo;
import com.android.launcher3.logger.LauncherAtom.FromState;
import com.android.launcher3.logger.LauncherAtom.ToState;
@@ -600,6 +601,13 @@
}
/**
+ * Sets logging fields from provided {@link LauncherAtom.Slice}.
+ */
+ default StatsLogger withSlice(LauncherAtom.Slice slice) {
+ return this;
+ }
+
+ /**
* Builds the final message and logs it as {@link EventEnum}.
*/
default void log(EventEnum event) {
diff --git a/src/com/android/launcher3/popup/ArrowPopup.java b/src/com/android/launcher3/popup/ArrowPopup.java
index cb35f74..a89fb3b 100644
--- a/src/com/android/launcher3/popup/ArrowPopup.java
+++ b/src/com/android/launcher3/popup/ArrowPopup.java
@@ -16,9 +16,12 @@
package com.android.launcher3.popup;
+import static androidx.core.content.ContextCompat.getColorStateList;
+
import static com.android.launcher3.anim.Interpolators.ACCELERATED_EASE;
import static com.android.launcher3.anim.Interpolators.DECELERATED_EASE;
import static com.android.launcher3.anim.Interpolators.LINEAR;
+import static com.android.launcher3.config.FeatureFlags.ENABLE_LOCAL_COLOR_POPUPS;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -28,6 +31,7 @@
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.Resources;
+import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.ColorDrawable;
@@ -133,6 +137,8 @@
private final String mIterateChildrenTag;
+ private final int[] mColors;
+
public ArrowPopup(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mInflater = LayoutInflater.from(context);
@@ -171,9 +177,19 @@
boolean isAboveAnotherSurface = getTopOpenViewWithType(mLauncher, TYPE_FOLDER) != null
|| mLauncher.getStateManager().getState() == LauncherState.ALL_APPS;
- if (!isAboveAnotherSurface && Utilities.ATLEAST_S) {
+ if (!isAboveAnotherSurface && Utilities.ATLEAST_S && ENABLE_LOCAL_COLOR_POPUPS.get()) {
setupColorExtraction();
}
+
+ if (isAboveAnotherSurface) {
+ mColors = new int[] {
+ getColorStateList(context, R.color.popup_color_first).getDefaultColor()};
+ } else {
+ mColors = new int[] {
+ getColorStateList(context, R.color.popup_color_first).getDefaultColor(),
+ getColorStateList(context, R.color.popup_color_second).getDefaultColor(),
+ getColorStateList(context, R.color.popup_color_third).getDefaultColor()};
+ }
}
public ArrowPopup(Context context, AttributeSet attrs) {
@@ -220,6 +236,16 @@
* Set the margins and radius of backgrounds after views are properly ordered.
*/
public void assignMarginsAndBackgrounds(ViewGroup viewGroup) {
+ assignMarginsAndBackgrounds(viewGroup, Color.TRANSPARENT);
+ }
+
+ /**
+ * @param backgroundColor When Color.TRANSPARENT, we get color from {@link #mColors}.
+ * Otherwise, we will use this color for all child views.
+ */
+ private void assignMarginsAndBackgrounds(ViewGroup viewGroup, int backgroundColor) {
+ final boolean getColorFromColorArray = backgroundColor == Color.TRANSPARENT;
+
int count = viewGroup.getChildCount();
int totalVisibleShortcuts = 0;
for (int i = 0; i < count; i++) {
@@ -229,8 +255,10 @@
}
}
+ int numVisibleChild = 0;
int numVisibleShortcut = 0;
View lastView = null;
+ AnimatorSet colorAnimator = new AnimatorSet();
for (int i = 0; i < count; i++) {
View view = viewGroup.getChildAt(i);
if (view.getVisibility() == VISIBLE) {
@@ -242,8 +270,14 @@
MarginLayoutParams mlp = (MarginLayoutParams) lastView.getLayoutParams();
mlp.bottomMargin = 0;
+
+ if (getColorFromColorArray) {
+ backgroundColor = mColors[numVisibleChild % mColors.length];
+ }
+
if (view instanceof ViewGroup && mIterateChildrenTag.equals(view.getTag())) {
- assignMarginsAndBackgrounds((ViewGroup) view);
+ assignMarginsAndBackgrounds((ViewGroup) view, backgroundColor);
+ numVisibleChild++;
continue;
}
@@ -261,8 +295,22 @@
numVisibleShortcut++;
}
}
+
+ if (!ENABLE_LOCAL_COLOR_POPUPS.get()) {
+ setChildColor(view, backgroundColor, colorAnimator);
+ // Arrow color matches the first child or the last child.
+ if (!mIsAboveIcon && numVisibleChild == 0) {
+ mArrowColor = backgroundColor;
+ } else if (mIsAboveIcon) {
+ mArrowColor = backgroundColor;
+ }
+ }
+
+ numVisibleChild++;
}
}
+
+ colorAnimator.setDuration(0).start();
measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
}
diff --git a/src/com/android/launcher3/views/SpringRelativeLayout.java b/src/com/android/launcher3/views/SpringRelativeLayout.java
index 8f814a1..923eb19 100644
--- a/src/com/android/launcher3/views/SpringRelativeLayout.java
+++ b/src/com/android/launcher3/views/SpringRelativeLayout.java
@@ -105,9 +105,8 @@
@NonNull @Override
protected EdgeEffect createEdgeEffect(RecyclerView view, int direction) {
- switch (direction) {
- case DIRECTION_TOP:
- return new EdgeEffectProxy(getContext(), mEdgeGlowTop);
+ if (direction == DIRECTION_TOP) {
+ return new EdgeEffectProxy(getContext(), mEdgeGlowTop);
}
return super.createEdgeEffect(view, direction);
}
diff --git a/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java b/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java
index 5a29171..d77d99d 100644
--- a/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java
+++ b/src/com/android/launcher3/widget/LauncherAppWidgetProviderInfo.java
@@ -160,8 +160,11 @@
}
}
- this.minSpanX = minSpanX;
- this.minSpanY = minSpanY;
+ // If minSpanX/Y > spanX/Y, ignore the minSpanX/Y to match the behavior described in
+ // minResizeWidth & minResizeHeight Android documentation. See
+ // https://developer.android.com/reference/android/appwidget/AppWidgetProviderInfo
+ this.minSpanX = Math.min(spanX, minSpanX);
+ this.minSpanY = Math.min(spanY, minSpanY);
this.maxSpanX = maxSpanX;
this.maxSpanY = maxSpanY;
this.mIsMinSizeFulfilled = Math.min(spanX, minSpanX) <= idp.numColumns