Updating clings, removing ununsed clings

issue: 16127412

Change-Id: I1d18515765100ff10d33439b3ac39ebfc5da35c7
diff --git a/src/com/android/launcher3/LauncherClings.java b/src/com/android/launcher3/LauncherClings.java
index 00586bd..840fb52 100644
--- a/src/com/android/launcher3/LauncherClings.java
+++ b/src/com/android/launcher3/LauncherClings.java
@@ -18,31 +18,31 @@
 
 import android.accounts.Account;
 import android.accounts.AccountManager;
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
+import android.animation.ValueAnimator;
 import android.app.ActivityManager;
-import android.content.ComponentName;
 import android.content.Context;
 import android.content.SharedPreferences;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.graphics.Rect;
 import android.os.Bundle;
 import android.os.UserManager;
 import android.provider.Settings;
+import android.view.ContextThemeWrapper;
 import android.view.LayoutInflater;
 import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.View.OnLongClickListener;
 import android.view.ViewGroup;
+import android.view.ViewTreeObserver.OnGlobalLayoutListener;
 import android.view.accessibility.AccessibilityManager;
-import android.widget.TextView;
 
-class LauncherClings {
-    private static final String FIRST_RUN_CLING_DISMISSED_KEY = "cling_gel.first_run.dismissed";
+class LauncherClings implements OnClickListener {
     private static final String MIGRATION_CLING_DISMISSED_KEY = "cling_gel.migration.dismissed";
-    private static final String MIGRATION_WORKSPACE_CLING_DISMISSED_KEY =
-            "cling_gel.migration_workspace.dismissed";
     private static final String WORKSPACE_CLING_DISMISSED_KEY = "cling_gel.workspace.dismissed";
-    private static final String FOLDER_CLING_DISMISSED_KEY = "cling_gel.folder.dismissed";
+
+    private static final String ANIM_SLIDE_FROM_BOTTOM = "slide_from_bottom";
+    private static final String ANIM_SLIDE_FROM_TOP = "slide_from_top";
 
     private static final boolean DISABLE_CLINGS = false;
 
@@ -54,33 +54,169 @@
 
     private Launcher mLauncher;
     private LayoutInflater mInflater;
-    private HideFromAccessibilityHelper mHideFromAccessibilityHelper
-            = new HideFromAccessibilityHelper();
 
     /** Ctor */
     public LauncherClings(Launcher launcher) {
         mLauncher = launcher;
-        mInflater = mLauncher.getLayoutInflater();
+        mInflater = LayoutInflater.from(new
+                ContextThemeWrapper(mLauncher, android.R.style.Theme_DeviceDefault));
     }
 
-    /** Initializes a cling */
-    private Cling initCling(int clingId, int scrimId, boolean animate,
-                            boolean dimNavBarVisibilty) {
-        Cling cling = (Cling) mLauncher.findViewById(clingId);
-        View scrim = null;
-        if (scrimId > 0) {
-            scrim = mLauncher.findViewById(scrimId);
+    @Override
+    public void onClick(View v) {
+        int id = v.getId();
+        if (id == R.id.cling_dismiss_migration_use_default) {
+            // Disable the migration cling
+            dismissMigrationCling();
+        } else if (id == R.id.cling_dismiss_migration_copy_apps) {
+            // Copy the shortcuts from the old database
+            LauncherModel model = mLauncher.getModel();
+            model.resetLoadedState(false, true);
+            model.startLoader(false, PagedView.INVALID_RESTORE_PAGE,
+                    LauncherModel.LOADER_FLAG_CLEAR_WORKSPACE
+                            | LauncherModel.LOADER_FLAG_MIGRATE_SHORTCUTS);
+            // Set the flag to skip the folder cling
+            String spKey = LauncherAppState.getSharedPreferencesKey();
+            SharedPreferences sp = mLauncher.getSharedPreferences(spKey, Context.MODE_PRIVATE);
+            SharedPreferences.Editor editor = sp.edit();
+            editor.putBoolean(Launcher.USER_HAS_MIGRATED, true);
+            editor.apply();
+            // Disable the migration cling
+            dismissMigrationCling();
+        } else if (id == R.id.cling_dismiss_longpress_info) {
+            dismissLongPressCling();
         }
-        if (cling != null) {
-            cling.init(mLauncher, scrim);
-            cling.show(animate, SHOW_CLING_DURATION);
+    }
 
-            if (dimNavBarVisibilty) {
-                cling.setSystemUiVisibility(cling.getSystemUiVisibility() |
-                        View.SYSTEM_UI_FLAG_LOW_PROFILE);
+    /**
+     * Shows the migration cling.
+     *
+     * This flow is mutually exclusive with showFirstRunCling, and only runs if this Launcher
+     * package was not preinstalled and there exists a db to migrate from.
+     */
+    public void showMigrationCling() {
+        mLauncher.hideWorkspaceSearchAndHotseat();
+
+        ViewGroup root = (ViewGroup) mLauncher.findViewById(R.id.launcher);
+        View inflated = mInflater.inflate(R.layout.migration_cling, root);
+        inflated.findViewById(R.id.cling_dismiss_migration_copy_apps).setOnClickListener(this);
+        inflated.findViewById(R.id.cling_dismiss_migration_use_default).setOnClickListener(this);
+    }
+
+    private void dismissMigrationCling() {
+        mLauncher.showWorkspaceSearchAndHotseat();
+        Runnable dismissCb = new Runnable() {
+            public void run() {
+                Runnable cb = new Runnable() {
+                    public void run() {
+                        // Show the longpress cling next
+                        showLongPressCling(false);
+                    }
+                };
+                dismissCling(mLauncher.findViewById(R.id.migration_cling), cb,
+                        MIGRATION_CLING_DISMISSED_KEY, DISMISS_CLING_DURATION);
+            }
+        };
+        mLauncher.getWorkspace().post(dismissCb);
+    }
+
+    public void showLongPressCling(boolean showWelcome) {
+        ViewGroup root = (ViewGroup) mLauncher.findViewById(R.id.launcher);
+        View cling = mInflater.inflate(R.layout.longpress_cling, root, false);
+
+        final ClearCircleLayout hole = (ClearCircleLayout) cling.findViewById(R.id.cling_longpress_hole);
+        hole.initHole(mLauncher);
+        hole.setClickable(true);
+        hole.setOnLongClickListener(new OnLongClickListener() {
+
+            @Override
+            public boolean onLongClick(View v) {
+                mLauncher.getWorkspace().enterOverviewMode();
+                dismissLongPressCling();
+                return true;
+            }
+        });
+
+        final ViewGroup content = (ViewGroup) cling.findViewById(R.id.cling_content);
+        mInflater.inflate(showWelcome ? R.layout.longpress_cling_welcome_content
+                : R.layout.longpress_cling_content, content);
+        content.findViewById(R.id.cling_dismiss_longpress_info).setOnClickListener(this);
+
+        root.addView(cling);
+
+        if (showWelcome) {
+            // This is the first cling being shown. No need to animate.
+            return;
+        }
+
+        // Animate
+        content.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
+
+            @Override
+            public void onGlobalLayout() {
+                content.getViewTreeObserver().removeOnGlobalLayoutListener(this);
+
+                hole.setAlpha(0);
+                ValueAnimator anim1 = LauncherAnimUtils.ofFloat(hole, "alpha", 1);
+
+                ObjectAnimator anim2;
+
+                if (ANIM_SLIDE_FROM_TOP.equals(content.getTag())) {
+                    content.setTranslationY(-content.getMeasuredHeight());
+                    anim2 = LauncherAnimUtils.ofFloat(content, "translationY", 0);
+                } else if (ANIM_SLIDE_FROM_BOTTOM.equals(content.getTag())) {
+                    content.setTranslationY(content.getMeasuredHeight());
+                    anim2 = LauncherAnimUtils.ofFloat(content, "translationY", 0);
+                } else {
+                    content.setScaleX(0);
+                    content.setScaleY(0);
+                    PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1);
+                    PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1);
+                    anim2 = LauncherAnimUtils.ofPropertyValuesHolder(content, scaleX, scaleY);
+                }
+
+                AnimatorSet anim = LauncherAnimUtils.createAnimatorSet();
+                anim.setDuration(SHOW_CLING_DURATION);
+                anim.setInterpolator(new LogDecelerateInterpolator(100, 0));
+                anim.playTogether(anim1, anim2);
+                anim.start();
+            }
+        });
+    }
+
+    private void dismissLongPressCling() {
+        Runnable dismissCb = new Runnable() {
+            public void run() {
+                dismissCling(mLauncher.findViewById(R.id.longpress_cling), null,
+                        WORKSPACE_CLING_DISMISSED_KEY, DISMISS_CLING_DURATION);
+            }
+        };
+        mLauncher.getWorkspace().post(dismissCb);
+    }
+
+    /** Hides the specified Cling */
+    private void dismissCling(final View cling, final Runnable postAnimationCb,
+                              final String flag, int duration) {
+        // To catch cases where siblings of top-level views are made invisible, just check whether
+        // the cling is directly set to GONE before dismissing it.
+        if (cling != null && cling.getVisibility() != View.GONE) {
+            final Runnable cleanUpClingCb = new Runnable() {
+                public void run() {
+                    cling.setVisibility(View.GONE);
+                    mLauncher.getSharedPrefs().edit()
+                        .putBoolean(flag, true)
+                        .apply();
+                    if (postAnimationCb != null) {
+                        postAnimationCb.run();
+                    }
+                }
+            };
+            if (duration <= 0) {
+                cleanUpClingCb.run();
+            } else {
+                cling.animate().alpha(0).setDuration(duration).withEndAction(cleanUpClingCb);
             }
         }
-        return cling;
     }
 
     /** Returns whether the clings are enabled or should be shown */
@@ -118,346 +254,18 @@
         return true;
     }
 
-    /** Returns whether the folder cling is visible. */
-    public boolean isFolderClingVisible() {
-        Cling cling = (Cling) mLauncher.findViewById(R.id.folder_cling);
-        if (cling != null) {
-            return cling.getVisibility() == View.VISIBLE;
-        }
-        return false;
-    }
-
-    private boolean skipCustomClingIfNoAccounts() {
-        Cling cling = (Cling) mLauncher.findViewById(R.id.workspace_cling);
-        boolean customCling = cling.getDrawIdentifier().equals("workspace_custom");
-        if (customCling) {
-            AccountManager am = AccountManager.get(mLauncher);
-            if (am == null) return false;
-            Account[] accounts = am.getAccountsByType("com.google");
-            return accounts.length == 0;
-        }
-        return false;
-    }
-
-    /** Updates the first run cling custom content hint */
-    private void setCustomContentHintVisibility(Cling cling, String ccHintStr, boolean visible,
-                                                boolean animate) {
-        final TextView ccHint = (TextView) cling.findViewById(R.id.custom_content_hint);
-        if (ccHint != null) {
-            if (visible && !ccHintStr.isEmpty()) {
-                ccHint.setText(ccHintStr);
-                ccHint.setVisibility(View.VISIBLE);
-                if (animate) {
-                    ccHint.setAlpha(0f);
-                    ccHint.animate().alpha(1f)
-                            .setDuration(SHOW_CLING_DURATION)
-                            .start();
-                } else {
-                    ccHint.setAlpha(1f);
-                }
-            } else {
-                if (animate) {
-                    ccHint.animate().alpha(0f)
-                            .setDuration(SHOW_CLING_DURATION)
-                            .setListener(new AnimatorListenerAdapter() {
-                                @Override
-                                public void onAnimationEnd(Animator animation) {
-                                    ccHint.setVisibility(View.GONE);
-                                }
-                            })
-                            .start();
-                } else {
-                    ccHint.setAlpha(0f);
-                    ccHint.setVisibility(View.GONE);
-                }
-            }
-        }
-    }
-
-    /** Updates the first run cling custom content hint */
-    public void updateCustomContentHintVisibility() {
-        Cling cling = (Cling) mLauncher.findViewById(R.id.first_run_cling);
-        String ccHintStr = mLauncher.getFirstRunCustomContentHint();
-
-        if (mLauncher.getWorkspace().hasCustomContent()) {
-            // Show the custom content hint if ccHintStr is not empty
-            if (cling != null) {
-                setCustomContentHintVisibility(cling, ccHintStr, true, true);
-            }
-        } else {
-            // Hide the custom content hint
-            if (cling != null) {
-                setCustomContentHintVisibility(cling, ccHintStr, false, true);
-            }
-        }
-    }
-
-    /** Updates the first run cling search bar hint. */
-    public void updateSearchBarHint(String hint) {
-        Cling cling = (Cling) mLauncher.findViewById(R.id.first_run_cling);
-        if (cling != null && cling.getVisibility() == View.VISIBLE && !hint.isEmpty()) {
-            TextView sbHint = (TextView) cling.findViewById(R.id.search_bar_hint);
-            sbHint.setText(hint);
-            sbHint.setVisibility(View.VISIBLE);
-        }
-    }
-
     public boolean shouldShowFirstRunOrMigrationClings() {
         SharedPreferences sharedPrefs = mLauncher.getSharedPrefs();
         return areClingsEnabled() &&
-            !sharedPrefs.getBoolean(FIRST_RUN_CLING_DISMISSED_KEY, false) &&
+            !sharedPrefs.getBoolean(WORKSPACE_CLING_DISMISSED_KEY, false) &&
             !sharedPrefs.getBoolean(MIGRATION_CLING_DISMISSED_KEY, false);
     }
 
-    public void removeFirstRunAndMigrationClings() {
-        removeCling(R.id.first_run_cling);
-        removeCling(R.id.migration_cling);
-    }
-
-    /**
-     * Shows the first run cling.
-     *
-     * This flow is mutually exclusive with showMigrationCling, and only runs if this Launcher
-     * package was preinstalled or there is no db to migrate from.
-     */
-    public void showFirstRunCling() {
-        if (!skipCustomClingIfNoAccounts()) {
-            Cling cling = (Cling) mLauncher.findViewById(R.id.first_run_cling);
-            if (cling != null) {
-                String sbHintStr = mLauncher.getFirstRunClingSearchBarHint();
-                String ccHintStr = mLauncher.getFirstRunCustomContentHint();
-                if (!sbHintStr.isEmpty()) {
-                    TextView sbHint = (TextView) cling.findViewById(R.id.search_bar_hint);
-                    sbHint.setText(sbHintStr);
-                    sbHint.setVisibility(View.VISIBLE);
-                }
-                setCustomContentHintVisibility(cling, ccHintStr, true, false);
-            }
-            initCling(R.id.first_run_cling, 0, false, true);
-        } else {
-            removeFirstRunAndMigrationClings();
-        }
-    }
-
-    /**
-     * Shows the migration cling.
-     *
-     * This flow is mutually exclusive with showFirstRunCling, and only runs if this Launcher
-     * package was not preinstalled and there exists a db to migrate from.
-     */
-    public void showMigrationCling() {
-        mLauncher.hideWorkspaceSearchAndHotseat();
-
-        Cling c = initCling(R.id.migration_cling, 0, false, true);
-        c.bringScrimToFront();
-        c.bringToFront();
-    }
-
-    public void showMigrationWorkspaceCling() {
-        // Enable the clings only if they have not been dismissed before
-        if (areClingsEnabled() && !mLauncher.getSharedPrefs().getBoolean(
-                MIGRATION_WORKSPACE_CLING_DISMISSED_KEY, false)) {
-            Cling c = initCling(R.id.migration_workspace_cling, 0, false, true);
-            c.updateMigrationWorkspaceBubblePosition();
-            c.bringScrimToFront();
-            c.bringToFront();
-        } else {
-            removeCling(R.id.migration_workspace_cling);
-        }
-    }
-
-    public void showWorkspaceCling() {
-        // Enable the clings only if they have not been dismissed before
-        if (areClingsEnabled() && !mLauncher.getSharedPrefs().getBoolean(
-                WORKSPACE_CLING_DISMISSED_KEY, false)) {
-            Cling c = initCling(R.id.workspace_cling, 0, false, true);
-            c.updateWorkspaceBubblePosition();
-            if (mLauncher.shouldClingFocusHotseatApp()) {
-                // Set the focused hotseat app
-                c.setFocusedHotseatApp(mLauncher.getFirstRunFocusedHotseatAppDrawableId(),
-                    mLauncher.getFirstRunFocusedHotseatAppRank(),
-                    mLauncher.getFirstRunFocusedHotseatAppComponentName(),
-                    mLauncher.getFirstRunFocusedHotseatAppBubbleTitle(),
-                    mLauncher.getFirstRunFocusedHotseatAppBubbleDescription());
-            }
-        } else {
-            removeCling(R.id.workspace_cling);
-        }
-    }
-
-    public Cling showFoldersCling() {
-        SharedPreferences sharedPrefs = mLauncher.getSharedPrefs();
-        // Enable the clings only if they have not been dismissed before
-        if (areClingsEnabled() &&
-                !sharedPrefs.getBoolean(FOLDER_CLING_DISMISSED_KEY, false) &&
-                !sharedPrefs.getBoolean(Launcher.USER_HAS_MIGRATED, false)) {
-            Cling cling = initCling(R.id.folder_cling, R.id.cling_scrim,
-                    true, true);
-            Folder openFolder = mLauncher.getWorkspace().getOpenFolder();
-            if (openFolder != null) {
-                Rect openFolderRect = new Rect();
-                openFolder.getHitRect(openFolderRect);
-                cling.setOpenFolderRect(openFolderRect);
-                openFolder.bringToFront();
-            }
-            return cling;
-        } else {
-            removeCling(R.id.folder_cling);
-            return null;
-        }
-    }
-
     public static void synchonouslyMarkFirstRunClingDismissed(Context ctx) {
         SharedPreferences prefs = ctx.getSharedPreferences(
                 LauncherAppState.getSharedPreferencesKey(), Context.MODE_PRIVATE);
         SharedPreferences.Editor editor = prefs.edit();
-        editor.putBoolean(LauncherClings.FIRST_RUN_CLING_DISMISSED_KEY, true);
+        editor.putBoolean(WORKSPACE_CLING_DISMISSED_KEY, true);
         editor.commit();
     }
-
-    /** Removes the cling outright from the DragLayer */
-    private void removeCling(int id) {
-        final View cling = mLauncher.findViewById(id);
-        if (cling != null) {
-            final ViewGroup parent = (ViewGroup) cling.getParent();
-            parent.post(new Runnable() {
-                @Override
-                public void run() {
-                    parent.removeView(cling);
-                }
-            });
-            mHideFromAccessibilityHelper.restoreImportantForAccessibility(mLauncher.getDragLayer());
-        }
-    }
-
-    /** Hides the specified Cling */
-    private void dismissCling(final Cling cling, final Runnable postAnimationCb,
-                              final String flag, int duration, boolean restoreNavBarVisibilty) {
-        // To catch cases where siblings of top-level views are made invisible, just check whether
-        // the cling is directly set to GONE before dismissing it.
-        if (cling != null && cling.getVisibility() != View.GONE) {
-            final Runnable cleanUpClingCb = new Runnable() {
-                public void run() {
-                    cling.cleanup();
-                    SharedPreferences.Editor editor = mLauncher.getSharedPrefs().edit();
-                    editor.putBoolean(flag, true);
-                    editor.apply();
-                    if (postAnimationCb != null) {
-                        postAnimationCb.run();
-                    }
-                }
-            };
-            if (duration <= 0) {
-                cleanUpClingCb.run();
-            } else {
-                cling.hide(duration, cleanUpClingCb);
-            }
-            mHideFromAccessibilityHelper.restoreImportantForAccessibility(mLauncher.getDragLayer());
-
-            if (restoreNavBarVisibilty) {
-                cling.setSystemUiVisibility(cling.getSystemUiVisibility() &
-                        ~View.SYSTEM_UI_FLAG_LOW_PROFILE);
-            }
-        }
-    }
-
-    public void dismissFirstRunCling(View v) {
-        Cling cling = (Cling) mLauncher.findViewById(R.id.first_run_cling);
-        Runnable cb = new Runnable() {
-            public void run() {
-                // Show the workspace cling next
-                showWorkspaceCling();
-            }
-        };
-        dismissCling(cling, cb, FIRST_RUN_CLING_DISMISSED_KEY,
-                DISMISS_CLING_DURATION, false);
-
-        // Fade out the search bar for the workspace cling coming up
-        mLauncher.getSearchBar().hideSearchBar(true);
-    }
-
-    private void dismissMigrationCling() {
-        mLauncher.showWorkspaceSearchAndHotseat();
-        Runnable dismissCb = new Runnable() {
-            public void run() {
-                Cling cling = (Cling) mLauncher.findViewById(R.id.migration_cling);
-                Runnable cb = new Runnable() {
-                    public void run() {
-                        // Show the migration workspace cling next
-                        showMigrationWorkspaceCling();
-                    }
-                };
-                dismissCling(cling, cb, MIGRATION_CLING_DISMISSED_KEY,
-                        DISMISS_CLING_DURATION, true);
-            }
-        };
-        mLauncher.getWorkspace().post(dismissCb);
-    }
-
-    private void dismissAnyWorkspaceCling(Cling cling, String key, View v) {
-        Runnable cb = null;
-        if (v == null) {
-            cb = new Runnable() {
-                public void run() {
-                    mLauncher.getWorkspace().enterOverviewMode();
-                }
-            };
-        }
-        dismissCling(cling, cb, key, DISMISS_CLING_DURATION, true);
-
-        // Fade in the search bar
-        mLauncher.getSearchBar().showSearchBar(true);
-    }
-
-    public void markFolderClingDismissedIfNecessary() {
-        SharedPreferences prefs = mLauncher.getSharedPrefs();
-        if (!prefs.getBoolean(FOLDER_CLING_DISMISSED_KEY, false)) {
-            SharedPreferences.Editor editor = prefs.edit();
-            editor.putBoolean(FOLDER_CLING_DISMISSED_KEY, true);
-            editor.apply();
-        }
-    }
-
-    public void dismissMigrationClingCopyApps(View v) {
-        // Copy the shortcuts from the old database
-        LauncherModel model = mLauncher.getModel();
-        model.resetLoadedState(false, true);
-        model.startLoader(false, PagedView.INVALID_RESTORE_PAGE,
-                LauncherModel.LOADER_FLAG_CLEAR_WORKSPACE
-                        | LauncherModel.LOADER_FLAG_MIGRATE_SHORTCUTS);
-
-        // Set the flag to skip the folder cling
-        String spKey = LauncherAppState.getSharedPreferencesKey();
-        SharedPreferences sp = mLauncher.getSharedPreferences(spKey, Context.MODE_PRIVATE);
-        SharedPreferences.Editor editor = sp.edit();
-        editor.putBoolean(Launcher.USER_HAS_MIGRATED, true);
-        editor.apply();
-
-        // Disable the migration cling
-        dismissMigrationCling();
-    }
-
-    public void dismissMigrationClingUseDefault(View v) {
-        // Don't need to do anything special here. We've already loaded the default workspace,
-        // (which is the default loader behavior triggered from Launcher#onCreate.).
-
-        // Disable the migration cling
-        dismissMigrationCling();
-    }
-
-    public void dismissMigrationWorkspaceCling(View v) {
-        Cling cling = (Cling) mLauncher.findViewById(R.id.migration_workspace_cling);
-        dismissAnyWorkspaceCling(cling, MIGRATION_WORKSPACE_CLING_DISMISSED_KEY, v);
-    }
-
-    public void dismissWorkspaceCling(View v) {
-        Cling cling = (Cling) mLauncher.findViewById(R.id.workspace_cling);
-        dismissAnyWorkspaceCling(cling, WORKSPACE_CLING_DISMISSED_KEY, v);
-    }
-
-    public void dismissFolderCling(View v) {
-        Cling cling = (Cling) mLauncher.findViewById(R.id.folder_cling);
-        dismissCling(cling, null, FOLDER_CLING_DISMISSED_KEY,
-                DISMISS_CLING_DURATION, true);
-    }
 }