Merge "Removing some Launcher3 dependencies from BaseIconCache" into ub-launcher3-master
diff --git a/go/AndroidManifest.xml b/go/AndroidManifest.xml
index 0a9ad7b..0080898 100644
--- a/go/AndroidManifest.xml
+++ b/go/AndroidManifest.xml
@@ -36,16 +36,14 @@
android:restoreAnyVersion="true"
android:supportsRtl="true" >
- <!-- Activity for handling PinItemRequest. Only supports shortcuts -->
+ <!-- Activity for handling PinItemRequest is disabled on Android Go. -->
<activity android:name="com.android.launcher3.dragndrop.AddItemActivity"
android:theme="@android:style/Theme.DeviceDefault.Light.Dialog.Alert"
android:excludeFromRecents="true"
android:autoRemoveFromRecents="true"
android:label="@string/action_add_to_workspace"
+ android:enabled="false"
tools:node="replace" >
- <intent-filter>
- <action android:name="android.content.pm.action.CONFIRM_PIN_SHORTCUT" />
- </intent-filter>
</activity>
</application>
diff --git a/go/res/layout/widget_cell_content.xml b/go/res/layout/widget_cell_content.xml
deleted file mode 100644
index 49506d9..0000000
--- a/go/res/layout/widget_cell_content.xml
+++ /dev/null
@@ -1,66 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<merge xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content">
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingTop="@dimen/widget_preview_label_vertical_padding"
- android:paddingBottom="@dimen/widget_preview_label_vertical_padding"
- android:paddingLeft="@dimen/widget_preview_label_horizontal_padding"
- android:paddingRight="@dimen/widget_preview_label_horizontal_padding"
- android:orientation="horizontal">
-
- <!-- The name of the widget. -->
- <TextView
- android:id="@+id/widget_name"
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:ellipsize="end"
- android:fadingEdge="horizontal"
- android:fontFamily="sans-serif-condensed"
- android:gravity="center"
- android:singleLine="true"
- android:maxLines="1"
- android:textColor="?android:attr/textColorSecondary"
- android:textSize="14sp" />
-
- <!-- The original dimensions of the widget (can't be the same text as above due to different
- style. -->
- <TextView
- android:id="@+id/widget_dims"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginStart="5dp"
- android:layout_marginLeft="5dp"
- android:visibility="gone"
- android:textColor="?android:attr/textColorSecondary"
- android:textSize="14sp"
- android:fontFamily="sans-serif-condensed"
- android:alpha="0.8" />
- </LinearLayout>
-
- <!-- The image of the widget. This view does not support padding. Any placement adjustment
- should be done using margins. -->
- <com.android.launcher3.widget.WidgetImageView
- android:id="@+id/widget_preview"
- android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_weight="1" />
-</merge>
\ No newline at end of file
diff --git a/proguard.flags b/proguard.flags
index bb52a6c..eb27737 100644
--- a/proguard.flags
+++ b/proguard.flags
@@ -24,7 +24,7 @@
-keep class androidx.recyclerview.widget.RecyclerView { *; }
# Preference fragments
--keep class ** extends android.preference.PreferenceFragment {
+-keep class ** extends android.app.Fragment {
public <init>(...);
}
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index 1e787a2..6834070 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -463,7 +463,7 @@
}
if (action == R.string.accessibility_app_usage_settings) {
- openAppUsageSettings();
+ openAppUsageSettings(this);
return true;
}
@@ -485,14 +485,16 @@
return super.performAccessibilityAction(action, arguments);
}
- private void openAppUsageSettings() {
+ private void openAppUsageSettings(View view) {
final Intent intent = new Intent(SEE_TIME_IN_APP_TEMPLATE)
.putExtra(Intent.EXTRA_PACKAGE_NAME,
mTask.getTopComponent().getPackageName()).addFlags(
Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
try {
final Launcher launcher = Launcher.getLauncher(getContext());
- launcher.startActivity(intent);
+ final ActivityOptions options = ActivityOptions.makeScaleUpAnimation(view, 0, 0,
+ view.getWidth(), view.getHeight());
+ launcher.startActivity(intent, options.toBundle());
launcher.getUserEventDispatcher().logActionOnControl(LauncherLogProto.Action.Touch.TAP,
LauncherLogProto.ControlType.APP_USAGE_SETTINGS, this);
} catch (ActivityNotFoundException e) {
diff --git a/res/layout/all_apps.xml b/res/layout/all_apps.xml
index b1e6f2e..33ff46b 100644
--- a/res/layout/all_apps.xml
+++ b/res/layout/all_apps.xml
@@ -30,7 +30,50 @@
layout="@layout/all_apps_rv_layout"
android:visibility="gone" />
- <include layout="@layout/all_apps_floating_header" />
+ <com.android.launcher3.allapps.FloatingHeaderView
+ android:id="@+id/all_apps_header"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/search_container_all_apps"
+ android:clipToPadding="false"
+ android:paddingTop="@dimen/all_apps_header_top_padding"
+ android:orientation="vertical" >
+
+ <include layout="@layout/floating_header_content" />
+
+ <com.android.launcher3.allapps.PersonalWorkSlidingTabStrip
+ android:id="@+id/tabs"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/all_apps_header_tab_height"
+ android:layout_marginLeft="@dimen/all_apps_tabs_side_padding"
+ android:layout_marginRight="@dimen/all_apps_tabs_side_padding"
+ android:orientation="horizontal">
+
+ <Button
+ android:id="@+id/tab_personal"
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:background="?android:attr/selectableItemBackground"
+ android:fontFamily="sans-serif-medium"
+ android:text="@string/all_apps_personal_tab"
+ android:textAllCaps="true"
+ android:textColor="@color/all_apps_tab_text"
+ android:textSize="14sp" />
+
+ <Button
+ android:id="@+id/tab_work"
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:background="?android:attr/selectableItemBackground"
+ android:fontFamily="sans-serif-medium"
+ android:text="@string/all_apps_work_tab"
+ android:textAllCaps="true"
+ android:textColor="@color/all_apps_tab_text"
+ android:textSize="14sp" />
+ </com.android.launcher3.allapps.PersonalWorkSlidingTabStrip>
+ </com.android.launcher3.allapps.FloatingHeaderView>
<include
android:id="@id/search_container_all_apps"
diff --git a/res/layout/all_apps_floating_header.xml b/res/layout/all_apps_floating_header.xml
deleted file mode 100644
index c4240f8..0000000
--- a/res/layout/all_apps_floating_header.xml
+++ /dev/null
@@ -1,58 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<com.android.launcher3.allapps.FloatingHeaderView
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/all_apps_header"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_below="@id/search_container_all_apps"
- android:clipToPadding="false"
- android:paddingTop="@dimen/all_apps_header_top_padding"
- android:orientation="vertical" >
-
- <com.android.launcher3.allapps.PersonalWorkSlidingTabStrip
- android:id="@+id/tabs"
- android:layout_width="match_parent"
- android:layout_height="@dimen/all_apps_header_tab_height"
- android:layout_marginLeft="@dimen/all_apps_tabs_side_padding"
- android:layout_marginRight="@dimen/all_apps_tabs_side_padding"
- android:orientation="horizontal">
-
- <Button
- android:id="@+id/tab_personal"
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:background="?android:attr/selectableItemBackground"
- android:fontFamily="sans-serif-medium"
- android:text="@string/all_apps_personal_tab"
- android:textAllCaps="true"
- android:textColor="@color/all_apps_tab_text"
- android:textSize="14sp" />
-
- <Button
- android:id="@+id/tab_work"
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:background="?android:attr/selectableItemBackground"
- android:fontFamily="sans-serif-medium"
- android:text="@string/all_apps_work_tab"
- android:textAllCaps="true"
- android:textColor="@color/all_apps_tab_text"
- android:textSize="14sp" />
- </com.android.launcher3.allapps.PersonalWorkSlidingTabStrip>
-</com.android.launcher3.allapps.FloatingHeaderView>
diff --git a/res/layout/floating_header_content.xml b/res/layout/floating_header_content.xml
new file mode 100644
index 0000000..e4061c2
--- /dev/null
+++ b/res/layout/floating_header_content.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<merge />
\ No newline at end of file
diff --git a/src/com/android/launcher3/allapps/FloatingHeaderRow.java b/src/com/android/launcher3/allapps/FloatingHeaderRow.java
new file mode 100644
index 0000000..922e4f1
--- /dev/null
+++ b/src/com/android/launcher3/allapps/FloatingHeaderRow.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.allapps;
+
+import android.graphics.Rect;
+import android.view.animation.Interpolator;
+
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.anim.PropertySetter;
+
+/**
+ * A abstract representation of a row in all-apps view
+ */
+public interface FloatingHeaderRow {
+
+ FloatingHeaderRow[] NO_ROWS = new FloatingHeaderRow[0];
+
+ void setup(FloatingHeaderView parent, FloatingHeaderRow[] allRows, boolean tabsHidden);
+
+ void setInsets(Rect insets, DeviceProfile grid);
+
+ int getExpectedHeight();
+
+ /**
+ * Returns true if the row should draw based on its current position and layout.
+ */
+ boolean shouldDraw();
+
+ /**
+ * Returns true if the view has anything worth drawing. This is different than
+ * {@link #shouldDraw()} as this is called earlier in the layout to determine the view
+ * position.
+ */
+ boolean hasVisibleContent();
+
+ void setContentVisibility(boolean hasHeaderExtra, boolean hasContent,
+ PropertySetter setter, Interpolator fadeInterpolator);
+
+ /**
+ * Scrolls the content vertically.
+ */
+ void setVerticalScroll(int scroll, boolean isScrolledOut);
+
+ Class<? extends FloatingHeaderRow> getTypeClass();
+}
diff --git a/src/com/android/launcher3/allapps/FloatingHeaderView.java b/src/com/android/launcher3/allapps/FloatingHeaderView.java
index 90e195b..66dced9 100644
--- a/src/com/android/launcher3/allapps/FloatingHeaderView.java
+++ b/src/com/android/launcher3/allapps/FloatingHeaderView.java
@@ -19,28 +19,34 @@
import android.content.Context;
import android.graphics.Point;
import android.graphics.Rect;
+import android.util.ArrayMap;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Interpolator;
import android.widget.LinearLayout;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.recyclerview.widget.RecyclerView;
+
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.Insettable;
+import com.android.launcher3.Launcher;
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.AllAppsRow.OnHeightUpdatedListener;
import com.android.systemui.plugins.PluginListener;
import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
import java.util.Map;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.recyclerview.widget.RecyclerView;
+
public class FloatingHeaderView extends LinearLayout implements
- ValueAnimator.AnimatorUpdateListener, PluginListener<AllAppsRow> {
+ ValueAnimator.AnimatorUpdateListener, PluginListener<AllAppsRow>, Insettable,
+ OnHeightUpdatedListener {
private final Rect mClip = new Rect(0, 0, Integer.MAX_VALUE, Integer.MAX_VALUE);
private final ValueAnimator mAnimator = ValueAnimator.ofInt(0, 0);
@@ -62,17 +68,18 @@
int current = -mCurrentRV.getCurrentScrollY();
moved(current);
- apply();
+ applyVerticalMove();
}
};
+ private final int mHeaderTopPadding;
+
+ protected final Map<AllAppsRow, PluginHeaderRow> mPluginRows = new ArrayMap<>();
+
protected ViewGroup mTabLayout;
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;
@@ -85,20 +92,42 @@
protected int mMaxTranslation;
private boolean mMainRVActive = true;
+ private boolean mCollapsed = false;
+
+ // This is initialized once during inflation and stays constant after that. Fixed views
+ // cannot be added or removed dynamically.
+ private FloatingHeaderRow[] mFixedRows = FloatingHeaderRow.NO_ROWS;
+
+ // Array of all fixed rows and plugin rows. This is initialized every time a plugin is
+ // enabled or disabled, and represent the current set of all rows.
+ private FloatingHeaderRow[] mAllRows = FloatingHeaderRow.NO_ROWS;
+
public FloatingHeaderView(@NonNull Context context) {
this(context, null);
}
public FloatingHeaderView(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
- mPluginRows = new HashMap<>();
- mPluginRowViews = new ArrayList<>();
+ mHeaderTopPadding = context.getResources()
+ .getDimensionPixelSize(R.dimen.all_apps_header_top_padding);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
mTabLayout = findViewById(R.id.tabs);
+
+ // Find all floating header rows.
+ ArrayList<FloatingHeaderRow> rows = new ArrayList<>();
+ int count = getChildCount();
+ for (int i = 0; i < count; i++) {
+ View child = getChildAt(i);
+ if (child instanceof FloatingHeaderRow) {
+ rows.add((FloatingHeaderRow) child);
+ }
+ }
+ mFixedRows = rows.toArray(new FloatingHeaderRow[rows.size()]);
+ mAllRows = mFixedRows;
}
@Override
@@ -114,50 +143,70 @@
PluginManagerWrapper.INSTANCE.get(getContext()).removePluginListener(this);
}
- @Override
- public void onPluginConnected(AllAppsRow allAppsRowPlugin, Context context) {
- mPluginRows.put(allAppsRowPlugin, null);
- setupPluginRows();
- allAppsRowPlugin.setOnHeightUpdatedListener(this::onPluginRowHeightUpdated);
+ private void recreateAllRowsArray() {
+ int pluginCount = mPluginRows.size();
+ if (pluginCount == 0) {
+ mAllRows = mFixedRows;
+ } else {
+ int count = mFixedRows.length;
+ mAllRows = new FloatingHeaderRow[count + pluginCount];
+ for (int i = 0; i < count; i++) {
+ mAllRows[i] = mFixedRows[i];
+ }
+
+ for (PluginHeaderRow row : mPluginRows.values()) {
+ mAllRows[count] = row;
+ count++;
+ }
+ }
}
- protected void onPluginRowHeightUpdated() {
+ @Override
+ public void onPluginConnected(AllAppsRow allAppsRowPlugin, Context context) {
+ PluginHeaderRow headerRow = new PluginHeaderRow(allAppsRowPlugin, this);
+ addView(headerRow.mView, indexOfChild(mTabLayout));
+ mPluginRows.put(allAppsRowPlugin, headerRow);
+ recreateAllRowsArray();
+ allAppsRowPlugin.setOnHeightUpdatedListener(this);
+ }
+
+ @Override
+ public void onHeightUpdated() {
+ int oldMaxHeight = mMaxTranslation;
+ updateExpectedHeight();
+
+ if (mMaxTranslation != oldMaxHeight) {
+ AllAppsContainerView parent = (AllAppsContainerView) getParent();
+ if (parent != null) {
+ parent.setupHeader();
+ }
+ }
}
@Override
public void onPluginDisconnected(AllAppsRow plugin) {
- View pluginRowView = mPluginRows.get(plugin);
- removeView(pluginRowView);
+ PluginHeaderRow row = mPluginRows.get(plugin);
+ removeView(row.mView);
mPluginRows.remove(plugin);
- mPluginRowViews.remove(pluginRowView);
- onPluginRowHeightUpdated();
+ recreateAllRowsArray();
+ onHeightUpdated();
}
public void setup(AllAppsContainerView.AdapterHolder[] mAH, boolean tabsHidden) {
+ for (FloatingHeaderRow row : mAllRows) {
+ row.setup(this, mAllRows, tabsHidden);
+ }
+ updateExpectedHeight();
+
mTabsHidden = tabsHidden;
mTabLayout.setVisibility(tabsHidden ? View.GONE : View.VISIBLE);
mMainRV = setupRV(mMainRV, mAH[AllAppsContainerView.AdapterHolder.MAIN].recyclerView);
mWorkRV = setupRV(mWorkRV, mAH[AllAppsContainerView.AdapterHolder.WORK].recyclerView);
mParent = (ViewGroup) mMainRV.getParent();
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);
@@ -165,6 +214,16 @@
return updated;
}
+ private void updateExpectedHeight() {
+ mMaxTranslation = 0;
+ if (mCollapsed) {
+ return;
+ }
+ for (FloatingHeaderRow row : mAllRows) {
+ mMaxTranslation += row.getExpectedHeight();
+ }
+ }
+
public void setMainActive(boolean active) {
mCurrentRV = active ? mMainRV : mWorkRV;
mMainRVActive = active;
@@ -208,12 +267,21 @@
}
}
- protected void applyScroll(int uncappedY, int currentY) { }
-
- protected void apply() {
+ protected void applyVerticalMove() {
int uncappedTranslationY = mTranslationY;
mTranslationY = Math.max(mTranslationY, -mMaxTranslation);
- applyScroll(uncappedTranslationY, mTranslationY);
+
+ if (mCollapsed || uncappedTranslationY < mTranslationY - mHeaderTopPadding) {
+ // we hide it completely if already capped (for opening search anim)
+ for (FloatingHeaderRow row : mAllRows) {
+ row.setVerticalScroll(0, true /* isScrolledOut */);
+ }
+ } else {
+ for (FloatingHeaderRow row : mAllRows) {
+ row.setVerticalScroll(uncappedTranslationY, false /* isScrolledOut */);
+ }
+ }
+
mTabLayout.setTranslationY(mTranslationY);
mClip.top = mMaxTranslation + mTranslationY;
// clipping on a draw might cause additional redraw
@@ -223,6 +291,16 @@
}
}
+ /**
+ * Hides all the floating rows
+ */
+ public void setCollapsed(boolean collapse) {
+ if (mCollapsed == collapse) return;
+
+ mCollapsed = collapse;
+ onHeightUpdated();
+ }
+
public void reset(boolean animate) {
if (mAnimator.isStarted()) {
mAnimator.cancel();
@@ -234,7 +312,7 @@
mAnimator.start();
} else {
mTranslationY = 0;
- apply();
+ applyVerticalMove();
}
mHeaderCollapsed = false;
mSnappedScrolledY = -mMaxTranslation;
@@ -248,7 +326,7 @@
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mTranslationY = (Integer) animation.getAnimatedValue();
- apply();
+ applyVerticalMove();
}
@Override
@@ -287,8 +365,12 @@
public void setContentVisibility(boolean hasHeader, boolean hasContent, PropertySetter setter,
Interpolator fadeInterpolator) {
- setter.setViewAlpha(this, hasContent ? 1 : 0, fadeInterpolator);
+ for (FloatingHeaderRow row : mAllRows) {
+ row.setContentVisibility(hasHeader, hasContent, setter, fadeInterpolator);
+ }
+
allowTouchForwarding(hasContent);
+ setter.setFloat(mTabLayout, ALPHA, hasContent ? 1 : 0, fadeInterpolator);
}
protected void allowTouchForwarding(boolean allow) {
@@ -296,6 +378,11 @@
}
public boolean hasVisibleContent() {
+ for (FloatingHeaderRow row : mAllRows) {
+ if (row.hasVisibleContent()) {
+ return true;
+ }
+ }
return false;
}
@@ -303,6 +390,23 @@
public boolean hasOverlappingRendering() {
return false;
}
+
+ @Override
+ public void setInsets(Rect insets) {
+ DeviceProfile grid = Launcher.getLauncher(getContext()).getDeviceProfile();
+ for (FloatingHeaderRow row : mAllRows) {
+ row.setInsets(insets, grid);
+ }
+ }
+
+ public <T extends FloatingHeaderRow> T findFixedRowByType(Class<T> type) {
+ for (FloatingHeaderRow row : mAllRows) {
+ if (row.getTypeClass() == type) {
+ return (T) row;
+ }
+ }
+ return null;
+ }
}
diff --git a/src/com/android/launcher3/allapps/PluginHeaderRow.java b/src/com/android/launcher3/allapps/PluginHeaderRow.java
new file mode 100644
index 0000000..b283ff4
--- /dev/null
+++ b/src/com/android/launcher3/allapps/PluginHeaderRow.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.allapps;
+
+import static android.view.View.ALPHA;
+import static android.view.View.INVISIBLE;
+import static android.view.View.VISIBLE;
+
+import android.graphics.Rect;
+import android.view.View;
+import android.view.animation.Interpolator;
+
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.anim.PropertySetter;
+import com.android.systemui.plugins.AllAppsRow;
+
+/**
+ * Wrapper over an {@link AllAppsRow} plugin with {@link FloatingHeaderRow} interface so that
+ * it can be easily added in {@link FloatingHeaderView}.
+ */
+public class PluginHeaderRow implements FloatingHeaderRow {
+
+ private final AllAppsRow mPlugin;
+ final View mView;
+
+ PluginHeaderRow(AllAppsRow plugin, FloatingHeaderView parent) {
+ mPlugin = plugin;
+ mView = mPlugin.setup(parent);
+ }
+
+ @Override
+ public void setup(FloatingHeaderView parent, FloatingHeaderRow[] allRows,
+ boolean tabsHidden) { }
+
+ @Override
+ public void setInsets(Rect insets, DeviceProfile grid) { }
+
+ @Override
+ public int getExpectedHeight() {
+ return mPlugin.getExpectedHeight();
+ }
+
+ @Override
+ public boolean shouldDraw() {
+ return true;
+ }
+
+ @Override
+ public boolean hasVisibleContent() {
+ return true;
+ }
+
+ @Override
+ public void setContentVisibility(boolean hasHeaderExtra, boolean hasContent,
+ PropertySetter setter, Interpolator fadeInterpolator) {
+ // Don't use setViewAlpha as we want to control the visibility ourselves.
+ setter.setFloat(mView, ALPHA, hasContent ? 1 : 0, fadeInterpolator);
+ }
+
+ @Override
+ public void setVerticalScroll(int scroll, boolean isScrolledOut) {
+ mView.setVisibility(isScrolledOut ? INVISIBLE : VISIBLE);
+ if (!isScrolledOut) {
+ mView.setTranslationY(scroll);
+ }
+ }
+
+ @Override
+ public Class<PluginHeaderRow> getTypeClass() {
+ return PluginHeaderRow.class;
+ }
+}
\ No newline at end of file
diff --git a/src/com/android/launcher3/icons/IconCacheUpdateHandler.java b/src/com/android/launcher3/icons/IconCacheUpdateHandler.java
index c679da4..0c601b9 100644
--- a/src/com/android/launcher3/icons/IconCacheUpdateHandler.java
+++ b/src/com/android/launcher3/icons/IconCacheUpdateHandler.java
@@ -27,11 +27,8 @@
import android.util.Log;
import android.util.SparseBooleanArray;
-import com.android.launcher3.Utilities;
import com.android.launcher3.icons.BaseIconCache.IconDB;
-import com.android.launcher3.util.IntArray;
-import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
@@ -204,18 +201,31 @@
}
}
+ /**
+ * Commits all updates as part of the update handler to disk. Not more calls should be made
+ * to this class after this.
+ */
public void finish() {
// Commit all deletes
- IntArray deleteIds = new IntArray();
+ int deleteCount = 0;
+ StringBuilder queryBuilder = new StringBuilder()
+ .append(IconDB.COLUMN_ROWID)
+ .append(" IN (");
+
int count = mItemsToDelete.size();
for (int i = 0; i < count; i++) {
if (mItemsToDelete.valueAt(i)) {
- deleteIds.add(mItemsToDelete.keyAt(i));
+ if (deleteCount > 0) {
+ queryBuilder.append(", ");
+ }
+ queryBuilder.append(mItemsToDelete.keyAt(i));
+ deleteCount++;
}
}
- if (!deleteIds.isEmpty()) {
- mIconCache.mIconDb.delete(
- Utilities.createDbSelectionQuery(IconDB.COLUMN_ROWID, deleteIds), null);
+ queryBuilder.append(')');
+
+ if (deleteCount > 0) {
+ mIconCache.mIconDb.delete(queryBuilder.toString(), null);
}
}