summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--RemoteFolder/src/com/android/launcher3/RemoteFolderManager.java28
-rw-r--r--RemoteFolder/src/com/android/launcher3/RemoteFolderUpdater.java83
-rw-r--r--res/layout/app_drawer_item.xml33
-rw-r--r--res/layout/app_drawer_item_custom_header.xml3
-rw-r--r--res/values/dimens.xml21
-rw-r--r--src/com/android/launcher3/AppDrawerIconView.java1
-rw-r--r--src/com/android/launcher3/AppDrawerListAdapter.java64
-rw-r--r--src/com/android/launcher3/AppInfo.java8
-rw-r--r--src/com/android/launcher3/Folder.java126
-rw-r--r--src/com/android/launcher3/FolderIcon.java18
-rw-r--r--src/com/android/launcher3/Launcher.java17
-rw-r--r--src/com/android/launcher3/LauncherApplication.java2
-rw-r--r--src/com/android/launcher3/LauncherModel.java43
-rw-r--r--src/com/android/launcher3/RemoteFolder.java229
-rw-r--r--src/com/android/launcher3/ShortcutInfo.java11
-rw-r--r--src/com/android/launcher3/stats/LauncherStats.java35
-rw-r--r--src/com/android/launcher3/stats/internal/model/TrackingEvent.java8
17 files changed, 161 insertions, 569 deletions
diff --git a/RemoteFolder/src/com/android/launcher3/RemoteFolderManager.java b/RemoteFolder/src/com/android/launcher3/RemoteFolderManager.java
index c93b8338b..61a003399 100644
--- a/RemoteFolder/src/com/android/launcher3/RemoteFolderManager.java
+++ b/RemoteFolder/src/com/android/launcher3/RemoteFolderManager.java
@@ -1,5 +1,7 @@
package com.android.launcher3;
+import java.util.ArrayList;
+
/**
* Manages adding and removing the remote folder from the workspace.
*/
@@ -7,7 +9,12 @@ public class RemoteFolderManager {
public RemoteFolderManager(final Launcher launcher) { }
- public void setRemoteFolder(final FolderIcon remoteFolder) { }
+ /**
+ * Create a remote folder view.
+ * @param icon folder icon view on the workspace.
+ * @return a view for the remote folder.
+ */
+ public Folder createRemoteFolder(final FolderIcon icon) { return null; }
/**
* Called when Launcher finishes binding items from the model.
@@ -31,7 +38,26 @@ public class RemoteFolderManager {
public void onAppDrawerOpened() { }
/**
+ * Called when new apps are added to launcher.
+ * @param apps list of added apps.
+ */
+ public void onBindAddApps(ArrayList<AppInfo> apps) { }
+
+ /**
* Called when the info icon is clicked
*/
public void onInfoIconClicked() { }
+
+ /**
+ * Called when the view holder is created for the remote header.
+ * @param holder remote view holder.
+ */
+ public void onCreateViewHolder(final AppDrawerListAdapter.ViewHolder holder) { }
+ /**
+ * Called when the view holder is bound for the remote header.
+ * @param holder remote view holder.
+ * @param indexedInfo header info.
+ */
+ public void onBindViewHolder(final AppDrawerListAdapter.ViewHolder holder,
+ final AppDrawerListAdapter.AppItemIndexedInfo indexedInfo) { }
}
diff --git a/RemoteFolder/src/com/android/launcher3/RemoteFolderUpdater.java b/RemoteFolder/src/com/android/launcher3/RemoteFolderUpdater.java
deleted file mode 100644
index 954595e1f..000000000
--- a/RemoteFolder/src/com/android/launcher3/RemoteFolderUpdater.java
+++ /dev/null
@@ -1,83 +0,0 @@
-package com.android.launcher3;
-
-import android.content.Context;
-import android.content.Intent;
-import android.graphics.Bitmap;
-import android.view.View;
-import java.util.List;
-import android.util.Log;
-
-public class RemoteFolderUpdater {
-
- private static final String TAG = "RemoteFolderUpdater";
-
- private static final Object sLock = new Object();
- private static RemoteFolderUpdater sInstance;
-
- public interface RemoteFolderUpdateListener {
- void onSuccess(List<RemoteFolderInfo> remoteFolderInfoList);
- void onFailure(String error);
- }
-
- public static RemoteFolderUpdater getInstance() {
- synchronized (sLock) {
- if (sInstance == null) {
- sInstance = new RemoteFolderUpdater();
- }
-
- return sInstance;
- }
- }
-
- private RemoteFolderUpdater() { }
-
- /**
- * Requests data needed by remote folders.
- * @param context
- * @param size
- * @param listener
- */
- public synchronized void requestSync(Context context, final int size, final RemoteFolderUpdateListener listener) {
- if (listener != null) {
- listener.onFailure("RemoteFolderUpdater may not have been properly setup");
- }
- }
-
- /**
- * Register a callback to track clicks on our individual Remote Folder items. Make sure the
- * intent associated with each item has a unique ID.
- *
- * @param view The individual item the user may click (or just clicked)
- * @param intent The intent associated with the ShortcutInfo that belongs to our view
- */
- public void registerViewForInteraction(View view, Intent intent) {
- Log.e(TAG, "Couldn't register view for user interaction, RemoteFolderUpdater may not have been properly setup");
- }
-
- /**
- * Holds important information that the launcher will need for each item in the remote folder.
- */
- public class RemoteFolderInfo {
-
- public void setRecommendationData(View view) {
- return;
- }
-
- public String getTitle() {
- return null;
- }
-
- public Bitmap getIcon() {
- return null;
- }
-
- public String getIconUrl() {
- return null;
- }
-
- public Intent getIntent() {
- return null;
- }
- }
-
-}
diff --git a/res/layout/app_drawer_item.xml b/res/layout/app_drawer_item.xml
index d8b3eb43e..03ca60a00 100644
--- a/res/layout/app_drawer_item.xml
+++ b/res/layout/app_drawer_item.xml
@@ -30,28 +30,9 @@
android:layout_alignBottom="@+id/drawer_item_flow"
android:background="@color/app_drawer_drag_background" />
- <TextView
- android:id="@+id/custom_title"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textColor="@android:color/white"
- android:textSize="@dimen/drawer_custom_title_text_size"
- android:layout_marginStart="@dimen/drawer_custom_title_margin_start"
- android:layout_marginTop="@dimen/drawer_custom_title_margin_top"
- android:includeFontPadding="false"
- android:fontFamily="roboto-light"
- android:text="@string/recommendations_title"
- android:visibility="gone" />
-
- <ImageView
- android:id="@+id/custom_title_icon"
- android:layout_width="@dimen/drawer_custom_icon_size"
- android:layout_height="@dimen/drawer_custom_icon_size"
- android:layout_marginEnd="@dimen/drawer_custom_icon_margin_end"
- android:layout_marginTop="@dimen/drawer_custom_icon_margin_top"
- android:layout_alignParentEnd="true"
- android:src="@drawable/triangle_icon"
- android:visibility="gone" />
+ <include
+ android:id="@+id/custom_header_layout"
+ layout="@layout/app_drawer_item_custom_header" />
<LinearLayout
android:id="@+id/drawer_item_flow"
@@ -59,7 +40,7 @@
android:layout_toEndOf="@+id/drawer_item_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_below="@id/custom_title"
+ android:layout_below="@id/custom_header_layout"
android:orientation="horizontal" />
<View
@@ -75,17 +56,17 @@
android:id="@id/drawer_item_title"
android:layout_width="@dimen/drawer_header_text_char_width"
android:layout_height="wrap_content"
- android:layout_marginTop="@dimen/drawer_header_text_margin_top_default"
+ android:layout_marginTop="@dimen/drawer_header_text_margin_top"
android:layout_marginBottom="@dimen/drawer_header_text_margin_bottom"
android:layout_marginStart="@dimen/drawer_header_text_margin_start"
- android:layout_alignTop="@id/custom_title"
+ android:layout_alignTop="@id/custom_header_layout"
android:layout_alignWithParentIfMissing="true"
android:layout_alignBottom="@id/drawer_item_flow"
android:includeFontPadding="false"
android:gravity="center"
android:singleLine="true"
autofit:minTextSize="@dimen/drawer_header_text_min_text_size"
- android:textSize="@dimen/drawer_header_text_size_default"
+ android:textSize="@dimen/drawer_header_text_size"
android:fontFamily="sans-serif-light"
android:textColor="@android:color/white"
android:shadowRadius="@dimen/drawer_header_text_shadow_radius"
diff --git a/res/layout/app_drawer_item_custom_header.xml b/res/layout/app_drawer_item_custom_header.xml
new file mode 100644
index 000000000..14c171ee6
--- /dev/null
+++ b/res/layout/app_drawer_item_custom_header.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="utf-8"?>
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+</merge> \ No newline at end of file
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index f6459a5da..088640f89 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -136,28 +136,11 @@
<dimen name="drawer_header_text_min_text_size">8sp</dimen>
<dimen name="drawer_header_text_margin_bottom">24dp</dimen>
<dimen name="drawer_header_text_margin_start">6dp</dimen>
+ <dimen name="drawer_header_text_margin_top">6dp</dimen>
+ <dimen name="drawer_header_text_size">20sp</dimen>
<item name="drawer_header_text_shadow_radius" format="float" type="dimen">4</item>
<item name="drawer_header_text_shadow_dy" format="float" type="dimen">2</item>
- <!-- Custom/default variances -->
- <dimen name="drawer_header_text_size_default">20sp</dimen>
- <dimen name="drawer_header_text_margin_top_default">6dp</dimen>
- <dimen name="drawer_item_flow_padding_bottom_default">0dp</dimen>
- <dimen name="drawer_container_bottom_margin_default">0dp</dimen>
-
- <dimen name="drawer_header_text_size_custom">16sp</dimen>
- <dimen name="drawer_header_text_margin_top_custom">-2dp</dimen>
- <dimen name="drawer_item_flow_padding_bottom_custom">15dp</dimen>
- <dimen name="drawer_container_bottom_margin_custom">20dp</dimen>
-
- <!-- Custom header -->
- <dimen name="drawer_custom_title_text_size">16sp</dimen>
- <dimen name="drawer_custom_title_margin_start">50dp</dimen>
- <dimen name="drawer_custom_title_margin_top">15dp</dimen>
- <dimen name="drawer_custom_icon_margin_top">20dp</dimen>
- <dimen name="drawer_custom_icon_margin_end">14dp</dimen>
- <dimen name="drawer_custom_icon_size">12dp</dimen>
-
<!-- Folder open animation -->
<integer name="folder_translate_y_dist">300</integer>
<integer name="folder_icon_translate_y_dist">100</integer>
diff --git a/src/com/android/launcher3/AppDrawerIconView.java b/src/com/android/launcher3/AppDrawerIconView.java
index 94b5e93f4..d8564b6ed 100644
--- a/src/com/android/launcher3/AppDrawerIconView.java
+++ b/src/com/android/launcher3/AppDrawerIconView.java
@@ -33,7 +33,6 @@ public class AppDrawerIconView extends LinearLayout {
TextView mLabel;
ImageView mIcon;
- boolean mDraggable = true;
public AppDrawerIconView(Context context) {
super(context);
diff --git a/src/com/android/launcher3/AppDrawerListAdapter.java b/src/com/android/launcher3/AppDrawerListAdapter.java
index fb47eb816..b3001e527 100644
--- a/src/com/android/launcher3/AppDrawerListAdapter.java
+++ b/src/com/android/launcher3/AppDrawerListAdapter.java
@@ -53,7 +53,7 @@ import java.util.LinkedHashMap;
* AppDrawerListAdapter - list adapter for the vertical app drawer
*/
public class AppDrawerListAdapter extends RecyclerView.Adapter<AppDrawerListAdapter.ViewHolder>
- implements View.OnLongClickListener, View.OnClickListener, DragSource, SectionIndexer {
+ implements View.OnLongClickListener, DragSource, SectionIndexer {
public static final String REMOTE_HEADER = "☆";
public static final String REMOTE_SCRUBBER = "★";
@@ -87,7 +87,7 @@ public class AppDrawerListAdapter extends RecyclerView.Adapter<AppDrawerListAdap
}
private static Bucket getBucketForApp(AppInfo app) {
- if (app.isRemote()) {
+ if (app.hasFlag(AppInfo.REMOTE_APP_FLAG)) {
return new Bucket(Integer.MIN_VALUE, REMOTE_HEADER);
} else {
LocaleUtils localeUtils = LocaleUtils.getInstance();
@@ -101,6 +101,8 @@ public class AppDrawerListAdapter extends RecyclerView.Adapter<AppDrawerListAdap
}
}
+ private final RemoteFolderManager mRemoteFolderManager;
+
private HashSet<AppInfo> mAllApps;
private ArrayList<AppItemIndexedInfo> mHeaderList;
private LayoutInflater mLayoutInflater;
@@ -147,8 +149,6 @@ public class AppDrawerListAdapter extends RecyclerView.Adapter<AppDrawerListAdap
public static int TYPE_NORMAL = 0;
public static int TYPE_CUSTOM = 1;
- public TextView mCustomTitleTextView;
- public ImageView mCustomImageView;
public AutoFitTextView mHeaderTextView;
public ViewGroup mIconLayout;
public View mContainerView;
@@ -161,8 +161,6 @@ public class AppDrawerListAdapter extends RecyclerView.Adapter<AppDrawerListAdap
mFadingBackgroundFrontView = itemView.findViewById(R.id.fading_background_front);
mHeaderTextView = (AutoFitTextView) itemView.findViewById(R.id.drawer_item_title);
mHeaderTextView.bringToFront();
- mCustomTitleTextView = (TextView) itemView.findViewById(R.id.custom_title);
- mCustomImageView = (ImageView) itemView.findViewById(R.id.custom_title_icon);
mIconLayout = (ViewGroup) itemView.findViewById(R.id.drawer_item_flow);
}
}
@@ -411,6 +409,8 @@ public class AppDrawerListAdapter extends RecyclerView.Adapter<AppDrawerListAdap
mAllApps = new HashSet<AppInfo>();
mLayoutInflater = LayoutInflater.from(launcher);
+ mRemoteFolderManager = mLauncher.getRemoteFolderManager();
+
mLocaleSetManager = new LocaleSetManager(mLauncher);
mLocaleSetManager.updateLocaleSet(mLocaleSetManager.getSystemLocaleSet());
mItemAnimatorSet = new ItemAnimatorSet(launcher);
@@ -600,8 +600,7 @@ public class AppDrawerListAdapter extends RecyclerView.Adapter<AppDrawerListAdap
}
if (viewType == ViewHolder.TYPE_CUSTOM) {
- applyCustomStyle(holder);
- holder.mCustomImageView.setOnClickListener(this);
+ mRemoteFolderManager.onCreateViewHolder(holder);
}
return holder;
@@ -686,20 +685,18 @@ public class AppDrawerListAdapter extends RecyclerView.Adapter<AppDrawerListAdap
mDeviceProfile.iconDrawablePaddingPx);
icon.mLabel.setText(info.title);
icon.mLabel.setVisibility(mHideIconLabels ? View.INVISIBLE : View.VISIBLE);
-
- if (info.isRemote()) {
- RemoteFolderUpdater.getInstance()
- .registerViewForInteraction(icon, info.getIntent());
- icon.mDraggable = false;
- }
}
}
holder.itemView.setTag(indexedInfo);
+
+ if (indexedInfo.isRemote()) {
+ mRemoteFolderManager.onBindViewHolder(holder, indexedInfo);
+ }
}
@Override
public boolean onLongClick(View v) {
- if (v instanceof AppDrawerIconView && ((AppDrawerIconView) v).mDraggable) {
+ if (v instanceof AppDrawerIconView) {
beginDraggingApplication(v);
mLauncher.enterSpringLoadedDragMode();
}
@@ -707,13 +704,6 @@ public class AppDrawerListAdapter extends RecyclerView.Adapter<AppDrawerListAdap
}
@Override
- public void onClick(View v) {
- if (v.getId() == R.id.custom_title_icon) {
- mLauncher.getRemoteFolderManager().onInfoIconClicked();
- }
- }
-
- @Override
public void onDropCompleted(View target, DropTarget.DragObject d, boolean isFlingToDelete,
boolean success) {
// Return early and wait for onFlingToDeleteCompleted if this was the result of a fling
@@ -829,6 +819,10 @@ public class AppDrawerListAdapter extends RecyclerView.Adapter<AppDrawerListAdap
public boolean isRemote() {
return mStartString == REMOTE_HEADER;
}
+
+ public ArrayList<AppInfo> getInfo() {
+ return mInfo;
+ }
}
@Override
@@ -893,30 +887,4 @@ public class AppDrawerListAdapter extends RecyclerView.Adapter<AppDrawerListAdap
}
}
}
-
- /**
- * Remote header uses a custom styled view. Apply it here.
- * @param holder view which needs a custom style.
- */
- private void applyCustomStyle(final ViewHolder holder) {
- Resources res = mLauncher.getResources();
- RelativeLayout.LayoutParams lp =
- (RelativeLayout.LayoutParams) holder.mHeaderTextView.getLayoutParams();
- lp.removeRule(RelativeLayout.ALIGN_BOTTOM);
- lp.topMargin = res.getDimensionPixelOffset(R.dimen.drawer_header_text_margin_top_custom);
-
- holder.mContainerView.setBackgroundColor(
- res.getColor(R.color.drawer_container_background_custom));
- holder.mCustomTitleTextView.setVisibility(View.VISIBLE);
- holder.mCustomImageView.setVisibility(View.VISIBLE);
- holder.mHeaderTextView.setTextSize(
- res.getDimension(R.dimen.drawer_header_text_size_custom));
- holder.mIconLayout.setPadding(0, 0, 0,
- res.getDimensionPixelOffset(R.dimen.drawer_item_flow_padding_bottom_custom));
-
- RecyclerView.LayoutParams containerLP =
- (RecyclerView.LayoutParams) holder.mContainerView.getLayoutParams();
- containerLP.bottomMargin =
- res.getDimensionPixelOffset(R.dimen.drawer_container_bottom_margin_custom);
- }
}
diff --git a/src/com/android/launcher3/AppInfo.java b/src/com/android/launcher3/AppInfo.java
index e8767e67e..907b42cd9 100644
--- a/src/com/android/launcher3/AppInfo.java
+++ b/src/com/android/launcher3/AppInfo.java
@@ -142,10 +142,12 @@ public class AppInfo extends ItemInfo {
}
/**
- * @return true if this info represents a remote app, false otherwise
+ * Check if this app has a specific flag.
+ * @param flag flag to check.
+ * @return true if the flag is present, false otherwise.
*/
- public boolean isRemote() {
- return (flags & REMOTE_APP_FLAG) != 0;
+ public boolean hasFlag(int flag) {
+ return (flags & flag) != 0;
}
@Override
diff --git a/src/com/android/launcher3/Folder.java b/src/com/android/launcher3/Folder.java
index 2bd656565..b3b690042 100644
--- a/src/com/android/launcher3/Folder.java
+++ b/src/com/android/launcher3/Folder.java
@@ -62,7 +62,6 @@ import android.widget.ScrollView;
import android.widget.TextView;
import com.android.launcher3.FolderInfo.FolderListener;
-import com.android.launcher3.compat.UserHandleCompat;
import com.android.launcher3.settings.SettingsProvider;
import java.util.ArrayList;
@@ -485,69 +484,36 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
mInfo = info;
final ArrayList<ShortcutInfo> children = info.contents;
- if (info.isRemote() && children.isEmpty()) {
- final int count = 6;
- RemoteFolderUpdater updater = RemoteFolderUpdater.getInstance();
- updater.requestSync(getContext(), count, new RemoteFolderUpdater.RemoteFolderUpdateListener() {
- @Override
- public void onSuccess(List<RemoteFolderUpdater.RemoteFolderInfo> remoteFolderInfoList) {
- children.clear();
- for (RemoteFolderUpdater.RemoteFolderInfo remoteFolderInfo : remoteFolderInfoList) {
- ShortcutInfo shortcutInfo = new ShortcutInfo(remoteFolderInfo.getIntent(),
- remoteFolderInfo.getTitle(),
- remoteFolderInfo.getTitle(),
- remoteFolderInfo.getIcon(),
- UserHandleCompat.myUserHandle());
- children.add(shortcutInfo);
-
- View child = mLauncher.createShortcut(R.layout.application, mContent,
- shortcutInfo);
- remoteFolderInfo.setRecommendationData(child);
- LauncherModel.addOrMoveItemInDatabase(mLauncher, shortcutInfo, info.container,
- info.screenId, info.cellX, info.cellY);
- }
- info.contents = children;
- bind(info);
- }
-
- @Override
- public void onFailure(String error) {
- Log.e(TAG, "Failed to sync data for the remote folder's shortcuts. Reason: " + error);
- setupContentForNumItems(count);
- }
- });
- } else {
- ArrayList<ShortcutInfo> overflow = new ArrayList<ShortcutInfo>();
- setupContentForNumItems(children.size());
- placeInReadingOrder(children);
- int count = 0;
- for (int i = 0; i < children.size(); i++) {
- ShortcutInfo child = (ShortcutInfo) children.get(i);
- if (createAndAddShortcut(child) == null) {
- overflow.add(child);
- } else {
- count++;
- }
+ ArrayList<ShortcutInfo> overflow = new ArrayList<ShortcutInfo>();
+ setupContentForNumItems(children.size());
+ placeInReadingOrder(children);
+ int count = 0;
+ for (int i = 0; i < children.size(); i++) {
+ ShortcutInfo child = (ShortcutInfo) children.get(i);
+ if (createAndAddShortcut(child) == null) {
+ overflow.add(child);
+ } else {
+ count++;
}
+ }
- // We rearrange the items in case there are any empty gaps
- setupContentForNumItems(count);
+ // We rearrange the items in case there are any empty gaps
+ setupContentForNumItems(count);
- // If our folder has too many items we prune them from the list. This is an issue
- // when upgrading from the old Folders implementation which could contain an unlimited
- // number of items.
- for (ShortcutInfo item: overflow) {
- mInfo.remove(item);
- LauncherModel.deleteItemFromDatabase(mLauncher, item);
- }
+ // If our folder has too many items we prune them from the list. This is an issue
+ // when upgrading from the old Folders implementation which could contain an unlimited
+ // number of items.
+ for (ShortcutInfo item: overflow) {
+ mInfo.remove(item);
+ LauncherModel.deleteItemFromDatabase(mLauncher, item);
+ }
- mItemsInvalidated = true;
- updateTextViewFocus();
- mInfo.addListener(this);
+ mItemsInvalidated = true;
+ updateTextViewFocus();
+ mInfo.addListener(this);
- setFolderName();
- updateItemLocationsInDatabase();
- }
+ setFolderName();
+ updateItemLocationsInDatabase();
}
public void setFolderName() {
@@ -1264,7 +1230,16 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
// Do nothing
}
+ /**
+ * @return true if contents should persist their status to the database.
+ */
+ protected boolean shouldUpdateContentsInDatabase() {
+ return true;
+ }
+
private void updateItemLocationsInDatabase() {
+ if (!shouldUpdateContentsInDatabase()) return;
+
ArrayList<View> list = getItemsInReadingOrder();
for (int i = 0; i < list.size(); i++) {
View v = list.get(i);
@@ -1275,6 +1250,8 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
}
private void updateItemLocationsInDatabaseBatch() {
+ if (!shouldUpdateContentsInDatabase()) return;
+
ArrayList<View> list = getItemsInReadingOrder();
ArrayList<ItemInfo> items = new ArrayList<ItemInfo>();
for (int i = 0; i < list.size(); i++) {
@@ -1287,6 +1264,8 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
}
public void addItemLocationsInDatabase() {
+ if (!shouldUpdateContentsInDatabase()) return;
+
ArrayList<View> list = getItemsInReadingOrder();
for (int i = 0; i < list.size(); i++) {
View v = list.get(i);
@@ -1475,8 +1454,11 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
if (info.cellX != vacant[0] || info.cellY != vacant[1]) {
info.cellX = vacant[0];
info.cellY = vacant[1];
- LauncherModel.addOrMoveItemInDatabase(mLauncher, info, mInfo.id, 0,
- info.cellX, info.cellY);
+
+ if (shouldUpdateContentsInDatabase()) {
+ LauncherModel.addOrMoveItemInDatabase(mLauncher, info, mInfo.id, 0,
+ info.cellX, info.cellY);
+ }
}
boolean insert = false;
mContent.addViewToCellLayout(v, insert ? 0 : -1, (int)info.id, lp, true);
@@ -1515,11 +1497,7 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
mSuppressFolderDeletion = false;
}
- private void replaceFolderWithFinalItem() {
- if (mInfo.isRemote()) {
- return;
- }
-
+ protected void replaceFolderWithFinalItem() {
if (mInfo.hidden && getItemCount() >= 1) {
return;
}
@@ -1609,8 +1587,10 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
// Actually move the item in the database if it was an external drag. Call this
// before creating the view, so that ShortcutInfo is updated appropriately.
- LauncherModel.addOrMoveItemInDatabase(
- mLauncher, si, mInfo.id, 0, si.cellX, si.cellY);
+ if (shouldUpdateContentsInDatabase()) {
+ LauncherModel.addOrMoveItemInDatabase(
+ mLauncher, si, mInfo.id, 0, si.cellX, si.cellY);
+ }
// We only need to update the locations if it doesn't get handled in #onDropCompleted.
if (d.dragSource != this) {
@@ -1676,15 +1656,11 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList
findAndSetEmptyCells(item);
}
createAndAddShortcut(item);
- LauncherModel.addOrMoveItemInDatabase(
- mLauncher, item, mInfo.id, 0, item.cellX, item.cellY);
- // If this is a Remote Folder, we need to register each view with our updater for click handling.
- if (mInfo.isRemote()) {
- RemoteFolderUpdater updater = RemoteFolderUpdater.getInstance();
- updater.registerViewForInteraction(getViewForInfo(item), item.getIntent());
+ if (shouldUpdateContentsInDatabase()) {
+ LauncherModel.addOrMoveItemInDatabase(
+ mLauncher, item, mInfo.id, 0, item.cellX, item.cellY);
}
-
}
public void onRemove(ShortcutInfo item) {
diff --git a/src/com/android/launcher3/FolderIcon.java b/src/com/android/launcher3/FolderIcon.java
index 33787ab35..17ea4899d 100644
--- a/src/com/android/launcher3/FolderIcon.java
+++ b/src/com/android/launcher3/FolderIcon.java
@@ -170,19 +170,17 @@ public class FolderIcon extends FrameLayout implements FolderListener {
icon.mLauncher = launcher;
icon.setContentDescription(String.format(launcher.getString(R.string.folder_name_format),
folderInfo.title));
+ Folder folder;
if (folderInfo.isRemote()) {
- RemoteFolder folder = RemoteFolder.fromXml(launcher);
- folder.setDragController(launcher.getDragController());
- folder.setFolderIcon(icon);
- folder.bind(folderInfo);
- icon.mFolder = folder;
+ folder = launcher.getRemoteFolderManager().createRemoteFolder(icon);
} else {
- Folder folder = Folder.fromXml(launcher);
- folder.setDragController(launcher.getDragController());
- folder.setFolderIcon(icon);
- folder.bind(folderInfo);
- icon.mFolder = folder;
+ folder = Folder.fromXml(launcher);
}
+ folder.setDragController(launcher.getDragController());
+ folder.setFolderIcon(icon);
+ folder.bind(folderInfo);
+ icon.mFolder = folder;
+
icon.mFolderRingAnimator = new FolderRingAnimator(launcher, icon);
folderInfo.addListener(icon);
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index ff59dce08..7fc373061 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -2984,14 +2984,6 @@ public class Launcher extends Activity
onClickAllAppsButton(v);
} else if (tag instanceof AppInfo) {
AppInfo info = (AppInfo) tag;
-
- // Remote apps do not exist in package manager, so they should be launched
- // directly by intent.
- if (info.isRemote()) {
- startActivity(info.intent);
- return;
- }
-
startAppShortcutOrInfoActivity(v);
LauncherApplication.getLauncherStats().sendAppLaunchEvent(
LauncherStats.ORIGIN_APPDRAWER, info.componentName.getPackageName());
@@ -3242,10 +3234,6 @@ public class Launcher extends Activity
closeFolder();
// Open the requested folder
openFolder(folderIcon, folderTouchXYOffset);
-
- if (info.isRemote()) {
- mModel.syncRemoteFolder(info, this);
- }
} else {
// Find the open folder...
int folderScreen;
@@ -4882,6 +4870,7 @@ public class Launcher extends Activity
addedApps != null && mAppsCustomizeContent != null) {
mAppsCustomizeContent.addApps(addedApps);
mAppDrawerAdapter.addApps(addedApps);
+ mRemoteFolderManager.onBindAddApps(addedApps);
}
}
@@ -4962,10 +4951,6 @@ public class Launcher extends Activity
newFolder.setTextVisible(!mHideIconLabels);
workspace.addInScreenFromBind(newFolder, item.container, item.screenId, item.cellX,
item.cellY, 1, 1);
-
- if (((FolderInfo) item).isRemote()) {
- mRemoteFolderManager.setRemoteFolder(newFolder);
- }
break;
default:
throw new RuntimeException("Invalid Item Type");
diff --git a/src/com/android/launcher3/LauncherApplication.java b/src/com/android/launcher3/LauncherApplication.java
index eab9861bd..3facb3c21 100644
--- a/src/com/android/launcher3/LauncherApplication.java
+++ b/src/com/android/launcher3/LauncherApplication.java
@@ -66,7 +66,7 @@ public class LauncherApplication extends Application {
if (getResources().getBoolean(R.bool.config_launcher_stkAppRename)) {
registerAppNameChangeReceiver();
}
- sLauncherStats = LauncherStats.createInstance(this);
+ sLauncherStats = LauncherStats.getInstance(this);
AggregationIntentService.scheduleService(this);
}
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index 050c1f759..78630afea 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -2387,11 +2387,6 @@ public class LauncherModel extends BroadcastReceiver
sBgItemsIdMap.put(folderInfo.id, folderInfo);
sBgFolders.put(folderInfo.id, folderInfo);
-
- if (folderInfo.isRemote()) {
- syncRemoteFolder(folderInfo, mContext);
- }
-
break;
case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:
@@ -4253,42 +4248,4 @@ public class LauncherModel extends BroadcastReceiver
public Callbacks getCallback() {
return mCallbacks != null ? mCallbacks.get() : null;
}
-
- protected synchronized void syncRemoteFolder(final FolderInfo folderInfo, final Context context) {
- RemoteFolderUpdater updater = RemoteFolderUpdater.getInstance();
- final int count = 6;
-
- updater.requestSync(context, count, new RemoteFolderUpdater.RemoteFolderUpdateListener() {
- @Override
- public void onSuccess(List<RemoteFolderUpdater.RemoteFolderInfo> remoteFolderInfoList) {
-
- synchronized (mLock) {
-
- // Clear contents to prevent any duplicates
- if (folderInfo.contents != null && !folderInfo.contents.isEmpty()) {
- deleteItemsFromDatabase(context, folderInfo.contents);
- folderInfo.contents.clear();
- }
-
- // Add each remote folder item, update the DB, and notify listeners
- for (RemoteFolderUpdater.RemoteFolderInfo remoteFolderInfo : remoteFolderInfoList) {
- ShortcutInfo shortcutInfo = new ShortcutInfo(remoteFolderInfo.getIntent(),
- remoteFolderInfo.getTitle(),
- remoteFolderInfo.getTitle(),
- remoteFolderInfo.getIcon(),
- UserHandleCompat.myUserHandle());
- folderInfo.add(shortcutInfo);
- }
-
- updateItemInDatabase(context, folderInfo);
- folderInfo.itemsChanged();
- }
- }
-
- @Override
- public void onFailure(String error) {
- Log.e(TAG, "Failed to sync data for the remote folder's shortcuts. Reason: " + error);
- }
- });
- }
}
diff --git a/src/com/android/launcher3/RemoteFolder.java b/src/com/android/launcher3/RemoteFolder.java
deleted file mode 100644
index 136489466..000000000
--- a/src/com/android/launcher3/RemoteFolder.java
+++ /dev/null
@@ -1,229 +0,0 @@
-package com.android.launcher3;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.text.TextUtils;
-import android.util.AttributeSet;
-import android.util.DisplayMetrics;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.Button;
-import android.widget.ImageView;
-import android.widget.ScrollView;
-import android.widget.TextView;
-
-/**
- * Created by tmiller on 11/24/15.
- */
-public class RemoteFolder extends Folder {
-
- public static final String TAG = "RemoteFolder";
- public static final String REMOTE_FOLDER_ENABLED = "remote_folder_enabled";
- private ScrollView mContentScrollView;
- private ImageView mFolderInfo;
- private TextView mFolderHelpText;
- private Button mCloseInfoButton;
- private View mFolderInfoContainer;
-
- private int mFolderInfoContainerHeight;
- private int mHelpTextHeight;
- private int mHelpTextWidth;
- private int mButtonHeight;
- private int mFolderInfoIconHeight;
- /**
- * Used to inflate the Workspace from XML.
- *
- * @param context The application's context.
- * @param attrs The attribtues set containing the Workspace's customization values.
- */
- public RemoteFolder(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- /**
- * Creates a new UserFolder, inflated from R.layout.remote_folder.
- *
- * @param context The application's context.
- *
- * @return A new UserFolder.
- */
- static RemoteFolder fromXml(Context context) {
- return (RemoteFolder) LayoutInflater.from(context).inflate(R.layout.remote_folder, null);
- }
-
- @Override
- protected void onFinishInflate() {
- super.onFinishInflate();
- int measureSpec = MeasureSpec.UNSPECIFIED;
-
- mContentScrollView = (ScrollView) findViewById(R.id.scroll_view);
-
- mFolderInfoContainer = findViewById(R.id.folder_info_container);
- mFolderInfoContainer.measure(measureSpec, measureSpec);
- mFolderInfoContainerHeight = mFolderInfoContainer.getMeasuredHeight();
-
- mFolderInfo = (ImageView) findViewById(R.id.folder_info);
- mFolderInfo.measure(measureSpec, measureSpec);
- mFolderInfoIconHeight = mFolderInfo.getMeasuredHeight();
- mFolderInfo.setOnClickListener(this);
-
- mFolderHelpText = (TextView) findViewById(R.id.help_text_view);
- mFolderHelpText.setText(getResources().getString(R.string.recommendations_help_text));
- mFolderHelpText.measure(measureSpec, measureSpec);
- mHelpTextHeight = (mFolderHelpText.getLineHeight() * mFolderHelpText.getLineCount()) +
- mFolderHelpText.getPaddingTop() + mFolderHelpText.getPaddingBottom();
- mHelpTextWidth = mFolderHelpText.getMeasuredWidth();
- mFolderHelpText.setVisibility(GONE);
-
- mCloseInfoButton = (Button) findViewById(R.id.close_info_button);
- mCloseInfoButton.setText(getResources().getString(R.string.close));
- mCloseInfoButton.measure(measureSpec, measureSpec);
- mButtonHeight = mCloseInfoButton.getMeasuredHeight();
- mCloseInfoButton.setOnClickListener(this);
- }
-
- protected int getFolderHeight() {
- if (mFolderHelpText.getVisibility() == VISIBLE) {
- mHelpTextHeight = (mFolderHelpText.getLineHeight() * mFolderHelpText.getLineCount()) +
- mFolderHelpText.getPaddingTop() + mFolderHelpText.getPaddingBottom();
-
- int height = getPaddingTop() + getPaddingBottom() + mFolderInfoIconHeight
- + mHelpTextHeight + mButtonHeight;
- return height;
- } else {
- int height = getPaddingTop() + getPaddingBottom() + mFolderInfoIconHeight
- + getContentAreaHeight();
- return height;
-
- }
- }
-
- private int getFolderWidth() {
- if (mFolderHelpText.getVisibility() == VISIBLE) {
- DisplayMetrics displayMetrics = this.getResources().getDisplayMetrics();
- int screenWidth = displayMetrics.widthPixels;
- int width = Math.min(mHelpTextWidth, screenWidth - getPaddingLeft() - getPaddingRight());
- return width;
- } else {
- int width = getPaddingLeft() + getPaddingRight() + mContent.getDesiredWidth();
- return width;
- }
- }
-
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- // TODO (Tyson): clean this up before merging into main CM branch
- int width = getFolderWidth();
- int height = getFolderHeight();
- int contentAreaWidthSpec = MeasureSpec.makeMeasureSpec(getContentAreaWidth(),
- MeasureSpec.EXACTLY);
- int contentAreaHeightSpec = MeasureSpec.makeMeasureSpec(getContentAreaHeight(),
- MeasureSpec.EXACTLY);
-
- if (LauncherAppState.isDisableAllApps()) {
- // Don't cap the height of the content to allow scrolling.
- mContent.setFixedSize(getContentAreaWidth(), mContent.getDesiredHeight());
- } else {
- mContent.setFixedSize(getContentAreaWidth(), getContentAreaHeight());
- }
- mContentScrollView.measure(contentAreaWidthSpec, contentAreaHeightSpec);
-
- if (mFolderHelpText.getVisibility() == VISIBLE) {
- mHelpTextHeight = (mFolderHelpText.getLineHeight() * mFolderHelpText.getLineCount()) +
- mFolderHelpText.getPaddingTop() + mFolderHelpText.getPaddingBottom();
-
- mFolderHelpText.measure(contentAreaWidthSpec, MeasureSpec.makeMeasureSpec(
- mHelpTextHeight, MeasureSpec.EXACTLY));
- mFolderInfoContainer.measure(contentAreaWidthSpec,
- MeasureSpec.makeMeasureSpec(
- mFolderInfoIconHeight + mHelpTextHeight + mButtonHeight, MeasureSpec.EXACTLY));
- mCloseInfoButton.measure(contentAreaWidthSpec,
- MeasureSpec.makeMeasureSpec(mButtonHeight, MeasureSpec.EXACTLY));
- } else {
- mHelpTextHeight = 0;
- mFolderHelpText.measure(contentAreaWidthSpec, MeasureSpec.makeMeasureSpec(
- mHelpTextHeight, MeasureSpec.EXACTLY));
- mFolderInfoContainer.measure(contentAreaWidthSpec,
- MeasureSpec.makeMeasureSpec(mFolderInfoIconHeight, MeasureSpec.EXACTLY));
- mCloseInfoButton.measure(contentAreaWidthSpec,
- MeasureSpec.makeMeasureSpec(0, MeasureSpec.EXACTLY));
- }
-
- Log.e(TAG, "onMeasure(), width: " + width + ", height:" + height);
-
- setMeasuredDimension(width, height);
- }
-
- public void onClick(View v) {
- Object tag = v.getTag();
- if (tag instanceof ShortcutInfo) {
- mLauncher.onClick(v);
- }
-
- switch (v.getId()) {
- case R.id.folder_info:
- toggleInfoPane();
- break;
- case R.id.close_info_button:
- mLauncher.closeFolder();
- break;
- default:
- break;
- }
- }
-
- @Override
- public boolean onLongClick(View v) {
- // Eat the event without doing anything. We do not allow users to remove items.
- return true;
- }
-
- private void toggleInfoPane() {
- if (mFolderHelpText.getVisibility() == VISIBLE) {
- // info ImageView becomes a close "X" when the help text is showing, handle accordingly
- mContentScrollView.setVisibility(VISIBLE);
- mContent.setVisibility(VISIBLE);
-
- mFolderHelpText.setVisibility(GONE);
-
- mCloseInfoButton.setVisibility(GONE);
-
- mFolderInfo.setImageDrawable(getResources().getDrawable(R.drawable.ic_launcher_info_normal_holo));
-
- } else {
- // show the info to the user about remote folders, including the option to disable it
- mContentScrollView.setVisibility(GONE);
- mContent.setVisibility(GONE);
-
- mFolderHelpText.setVisibility(VISIBLE);
-
- mCloseInfoButton.setVisibility(VISIBLE);
-
- mFolderInfo.setImageDrawable(getResources().getDrawable(R.drawable.ic_launcher_clear_normal_holo));
- }
- this.invalidate();
- }
-
- @Override
- public void animateClosed(boolean animate) {
- super.animateClosed(animate);
- mFolderHelpText.setVisibility(GONE);
- mCloseInfoButton.setVisibility(GONE);
- mContentScrollView.setVisibility(VISIBLE);
- mFolderInfo.setImageDrawable(getResources().getDrawable(R.drawable.ic_launcher_info_normal_holo));
- }
-
- @Override
- public void animateOpen(Workspace workspace, int[] folderTouch) {
- super.animateOpen(workspace, folderTouch);
-
- mFolderHelpText.setText(getResources().getString(R.string.recommendations_help_text));
- mFolderHelpText.setVisibility(GONE);
- mCloseInfoButton.setVisibility(GONE);
- mContentScrollView.setVisibility(VISIBLE);
- mContent.setVisibility(VISIBLE);
- mFolderInfo.setImageDrawable(getResources().getDrawable(R.drawable.ic_launcher_info_normal_holo));
- this.invalidate();
- }
-}
diff --git a/src/com/android/launcher3/ShortcutInfo.java b/src/com/android/launcher3/ShortcutInfo.java
index 01f79314e..0a762849c 100644
--- a/src/com/android/launcher3/ShortcutInfo.java
+++ b/src/com/android/launcher3/ShortcutInfo.java
@@ -59,6 +59,9 @@ public class ShortcutInfo extends ItemInfo {
*/
public static final int FLAG_RESTORE_STARTED = 8;
+ /** Indicates that this shortcut is part of the remote folder **/
+ public static final int FLAG_REMOTE = 16;
+
/**
* The intent used to start the application.
*/
@@ -243,6 +246,14 @@ public class ShortcutInfo extends ItemInfo {
return (status & flag) != 0;
}
+ /**
+ * Check if this shortcut has a specific flag.
+ * @param flag flag to check.
+ * @return true if the flag is present, false otherwise.
+ */
+ public boolean hasFlag(int flag) {
+ return (flags & flag) != 0;
+ }
public final boolean isPromise() {
return hasStatusFlag(FLAG_RESTORED_ICON | FLAG_AUTOINTALL_ICON);
diff --git a/src/com/android/launcher3/stats/LauncherStats.java b/src/com/android/launcher3/stats/LauncherStats.java
index e1dd1bbc6..5e8cb83d5 100644
--- a/src/com/android/launcher3/stats/LauncherStats.java
+++ b/src/com/android/launcher3/stats/LauncherStats.java
@@ -16,12 +16,12 @@
package com.android.launcher3.stats;
+import android.content.Context;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
-import com.android.launcher3.LauncherApplication;
import com.android.launcher3.stats.internal.db.DatabaseHelper;
import com.android.launcher3.stats.internal.model.TrackingEvent;
@@ -41,6 +41,9 @@ public class LauncherStats {
public static final String ORIGIN_APPDRAWER = "appdrawer";
public static final String ORIGIN_TREB_LONGPRESS = "trebuchet_longpress";
public static final String ORIGIN_CHOOSER = "theme_chooser";
+ public static final String ORIGIN_SETTINGS = "settings";
+ public static final String ORIGIN_DRAG_DROP = "drag_drop";
+ public static final String ORIGIN_FOLDER = "folder";
private static void log(String msg) throws IllegalArgumentException {
if (TextUtils.isEmpty(msg)) {
@@ -101,17 +104,16 @@ public class LauncherStats {
private static LauncherStats sInstance = null;
// Members
- private static WriteHandlerThread sHandlerThread = new WriteHandlerThread();
+ private static WriteHandlerThread sHandlerThread;
private static WriteHandler sWriteHandler;
private static DatabaseHelper sDatabaseHelper;
- private LauncherApplication mApplication;
/**
* Send a message to the handler to store event data
*
* @param trackingEvent {@link TrackingEvent}
*/
- private void sendStoreEventMessage(TrackingEvent trackingEvent) {
+ protected void sendStoreEventMessage(TrackingEvent trackingEvent) {
log("Sending tracking event to handler: " + trackingEvent);
Message msg = new Message();
msg.what = MSG_STORE_EVENT;
@@ -134,32 +136,37 @@ public class LauncherStats {
}
/**
+ * Used only for overlay extensions
+ */
+ protected LauncherStats() { }
+
+ /**
* Constructor
*
- * @param application {@link LauncherApplication} not null!
+ * @param context {@link Context} not null!
* @throws IllegalArgumentException {@link IllegalArgumentException}
*/
- private LauncherStats(LauncherApplication application) throws IllegalArgumentException {
- if (application == null) {
- throw new IllegalArgumentException("'application' cannot be null!");
+ private LauncherStats(Context context) throws IllegalArgumentException {
+ if (context == null) {
+ throw new IllegalArgumentException("'context' cannot be null!");
}
- mApplication = application;
- sDatabaseHelper = new DatabaseHelper(application);
+ sDatabaseHelper = new DatabaseHelper(context);
+ sHandlerThread = new WriteHandlerThread();
sHandlerThread.start();
sWriteHandler = new WriteHandler();
}
/**
- * Creates a singleton instance of the stats utility
+ * Gets a singleton instance of the stats utility
*
- * @param application {@link LauncherApplication} not null!
+ * @param context {@link Context} not null!
* @return {@link LauncherStats}
* @throws IllegalArgumentException {@link IllegalArgumentException}
*/
- public static LauncherStats createInstance(LauncherApplication application)
+ public static LauncherStats getInstance(Context context)
throws IllegalArgumentException {
if (sInstance == null) {
- sInstance = new LauncherStats(application);
+ sInstance = new LauncherStats(context);
}
return sInstance;
}
diff --git a/src/com/android/launcher3/stats/internal/model/TrackingEvent.java b/src/com/android/launcher3/stats/internal/model/TrackingEvent.java
index 91a9017be..a44d3f148 100644
--- a/src/com/android/launcher3/stats/internal/model/TrackingEvent.java
+++ b/src/com/android/launcher3/stats/internal/model/TrackingEvent.java
@@ -51,6 +51,14 @@ public class TrackingEvent {
WALLPAPER_CHANGE,
HOMESCREEN_PAGE,
WIDGET,
+
+ // Remote folder specific
+ REMOTE_FOLDER_DISABLED,
+ REMOTE_FOLDER_OPENED,
+ REMOTE_FOLDER_INFO_OPENED,
+ REMOTE_APP_OPENED,
+ REMOTE_APP_INSTALLED,
+ REMOTE_SYNC_TIME
}
public static final String KEY_ORIGIN = TrackingBundle.KEY_METADATA_ORIGIN;