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 | |
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
-rw-r--r-- | Android.mk | 25 | ||||
-rw-r--r-- | AndroidManifest.xml | 22 | ||||
-rw-r--r-- | RemoteFolder/Android.mk | 1 | ||||
-rw-r--r-- | RemoteFolder/src/com.cyngn.RemoteFolder/RemoteFolderUpdater.java | 64 | ||||
-rw-r--r-- | proguard.flags | 28 | ||||
-rw-r--r-- | res/layout/remote_folder.xml | 123 | ||||
-rw-r--r-- | res/values/cm_strings.xml | 6 | ||||
-rw-r--r-- | res/values/version.xml | 4 | ||||
-rw-r--r-- | res/xml/default_workspace_4x4.xml | 4 | ||||
-rw-r--r-- | res/xml/default_workspace_5x5.xml | 4 | ||||
-rw-r--r-- | res/xml/default_workspace_5x6.xml | 4 | ||||
-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 |
20 files changed, 819 insertions, 52 deletions
diff --git a/Android.mk b/Android.mk index af967ac5a..f93af5b89 100644 --- a/Android.mk +++ b/Android.mk @@ -27,13 +27,22 @@ LOCAL_STATIC_JAVA_LIBRARIES := android-support-v13 \ android-support-v7-recyclerview \ guava +<<<<<<< HEAD +REMOTE_FOLDER_UPDATER ?= $(LOCAL_PATH)/RemoteFolder + + LOCAL_SRC_FILES := $(call all-java-files-under, src) \ + $(call all-java-files-under, $(REMOTE_FOLDER_UPDATER)/src) \ +======= +LOCAL_SRC_FILES := $(call all-java-files-under, src) \ +>>>>>>> 861f6e8... Trebuchet: Remote Folder hooks setup. Updater call still needs to be moved from Folder to LauncherModel $(call all-java-files-under, WallpaperPicker/src) \ $(call all-renderscript-files-under, src) \ $(call all-proto-files-under, protos) LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/WallpaperPicker/res $(LOCAL_PATH)/res -LOCAL_AAPT_FLAGS := --auto-add-overlay +LOCAL_AAPT_FLAGS := --auto-add-overlay \ + --extra-packages com.cyngn.RemoteFolder LOCAL_PROTOC_OPTIMIZE_TYPE := nano LOCAL_PROTOC_FLAGS := --proto_path=$(LOCAL_PATH)/protos/ @@ -49,10 +58,16 @@ LOCAL_AAPT_FLAGS += --rename-manifest-package com.cyanogenmod.trebuchet LOCAL_OVERRIDES_PACKAGES := Launcher3 LOCAL_PROGUARD_FLAG_FILES := proguard.flags -LOCAL_PROGUARD_ENABLED := disabled +LOCAL_PROGUARD_ENABLED := full + +REMOTE_FOLDER_UPDATER ?= $(LOCAL_PATH)/RemoteFolder +include $(REMOTE_FOLDER_UPDATER)/Android.mk include $(BUILD_PACKAGE) +include $(CLEAR_VARS) +include $(REMOTE_FOLDER_UPDATER)/Android.mk +include $(BUILD_MULTI_PREBUILT) # # Protocol Buffer Debug Utility in Java @@ -72,6 +87,7 @@ LOCAL_JAR_MANIFEST := util/etc/manifest.txt include $(BUILD_HOST_JAVA_LIBRARY) + # # Protocol Buffer Debug Utility Wrapper Script # @@ -89,4 +105,9 @@ $(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/util/etc/launcher_protoutil | $(ACP) $(copy-file-to-new-target) $(hide) chmod 755 $@ +<<<<<<< HEAD +include $(REMOTE_FOLDER_UPDATER)/Android.mk + +======= +>>>>>>> 861f6e8... Trebuchet: Remote Folder hooks setup. Updater call still needs to be moved from Folder to LauncherModel include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index f3425fe44..b6ae5a2c2 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -76,6 +76,8 @@ <uses-permission android:name="com.android.launcher3.permission.RECEIVE_FIRST_LOAD_BROADCAST" /> <uses-permission android:name="cyanogenmod.permission.PROTECTED_APP" /> <uses-permission android:name="com.cyngn.stats.SEND_ANALYTICS" /> + <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> + <uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION"/> <application android:name="com.android.launcher3.LauncherApplication" @@ -266,5 +268,25 @@ <meta-data android:name="com.google.android.backup.api_key" android:value="@string/backup_api_key" /> + <meta-data android:name="com.google.android.gms.version" + android:value="@integer/google_play_services_version" /> + + <!-- For InMobi --> + <!--<activity android:name="com.inmobi.rendering.InMobiAdActivity" + android:configChanges="keyboardHidden|orientation|keyboard|smallestScreenSize|screenSize" + android:theme="@android:style/Theme.Translucent.NoTitleBar" + android:hardwareAccelerated="true" /> + + <service android:enabled="true" android:name="com.inmobi.commons.internal.ActivityRecognitionManager" /> + + <receiver + android:name="com.inmobi.commons.core.utilities.uid.ImIdShareBroadCastReceiver" + android:enabled="true" + android:exported="true" > + <intent-filter> + <action android:name="com.inmobi.share.id" /> + </intent-filter> + </receiver>--> + </application> </manifest> diff --git a/RemoteFolder/Android.mk b/RemoteFolder/Android.mk new file mode 100644 index 000000000..0857902d9 --- /dev/null +++ b/RemoteFolder/Android.mk @@ -0,0 +1 @@ +LOCAL_SRC_FILES += (call all-java-files-under, RemoteFolder/src)
\ No newline at end of file diff --git a/RemoteFolder/src/com.cyngn.RemoteFolder/RemoteFolderUpdater.java b/RemoteFolder/src/com.cyngn.RemoteFolder/RemoteFolderUpdater.java new file mode 100644 index 000000000..909154c2c --- /dev/null +++ b/RemoteFolder/src/com.cyngn.RemoteFolder/RemoteFolderUpdater.java @@ -0,0 +1,64 @@ +package com.cyngn.RemoteFolder; + +import android.content.Context; +import android.content.Intent; +import android.graphics.Bitmap; +import android.view.View; +import java.util.List; + +public class RemoteFolderUpdater { + + public interface RemoteFolderUpdateListener { + void onSuccess(List<RemoteFolderInfo> remoteFolderInfoList); + void onFailure(String error); + } + + /** + * 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; + } + } +}
\ No newline at end of file diff --git a/proguard.flags b/proguard.flags index 0b28c0ef4..5eef9074c 100644 --- a/proguard.flags +++ b/proguard.flags @@ -1,3 +1,8 @@ +-keepattributes SourceFile,LineNumberTable,InnerClasses +-keep class com.inmobi.** { *; } +-dontwarn com.inmobi.** +-dontwarn com.google.android.gms** + -keep class com.android.launcher3.Launcher { public void previousScreen(android.view.View); public void nextScreen(android.view.View); @@ -57,3 +62,26 @@ public float getAnimationProgress(); public void setAnimationProgress(float); } + +-keep class * extends java.util.ListResourceBundle { + protected Object[][] getContents(); +} + +-keep public class com.google.android.gms.common.internal.safeparcel.SafeParcelable { + public static final *** NULL; +} + +-keepnames @com.google.android.gms.common.annotation.KeepName class * +-keepclassmembernames class * { + @com.google.android.gms.common.annotation.KeepName *; +} + +-keepnames class * implements android.os.Parcelable { + public static final ** CREATOR; +} + +-keep class android.content.res.** { *; } +-dontwarn android.content.res.* + +-keep class android.view.inputmethod.** { *; } +-dontwarn android.view.inputmethod.* diff --git a/res/layout/remote_folder.xml b/res/layout/remote_folder.xml new file mode 100644 index 000000000..b185a2109 --- /dev/null +++ b/res/layout/remote_folder.xml @@ -0,0 +1,123 @@ +<?xml version="1.0" encoding="utf-8"?> + <!-- Copyright (C) 2008 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.RemoteFolder +xmlns:android="http://schemas.android.com/apk/res/android" +xmlns:launcher="http://schemas.android.com/apk/res-auto" +android:layout_width="wrap_content" +android:layout_height="wrap_content" +android:orientation="vertical" +android:paddingTop="16dp" +android:paddingStart="@dimen/folder_preview_padding" +android:paddingEnd="@dimen/folder_preview_padding" +android:paddingBottom="@dimen/folder_preview_padding" +android:layout_gravity="center" +android:background="@drawable/folder_bg"> + + <RelativeLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:id="@+id/folder_info_container" + android:background="@android:color/holo_green_dark"> + + <!-- TODO replace background with android:background="@android:color/transparent" --> + <com.android.launcher3.FolderEditText + android:id="@+id/folder_name" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:background="@android:color/holo_orange_dark" + android:fontFamily="sans-serif-condensed" + android:hint="@string/folder_hint_text" + android:imeOptions="flagNoExtractUi" + android:paddingBottom="@dimen/folder_name_padding" + android:paddingTop="@dimen/folder_name_padding" + android:layout_marginStart="@dimen/folder_name_padding" + android:layout_marginEnd="@dimen/folder_name_padding" + android:gravity="center_vertical" + android:singleLine="true" + android:textColor="@color/workspace_icon_text_color" + android:textColorHighlight="#ffCCCCCC" + android:textColorHint="#78ffffff" + android:textCursorDrawable="@null" + android:textSize="18sp" + android:layout_alignParentTop="true" + android:layout_alignParentLeft="true"/> + + + <ImageView + android:id="@+id/folder_info" + android:layout_width="@dimen/folder_lock_icon" + android:layout_height="@dimen/folder_lock_icon" + android:padding="@dimen/folder_name_padding" + android:src="@drawable/ic_launcher_info_normal_holo" + android:layout_alignTop="@id/folder_name" + android:layout_alignParentRight="true"/> + + <TextView + android:id="@+id/help_text_view" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginStart="@dimen/folder_name_padding" + android:layout_marginEnd="@dimen/folder_name_padding" + android:text="@string/recommendations_help_text" + android:fontFamily="sans-serif-condensed" + android:textSize="18sp" + android:textColor="@color/workspace_icon_text_color" + android:textColorHighlight="#ffCCCCCC" + android:textColorHint="#78ffffff" + android:layout_below="@id/folder_info" + android:background="@android:color/holo_purple" + /> + + <Button + android:id="@+id/close_info_button" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:minHeight="@dimen/folder_lock_icon" + android:text="@string/close" + android:layout_below="@id/help_text_view" + android:layout_alignParentBottom="true" + android:layout_alignParentRight="true" + /> + + <Button + android:id="@+id/disable_remote_folder_button" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:minHeight="@dimen/folder_lock_icon" + android:text="@string/disable" + android:layout_below="@id/help_text_view" + android:layout_toLeftOf="@id/close_info_button" + android:layout_alignParentBottom="true" + /> + + </RelativeLayout> + + <ScrollView + android:id="@+id/scroll_view" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_gravity="center_horizontal" + android:background="@android:color/holo_red_dark"> + + <com.android.launcher3.CellLayout + android:id="@+id/folder_content" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:cacheColorHint="#ff333333" + android:hapticFeedbackEnabled="false" + android:background="@android:color/holo_blue_bright"/> + </ScrollView> +</com.android.launcher3.RemoteFolder>
\ No newline at end of file diff --git a/res/values/cm_strings.xml b/res/values/cm_strings.xml index 7602ac107..a235a2a90 100644 --- a/res/values/cm_strings.xml +++ b/res/values/cm_strings.xml @@ -87,4 +87,10 @@ <!-- Search Manager doesn't exist --> <string name="search_activity_not_found">A search activity could not be found!</string> + + <!-- Featured Apps Strings --> + <string name="recommendations_title">Featured Apps</string> + <string name="recommendations_help_text">This is a dynamic folder that will automatically load with recommended and featured apps from us at Cyanogen Inc. If you would not like to receive these awesome offers, simply disable below and the folder will be removed.</string> + <string name="disable">DISABLE</string> + <string name="close">CLOSE</string> </resources> diff --git a/res/values/version.xml b/res/values/version.xml new file mode 100644 index 000000000..d8a0e1f85 --- /dev/null +++ b/res/values/version.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <integer name="google_play_services_version">7571000</integer> +</resources>
\ No newline at end of file diff --git a/res/xml/default_workspace_4x4.xml b/res/xml/default_workspace_4x4.xml index 5970f12f4..809697ebe 100644 --- a/res/xml/default_workspace_4x4.xml +++ b/res/xml/default_workspace_4x4.xml @@ -29,6 +29,10 @@ launcher:spanX="4" launcher:spanY="2" /> + <!-- Recommended Folder --> + <remote-folder launcher:screen="1" launcher:x="0" launcher:y="2" launcher:title="@string/recommendations_title"> + </remote-folder> + <!-- Google Folder --> <folder launcher:screen="1" launcher:x="0" launcher:y="3" launcher:title="@string/google_title"> <favorite diff --git a/res/xml/default_workspace_5x5.xml b/res/xml/default_workspace_5x5.xml index 5839438f6..3577bb7a1 100644 --- a/res/xml/default_workspace_5x5.xml +++ b/res/xml/default_workspace_5x5.xml @@ -29,6 +29,10 @@ launcher:spanX="5" launcher:spanY="2" /> + <!-- Recommended Folder --> + <remote-folder launcher:screen="1" launcher:x="0" launcher:y="3" launcher:title="@string/recommendations_title"> + </remote-folder> + <!-- Google Folder --> <folder launcher:screen="1" launcher:x="0" launcher:y="4" launcher:title="@string/google_title"> <favorite diff --git a/res/xml/default_workspace_5x6.xml b/res/xml/default_workspace_5x6.xml index 81a1ef701..96845ae56 100644 --- a/res/xml/default_workspace_5x6.xml +++ b/res/xml/default_workspace_5x6.xml @@ -29,6 +29,10 @@ launcher:spanX="6" launcher:spanY="2" /> + <!-- Recommended Folder --> + <remote-folder launcher:screen="1" launcher:x="0" launcher:y="3" launcher:title="@string/recommendations_title"> + </remote-folder> + <!-- Google Folder --> <folder launcher:screen="1" launcher:x="0" launcher:y="4" launcher:title="@string/google_title"> <favorite 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; |