Merge "Add more Launcher files to delete on Clear Launcher Data" into ub-now-queens
diff --git a/res/values-ms-rMY/strings.xml b/res/values-ms-rMY/strings.xml
index 07236d6..32c8c02 100644
--- a/res/values-ms-rMY/strings.xml
+++ b/res/values-ms-rMY/strings.xml
@@ -24,8 +24,7 @@
     <string name="uid_name" msgid="7820867637514617527">"Apl Teras Android"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="activity_not_found" msgid="8071924732094499514">"Apl tidak dipasang."</string>
-    <!-- no translation found for activity_not_available (7456344436509528827) -->
-    <skip />
+    <string name="activity_not_available" msgid="7456344436509528827">"Apl tidak tersedia"</string>
     <string name="safemode_shortcut_error" msgid="9160126848219158407">"Apl yang dimuat turun dilumpuhkan dalam mod Selamat"</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Widget"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Widget"</string>
diff --git a/src/com/android/launcher3/InstallShortcutReceiver.java b/src/com/android/launcher3/InstallShortcutReceiver.java
index 2edde4f..e9fb499 100644
--- a/src/com/android/launcher3/InstallShortcutReceiver.java
+++ b/src/com/android/launcher3/InstallShortcutReceiver.java
@@ -17,7 +17,6 @@
 package com.android.launcher3;
 
 import android.content.BroadcastReceiver;
-import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.SharedPreferences;
@@ -45,17 +44,17 @@
     private static final String TAG = "InstallShortcutReceiver";
     private static final boolean DBG = false;
 
-    public static final String ACTION_INSTALL_SHORTCUT =
+    private static final String ACTION_INSTALL_SHORTCUT =
             "com.android.launcher.action.INSTALL_SHORTCUT";
 
-    public static final String DATA_INTENT_KEY = "intent.data";
-    public static final String LAUNCH_INTENT_KEY = "intent.launch";
-    public static final String NAME_KEY = "name";
-    public static final String ICON_KEY = "icon";
-    public static final String ICON_RESOURCE_NAME_KEY = "iconResource";
-    public static final String ICON_RESOURCE_PACKAGE_NAME_KEY = "iconResourcePackage";
+    private static final String DATA_INTENT_KEY = "intent.data";
+    private static final String LAUNCH_INTENT_KEY = "intent.launch";
+    private static final String NAME_KEY = "name";
+    private static final String ICON_KEY = "icon";
+    private static final String ICON_RESOURCE_NAME_KEY = "iconResource";
+    private static final String ICON_RESOURCE_PACKAGE_NAME_KEY = "iconResourcePackage";
     // The set of shortcuts that are pending install
-    public static final String APPS_PENDING_INSTALL = "apps_to_install";
+    private static final String APPS_PENDING_INSTALL = "apps_to_install";
 
     public static final int NEW_SHORTCUT_BOUNCE_DURATION = 450;
     public static final int NEW_SHORTCUT_STAGGER_DELAY = 85;
@@ -63,17 +62,13 @@
     private static final int INSTALL_SHORTCUT_SUCCESSFUL = 0;
     private static final int INSTALL_SHORTCUT_IS_DUPLICATE = -1;
 
-    // A mime-type representing shortcut data
-    public static final String SHORTCUT_MIMETYPE =
-            "com.android.launcher3/shortcut";
-
     private static Object sLock = new Object();
 
     private static void addToStringSet(SharedPreferences sharedPrefs,
             SharedPreferences.Editor editor, String key, String value) {
         Set<String> strings = sharedPrefs.getStringSet(key, null);
         if (strings == null) {
-            strings = new HashSet<String>(0);
+            strings = new HashSet<String>(1);
         } else {
             strings = new HashSet<String>(strings);
         }
@@ -133,6 +128,9 @@
                         Intent launchIntent = Intent.parseUri(object.getString(LAUNCH_INTENT_KEY), 0);
                         String pn = launchIntent.getPackage();
                         if (pn == null) {
+                            if (launchIntent.getComponent() == null) {
+                                continue;
+                            }
                             pn = launchIntent.getComponent().getPackageName();
                         }
                         if (packageNames.contains(pn)) {
@@ -355,7 +353,7 @@
                     Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
         }
         LauncherAppState app = LauncherAppState.getInstance();
-        ShortcutInfo info = app.getModel().infoFromShortcutIntent(context, data, null);
+        ShortcutInfo info = app.getModel().infoFromShortcutIntent(context, data);
         info.title = ensureValidName(context, launchIntent, info.title);
         return info;
     }
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index be9f268..d5cb55b 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -403,6 +403,10 @@
                     .build());
         }
 
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.preOnCreate();
+        }
+
         super.onCreate(savedInstanceState);
 
         LauncherAppState.setApplicationContext(getApplicationContext());
