summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--build.gradle8
-rw-r--r--proguard.flags5
-rw-r--r--quickstep/res/values/config.xml19
-rw-r--r--quickstep/res/values/override.xml (renamed from res/layout/predictions_view.xml)11
-rw-r--r--quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java (renamed from quickstep/src/com/android/launcher3/LauncherAppTransitionManager.java)161
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/EdgeSwipeController.java12
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/UiFactory.java28
-rw-r--r--quickstep/src/com/android/quickstep/RecentsView.java2
-rw-r--r--quickstep/src/com/android/quickstep/TaskOverlayFactory.java55
-rw-r--r--quickstep/src/com/android/quickstep/TaskThumbnailView.java45
-rw-r--r--quickstep/src/com/android/quickstep/TaskView.java2
-rw-r--r--quickstep/src/com/android/quickstep/TouchInteractionService.java1
-rw-r--r--res/layout/all_apps.xml43
-rw-r--r--res/layout/all_apps_floating_header.xml58
-rw-r--r--res/values/config.xml3
-rw-r--r--src/com/android/launcher3/DeviceProfile.java7
-rw-r--r--src/com/android/launcher3/DropTargetBar.java4
-rw-r--r--src/com/android/launcher3/Hotseat.java2
-rw-r--r--src/com/android/launcher3/IconCache.java5
-rw-r--r--src/com/android/launcher3/IconProvider.java24
-rw-r--r--src/com/android/launcher3/Launcher.java38
-rw-r--r--src/com/android/launcher3/LauncherAppTransitionManager.java64
-rw-r--r--src/com/android/launcher3/allapps/AllAppsContainerView.java129
-rw-r--r--src/com/android/launcher3/allapps/AllAppsStore.java127
-rw-r--r--src/com/android/launcher3/allapps/AlphabeticalAppsList.java24
-rw-r--r--src/com/android/launcher3/allapps/FloatingHeaderView.java47
-rw-r--r--src/com/android/launcher3/allapps/PredictionRowView.java245
-rw-r--r--src/com/android/launcher3/allapps/SearchUiManager.java6
-rw-r--r--src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java26
-rw-r--r--src/com/android/launcher3/dragndrop/DragLayer.java1
-rw-r--r--src/com/android/launcher3/graphics/GradientView.java2
-rw-r--r--src/com/android/launcher3/pageindicators/WorkspacePageIndicator.java8
-rw-r--r--src/com/android/launcher3/util/ComponentKeyMapper.java2
-rw-r--r--src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java6
34 files changed, 599 insertions, 621 deletions
diff --git a/build.gradle b/build.gradle
index 61c05e562..0030b8bfc 100644
--- a/build.gradle
+++ b/build.gradle
@@ -13,12 +13,12 @@ apply plugin: 'com.android.application'
apply plugin: 'com.google.protobuf'
android {
- compileSdkVersion 27
- buildToolsVersion '27.0.0'
+ compileSdkVersion 28
+ buildToolsVersion '28.0.0'
defaultConfig {
minSdkVersion 21
- targetSdkVersion 27
+ targetSdkVersion 28
versionCode 1
versionName "1.0"
@@ -102,7 +102,7 @@ repositories {
jcenter()
}
-final String SUPPORT_LIBS_VERSION = '27.0.0-SNAPSHOT'
+final String SUPPORT_LIBS_VERSION = '28.0.0-SNAPSHOT'
dependencies {
compile "com.android.support:support-v4:${SUPPORT_LIBS_VERSION}"
compile "com.android.support:support-dynamic-animation:${SUPPORT_LIBS_VERSION}"
diff --git a/proguard.flags b/proguard.flags
index 987fb6f12..b8cade572 100644
--- a/proguard.flags
+++ b/proguard.flags
@@ -97,6 +97,11 @@
# support jar.
-keep class android.support.v7.widget.RecyclerView { *; }
+# LauncherAppTransitionManager
+-keep class com.android.launcher3.LauncherAppTransitionManagerImpl {
+ public <init>(...);
+}
+
-keep interface com.android.launcher3.userevent.nano.LauncherLogProto.** {
*;
}
diff --git a/quickstep/res/values/config.xml b/quickstep/res/values/config.xml
new file mode 100644
index 000000000..94211c62f
--- /dev/null
+++ b/quickstep/res/values/config.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 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>
+ <string name="task_overlay_factory_class" translatable="false"></string>
+
+</resources>
diff --git a/res/layout/predictions_view.xml b/quickstep/res/values/override.xml
index 280290c6a..ba99d81c0 100644
--- a/res/layout/predictions_view.xml
+++ b/quickstep/res/values/override.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
+<!-- Copyright (C) 2018 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.
@@ -13,7 +13,8 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<com.android.launcher3.allapps.PredictionRowView
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content" /> \ No newline at end of file
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_transition_manager_class" translatable="false">com.android.launcher3.LauncherAppTransitionManagerImpl</string>
+</resources>
+
diff --git a/quickstep/src/com/android/launcher3/LauncherAppTransitionManager.java b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
index 47179c5a0..9968ca72c 100644
--- a/quickstep/src/com/android/launcher3/LauncherAppTransitionManager.java
+++ b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
@@ -26,6 +26,8 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
+import android.content.Context;
+import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Matrix;
@@ -55,11 +57,15 @@ import com.android.systemui.shared.system.WindowManagerWrapper;
/**
* Manages the opening and closing app transitions from Launcher.
*/
-public class LauncherAppTransitionManager {
+public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManager {
private static final String TAG = "LauncherTransition";
private static final int REFRESH_RATE_MS = 16;
+ private static final String CONTROL_REMOTE_APP_TRANSITION_PERMISSION =
+ "android.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS";
+
+ private static final int LAUNCHER_RESUME_START_DELAY = 150;
private static final int CLOSING_TRANSITION_DURATION_MS = 350;
// Progress = 0: All apps is fully pulled up, Progress = 1: All apps is fully pulled down.
@@ -76,60 +82,79 @@ public class LauncherAppTransitionManager {
private ImageView mFloatingView;
private boolean mIsRtl;
- public LauncherAppTransitionManager(Launcher launcher) {
- mLauncher = launcher;
- mDragLayer = launcher.getDragLayer();
- mDeviceProfile = launcher.getDeviceProfile();
+ private Animator mCurrentAnimator;
+
+ public LauncherAppTransitionManagerImpl(Context context) {
+ mLauncher = Launcher.getLauncher(context);
+ mDragLayer = mLauncher.getDragLayer();
+ mDeviceProfile = mLauncher.getDeviceProfile();
- mIsRtl = Utilities.isRtl(launcher.getResources());
+ mIsRtl = Utilities.isRtl(mLauncher.getResources());
- Resources res = launcher.getResources();
+ Resources res = mLauncher.getResources();
mContentTransY = res.getDimensionPixelSize(R.dimen.content_trans_y);
mWorkspaceTransY = res.getDimensionPixelSize(R.dimen.workspace_trans_y);
}
+ private void setCurrentAnimator(Animator animator) {
+ if (mCurrentAnimator != null && mCurrentAnimator.isRunning()) {
+ mCurrentAnimator.cancel();
+ }
+ mCurrentAnimator = animator;
+ }
+
/**
* @return A Bundle with remote animations that controls how the window of the opening
* targets are displayed.
*/
- public Bundle getActivityLauncherOptions(View v) {
- RemoteAnimationRunnerCompat runner = new LauncherAnimationRunner(mLauncher) {
- @Override
- public void onAnimationStart(RemoteAnimationTargetCompat[] targets,
- Runnable finishedCallback) {
- // Post at front of queue ignoring sync barriers to make sure it gets processed
- // before the next frame.
- postAtFrontOfQueueAsynchronously(v.getHandler(), () -> {
- mAnimator = new AnimatorSet();
- mAnimator.play(getLauncherAnimators(v));
- mAnimator.play(getWindowAnimators(v, targets));
- mAnimator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- // Reset launcher to normal state
- v.setVisibility(View.VISIBLE);
- ((ViewGroup) mDragLayer.getParent()).removeView(mFloatingView);
-
- mDragLayer.setAlpha(1f);
- mDragLayer.setTranslationY(0f);
-
- View appsView = mLauncher.getAppsView();
- appsView.setAlpha(1f);
- appsView.setTranslationY(0f);
+ @Override
+ public Bundle getActivityLaunchOptions(Launcher launcher, View v) {
+ if (hasControlRemoteAppTransitionPermission()) {
+ try {
+ RemoteAnimationRunnerCompat runner = new LauncherAnimationRunner(mLauncher) {
+ @Override
+ public void onAnimationStart(RemoteAnimationTargetCompat[] targets,
+ Runnable finishedCallback) {
+ // Post at front of queue ignoring sync barriers to make sure it gets
+ // processed before the next frame.
+ postAtFrontOfQueueAsynchronously(v.getHandler(), () -> {
+ mAnimator = new AnimatorSet();
+ setCurrentAnimator(mAnimator);
+ mAnimator.play(getLauncherAnimators(v));
+ mAnimator.play(getWindowAnimators(v, targets));
+ mAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ // Reset launcher to normal state
+ v.setVisibility(View.VISIBLE);
+ ((ViewGroup) mDragLayer.getParent()).removeView(mFloatingView);
+
+ mDragLayer.setAlpha(1f);
+ mDragLayer.setTranslationY(0f);
+
+ View appsView = mLauncher.getAppsView();
+ appsView.setAlpha(1f);
+ appsView.setTranslationY(0f);
+
+ finishedCallback.run();
+ }
+ });
+ mAnimator.start();
+ // Because t=0 has the app icon in its original spot, we can skip the
+ // first frame and have the same movement one frame earlier.
+ mAnimator.setCurrentPlayTime(REFRESH_RATE_MS);
+ });
+ }
+ };
- finishedCallback.run();
- }
- });
- mAnimator.start();
- // Because t=0 has the app icon in its original spot, we can skip the first
- // frame and have the same movement one frame earlier.
- mAnimator.setCurrentPlayTime(REFRESH_RATE_MS);
- });
+ return ActivityOptionsCompat.makeRemoteAnimation(
+ new RemoteAnimationAdapterCompat(runner, 500, 380)).toBundle();
+ } catch (NoClassDefFoundError e) {
+ // Gracefully fall back to default launch options if the user's platform doesn't
+ // have the latest changes.
}
- };
-
- return ActivityOptionsCompat.makeRemoteAnimation(
- new RemoteAnimationAdapterCompat(runner, 500, 380)).toBundle();
+ }
+ return getDefaultActivityLaunchOptions(launcher, v);
}
/**
@@ -149,7 +174,7 @@ public class LauncherAppTransitionManager {
* Else: Animate the content so that it moves downwards and fades out.
*/
private AnimatorSet getLauncherContentAnimator(boolean show) {
- AnimatorSet hideLauncher = new AnimatorSet();
+ AnimatorSet launcherAnimator = new AnimatorSet();
float[] alphas = show
? new float[] {0, 1}
@@ -161,6 +186,9 @@ public class LauncherAppTransitionManager {
if (mLauncher.isInState(LauncherState.ALL_APPS) && !mDeviceProfile.isVerticalBarLayout()) {
// All Apps in portrait mode is full screen, so we only animate AllAppsContainerView.
View appsView = mLauncher.getAppsView();
+ appsView.setAlpha(alphas[0]);
+ appsView.setTranslationY(trans[0]);
+
ObjectAnimator alpha = ObjectAnimator.ofFloat(appsView, View.ALPHA, alphas);
alpha.setDuration(217);
alpha.setInterpolator(Interpolators.LINEAR);
@@ -168,9 +196,12 @@ public class LauncherAppTransitionManager {
transY.setInterpolator(Interpolators.AGGRESSIVE_EASE);
transY.setDuration(350);
- hideLauncher.play(alpha);
- hideLauncher.play(transY);
+ launcherAnimator.play(alpha);
+ launcherAnimator.play(transY);
} else {
+ mDragLayer.setAlpha(alphas[0]);
+ mDragLayer.setTranslationY(trans[0]);
+
ObjectAnimator dragLayerAlpha = ObjectAnimator.ofFloat(mDragLayer, View.ALPHA, alphas);
dragLayerAlpha.setDuration(217);
dragLayerAlpha.setInterpolator(Interpolators.LINEAR);
@@ -179,10 +210,10 @@ public class LauncherAppTransitionManager {
dragLayerTransY.setInterpolator(Interpolators.AGGRESSIVE_EASE);
dragLayerTransY.setDuration(350);
- hideLauncher.play(dragLayerAlpha);
- hideLauncher.play(dragLayerTransY);
+ launcherAnimator.play(dragLayerAlpha);
+ launcherAnimator.play(dragLayerTransY);
}
- return hideLauncher;
+ return launcherAnimator;
}
/**
@@ -361,15 +392,22 @@ public class LauncherAppTransitionManager {
/**
* Registers remote animations used when closing apps to home screen.
*/
+ @Override
public void registerRemoteAnimations() {
- RemoteAnimationDefinitionCompat definition = new RemoteAnimationDefinitionCompat();
- definition.addRemoteAnimation(WindowManagerWrapper.TRANSIT_WALLPAPER_OPEN,
- new RemoteAnimationAdapterCompat(getWallpaperOpenRunner(), 0,
- CLOSING_TRANSITION_DURATION_MS));
+ if (hasControlRemoteAppTransitionPermission()) {
+ try {
+ RemoteAnimationDefinitionCompat definition = new RemoteAnimationDefinitionCompat();
+ definition.addRemoteAnimation(WindowManagerWrapper.TRANSIT_WALLPAPER_OPEN,
+ new RemoteAnimationAdapterCompat(getWallpaperOpenRunner(), 0,
+ CLOSING_TRANSITION_DURATION_MS));
// TODO: App controlled transition for unlock to home TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER
- new ActivityCompat(mLauncher).registerRemoteAnimations(definition);
+ new ActivityCompat(mLauncher).registerRemoteAnimations(definition);
+ } catch (NoClassDefFoundError e) {
+ // Gracefully fall back if the user's platform doesn't have the latest changes
+ }
+ }
}
/**
@@ -385,11 +423,13 @@ public class LauncherAppTransitionManager {
postAtFrontOfQueueAsynchronously(handler, () -> {
// We use a separate transition for Overview mode.
if (mLauncher.isInState(LauncherState.OVERVIEW)) {
+ setCurrentAnimator(null);
finishedCallback.run();
return;
}
mAnimator = new AnimatorSet();
+ setCurrentAnimator(mAnimator);
mAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
@@ -465,7 +505,9 @@ public class LauncherAppTransitionManager {
private AnimatorSet getLauncherResumeAnimation() {
if (mLauncher.isInState(LauncherState.ALL_APPS)
|| mLauncher.getDeviceProfile().isVerticalBarLayout()) {
- return getLauncherContentAnimator(true /* show */);
+ AnimatorSet contentAnimator = getLauncherContentAnimator(true /* show */);
+ contentAnimator.setStartDelay(LAUNCHER_RESUME_START_DELAY);
+ return contentAnimator;
} else {
AnimatorSet workspaceAnimator = new AnimatorSet();
mLauncher.getWorkspace().setTranslationY(mWorkspaceTransY);
@@ -474,7 +516,7 @@ public class LauncherAppTransitionManager {
View.TRANSLATION_Y, mWorkspaceTransY, 0));
workspaceAnimator.play(ObjectAnimator.ofFloat(mLauncher.getWorkspace(), View.ALPHA,
0, 1f));
- workspaceAnimator.setStartDelay(150);
+ workspaceAnimator.setStartDelay(LAUNCHER_RESUME_START_DELAY);
workspaceAnimator.setDuration(333);
workspaceAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
@@ -489,7 +531,7 @@ public class LauncherAppTransitionManager {
Animator allAppsSlideIn =
ObjectAnimator.ofFloat(allAppsController, ALL_APPS_PROGRESS, startY, slideEnd);
- allAppsSlideIn.setStartDelay(150);
+ allAppsSlideIn.setStartDelay(LAUNCHER_RESUME_START_DELAY);
allAppsSlideIn.setDuration(317);
allAppsSlideIn.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
@@ -505,6 +547,11 @@ public class LauncherAppTransitionManager {
}
}
+ private boolean hasControlRemoteAppTransitionPermission() {
+ return mLauncher.checkSelfPermission(CONTROL_REMOTE_APP_TRANSITION_PERMISSION)
+ == PackageManager.PERMISSION_GRANTED;
+ }
+
/**
* Helper method that allows us to get interpolated values for embedded
* animations with a delay and/or different duration.
diff --git a/quickstep/src/com/android/launcher3/uioverrides/EdgeSwipeController.java b/quickstep/src/com/android/launcher3/uioverrides/EdgeSwipeController.java
index 356a144b7..fa09f237e 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/EdgeSwipeController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/EdgeSwipeController.java
@@ -26,6 +26,7 @@ import static com.android.quickstep.TouchInteractionService.EDGE_NAV_BAR;
import android.graphics.Rect;
import android.view.MotionEvent;
+import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.anim.SpringAnimationHandler;
import com.android.launcher3.dragndrop.DragLayer;
@@ -56,11 +57,7 @@ public class EdgeSwipeController extends VerticalSwipeController {
@Override
protected boolean isTransitionFlipped() {
- if (mLauncher.getDeviceProfile().isVerticalBarLayout()) {
- Rect insets = mLauncher.getDragLayer().getInsets();
- return insets.left > insets.right;
- }
- return false;
+ return mLauncher.getDeviceProfile().isSeascape();
}
@Override
@@ -82,9 +79,10 @@ public class EdgeSwipeController extends VerticalSwipeController {
RecentsView.getPageRect(launcher.getDeviceProfile(), launcher, sTempRect);
DragLayer dl = launcher.getDragLayer();
Rect insets = dl.getInsets();
+ DeviceProfile dp = launcher.getDeviceProfile();
- if (launcher.getDeviceProfile().isVerticalBarLayout()) {
- if (insets.left > insets.right) {
+ if (dp.isVerticalBarLayout()) {
+ if (dp.isSeascape()) {
return insets.left + sTempRect.left;
} else {
return dl.getWidth() - sTempRect.right + insets.right;
diff --git a/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java b/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
index a004dacde..b4f40c215 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
@@ -25,7 +25,6 @@ import android.view.View;
import android.view.View.AccessibilityDelegate;
import com.android.launcher3.Launcher;
-import com.android.launcher3.LauncherAppTransitionManager;
import com.android.launcher3.LauncherStateManager.StateHandler;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.graphics.BitmapRenderer;
@@ -84,31 +83,4 @@ public class UiFactory {
RecentsView recents = launcher.getOverviewPanel();
recents.reset();
}
-
- private static boolean hasControlRemoteAppTransitionPermission(Launcher launcher) {
- return launcher.checkSelfPermission(CONTROL_REMOTE_APP_TRANSITION_PERMISSION)
- == PackageManager.PERMISSION_GRANTED;
- }
-
- public static Bundle getActivityLaunchOptions(Launcher launcher, View v) {
- if (hasControlRemoteAppTransitionPermission(launcher)) {
- try {
- return new LauncherAppTransitionManager(launcher).getActivityLauncherOptions(v);
- } catch (NoClassDefFoundError e) {
- // Gracefully fall back to default launch options if the user's platform doesn't
- // have the latest changes.
- }
- }
- return launcher.getDefaultActivityLaunchOptions(v);
- }
-
- public static void registerRemoteAnimations(Launcher launcher) {
- if (hasControlRemoteAppTransitionPermission(launcher)) {
- try {
- new LauncherAppTransitionManager(launcher).registerRemoteAnimations();
- } catch (NoClassDefFoundError e) {
- // Gracefully fall back if the user's platform doesn't have the latest changes
- }
- }
- }
}
diff --git a/quickstep/src/com/android/quickstep/RecentsView.java b/quickstep/src/com/android/quickstep/RecentsView.java
index 31f8058af..b35d31bfe 100644
--- a/quickstep/src/com/android/quickstep/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/RecentsView.java
@@ -176,7 +176,7 @@ public class RecentsView extends PagedView implements Insettable {
if (dp.isVerticalBarLayout()) {
boolean wasScrimOnLeft = mScrimOnLeft;
- mScrimOnLeft = insets.left > insets.right;
+ mScrimOnLeft = dp.isSeascape();
if (mScrim == null || wasScrimOnLeft != mScrimOnLeft) {
Drawable scrim = getContext().getDrawable(mScrimOnLeft
diff --git a/quickstep/src/com/android/quickstep/TaskOverlayFactory.java b/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
new file mode 100644
index 000000000..c2fb7beb7
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.quickstep;
+
+import android.content.Context;
+import android.graphics.Matrix;
+import android.view.View;
+
+import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.util.Preconditions;
+import com.android.systemui.shared.recents.model.ThumbnailData;
+
+/**
+ * Factory class to create and add an overlays on the TaskView
+ */
+public class TaskOverlayFactory {
+
+ private static TaskOverlayFactory sInstance;
+
+ public static TaskOverlayFactory get(Context context) {
+ Preconditions.assertUIThread();
+ if (sInstance == null) {
+ sInstance = Utilities.getOverrideObject(TaskOverlayFactory.class,
+ context.getApplicationContext(), R.string.task_overlay_factory_class);
+ }
+ return sInstance;
+ }
+
+ public TaskOverlay createOverlay(View thumbnailView) {
+ return new TaskOverlay();
+ }
+
+ public static class TaskOverlay {
+
+ public void setTaskInfo(ThumbnailData thumbnail, Matrix matrix) { }
+
+ public void reset() { }
+
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/TaskThumbnailView.java b/quickstep/src/com/android/quickstep/TaskThumbnailView.java
index 87dec6759..36a0601c8 100644
--- a/quickstep/src/com/android/quickstep/TaskThumbnailView.java
+++ b/quickstep/src/com/android/quickstep/TaskThumbnailView.java
@@ -28,7 +28,6 @@ import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
-import android.graphics.Rect;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.view.View;
@@ -36,6 +35,7 @@ import android.view.View;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
+import com.android.quickstep.TaskOverlayFactory.TaskOverlay;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.recents.model.ThumbnailData;
@@ -49,15 +49,14 @@ public class TaskThumbnailView extends View {
private final float mCornerRadius;
private final float mFadeLength;
+ private final TaskOverlay mOverlay;
private final Paint mPaint = new Paint();
private final Matrix mMatrix = new Matrix();
- private final Rect mThumbnailRect = new Rect();
private ThumbnailData mThumbnailData;
protected BitmapShader mBitmapShader;
- private float mThumbnailScale;
private float mDimAlpha = 1f;
public TaskThumbnailView(Context context) {
@@ -72,6 +71,11 @@ public class TaskThumbnailView extends View {
super(context, attrs, defStyleAttr);
mCornerRadius = getResources().getDimension(R.dimen.task_corner_radius);
mFadeLength = getResources().getDimension(R.dimen.task_fade_length);
+ mOverlay = TaskOverlayFactory.get(context).createOverlay(this);
+ }
+
+ public void bind() {
+ mOverlay.reset();
}
/**
@@ -83,19 +87,15 @@ public class TaskThumbnailView extends View {
if (thumbnailData != null && thumbnailData.thumbnail != null) {
Bitmap bm = thumbnailData.thumbnail;
bm.prepareToDraw();
- mThumbnailScale = thumbnailData.scale;
mBitmapShader = new BitmapShader(bm, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
mPaint.setShader(mBitmapShader);
- mThumbnailRect.set(0, 0,
- bm.getWidth() - thumbnailData.insets.left - thumbnailData.insets.right,
- bm.getHeight() - thumbnailData.insets.top - thumbnailData.insets.bottom);
mThumbnailData = thumbnailData;
updateThumbnailMatrix();
} else {
mBitmapShader = null;
mThumbnailData = null;
mPaint.setShader(null);
- mThumbnailRect.setEmpty();
+ mOverlay.reset();
}
updateThumbnailPaintFilter();
}
@@ -126,36 +126,41 @@ public class TaskThumbnailView extends View {
}
private void updateThumbnailMatrix() {
- mThumbnailScale = 1f;
if (mBitmapShader != null && mThumbnailData != null) {
+ float scale = mThumbnailData.scale;
+ float thumbnailWidth = mThumbnailData.thumbnail.getWidth() -
+ (mThumbnailData.insets.left + mThumbnailData.insets.right) * scale;
+ float thumbnailHeight = mThumbnailData.thumbnail.getHeight() -
+ (mThumbnailData.insets.top + mThumbnailData.insets.bottom) * scale;
+ final float thumbnailScale;
+
if (getMeasuredWidth() == 0) {
// If we haven't measured , skip the thumbnail drawing and only draw the background
// color
- mThumbnailScale = 0f;
+ thumbnailScale = 0f;
} else {
- float invThumbnailScale = 1f / mThumbnailScale;
final Configuration configuration =
getContext().getApplicationContext().getResources().getConfiguration();
final DeviceProfile profile = Launcher.getLauncher(getContext()).getDeviceProfile();
if (configuration.orientation == mThumbnailData.orientation) {
// If we are in the same orientation as the screenshot, just scale it to the
// width of the task view
- mThumbnailScale = (float) getMeasuredWidth() / mThumbnailRect.width();
+ thumbnailScale = getMeasuredWidth() / thumbnailWidth;
} else if (configuration.orientation == Configuration.ORIENTATION_PORTRAIT) {
// Scale the landscape thumbnail up to app size, then scale that to the task
// view size to match other portrait screenshots
- mThumbnailScale = invThumbnailScale *
- ((float) getMeasuredWidth() / profile.widthPx);
+ thumbnailScale = ((float) getMeasuredWidth() / profile.widthPx);
} else {
// Otherwise, scale the screenshot to fit 1:1 in the current orientation
- mThumbnailScale = invThumbnailScale;
+ thumbnailScale = 1;
}
}
- mMatrix.setTranslate(-mThumbnailData.insets.left, -mThumbnailData.insets.top);
- mMatrix.postScale(mThumbnailScale, mThumbnailScale);
+ mMatrix.setTranslate(-mThumbnailData.insets.left * scale,
+ -mThumbnailData.insets.top * scale);
+ mMatrix.postScale(thumbnailScale, thumbnailScale);
mBitmapShader.setLocalMatrix(mMatrix);
- float bitmapHeight = Math.max(mThumbnailRect.height() * mThumbnailScale, 0);
+ float bitmapHeight = Math.max(thumbnailHeight * thumbnailScale, 0);
Shader shader = mBitmapShader;
if (bitmapHeight < getMeasuredHeight()) {
int color = mPaint.getColor();
@@ -165,7 +170,7 @@ public class TaskThumbnailView extends View {
shader = new ComposeShader(fade, shader, Mode.DST_OVER);
}
- float bitmapWidth = Math.max(mThumbnailRect.width() * mThumbnailScale, 0);
+ float bitmapWidth = Math.max(thumbnailWidth * thumbnailScale, 0);
if (bitmapWidth < getMeasuredWidth()) {
int color = mPaint.getColor();
LinearGradient fade = new LinearGradient(
@@ -175,6 +180,8 @@ public class TaskThumbnailView extends View {
}
mPaint.setShader(shader);
}
+
+ mOverlay.setTaskInfo(mThumbnailData, mMatrix);
invalidate();
}
diff --git a/quickstep/src/com/android/quickstep/TaskView.java b/quickstep/src/com/android/quickstep/TaskView.java
index 0e999f8e3..46fcc724c 100644
--- a/quickstep/src/com/android/quickstep/TaskView.java
+++ b/quickstep/src/com/android/quickstep/TaskView.java
@@ -36,6 +36,7 @@ import android.widget.ImageView;
import com.android.launcher3.R;
import com.android.quickstep.RecentsView.PageCallbacks;
import com.android.quickstep.RecentsView.ScrollState;
+import com.android.quickstep.TaskOverlayFactory.TaskOverlay;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.recents.model.Task.TaskCallbacks;
import com.android.systemui.shared.recents.model.ThumbnailData;
@@ -113,6 +114,7 @@ public class TaskView extends FrameLayout implements TaskCallbacks, PageCallback
mTask.removeCallback(this);
}
mTask = task;
+ mSnapshotView.bind();
task.addCallback(this);
}
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index fe187038c..509ffa9dc 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -185,6 +185,7 @@ public class TouchInteractionService extends Service {
@Override
public void onDestroy() {
sConnected = false;
+ sQuickScrubEnabled = false;
super.onDestroy();
}
diff --git a/res/layout/all_apps.xml b/res/layout/all_apps.xml
index 8cf32bd0e..2ce6b8cfd 100644
--- a/res/layout/all_apps.xml
+++ b/res/layout/all_apps.xml
@@ -31,48 +31,7 @@
<include layout="@layout/all_apps_fast_scroller" />
- <com.android.launcher3.allapps.FloatingHeaderView
- android:id="@+id/all_apps_header"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingTop="@dimen/all_apps_header_top_padding"
- android:clipToPadding="false"
- android:layout_below="@id/search_container_all_apps" >
-
- <include layout="@layout/predictions_view" android:id="@+id/header_content" />
-
- <com.android.launcher3.allapps.PersonalWorkSlidingTabStrip
- android:id="@+id/tabs"
- android:layout_width="match_parent"
- android:layout_height="@dimen/all_apps_header_tab_height"
- android:layout_marginLeft="@dimen/all_apps_tabs_side_padding"
- android:layout_marginRight="@dimen/all_apps_tabs_side_padding"
- android:layout_below="@id/header_content"
- android:orientation="horizontal">
- <Button
- android:id="@+id/tab_personal"
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:background="?android:attr/selectableItemBackground"
- android:fontFamily="sans-serif-medium"
- android:text="@string/all_apps_personal_tab"
- android:textAllCaps="true"
- android:textColor="@color/all_apps_tab_text"
- android:textSize="14sp"/>
- <Button
- android:id="@+id/tab_work"
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:background="?android:attr/selectableItemBackground"
- android:fontFamily="sans-serif-medium"
- android:text="@string/all_apps_work_tab"
- android:textAllCaps="true"
- android:textColor="@color/all_apps_work_tab_text"
- android:textSize="14sp"/>
- </com.android.launcher3.allapps.PersonalWorkSlidingTabStrip>
- </com.android.launcher3.allapps.FloatingHeaderView>
+ <include layout="@layout/all_apps_floating_header" />
<!-- Note: we are reusing/repurposing a system attribute for search layout, because of a
platform bug, which prevents using custom attributes in <include> tag -->
diff --git a/res/layout/all_apps_floating_header.xml b/res/layout/all_apps_floating_header.xml
new file mode 100644
index 000000000..166725da3
--- /dev/null
+++ b/res/layout/all_apps_floating_header.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<com.android.launcher3.allapps.FloatingHeaderView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/all_apps_header"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/search_container_all_apps"
+ android:clipToPadding="false"
+ android:paddingTop="@dimen/all_apps_header_top_padding"
+ android:orientation="vertical" >
+
+ <com.android.launcher3.allapps.PersonalWorkSlidingTabStrip
+ android:id="@+id/tabs"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/all_apps_header_tab_height"
+ android:layout_marginLeft="@dimen/all_apps_tabs_side_padding"
+ android:layout_marginRight="@dimen/all_apps_tabs_side_padding"
+ android:orientation="horizontal">
+
+ <Button
+ android:id="@+id/tab_personal"
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:background="?android:attr/selectableItemBackground"
+ android:fontFamily="sans-serif-medium"
+ android:text="@string/all_apps_personal_tab"
+ android:textAllCaps="true"
+ android:textColor="@color/all_apps_tab_text"
+ android:textSize="14sp" />
+
+ <Button
+ android:id="@+id/tab_work"
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:background="?android:attr/selectableItemBackground"
+ android:fontFamily="sans-serif-medium"
+ android:text="@string/all_apps_work_tab"
+ android:textAllCaps="true"
+ android:textColor="@color/all_apps_work_tab_text"
+ android:textSize="14sp" />
+ </com.android.launcher3.allapps.PersonalWorkSlidingTabStrip>
+</com.android.launcher3.allapps.FloatingHeaderView>
diff --git a/res/values/config.xml b/res/values/config.xml
index 209620038..3dddac22d 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -92,6 +92,9 @@
<!-- Name of a user event dispatcher class. -->
<string name="user_event_dispatcher_class" translatable="false"></string>
+ <!-- Name of an app transition manager class. -->
+ <string name="app_transition_manager_class" translatable="false"></string>
+
<!-- Name of a color extraction implementation class. -->
<string name="color_extraction_impl_class" translatable="false"></string>
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 164efe54a..5789755ca 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -412,7 +412,7 @@ public class DeviceProfile {
padding.bottom = edgeMarginPx;
padding.left = hotseatBarSidePaddingPx;
padding.right = hotseatBarSidePaddingPx;
- if (mInsets.left > mInsets.right) {
+ if (isSeascape()) {
padding.left += hotseatBarSizePx;
padding.right += pageIndicatorSizePx;
} else {
@@ -480,6 +480,11 @@ public class DeviceProfile {
return isLandscape && transposeLayoutWithOrientation;
}
+ public boolean isSeascape() {
+ // TODO: This might not hold true for multi window mode, use configuration insead.
+ return isVerticalBarLayout() && mInsets.left > mInsets.right;
+ }
+
public boolean shouldFadeAdjacentWorkspaceScreens() {
return isVerticalBarLayout() || isLargeTablet;
}
diff --git a/src/com/android/launcher3/DropTargetBar.java b/src/com/android/launcher3/DropTargetBar.java
index d78043d88..cc6a58f9a 100644
--- a/src/com/android/launcher3/DropTargetBar.java
+++ b/src/com/android/launcher3/DropTargetBar.java
@@ -93,8 +93,8 @@ public class DropTargetBar extends FrameLayout
if (grid.isVerticalBarLayout()) {
lp.width = grid.dropTargetBarSizePx;
lp.height = grid.availableHeightPx - 2 * grid.edgeMarginPx;
- lp.gravity = insets.left > insets.right ? Gravity.RIGHT : Gravity.LEFT;
- tooltipLocation = insets.left > insets.right ? TOOLTIP_LEFT : TOOLTIP_RIGHT;
+ lp.gravity = grid.isSeascape() ? Gravity.RIGHT : Gravity.LEFT;
+ tooltipLocation = grid.isSeascape() ? TOOLTIP_LEFT : TOOLTIP_RIGHT;
} else {
int gap;
if (grid.isTablet) {
diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java
index 25eacb52f..9d2bb070e 100644
--- a/src/com/android/launcher3/Hotseat.java
+++ b/src/com/android/launcher3/Hotseat.java
@@ -164,7 +164,7 @@ public class Hotseat extends FrameLayout implements LogContainerProvider, Insett
mContent.setGridSize(1, grid.inv.numHotseatIcons);
lp.height = ViewGroup.LayoutParams.MATCH_PARENT;
- if (insets.left > insets.right) {
+ if (grid.isSeascape()) {
lp.gravity = Gravity.LEFT;
lp.width = grid.hotseatBarSizePx + insets.left + grid.hotseatBarSidePaddingPx;
getLayout().setPadding(
diff --git a/src/com/android/launcher3/IconCache.java b/src/com/android/launcher3/IconCache.java
index a5ca3eece..957a5e51f 100644
--- a/src/com/android/launcher3/IconCache.java
+++ b/src/com/android/launcher3/IconCache.java
@@ -118,8 +118,7 @@ public class IconCache {
mIconDpi = inv.fillResIconDpi;
mIconDb = new IconDB(context, inv.iconBitmapSize);
- mIconProvider = Utilities.getOverrideObject(
- IconProvider.class, context, R.string.icon_provider_class);
+ mIconProvider = IconProvider.newInstance(context);
mWorkerHandler = new Handler(LauncherModel.getWorkerLooper());
mLowResOptions = new BitmapFactory.Options();
@@ -254,7 +253,7 @@ public class IconCache {
// Remove all active icon update tasks.
mWorkerHandler.removeCallbacksAndMessages(ICON_UPDATE_TOKEN);
- mIconProvider.updateSystemStateString();
+ mIconProvider.updateSystemStateString(mContext);
for (UserHandle user : mUserManager.getUserProfiles()) {
// Query for the set of apps
final List<LauncherActivityInfo> apps = mLauncherApps.getActivityList(null, user);
diff --git a/src/com/android/launcher3/IconProvider.java b/src/com/android/launcher3/IconProvider.java
index 4dee2b57d..b469a8f45 100644
--- a/src/com/android/launcher3/IconProvider.java
+++ b/src/com/android/launcher3/IconProvider.java
@@ -1,5 +1,6 @@
package com.android.launcher3;
+import android.content.Context;
import android.content.pm.LauncherActivityInfo;
import android.graphics.drawable.Drawable;
import android.os.Build;
@@ -8,17 +9,26 @@ import java.util.Locale;
public class IconProvider {
- private static final boolean DBG = false;
- private static final String TAG = "IconProvider";
-
protected String mSystemState;
- public IconProvider() {
- updateSystemStateString();
+ public static IconProvider newInstance(Context context) {
+ IconProvider provider = Utilities.getOverrideObject(
+ IconProvider.class, context, R.string.icon_provider_class);
+ provider.updateSystemStateString(context);
+ return provider;
}
- public void updateSystemStateString() {
- mSystemState = Locale.getDefault().toString() + "," + Build.VERSION.SDK_INT;
+ public IconProvider() { }
+
+ public void updateSystemStateString(Context context) {
+ final String locale;
+ if (Utilities.ATLEAST_NOUGAT) {
+ locale = context.getResources().getConfiguration().getLocales().toLanguageTags();
+ } else {
+ locale = Locale.getDefault().toString();
+ }
+
+ mSystemState = locale + "," + Build.VERSION.SDK_INT;
}
public String getIconSystemState(String packageName) {
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 5db0a3b72..a91907d44 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -214,6 +214,8 @@ public class Launcher extends BaseActivity
private static final int NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS = 5;
@Thunk static final int NEW_APPS_ANIMATION_DELAY = 500;
+ private LauncherAppTransitionManager mAppTransitionManager;
+
@Thunk Workspace mWorkspace;
private View mLauncherView;
@Thunk DragLayer mDragLayer;
@@ -403,8 +405,11 @@ public class Launcher extends BaseActivity
getSystemUiController().updateUiState(SystemUiController.UI_STATE_BASE_WINDOW,
Themes.getAttrBoolean(this, R.attr.isWorkspaceDarkText));
+ mAppTransitionManager = Utilities.getOverrideObject(LauncherAppTransitionManager.class,
+ this, R.string.app_transition_manager_class);
+
if (!isInMultiWindowModeCompat()) {
- UiFactory.registerRemoteAnimations(this);
+ mAppTransitionManager.registerRemoteAnimations();
}
if (mLauncherCallbacks != null) {
@@ -1918,38 +1923,11 @@ public class Launcher extends BaseActivity
}
}
- public Bundle getDefaultActivityLaunchOptions(View v) {
- if (Utilities.ATLEAST_MARSHMALLOW) {
- int left = 0, top = 0;
- int width = v.getMeasuredWidth(), height = v.getMeasuredHeight();
- if (v instanceof BubbleTextView) {
- // Launch from center of icon, not entire view
- Drawable icon = ((BubbleTextView) v).getIcon();
- if (icon != null) {
- Rect bounds = icon.getBounds();
- left = (width - bounds.width()) / 2;
- top = v.getPaddingTop();
- width = bounds.width();
- height = bounds.height();
- }
- }
- return ActivityOptions.makeClipRevealAnimation(v, left, top, width, height)
- .toBundle();
- } else if (Utilities.ATLEAST_LOLLIPOP_MR1) {
- // On L devices, we use the device default slide-up transition.
- // On L MR1 devices, we use a custom version of the slide-up transition which
- // doesn't have the delay present in the device default.
- return ActivityOptions.makeCustomAnimation(
- this, R.anim.task_open_enter, R.anim.no_anim).toBundle();
- }
- return null;
- }
-
@TargetApi(Build.VERSION_CODES.M)
public Bundle getActivityLaunchOptions(View v, boolean useDefaultLaunchOptions) {
return useDefaultLaunchOptions
- ? getDefaultActivityLaunchOptions(v)
- : UiFactory.getActivityLaunchOptions(this, v);
+ ? mAppTransitionManager.getDefaultActivityLaunchOptions(this, v)
+ : mAppTransitionManager.getActivityLaunchOptions(this, v);
}
public Rect getViewBounds(View v) {
diff --git a/src/com/android/launcher3/LauncherAppTransitionManager.java b/src/com/android/launcher3/LauncherAppTransitionManager.java
new file mode 100644
index 000000000..9d68dc9e8
--- /dev/null
+++ b/src/com/android/launcher3/LauncherAppTransitionManager.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3;
+
+
+import android.app.ActivityOptions;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.view.View;
+
+/**
+ * Manages the opening and closing app transitions from Launcher.
+ */
+public class LauncherAppTransitionManager {
+
+ public Bundle getDefaultActivityLaunchOptions(Launcher launcher, View v) {
+ if (Utilities.ATLEAST_MARSHMALLOW) {
+ int left = 0, top = 0;
+ int width = v.getMeasuredWidth(), height = v.getMeasuredHeight();
+ if (v instanceof BubbleTextView) {
+ // Launch from center of icon, not entire view
+ Drawable icon = ((BubbleTextView) v).getIcon();
+ if (icon != null) {
+ Rect bounds = icon.getBounds();
+ left = (width - bounds.width()) / 2;
+ top = v.getPaddingTop();
+ width = bounds.width();
+ height = bounds.height();
+ }
+ }
+ return ActivityOptions.makeClipRevealAnimation(v, left, top, width, height)
+ .toBundle();
+ } else if (Utilities.ATLEAST_LOLLIPOP_MR1) {
+ // On L devices, we use the device default slide-up transition.
+ // On L MR1 devices, we use a custom version of the slide-up transition which
+ // doesn't have the delay present in the device default.
+ return ActivityOptions.makeCustomAnimation(launcher, R.anim.task_open_enter,
+ R.anim.no_anim).toBundle();
+ }
+ return null;
+ }
+
+ public Bundle getActivityLaunchOptions(Launcher launcher, View v) {
+ return getDefaultActivityLaunchOptions(launcher, v);
+ }
+
+ public void registerRemoteAnimations() {
+ }
+}
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index 2e544ecef..dc3de18d5 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -55,13 +55,11 @@ import com.android.launcher3.dragndrop.DragController;
import com.android.launcher3.dragndrop.DragOptions;
import com.android.launcher3.keyboard.FocusedItemDecorator;
import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
-import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.ComponentKeyMapper;
import com.android.launcher3.util.ItemInfoMatcher;
import com.android.launcher3.util.PackageUserKey;
import com.android.launcher3.views.BottomUserEducationView;
-import java.util.HashMap;
import java.util.List;
import java.util.Set;
@@ -76,6 +74,7 @@ public class AllAppsContainerView extends RelativeLayout implements DragSource,
private final ClickShadowView mTouchFeedbackView;
private final ItemInfoMatcher mPersonalMatcher = ItemInfoMatcher.ofUser(Process.myUserHandle());
private final ItemInfoMatcher mWorkMatcher = ItemInfoMatcher.not(mPersonalMatcher);
+ private final AllAppsStore mAllAppsStore = new AllAppsStore();
private SearchUiManager mSearchUiManager;
private View mSearchContainer;
@@ -92,8 +91,6 @@ public class AllAppsContainerView extends RelativeLayout implements DragSource,
private boolean mHasPredictions = false;
private boolean mSearchModeWhileUsingTabs = false;
- private final HashMap<ComponentKey, AppInfo> mComponentToAppMap = new HashMap<>();
-
public AllAppsContainerView(Context context) {
this(context, null);
}
@@ -132,6 +129,10 @@ public class AllAppsContainerView extends RelativeLayout implements DragSource,
// TODO: Reimplement once fast scroller is fixed.
}
+ public AllAppsStore getAppsStore() {
+ return mAllAppsStore;
+ }
+
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
@@ -149,64 +150,29 @@ public class AllAppsContainerView extends RelativeLayout implements DragSource,
public void setApps(List<AppInfo> apps) {
boolean hasWorkProfileApp = hasWorkProfileApp(apps);
rebindAdapters(hasWorkProfileApp);
- mComponentToAppMap.clear();
- addOrUpdateApps(apps);
+ mAllAppsStore.setApps(apps);
}
/**
* Adds or updates existing apps in the list
*/
public void addOrUpdateApps(List<AppInfo> apps) {
- for (AppInfo app : apps) {
- mComponentToAppMap.put(app.toComponentKey(), app);
- }
- onAppsUpdated();
- mSearchUiManager.refreshSearchResult();
- mHeader.onAppsUpdated();
+ mAllAppsStore.addOrUpdateApps(apps);
}
/**
* Removes some apps from the list.
*/
public void removeApps(List<AppInfo> apps) {
- for (AppInfo app : apps) {
- mComponentToAppMap.remove(app.toComponentKey());
- }
- onAppsUpdated();
- mSearchUiManager.refreshSearchResult();
- }
-
- private void onAppsUpdated() {
- for (int i = 0; i < getNumOfAdapters(); i++) {
- mAH[i].appsList.onAppsUpdated();
- }
- }
-
- private int getNumOfAdapters() {
- return mUsingTabs ? mAH.length : 1;
+ mAllAppsStore.removeApps(apps);
}
public void updatePromiseAppProgress(PromiseAppInfo app) {
- for (int i = 0; i < mAH.length; i++) {
- updatePromiseAppProgress(app, mAH[i].recyclerView);
- }
- if (isHeaderVisible()) {
- updatePromiseAppProgress(app, mHeader.getPredictionRow());
- }
- }
-
- private void updatePromiseAppProgress(PromiseAppInfo app, ViewGroup parent) {
- if (parent == null) {
- return;
- }
- int childCount = parent.getChildCount();
- for (int i = 0; i < childCount; i++) {
- View child = parent.getChildAt(i);
- if (child instanceof BubbleTextView && child.getTag() == app) {
- BubbleTextView bubbleTextView = (BubbleTextView) child;
- bubbleTextView.applyProgressLevel(app.level);
+ mAllAppsStore.updateAllIcons((child) -> {
+ if (child.getTag() == app) {
+ child.applyProgressLevel(app.level);
}
- }
+ });
}
/**
@@ -358,34 +324,15 @@ public class AllAppsContainerView extends RelativeLayout implements DragSource,
}
public void updateIconBadges(Set<PackageUserKey> updatedBadges) {
- final PackageUserKey packageUserKey = new PackageUserKey(null, null);
- for (int j = 0; j < mAH.length; j++) {
- updateIconBadges(updatedBadges, packageUserKey, mAH[j].recyclerView);
- }
- if (mHeader != null) {
- updateIconBadges(updatedBadges, packageUserKey, mHeader.getPredictionRow());
- }
- }
-
- private void updateIconBadges(Set<PackageUserKey> updatedBadges, PackageUserKey packageUserKey,
- ViewGroup parent) {
- if (parent == null) {
- return;
- }
- final int n = parent.getChildCount();
- for (int i = 0; i < n; i++) {
- View child = parent.getChildAt(i);
- if (child instanceof PredictionRowView) {
- updateIconBadges(updatedBadges, packageUserKey, (PredictionRowView) child);
- }
- if (!(child instanceof BubbleTextView) || !(child.getTag() instanceof ItemInfo)) {
- continue;
- }
- ItemInfo info = (ItemInfo) child.getTag();
- if (packageUserKey.updateFromItemInfo(info) && updatedBadges.contains(packageUserKey)) {
- ((BubbleTextView) child).applyBadgeState(info, true /* animate */);
+ PackageUserKey tempKey = new PackageUserKey(null, null);
+ mAllAppsStore.updateAllIcons((child) -> {
+ if (child.getTag() instanceof ItemInfo) {
+ ItemInfo info = (ItemInfo) child.getTag();
+ if (tempKey.updateFromItemInfo(info) && updatedBadges.contains(tempKey)) {
+ child.applyBadgeState(info, true /* animate */);
+ }
}
- }
+ });
}
public SpringAnimationHandler getSpringAnimationHandler() {
@@ -403,6 +350,9 @@ public class AllAppsContainerView extends RelativeLayout implements DragSource,
replaceRVContainer(showTabs);
mUsingTabs = showTabs;
+ mAllAppsStore.unregisterIconContainer(mAH[AdapterHolder.MAIN].recyclerView);
+ mAllAppsStore.unregisterIconContainer(mAH[AdapterHolder.WORK].recyclerView);
+
if (mUsingTabs) {
mAH[AdapterHolder.MAIN].setup(mViewPager.getChildAt(0), mPersonalMatcher);
mAH[AdapterHolder.WORK].setup(mViewPager.getChildAt(1), mWorkMatcher);
@@ -419,6 +369,9 @@ public class AllAppsContainerView extends RelativeLayout implements DragSource,
}
}
+ mAllAppsStore.registerIconContainer(mAH[AdapterHolder.MAIN].recyclerView);
+ mAllAppsStore.registerIconContainer(mAH[AdapterHolder.WORK].recyclerView);
+
applyTouchDelegate();
}
@@ -492,9 +445,6 @@ public class AllAppsContainerView extends RelativeLayout implements DragSource,
}
public void setPredictedApps(List<ComponentKeyMapper<AppInfo>> apps) {
- if (isHeaderVisible()) {
- mHeader.getPredictionRow().setPredictedApps(apps);
- }
mAH[AdapterHolder.MAIN].appsList.setPredictedApps(apps);
boolean hasPredictions = !apps.isEmpty();
if (mHasPredictions != hasPredictions) {
@@ -506,7 +456,7 @@ public class AllAppsContainerView extends RelativeLayout implements DragSource,
}
public AppInfo findApp(ComponentKeyMapper<AppInfo> mapper) {
- return mapper.getItem(mComponentToAppMap);
+ return mAllAppsStore.getApp(mapper);
}
public AlphabeticalAppsList getApps() {
@@ -526,9 +476,9 @@ public class AllAppsContainerView extends RelativeLayout implements DragSource,
return;
}
mHeader.setVisibility(View.VISIBLE);
- mHeader.setup(mAH, mComponentToAppMap, mNumPredictedAppsPerRow);
+ mHeader.setup(mAH, mAH[AllAppsContainerView.AdapterHolder.WORK].recyclerView == null);
- int padding = mHeader.getPredictionRow().getExpectedHeight();
+ int padding = mHeader.getMaxTranslation();
if (mHasPredictions && !mUsingTabs) {
padding += mHeader.getPaddingTop() + mHeader.getPaddingBottom();
}
@@ -582,14 +532,6 @@ public class AllAppsContainerView extends RelativeLayout implements DragSource,
}
}
- public List<AppInfo> getPredictedApps() {
- if (isHeaderVisible()) {
- return mHeader.getPredictionRow().getPredictedApps();
- } else {
- return mAH[AdapterHolder.MAIN].appsList.getPredictedApps();
- }
- }
-
public boolean isHeaderVisible() {
return mHeader != null && mHeader.getVisibility() == View.VISIBLE;
}
@@ -604,7 +546,7 @@ public class AllAppsContainerView extends RelativeLayout implements DragSource,
public static final int MAIN = 0;
public static final int WORK = 1;
- final AllAppsGridAdapter adapter;
+ public final AllAppsGridAdapter adapter;
final LinearLayoutManager layoutManager;
final SpringAnimationHandler animationHandler;
final AlphabeticalAppsList appsList;
@@ -614,7 +556,7 @@ public class AllAppsContainerView extends RelativeLayout implements DragSource,
boolean verticalFadingEdge;
AdapterHolder(boolean isWork) {
- appsList = new AlphabeticalAppsList(mLauncher, mComponentToAppMap, isWork);
+ appsList = new AlphabeticalAppsList(mLauncher, mAllAppsStore, isWork);
adapter = new AllAppsGridAdapter(mLauncher, appsList, mLauncher,
AllAppsContainerView.this, true);
appsList.setAdapter(adapter);
@@ -649,11 +591,6 @@ public class AllAppsContainerView extends RelativeLayout implements DragSource,
? paddingTopForTabs : padding.top;
recyclerView.setPadding(padding.left, paddingTop, padding.right, padding.bottom);
}
- if (isHeaderVisible()) {
- PredictionRowView prv = mHeader.getPredictionRow();
- prv.setPadding(padding.left, prv.getPaddingTop() , padding.right,
- prv.getPaddingBottom());
- }
}
void applyNumsPerRow() {
@@ -663,10 +600,6 @@ public class AllAppsContainerView extends RelativeLayout implements DragSource,
}
adapter.setNumAppsPerRow(mNumAppsPerRow);
appsList.setNumAppsPerRow(mNumAppsPerRow, mNumPredictedAppsPerRow);
- if (isHeaderVisible()) {
- mHeader.getPredictionRow()
- .setNumAppsPerRow(mNumPredictedAppsPerRow);
- }
}
}
diff --git a/src/com/android/launcher3/allapps/AllAppsStore.java b/src/com/android/launcher3/allapps/AllAppsStore.java
new file mode 100644
index 000000000..17f1c8910
--- /dev/null
+++ b/src/com/android/launcher3/allapps/AllAppsStore.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2018 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.allapps;
+
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.android.launcher3.AppInfo;
+import com.android.launcher3.BubbleTextView;
+import com.android.launcher3.util.ComponentKey;
+import com.android.launcher3.util.ComponentKeyMapper;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * A utility class to maintain the collection of all apps.
+ */
+public class AllAppsStore {
+
+ private final HashMap<ComponentKey, AppInfo> mComponentToAppMap = new HashMap<>();
+ private final List<OnUpdateListener> mUpdateListeners = new ArrayList<>();
+ private final ArrayList<ViewGroup> mIconContainers = new ArrayList<>();
+
+ public Collection<AppInfo> getApps() {
+ return mComponentToAppMap.values();
+ }
+
+ /**
+ * Sets the current set of apps.
+ */
+ public void setApps(List<AppInfo> apps) {
+ mComponentToAppMap.clear();
+ addOrUpdateApps(apps);
+ }
+
+ public AppInfo getApp(ComponentKey key) {
+ return mComponentToAppMap.get(key);
+ }
+
+ public AppInfo getApp(ComponentKeyMapper<AppInfo> mapper) {
+ return mapper.getItem(mComponentToAppMap);
+ }
+
+ /**
+ * Adds or updates existing apps in the list
+ */
+ public void addOrUpdateApps(List<AppInfo> apps) {
+ for (AppInfo app : apps) {
+ mComponentToAppMap.put(app.toComponentKey(), app);
+ }
+ notifyUpdate();
+ }
+
+ /**
+ * Removes some apps from the list.
+ */
+ public void removeApps(List<AppInfo> apps) {
+ for (AppInfo app : apps) {
+ mComponentToAppMap.remove(app.toComponentKey());
+ }
+ notifyUpdate();
+ }
+
+
+ private void notifyUpdate() {
+ int count = mUpdateListeners.size();
+ for (int i = 0; i < count; i++) {
+ mUpdateListeners.get(i).onAppsUpdated();
+ }
+ }
+
+ public void addUpdateListener(OnUpdateListener listener) {
+ mUpdateListeners.add(listener);
+ }
+
+ public void removeUpdateListener(OnUpdateListener listener) {
+ mUpdateListeners.remove(listener);
+ }
+
+ public void registerIconContainer(ViewGroup container) {
+ if (container != null) {
+ mIconContainers.add(container);
+ }
+ }
+
+ public void unregisterIconContainer(ViewGroup container) {
+ mIconContainers.remove(container);
+ }
+
+ public void updateAllIcons(IconAction action) {
+ for (int i = mIconContainers.size() - 1; i >= 0; i--) {
+ ViewGroup parent = mIconContainers.get(i);
+ int childCount = parent.getChildCount();
+
+ for (int j = 0; j < childCount; j++) {
+ View child = parent.getChildAt(j);
+ if (child instanceof BubbleTextView) {
+ action.apply((BubbleTextView) child);
+ }
+ }
+ }
+ }
+
+ public interface OnUpdateListener {
+ void onAppsUpdated();
+ }
+
+ public interface IconAction {
+ void apply(BubbleTextView icon);
+ }
+}
diff --git a/src/com/android/launcher3/allapps/AlphabeticalAppsList.java b/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
index 76828deb6..29b32b06c 100644
--- a/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
+++ b/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
@@ -44,7 +44,7 @@ import java.util.TreeMap;
/**
* The alphabetically sorted list of applications.
*/
-public class AlphabeticalAppsList {
+public class AlphabeticalAppsList implements AllAppsStore.OnUpdateListener {
public static final String TAG = "AlphabeticalAppsList";
private static final boolean DEBUG = false;
@@ -153,7 +153,7 @@ public class AlphabeticalAppsList {
// The set of apps from the system not including predictions
private final List<AppInfo> mApps = new ArrayList<>();
- private final HashMap<ComponentKey, AppInfo> mComponentToAppMap;
+ private final AllAppsStore mAllAppsStore;
// The set of filtered apps with the current filter
private final List<AppInfo> mFilteredApps = new ArrayList<>();
@@ -179,16 +179,13 @@ public class AlphabeticalAppsList {
private int mNumAppRowsInAdapter;
private ItemInfoMatcher mItemFilter;
- public AlphabeticalAppsList(
- Context context,
- HashMap<ComponentKey,
- AppInfo> componentToAppMap,
- boolean isWork) {
- mComponentToAppMap = componentToAppMap;
+ public AlphabeticalAppsList(Context context, AllAppsStore appsStore, boolean isWork) {
+ mAllAppsStore = appsStore;
mLauncher = Launcher.getLauncher(context);
mIndexer = new AlphabeticIndexCompat(context);
mAppNameComparator = new AppInfoComparator(context);
mIsWork = isWork;
+ mAllAppsStore.addUpdateListener(this);
}
public void updateItemFilter(ItemInfoMatcher itemFilter) {
@@ -283,14 +280,14 @@ public class AlphabeticalAppsList {
}
private List<AppInfo> processPredictedAppComponents(List<ComponentKeyMapper<AppInfo>> components) {
- if (mComponentToAppMap.isEmpty()) {
+ if (mAllAppsStore.getApps().isEmpty()) {
// Apps have not been bound yet.
return Collections.emptyList();
}
List<AppInfo> predictedApps = new ArrayList<>();
for (ComponentKeyMapper<AppInfo> mapper : components) {
- AppInfo info = mapper.getItem(mComponentToAppMap);
+ AppInfo info = mAllAppsStore.getApp(mapper);
if (info != null) {
predictedApps.add(info);
} else {
@@ -359,11 +356,12 @@ public class AlphabeticalAppsList {
/**
* Updates internals when the set of apps are updated.
*/
- void onAppsUpdated() {
+ @Override
+ public void onAppsUpdated() {
// Sort the list of apps
mApps.clear();
- for (AppInfo app : mComponentToAppMap.values()) {
+ for (AppInfo app : mAllAppsStore.getApps()) {
if (mItemFilter == null || mItemFilter.matches(app, null) || hasFilter()) {
mApps.add(app);
}
@@ -580,7 +578,7 @@ public class AlphabeticalAppsList {
}
ArrayList<AppInfo> result = new ArrayList<>();
for (ComponentKey key : mSearchResults) {
- AppInfo match = mComponentToAppMap.get(key);
+ AppInfo match = mAllAppsStore.getApp(key);
if (match != null) {
result.add(match);
}
diff --git a/src/com/android/launcher3/allapps/FloatingHeaderView.java b/src/com/android/launcher3/allapps/FloatingHeaderView.java
index 23917683f..d8a9f6364 100644
--- a/src/com/android/launcher3/allapps/FloatingHeaderView.java
+++ b/src/com/android/launcher3/allapps/FloatingHeaderView.java
@@ -15,7 +15,6 @@
*/
package com.android.launcher3.allapps;
-
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Point;
@@ -27,18 +26,14 @@ import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.LinearLayout;
import android.widget.RelativeLayout;
-import com.android.launcher3.AppInfo;
import com.android.launcher3.R;
-import com.android.launcher3.util.ComponentKey;
-
-import java.util.HashMap;
-public class FloatingHeaderView extends RelativeLayout implements
+public class FloatingHeaderView extends LinearLayout implements
ValueAnimator.AnimatorUpdateListener {
-
private final Rect mClip = new Rect(0, 0, Integer.MAX_VALUE, Integer.MAX_VALUE);
private final ValueAnimator mAnimator = ValueAnimator.ofInt(0, 0);
private final Point mTempOffset = new Point();
@@ -63,19 +58,18 @@ public class FloatingHeaderView extends RelativeLayout implements
}
};
- private PredictionRowView mPredictionRow;
private ViewGroup mTabLayout;
private AllAppsRecyclerView mMainRV;
private AllAppsRecyclerView mWorkRV;
private AllAppsRecyclerView mCurrentRV;
private ViewGroup mParent;
- private boolean mTabsHidden;
private boolean mHeaderCollapsed;
- private int mMaxTranslation;
private int mSnappedScrolledY;
private int mTranslationY;
private boolean mForwardToRecyclerView;
+ protected int mMaxTranslation;
+
public FloatingHeaderView(@NonNull Context context) {
this(context, null);
}
@@ -88,17 +82,10 @@ public class FloatingHeaderView extends RelativeLayout implements
protected void onFinishInflate() {
super.onFinishInflate();
mTabLayout = findViewById(R.id.tabs);
- mPredictionRow = findViewById(R.id.header_content);
}
- public void setup(AllAppsContainerView.AdapterHolder[] mAH,
- HashMap<ComponentKey, AppInfo> componentToAppMap, int numPredictedAppsPerRow) {
- mTabsHidden = mAH[AllAppsContainerView.AdapterHolder.WORK].recyclerView == null;
- mTabLayout.setVisibility(mTabsHidden ? View.GONE : View.VISIBLE);
- mPredictionRow.setup(mAH[AllAppsContainerView.AdapterHolder.MAIN].adapter,
- componentToAppMap, numPredictedAppsPerRow);
- mPredictionRow.setShowDivider(mTabsHidden);
- mMaxTranslation = mPredictionRow.getExpectedHeight();
+ public void setup(AllAppsContainerView.AdapterHolder[] mAH, boolean tabsHidden) {
+ mTabLayout.setVisibility(tabsHidden ? View.GONE : View.VISIBLE);
mMainRV = setupRV(mMainRV, mAH[AllAppsContainerView.AdapterHolder.MAIN].recyclerView);
mWorkRV = setupRV(mWorkRV, mAH[AllAppsContainerView.AdapterHolder.WORK].recyclerView);
mParent = (ViewGroup) mMainRV.getParent();
@@ -117,12 +104,12 @@ public class FloatingHeaderView extends RelativeLayout implements
mCurrentRV = active ? mMainRV : mWorkRV;
}
- public PredictionRowView getPredictionRow() {
- return mPredictionRow;
+ public int getMaxTranslation() {
+ return mMaxTranslation;
}
private boolean canSnapAt(int currentScrollY) {
- return Math.abs(currentScrollY) <= mPredictionRow.getHeight();
+ return Math.abs(currentScrollY) <= mMaxTranslation;
}
private void moved(final int currentScrollY) {
@@ -149,16 +136,12 @@ public class FloatingHeaderView extends RelativeLayout implements
}
}
- private void apply() {
+ protected void applyScroll(int uncappedY, int currentY) { }
+
+ protected void apply() {
int uncappedTranslationY = mTranslationY;
mTranslationY = Math.max(mTranslationY, -mMaxTranslation);
- if (mTranslationY != uncappedTranslationY) {
- // we hide it completely if already capped (for opening search anim)
- mPredictionRow.setVisibility(View.INVISIBLE);
- } else {
- mPredictionRow.setVisibility(View.VISIBLE);
- mPredictionRow.setTranslationY(uncappedTranslationY);
- }
+ applyScroll(uncappedTranslationY, mTranslationY);
mTabLayout.setTranslationY(mTranslationY);
mClip.top = mMaxTranslation + mTranslationY;
// clipping on a draw might cause additional redraw
@@ -218,10 +201,6 @@ public class FloatingHeaderView extends RelativeLayout implements
p.x = getLeft() - mCurrentRV.getLeft() - mParent.getLeft();
p.y = getTop() - mCurrentRV.getTop() - mParent.getTop();
}
-
- public void onAppsUpdated() {
- mPredictionRow.onAppsUpdated();
- }
}
diff --git a/src/com/android/launcher3/allapps/PredictionRowView.java b/src/com/android/launcher3/allapps/PredictionRowView.java
deleted file mode 100644
index 267ef3c4f..000000000
--- a/src/com/android/launcher3/allapps/PredictionRowView.java
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3.allapps;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.View;
-import android.widget.LinearLayout;
-
-import com.android.launcher3.AppInfo;
-import com.android.launcher3.BubbleTextView;
-import com.android.launcher3.ItemInfo;
-import com.android.launcher3.Launcher;
-import com.android.launcher3.R;
-import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.logging.UserEventDispatcher;
-import com.android.launcher3.userevent.nano.LauncherLogProto;
-import com.android.launcher3.util.ComponentKey;
-import com.android.launcher3.util.ComponentKeyMapper;
-import com.android.launcher3.util.Themes;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-
-public class PredictionRowView extends LinearLayout implements
- UserEventDispatcher.LogContainerProvider {
-
- private static final String TAG = "PredictionRowView";
-
- private HashMap<ComponentKey, AppInfo> mComponentToAppMap;
- private int mNumPredictedAppsPerRow;
- // The set of predicted app component names
- private final List<ComponentKeyMapper<AppInfo>> mPredictedAppComponents = new ArrayList<>();
- // The set of predicted apps resolved from the component names and the current set of apps
- private final ArrayList<AppInfo> mPredictedApps = new ArrayList<>();
- private final Paint mPaint;
- // This adapter is only used to create an identical item w/ same behavior as in the all apps RV
- private AllAppsGridAdapter mAdapter;
- private boolean mShowDivider;
-
- public PredictionRowView(@NonNull Context context) {
- this(context, null);
- }
-
- public PredictionRowView(@NonNull Context context, @Nullable AttributeSet attrs) {
- super(context, attrs);
- setOrientation(LinearLayout.HORIZONTAL);
- setWillNotDraw(false);
- mPaint = new Paint();
- mPaint.setColor(Themes.getAttrColor(context, android.R.attr.colorControlHighlight));
- mPaint.setStrokeWidth(getResources().getDimensionPixelSize(R.dimen.all_apps_divider_height));
- }
-
- public void setup(AllAppsGridAdapter adapter, HashMap<ComponentKey, AppInfo> componentToAppMap,
- int numPredictedAppsPerRow) {
- mAdapter = adapter;
- mComponentToAppMap = componentToAppMap;
- mNumPredictedAppsPerRow = numPredictedAppsPerRow;
- setVisibility(mPredictedAppComponents.isEmpty() ? View.GONE : View.VISIBLE);
- }
-
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(getExpectedHeight(),
- MeasureSpec.EXACTLY));
- }
-
- public int getExpectedHeight() {
- int height = 0;
- if (!mPredictedAppComponents.isEmpty()) {
- height += Launcher.getLauncher(getContext())
- .getDeviceProfile().allAppsCellHeightPx;
- height += getPaddingTop() + getPaddingBottom();
- }
- return height;
- }
-
- public void setShowDivider(boolean showDivider) {
- mShowDivider = showDivider;
- int paddingBottom = showDivider ? getResources()
- .getDimensionPixelSize(R.dimen.all_apps_prediction_row_divider_height) : 0;
- setPadding(getPaddingLeft(), getPaddingTop(), getPaddingRight(), paddingBottom);
- }
-
- /**
- * Sets the number of apps per row.
- */
- public void setNumAppsPerRow(int numPredictedAppsPerRow) {
- if (mNumPredictedAppsPerRow != numPredictedAppsPerRow) {
- mNumPredictedAppsPerRow = numPredictedAppsPerRow;
- onPredictionsUpdated();
- }
- }
-
- /**
- * Returns the predicted apps.
- */
- public List<AppInfo> getPredictedApps() {
- return mPredictedApps;
- }
-
- /**
- * Sets the current set of predicted apps.
- *
- * This can be called before we get the full set of applications, we should merge the results
- * only in onPredictionsUpdated() which is idempotent.
- *
- * If the number of predicted apps is the same as the previous list of predicted apps,
- * we can optimize by swapping them in place.
- */
- public void setPredictedApps(List<ComponentKeyMapper<AppInfo>> apps) {
- mPredictedAppComponents.clear();
- mPredictedAppComponents.addAll(apps);
- mPredictedApps.clear();
- mPredictedApps.addAll(processPredictedAppComponents(mPredictedAppComponents));
- onPredictionsUpdated();
- }
-
- private void onPredictionsUpdated() {
- int childCountBefore = getChildCount();
- if (getChildCount() != mNumPredictedAppsPerRow) {
- while (getChildCount() > mNumPredictedAppsPerRow) {
- removeViewAt(0);
- }
- while (getChildCount() < mNumPredictedAppsPerRow) {
- AllAppsGridAdapter.ViewHolder holder = mAdapter
- .onCreateViewHolder(this, AllAppsGridAdapter.VIEW_TYPE_ICON);
- BubbleTextView icon = (BubbleTextView) holder.itemView;
- LinearLayout.LayoutParams params =
- new LayoutParams(0, icon.getLayoutParams().height);
- params.weight = 1;
- icon.setLayoutParams(params);
- addView(icon);
- }
- }
-
- for (int i = 0; i < getChildCount(); i++) {
- BubbleTextView icon = (BubbleTextView) getChildAt(i);
- icon.reset();
- if (mPredictedApps.size() > i) {
- icon.setVisibility(View.VISIBLE);
- icon.applyFromApplicationInfo(mPredictedApps.get(i));
- } else {
- icon.setVisibility(View.INVISIBLE);
- }
- }
-
- if (getChildCount() > 0 && childCountBefore == 0
- || getChildCount() == 0 && childCountBefore > 0) {
- // setting up header to adjust the height
- // only necessary if childcount switches from/to 0
- Launcher.getLauncher(getContext()).getAppsView().setupHeader();
- }
- }
-
- /**
- * Refreshes the app icons in the row view, while preserving the same set of predictions.
- */
- public void onAppsUpdated() {
- for (int i = 0; i < getChildCount(); i++) {
- View child = getChildAt(i);
- if (!(child instanceof BubbleTextView)) {
- continue;
- }
- if (i >= mPredictedApps.size()) {
- break;
- }
- BubbleTextView icon = (BubbleTextView) getChildAt(i);
- icon.reset();
- icon.applyFromApplicationInfo(mPredictedApps.get(i));
- }
- }
-
- private List<AppInfo> processPredictedAppComponents(
- List<ComponentKeyMapper<AppInfo>> components) {
- if (mComponentToAppMap.isEmpty()) {
- // Apps have not been bound yet.
- return Collections.emptyList();
- }
-
- List<AppInfo> predictedApps = new ArrayList<>();
- for (ComponentKeyMapper<AppInfo> mapper : components) {
- AppInfo info = mapper.getItem(mComponentToAppMap);
- if (info != null) {
- predictedApps.add(info);
- } else {
- if (FeatureFlags.IS_DOGFOOD_BUILD) {
- Log.e(TAG, "Predicted app not found: " + mapper);
- }
- }
- // Stop at the number of predicted apps
- if (predictedApps.size() == mNumPredictedAppsPerRow) {
- break;
- }
- }
- return predictedApps;
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
-
- if (mShowDivider) {
- int side = getResources().getDimensionPixelSize(R.dimen.dynamic_grid_edge_margin);
- int y = getHeight() - (getPaddingBottom() / 2);
- int x1 = getPaddingLeft() + side;
- int x2 = getWidth() - getPaddingRight() - side;
- canvas.drawLine(x1, y, x2, y, mPaint);
- }
- }
-
- @Override
- public void fillInLogContainerData(View v, ItemInfo info, LauncherLogProto.Target target,
- LauncherLogProto.Target targetParent) {
- for (int i = 0; i < mPredictedApps.size(); i++) {
- AppInfo appInfo = mPredictedApps.get(i);
- if (appInfo == info) {
- targetParent.containerType = LauncherLogProto.ContainerType.PREDICTION;
- target.predictedRank = i;
- break;
- }
- }
- }
-}
diff --git a/src/com/android/launcher3/allapps/SearchUiManager.java b/src/com/android/launcher3/allapps/SearchUiManager.java
index f562b6aa0..bb17ed5e2 100644
--- a/src/com/android/launcher3/allapps/SearchUiManager.java
+++ b/src/com/android/launcher3/allapps/SearchUiManager.java
@@ -35,12 +35,6 @@ public interface SearchUiManager {
@NonNull SpringAnimation getSpringForFling();
/**
- * Notifies the search manager that the apps-list has changed and the search UI should be
- * updated accordingly.
- */
- void refreshSearchResult();
-
- /**
* Notifies the search manager to close any active search session.
*/
void reset();
diff --git a/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java b/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java
index 6f07eebc6..a56c8b816 100644
--- a/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java
+++ b/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java
@@ -21,7 +21,6 @@ import android.support.animation.FloatValueHolder;
import android.support.animation.SpringAnimation;
import android.support.animation.SpringForce;
import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
import android.text.Selection;
import android.text.Spannable;
import android.text.SpannableString;
@@ -37,6 +36,7 @@ import com.android.launcher3.ExtendedEditText;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.allapps.AllAppsContainerView;
+import com.android.launcher3.allapps.AllAppsStore;
import com.android.launcher3.allapps.AlphabeticalAppsList;
import com.android.launcher3.allapps.SearchUiManager;
import com.android.launcher3.graphics.TintedDrawableSpan;
@@ -48,7 +48,8 @@ import java.util.ArrayList;
* Layout to contain the All-apps search UI.
*/
public class AppsSearchContainerLayout extends FrameLayout
- implements SearchUiManager, AllAppsSearchBarController.Callbacks {
+ implements SearchUiManager, AllAppsSearchBarController.Callbacks,
+ AllAppsStore.OnUpdateListener {
private final Launcher mLauncher;
private final int mMinHeight;
@@ -111,9 +112,22 @@ public class AppsSearchContainerLayout extends FrameLayout
}
@Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ mLauncher.getAppsView().getAppsStore().addUpdateListener(this);
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ mLauncher.getAppsView().getAppsStore().removeUpdateListener(this);
+ }
+
+ @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- if (!mLauncher.getDeviceProfile().isVerticalBarLayout()) {
- getLayoutParams().height = mLauncher.getDragLayer().getInsets().top + mMinHeight;
+ DeviceProfile dp = mLauncher.getDeviceProfile();
+ if (!dp.isVerticalBarLayout()) {
+ getLayoutParams().height = dp.getInsets().top + mMinHeight;
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@@ -134,7 +148,7 @@ public class AppsSearchContainerLayout extends FrameLayout
}
@Override
- public void refreshSearchResult() {
+ public void onAppsUpdated() {
mSearchBarController.refreshSearchResult();
}
@@ -198,7 +212,7 @@ public class AppsSearchContainerLayout extends FrameLayout
int oldLeft, int oldTop, int oldRight, int oldBottom) {
DeviceProfile dp = mLauncher.getDeviceProfile();
if (!dp.isVerticalBarLayout()) {
- Rect insets = mLauncher.getDragLayer().getInsets();
+ Rect insets = dp.getInsets();
int hotseatBottom = bottom - dp.hotseatBarBottomPaddingPx - insets.bottom;
int searchTopMargin = insets.top + (mMinHeight - mSearchBoxHeight)
+ ((MarginLayoutParams) getLayoutParams()).bottomMargin;
diff --git a/src/com/android/launcher3/dragndrop/DragLayer.java b/src/com/android/launcher3/dragndrop/DragLayer.java
index 677694f74..a32f6b1dc 100644
--- a/src/com/android/launcher3/dragndrop/DragLayer.java
+++ b/src/com/android/launcher3/dragndrop/DragLayer.java
@@ -52,7 +52,6 @@ import com.android.launcher3.folder.Folder;
import com.android.launcher3.folder.FolderIcon;
import com.android.launcher3.keyboard.ViewGroupFocusHelper;
import com.android.launcher3.uioverrides.UiFactory;
-import com.android.launcher3.util.Themes;
import com.android.launcher3.util.Thunk;
import com.android.launcher3.util.TouchController;
diff --git a/src/com/android/launcher3/graphics/GradientView.java b/src/com/android/launcher3/graphics/GradientView.java
index bacb06323..6253e1807 100644
--- a/src/com/android/launcher3/graphics/GradientView.java
+++ b/src/com/android/launcher3/graphics/GradientView.java
@@ -75,7 +75,7 @@ public class GradientView extends View implements WallpaperColorInfo.OnChangeLis
this.mMaskHeight = Utilities.pxFromDp(ALPHA_MASK_HEIGHT_DP, dm);
this.mMaskWidth = Utilities.pxFromDp(ALPHA_MASK_WIDTH_DP, dm);
Launcher launcher = Launcher.getLauncher(context);
- this.mAlphaStart = launcher.getDeviceProfile().isVerticalBarLayout() ? 0 : 100;
+ this.mAlphaStart = 0;
this.mScrimColor = Themes.getAttrColor(context, R.attr.allAppsScrimColor);
this.mWallpaperColorInfo = WallpaperColorInfo.getInstance(launcher);
mAlphaColors = getResources().getInteger(R.integer.extracted_color_gradient_alpha);
diff --git a/src/com/android/launcher3/pageindicators/WorkspacePageIndicator.java b/src/com/android/launcher3/pageindicators/WorkspacePageIndicator.java
index f3b0d6126..3e4bd3100 100644
--- a/src/com/android/launcher3/pageindicators/WorkspacePageIndicator.java
+++ b/src/com/android/launcher3/pageindicators/WorkspacePageIndicator.java
@@ -22,6 +22,7 @@ import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewConfiguration;
+import android.view.accessibility.AccessibilityManager;
import android.widget.FrameLayout;
import com.android.launcher3.DeviceProfile;
@@ -55,6 +56,7 @@ public class WorkspacePageIndicator extends PageIndicator implements Insettable,
private final Handler mDelayedLineFadeHandler = new Handler(Looper.getMainLooper());
private final Launcher mLauncher;
+ private final AccessibilityManager mAccessibilityManager;
private boolean mShouldAutoHide = true;
@@ -136,6 +138,8 @@ public class WorkspacePageIndicator extends PageIndicator implements Insettable,
boolean darkText = WallpaperColorInfo.getInstance(context).supportsDarkText();
mActiveAlpha = darkText ? BLACK_ALPHA : WHITE_ALPHA;
mLinePaint.setColor(darkText ? Color.BLACK : Color.WHITE);
+ mAccessibilityManager = (AccessibilityManager)
+ getContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
}
@Override
@@ -249,7 +253,7 @@ public class WorkspacePageIndicator extends PageIndicator implements Insettable,
FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams();
if (mIsLandscapeUi) {
- if (insets.left > insets.right) {
+ if (grid.isSeascape()) {
lp.leftMargin = grid.hotseatBarSidePaddingPx;
lp.rightMargin = insets.right;
lp.gravity = Gravity.RIGHT | Gravity.BOTTOM;
@@ -274,7 +278,7 @@ public class WorkspacePageIndicator extends PageIndicator implements Insettable,
setBackgroundResource(0);
setOnFocusChangeListener(null);
- setOnClickListener(null);
+ setOnClickListener(mAccessibilityManager.isTouchExplorationEnabled() ? this : null);
}
setLayoutParams(lp);
diff --git a/src/com/android/launcher3/util/ComponentKeyMapper.java b/src/com/android/launcher3/util/ComponentKeyMapper.java
index 916176ac4..a7f0d764e 100644
--- a/src/com/android/launcher3/util/ComponentKeyMapper.java
+++ b/src/com/android/launcher3/util/ComponentKeyMapper.java
@@ -18,8 +18,6 @@ package com.android.launcher3.util;
import android.support.annotation.Nullable;
-import java.util.ArrayList;
-import java.util.List;
import java.util.Map;
public class ComponentKeyMapper<T> {
diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java b/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java
index c857bf6a0..744125e15 100644
--- a/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java
+++ b/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java
@@ -61,10 +61,4 @@ public class UiFactory {
}
public static void resetOverview(Launcher launcher) { }
-
- public static Bundle getActivityLaunchOptions(Launcher launcher, View v) {
- return launcher.getDefaultActivityLaunchOptions(v);
- }
-
- public static void registerRemoteAnimations(Launcher launcher) { }
}