Merge "Fixing missing file in build rule" into ub-launcher3-master
diff --git a/Android.mk b/Android.mk
index b8e6c85..15daf1f 100644
--- a/Android.mk
+++ b/Android.mk
@@ -53,7 +53,6 @@
LOCAL_SDK_VERSION := current
LOCAL_MIN_SDK_VERSION := 28
LOCAL_MODULE := LauncherPluginLib
-LOCAL_PRIVILEGED_MODULE := true
include $(BUILD_STATIC_JAVA_LIBRARY)
@@ -69,7 +68,7 @@
androidx.recyclerview_recyclerview \
androidx.dynamicanimation_dynamicanimation
-LOCAL_STATIC_JAVA_LIBRARIES := libPluginCore
+LOCAL_STATIC_JAVA_LIBRARIES := LauncherPluginLib
LOCAL_SRC_FILES := \
$(call all-proto-files-under, protos) \
diff --git a/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginManagerWrapper.java b/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginManagerWrapper.java
index ca12951..88c362d 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginManagerWrapper.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginManagerWrapper.java
@@ -43,7 +43,12 @@
}
public void addPluginListener(PluginListener<? extends Plugin> listener, Class<?> pluginClass) {
- mPluginManager.addPluginListener(listener, pluginClass);
+ addPluginListener(listener, pluginClass, false);
+ }
+
+ public void addPluginListener(PluginListener<? extends Plugin> listener, Class<?> pluginClass,
+ boolean allowMultiple) {
+ mPluginManager.addPluginListener(listener, pluginClass, allowMultiple);
}
public void removePluginListener(PluginListener<? extends Plugin> listener) {
diff --git a/quickstep/src/com/android/quickstep/TaskSystemShortcut.java b/quickstep/src/com/android/quickstep/TaskSystemShortcut.java
index e64d04a..66ce4c3 100644
--- a/quickstep/src/com/android/quickstep/TaskSystemShortcut.java
+++ b/quickstep/src/com/android/quickstep/TaskSystemShortcut.java
@@ -64,7 +64,7 @@
protected T mSystemShortcut;
protected TaskSystemShortcut(T systemShortcut) {
- super(systemShortcut.iconResId, systemShortcut.labelResId);
+ super(systemShortcut);
mSystemShortcut = systemShortcut;
}
diff --git a/quickstep/src/com/android/quickstep/views/TaskMenuView.java b/quickstep/src/com/android/quickstep/views/TaskMenuView.java
index 28928a8..c4afad7 100644
--- a/quickstep/src/com/android/quickstep/views/TaskMenuView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskMenuView.java
@@ -208,8 +208,8 @@
private void addMenuOption(TaskSystemShortcut menuOption, OnClickListener onClickListener) {
ViewGroup menuOptionView = (ViewGroup) mActivity.getLayoutInflater().inflate(
R.layout.task_view_menu_option, this, false);
- menuOptionView.findViewById(R.id.icon).setBackgroundResource(menuOption.iconResId);
- ((TextView) menuOptionView.findViewById(R.id.text)).setText(menuOption.labelResId);
+ menuOption.setIconAndLabelFor(
+ menuOptionView.findViewById(R.id.icon), menuOptionView.findViewById(R.id.text));
menuOptionView.setOnClickListener(onClickListener);
mOptionLayout.addView(menuOptionView);
}
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index a0615f5..c1424c4 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -387,8 +387,7 @@
for (TaskSystemShortcut menuOption : TaskMenuView.MENU_OPTIONS) {
OnClickListener onClickListener = menuOption.getOnClickListener(activity, this);
if (onClickListener != null) {
- info.addAction(new AccessibilityNodeInfo.AccessibilityAction(menuOption.labelResId,
- context.getText(menuOption.labelResId)));
+ info.addAction(menuOption.createAccessibilityAction(context));
}
}
@@ -409,7 +408,7 @@
}
for (TaskSystemShortcut menuOption : TaskMenuView.MENU_OPTIONS) {
- if (action == menuOption.labelResId) {
+ if (menuOption.hasHandlerForAction(action)) {
OnClickListener onClickListener = menuOption.getOnClickListener(
fromContext(getContext()), this);
if (onClickListener != null) {
diff --git a/src/com/android/launcher3/allapps/FloatingHeaderView.java b/src/com/android/launcher3/allapps/FloatingHeaderView.java
index 5348349..90e195b 100644
--- a/src/com/android/launcher3/allapps/FloatingHeaderView.java
+++ b/src/com/android/launcher3/allapps/FloatingHeaderView.java
@@ -25,16 +25,22 @@
import android.view.ViewGroup;
import android.view.animation.Interpolator;
import android.widget.LinearLayout;
-
-import com.android.launcher3.R;
-import com.android.launcher3.anim.PropertySetter;
-
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
+import com.android.launcher3.R;
+import com.android.launcher3.anim.PropertySetter;
+import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
+import com.android.systemui.plugins.AllAppsRow;
+import com.android.systemui.plugins.PluginListener;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
public class FloatingHeaderView extends LinearLayout implements
- ValueAnimator.AnimatorUpdateListener {
+ ValueAnimator.AnimatorUpdateListener, PluginListener<AllAppsRow> {
private final Rect mClip = new Rect(0, 0, Integer.MAX_VALUE, Integer.MAX_VALUE);
private final ValueAnimator mAnimator = ValueAnimator.ofInt(0, 0);
@@ -64,6 +70,9 @@
private AllAppsRecyclerView mMainRV;
private AllAppsRecyclerView mWorkRV;
private AllAppsRecyclerView mCurrentRV;
+ protected final Map<AllAppsRow, View> mPluginRows;
+ // Contains just the values of the above map so we can iterate without extracting a new list.
+ protected final List<View> mPluginRowViews;
private ViewGroup mParent;
private boolean mHeaderCollapsed;
private int mSnappedScrolledY;
@@ -82,6 +91,8 @@
public FloatingHeaderView(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
+ mPluginRows = new HashMap<>();
+ mPluginRowViews = new ArrayList<>();
}
@Override
@@ -90,6 +101,38 @@
mTabLayout = findViewById(R.id.tabs);
}
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ PluginManagerWrapper.INSTANCE.get(getContext()).addPluginListener(this,
+ AllAppsRow.class, true /* allowMultiple */);
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ PluginManagerWrapper.INSTANCE.get(getContext()).removePluginListener(this);
+ }
+
+ @Override
+ public void onPluginConnected(AllAppsRow allAppsRowPlugin, Context context) {
+ mPluginRows.put(allAppsRowPlugin, null);
+ setupPluginRows();
+ allAppsRowPlugin.setOnHeightUpdatedListener(this::onPluginRowHeightUpdated);
+ }
+
+ protected void onPluginRowHeightUpdated() {
+ }
+
+ @Override
+ public void onPluginDisconnected(AllAppsRow plugin) {
+ View pluginRowView = mPluginRows.get(plugin);
+ removeView(pluginRowView);
+ mPluginRows.remove(plugin);
+ mPluginRowViews.remove(pluginRowView);
+ onPluginRowHeightUpdated();
+ }
+
public void setup(AllAppsContainerView.AdapterHolder[] mAH, boolean tabsHidden) {
mTabsHidden = tabsHidden;
mTabLayout.setVisibility(tabsHidden ? View.GONE : View.VISIBLE);
@@ -97,9 +140,24 @@
mWorkRV = setupRV(mWorkRV, mAH[AllAppsContainerView.AdapterHolder.WORK].recyclerView);
mParent = (ViewGroup) mMainRV.getParent();
setMainActive(mMainRVActive || mWorkRV == null);
+ setupPluginRows();
reset(false);
}
+ private void setupPluginRows() {
+ for (Map.Entry<AllAppsRow, View> rowPluginEntry : mPluginRows.entrySet()) {
+ if (rowPluginEntry.getValue() == null) {
+ View pluginRow = rowPluginEntry.getKey().setup(this);
+ addView(pluginRow, indexOfChild(mTabLayout));
+ rowPluginEntry.setValue(pluginRow);
+ mPluginRowViews.add(pluginRow);
+ }
+ }
+ for (View plugin : mPluginRowViews) {
+ plugin.setVisibility(mHeaderCollapsed ? GONE : VISIBLE);
+ }
+ }
+
private AllAppsRecyclerView setupRV(AllAppsRecyclerView old, AllAppsRecyclerView updated) {
if (old != updated && updated != null ) {
updated.addOnScrollListener(mOnScrollListener);
diff --git a/src/com/android/launcher3/popup/PopupContainerWithArrow.java b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
index 6877cc4..b9e6a98 100644
--- a/src/com/android/launcher3/popup/PopupContainerWithArrow.java
+++ b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
@@ -391,13 +391,10 @@
if (view instanceof DeepShortcutView) {
// Expanded system shortcut, with both icon and text shown on white background.
final DeepShortcutView shortcutView = (DeepShortcutView) view;
- shortcutView.getIconView().setBackgroundResource(info.iconResId);
- shortcutView.getBubbleText().setText(info.labelResId);
+ info.setIconAndLabelFor(shortcutView.getIconView(), shortcutView.getBubbleText());
} else if (view instanceof ImageView) {
// Only the system shortcut icon shows on a gray background header.
- final ImageView shortcutIcon = (ImageView) view;
- shortcutIcon.setImageResource(info.iconResId);
- shortcutIcon.setContentDescription(getContext().getText(info.labelResId));
+ info.setIconAndContentDescriptionFor((ImageView) view);
}
view.setTag(info);
view.setOnClickListener(info.getOnClickListener(mLauncher,
diff --git a/src/com/android/launcher3/popup/SystemShortcut.java b/src/com/android/launcher3/popup/SystemShortcut.java
index 693e532..b80ba8a 100644
--- a/src/com/android/launcher3/popup/SystemShortcut.java
+++ b/src/com/android/launcher3/popup/SystemShortcut.java
@@ -3,10 +3,15 @@
import static com.android.launcher3.userevent.nano.LauncherLogProto.Action;
import static com.android.launcher3.userevent.nano.LauncherLogProto.ControlType;
+import android.content.Context;
import android.content.Intent;
import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.View;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.widget.ImageView;
+import android.widget.TextView;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.BaseDraggingActivity;
@@ -23,18 +28,82 @@
import java.util.List;
/**
- * Represents a system shortcut for a given app. The shortcut should have a static label and
- * icon, and an onClickListener that depends on the item that the shortcut services.
+ * Represents a system shortcut for a given app. The shortcut should have a label and icon, and an
+ * onClickListener that depends on the item that the shortcut services.
*
* Example system shortcuts, defined as inner classes, include Widgets and AppInfo.
*/
public abstract class SystemShortcut<T extends BaseDraggingActivity> extends ItemInfo {
- public final int iconResId;
- public final int labelResId;
+ private final int mIconResId;
+ private final int mLabelResId;
+ private final Drawable mIcon;
+ private final CharSequence mLabel;
+ private final CharSequence mContentDescription;
+ private final int mAccessibilityActionId;
public SystemShortcut(int iconResId, int labelResId) {
- this.iconResId = iconResId;
- this.labelResId = labelResId;
+ mIconResId = iconResId;
+ mLabelResId = labelResId;
+ mAccessibilityActionId = labelResId;
+ mIcon = null;
+ mLabel = null;
+ mContentDescription = null;
+ }
+
+ public SystemShortcut(Drawable icon, CharSequence label, CharSequence contentDescription,
+ int accessibilityActionId) {
+ mIcon = icon;
+ mLabel = label;
+ mContentDescription = contentDescription;
+ mAccessibilityActionId = accessibilityActionId;
+ mIconResId = 0;
+ mLabelResId = 0;
+ }
+
+ public SystemShortcut(SystemShortcut other) {
+ mIconResId = other.mIconResId;
+ mLabelResId = other.mLabelResId;
+ mIcon = other.mIcon;
+ mLabel = other.mLabel;
+ mContentDescription = other.mContentDescription;
+ mAccessibilityActionId = other.mAccessibilityActionId;
+ }
+
+ public void setIconAndLabelFor(View iconView, TextView labelView) {
+ if (mIcon != null) {
+ iconView.setBackground(mIcon);
+ } else {
+ iconView.setBackgroundResource(mIconResId);
+ }
+
+ if (mLabel != null) {
+ labelView.setText(mLabel);
+ } else {
+ labelView.setText(mLabelResId);
+ }
+ }
+
+ public void setIconAndContentDescriptionFor(ImageView view) {
+ if (mIcon != null) {
+ view.setImageDrawable(mIcon);
+ } else {
+ view.setImageResource(mIconResId);
+ }
+
+ view.setContentDescription(getContentDescription(view.getContext()));
+ }
+
+ private CharSequence getContentDescription(Context context) {
+ return mContentDescription != null ? mContentDescription : context.getText(mLabelResId);
+ }
+
+ public AccessibilityNodeInfo.AccessibilityAction createAccessibilityAction(Context context) {
+ return new AccessibilityNodeInfo.AccessibilityAction(mAccessibilityActionId,
+ getContentDescription(context));
+ }
+
+ public boolean hasHandlerForAction(int action) {
+ return mAccessibilityActionId == action;
}
public abstract View.OnClickListener getOnClickListener(T activity, ItemInfo itemInfo);
diff --git a/src_plugins/com/android/systemui/plugins/AllAppsRow.java b/src_plugins/com/android/systemui/plugins/AllAppsRow.java
new file mode 100644
index 0000000..c003fc1
--- /dev/null
+++ b/src_plugins/com/android/systemui/plugins/AllAppsRow.java
@@ -0,0 +1,51 @@
+/*
+ * 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.systemui.plugins;
+
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.android.systemui.plugins.annotations.ProvidesInterface;
+
+/**
+ * Implement this plugin interface to add a row of views to the top of the all apps drawer.
+ */
+@ProvidesInterface(action = AllAppsRow.ACTION, version = AllAppsRow.VERSION)
+public interface AllAppsRow extends Plugin {
+ String ACTION = "com.android.systemui.action.PLUGIN_ALL_APPS_ACTIONS";
+ int VERSION = 1;
+
+ /**
+ * Setup the row and return the parent view.
+ * @param parent The ViewGroup to which launcher will add this row.
+ */
+ View setup(ViewGroup parent);
+
+ /**
+ * @return The height to reserve in all apps for your views.
+ */
+ int getExpectedHeight();
+
+ /**
+ * Update launcher whenever {@link #getExpectedHeight()} changes.
+ */
+ void setOnHeightUpdatedListener(OnHeightUpdatedListener onHeightUpdatedListener);
+
+ interface OnHeightUpdatedListener {
+ void onHeightUpdated();
+ }
+}
diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/plugins/PluginManagerWrapper.java b/src_ui_overrides/com/android/launcher3/uioverrides/plugins/PluginManagerWrapper.java
index fcb2abe..31dbb34 100644
--- a/src_ui_overrides/com/android/launcher3/uioverrides/plugins/PluginManagerWrapper.java
+++ b/src_ui_overrides/com/android/launcher3/uioverrides/plugins/PluginManagerWrapper.java
@@ -31,6 +31,10 @@
public void addPluginListener(PluginListener<? extends Plugin> listener, Class<?> pluginClass) {
}
+ public void addPluginListener(PluginListener<? extends Plugin> listener, Class<?> pluginClass,
+ boolean allowMultiple) {
+ }
+
public void removePluginListener(PluginListener<? extends Plugin> listener) {
}
}