diff options
author | Tyson Miller <tmiller@cyngn.com> | 2015-11-10 08:59:15 -0800 |
---|---|---|
committer | Tyson Miller <tmiller@cyngn.com> | 2015-12-01 17:16:59 -0800 |
commit | 719deb83a0ac84422b68605f4d5c782865766aef (patch) | |
tree | fd3db92c9e10fa1665c2bb5c7f2e0b059ba79d5d /src | |
parent | b0bc788a4fc3d6d7a86ff3f286d8524e3fa2787c (diff) | |
download | android_packages_apps_Trebuchet-719deb83a0ac84422b68605f4d5c782865766aef.tar.gz android_packages_apps_Trebuchet-719deb83a0ac84422b68605f4d5c782865766aef.tar.bz2 android_packages_apps_Trebuchet-719deb83a0ac84422b68605f4d5c782865766aef.zip |
Trebuchet: dynamic folder type added
Issue-Id: CYNGNOS-1328
Change-Id: I09bf7bec119307f54836fedee8a1532627035d9a
Diffstat (limited to 'src')
-rw-r--r-- | src/com/android/launcher3/AutoInstallsLayout.java | 47 | ||||
-rw-r--r-- | src/com/android/launcher3/DefaultLayoutParser.java | 32 | ||||
-rw-r--r-- | src/com/android/launcher3/Folder.java | 134 | ||||
-rw-r--r-- | src/com/android/launcher3/FolderIcon.java | 19 | ||||
-rw-r--r-- | src/com/android/launcher3/FolderInfo.java | 3 | ||||
-rw-r--r-- | src/com/android/launcher3/Launcher.java | 19 | ||||
-rw-r--r-- | src/com/android/launcher3/LauncherModel.java | 70 | ||||
-rw-r--r-- | src/com/android/launcher3/RemoteFolder.java | 260 | ||||
-rw-r--r-- | src/com/android/launcher3/Workspace.java | 2 |
9 files changed, 536 insertions, 50 deletions
diff --git a/src/com/android/launcher3/AutoInstallsLayout.java b/src/com/android/launcher3/AutoInstallsLayout.java index a5d22286d..b7a6d9ae9 100644 --- a/src/com/android/launcher3/AutoInstallsLayout.java +++ b/src/com/android/launcher3/AutoInstallsLayout.java @@ -82,6 +82,7 @@ public class AutoInstallsLayout { private static final String TAG_APP_ICON = "appicon"; private static final String TAG_AUTO_INSTALL = "autoinstall"; private static final String TAG_FOLDER = "folder"; + private static final String TAG_REMOTE_FOLDER = "remote-folder"; private static final String TAG_APPWIDGET = "appwidget"; private static final String TAG_SHORTCUT = "shortcut"; private static final String TAG_EXTRA = "extra"; @@ -257,6 +258,7 @@ public class AutoInstallsLayout { parsers.put(TAG_APP_ICON, new AppShortcutParser()); parsers.put(TAG_AUTO_INSTALL, new AutoInstallParser()); parsers.put(TAG_FOLDER, new FolderParser()); + parsers.put(TAG_REMOTE_FOLDER, new RemoteFolderParser()); parsers.put(TAG_APPWIDGET, new AppWidgetParser()); parsers.put(TAG_SHORTCUT, new ShortcutParser(mSourceRes)); return parsers; @@ -269,6 +271,8 @@ public class AutoInstallsLayout { */ long parseAndAdd(XmlResourceParser parser) throws XmlPullParserException, IOException; + + boolean isRemoteFolder(); } /** @@ -311,6 +315,11 @@ public class AutoInstallsLayout { } } + @Override + public boolean isRemoteFolder() { + return false; + } + /** * Helper method to allow extending the parser capabilities */ @@ -343,6 +352,11 @@ public class AutoInstallsLayout { return addShortcut(mContext.getString(R.string.package_state_unknown), intent, Favorites.ITEM_TYPE_APPLICATION); } + + @Override + public boolean isRemoteFolder() { + return false; + } } /** @@ -396,6 +410,11 @@ public class AutoInstallsLayout { } return new Intent(Intent.ACTION_VIEW, null).setData(Uri.parse(url)); } + + @Override + public boolean isRemoteFolder() { + return false; + } } /** @@ -488,6 +507,11 @@ public class AutoInstallsLayout { } return insertedId; } + + @Override + public boolean isRemoteFolder() { + return false; + } } protected class FolderParser implements TagParser { @@ -517,6 +541,11 @@ public class AutoInstallsLayout { mValues.put(Favorites.SPANX, 1); mValues.put(Favorites.SPANY, 1); mValues.put(Favorites._ID, mCallback.generateNewItemId()); + + if (isRemoteFolder()) { + mValues.put("subType", 1); + } + long folderId = mCallback.insertAndCheck(mDb, mValues); if (folderId < 0) { if (LOGD) Log.e(TAG, "Unable to add folder"); @@ -575,6 +604,11 @@ public class AutoInstallsLayout { } return addedId; } + + @Override + public boolean isRemoteFolder() { + return false; + } } protected static final void beginDocument(XmlPullParser parser, String firstElementName) @@ -630,4 +664,17 @@ public class AutoInstallsLayout { private static void copyInteger(ContentValues from, ContentValues to, String key) { to.put(key, from.getAsInteger(key)); } + + protected class RemoteFolderParser extends FolderParser { + + @Override + public long parseAndAdd(XmlResourceParser parser) throws XmlPullParserException, IOException { + return super.parseAndAdd(parser); + } + + @Override + public boolean isRemoteFolder() { + return true; + } + } } diff --git a/src/com/android/launcher3/DefaultLayoutParser.java b/src/com/android/launcher3/DefaultLayoutParser.java index e3ea40ebb..d9c400b3a 100644 --- a/src/com/android/launcher3/DefaultLayoutParser.java +++ b/src/com/android/launcher3/DefaultLayoutParser.java @@ -243,6 +243,11 @@ public class DefaultLayoutParser extends AutoInstallsLayout { } return addedId; } + + @Override + public boolean isRemoteFolder() { + return false; + } } /** @@ -269,6 +274,11 @@ public class DefaultLayoutParser extends AutoInstallsLayout { } return -1; } + + @Override + public boolean isRemoteFolder() { + return false; + } } /** @@ -287,4 +297,26 @@ public class DefaultLayoutParser extends AutoInstallsLayout { return super.parseAndAdd(parser); } } + + protected class RemoteFolderParser extends FolderParser { + public RemoteFolderParser() { + super(); + } + + @Override + public long parseAndAdd(XmlResourceParser parser) throws XmlPullParserException, + IOException { + final int resId = getAttributeResourceValue(parser, ATTR_FOLDER_ITEMS, 0); + if (resId != 0) { + parser = mSourceRes.getXml(resId); + beginDocument(parser, TAG_REMOTE_FOLDER); + } + return super.parseAndAdd(parser); + } + + @Override + public boolean isRemoteFolder() { + return true; + } + } } diff --git a/src/com/android/launcher3/Folder.java b/src/com/android/launcher3/Folder.java index d10be4efc..4cc328c5a 100644 --- a/src/com/android/launcher3/Folder.java +++ b/src/com/android/launcher3/Folder.java @@ -62,7 +62,9 @@ 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 com.cyngn.RemoteFolder.RemoteFolderUpdater; import java.util.ArrayList; import java.util.Collections; @@ -232,7 +234,7 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList mContent.setGridSize(0, 0); mContent.getShortcutsAndWidgets().setMotionEventSplittingEnabled(false); mContent.setInvertIfRtl(true); - mFolderNameLockContainer = findViewById(R.id.folder_name_lock_container); + mFolderName = (FolderEditText) findViewById(R.id.folder_name); mFolderName.setFolder(this); mFolderName.setOnFocusChangeListener(this); @@ -257,11 +259,15 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList mFolderName.setVisibility(View.GONE); } + mFolderNameLockContainer = findViewById(R.id.folder_name_lock_container); mFolderLock = (ImageView) findViewById(R.id.folder_lock); - mFolderLock.measure(measureSpec, measureSpec); - mFolderLock.setOnClickListener(this); - mFolderLockHeight = mFolderLock.getMeasuredHeight(); + // Could be null if this Folder an instance of the RemoteFolder subclass + if (mFolderLock != null) { + mFolderLock.measure(measureSpec, measureSpec); + mFolderLock.setOnClickListener(this); + mFolderLockHeight = mFolderLock.getMeasuredHeight(); + } DisplayMetrics displayMetrics = this.getResources().getDisplayMetrics(); mScreenWidth = displayMetrics.widthPixels; } @@ -476,39 +482,73 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList } } - void bind(FolderInfo info) { + void bind(final FolderInfo info) { mInfo = info; - ArrayList<ShortcutInfo> children = info.contents; - 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++; + final ArrayList<ShortcutInfo> children = info.contents; + + if (info.subType == FolderInfo.REMOTE_SUBTYPE && children.isEmpty()) { + final int count = 6; + RemoteFolderUpdater updater = mLauncher.getRemoteFolderUpdaterInstance(); + 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++; + } } - } - // 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() { @@ -658,12 +698,19 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList Animator circReveal = LauncherAnimUtils.createCircularReveal(this, circX, circY, 0, mScreenWidth); - final View[] alphaViewSet = new View[] { mFolderNameLockContainer, - mContent, mFolderName, mFolderLock }; + final View[] alphaViewSet; + if (mInfo.subType == FolderInfo.REMOTE_SUBTYPE) { + alphaViewSet = new View[] { mContent, mFolderName }; + } else { + alphaViewSet = new View[] { mFolderNameLockContainer, + mContent, mFolderName, mFolderLock }; + } + for (View view : alphaViewSet) { view.setAlpha(0f); } + circReveal.setDuration(150); circReveal.addListener(new AnimatorListenerAdapter() { @Override @@ -1371,15 +1418,15 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList centerAboutIcon(); } - private int getContentAreaHeight() { + protected int getContentAreaHeight() { return Math.max(mContent.getDesiredHeight(), MIN_CONTENT_DIMEN); } - private int getContentAreaWidth() { + protected int getContentAreaWidth() { return Math.max(mContent.getDesiredWidth(), MIN_CONTENT_DIMEN); } - private int getFolderHeight() { + protected int getFolderHeight() { int height = getPaddingTop() + getPaddingBottom() + mFolderNameHeight + getContentAreaHeight(); return height; @@ -1405,8 +1452,10 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList mFolderName.measure(contentAreaWidthSpec, MeasureSpec.makeMeasureSpec( mFolderNameHeight, MeasureSpec.EXACTLY)); } + mFolderNameLockContainer.measure(contentAreaWidthSpec, - MeasureSpec.makeMeasureSpec(mFolderNameHeight,MeasureSpec.EXACTLY)); + MeasureSpec.makeMeasureSpec(mFolderNameHeight, MeasureSpec.EXACTLY)); + setMeasuredDimension(width, height); } @@ -1468,6 +1517,10 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList } private void replaceFolderWithFinalItem() { + if (mInfo.subType == FolderInfo.REMOTE_SUBTYPE) { + return; + } + if (mInfo.hidden && getItemCount() >= 1) { return; } @@ -1626,6 +1679,13 @@ public class Folder extends LinearLayout implements DragSource, View.OnClickList 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.subType == FolderInfo.REMOTE_SUBTYPE) { + RemoteFolderUpdater updater = mLauncher.getModel().getRemoteFolderUpdaterInstance(); + updater.registerViewForInteraction(getViewForInfo(item), item.getIntent()); + } + } public void onRemove(ShortcutInfo item) { diff --git a/src/com/android/launcher3/FolderIcon.java b/src/com/android/launcher3/FolderIcon.java index 214ec3241..b66d5b70d 100644 --- a/src/com/android/launcher3/FolderIcon.java +++ b/src/com/android/launcher3/FolderIcon.java @@ -170,12 +170,19 @@ 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 = Folder.fromXml(launcher); - folder.setDragController(launcher.getDragController()); - folder.setFolderIcon(icon); - folder.bind(folderInfo); - icon.mFolder = folder; - + if (folderInfo.subType == FolderInfo.REMOTE_SUBTYPE) { + RemoteFolder folder = RemoteFolder.fromXml(launcher); + folder.setDragController(launcher.getDragController()); + folder.setFolderIcon(icon); + folder.bind(folderInfo); + icon.mFolder = folder; + } else { + 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/FolderInfo.java b/src/com/android/launcher3/FolderInfo.java index 104bd6cc1..12b3032ec 100644 --- a/src/com/android/launcher3/FolderInfo.java +++ b/src/com/android/launcher3/FolderInfo.java @@ -28,6 +28,7 @@ import java.util.Arrays; * Represents a folder containing shortcuts or apps. */ public class FolderInfo extends ItemInfo { + public static final int REMOTE_SUBTYPE = 1; /** * Whether this folder has been opened @@ -118,7 +119,7 @@ public class FolderInfo extends ItemInfo { @Override public String toString() { - return "FolderInfo(id=" + this.id + " type=" + this.itemType + return "FolderInfo(id=" + this.id + " type=" + this.itemType + " subtype=" + this.subType + " container=" + this.container + " screen=" + screenId + " cellX=" + cellX + " cellY=" + cellY + " spanX=" + spanX + " spanY=" + spanY + " dropPos=" + Arrays.toString(dropPos) + ")"; diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index bada6ba13..b734ad032 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -125,6 +125,7 @@ import com.android.launcher3.PagedView.TransitionEffect; import com.android.launcher3.settings.SettingsProvider; import com.android.launcher3.stats.LauncherStats; import com.android.launcher3.stats.internal.service.AggregationIntentService; +import com.cyngn.RemoteFolder.RemoteFolderUpdater; import java.io.DataInputStream; import java.io.DataOutputStream; @@ -403,6 +404,9 @@ public class Launcher extends Activity private BubbleTextView mWaitingForResume; + // Remote Folder Updater, used in Workspace and Folder + private RemoteFolderUpdater remoteFolderUpdater; + // Search widget int mSearchWidgetId; AppWidgetProviderInfo mSearchWidgetInfo; @@ -3225,6 +3229,10 @@ public class Launcher extends Activity closeFolder(); // Open the requested folder openFolder(folderIcon, folderTouchXYOffset); + + if (info.subType == FolderInfo.REMOTE_SUBTYPE) { + mModel.syncRemoteFolder(info, this); + } } else { // Find the open folder... int folderScreen; @@ -4883,7 +4891,7 @@ public class Launcher extends Activity final AnimatorSet anim = LauncherAnimUtils.createAnimatorSet(); final Collection<Animator> bounceAnims = new ArrayList<Animator>(); final boolean animateIcons = forceAnimateIcons && canRunNewAppsAnimation(); - Workspace workspace = mWorkspace; + final Workspace workspace = mWorkspace; long newShortcutsScreenId = -1; for (int i = start; i < end; i++) { final ItemInfo item = shortcuts.get(i); @@ -4934,7 +4942,7 @@ public class Launcher extends Activity } break; case LauncherSettings.Favorites.ITEM_TYPE_FOLDER: - FolderIcon newFolder = FolderIcon.fromXml(R.layout.folder_icon, this, + final FolderIcon newFolder = FolderIcon.fromXml(R.layout.folder_icon, this, (ViewGroup) workspace.getChildAt(workspace.getCurrentPage()), (FolderInfo) item, mIconCache); newFolder.setTextVisible(!mHideIconLabels); @@ -5938,6 +5946,13 @@ public class Launcher extends Activity SettingsProvider.SETTINGS_UI_HOMESCREEN_SEARCH, R.bool.preferences_interface_homescreen_search_default); } + + public RemoteFolderUpdater getRemoteFolderUpdaterInstance() { + if (remoteFolderUpdater == null) { + remoteFolderUpdater = new RemoteFolderUpdater(); + } + return remoteFolderUpdater; + } } interface LauncherTransitionable { diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java index dae2c180f..724fa3227 100644 --- a/src/com/android/launcher3/LauncherModel.java +++ b/src/com/android/launcher3/LauncherModel.java @@ -116,6 +116,8 @@ public class LauncherModel extends BroadcastReceiver private boolean mIsLoaderTaskRunning; private volatile boolean mFlushingWorkerThread; + private static RemoteFolderUpdater remoteFolderUpdater; + /** * Maintain a set of packages per user, for which we added a shortcut on the workspace. */ @@ -933,10 +935,10 @@ public class LauncherModel extends BroadcastReceiver String userSerial = Long.toString(UserManagerCompat.getInstance(context) .getSerialNumberForUser(user)); Cursor c = cr.query(LauncherSettings.Favorites.CONTENT_URI, - new String[] { "title", "intent", "profileId" }, - "title=? and (intent=? or intent=?) and profileId=?", - new String[] { title, intentWithPkg.toUri(0), intentWithoutPkg.toUri(0), userSerial }, - null); + new String[]{"title", "intent", "profileId"}, + "title=? and (intent=? or intent=?) and profileId=?", + new String[]{title, intentWithPkg.toUri(0), intentWithoutPkg.toUri(0), userSerial}, + null); try { return c.moveToFirst(); } finally { @@ -2384,6 +2386,11 @@ public class LauncherModel extends BroadcastReceiver sBgItemsIdMap.put(folderInfo.id, folderInfo); sBgFolders.put(folderInfo.id, folderInfo); + + if (folderInfo.subType == FolderInfo.REMOTE_SUBTYPE) { + syncRemoteFolder(folderInfo, mContext); + } + break; case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET: @@ -4245,4 +4252,59 @@ public class LauncherModel extends BroadcastReceiver public Callbacks getCallback() { return mCallbacks != null ? mCallbacks.get() : null; } + + public static RemoteFolderUpdater getRemoteFolderUpdaterInstance() { + if (remoteFolderUpdater == null) { + remoteFolderUpdater = new RemoteFolderUpdater(); + } + return remoteFolderUpdater; + } + + protected synchronized void syncRemoteFolder(final FolderInfo folderInfo, final Context context) { + + String spKey = LauncherAppState.getSharedPreferencesKey(); + SharedPreferences sp = context.getSharedPreferences(spKey, Context.MODE_PRIVATE); + boolean isEnabled = sp.getBoolean(RemoteFolder.REMOTE_FOLDER_ENABLED, true); + + if (!isEnabled) { + Log.e(TAG, "Prevented remote folder sync, since it has been explicitly disabled."); + return; + } + + RemoteFolderUpdater updater = getRemoteFolderUpdaterInstance(); + 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 new file mode 100644 index 000000000..0d33a5536 --- /dev/null +++ b/src/com/android/launcher3/RemoteFolder.java @@ -0,0 +1,260 @@ +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 Button mDisableFolderButton; + 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); + + mDisableFolderButton = (Button) findViewById(R.id.disable_remote_folder_button); + mDisableFolderButton.setText(getResources().getString(R.string.disable)); + mDisableFolderButton.measure(measureSpec, measureSpec); + mDisableFolderButton.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)); + mDisableFolderButton.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)); + mDisableFolderButton.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; + case R.id.disable_remote_folder_button: + disableRemoteFolder(); + break; + default: + break; + } + } + + 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); + mDisableFolderButton.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); + mDisableFolderButton.setVisibility(VISIBLE); + + mFolderInfo.setImageDrawable(getResources().getDrawable(R.drawable.ic_launcher_clear_normal_holo)); + } + this.invalidate(); + + } + + private void disableRemoteFolder() { + // close the folder UX & disable remote folders. + mLauncher.closeFolder(); + + if (mContext != null) { + String spKey = LauncherAppState.getSharedPreferencesKey(); + SharedPreferences sp = mContext.getSharedPreferences(spKey, Context.MODE_PRIVATE); + sp.edit().putBoolean(REMOTE_FOLDER_ENABLED, false).commit(); + Log.e(TAG, "Set preference to disable remote folder. Requesting sync to remove existing folder"); + + LauncherModel.deleteFolderContentsFromDatabase(mContext, mInfo); + LauncherModel.deleteItemFromDatabase(mContext, mInfo); + mLauncher.getWorkspace().removeView(this); + mLauncher.removeFolder(mInfo); + + mLauncher.getWorkspace().refreshDrawableState(); + } + } + + @Override + public void animateClosed(boolean animate) { + super.animateClosed(animate); + mFolderHelpText.setVisibility(GONE); + mCloseInfoButton.setVisibility(GONE); + mDisableFolderButton.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); + mDisableFolderButton.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/Workspace.java b/src/com/android/launcher3/Workspace.java index 71407b9fc..197c09a77 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -76,11 +76,13 @@ import com.android.launcher3.compat.PackageInstallerCompat; import com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo; import com.android.launcher3.compat.UserHandleCompat; import com.android.launcher3.settings.SettingsProvider; +import com.cyngn.RemoteFolder.RemoteFolderUpdater; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; |