@@ -499,13 +503,38 @@
             showFirstRunActivity();
             showFirstRunClings();
         }
+
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.onCreate(savedInstanceState);
+        }
+    }
+
+    private LauncherCallbacks mLauncherCallbacks;
+
+    public void onPostCreate(Bundle savedInstanceState) {
+        super.onPostCreate(savedInstanceState);
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.onPostCreate(savedInstanceState);
+        }
+    }
+
+    public boolean setLauncherCallbacks(LauncherCallbacks callbacks) {
+        mLauncherCallbacks = callbacks;
+        return true;
     }
 
     @Override
-    public void onLauncherProviderChange() { }
+    public void onLauncherProviderChange() {
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.onLauncherProviderChange();
+        }
+    }
 
-    /** To be overriden by subclasses to hint to Launcher that we have custom content */
+    /** To be overridden by subclasses to hint to Launcher that we have custom content */
     protected boolean hasCustomContentToLeft() {
+        if (mLauncherCallbacks != null) {
+            return mLauncherCallbacks.hasCustomContentToLeft();
+        }
         return false;
     }
 
@@ -515,6 +544,9 @@
      * {@link #hasCustomContentToLeft()} is {@code true}.
      */
     protected void populateCustomContentContainer() {
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.populateCustomContentContainer();
+        }
     }
 
     /**
@@ -953,12 +985,20 @@
     protected void onStop() {
         super.onStop();
         FirstFrameAnimatorHelper.setIsVisible(false);
+
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.onStop();
+        }
     }
 
     @Override
     protected void onStart() {
         super.onStart();
         FirstFrameAnimatorHelper.setIsVisible(true);
+
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.onStart();
+        }
     }
 
     @Override
@@ -968,6 +1008,11 @@
             startTime = System.currentTimeMillis();
             Log.v(TAG, "Launcher.onResume()");
         }
+
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.preOnResume();
+        }
+
         super.onResume();
 
         // Restore the previous launcher state
@@ -1056,6 +1101,10 @@
         mWorkspace.onResume();
 
         PackageInstallerCompat.getInstance(this).onResume();
+
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.onResume();
+        }
     }
 
     @Override
@@ -1074,25 +1123,10 @@
         if (mWorkspace.getCustomContentCallbacks() != null) {
             mWorkspace.getCustomContentCallbacks().onHide();
         }
-    }
 
-    QSBScroller mQsbScroller = new QSBScroller() {
-        int scrollY = 0;
-
-        @Override
-        public void setScrollY(int scroll) {
-            scrollY = scroll;
-
-            if (mWorkspace.isOnOrMovingToCustomContent()) {
-                mSearchDropTargetBar.setTranslationY(- scrollY);
-                getQsbBar().setTranslationY(-scrollY);
-            }
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.onPause();
         }
-    };
-
-    public void resetQSBScroll() {
-        mSearchDropTargetBar.animate().translationY(0).start();
-        getQsbBar().animate().translationY(0).start();
     }
 
     public interface CustomContentCallbacks {
@@ -1111,17 +1145,16 @@
     }
 
     protected boolean hasSettings() {
+        if (mLauncherCallbacks != null) {
+            return mLauncherCallbacks.hasSettings();
+        }
         return false;
     }
 
-    public interface QSBScroller {
-        public void setScrollY(int scrollY);
-    }
 
-    public QSBScroller addToCustomContentPage(View customContent,
+    public void addToCustomContentPage(View customContent,
             CustomContentCallbacks callbacks, String description) {
         mWorkspace.addToCustomContentPage(customContent, callbacks, description);
-        return mQsbScroller;
     }
 
     // The custom content needs to offset its content to account for the QSB
@@ -1146,6 +1179,10 @@
     public void onWindowFocusChanged(boolean hasFocus) {
         super.onWindowFocusChanged(hasFocus);
         mHasFocus = hasFocus;
+
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.onWindowFocusChanged(hasFocus);
+        }
     }
 
     private boolean acceptFilter() {
@@ -1434,7 +1471,7 @@
 
         boolean foundCellSpan = false;
 
-        ShortcutInfo info = mModel.infoFromShortcutIntent(this, data, null);
+        ShortcutInfo info = mModel.infoFromShortcutIntent(this, data);
         if (info == null) {
             return;
         }
@@ -1884,8 +1921,11 @@
             Folder openFolder = mWorkspace.getOpenFolder();
             // In all these cases, only animate if we're already on home
             mWorkspace.exitWidgetResizeMode();
+
+            boolean moveToDefaultScreen = mLauncherCallbacks != null ?
+                    mLauncherCallbacks.shouldMoveToDefaultScreenOnHomeIntent() : true;
             if (alreadyOnHome && mState == State.WORKSPACE && !mWorkspace.isTouchActive() &&
-                    openFolder == null && shouldMoveToDefaultScreenOnHomeIntent()) {
+                    openFolder == null && moveToDefaultScreen) {
                 mWorkspace.moveToDefaultScreen(true);
             }
 
@@ -1912,27 +1952,18 @@
                 mAppsCustomizeTabHost.reset();
             }
 
-            onHomeIntent();
+            if (mLauncherCallbacks != null) {
+                mLauncherCallbacks.onHomeIntent();
+            }
         }
 
         if (DEBUG_RESUME_TIME) {
             Log.d(TAG, "Time spent in onNewIntent: " + (System.currentTimeMillis() - startTime));
         }
-    }
 
-    /**
-     * Override point for subclasses to prevent movement to the default screen when the home
-     * button is pressed. Used (for example) in GEL, to prevent movement during a search.
-     */
-    protected boolean shouldMoveToDefaultScreenOnHomeIntent() {
-        return true;
-    }
-
-    /**
-     * Override point for subclasses to provide custom behaviour for when a home intent is fired.
-     */
-    protected void onHomeIntent() {
-        // Do nothing
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.onNewIntent(intent);
+        }
     }
 
     @Override
