Merge "Moving folder shape logic definition to xml Adding support for storing custom parameters in shape definition" into ub-launcher3-master
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 4ac51ab..1a485ed 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -20,7 +20,7 @@
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.launcher3">
- <uses-sdk android:targetSdkVersion="23" android:minSdkVersion="21"/>
+ <uses-sdk android:targetSdkVersion="28" android:minSdkVersion="21"/>
<!--
Manifest entries specific to Launcher3. This is merged with AndroidManifest-common.xml.
Refer comments around specific entries on how to extend individual components.
diff --git a/build.gradle b/build.gradle
index 33409c5..e40df06 100644
--- a/build.gradle
+++ b/build.gradle
@@ -36,28 +36,32 @@
targetCompatibility JavaVersion.VERSION_1_8
}
- flavorDimensions "default"
+ // The flavor dimensions for build variants (e.g. aospWithQuickstep, aospWithoutQuickstep)
+ // See: https://developer.android.com/studio/build/build-variants#flavor-dimensions
+ flavorDimensions "app", "recents"
productFlavors {
aosp {
- dimension "default"
+ dimension "app"
applicationId 'com.android.launcher3'
testApplicationId 'com.android.launcher3.tests'
}
l3go {
- dimension "default"
+ dimension "app"
applicationId 'com.android.launcher3'
testApplicationId 'com.android.launcher3.tests'
}
- quickstep {
- dimension "default"
- applicationId 'com.android.launcher3'
- testApplicationId 'com.android.launcher3.tests'
+ withQuickstep {
+ dimension "recents"
minSdkVersion 28
}
+
+ withoutQuickstep {
+ dimension "recents"
+ }
}
// Disable release builds for now
@@ -70,7 +74,7 @@
sourceSets {
main {
res.srcDirs = ['res']
- java.srcDirs = ['src', 'src_shortcuts_overrides']
+ java.srcDirs = ['src', 'src_plugins']
manifest.srcFile 'AndroidManifest-common.xml'
proto {
srcDir 'protos/'
@@ -93,18 +97,23 @@
}
aosp {
- java.srcDirs = ['src_flags', "src_ui_overrides"]
+ java.srcDirs = ['src_flags', 'src_shortcuts_overrides']
+ manifest.srcFile "AndroidManifest.xml"
}
l3go {
res.srcDirs = ['go/res']
- java.srcDirs = ['go/src', "src_ui_overrides"]
+ java.srcDirs = ['go/src']
manifest.srcFile "go/AndroidManifest.xml"
}
- quickstep {
+ withoutQuickstep {
+ java.srcDirs = ['src_ui_overrides']
+ }
+
+ withQuickstep {
res.srcDirs = ['quickstep/res']
- java.srcDirs = ['src_flags', 'quickstep/src']
+ java.srcDirs = ['quickstep/src']
manifest.srcFile "quickstep/AndroidManifest.xml"
}
}
@@ -121,14 +130,14 @@
implementation "androidx.dynamicanimation:dynamicanimation:${ANDROID_X_VERSION}"
implementation "androidx.recyclerview:recyclerview:${ANDROID_X_VERSION}"
implementation "androidx.preference:preference:${ANDROID_X_VERSION}"
- implementation PROTOBUF_DEPENDENCY
implementation project(':IconLoader')
+ implementation fileTree(dir: "libs", include: 'launcher_protos.jar')
- // This is already included in sysui_shared
- aospImplementation fileTree(dir: "libs", include: 'plugin_core.jar')
- l3goImplementation fileTree(dir: "libs", include: 'plugin_core.jar')
+ // Recents lib dependency
+ withQuickstepImplementation fileTree(dir: "quickstep/libs", include: 'sysui_shared.jar')
- quickstepImplementation fileTree(dir: "quickstep/libs", include: 'sysui_shared.jar')
+ // Required for AOSP to compile. This is already included in the sysui_shared.jar
+ withoutQuickstepImplementation fileTree(dir: "libs", include: 'plugin_core.jar')
testImplementation 'junit:junit:4.12'
androidTestImplementation "org.mockito:mockito-core:1.9.5"
diff --git a/go/AndroidManifest.xml b/go/AndroidManifest.xml
index 0080898..25518af 100644
--- a/go/AndroidManifest.xml
+++ b/go/AndroidManifest.xml
@@ -22,7 +22,7 @@
xmlns:tools="http://schemas.android.com/tools"
package="com.android.launcher3" >
- <uses-sdk android:targetSdkVersion="23" android:minSdkVersion="21"/>
+ <uses-sdk android:targetSdkVersion="28" android:minSdkVersion="21"/>
<application
android:backupAgent="com.android.launcher3.LauncherBackupAgent"
diff --git a/iconloaderlib/src/com/android/launcher3/icons/cache/BaseIconCache.java b/iconloaderlib/src/com/android/launcher3/icons/cache/BaseIconCache.java
index 63820f6..ce66448 100644
--- a/iconloaderlib/src/com/android/launcher3/icons/cache/BaseIconCache.java
+++ b/iconloaderlib/src/com/android/launcher3/icons/cache/BaseIconCache.java
@@ -151,7 +151,7 @@
private synchronized void updateIconParamsBg(int iconDpi, int iconPixelSize) {
mIconDpi = iconDpi;
mDefaultIcons.clear();
-
+ mIconDb.clear();
mIconDb.close();
mIconDb = new IconDB(mContext, mDbFileName, iconPixelSize);
mCache.clear();
diff --git a/quickstep/libs/sysui_shared.jar b/quickstep/libs/sysui_shared.jar
index 6e7534d..8af310c 100644
--- a/quickstep/libs/sysui_shared.jar
+++ b/quickstep/libs/sysui_shared.jar
Binary files differ
diff --git a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
index 20a83b5..a1cee82 100644
--- a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
+++ b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
@@ -80,8 +80,8 @@
import com.android.systemui.shared.system.RemoteAnimationDefinitionCompat;
import com.android.systemui.shared.system.RemoteAnimationRunnerCompat;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
-import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplier;
-import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplier.SurfaceParams;
+import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat;
+import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams;
import com.android.systemui.shared.system.WindowManagerWrapper;
/**
@@ -204,7 +204,15 @@
mLauncher.getStateManager().setCurrentAnimation(anim);
Rect windowTargetBounds = getWindowTargetBounds(targetCompats);
- playIconAnimators(anim, v, windowTargetBounds);
+ boolean isAllOpeningTargetTrs = true;
+ for (int i = 0; i < targetCompats.length; i++) {
+ RemoteAnimationTargetCompat target = targetCompats[i];
+ if (target.mode == MODE_OPENING) {
+ isAllOpeningTargetTrs &= target.isTranslucent;
+ }
+ if (!isAllOpeningTargetTrs) break;
+ }
+ playIconAnimators(anim, v, windowTargetBounds, !isAllOpeningTargetTrs);
if (launcherClosing) {
Pair<AnimatorSet, Runnable> launcherContentAnimator =
getLauncherContentAnimator(true /* isAppOpening */);
@@ -432,7 +440,8 @@
/**
* Animators for the "floating view" of the view used to launch the target.
*/
- private void playIconAnimators(AnimatorSet appOpenAnimator, View v, Rect windowTargetBounds) {
+ private void playIconAnimators(AnimatorSet appOpenAnimator, View v, Rect windowTargetBounds,
+ boolean toggleVisibility) {
final boolean isBubbleTextView = v instanceof BubbleTextView;
mFloatingView = new View(mLauncher);
if (isBubbleTextView && v.getTag() instanceof ItemInfoWithIcon ) {
@@ -485,7 +494,9 @@
// Swap the two views in place.
((ViewGroup) mDragLayer.getParent()).addView(mFloatingView);
- v.setVisibility(View.INVISIBLE);
+ if (toggleVisibility) {
+ v.setVisibility(View.INVISIBLE);
+ }
int[] dragLayerBounds = new int[2];
mDragLayer.getLocationOnScreen(dragLayerBounds);
@@ -580,8 +591,8 @@
MODE_OPENING);
RemoteAnimationTargetSet closingTargets = new RemoteAnimationTargetSet(targets,
MODE_CLOSING);
- SyncRtSurfaceTransactionApplier surfaceApplier = new SyncRtSurfaceTransactionApplier(
- mFloatingView);
+ SyncRtSurfaceTransactionApplierCompat surfaceApplier =
+ new SyncRtSurfaceTransactionApplierCompat(mFloatingView);
ValueAnimator appAnimator = ValueAnimator.ofFloat(0, 1);
appAnimator.setDuration(APP_LAUNCH_DURATION);
@@ -740,8 +751,8 @@
* Animator that controls the transformations of the windows the targets that are closing.
*/
private Animator getClosingWindowAnimators(RemoteAnimationTargetCompat[] targets) {
- SyncRtSurfaceTransactionApplier surfaceApplier =
- new SyncRtSurfaceTransactionApplier(mDragLayer);
+ SyncRtSurfaceTransactionApplierCompat surfaceApplier =
+ new SyncRtSurfaceTransactionApplierCompat(mDragLayer);
Matrix matrix = new Matrix();
ValueAnimator closingAnimator = ValueAnimator.ofFloat(0, 1);
int duration = CLOSING_TRANSITION_DURATION_MS;
diff --git a/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginEnablerImpl.java b/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginEnablerImpl.java
index eaf4183..5afeca7 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginEnablerImpl.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginEnablerImpl.java
@@ -34,7 +34,16 @@
}
@Override
- public void setEnabled(ComponentName component, boolean enabled) {
+ public void setEnabled(ComponentName component) {
+ setState(component, true);
+ }
+
+ @Override
+ public void setDisabled(ComponentName component, int reason) {
+ setState(component, reason == ENABLED);
+ }
+
+ private void setState(ComponentName component, boolean enabled) {
putBoolean(pluginEnabledKey(component), enabled);
}
@@ -44,6 +53,11 @@
}
@Override
+ public int getDisableReason(ComponentName componentName) {
+ return isEnabled(componentName) ? ENABLED : DISABLED_MANUALLY;
+ }
+
+ @Override
public void putBoolean(String key, boolean value) {
mSharedPrefs.edit().putBoolean(key, value).apply();
}
diff --git a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
index a3207f5..9bbe57a 100644
--- a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
+++ b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
@@ -66,7 +66,7 @@
import com.android.systemui.shared.system.LatencyTrackerCompat;
import com.android.systemui.shared.system.PackageManagerWrapper;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
-import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplier;
+import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat;
import com.android.systemui.shared.system.TransactionCompat;
import java.util.ArrayList;
@@ -344,7 +344,7 @@
clipHelper.prepareAnimation(false /* isOpening */);
ClipAnimationHelper.TransformParams params = new ClipAnimationHelper.TransformParams()
- .setSyncTransactionApplier(new SyncRtSurfaceTransactionApplier(rootView));
+ .setSyncTransactionApplier(new SyncRtSurfaceTransactionApplierCompat(rootView));
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1);
valueAnimator.setDuration(RECENTS_LAUNCH_DURATION);
valueAnimator.setInterpolator(TOUCH_RESPONSE_INTERPOLATOR);
diff --git a/quickstep/src/com/android/quickstep/QuickScrubController.java b/quickstep/src/com/android/quickstep/QuickScrubController.java
index b07f8af..da5c4fa 100644
--- a/quickstep/src/com/android/quickstep/QuickScrubController.java
+++ b/quickstep/src/com/android/quickstep/QuickScrubController.java
@@ -21,6 +21,7 @@
import static com.android.launcher3.anim.Interpolators.DEACCEL_3;
import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
import static com.android.launcher3.anim.Interpolators.LINEAR;
+import static com.android.launcher3.config.FeatureFlags.ENABLE_TASK_STABILIZER;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -289,16 +290,20 @@
}
mPrevPrevProgressDelta = mPrevProgressDelta;
mPrevProgressDelta = progressDelta;
- float scrollDiff = nextPage.getWidth() + mRecentsView.getPageSpacing();
- int scrollDir = mRecentsView.isRtl() ? -1 : 1;
- int linearScrollDiff = (int) (progress * scrollDiff * scrollDir);
- float accelScrollDiff = ACCEL.getInterpolation(progress) * scrollDiff * scrollDir;
+ int startScroll = mRecentsView.getScrollForPage(
+ mRecentsView.indexOfChild(currentPage));
+ int scrollDiff = mRecentsView.getScrollForPage(mRecentsView.indexOfChild(nextPage))
+ - startScroll;
+
+ int linearScrollDiff = (int) (progress * scrollDiff);
currentPage.setZoomScale(1 - DEACCEL_3.getInterpolation(progress)
* TaskView.EDGE_SCALE_DOWN_FACTOR);
- currentPage.setTranslationX(linearScrollDiff + accelScrollDiff);
+ if (!ENABLE_TASK_STABILIZER.get()) {
+ float accelScrollDiff = ACCEL.getInterpolation(progress) * scrollDiff;
+ currentPage.setTranslationX(linearScrollDiff + accelScrollDiff);
+ }
nextPage.setTranslationZ(1);
nextPage.setTranslationY(currentPage.getTranslationY());
- int startScroll = mRecentsView.isRtl() ? mRecentsView.getMaxScrollX() : 0;
mRecentsView.setScrollX(startScroll + linearScrollDiff);
}
return;
@@ -358,9 +363,16 @@
: mStartedFromHome
? QUICK_SCRUB_FROM_HOME_START_DURATION
: QUICK_SCRUB_FROM_APP_START_DURATION;
- int pageToGoTo = mStartedFromHome || mIsQuickSwitch
- ? 0
- : mRecentsView.getNextPage() + 1;
+ final int pageToGoTo;
+ if (mStartedFromHome) {
+ pageToGoTo = 0;
+ } else if (mIsQuickSwitch) {
+ TaskView tv = mRecentsView.getRunningTaskView();
+ pageToGoTo = tv != null ? mRecentsView.indexOfChild(tv)
+ : mRecentsView.getNextPage();
+ } else {
+ pageToGoTo = mRecentsView.getNextPage() + 1;
+ }
goToPageWithHaptic(pageToGoTo, duration, true /* forceHaptic */,
QUICK_SCRUB_START_INTERPOLATOR);
}
diff --git a/quickstep/src/com/android/quickstep/TaskUtils.java b/quickstep/src/com/android/quickstep/TaskUtils.java
index cf46b09..c2777e7 100644
--- a/quickstep/src/com/android/quickstep/TaskUtils.java
+++ b/quickstep/src/com/android/quickstep/TaskUtils.java
@@ -43,7 +43,7 @@
import com.android.quickstep.views.TaskView;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
-import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplier;
+import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat;
import java.util.List;
@@ -146,7 +146,8 @@
public static ValueAnimator getRecentsWindowAnimator(TaskView v, boolean skipViewChanges,
RemoteAnimationTargetCompat[] targets, final ClipAnimationHelper inOutHelper) {
ClipAnimationHelper.TransformParams params = new ClipAnimationHelper.TransformParams()
- .setSyncTransactionApplier(new SyncRtSurfaceTransactionApplier(v));
+ .setSyncTransactionApplier(new SyncRtSurfaceTransactionApplierCompat(v));
+
final ValueAnimator appAnimator = ValueAnimator.ofFloat(0, 1);
appAnimator.setInterpolator(TOUCH_RESPONSE_INTERPOLATOR);
appAnimator.addUpdateListener(new MultiValueUpdateListener() {
diff --git a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
index 686b52b..e951750 100644
--- a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
+++ b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
@@ -87,7 +87,7 @@
import com.android.systemui.shared.system.LatencyTrackerCompat;
import com.android.systemui.shared.system.RecentsAnimationControllerCompat;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
-import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplier;
+import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat;
import com.android.systemui.shared.system.WindowCallbacksCompat;
import java.util.StringJoiner;
@@ -216,7 +216,7 @@
private T mActivity;
private LayoutListener mLayoutListener;
private RecentsView mRecentsView;
- private SyncRtSurfaceTransactionApplier mSyncTransactionApplier;
+ private SyncRtSurfaceTransactionApplierCompat mSyncTransactionApplier;
private QuickScrubController mQuickScrubController;
private AnimationFactory mAnimationFactory = (t, i) -> { };
@@ -407,7 +407,7 @@
}
mRecentsView = activity.getOverviewPanel();
- SyncRtSurfaceTransactionApplier.create(mRecentsView, (applier) -> {
+ SyncRtSurfaceTransactionApplierCompat.create(mRecentsView, (applier) -> {
mSyncTransactionApplier = applier;
});
mQuickScrubController = mRecentsView.getQuickScrubController();
@@ -588,7 +588,7 @@
RecentsAnimationControllerCompat controller = mRecentsAnimationWrapper.getController();
if (controller != null) {
- SyncRtSurfaceTransactionApplier syncTransactionApplier
+ SyncRtSurfaceTransactionApplierCompat syncTransactionApplier
= Looper.myLooper() == mMainThreadHandler.getLooper()
? mSyncTransactionApplier
: null;
diff --git a/quickstep/src/com/android/quickstep/util/ClipAnimationHelper.java b/quickstep/src/com/android/quickstep/util/ClipAnimationHelper.java
index d8a3282..431517a 100644
--- a/quickstep/src/com/android/quickstep/util/ClipAnimationHelper.java
+++ b/quickstep/src/com/android/quickstep/util/ClipAnimationHelper.java
@@ -46,8 +46,8 @@
import com.android.systemui.shared.recents.ISystemUiProxy;
import com.android.systemui.shared.recents.utilities.RectFEvaluator;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
-import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplier;
-import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplier.SurfaceParams;
+import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat;
+import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams;
import com.android.systemui.shared.system.TransactionCompat;
import com.android.systemui.shared.system.WindowManagerWrapper;
@@ -217,14 +217,14 @@
return mCurrentRectWithInsets;
}
- private void applySurfaceParams(@Nullable SyncRtSurfaceTransactionApplier
+ private void applySurfaceParams(@Nullable SyncRtSurfaceTransactionApplierCompat
syncTransactionApplier, SurfaceParams[] params) {
if (syncTransactionApplier != null) {
syncTransactionApplier.scheduleApply(params);
} else {
TransactionCompat t = new TransactionCompat();
for (SurfaceParams param : params) {
- SyncRtSurfaceTransactionApplier.applyParams(t, param);
+ SyncRtSurfaceTransactionApplierCompat.applyParams(t, param);
}
t.setEarlyWakeup();
t.apply();
@@ -353,7 +353,7 @@
public static class TransformParams {
float progress;
- SyncRtSurfaceTransactionApplier syncTransactionApplier;
+ SyncRtSurfaceTransactionApplierCompat syncTransactionApplier;
public TransformParams() {
progress = 0;
@@ -364,7 +364,8 @@
return this;
}
- public TransformParams setSyncTransactionApplier(SyncRtSurfaceTransactionApplier applier) {
+ public TransformParams setSyncTransactionApplier(
+ SyncRtSurfaceTransactionApplierCompat applier) {
this.syncTransactionApplier = applier;
return this;
}
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 6861bc1..34b5748 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -484,6 +484,11 @@
final TaskView taskView = (TaskView) getChildAt(pageIndex);
taskView.bind(task);
}
+ TaskView runningTaskView = getRunningTaskView();
+ if (runningTaskView != null) {
+ setCurrentPage(indexOfChild(runningTaskView));
+ }
+
if (mIgnoreResetTaskId != -1 && getTaskView(mIgnoreResetTaskId) != ignoreRestTaskView) {
// If the taskView mapping is changing, do not preserve the visuals. Since we are
// mostly preserving the first task, and new taskViews are added to the end, it should
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index 4853a90..d96855e 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -342,6 +342,14 @@
}
@Override
+ public void onVisibilityAggregated(boolean isVisible) {
+ super.onVisibilityAggregated(isVisible);
+ if (mIcon != null) {
+ mIcon.setVisible(isVisible, false);
+ }
+ }
+
+ @Override
public void onLauncherResume() {
// Reset the pressed state of icon that was locked in the press state while activity
// was launching
@@ -573,6 +581,9 @@
applyCompoundDrawables(icon);
}
mIcon = icon;
+ if (mIcon != null) {
+ mIcon.setVisible(getWindowVisibility() == VISIBLE && isShown(), false);
+ }
}
public void setIconVisible(boolean visible) {
diff --git a/src/com/android/launcher3/DropTarget.java b/src/com/android/launcher3/DropTarget.java
index 4d30479..763432d 100644
--- a/src/com/android/launcher3/DropTarget.java
+++ b/src/com/android/launcher3/DropTarget.java
@@ -78,17 +78,17 @@
*/
public final float[] getVisualCenter(float[] recycle) {
final float res[] = (recycle == null) ? new float[2] : recycle;
+ Rect dragRegion = dragView.getDragRegion();
// These represent the visual top and left of drag view if a dragRect was provided.
// If a dragRect was not provided, then they correspond to the actual view left and
// top, as the dragRect is in that case taken to be the entire dragView.
- // R.dimen.dragViewOffsetY.
- int left = x - xOffset;
- int top = y - yOffset;
+ int left = x - xOffset - dragRegion.left;
+ int top = y - yOffset - dragRegion.top;
// In order to find the visual center, we shift by half the dragRect
- res[0] = left + dragView.getDragRegion().width() / 2;
- res[1] = top + dragView.getDragRegion().height() / 2;
+ res[0] = left + dragRegion.width() / 2;
+ res[1] = top + dragRegion.height() / 2;
return res;
}
diff --git a/src/com/android/launcher3/FastBitmapDrawable.java b/src/com/android/launcher3/FastBitmapDrawable.java
index daf587a..964e8b6 100644
--- a/src/com/android/launcher3/FastBitmapDrawable.java
+++ b/src/com/android/launcher3/FastBitmapDrawable.java
@@ -17,6 +17,7 @@
package com.android.launcher3;
import static com.android.launcher3.anim.Interpolators.ACCEL;
+import static com.android.launcher3.anim.Interpolators.DEACCEL;
import android.animation.ObjectAnimator;
import android.graphics.Bitmap;
@@ -221,8 +222,15 @@
mScaleAnimation.setInterpolator(ACCEL);
mScaleAnimation.start();
} else {
- mScale = 1f;
- invalidateSelf();
+ if (isVisible()) {
+ mScaleAnimation = ObjectAnimator.ofFloat(this, SCALE, 1f);
+ mScaleAnimation.setDuration(CLICK_FEEDBACK_DURATION);
+ mScaleAnimation.setInterpolator(DEACCEL);
+ mScaleAnimation.start();
+ } else {
+ mScale = 1f;
+ invalidateSelf();
+ }
}
return true;
}
diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index dbefa45..5c842a5 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -17,10 +17,12 @@
package com.android.launcher3;
import static com.android.launcher3.config.FeatureFlags.APPLY_CONFIG_AT_RUNTIME;
+import static com.android.launcher3.Utilities.getDevicePrefs;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.Configuration;
+import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
import android.graphics.Point;
@@ -46,24 +48,30 @@
public class InvariantDeviceProfile {
+ public static final String TAG = "IDP";
// We do not need any synchronization for this variable as its only written on UI thread.
public static final MainThreadInitializedObject<InvariantDeviceProfile> INSTANCE =
new MainThreadInitializedObject<>(InvariantDeviceProfile::new);
- private static final String KEY_IDP_GRIP_NAME = "idp_grid_name";
+ private static final String KEY_IDP_GRID_NAME = "idp_grid_name";
private static final float ICON_SIZE_DEFINED_IN_APP_DP = 48;
public static final int CHANGE_FLAG_GRID = 1 << 0;
- public static final int CHANGE_FLAG_ICON_SIZE = 1 << 1;
+ public static final int CHANGE_FLAG_ICON_PARAMS = 1 << 1;
+
+ public static final String KEY_ICON_PATH_REF = "pref_icon_shape_path";
// Constants that affects the interpolation curve between statically defined device profile
// buckets.
- private static float KNEARESTNEIGHBOR = 3;
- private static float WEIGHT_POWER = 5;
+ private static final float KNEARESTNEIGHBOR = 3;
+ private static final float WEIGHT_POWER = 5;
// used to offset float not being able to express extremely small weights in extreme cases.
- private static float WEIGHT_EFFICIENT = 100000f;
+ private static final float WEIGHT_EFFICIENT = 100000f;
+
+ private static final int CONFIG_ICON_MASK_RES_ID = Resources.getSystem().getIdentifier(
+ "config_icon_mask", "string", "android");
/**
* Number of icons per row and column in the workspace.
@@ -77,6 +85,7 @@
public int numFolderRows;
public int numFolderColumns;
public float iconSize;
+ public String iconShapePath;
public float landscapeIconSize;
public int iconBitmapSize;
public int fillResIconDpi;
@@ -107,6 +116,7 @@
numFolderRows = p.numFolderRows;
numFolderColumns = p.numFolderColumns;
iconSize = p.iconSize;
+ iconShapePath = p.iconShapePath;
landscapeIconSize = p.landscapeIconSize;
iconTextSize = p.iconTextSize;
numHotseatIcons = p.numHotseatIcons;
@@ -116,11 +126,22 @@
@TargetApi(23)
private InvariantDeviceProfile(Context context) {
- initGrid(context, Utilities.getPrefs(context).getString(KEY_IDP_GRIP_NAME, null));
+ initGrid(context, Utilities.getPrefs(context).getString(KEY_IDP_GRID_NAME, null));
mConfigMonitor = new ConfigMonitor(context,
APPLY_CONFIG_AT_RUNTIME.get() ? this::onConfigChanged : this::killProcess);
}
+ /**
+ * Retrieve system defined or RRO overriden icon shape.
+ */
+ private static String getIconShapePath(Context context) {
+ if (CONFIG_ICON_MASK_RES_ID == 0) {
+ Log.e(TAG, "Icon mask res identifier failed to retrieve.");
+ return "";
+ }
+ return context.getResources().getString(CONFIG_ICON_MASK_RES_ID);
+ }
+
private void initGrid(Context context, String gridName) {
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
@@ -152,10 +173,11 @@
numFolderColumns = closestProfile.numFolderColumns;
if (!closestProfile.name.equals(gridName)) {
Utilities.getPrefs(context).edit()
- .putString(KEY_IDP_GRIP_NAME, closestProfile.name).apply();
+ .putString(KEY_IDP_GRID_NAME, closestProfile.name).apply();
}
iconSize = interpolatedDisplayOption.iconSize;
+ iconShapePath = getIconShapePath(context);
landscapeIconSize = interpolatedDisplayOption.landscapeIconSize;
iconBitmapSize = Utilities.pxFromDp(iconSize, dm);
iconTextSize = interpolatedDisplayOption.iconTextSize;
@@ -197,12 +219,26 @@
android.os.Process.killProcess(android.os.Process.myPid());
}
+ public void verifyConfigChangedInBackground(final Context context) {
+
+ String savedIconMaskPath = getDevicePrefs(context).getString(KEY_ICON_PATH_REF, "");
+ // Good place to check if grid size changed in themepicker when launcher was dead.
+ if (savedIconMaskPath.isEmpty()) {
+ getDevicePrefs(context).edit().putString(KEY_ICON_PATH_REF, getIconShapePath(context))
+ .apply();
+ } else if (!savedIconMaskPath.equals(getIconShapePath(context))) {
+ getDevicePrefs(context).edit().putString(KEY_ICON_PATH_REF, getIconShapePath(context))
+ .apply();
+ apply(context, CHANGE_FLAG_ICON_PARAMS);
+ }
+ }
+
private void onConfigChanged(Context context) {
// Config changes, what shall we do?
InvariantDeviceProfile oldProfile = new InvariantDeviceProfile(this);
// Re-init grid
- initGrid(context, Utilities.getPrefs(context).getString(KEY_IDP_GRIP_NAME, null));
+ initGrid(context, Utilities.getPrefs(context).getString(KEY_IDP_GRID_NAME, null));
int changeFlags = 0;
if (numRows != oldProfile.numRows ||
@@ -213,10 +249,14 @@
changeFlags |= CHANGE_FLAG_GRID;
}
- if (iconSize != oldProfile.iconSize || iconBitmapSize != oldProfile.iconBitmapSize) {
- changeFlags |= CHANGE_FLAG_ICON_SIZE;
+ if (iconSize != oldProfile.iconSize || iconBitmapSize != oldProfile.iconBitmapSize ||
+ !iconShapePath.equals(oldProfile.iconShapePath)) {
+ changeFlags |= CHANGE_FLAG_ICON_PARAMS;
}
+ apply(context, changeFlags);
+ }
+ private void apply(Context context, int changeFlags) {
// Create a new config monitor
mConfigMonitor.unregister();
mConfigMonitor = new ConfigMonitor(context, this::onConfigChanged);
@@ -231,7 +271,6 @@
try (XmlResourceParser parser = context.getResources().getXml(R.xml.device_profiles)) {
final int depth = parser.getDepth();
int type;
-
while (((type = parser.next()) != XmlPullParser.END_TAG ||
parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
if ((type == XmlPullParser.START_TAG) && "grid-option".equals(parser.getName())) {
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index 182a4ee..74fa447 100644
--- a/src/com/android/launcher3/LauncherAppState.java
+++ b/src/com/android/launcher3/LauncherAppState.java
@@ -16,14 +16,15 @@
package com.android.launcher3;
+import static com.android.launcher3.InvariantDeviceProfile.CHANGE_FLAG_ICON_PARAMS;
import static com.android.launcher3.util.SecureSettingsObserver.newNotificationSettingsObserver;
-import static com.android.launcher3.InvariantDeviceProfile.CHANGE_FLAG_ICON_SIZE;
import android.content.ComponentName;
import android.content.ContentProviderClient;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.os.Handler;
import android.util.Log;
import com.android.launcher3.compat.LauncherAppsCompat;
@@ -97,6 +98,7 @@
mContext.registerReceiver(mModel, filter);
UserManagerCompat.getInstance(mContext).enableAndResetCache();
mInvariantDeviceProfile.addOnChangeListener(this::onIdpChanged);
+ new Handler().post( () -> mInvariantDeviceProfile.verifyConfigChangedInBackground(context));
if (!mContext.getResources().getBoolean(R.bool.notification_dots_enabled)) {
mNotificationDotsObserver = null;
@@ -121,7 +123,7 @@
return;
}
- if ((changeFlags & CHANGE_FLAG_ICON_SIZE) != 0) {
+ if ((changeFlags & CHANGE_FLAG_ICON_PARAMS) != 0) {
LauncherIcons.clearPool();
mIconCache.updateIconParams(idp.fillResIconDpi, idp.iconBitmapSize);
}
diff --git a/src/com/android/launcher3/config/BaseFlags.java b/src/com/android/launcher3/config/BaseFlags.java
index 3f420fa..03fdc64 100644
--- a/src/com/android/launcher3/config/BaseFlags.java
+++ b/src/com/android/launcher3/config/BaseFlags.java
@@ -93,10 +93,10 @@
* Feature flag to handle define config changes dynamically instead of killing the process.
*/
public static final TogglableFlag APPLY_CONFIG_AT_RUNTIME = new TogglableFlag(
- "APPLY_CONFIG_AT_RUNTIME", false, "Apply display changes dynamically");
+ "APPLY_CONFIG_AT_RUNTIME", true, "Apply display changes dynamically");
public static final TogglableFlag ENABLE_TASK_STABILIZER = new TogglableFlag(
- "ENABLE_TASK_STABILIZER", true, "Stable task list across fast task switches");
+ "ENABLE_TASK_STABILIZER", false, "Stable task list across fast task switches");
public static void initialize(Context context) {
// Avoid the disk read for user builds
diff --git a/src/com/android/launcher3/util/ConfigMonitor.java b/src/com/android/launcher3/util/ConfigMonitor.java
index 717acdc..607afab 100644
--- a/src/com/android/launcher3/util/ConfigMonitor.java
+++ b/src/com/android/launcher3/util/ConfigMonitor.java
@@ -29,6 +29,7 @@
import android.view.Display;
import android.view.WindowManager;
+import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.MainThreadExecutor;
import com.android.launcher3.Utilities.Consumer;
@@ -40,6 +41,8 @@
private static final String TAG = "ConfigMonitor";
+ private final String ACTION_OVERLAY_CHANGED = "android.intent.action.OVERLAY_CHANGED";
+
private final Point mTmpPoint1 = new Point();
private final Point mTmpPoint2 = new Point();
@@ -72,7 +75,15 @@
mCallback = callback;
+ // Listen for configuration change
mContext.registerReceiver(this, new IntentFilter(Intent.ACTION_CONFIGURATION_CHANGED));
+
+ // Listen for {@link OverlayManager} change
+ IntentFilter filter = new IntentFilter(ACTION_OVERLAY_CHANGED);
+ filter.addDataScheme("package");
+ mContext.registerReceiver(this, filter);
+
+ // Listen for display manager change
mContext.getSystemService(DisplayManager.class)
.registerDisplayListener(this, new Handler(UiThreadHelper.getBackgroundLooper()));
}
@@ -80,8 +91,14 @@
@Override
public void onReceive(Context context, Intent intent) {
Configuration config = context.getResources().getConfiguration();
+ // TODO: when overlay manager service encodes more information to the Uri such as category
+ // of the overlay, only listen to the ones that are of interest to launcher.
+ if (intent != null && ACTION_OVERLAY_CHANGED.equals(intent.getAction())) {
+ Log.d(TAG, "Overlay changed.");
+ notifyChange();
+ }
if (mFontScale != config.fontScale || mDensity != config.densityDpi) {
- Log.d(TAG, "Configuration changed");
+ Log.d(TAG, "Configuration changed.");
notifyChange();
}
}
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
index 0be5f11..ebab122 100644
--- a/tests/AndroidManifest.xml
+++ b/tests/AndroidManifest.xml
@@ -18,7 +18,7 @@
xmlns:tools="http://schemas.android.com/tools"
package="com.android.launcher3.tests">
- <uses-sdk android:targetSdkVersion="25" android:minSdkVersion="21"
+ <uses-sdk android:targetSdkVersion="28" android:minSdkVersion="21"
tools:overrideLibrary="android.support.test.uiautomator.v18"/>
<application android:debuggable="true">
diff --git a/tests/dummy_app/AndroidManifest.xml b/tests/dummy_app/AndroidManifest.xml
index 0546015..9d0a74a 100644
--- a/tests/dummy_app/AndroidManifest.xml
+++ b/tests/dummy_app/AndroidManifest.xml
@@ -21,7 +21,7 @@
to come from a domain that you own or have control over. -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.aardwolf">
- <uses-sdk android:targetSdkVersion="25" android:minSdkVersion="21"/>
+ <uses-sdk android:targetSdkVersion="28" android:minSdkVersion="21"/>
<application android:label="Aardwolf">
<activity
android:name="Activity1"