Snap for 10580366 from fd35baa3f8 to udc-qpr1-release

Change-Id: Ia6e829c8a73b015f9c7e6570b82cbc1a84273046
This commit is contained in:
Android Build Coastguard Worker
2023-07-29 01:23:23 +00:00
33 changed files with 378 additions and 131 deletions
+1 -1
View File
@@ -19,6 +19,6 @@
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:fillColor="@color/overview_button"
android:pathData="M15.08,7.05c0.84,1.18 0.84,2.71 0,3.89l1.68,1.69c2.02,-2.02 2.02,-5.07 0,-7.27l-1.68,1.69zM20.07,2l-1.63,1.63c2.77,3.02 2.77,7.56 0,10.74L20.07,16c3.9,-3.89 3.91,-9.95 0,-14zM9,13c2.21,0 4,-1.79 4,-4s-1.79,-4 -4,-4 -4,1.79 -4,4 1.79,4 4,4zM9,7c1.1,0 2,0.9 2,2s-0.9,2 -2,2 -2,-0.9 -2,-2 0.9,-2 2,-2zM9,14c-2.67,0 -8,1.34 -8,4v3h16v-3c0,-2.66 -5.33,-4 -8,-4zM15,19L3,19v-0.99C3.2,17.29 6.3,16 9,16s5.8,1.29 6,2v1z"/>
</vector>
+5 -5
View File
@@ -19,18 +19,18 @@
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:fillColor="@color/overview_button"
android:pathData="M16,3h-2v2h2c1.65,0 3,1.35 3,3v2h2V8C21,5.24 18.76,3 16,3z"/>
<path
android:fillColor="@android:color/white"
android:fillColor="@color/overview_button"
android:pathData="M5,16v-2H3v2c0,2.76 2.24,5 5,5h2v-2H8C6.35,19 5,17.65 5,16z"/>
<path
android:fillColor="@android:color/white"
android:fillColor="@color/overview_button"
android:pathData="M12,8.5c-1.93,0 -3.5,1.57 -3.5,3.5s1.57,3.5 3.5,3.5s3.5,-1.57 3.5,-3.5S13.93,8.5 12,8.5z"/>
<path
android:fillColor="@android:color/white"
android:fillColor="@color/overview_button"
android:pathData="M18,18m-2,0a2,2 0,1 1,4 0a2,2 0,1 1,-4 0"/>
<path
android:fillColor="@android:color/white"
android:fillColor="@color/overview_button"
android:pathData="M5,8c0,-1.65 1.35,-3 3,-3h2V3H8C5.24,3 3,5.24 3,8v2h2V8z"/>
</vector>
+1 -1
View File
@@ -19,6 +19,6 @@
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:fillColor="@color/overview_button"
android:pathData="M12.87,15.07l-2.54,-2.51 0.03,-0.03c1.74,-1.94 2.98,-4.17 3.71,-6.53L17,6L17,4h-7L10,2L8,2v2L1,4v1.99h11.17C11.5,7.92 10.44,9.75 9,11.35 8.07,10.32 7.3,9.19 6.69,8h-2c0.73,1.63 1.73,3.17 2.98,4.56l-5.09,5.02L4,19l5,-5 3.11,3.11 0.76,-2.04zM18.5,10h-2L12,22h2l1.12,-3h4.75L21,22h2l-4.5,-12zM15.88,17l1.62,-4.33L19.12,17h-3.24z"/>
</vector>
@@ -23,8 +23,8 @@
<LinearLayout
android:id="@+id/action_buttons"
android:layout_width="match_parent"
android:layout_height="@dimen/overview_actions_height"
android:layout_gravity="top|center_horizontal"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center_horizontal"
android:orientation="horizontal">
<Space
@@ -104,13 +104,11 @@
</LinearLayout>
<!-- Unused. Included only for compatibility with parent class. -->
<Button
<ImageButton
android:id="@+id/action_split"
style="@style/GoOverviewActionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableStart="@drawable/ic_split_vertical"
android:text="@string/action_split"
android:src="@drawable/ic_split_vertical"
android:contentDescription="@string/action_split"
android:theme="@style/ThemeControlHighlightWorkspaceColor"
android:visibility="gone" />
+1 -1
View File
@@ -24,7 +24,7 @@
<dimen name="go_overview_button_container_width">80dp</dimen>
<dimen name="go_overview_button_container_margin">16dp</dimen>
<dimen name="go_overview_button_caption_margin">8dp</dimen>
<dimen name="overview_actions_height">96dp</dimen>
<dimen name="overview_actions_size">96dp</dimen>
<dimen name="overview_proactive_row_height">0dp</dimen>
<dimen name="overview_proactive_row_bottom_margin">24dp</dimen>
<dimen name="task_corner_radius_override">28dp</dimen>
+8 -30
View File
@@ -1,32 +1,10 @@
<!-- 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="20dp"
android:height="20dp"
android:viewportWidth="20"
android:viewportHeight="20">
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M5.8334,1.666H8.3334V3.3327H5.8334V6.666H4.1667V3.3327C4.1667,2.4122 4.9129,1.666 5.8334,1.666Z"
android:fillColor="#000000"/>
<path
android:pathData="M4.1667,13.3327V16.666C4.1667,17.5865 4.9129,18.3327 5.8334,18.3327H8.3334V16.666H5.8334V13.3327H4.1667Z"
android:fillColor="#000000"/>
<path
android:pathData="M14.1667,13.3327V16.666H11.6667V18.3327H14.1667C15.0872,18.3327 15.8334,17.5865 15.8334,16.666V13.3327H14.1667Z"
android:fillColor="#000000"/>
<path
android:pathData="M15.8334,6.666V3.3327C15.8334,2.4122 15.0872,1.666 14.1667,1.666H11.6667V3.3327H14.1667V6.666H15.8334Z"
android:fillColor="#000000"/>
</vector>
android:pathData="M5,4C5,2.343 6.343,1 8,1L16,1C17.657,1 19,2.343 19,4L19,20C19,21.657 17.657,23 16,23L8,23C6.343,23 5,21.657 5,20L5,4ZM8,3C7.448,3 7,3.448 7,4L7,20C7,20.552 7.448,21 8,21L16,21C16.552,21 17,20.552 17,20L17,4C17,3.448 16.552,3 16,3L8,3ZM8,4L8,8L9.5,8L9.5,5.5L12,5.5L12,4L8,4ZM16,16L16,20L12,20L12,18.5L14.5,18.5L14.5,16L16,16Z"
android:fillColor="@color/overview_button"
android:fillType="evenOdd"/>
</vector>
@@ -15,6 +15,7 @@
-->
<com.android.launcher3.LauncherRootView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/launcher"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
@@ -22,7 +22,7 @@
<LinearLayout
android:id="@+id/action_buttons"
android:layout_width="match_parent"
android:layout_height="@dimen/overview_actions_height"
android:layout_height="@dimen/overview_actions_size"
android:layout_gravity="bottom|center_horizontal"
android:orientation="horizontal">
@@ -31,13 +31,14 @@
android:layout_height="1dp"
android:layout_weight="1" />
<Button
<ImageButton
android:id="@+id/action_screenshot"
style="@style/OverviewActionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableStart="@drawable/ic_screenshot"
android:text="@string/action_screenshot"
android:layout_width="@dimen/overview_actions_size"
android:layout_height="@dimen/overview_actions_size"
android:gravity="center"
android:src="@drawable/ic_screenshot"
android:contentDescription="@string/action_screenshot"
android:theme="@style/ThemeControlHighlightWorkspaceColor" />
<Space
@@ -46,12 +47,14 @@
android:layout_height="1dp"
android:visibility="gone" />
<Button
<ImageButton
android:id="@+id/action_split"
style="@style/OverviewActionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/action_split"
android:layout_width="@dimen/overview_actions_size"
android:layout_height="@dimen/overview_actions_size"
android:gravity="center"
android:src="@drawable/ic_split_vertical"
android:contentDescription="@string/action_split"
android:theme="@style/ThemeControlHighlightWorkspaceColor"
android:visibility="gone" />
+3 -1
View File
@@ -50,8 +50,10 @@
<!-- Overrideable in overlay that provides the Overview Actions. -->
<dimen name="overview_actions_top_margin">24dp</dimen>
<dimen name="overview_actions_height">48dp</dimen>
<dimen name="overview_actions_size">60dp</dimen>
<dimen name="overview_actions_button_spacing">36dp</dimen>
<!-- 12dp + 156dp floating search pill width (note this is in addition to normal 36dp) -->
<dimen name="overview_actions_additional_floating_search_spacing">168dp</dimen>
<!-- These speeds are in dp/s -->
<dimen name="max_task_dismiss_drag_velocity">2.25dp</dimen>
+3 -8
View File
@@ -221,15 +221,10 @@
<item name="android:colorControlHighlight">?attr/workspaceTextColor</item>
</style>
<style name="OverviewActionButton"
parent="@android:style/Widget.DeviceDefault.Button.Borderless">
<item name="android:paddingTop">4dp</item>
<item name="android:paddingBottom">4dp</item>
<item name="android:textColor">@color/overview_button</item>
<style name="OverviewActionButton" parent="@android:style/Widget.DeviceDefault.ImageButton">
<item name="android:background">@drawable/circle_btn_bg</item>
<item name="android:backgroundTint">?androidprv:attr/materialColorSurfaceBright</item>
<item name="android:drawableTint">@color/overview_button</item>
<item name="android:tint">?android:attr/textColorPrimary</item>
<item name="android:drawablePadding">8dp</item>
<item name="android:textAllCaps">false</item>
</style>
<style name="OverviewClearAllButton" parent="@android:style/Widget.DeviceDefault.Button">
@@ -362,10 +362,9 @@ public class BubbleBarController extends IBubblesListener.Stub {
}
if (bubbleToSelect != null) {
setSelectedBubble(bubbleToSelect);
}
if (previouslySelectedBubble == null) {
mBubbleStashController.animateToInitialState(update.expanded);
if (previouslySelectedBubble == null) {
mBubbleStashController.animateToInitialState(update.expanded);
}
}
if (update.expandedChanged) {
@@ -152,6 +152,11 @@ public class BubbleBarViewController {
return mBarView.getBubbleBarBounds();
}
/** The horizontal margin of the bubble bar from the edge of the screen. */
public int getHorizontalMargin() {
return mBarView.getHorizontalMargin();
}
/**
* When the bubble bar is not stashed, it can be collapsed (the icons are in a stack) or
* expanded (the icons are in a row). This indicates whether the bubble bar is expanded.
@@ -201,7 +201,7 @@ public class BubbleStashController {
public void onSysuiLockedStateChange(boolean isSysuiLocked) {
if (isSysuiLocked != mIsSysuiLocked) {
mIsSysuiLocked = isSysuiLocked;
if (!mIsSysuiLocked) {
if (!mIsSysuiLocked && mBarViewController.hasBubbles()) {
animateToInitialState(false /* expanding */);
}
}
@@ -123,13 +123,15 @@ public class BubbleStashedHandleViewController {
private void updateBounds() {
// As more bubbles get added, the icon bounds become larger. To ensure a consistent
// handle bar position, we pin it to the edge of the screen.
Rect bubblebarRect = mBarViewController.getBubbleBarBounds();
final int right =
mActivity.getDeviceProfile().widthPx - mBarViewController.getHorizontalMargin();
final int stashedCenterY = mStashedHandleView.getHeight() - mStashedTaskbarHeight / 2;
mStashedHandleBounds.set(
bubblebarRect.right - mStashedHandleWidth,
right - mStashedHandleWidth,
stashedCenterY - mStashedHandleHeight / 2,
bubblebarRect.right,
right,
stashedCenterY + mStashedHandleHeight / 2);
mStashedHandleView.updateSampledRegion(mStashedHandleBounds);
@@ -240,9 +242,6 @@ public class BubbleStashedHandleViewController {
*/
public Animator createRevealAnimToIsStashed(boolean isStashed) {
Rect bubbleBarBounds = new Rect(mBarViewController.getBubbleBarBounds());
// the bubble bar may have been invisible when the bounds were previously calculated,
// update them again to ensure they're correct.
updateBounds();
// Account for the full visual height of the bubble bar
int heightDiff = (mBarSize - bubbleBarBounds.height()) / 2;
@@ -125,8 +125,33 @@ public class OverviewState extends LauncherState {
@Override
public int getFloatingSearchBarRestingMarginBottom(Launcher launcher) {
return areElementsVisible(launcher, FLOATING_SEARCH_BAR) ? 0
: super.getFloatingSearchBarRestingMarginBottom(launcher);
if (!areElementsVisible(launcher, FLOATING_SEARCH_BAR)) {
return super.getFloatingSearchBarRestingMarginBottom(launcher);
}
RecentsView recentsView = launcher.getOverviewPanel();
DeviceProfile dp = launcher.getDeviceProfile();
int activeTaskMarginBottom = LayoutUtils.getShelfTrackingDistance(launcher, dp,
recentsView.getPagedOrientationHandler());
// Center between task bottom and bottom of the screen.
return (activeTaskMarginBottom - dp.overviewActionsHeight) / 2
- launcher.getResources().getDimensionPixelSize(R.dimen.qsb_shadow_height);
}
@Override
public int getFloatingSearchBarRestingMarginStart(Launcher launcher) {
return getFloatingSearchBarRestingMarginHorizontal(launcher);
}
@Override
public int getFloatingSearchBarRestingMarginEnd(Launcher launcher) {
return getFloatingSearchBarRestingMarginHorizontal(launcher);
}
private static int getFloatingSearchBarRestingMarginHorizontal(Launcher launcher) {
// Width if the search bar were to be expanded (focused).
int expandedWidth = launcher.getResources().getDimensionPixelSize(
R.dimen.overview_floating_search_width);
return (launcher.getDeviceProfile().widthPx - expandedWidth) / 2;
}
@Override
@@ -20,6 +20,7 @@ import static android.app.ActivityTaskManager.INVALID_TASK_ID;
import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.CLEAR_ALL_BUTTON;
import static com.android.launcher3.LauncherState.EDIT_MODE;
import static com.android.launcher3.LauncherState.FLOATING_SEARCH_BAR;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.LauncherState.OVERVIEW_MODAL_TASK;
@@ -98,6 +99,12 @@ public class LauncherRecentsView extends RecentsView<QuickstepLauncher, Launcher
return mActivity.canStartHomeSafely();
}
@Override
public boolean isFloatingSearchVisible() {
return FeatureFlags.ENABLE_FLOATING_SEARCH_BAR.get()
&& OVERVIEW.areElementsVisible(mActivity, FLOATING_SEARCH_BAR);
}
@Override
protected void onTaskLaunchAnimationEnd(boolean success) {
if (success) {
@@ -22,12 +22,14 @@ import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import androidx.annotation.IntDef;
import androidx.annotation.Nullable;
import com.android.launcher3.BaseActivity;
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Insettable;
import com.android.launcher3.R;
@@ -49,6 +51,7 @@ public class OverviewActionsView<T extends OverlayUICallbacks> extends FrameLayo
implements OnClickListener, Insettable {
private final Rect mInsets = new Rect();
private BaseDraggingActivity mActivity;
@IntDef(flag = true, value = {
HIDDEN_NON_ZERO_ROTATION,
@@ -96,7 +99,7 @@ public class OverviewActionsView<T extends OverlayUICallbacks> extends FrameLayo
public static final int FLAG_SINGLE_TASK = 1 << 0;
private MultiValueAlpha mMultiValueAlpha;
private Button mSplitButton;
private ImageButton mSplitButton;
@ActionsHiddenFlags
private int mHiddenFlags;
@@ -132,6 +135,8 @@ public class OverviewActionsView<T extends OverlayUICallbacks> extends FrameLayo
@Override
protected void onFinishInflate() {
super.onFinishInflate();
mActivity = BaseActivity.fromContext(getContext());
mMultiValueAlpha = new MultiValueAlpha(findViewById(R.id.action_buttons), NUM_ALPHAS);
mMultiValueAlpha.setUpdateVisibility(true);
@@ -273,7 +278,7 @@ public class OverviewActionsView<T extends OverlayUICallbacks> extends FrameLayo
LayoutParams actionParams = (LayoutParams) findViewById(
R.id.action_buttons).getLayoutParams();
actionParams.setMargins(
actionParams.leftMargin, mDp.overviewActionsTopMarginPx,
actionParams.leftMargin, 0,
actionParams.rightMargin, getBottomMargin());
}
@@ -286,6 +291,11 @@ public class OverviewActionsView<T extends OverlayUICallbacks> extends FrameLayo
return mDp.stashedTaskbarHeight;
}
if (isFloatingSearchVisible()) {
// Center between task and bottom of the screen.
return (mDp.heightPx - mTaskSize.bottom - mDp.overviewActionsHeight) / 2;
}
// Align to bottom of task Rect.
return mDp.heightPx - mTaskSize.bottom - mDp.overviewActionsTopMarginPx
- mDp.overviewActionsHeight;
@@ -301,9 +311,12 @@ public class OverviewActionsView<T extends OverlayUICallbacks> extends FrameLayo
requestLayout();
mSplitButton.setCompoundDrawablesRelativeWithIntrinsicBounds(
(dp.isLandscape ? R.drawable.ic_split_horizontal : R.drawable.ic_split_vertical),
0, 0, 0);
mSplitButton.setImageResource(
dp.isLandscape ? R.drawable.ic_split_horizontal : R.drawable.ic_split_vertical);
}
protected boolean isFloatingSearchVisible() {
return ((RecentsView) mActivity.getOverviewPanel()).isFloatingSearchVisible();
}
/**
@@ -5220,6 +5220,11 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
});
}
/** @return {@code true} if floating search bar is visible in Recents. */
public boolean isFloatingSearchVisible() {
return false;
}
public RemoteTargetHandle[] getRemoteTargetHandles() {
return mRemoteTargetHandles;
}
+2 -2
View File
@@ -3,10 +3,10 @@
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
<item
android:alpha="1"
android:color="?androidprv:attr/materialColorOnSurface"
android:color="?androidprv:attr/materialColorOnSurfaceVariant"
android:state_enabled="true" />
<item
android:alpha="?android:disabledAlpha"
android:color="?androidprv:attr/materialColorOnSurface"
android:color="?androidprv:attr/materialColorOnSurfaceVariant"
android:state_enabled="false" />
</selector>
+14
View File
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@color/accent_ripple_color">
<item android:id="@android:id/mask">
<shape android:shape="oval">
<solid android:color="@android:color/white" />
</shape>
</item>
<item>
<shape android:shape="oval">
<solid android:color="@android:color/white" />
</shape>
</item>
</ripple>
+1 -1
View File
@@ -5,5 +5,5 @@
android:viewportHeight="24">
<path
android:pathData="M4,6L9,6L9,18L4,18L4,6ZM2,6L2,18C2,19.1 2.9,20 4,20L9,20C10.1,20 11,19.1 11,18L11,6C11,4.9 10.1,4 9,4L4,4C2.9,4 2,4.9 2,6ZM15,6L20,6L20,18L15,18L15,6ZM13,6L13,18C13,19.1 13.9,20 15,20L20,20C21.1,20 22,19.1 22,18L22,6C22,4.9 21.1,4 20,4L15,4C13.9,4 13,4.9 13,6Z"
android:fillColor="#000000"/>
android:fillColor="@color/overview_button"/>
</vector>
+1 -1
View File
@@ -5,5 +5,5 @@
android:viewportHeight="24">
<path
android:pathData="M18,4V9H6V4H18ZM18,2H6C4.9,2 4,2.9 4,4V9C4,10.1 4.9,11 6,11H18C19.1,11 20,10.1 20,9V4C20,2.9 19.1,2 18,2ZM18,15V20H6V15H18ZM18,13H6C4.9,13 4,13.9 4,15V20C4,21.1 4.9,22 6,22H18C19.1,22 20,21.1 20,20V15C20,13.9 19.1,13 18,13Z"
android:fillColor="#000000"/>
android:fillColor="@color/overview_button"/>
</vector>
+3 -1
View File
@@ -396,10 +396,12 @@
<dimen name="task_thumbnail_icon_drawable_size">0dp</dimen>
<dimen name="task_thumbnail_icon_drawable_size_grid">0dp</dimen>
<dimen name="overview_task_margin">0dp</dimen>
<dimen name="overview_actions_height">0dp</dimen>
<dimen name="overview_actions_size">0dp</dimen>
<dimen name="overview_actions_button_spacing">0dp</dimen>
<dimen name="overview_actions_margin_gesture">0dp</dimen>
<dimen name="overview_actions_top_margin">0dp</dimen>
<!-- Width if the search bar were to be full-size in Overview. Note pill is 192dp smaller. -->
<dimen name="overview_floating_search_width">348dp</dimen>
<dimen name="overview_grid_side_margin">0dp</dimen>
<dimen name="overview_grid_row_spacing">0dp</dimen>
<dimen name="overview_page_spacing">0dp</dimen>
+2 -4
View File
@@ -584,13 +584,11 @@ public class DeviceProfile {
overviewTaskIconDrawableSizeGridPx =
res.getDimensionPixelSize(R.dimen.task_thumbnail_icon_drawable_size_grid);
overviewTaskThumbnailTopMarginPx = overviewTaskIconSizePx + overviewTaskMarginPx;
// Don't add margin with floating search bar to minimize risk of overlapping.
overviewActionsTopMarginPx = FeatureFlags.ENABLE_FLOATING_SEARCH_BAR.get() ? 0
: res.getDimensionPixelSize(R.dimen.overview_actions_top_margin);
overviewActionsTopMarginPx = res.getDimensionPixelSize(R.dimen.overview_actions_top_margin);
overviewPageSpacing = res.getDimensionPixelSize(R.dimen.overview_page_spacing);
overviewActionsButtonSpacing = res.getDimensionPixelSize(
R.dimen.overview_actions_button_spacing);
overviewActionsHeight = res.getDimensionPixelSize(R.dimen.overview_actions_height);
overviewActionsHeight = res.getDimensionPixelSize(R.dimen.overview_actions_size);
overviewRowSpacing = res.getDimensionPixelSize(R.dimen.overview_grid_row_spacing);
overviewGridSideMargin = res.getDimensionPixelSize(R.dimen.overview_grid_side_margin);
@@ -22,6 +22,7 @@ import static com.android.launcher3.config.FeatureFlags.ENABLE_ALL_APPS_RV_PREIN
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_COUNT;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_TAP_ON_PERSONAL_TAB;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_TAP_ON_WORK_TAB;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.ScrollableLayoutManager.PREDICTIVE_BACK_MIN_SCALE;
import android.animation.Animator;
@@ -461,7 +462,7 @@ public class ActivityAllAppsContainerView<T extends Context & ActivityContext>
updateHeaderScroll(0);
if (exitSearch) {
// Reset the search bar after transitioning home.
mSearchUiManager.resetSearch();
MAIN_EXECUTOR.getHandler().post(mSearchUiManager::resetSearch);
// Animate to A-Z with 0 time to reset the animation with proper state management.
animateToSearchState(false, 0);
}
+22
View File
@@ -299,6 +299,28 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity-alias>
<activity-alias android:name="MaxShortcutsActivity"
android:label="TestActivityMaxShortcuts"
android:exported="true"
android:targetActivity="com.android.launcher3.testcomponent.OtherBaseTestingActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<meta-data android:name="android.app.shortcuts"
android:resource="@xml/max_shortcuts"/>
</activity-alias>
<activity-alias android:name="SingleShortcutActivity"
android:label="TestActivitySingleShortcut"
android:exported="true"
android:targetActivity="com.android.launcher3.testcomponent.OtherBaseTestingActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<meta-data android:name="android.app.shortcuts"
android:resource="@xml/single_shortcut"/>
</activity-alias>
<activity
android:name="com.android.launcher3.testcomponent.DialogTestActivity"
android:label="Dialog Activity"
+1
View File
@@ -3,4 +3,5 @@
<string name="shortcut1" translatable="false">Shortcut 1</string>
<string name="shortcut2" translatable="false">Shortcut 2</string>
<string name="shortcut3" translatable="false">Shortcut 3</string>
<string name="shortcut4" translatable="false">Shortcut 4</string>
</resources>
+39
View File
@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2023 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.
-->
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android" >
<shortcut
android:shortcutId="max_shortcut1"
android:icon="@drawable/test_theme_icon"
android:shortcutShortLabel="@string/shortcut1">
<intent android:action="com.android.launcher3.intent.action.test_shortcut_max"/>
</shortcut>
<shortcut
android:shortcutId="max_shortcut2"
android:shortcutShortLabel="@string/shortcut2">
<intent android:action="com.android.launcher3.intent.action.test_shortcut_max"/>
</shortcut>
<shortcut
android:shortcutId="max_shortcut3"
android:shortcutShortLabel="@string/shortcut3">
<intent android:action="com.android.launcher3.intent.action.test_shortcut_max"/>
</shortcut>
<shortcut
android:shortcutId="max_shortcut4"
android:shortcutShortLabel="@string/shortcut4">
<intent android:action="com.android.launcher3.intent.action.test_shortcut_max"/>
</shortcut>
</shortcuts>
+15
View File
@@ -1,4 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2023 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.
-->
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android" >
<shortcut
android:shortcutId="shortcut1_themed"
+24
View File
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2023 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.
-->
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android" >
<shortcut
android:shortcutId="single_shortcut_themed"
android:icon="@drawable/test_theme_icon"
android:shortcutShortLabel="@string/shortcut1">
<intent android:action="com.android.launcher3.intent.action.test_shortcut_single"/>
</shortcut>
</shortcuts>
@@ -16,6 +16,7 @@
package com.android.launcher3.celllayout;
import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
import static com.android.launcher3.ui.TestViewHelpers.findWidgetProvider;
import static com.android.launcher3.util.WidgetUtils.createWidgetInfo;
@@ -43,9 +44,9 @@ import java.util.stream.IntStream;
public class TestWorkspaceBuilder {
private static final String TAG = "CellLayoutBoardBuilder";
private static final ComponentName APP_COMPONENT_NAME = new ComponentName(
private static final String TEST_ACTIVITY_PACKAGE_PREFIX = "com.android.launcher3.tests.";
private ComponentName mAppComponentName = new ComponentName(
"com.google.android.calculator", "com.android.calculator2.Calculator");
private UserHandle mMyUser;
private Context mContext;
@@ -80,8 +81,20 @@ public class TestWorkspaceBuilder {
}
private AppInfo getApp() {
return new AppInfo(APP_COMPONENT_NAME, "test icon", mMyUser,
AppInfo.makeLaunchIntent(APP_COMPONENT_NAME));
return new AppInfo(mAppComponentName, "test icon", mMyUser,
AppInfo.makeLaunchIntent(mAppComponentName));
}
/**
* Helper to set the app to use for the test workspace,
* using activity-alias from AndroidManifest-common.
* @param testAppName the android:name field of the test app activity-alias to use
*/
public void setTestAppActivityAlias(String testAppName) {
this.mAppComponentName = new ComponentName(
getInstrumentation().getContext().getPackageName(),
TEST_ACTIVITY_PACKAGE_PREFIX + testAppName
);
}
private void addCorrespondingWidgetRect(CellLayoutBoard.WidgetRect widgetRect,
@@ -15,13 +15,12 @@
*/
package com.android.launcher3.util.viewcapture_analysis;
import static com.android.launcher3.util.viewcapture_analysis.ViewCaptureAnalyzer.diagPathFromRoot;
import com.android.launcher3.util.viewcapture_analysis.ViewCaptureAnalyzer.AnalysisNode;
import com.android.launcher3.util.viewcapture_analysis.ViewCaptureAnalyzer.AnomalyDetector;
import java.util.Collection;
import java.util.Set;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Anomaly detector that triggers an error when alpha of a view changes too rapidly.
@@ -32,9 +31,11 @@ final class AlphaJumpDetector extends AnomalyDetector {
private static final String CONTENT = "DecorView|LinearLayout|FrameLayout:id/content|";
private static final String DRAG_LAYER =
CONTENT + "LauncherRootView:id/launcher|DragLayer:id/drag_layer|";
private static final String RECENTS_DRAG_LAYER =
CONTENT + "LauncherRootView:id/launcher|RecentsDragLayer:id/drag_layer|";
// Paths of nodes that are excluded from analysis.
private static final Collection<String> PATHS_TO_IGNORE = Set.of(
private static final Iterable<String> PATHS_TO_IGNORE = List.of(
CONTENT
+ "AddItemDragLayer:id/add_item_drag_layer|AddItemWidgetsBottomSheet:id"
+ "/add_item_bottom_sheet|LinearLayout:id/add_item_bottom_sheet_content"
@@ -112,29 +113,102 @@ final class AlphaJumpDetector extends AnomalyDetector {
DRAG_LAYER + "WidgetsFullSheet|SpringRelativeLayout:id/container",
DRAG_LAYER + "WidgetsTwoPaneSheet|SpringRelativeLayout:id/container",
CONTENT + "LauncherRootView:id/launcher|FloatingIconView",
CONTENT
+ "LauncherRootView|RecentsDragLayer:id/drag_layer|ArrowTipView|View:id/arrow",
CONTENT
+ "LauncherRootView|RecentsDragLayer:id/drag_layer|FallbackRecentsView:id"
+ "/overview_panel",
CONTENT
+ "LauncherRootView|RecentsDragLayer:id/drag_layer|NexusOverviewActionsView"
+ ":id/overview_actions_view|LinearLayout:id/action_buttons|Button:id"
+ "/action_screenshot",
CONTENT
+ "LauncherRootView|RecentsDragLayer:id/drag_layer|NexusOverviewActionsView"
+ ":id/overview_actions_view|LinearLayout:id/action_buttons|Button:id"
+ "/action_select"
RECENTS_DRAG_LAYER + "ArrowTipView|View:id/arrow",
DRAG_LAYER + "FallbackRecentsView:id/overview_panel",
RECENTS_DRAG_LAYER + "FallbackRecentsView:id/overview_panel",
DRAG_LAYER
+ "NexusOverviewActionsView:id/overview_actions_view"
+ "|LinearLayout:id/action_buttons|ImageButton:id/action_screenshot",
RECENTS_DRAG_LAYER
+ "NexusOverviewActionsView:id/overview_actions_view"
+ "|LinearLayout:id/action_buttons|ImageButton:id/action_screenshot",
DRAG_LAYER
+ "NexusOverviewActionsView:id/overview_actions_view"
+ "|LinearLayout:id/action_buttons|ImageButton:id/action_select",
RECENTS_DRAG_LAYER
+ "NexusOverviewActionsView:id/overview_actions_view"
+ "|LinearLayout:id/action_buttons|ImageButton:id/action_select",
DRAG_LAYER
+ "NexusOverviewActionsView:id/overview_actions_view"
+ "|LinearLayout:id/action_buttons|ImageButton:id/action_split",
RECENTS_DRAG_LAYER
+ "NexusOverviewActionsView:id/overview_actions_view"
+ "|LinearLayout:id/action_buttons|ImageButton:id/action_split"
);
/**
* Element of the tree of ignored nodes.
* If the "children" map is empty, then this node should be ignored, i.e. alpha jumps analysis
* shouldn't run for it.
* I.e. ignored nodes correspond to the leaves in the ignored nodes tree.
*/
private static class IgnoreNode {
// Map from child node identities to ignore-nodes for these children.
public final Map<String, IgnoreNode> children = new HashMap<>();
}
private static final IgnoreNode IGNORED_NODES_ROOT = buildIgnoreNodesTree();
// Converts the list of full paths of nodes to ignore to a more efficient tree of ignore-nodes.
private static IgnoreNode buildIgnoreNodesTree() {
final IgnoreNode root = new IgnoreNode();
for (String pathToIgnore : PATHS_TO_IGNORE) {
// Scan the diag path of an ignored node and add its elements into the tree.
IgnoreNode currentIgnoreNode = root;
for (String part : pathToIgnore.split("\\|")) {
// Ensure that the child of the node is added to the tree.
IgnoreNode child = currentIgnoreNode.children.get(part);
if (child == null) {
currentIgnoreNode.children.put(part, child = new IgnoreNode());
}
currentIgnoreNode = child;
}
}
return root;
}
// Minimal increase or decrease of view's alpha between frames that triggers the error.
private static final float ALPHA_JUMP_THRESHOLD = 1f;
// Per-AnalysisNode data that's specific to this detector.
private static class NodeData {
public boolean ignoreAlphaJumps;
// If ignoreNode is null, then this AnalysisNode node will be ignored if its parent is
// ignored.
// Otherwise, this AnalysisNode will be ignored if ignoreNode is a leaf i.e. has no
// children.
public IgnoreNode ignoreNode;
}
private NodeData getNodeData(AnalysisNode info) {
return (NodeData) info.detectorsData[detectorOrdinal];
}
@Override
void initializeNode(AnalysisNode info) {
final NodeData nodeData = new NodeData();
info.detectorsData[detectorOrdinal] = nodeData;
// If the parent view ignores alpha jumps, its descendants will too.
final boolean parentIgnoreAlphaJumps = info.parent != null && info.parent.ignoreAlphaJumps;
info.ignoreAlphaJumps = parentIgnoreAlphaJumps
|| PATHS_TO_IGNORE.contains(diagPathFromRoot(info));
final boolean parentIgnoresAlphaJumps = info.parent != null && getNodeData(
info.parent).ignoreAlphaJumps;
if (parentIgnoresAlphaJumps) {
nodeData.ignoreAlphaJumps = true;
return;
}
// Parent view doesn't ignore alpha jumps.
// Initialize this AnalysisNode's ignore-node with the corresponding child of the
// ignore-node of the parent, if present.
final IgnoreNode parentIgnoreNode = info.parent != null
? getNodeData(info.parent).ignoreNode
: IGNORED_NODES_ROOT;
nodeData.ignoreNode = parentIgnoreNode != null
? parentIgnoreNode.children.get(info.nodeIdentity) : null;
// AnalysisNode will be ignored if the corresponding ignore-node is a leaf.
nodeData.ignoreAlphaJumps =
nodeData.ignoreNode != null && nodeData.ignoreNode.children.isEmpty();
}
@Override
@@ -144,7 +218,7 @@ final class AlphaJumpDetector extends AnomalyDetector {
if (oldInfo != null && oldInfo.frameN != frameN) return;
final AnalysisNode latestInfo = newInfo != null ? newInfo : oldInfo;
if (latestInfo.ignoreAlphaJumps) return;
if (getNodeData(latestInfo).ignoreAlphaJumps) return;
final float oldAlpha = oldInfo != null ? oldInfo.alpha : 0;
final float newAlpha = newInfo != null ? newInfo.alpha : 0;
@@ -40,6 +40,9 @@ public class ViewCaptureAnalyzer {
* Detector of one kind of anomaly.
*/
abstract static class AnomalyDetector {
// Index of this detector in ViewCaptureAnalyzer.ANOMALY_DETECTORS
public int detectorOrdinal;
/**
* Initializes fields of the node that are specific to the anomaly detected by this
* detector.
@@ -64,9 +67,13 @@ public class ViewCaptureAnalyzer {
}
// All detectors. They will be invoked in the order listed here.
private static final Iterable<AnomalyDetector> ANOMALY_DETECTORS = Arrays.asList(
private static final AnomalyDetector[] ANOMALY_DETECTORS = {
new AlphaJumpDetector()
);
};
static {
for (int i = 0; i < ANOMALY_DETECTORS.length; ++i) ANOMALY_DETECTORS[i].detectorOrdinal = i;
}
// A view from view capture data converted to a form that's convenient for detecting anomalies.
static class AnalysisNode {
@@ -86,7 +93,11 @@ public class ViewCaptureAnalyzer {
public int frameN;
public ViewNode viewCaptureNode;
public boolean ignoreAlphaJumps;
// Class name + resource id
public String nodeIdentity;
// Collection of detector-specific data for this node.
public final Object[] detectorsData = new Object[ANOMALY_DETECTORS.length];
@Override
public String toString() {
@@ -139,7 +150,7 @@ public class ViewCaptureAnalyzer {
for (AnalysisNode info : lastSeenNodes.values()) {
if (info.frameN == frameN - 1) {
if (!info.viewCaptureNode.getWillNotDraw()) {
ANOMALY_DETECTORS.forEach(
Arrays.stream(ANOMALY_DETECTORS).forEach(
detector -> detector.detectAnomalies(
/* oldInfo = */ info,
/* newInfo = */ null,
@@ -177,6 +188,8 @@ public class ViewCaptureAnalyzer {
final AnalysisNode newAnalysisNode = new AnalysisNode();
newAnalysisNode.className = viewCaptureData.getClassname(classIndex);
newAnalysisNode.resourceId = viewCaptureNode.getId();
newAnalysisNode.nodeIdentity =
getNodeIdentity(newAnalysisNode.className, newAnalysisNode.resourceId);
newAnalysisNode.parent = parent;
newAnalysisNode.left = left;
newAnalysisNode.top = top;
@@ -185,12 +198,13 @@ public class ViewCaptureAnalyzer {
newAnalysisNode.alpha = alpha;
newAnalysisNode.frameN = frameN;
newAnalysisNode.viewCaptureNode = viewCaptureNode;
ANOMALY_DETECTORS.forEach(detector -> detector.initializeNode(newAnalysisNode));
Arrays.stream(ANOMALY_DETECTORS).forEach(
detector -> detector.initializeNode(newAnalysisNode));
// Detect anomalies for the view
final AnalysisNode oldAnalysisNode = lastSeenNodes.get(hashcode); // may be null
if (frameN != 0 && !viewCaptureNode.getWillNotDraw()) {
ANOMALY_DETECTORS.forEach(
Arrays.stream(ANOMALY_DETECTORS).forEach(
detector -> detector.detectAnomalies(oldAnalysisNode, newAnalysisNode, frameN));
}
lastSeenNodes.put(hashcode, newAnalysisNode);
@@ -221,18 +235,18 @@ public class ViewCaptureAnalyzer {
return className.substring(className.lastIndexOf(".") + 1);
}
static String diagPathFromRoot(AnalysisNode nodeBox) {
final StringBuilder path = new StringBuilder(diagPathElement(nodeBox));
private static String diagPathFromRoot(AnalysisNode nodeBox) {
final StringBuilder path = new StringBuilder(nodeBox.nodeIdentity);
for (AnalysisNode ancestor = nodeBox.parent; ancestor != null; ancestor = ancestor.parent) {
path.insert(0, diagPathElement(ancestor) + "|");
path.insert(0, ancestor.nodeIdentity + "|");
}
return path.toString();
}
private static String diagPathElement(AnalysisNode nodeBox) {
private static String getNodeIdentity(String className, String resourceId) {
final StringBuilder sb = new StringBuilder();
sb.append(classNameToSimpleName(nodeBox.className));
if (!"NO_ID".equals(nodeBox.resourceId)) sb.append(":" + nodeBox.resourceId);
sb.append(classNameToSimpleName(className));
if (!"NO_ID".equals(resourceId)) sb.append(":" + resourceId);
return sb.toString();
}
}