@@ -1984,6 +2015,10 @@
             outState.putInt("apps_customize_currentIndex", currentIndex);
         }
         outState.putSerializable(RUNTIME_STATE_VIEW_IDS, mItemIdToViewId);
+
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.onSaveInstanceState(outState);
+        }
     }
 
     @Override
@@ -2033,6 +2068,10 @@
 
         PackageInstallerCompat.getInstance(this).onStop();
         LauncherAnimUtils.onDestroyActivity();
+
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.onDestroy();
+        }
     }
 
     public DragController getDragController() {
@@ -2086,6 +2125,11 @@
      */
     public boolean startSearch(String initialQuery,
             boolean selectInitialQuery, Bundle appSearchData, Rect sourceBounds) {
+        if (mLauncherCallbacks != null && mLauncherCallbacks.providesSearch()) {
+            return mLauncherCallbacks.startSearch(initialQuery, selectInitialQuery, appSearchData,
+                    sourceBounds);
+        }
+
         startGlobalSearch(initialQuery, selectInitialQuery,
                 appSearchData, sourceBounds);
         return false;
@@ -2112,7 +2156,7 @@
         } else {
             appSearchData = new Bundle(appSearchData);
         }
-        // Set source to package name of app that starts global search, if not set already.
+        // Set source to package name of app that starts global search if not set already.
         if (!appSearchData.containsKey("source")) {
             appSearchData.putString("source", getPackageName());
         }
@@ -2150,6 +2194,10 @@
                 showWorkspace(true);
             }
         }
