Removing arrow indicator from homescreen and
adding a separate view for various accessibility actions
Bug: 159247871
Change-Id: I14536844929e03d36a6a5f294d4f5daad8c82d15
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index f87138e..beb2a6a 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -215,10 +215,8 @@
switch (state.ordinal) {
case HINT_STATE_ORDINAL: {
Workspace workspace = getWorkspace();
- boolean willMoveScreens = workspace.getNextPage() != Workspace.DEFAULT_PAGE;
- getStateManager().goToState(NORMAL, true,
- willMoveScreens ? null : getScrimView()::startDragHandleEducationAnim);
- if (willMoveScreens) {
+ getStateManager().goToState(NORMAL);
+ if (workspace.getNextPage() != Workspace.DEFAULT_PAGE) {
workspace.post(workspace::moveToDefaultScreen);
}
break;
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java
index 0a4cec7..f31bc19 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -38,11 +38,9 @@
import com.android.launcher3.BaseQuickstepLauncher;
import com.android.launcher3.Hotseat;
import com.android.launcher3.LauncherState;
-import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.statehandlers.DepthController;
import com.android.launcher3.statemanager.StateManager.StateListener;
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
-import com.android.launcher3.views.ScrimView;
import com.android.quickstep.LauncherActivityInterface;
import com.android.quickstep.SysUINavigationMode;
import com.android.systemui.plugins.PluginListener;
@@ -126,12 +124,6 @@
}
anim.play(ObjectAnimator.ofFloat(
mActivity.getAllAppsController(), ALL_APPS_PROGRESS, allAppsProgressOffscreen));
-
- ObjectAnimator dragHandleAnim = ObjectAnimator.ofInt(
- mActivity.getScrimView(), ScrimView.DRAG_HANDLE_ALPHA, 0);
- dragHandleAnim.setInterpolator(Interpolators.ACCEL_2);
- anim.play(dragHandleAnim);
-
return anim;
}
diff --git a/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java b/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java
index 9ed2bbe..c2e67c1 100644
--- a/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java
+++ b/quickstep/src/com/android/quickstep/util/QuickstepOnboardingPrefs.java
@@ -87,20 +87,6 @@
});
}
- if (!hasReachedMaxCount(ALL_APPS_COUNT)) {
- stateManager.addStateListener(new StateListener<LauncherState>() {
- @Override
- public void onStateTransitionComplete(LauncherState finalState) {
- if (finalState == ALL_APPS) {
- if (incrementEventCount(ALL_APPS_COUNT)) {
- stateManager.removeStateListener(this);
- mLauncher.getScrimView().updateDragHandleVisibility();
- }
- }
- }
- });
- }
-
if (FeatureFlags.ENABLE_HYBRID_HOTSEAT.get() && !hasReachedMaxCount(
HOTSEAT_DISCOVERY_TIP_COUNT)) {
stateManager.addStateListener(new StateListener<LauncherState>() {
diff --git a/quickstep/src/com/android/quickstep/views/ShelfScrimView.java b/quickstep/src/com/android/quickstep/views/ShelfScrimView.java
index 19e278b..f1ac6a5 100644
--- a/quickstep/src/com/android/quickstep/views/ShelfScrimView.java
+++ b/quickstep/src/com/android/quickstep/views/ShelfScrimView.java
@@ -44,7 +44,6 @@
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.uioverrides.states.OverviewState;
-import com.android.launcher3.util.OnboardingPrefs;
import com.android.launcher3.util.Themes;
import com.android.launcher3.views.ScrimView;
import com.android.quickstep.SysUINavigationMode;
@@ -77,15 +76,11 @@
private final float mRadius;
private final int mMaxScrimAlpha;
private final Paint mPaint;
- private final OnboardingPrefs mOnboardingPrefs;
// Mid point where the alpha changes
private int mMidAlpha;
private float mMidProgress;
- // The progress at which the drag handle starts moving up with the shelf.
- private float mDragHandleProgress;
-
private Interpolator mBeforeMidProgressColorInterpolator = ACCEL;
private Interpolator mAfterMidProgressColorInterpolator = ACCEL;
@@ -103,7 +98,6 @@
private boolean mRemainingScreenPathValid = false;
private Mode mSysUINavigationMode;
- private boolean mIsTwoZoneSwipeModel;
public ShelfScrimView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -112,7 +106,6 @@
mEndAlpha = Color.alpha(mEndScrim);
mRadius = BOTTOM_CORNER_RADIUS_RATIO * Themes.getDialogCornerRadius(context);
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
- mOnboardingPrefs = mLauncher.getOnboardingPrefs();
// Just assume the easiest UI for now, until we have the proper layout information.
mDrawingFlatColor = true;
@@ -145,11 +138,9 @@
// Show the shelf more quickly before reaching overview progress.
mBeforeMidProgressColorInterpolator = ACCEL_2;
mAfterMidProgressColorInterpolator = ACCEL;
- mIsTwoZoneSwipeModel = FeatureFlags.ENABLE_OVERVIEW_ACTIONS.get();
} else {
mBeforeMidProgressColorInterpolator = ACCEL;
mAfterMidProgressColorInterpolator = Interpolators.clampToProgress(ACCEL, 0.5f, 1f);
- mIsTwoZoneSwipeModel = false;
}
}
@@ -164,7 +155,6 @@
Context context = getContext();
if ((OVERVIEW.getVisibleElements(mLauncher) & ALL_APPS_HEADER_EXTRA) == 0) {
- mDragHandleProgress = 1;
if (FeatureFlags.ENABLE_OVERVIEW_ACTIONS.get()
&& SysUINavigationMode.removeShelfFromOverview(context)) {
// Fade in all apps background quickly to distinguish from swiping from nav bar.
@@ -182,29 +172,22 @@
+ hotseatPadding.bottom + hotseatPadding.top;
float dragHandleTop =
Math.min(hotseatSize, LayoutUtils.getDefaultSwipeHeight(context, dp));
- mDragHandleProgress = 1 - (dragHandleTop / mShiftRange);
}
- mTopOffset = dp.getInsets().top - mDragHandleSize.y;
+ mTopOffset = dp.getInsets().top;
mShelfTopAtThreshold = mShiftRange * SCRIM_CATCHUP_THRESHOLD + mTopOffset;
}
updateColors();
updateSysUiColors();
- updateDragHandleAlpha();
invalidate();
}
@Override
public void updateColors() {
super.updateColors();
- mDragHandleOffset = 0;
if (mDrawingFlatColor) {
return;
}
- if (mProgress < mDragHandleProgress) {
- mDragHandleOffset = mShiftRange * (mDragHandleProgress - mProgress);
- }
-
if (mProgress >= SCRIM_CATCHUP_THRESHOLD) {
mShelfTop = mShiftRange * mProgress + mTopOffset;
} else {
@@ -259,19 +242,7 @@
}
@Override
- protected boolean shouldDragHandleBeVisible() {
- boolean needsAllAppsEdu = mIsTwoZoneSwipeModel
- && !mOnboardingPrefs.hasReachedMaxCount(OnboardingPrefs.ALL_APPS_COUNT);
- return needsAllAppsEdu || super.shouldDragHandleBeVisible();
- }
-
- @Override
protected void onDraw(Canvas canvas) {
- drawBackground(canvas);
- drawDragHandle(canvas);
- }
-
- private void drawBackground(Canvas canvas) {
if (mDrawingFlatColor) {
if (mCurrentFlatColor != 0) {
canvas.drawColor(mCurrentFlatColor);
@@ -311,9 +282,4 @@
mPaint.setColor(mShelfColor);
canvas.drawRoundRect(0, mShelfTop, width, height + mRadius, mRadius, mRadius, mPaint);
}
-
- @Override
- public float getVisualTop() {
- return mShelfTop;
- }
}
diff --git a/res/drawable-v24/drag_handle_indicator_shadow.xml b/res/drawable-v24/drag_handle_indicator_shadow.xml
deleted file mode 100644
index 774bc38..0000000
--- a/res/drawable-v24/drag_handle_indicator_shadow.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2020 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<com.android.launcher3.graphics.ShadowDrawable
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:src="@drawable/drag_handle_indicator_no_shadow"
- android:elevation="@dimen/vertical_drag_handle_elevation" />
diff --git a/res/drawable/drag_handle_indicator_no_shadow.xml b/res/drawable/drag_handle_indicator_no_shadow.xml
deleted file mode 100644
index 341e60c..0000000
--- a/res/drawable/drag_handle_indicator_no_shadow.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2020 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="@dimen/vertical_drag_handle_width"
- android:height="@dimen/vertical_drag_handle_height"
- android:viewportWidth="18.0"
- android:viewportHeight="6.0"
- android:tint="?attr/workspaceTextColor" >
-
- <path
- android:pathData="M17,6c-0.15,0-0.3-0.03-0.45-0.11L9,2.12L1.45,5.89c-0.5,0.25-1.09,
- 0.05-1.34-0.45S0.06,4.35,0.55,4.11l8-4c0.28-0.14,0.61-0.14,0.89,0l8,4c0.49,0.25,0.69,
- 0.85,0.45,1.34C17.72,5.8,17.37,6,17,6z"
- android:fillColor="@android:color/white" />
-</vector>
diff --git a/res/layout/launcher.xml b/res/layout/launcher.xml
index a137908..0c18c8a 100644
--- a/res/layout/launcher.xml
+++ b/res/layout/launcher.xml
@@ -28,6 +28,12 @@
android:clipToPadding="false"
android:importantForAccessibility="no">
+ <com.android.launcher3.views.AccessibilityActionsView
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:contentDescription="@string/home_screen"
+ />
+
<!-- The workspace contains 5 screens of cells -->
<!-- DO NOT CHANGE THE ID -->
<com.android.launcher3.Workspace
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 969765f..f59f02f 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -40,14 +40,6 @@
<dimen name="workspace_page_indicator_line_height">1dp</dimen>
<dimen name="workspace_page_indicator_overlap_workspace">0dp</dimen>
- <!-- Hotseat/all-apps scrim -->
- <dimen name="all_apps_scrim_blur">4dp</dimen>
- <dimen name="vertical_drag_handle_width">18dp</dimen>
- <dimen name="vertical_drag_handle_height">6dp</dimen>
- <dimen name="vertical_drag_handle_elevation">1dp</dimen>
- <dimen name="vertical_drag_handle_touch_size">48dp</dimen>
- <dimen name="vertical_drag_handle_padding_in_vertical_bar_layout">16dp</dimen>
-
<!-- Drop target bar -->
<dimen name="dynamic_grid_drop_target_size">48dp</dimen>
<dimen name="drop_target_vertical_gap">20dp</dimen>
diff --git a/res/values/drawables.xml b/res/values/drawables.xml
index 7d63142..9c57ec1 100644
--- a/res/values/drawables.xml
+++ b/res/values/drawables.xml
@@ -18,5 +18,4 @@
<drawable name="ic_remove_shadow">@drawable/ic_remove_no_shadow</drawable>
<drawable name="ic_uninstall_shadow">@drawable/ic_uninstall_no_shadow</drawable>
<drawable name="ic_block_shadow">@drawable/ic_block_no_shadow</drawable>
- <drawable name="all_apps_arrow_shadow">@drawable/drag_handle_indicator_no_shadow</drawable>
</resources>
\ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 80b511a..12beeeb 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -36,7 +36,7 @@
<!-- Message shown when a shortcut is not available. It could have been temporarily disabled and may start working again after some time. -->
<string name="shortcut_not_available">Shortcut isn\'t available</string>
<!-- User visible name for the launcher/home screen. [CHAR_LIMIT=30] -->
- <string name="home_screen">Home screen</string>
+ <string name="home_screen">Home</string>
<!-- Label for showing custom action list of a shortcut or widget. [CHAR_LIMIT=30] -->
<string name="custom_actions">Custom actions</string>
@@ -88,10 +88,6 @@
<string name="all_apps_button_personal_label">Personal apps list</string>
<string name="all_apps_button_work_label">Work apps list</string>
- <!-- Label for button in all applications label to go back home (to the workspace / desktop)
- for accessibilty (spoken when the button gets focus). -->
- <string name="all_apps_home_button_label">Home</string>
-
<!-- Label for remove drop target (from the homescreen only).
May appear next to uninstall_drop_target_label [CHAR_LIMIT=20] -->
<string name="remove_drop_target_label">Remove</string>
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index e49c455..f9fba6f 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -453,10 +453,10 @@
mAppsView.getAlphaProperty(APPS_VIEW_ALPHA_CHANNEL_INDEX).setValue(alpha);
} else if (finalState == OVERVIEW || finalState == OVERVIEW_PEEK) {
mAppsView.getAlphaProperty(APPS_VIEW_ALPHA_CHANNEL_INDEX).setValue(alpha);
- mScrimView.getAlphaProperty(SCRIM_VIEW_ALPHA_CHANNEL_INDEX).setValue(alpha);
+ mScrimView.setAlpha(alpha);
} else {
mAppsView.getAlphaProperty(APPS_VIEW_ALPHA_CHANNEL_INDEX).setValue(1f);
- mScrimView.getAlphaProperty(SCRIM_VIEW_ALPHA_CHANNEL_INDEX).setValue(1f);
+ mScrimView.setAlpha(1f);
}
}
});
@@ -553,7 +553,7 @@
mAppsView.getAlphaProperty(APPS_VIEW_ALPHA_CHANNEL_INDEX).setValue(alpha);
} else if (state == OVERVIEW || state == OVERVIEW_PEEK) {
mAppsView.getAlphaProperty(APPS_VIEW_ALPHA_CHANNEL_INDEX).setValue(alpha);
- mScrimView.getAlphaProperty(SCRIM_VIEW_ALPHA_CHANNEL_INDEX).setValue(alpha);
+ mScrimView.setAlpha(alpha);
}
}
@@ -1936,7 +1936,7 @@
// Populate event with a fake title based on the current state.
// TODO: When can workspace be null?
text.add(mWorkspace == null
- ? getString(R.string.all_apps_home_button_label)
+ ? getString(R.string.home_screen)
: mStateManager.getState().getDescription(this));
return result;
}
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 15e0daa..3be9ac7 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -3263,7 +3263,7 @@
}
if (nScreens == 0) {
// When the workspace is not loaded, we do not know how many screen will be bound.
- return getContext().getString(R.string.all_apps_home_button_label);
+ return getContext().getString(R.string.home_screen);
}
return getContext().getString(R.string.workspace_scroll_format, page + 1, nScreens);
}
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index 5b00631..1224cb0 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -19,7 +19,6 @@
import static com.android.launcher3.LauncherState.ALL_APPS_HEADER_EXTRA;
import static com.android.launcher3.LauncherState.APPS_VIEW_ITEM_MASK;
import static com.android.launcher3.LauncherState.OVERVIEW;
-import static com.android.launcher3.LauncherState.VERTICAL_SWIPE_INDICATOR;
import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
import static com.android.launcher3.anim.Interpolators.FINAL_FRAME;
import static com.android.launcher3.anim.Interpolators.INSTANT;
@@ -222,9 +221,6 @@
mAppsView.getSearchUiManager().setContentVisibility(visibleElements, setter, allAppsFade);
- setter.setInt(mScrimView, ScrimView.DRAG_HANDLE_ALPHA,
- (visibleElements & VERTICAL_SWIPE_INDICATOR) != 0 ? 255 : 0, allAppsFade);
-
// Set visibility of the container at the very beginning or end of the transition.
setter.setViewAlpha(mAppsView, hasAnyVisibleItem ? 1 : 0,
hasAnyVisibleItem ? INSTANT : FINAL_FRAME);
diff --git a/src/com/android/launcher3/util/OnboardingPrefs.java b/src/com/android/launcher3/util/OnboardingPrefs.java
index 26313e5..6e5e7d9 100644
--- a/src/com/android/launcher3/util/OnboardingPrefs.java
+++ b/src/com/android/launcher3/util/OnboardingPrefs.java
@@ -36,7 +36,6 @@
public static final String SHELF_BOUNCE_SEEN = "launcher.shelf_bounce_seen";
public static final String HOME_BOUNCE_COUNT = "launcher.home_bounce_count";
public static final String SHELF_BOUNCE_COUNT = "launcher.shelf_bounce_count";
- public static final String ALL_APPS_COUNT = "launcher.all_apps_count";
public static final String HOTSEAT_DISCOVERY_TIP_COUNT = "launcher.hotseat_discovery_tip_count";
public static final String HOTSEAT_LONGPRESS_TIP_SEEN = "launcher.hotseat_longpress_tip_seen";
@@ -56,7 +55,6 @@
@StringDef(value = {
HOME_BOUNCE_COUNT,
SHELF_BOUNCE_COUNT,
- ALL_APPS_COUNT,
HOTSEAT_DISCOVERY_TIP_COUNT
})
@Retention(RetentionPolicy.SOURCE)
@@ -67,7 +65,6 @@
Map<String, Integer> maxCounts = new ArrayMap<>(4);
maxCounts.put(HOME_BOUNCE_COUNT, 3);
maxCounts.put(SHELF_BOUNCE_COUNT, 3);
- maxCounts.put(ALL_APPS_COUNT, 5);
maxCounts.put(HOTSEAT_DISCOVERY_TIP_COUNT, 5);
MAX_COUNTS = Collections.unmodifiableMap(maxCounts);
}
diff --git a/src/com/android/launcher3/views/AccessibilityActionsView.java b/src/com/android/launcher3/views/AccessibilityActionsView.java
new file mode 100644
index 0000000..0eacaa3
--- /dev/null
+++ b/src/com/android/launcher3/views/AccessibilityActionsView.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3.views;
+
+import static com.android.launcher3.LauncherState.ALL_APPS;
+import static com.android.launcher3.LauncherState.NORMAL;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
+
+import androidx.annotation.Nullable;
+
+import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherState;
+import com.android.launcher3.R;
+import com.android.launcher3.statemanager.StateManager.StateListener;
+import com.android.launcher3.views.OptionsPopupView.OptionItem;
+
+/**
+ * Placeholder view to expose additional Launcher actions via accessibility actions
+ */
+public class AccessibilityActionsView extends View implements StateListener<LauncherState> {
+
+ public AccessibilityActionsView(Context context) {
+ this(context, null);
+ }
+
+ public AccessibilityActionsView(Context context, @Nullable AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public AccessibilityActionsView(Context context, @Nullable AttributeSet attrs,
+ int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ Launcher.getLauncher(context).getStateManager().addStateListener(this);
+ setWillNotDraw(true);
+ }
+
+ @Override
+ public void onStateTransitionComplete(LauncherState finalState) {
+ setImportantForAccessibility(finalState == NORMAL
+ ? IMPORTANT_FOR_ACCESSIBILITY_YES : IMPORTANT_FOR_ACCESSIBILITY_NO);
+ }
+
+ @Override
+ public AccessibilityNodeInfo createAccessibilityNodeInfo() {
+ AccessibilityNodeInfo info = super.createAccessibilityNodeInfo();
+ Launcher l = Launcher.getLauncher(getContext());
+ info.addAction(new AccessibilityAction(
+ R.string.all_apps_button_label, l.getText(R.string.all_apps_button_label)));
+ for (OptionItem item : OptionsPopupView.getOptions(l)) {
+ info.addAction(new AccessibilityAction(item.labelRes, l.getText(item.labelRes)));
+ }
+ return info;
+ }
+
+ @Override
+ public boolean performAccessibilityAction(int action, Bundle arguments) {
+ if (super.performAccessibilityAction(action, arguments)) {
+ return true;
+ }
+ Launcher l = Launcher.getLauncher(getContext());
+ if (action == R.string.all_apps_button_label) {
+ l.getStateManager().goToState(ALL_APPS);
+ return true;
+ }
+ for (OptionItem item : OptionsPopupView.getOptions(l)) {
+ if (item.labelRes == action) {
+ if (item.eventId.getId() > 0) {
+ l.getStatsLogManager().logger().log(item.eventId);
+ }
+ if (item.clickListener.onLongClick(this)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+}
diff --git a/src/com/android/launcher3/views/OptionsPopupView.java b/src/com/android/launcher3/views/OptionsPopupView.java
index 049a1ac..e95dc5b 100644
--- a/src/com/android/launcher3/views/OptionsPopupView.java
+++ b/src/com/android/launcher3/views/OptionsPopupView.java
@@ -85,10 +85,10 @@
if (item == null) {
return false;
}
- if (item.mEventId.getId() > 0) {
- mLauncher.getStatsLogManager().logger().log(item.mEventId);
+ if (item.eventId.getId() > 0) {
+ mLauncher.getStatsLogManager().logger().log(item.eventId);
}
- if (item.mClickListener.onLongClick(view)) {
+ if (item.clickListener.onLongClick(view)) {
close(true);
return true;
}
@@ -130,8 +130,8 @@
for (OptionItem item : items) {
DeepShortcutView view =
(DeepShortcutView) popup.inflateAndAdd(R.layout.system_shortcut, popup);
- view.getIconView().setBackgroundResource(item.mIconRes);
- view.getBubbleText().setText(item.mLabelRes);
+ view.getIconView().setBackgroundResource(item.iconRes);
+ view.getBubbleText().setText(item.labelRes);
view.setDividerVisibility(View.INVISIBLE);
view.setOnClickListener(popup);
view.setOnLongClickListener(popup);
@@ -152,7 +152,13 @@
y = launcher.getDragLayer().getHeight() / 2;
}
RectF target = new RectF(x - halfSize, y - halfSize, x + halfSize, y + halfSize);
+ show(launcher, target, getOptions(launcher));
+ }
+ /**
+ * Returns the list of supported actions
+ */
+ public static ArrayList<OptionItem> getOptions(Launcher launcher) {
ArrayList<OptionItem> options = new ArrayList<>();
int resString = Utilities.existsStyleWallpapers(launcher) ?
R.string.styles_wallpaper_button_text : R.string.wallpaper_button_text;
@@ -170,10 +176,10 @@
LAUNCHER_SETTINGS_BUTTON_TAP_OR_LONGPRESS,
OptionsPopupView::startSettings));
- show(launcher, target, options);
+ return options;
}
- public static boolean onWidgetsClicked(View view) {
+ private static boolean onWidgetsClicked(View view) {
return openWidgets(Launcher.getLauncher(view.getContext())) != null;
}
@@ -188,7 +194,7 @@
}
}
- public static boolean startSettings(View view) {
+ private static boolean startSettings(View view) {
TestLogging.recordEvent(TestProtocol.SEQUENCE_MAIN, "start: startSettings");
Launcher launcher = Launcher.getLauncher(view.getContext());
launcher.startActivity(new Intent(Intent.ACTION_APPLICATION_PREFERENCES)
@@ -201,7 +207,7 @@
* Event handler for the wallpaper picker button that appears after a long press
* on the home screen.
*/
- public static boolean startWallpaperPicker(View v) {
+ private static boolean startWallpaperPicker(View v) {
Launcher launcher = Launcher.getLauncher(v.getContext());
if (!Utilities.isWallpaperAllowed(launcher)) {
Toast.makeText(launcher, R.string.msg_disabled_by_admin, Toast.LENGTH_SHORT).show();
@@ -233,17 +239,17 @@
public static class OptionItem {
- private final int mLabelRes;
- private final int mIconRes;
- private final EventEnum mEventId;
- private final OnLongClickListener mClickListener;
+ public final int labelRes;
+ public final int iconRes;
+ public final EventEnum eventId;
+ public final OnLongClickListener clickListener;
public OptionItem(int labelRes, int iconRes, EventEnum eventId,
OnLongClickListener clickListener) {
- mLabelRes = labelRes;
- mIconRes = iconRes;
- mEventId = eventId;
- mClickListener = clickListener;
+ this.labelRes = labelRes;
+ this.iconRes = iconRes;
+ this.eventId = eventId;
+ this.clickListener = clickListener;
}
}
}
diff --git a/src/com/android/launcher3/views/ScrimView.java b/src/com/android/launcher3/views/ScrimView.java
index 22faf97..7f0765b 100644
--- a/src/com/android/launcher3/views/ScrimView.java
+++ b/src/com/android/launcher3/views/ScrimView.java
@@ -15,119 +15,37 @@
*/
package com.android.launcher3.views;
-import static android.content.Context.ACCESSIBILITY_SERVICE;
-import static android.view.MotionEvent.ACTION_DOWN;
-
import static androidx.core.graphics.ColorUtils.compositeColors;
-import static com.android.launcher3.LauncherState.ALL_APPS;
-import static com.android.launcher3.LauncherState.NORMAL;
-import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL;
-import static com.android.launcher3.anim.Interpolators.DEACCEL;
-import static com.android.launcher3.anim.Interpolators.LINEAR;
-import static com.android.launcher3.anim.Interpolators.clampToProgress;
import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
import static com.android.launcher3.util.SystemUiController.UI_STATE_SCRIM_VIEW;
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.Keyframe;
-import android.animation.ObjectAnimator;
-import android.animation.PropertyValuesHolder;
-import android.animation.RectEvaluator;
import android.content.Context;
-import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
-import android.graphics.Point;
import android.graphics.Rect;
-import android.graphics.RectF;
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
import android.util.AttributeSet;
-import android.util.IntProperty;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
import android.view.View;
-import android.view.accessibility.AccessibilityManager;
-import android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
import androidx.core.graphics.ColorUtils;
-import androidx.core.view.ViewCompat;
-import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
-import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat;
-import androidx.customview.widget.ExploreByTouchHelper;
-import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Insettable;
import com.android.launcher3.Launcher;
-import com.android.launcher3.LauncherState;
import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
-import com.android.launcher3.statemanager.StateManager;
-import com.android.launcher3.statemanager.StateManager.StateListener;
import com.android.launcher3.uioverrides.WallpaperColorInfo;
import com.android.launcher3.uioverrides.WallpaperColorInfo.OnChangeListener;
-import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
-import com.android.launcher3.userevent.nano.LauncherLogProto.ControlType;
-import com.android.launcher3.util.MultiValueAlpha;
-import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
import com.android.launcher3.util.Themes;
-import com.android.launcher3.widget.WidgetsFullSheet;
-
-import java.util.List;
/**
* Simple scrim which draws a flat color
*/
-public class ScrimView<T extends Launcher> extends View implements Insettable, OnChangeListener,
- AccessibilityStateChangeListener {
-
- public static final IntProperty<ScrimView> DRAG_HANDLE_ALPHA =
- new IntProperty<ScrimView>("dragHandleAlpha") {
-
- @Override
- public Integer get(ScrimView scrimView) {
- return scrimView.mDragHandleAlpha;
- }
-
- @Override
- public void setValue(ScrimView scrimView, int value) {
- scrimView.setDragHandleAlpha(value);
- }
- };
- private static final int WALLPAPERS = R.string.wallpaper_button_text;
- private static final int WIDGETS = R.string.widget_button_text;
- private static final int SETTINGS = R.string.settings_button_text;
- private static final int ALPHA_CHANNEL_COUNT = 1;
-
- private static final long DRAG_HANDLE_BOUNCE_DURATION_MS = 300;
- // How much to delay before repeating the bounce.
- private static final long DRAG_HANDLE_BOUNCE_DELAY_MS = 200;
- // Repeat this many times (i.e. total number of bounces is 1 + this).
- private static final int DRAG_HANDLE_BOUNCE_REPEAT_COUNT = 2;
-
- private final Rect mTempRect = new Rect();
- private final int[] mTempPos = new int[2];
+public class ScrimView<T extends Launcher> extends View implements Insettable, OnChangeListener {
protected final T mLauncher;
private final WallpaperColorInfo mWallpaperColorInfo;
- private final AccessibilityManager mAM;
protected final int mEndScrim;
protected final boolean mIsScrimDark;
- private final StateListener<LauncherState> mAccessibilityLauncherStateListener =
- new StateListener<LauncherState>() {
- @Override
- public void onStateTransitionComplete(LauncherState finalState) {
- setImportantForAccessibility(finalState == ALL_APPS
- ? IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
- : IMPORTANT_FOR_ACCESSIBILITY_AUTO);
- }
- };
-
protected float mMaxScrimAlpha;
protected float mProgress = 1;
@@ -137,22 +55,6 @@
protected int mEndFlatColor;
protected int mEndFlatColorAlpha;
- protected final Point mDragHandleSize;
- private final int mDragHandleTouchSize;
- private final int mDragHandlePaddingInVerticalBarLayout;
- protected float mDragHandleOffset;
- private final Rect mDragHandleBounds;
- private final RectF mHitRect = new RectF();
- private ObjectAnimator mDragHandleAnim;
-
- private final MultiValueAlpha mMultiValueAlpha;
-
- private final AccessibilityHelper mAccessibilityHelper;
- @Nullable
- protected Drawable mDragHandle;
-
- private int mDragHandleAlpha = 255;
-
public ScrimView(Context context, AttributeSet attrs) {
super(context, attrs);
mLauncher = Launcher.cast(Launcher.getLauncher(context));
@@ -161,59 +63,24 @@
mIsScrimDark = ColorUtils.calculateLuminance(mEndScrim) < 0.5f;
mMaxScrimAlpha = 0.7f;
-
- Resources res = context.getResources();
- mDragHandleSize = new Point(res.getDimensionPixelSize(R.dimen.vertical_drag_handle_width),
- res.getDimensionPixelSize(R.dimen.vertical_drag_handle_height));
- mDragHandleBounds = new Rect(0, 0, mDragHandleSize.x, mDragHandleSize.y);
- mDragHandleTouchSize = res.getDimensionPixelSize(R.dimen.vertical_drag_handle_touch_size);
- mDragHandlePaddingInVerticalBarLayout = context.getResources()
- .getDimensionPixelSize(R.dimen.vertical_drag_handle_padding_in_vertical_bar_layout);
-
- mAccessibilityHelper = createAccessibilityHelper();
- ViewCompat.setAccessibilityDelegate(this, mAccessibilityHelper);
-
- mAM = (AccessibilityManager) context.getSystemService(ACCESSIBILITY_SERVICE);
setFocusable(false);
- mMultiValueAlpha = new MultiValueAlpha(this, ALPHA_CHANNEL_COUNT);
- }
-
- public AlphaProperty getAlphaProperty(int index) {
- return mMultiValueAlpha.getProperty(index);
- }
-
- @NonNull
- protected AccessibilityHelper createAccessibilityHelper() {
- return new AccessibilityHelper();
}
@Override
- public void setInsets(Rect insets) {
- updateDragHandleBounds();
- updateDragHandleVisibility();
- }
+ public void setInsets(Rect insets) { }
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- updateDragHandleBounds();
- }
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
mWallpaperColorInfo.addOnChangeListener(this);
onExtractedColorsChanged(mWallpaperColorInfo);
-
- mAM.addAccessibilityStateChangeListener(this);
- onAccessibilityStateChanged(mAM.isEnabled());
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
mWallpaperColorInfo.removeOnChangeListener(this);
- mAM.removeAccessibilityStateChangeListener(this);
}
@Override
@@ -234,10 +101,8 @@
public void setProgress(float progress) {
if (mProgress != progress) {
mProgress = progress;
- stopDragHandleEducationAnim();
updateColors();
updateSysUiColors();
- updateDragHandleAlpha();
invalidate();
}
}
@@ -260,286 +125,10 @@
}
}
- protected void updateDragHandleAlpha() {
- if (mDragHandle != null) {
- mDragHandle.setAlpha(mDragHandleAlpha);
- }
- }
-
- private void setDragHandleAlpha(int alpha) {
- if (alpha != mDragHandleAlpha) {
- mDragHandleAlpha = alpha;
- if (mDragHandle != null) {
- mDragHandle.setAlpha(mDragHandleAlpha);
- invalidate();
- }
- }
- }
-
@Override
protected void onDraw(Canvas canvas) {
if (mCurrentFlatColor != 0) {
canvas.drawColor(mCurrentFlatColor);
}
- drawDragHandle(canvas);
- }
-
- protected void drawDragHandle(Canvas canvas) {
- if (mDragHandle != null) {
- canvas.translate(0, -mDragHandleOffset);
- mDragHandle.draw(canvas);
- canvas.translate(0, mDragHandleOffset);
- }
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- boolean superHandledTouch = super.onTouchEvent(event);
- if (event.getAction() == ACTION_DOWN) {
- if (!superHandledTouch && mHitRect.contains(event.getX(), event.getY())) {
- if (startDragHandleEducationAnim()) {
- return true;
- }
- }
- stopDragHandleEducationAnim();
- }
- return superHandledTouch;
- }
-
- /**
- * Animates the drag handle to demonstrate how to get to all apps.
- * @return Whether the animation was started (false if drag handle is invisible).
- */
- public boolean startDragHandleEducationAnim() {
- stopDragHandleEducationAnim();
-
- if (mDragHandle == null || mDragHandle.getAlpha() != 255) {
- return false;
- }
-
- final Drawable drawable = mDragHandle;
- mDragHandle = null;
-
- Rect bounds = new Rect(mDragHandleBounds);
- bounds.offset(0, -(int) mDragHandleOffset);
- drawable.setBounds(bounds);
-
- Rect topBounds = new Rect(bounds);
- topBounds.offset(0, -bounds.height());
-
- Rect invalidateRegion = new Rect(bounds);
- invalidateRegion.top = topBounds.top;
-
- final float progressToReachTop = 0.6f;
- Keyframe frameTop = Keyframe.ofObject(progressToReachTop, topBounds);
- frameTop.setInterpolator(DEACCEL);
- Keyframe frameBot = Keyframe.ofObject(1, bounds);
- frameBot.setInterpolator(ACCEL_DEACCEL);
- PropertyValuesHolder holder = PropertyValuesHolder.ofKeyframe("bounds",
- Keyframe.ofObject(0, bounds), frameTop, frameBot);
- holder.setEvaluator(new RectEvaluator());
-
- mDragHandleAnim = ObjectAnimator.ofPropertyValuesHolder(drawable, holder);
- long totalBounceDuration = DRAG_HANDLE_BOUNCE_DURATION_MS + DRAG_HANDLE_BOUNCE_DELAY_MS;
- // The bounce finishes by this progress, the rest of the duration just delays next bounce.
- float delayStartProgress = 1f - (float) DRAG_HANDLE_BOUNCE_DELAY_MS / totalBounceDuration;
- mDragHandleAnim.addUpdateListener((v) -> invalidate(invalidateRegion));
- mDragHandleAnim.setDuration(totalBounceDuration);
- mDragHandleAnim.setInterpolator(clampToProgress(LINEAR, 0, delayStartProgress));
- mDragHandleAnim.setRepeatCount(DRAG_HANDLE_BOUNCE_REPEAT_COUNT);
- getOverlay().add(drawable);
-
- mDragHandleAnim.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- mDragHandleAnim = null;
- getOverlay().remove(drawable);
- updateDragHandleVisibility(drawable);
- }
- });
- mDragHandleAnim.start();
- return true;
- }
-
- private void stopDragHandleEducationAnim() {
- if (mDragHandleAnim != null) {
- mDragHandleAnim.end();
- }
- }
-
- protected void updateDragHandleBounds() {
- DeviceProfile grid = mLauncher.getDeviceProfile();
- final int left;
- final int width = getMeasuredWidth();
- final int top = getMeasuredHeight() - mDragHandleSize.y - grid.getInsets().bottom;
- final int topMargin;
-
- if (grid.isVerticalBarLayout()) {
- topMargin = grid.workspacePadding.bottom + mDragHandlePaddingInVerticalBarLayout;
- if (grid.isSeascape()) {
- left = width - grid.getInsets().right - mDragHandleSize.x
- - mDragHandlePaddingInVerticalBarLayout;
- } else {
- left = grid.getInsets().left + mDragHandlePaddingInVerticalBarLayout;
- }
- } else {
- left = Math.round((width - mDragHandleSize.x) / 2f);
- topMargin = grid.hotseatBarSizePx;
- }
- mDragHandleBounds.offsetTo(left, top - topMargin);
- mHitRect.set(mDragHandleBounds);
- // Inset outwards to increase touch size.
- mHitRect.inset((mDragHandleSize.x - mDragHandleTouchSize) / 2f,
- (mDragHandleSize.y - mDragHandleTouchSize) / 2f);
-
- if (mDragHandle != null) {
- mDragHandle.setBounds(mDragHandleBounds);
- }
- }
-
- @Override
- public void onAccessibilityStateChanged(boolean enabled) {
- StateManager<LauncherState> stateManager = mLauncher.getStateManager();
- stateManager.removeStateListener(mAccessibilityLauncherStateListener);
-
- if (enabled) {
- stateManager.addStateListener(mAccessibilityLauncherStateListener);
- mAccessibilityLauncherStateListener.onStateTransitionComplete(stateManager.getState());
- } else {
- setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
- }
- updateDragHandleVisibility();
- }
-
- public void updateDragHandleVisibility() {
- updateDragHandleVisibility(null);
- }
-
- private void updateDragHandleVisibility(@Nullable Drawable recycle) {
- boolean visible = shouldDragHandleBeVisible();
- boolean wasVisible = mDragHandle != null;
- if (visible != wasVisible) {
- if (visible) {
- mDragHandle = recycle != null ? recycle :
- mLauncher.getDrawable(R.drawable.drag_handle_indicator_shadow);
- mDragHandle.setBounds(mDragHandleBounds);
-
- updateDragHandleAlpha();
- } else {
- mDragHandle = null;
- }
- invalidate();
- }
- }
-
- protected boolean shouldDragHandleBeVisible() {
- return mLauncher.getDeviceProfile().isVerticalBarLayout() || mAM.isEnabled();
- }
-
- @Override
- public boolean dispatchHoverEvent(MotionEvent event) {
- return mAccessibilityHelper.dispatchHoverEvent(event) || super.dispatchHoverEvent(event);
- }
-
- @Override
- public boolean dispatchKeyEvent(KeyEvent event) {
- return mAccessibilityHelper.dispatchKeyEvent(event) || super.dispatchKeyEvent(event);
- }
-
- @Override
- public void onFocusChanged(boolean gainFocus, int direction,
- Rect previouslyFocusedRect) {
- super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
- mAccessibilityHelper.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
- }
-
- protected class AccessibilityHelper extends ExploreByTouchHelper {
-
- private static final int DRAG_HANDLE_ID = 1;
-
- public AccessibilityHelper() {
- super(ScrimView.this);
- }
-
- @Override
- protected int getVirtualViewAt(float x, float y) {
- return mHitRect.contains((int) x, (int) y)
- ? DRAG_HANDLE_ID : INVALID_ID;
- }
-
- @Override
- protected void getVisibleVirtualViews(List<Integer> virtualViewIds) {
- virtualViewIds.add(DRAG_HANDLE_ID);
- }
-
- @Override
- protected void onPopulateNodeForVirtualView(int virtualViewId,
- AccessibilityNodeInfoCompat node) {
- node.setContentDescription(getContext().getString(R.string.all_apps_button_label));
- node.setBoundsInParent(mDragHandleBounds);
-
- getLocationOnScreen(mTempPos);
- mTempRect.set(mDragHandleBounds);
- mTempRect.offset(mTempPos[0], mTempPos[1]);
- node.setBoundsInScreen(mTempRect);
-
- node.addAction(AccessibilityNodeInfoCompat.ACTION_CLICK);
- node.setClickable(true);
- node.setFocusable(true);
-
- if (mLauncher.isInState(NORMAL)) {
- Context context = getContext();
- if (Utilities.isWallpaperAllowed(context)) {
- node.addAction(
- new AccessibilityActionCompat(WALLPAPERS, context.getText(WALLPAPERS)));
- }
- node.addAction(new AccessibilityActionCompat(WIDGETS, context.getText(WIDGETS)));
- node.addAction(new AccessibilityActionCompat(SETTINGS, context.getText(SETTINGS)));
- }
- }
-
- @Override
- protected boolean onPerformActionForVirtualView(
- int virtualViewId, int action, Bundle arguments) {
- if (action == AccessibilityNodeInfoCompat.ACTION_CLICK) {
- mLauncher.getUserEventDispatcher().logActionOnControl(
- Action.Touch.TAP, ControlType.ALL_APPS_BUTTON,
- mLauncher.getStateManager().getState().containerType);
- mLauncher.getStateManager().goToState(ALL_APPS);
- return true;
- } else if (action == WALLPAPERS) {
- return OptionsPopupView.startWallpaperPicker(ScrimView.this);
- } else if (action == WIDGETS) {
- int originalImportanceForAccessibility = getImportantForAccessibility();
- setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
- WidgetsFullSheet widgetsFullSheet = OptionsPopupView.openWidgets(mLauncher);
- if (widgetsFullSheet == null) {
- setImportantForAccessibility(originalImportanceForAccessibility);
- return false;
- }
- widgetsFullSheet.addOnAttachStateChangeListener(new OnAttachStateChangeListener() {
- @Override
- public void onViewAttachedToWindow(View view) {}
-
- @Override
- public void onViewDetachedFromWindow(View view) {
- setImportantForAccessibility(originalImportanceForAccessibility);
- widgetsFullSheet.removeOnAttachStateChangeListener(this);
- }
- });
- return true;
- } else if (action == SETTINGS) {
- return OptionsPopupView.startSettings(ScrimView.this);
- }
-
- return false;
- }
- }
-
- /**
- * @return The top of this scrim view, or {@link Float#MAX_VALUE} if there's no distinct top.
- */
- public float getVisualTop() {
- return Float.MAX_VALUE;
}
}