+        if (mLauncherCallbacks != null) {
+            return mLauncherCallbacks.onPrepareOptionsMenu(menu);
+        }
+
         return false;
     }
 
@@ -2184,7 +2232,11 @@
         }
     }
 
-    protected void onWorkspaceLockedChanged() { }
+    protected void onWorkspaceLockedChanged() {
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.onWorkspaceLockedChanged();
+        }
+    }
 
     private void resetAddInfo() {
         mPendingAddInfo.container = ItemInfo.NO_ID;
@@ -2346,6 +2398,9 @@
     }
 
     protected ComponentName getWallpaperPickerComponent() {
+        if (mLauncherCallbacks != null) {
+            return mLauncherCallbacks.getWallpaperPickerComponent();
+        }
         return new ComponentName(getPackageName(), LauncherWallpaperPickerActivity.class.getName());
     }
 
@@ -2384,6 +2439,10 @@
 
     @Override
     public void onBackPressed() {
+        if (mLauncherCallbacks != null && mLauncherCallbacks.handleBackPressed()) {
+            return;
+        }
+
         if (isAllAppsVisible()) {
             if (mAppsCustomizeContent.getContentType() ==
                     AppsCustomizePagedView.ContentType.Applications) {
@@ -2466,6 +2525,9 @@
 
     public void onClickPagedViewIcon(View v) {
         startAppShortcutOrInfoActivity(v);
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.onClickPagedViewIcon(v);
+        }
     }
 
     public boolean onTouch(View v, MotionEvent event) {
@@ -2527,6 +2589,11 @@
     }
 
     public void startVoice() {
+        if (mLauncherCallbacks != null && mLauncherCallbacks.providesSearch()) {
+            mLauncherCallbacks.startVoice();
+            return;
+        }
+
         try {
             final SearchManager searchManager =
                     (SearchManager) getSystemService(Context.SEARCH_SERVICE);
@@ -2557,6 +2624,9 @@
         } else {
             showAllApps(true, AppsCustomizePagedView.ContentType.Applications, false);
         }
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.onClickAllAppsButton(v);
+        }
     }
 
     private void showBrokenAppInstallDialog(final String packageName,
@@ -2631,6 +2701,10 @@
 
         // Start activities
         startAppShortcutOrInfoActivity(v);
+
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.onClickAppShortcut(v);
+        }
     }
 
     private void startAppShortcutOrInfoActivity(View v) {
@@ -2704,6 +2778,10 @@
                 }
             }
         }
+
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.onClickFolderIcon(v);
+        }
     }
 
     /**
@@ -2713,6 +2791,10 @@
     protected void onClickAddWidgetButton(View view) {
         if (LOGD) Log.d(TAG, "onClickAddWidgetButton");
         showAllApps(true, AppsCustomizePagedView.ContentType.Widgets, true);
+
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.onClickAddWidgetButton(view);
+        }
     }
 
     /**
@@ -2724,6 +2806,10 @@
         final Intent pickWallpaper = new Intent(Intent.ACTION_SET_WALLPAPER);
         pickWallpaper.setComponent(getWallpaperPickerComponent());
         startActivityForResult(pickWallpaper, REQUEST_PICK_WALLPAPER);
+
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.onClickWallpaperPicker(v);
+        }
     }
 
     /**
@@ -2732,6 +2818,9 @@
      */
     protected void onClickSettingsButton(View v) {
         if (LOGD) Log.d(TAG, "onClickSettingsButton");
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.onClickSettingsButton(v);
+        }
     }
 
     public void onTouchDownAllAppsButton(View v) {
@@ -2759,13 +2848,27 @@
         return mHapticFeedbackTouchListener;
     }
 
-    public void onDragStarted(View view) {}
+    public void onDragStarted(View view) {
+        if (isOnCustomContent()) {
+            // Custom content screen doesn't participate in drag and drop. If on custom
+            // content screen, move to default.
+            moveWorkspaceToDefaultScreen();
+        }
+
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.onDragStarted(view);
+        }
+    }
 
     /**
      * Called when the user stops interacting with the launcher.
      * This implies that the user is now on the homescreen and is not doing housekeeping.
      */
-    protected void onInteractionEnd() {}
+    protected void onInteractionEnd() {
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.onInteractionEnd();
+        }
+    }
 
     /**
      * Called when the user starts interacting with the launcher.
@@ -2776,7 +2879,11 @@
      * This is a good time to stop doing things that only make sense
      * when the user is on the homescreen and not doing housekeeping.
      */
-    protected void onInteractionBegin() {}
+    protected void onInteractionBegin() {
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.onInteractionBegin();
+        }
+    }
 
     void startApplicationDetailsActivity(ComponentName componentName, UserHandleCompat user) {
         String packageName = componentName.getPackageName();
@@ -3972,6 +4079,13 @@
     }
 
     public View getQsbBar() {
+        if (mLauncherCallbacks != null) {
+            View qsb = mLauncherCallbacks.getQsbBar();
+            if (qsb != null) {
+                return qsb;
+            }
+        }
+
         if (mQsb == null) {
             mQsb = mInflater.inflate(R.layout.qsb, mSearchDropTargetBar, false);
             mSearchDropTargetBar.addView(mQsb);
@@ -3980,6 +4094,10 @@
     }
 
     protected boolean updateGlobalSearchIcon() {
+        if (mLauncherCallbacks != null && mLauncherCallbacks.providesSearch()) {
+            return true;
+        }
+
         final View searchButtonContainer = findViewById(R.id.search_button_container);
         final ImageView searchButton = (ImageView) findViewById(R.id.search_button);
         final View voiceButtonContainer = findViewById(R.id.voice_button_container);
@@ -4015,6 +4133,7 @@
     }
 
     protected void updateGlobalSearchIcon(Drawable.ConstantState d) {
+        if (mLauncherCallbacks != null && mLauncherCallbacks.providesSearch()) return;
         final View searchButtonContainer = findViewById(R.id.search_button_container);
         final View searchButton = (ImageView) findViewById(R.id.search_button);
         updateButtonWithDrawable(R.id.search_button, d);
@@ -4022,6 +4141,9 @@
     }
 
     protected boolean updateVoiceSearchIcon(boolean searchVisible) {
+        if (mLauncherCallbacks != null && mLauncherCallbacks.providesSearch()) {
+            return true;
+        }
         final View voiceButtonContainer = findViewById(R.id.voice_button_container);
         final View voiceButton = findViewById(R.id.voice_button);
 
@@ -4068,6 +4190,10 @@
     }
 
     protected void updateVoiceSearchIcon(Drawable.ConstantState d) {
+        if (mLauncherCallbacks != null && mLauncherCallbacks.providesSearch()) {
+            return;
+        }
+
         final View voiceButtonContainer = findViewById(R.id.voice_button_container);
         final View voiceButton = findViewById(R.id.voice_button);
         updateButtonWithDrawable(R.id.voice_button, d);
@@ -4075,6 +4201,9 @@
     }
 
     public void updateVoiceButtonProxyVisible(boolean forceDisableVoiceButtonProxy) {
+        if (mLauncherCallbacks != null) {
+            forceDisableVoiceButtonProxy |= mLauncherCallbacks.forceDisableVoiceButtonProxy();
+        }
         final View voiceButtonProxy = findViewById(R.id.voice_button_proxy);
         if (voiceButtonProxy != null) {
             boolean visible = !forceDisableVoiceButtonProxy &&
@@ -4617,6 +4746,10 @@
             mIntentsOnWorkspaceFromUpgradePath = mWorkspace.getUniqueComponents(true, null);
         }
         PackageInstallerCompat.getInstance(this).onFinishBind();
+
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.finishBindingItems(upgradePath);
+        }
     }
 
     private void sendLoadingCompleteBroadcastIfNecessary() {
@@ -4698,6 +4831,9 @@
                         LauncherModel.getSortedWidgetsAndShortcuts(this));
             }
         }
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.bindAllApplications(apps);
+        }
     }
 
     /**
@@ -4891,16 +5027,10 @@
         }
     }
 
-    /**
-     * Called when the SearchBar hint should be changed.
-     *
-     * @param hint the hint to be displayed in the search bar.
-     */
-    protected void onSearchBarHintChanged(String hint) {
-
-    }
-
     protected boolean isLauncherPreinstalled() {
+        if (mLauncherCallbacks != null) {
+            return mLauncherCallbacks.isLauncherPreinstalled();
+        }
         PackageManager pm = getPackageManager();
         try {
             ApplicationInfo ai = pm.getApplicationInfo(getComponentName().getPackageName(), 0);
@@ -4920,6 +5050,9 @@
      * when our wallpaper cropper was not yet used to set a wallpaper.
      */
     protected boolean overrideWallpaperDimensions() {
+        if (mLauncherCallbacks != null) {
+            return mLauncherCallbacks.overrideWallpaperDimensions();
+        }
         return true;
     }
 
@@ -4928,6 +5061,9 @@
      * before showing the standard launcher experience.
      */
     protected boolean hasFirstRunActivity() {
+        if (mLauncherCallbacks != null) {
+            return mLauncherCallbacks.hasFirstRunActivity();
+        }
         return false;
     }
 
@@ -4935,6 +5071,9 @@
      * To be overridden by subclasses to launch any first run activity
      */
     protected Intent getFirstRunActivity() {
+        if (mLauncherCallbacks != null) {
+            return mLauncherCallbacks.getFirstRunActivity();
+        }
         return null;
     }
 
@@ -4971,6 +5110,9 @@
      * screen that must be displayed and dismissed.
      */
     protected boolean hasDismissableIntroScreen() {
+        if (mLauncherCallbacks != null) {
+            return mLauncherCallbacks.hasDismissableIntroScreen();
+        }
         return false;
     }
 
@@ -4978,6 +5120,9 @@
      * Full screen intro screen to be shown and dismissed before the launcher can be used.
      */
     protected View getIntroScreen() {
+        if (mLauncherCallbacks != null) {
+            return mLauncherCallbacks.getIntroScreen();
+        }
         return null;
     }
 
@@ -5089,6 +5234,9 @@
 
     @Override
     public void onPageSwitch(View newPage, int newPageIndex) {
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.onPageSwitch(newPage, newPageIndex);
+        }
     }
 
     /**
@@ -5120,6 +5268,9 @@
                 writer.println("  " + sDumpLogs.get(i));
             }
         }
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.dump(prefix, fd, writer, args);
+        }
     }
 
     public static void dumpDebugLogsToConsole() {
diff --git a/src/com/android/launcher3/LauncherCallbacks.java b/src/com/android/launcher3/LauncherCallbacks.java
new file mode 100644
index 0000000..aef2adc
--- /dev/null
+++ b/src/com/android/launcher3/LauncherCallbacks.java
@@ -0,0 +1,89 @@
+package com.android.launcher3;
+
+import android.content.ComponentName;
+import android.content.Intent;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.View;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+
+/**
+ * LauncherCallbacks is an interface used to extend the Launcher activity. It includes many hooks
+ * in order to add additional functionality. Some of these are very general, and give extending
+ * classes the ability to react to Activity life-cycle or specific user interactions. Others
+ * are more specific and relate to replacing parts of the application, for example, the search
+ * interface or the wallpaper picker.
+ */
+public interface LauncherCallbacks {
+
+    /*
+     * Activity life-cycle methods. These methods are triggered after
+     * the code in the corresponding Launcher method is executed.
+     */
+    public void preOnCreate();
+    public void onCreate(Bundle savedInstanceState);
+    public void preOnResume();
+    public void onResume();
+    public void onStart();
+    public void onStop();
+    public void onPause();
+    public void onDestroy();
+    public void onSaveInstanceState(Bundle outState);
+    public void onPostCreate(Bundle savedInstanceState);
+    public void onNewIntent(Intent intent);
+    public void onActivityResult(int requestCode, int resultCode, Intent data);
+    public void onWindowFocusChanged(boolean hasFocus);
+    public boolean onPrepareOptionsMenu(Menu menu);
+    public void dump(String prefix, FileDescriptor fd, PrintWriter w, String[] args);
+    public void onHomeIntent();
+    public boolean handleBackPressed();
+
+    /*
+     * Extension points for providing custom behavior on certain user interactions.
+     */
+    public void onLauncherProviderChange();
+    public void finishBindingItems(final boolean upgradePath);
+    public void onClickAllAppsButton(View v);
+    public void bindAllApplications(ArrayList<AppInfo> apps);
+    public void onClickFolderIcon(View v);
+    public void onClickAppShortcut(View v);
+    public void onClickPagedViewIcon(View v);
+    public void onClickWallpaperPicker(View v);
+    public void onClickSettingsButton(View v);
+    public void onClickAddWidgetButton(View v);
+    public void onPageSwitch(View newPage, int newPageIndex);
+    public void onWorkspaceLockedChanged();
+    public void onDragStarted(View view);
+    public void onInteractionBegin();
+    public void onInteractionEnd();
+
+    /*
+     * Extension points for replacing the search experience
+     */
+    public boolean forceDisableVoiceButtonProxy();
+    public boolean providesSearch();
+    public boolean startSearch(String initialQuery, boolean selectInitialQuery,
+            Bundle appSearchData, Rect sourceBounds);
+    public void startVoice();
+    public boolean hasCustomContentToLeft();
+    public void populateCustomContentContainer();
+    public View getQsbBar();
+
+    /*
+     * Extensions points for adding / replacing some other aspects of the Launcher experience.
+     */
+    public Intent getFirstRunActivity();
+    public boolean hasFirstRunActivity();
+    public boolean hasDismissableIntroScreen();
+    public View getIntroScreen();
+    public boolean shouldMoveToDefaultScreenOnHomeIntent();
+    public boolean hasSettings();
+    public ComponentName getWallpaperPickerComponent();
+    public boolean overrideWallpaperDimensions();
+    public boolean isLauncherPreinstalled();
+
+}
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index 0b7ee2e..f747423 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -3499,17 +3499,6 @@
         }
     }
 
-    ShortcutInfo addShortcut(Context context, Intent data, long container, int screen,
-            int cellX, int cellY, boolean notify) {
-        final ShortcutInfo info = infoFromShortcutIntent(context, data, null);
-        if (info == null) {
-            return null;
-        }
-        addItemToDatabase(context, info, container, screen, cellX, cellY, notify);
-
-        return info;
-    }
-
     /**
      * Attempts to find an AppWidgetProviderInfo that matches the given component.
      */
@@ -3525,7 +3514,7 @@
         return null;
     }
 
-    ShortcutInfo infoFromShortcutIntent(Context context, Intent data, Bitmap fallbackIcon) {
+    ShortcutInfo infoFromShortcutIntent(Context context, Intent data) {
         Intent intent = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT);
         String name = data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME);
         Parcelable bitmap = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON);
@@ -3558,12 +3547,8 @@
         // users wouldn't get here without intent forwarding anyway.
         info.user = UserHandleCompat.myUserHandle();
         if (icon == null) {
-            if (fallbackIcon != null) {
-                icon = fallbackIcon;
-            } else {
-                icon = mIconCache.getDefaultIcon(info.user);
-                info.usingFallbackIcon = true;
-            }
+            icon = mIconCache.getDefaultIcon(info.user);
+            info.usingFallbackIcon = true;
         }
         info.setIcon(icon);
 
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 965eaae..2683bec 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -1267,7 +1267,6 @@
             mCustomContentShowing = false;
             if (mCustomContentCallbacks != null) {
                 mCustomContentCallbacks.onHide();
-                mLauncher.resetQSBScroll();
                 mLauncher.updateVoiceButtonProxyVisible(false);
             }
         }