diff options
author | Samuel Fufa <sfufa@google.com> | 2019-08-19 17:04:36 -0700 |
---|---|---|
committer | Samuel Fufa <sfufa@google.com> | 2019-08-23 10:58:13 -0700 |
commit | ca37b8afe5968b44826506fc1094996592fd25fc (patch) | |
tree | 09f0a98daa1b1bd4e37f93bb16389ea256c84b5f | |
parent | 6fe3eec95cfb153ed7c16c6381623b7e762452c3 (diff) | |
download | packages_apps_Trebuchet-ca37b8afe5968b44826506fc1094996592fd25fc.tar.gz packages_apps_Trebuchet-ca37b8afe5968b44826506fc1094996592fd25fc.tar.bz2 packages_apps_Trebuchet-ca37b8afe5968b44826506fc1094996592fd25fc.zip |
Add support for searchwidget in layout files.
Test: Manual
Bug:139703885
Change-Id: I86b36187d95bb5db59dbf6ae2e20373d23e55aa1
-rw-r--r-- | src/com/android/launcher3/AutoInstallsLayout.java | 85 | ||||
-rw-r--r-- | src/com/android/launcher3/DefaultLayoutParser.java | 19 | ||||
-rw-r--r-- | src/com/android/launcher3/Launcher.java | 73 | ||||
-rw-r--r-- | src/com/android/launcher3/LauncherAppWidgetInfo.java | 18 | ||||
-rw-r--r-- | src/com/android/launcher3/model/LoaderTask.java | 23 | ||||
-rw-r--r-- | src/com/android/launcher3/qsb/QsbContainerView.java | 109 |
6 files changed, 228 insertions, 99 deletions
diff --git a/src/com/android/launcher3/AutoInstallsLayout.java b/src/com/android/launcher3/AutoInstallsLayout.java index 8bf1a37e2..ac4396778 100644 --- a/src/com/android/launcher3/AutoInstallsLayout.java +++ b/src/com/android/launcher3/AutoInstallsLayout.java @@ -38,10 +38,13 @@ import android.util.Pair; import android.util.Patterns; import android.util.Xml; +import androidx.annotation.Nullable; + import com.android.launcher3.LauncherProvider.SqlArguments; import com.android.launcher3.LauncherSettings.Favorites; import com.android.launcher3.icons.GraphicsUtils; import com.android.launcher3.icons.LauncherIcons; +import com.android.launcher3.qsb.QsbContainerView; import com.android.launcher3.util.IntArray; import com.android.launcher3.util.PackageManagerHelper; import com.android.launcher3.util.Thunk; @@ -84,7 +87,7 @@ public class AutoInstallsLayout { // Try with grid size and hotseat count String layoutName = String.format(Locale.ENGLISH, FORMATTED_LAYOUT_RES_WITH_HOSTEAT, - grid.numColumns, grid.numRows, grid.numHotseatIcons); + grid.numColumns, grid.numRows, grid.numHotseatIcons); int layoutId = targetRes.getIdentifier(layoutName, "xml", pkg); // Try with only grid size @@ -92,7 +95,7 @@ public class AutoInstallsLayout { Log.d(TAG, "Formatted layout: " + layoutName + " not found. Trying layout without hosteat"); layoutName = String.format(Locale.ENGLISH, FORMATTED_LAYOUT_RES, - grid.numColumns, grid.numRows); + grid.numColumns, grid.numRows); layoutId = targetRes.getIdentifier(layoutName, "xml", pkg); } @@ -117,6 +120,7 @@ public class AutoInstallsLayout { private static final String TAG_AUTO_INSTALL = "autoinstall"; private static final String TAG_FOLDER = "folder"; private static final String TAG_APPWIDGET = "appwidget"; + protected static final String TAG_SEARCH_WIDGET = "searchwidget"; private static final String TAG_SHORTCUT = "shortcut"; private static final String TAG_EXTRA = "extra"; @@ -148,8 +152,10 @@ public class AutoInstallsLayout { private static final String HOTSEAT_CONTAINER_NAME = Favorites.containerToString(Favorites.CONTAINER_HOTSEAT); - @Thunk final Context mContext; - @Thunk final AppWidgetHost mAppWidgetHost; + @Thunk + final Context mContext; + @Thunk + final AppWidgetHost mAppWidgetHost; protected final LayoutParserCallback mCallback; protected final PackageManager mPackageManager; @@ -161,7 +167,8 @@ public class AutoInstallsLayout { private final int mColumnCount; private final int[] mTemp = new int[2]; - @Thunk final ContentValues mValues; + @Thunk + final ContentValues mValues; protected final String mRootTag; protected SQLiteDatabase mDb; @@ -245,7 +252,7 @@ public class AutoInstallsLayout { */ protected int parseAndAddNode( XmlPullParser parser, ArrayMap<String, TagParser> tagParserMap, IntArray screenIds) - throws XmlPullParserException, IOException { + throws XmlPullParserException, IOException { if (TAG_INCLUDE.equals(parser.getName())) { final int resId = getAttributeResourceValue(parser, ATTR_WORKSPACE, 0); @@ -316,6 +323,7 @@ public class AutoInstallsLayout { parsers.put(TAG_AUTO_INSTALL, new AutoInstallParser()); parsers.put(TAG_FOLDER, new FolderParser()); parsers.put(TAG_APPWIDGET, new PendingWidgetParser()); + parsers.put(TAG_SEARCH_WIDGET, new SearchWidgetParser()); parsers.put(TAG_SHORTCUT, new ShortcutParser(mSourceRes)); return parsers; } @@ -348,15 +356,15 @@ public class AutoInstallsLayout { info = mPackageManager.getActivityInfo(cn, 0); } catch (PackageManager.NameNotFoundException nnfe) { String[] packages = mPackageManager.currentToCanonicalPackageNames( - new String[] { packageName }); + new String[]{packageName}); cn = new ComponentName(packages[0], className); info = mPackageManager.getActivityInfo(cn, 0); } final Intent intent = new Intent(Intent.ACTION_MAIN, null) - .addCategory(Intent.CATEGORY_LAUNCHER) - .setComponent(cn) - .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | - Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); + .addCategory(Intent.CATEGORY_LAUNCHER) + .setComponent(cn) + .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK + | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); return addShortcut(info.loadLabel(mPackageManager).toString(), intent, Favorites.ITEM_TYPE_APPLICATION); @@ -394,10 +402,10 @@ public class AutoInstallsLayout { mValues.put(Favorites.RESTORED, WorkspaceItemInfo.FLAG_AUTOINSTALL_ICON); final Intent intent = new Intent(Intent.ACTION_MAIN, null) - .addCategory(Intent.CATEGORY_LAUNCHER) - .setComponent(new ComponentName(packageName, className)) - .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | - Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); + .addCategory(Intent.CATEGORY_LAUNCHER) + .setComponent(new ComponentName(packageName, className)) + .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK + | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); return addShortcut(mContext.getString(R.string.package_state_unknown), intent, Favorites.ITEM_TYPE_APPLICATION); } @@ -445,7 +453,7 @@ public class AutoInstallsLayout { mValues.put(Favorites.ICON_RESOURCE, mIconRes.getResourceName(iconId)); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | - Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); + Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); return addShortcut(mSourceRes.getString(titleResId), intent, Favorites.ITEM_TYPE_SHORTCUT); } @@ -470,12 +478,22 @@ public class AutoInstallsLayout { */ protected class PendingWidgetParser implements TagParser { - @Override - public int parseAndAdd(XmlPullParser parser) - throws XmlPullParserException, IOException { + @Nullable + public ComponentName getComponentName(XmlPullParser parser) { final String packageName = getAttributeValue(parser, ATTR_PACKAGE_NAME); final String className = getAttributeValue(parser, ATTR_CLASS_NAME); if (TextUtils.isEmpty(packageName) || TextUtils.isEmpty(className)) { + return null; + } + return new ComponentName(packageName, className); + } + + + @Override + public int parseAndAdd(XmlPullParser parser) + throws XmlPullParserException, IOException { + ComponentName cn = getComponentName(parser); + if (cn == null) { if (LOGD) Log.d(TAG, "Skipping invalid <appwidget> with no component"); return -1; } @@ -506,16 +524,15 @@ public class AutoInstallsLayout { throw new RuntimeException("Widgets can contain only extras"); } } - - return verifyAndInsert(new ComponentName(packageName, className), extras); + return verifyAndInsert(cn, extras); } protected int verifyAndInsert(ComponentName cn, Bundle extras) { mValues.put(Favorites.APPWIDGET_PROVIDER, cn.flattenToString()); mValues.put(Favorites.RESTORED, - LauncherAppWidgetInfo.FLAG_ID_NOT_VALID | - LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY | - LauncherAppWidgetInfo.FLAG_DIRECT_CONFIG); + LauncherAppWidgetInfo.FLAG_ID_NOT_VALID + | LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY + | LauncherAppWidgetInfo.FLAG_DIRECT_CONFIG); mValues.put(Favorites._ID, mCallback.generateNewItemId()); if (!extras.isEmpty()) { mValues.put(Favorites.INTENT, new Intent().putExtras(extras).toUri(0)); @@ -530,6 +547,23 @@ public class AutoInstallsLayout { } } + protected class SearchWidgetParser extends PendingWidgetParser { + @Override + @Nullable + public ComponentName getComponentName(XmlPullParser parser) { + return QsbContainerView.getSearchComponentName(mContext); + } + + @Override + protected int verifyAndInsert(ComponentName cn, Bundle extras) { + mValues.put(Favorites.OPTIONS, LauncherAppWidgetInfo.OPTION_SEARCH_WIDGET); + int flags = mValues.getAsInteger(Favorites.RESTORED) + | WorkspaceItemInfo.FLAG_RESTORE_STARTED; + mValues.put(Favorites.RESTORED, flags); + return super.verifyAndInsert(cn, extras); + } + } + protected class FolderParser implements TagParser { private final ArrayMap<String, TagParser> mFolderElements; @@ -681,7 +715,8 @@ public class AutoInstallsLayout { int insertAndCheck(SQLiteDatabase db, ContentValues values); } - @Thunk static void copyInteger(ContentValues from, ContentValues to, String key) { + @Thunk + static void copyInteger(ContentValues from, ContentValues to, String key) { to.put(key, from.getAsInteger(key)); } } diff --git a/src/com/android/launcher3/DefaultLayoutParser.java b/src/com/android/launcher3/DefaultLayoutParser.java index 75297f63b..af8559477 100644 --- a/src/com/android/launcher3/DefaultLayoutParser.java +++ b/src/com/android/launcher3/DefaultLayoutParser.java @@ -14,13 +14,16 @@ import android.os.Bundle; import android.text.TextUtils; import android.util.ArrayMap; import android.util.Log; + import com.android.launcher3.LauncherSettings.Favorites; import com.android.launcher3.util.Thunk; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + import java.io.IOException; import java.net.URISyntaxException; import java.util.List; -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; /** * Implements the layout parser with rules for internal layouts and partner layouts. @@ -55,7 +58,8 @@ public class DefaultLayoutParser extends AutoInstallsLayout { return getFolderElementsMap(mSourceRes); } - @Thunk ArrayMap<String, TagParser> getFolderElementsMap(Resources res) { + @Thunk + ArrayMap<String, TagParser> getFolderElementsMap(Resources res) { ArrayMap<String, TagParser> parsers = new ArrayMap<>(); parsers.put(TAG_FAVORITE, new AppShortcutWithUriParser()); parsers.put(TAG_SHORTCUT, new UriShortcutParser(res)); @@ -67,6 +71,7 @@ public class DefaultLayoutParser extends AutoInstallsLayout { ArrayMap<String, TagParser> parsers = new ArrayMap<>(); parsers.put(TAG_FAVORITE, new AppShortcutWithUriParser()); parsers.put(TAG_APPWIDGET, new AppWidgetParser()); + parsers.put(TAG_SEARCH_WIDGET, new SearchWidgetParser()); parsers.put(TAG_SHORTCUT, new UriShortcutParser(mSourceRes)); parsers.put(TAG_RESOLVE, new ResolveParser()); parsers.put(TAG_FOLDER, new MyFolderParser()); @@ -229,7 +234,8 @@ public class DefaultLayoutParser extends AutoInstallsLayout { /** * A parser which adds a folder whose contents come from partner apk. */ - @Thunk class PartnerFolderParser implements TagParser { + @Thunk + class PartnerFolderParser implements TagParser { @Override public int parseAndAdd(XmlPullParser parser) throws XmlPullParserException, @@ -255,7 +261,8 @@ public class DefaultLayoutParser extends AutoInstallsLayout { /** * An extension of FolderParser which allows adding items from a different xml. */ - @Thunk class MyFolderParser extends FolderParser { + @Thunk + class MyFolderParser extends FolderParser { @Override public int parseAndAdd(XmlPullParser parser) throws XmlPullParserException, @@ -281,7 +288,7 @@ public class DefaultLayoutParser extends AutoInstallsLayout { mPackageManager.getReceiverInfo(cn, 0); } catch (Exception e) { String[] packages = mPackageManager.currentToCanonicalPackageNames( - new String[] { cn.getPackageName() }); + new String[]{cn.getPackageName()}); cn = new ComponentName(packages[0], cn.getClassName()); try { mPackageManager.getReceiverInfo(cn, 0); diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index cdb16d233..aa02441ff 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -110,6 +110,7 @@ import com.android.launcher3.model.ModelWriter; import com.android.launcher3.notification.NotificationListener; import com.android.launcher3.popup.PopupContainerWithArrow; import com.android.launcher3.popup.PopupDataProvider; +import com.android.launcher3.qsb.QsbContainerView; import com.android.launcher3.states.InternalStateHandler; import com.android.launcher3.states.RotationHelper; import com.android.launcher3.touch.ItemClickHandler; @@ -210,7 +211,8 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, // How long to wait before the new-shortcut animation automatically pans the workspace private static final int NEW_APPS_PAGE_MOVE_DELAY = 500; private static final int NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS = 5; - @Thunk static final int NEW_APPS_ANIMATION_DELAY = 500; + @Thunk + static final int NEW_APPS_ANIMATION_DELAY = 500; private static final int APPS_VIEW_ALPHA_CHANNEL_INDEX = 1; private static final int SCRIM_VIEW_ALPHA_CHANNEL_INDEX = 0; @@ -218,9 +220,11 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, private LauncherAppTransitionManager mAppTransitionManager; private Configuration mOldConfig; - @Thunk Workspace mWorkspace; + @Thunk + Workspace mWorkspace; private View mLauncherView; - @Thunk DragLayer mDragLayer; + @Thunk + DragLayer mDragLayer; private DragController mDragController; private AppWidgetManagerCompat mAppWidgetManager; @@ -228,21 +232,25 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, private final int[] mTmpAddItemCellCoordinates = new int[2]; - @Thunk Hotseat mHotseat; + @Thunk + Hotseat mHotseat; private DropTargetBar mDropTargetBar; // Main container view for the all apps screen. - @Thunk AllAppsContainerView mAppsView; + @Thunk + AllAppsContainerView mAppsView; AllAppsTransitionController mAllAppsController; // Scrim view for the all apps and overview state. - @Thunk ScrimView mScrimView; + @Thunk + ScrimView mScrimView; // UI and state for the overview panel private View mOverviewPanel; - @Thunk boolean mWorkspaceLoading = true; + @Thunk + boolean mWorkspaceLoading = true; private ArrayList<OnResumeCallback> mOnResumeCallbacks = new ArrayList<>(); @@ -387,7 +395,8 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, RaceConditionTracker.onEvent(ON_CREATE_EVT, EXIT); mStateManager.addStateListener(new LauncherStateManager.StateListener() { @Override - public void onStateTransitionStart(LauncherState toState) {} + public void onStateTransitionStart(LauncherState toState) { + } @Override public void onStateTransitionComplete(LauncherState finalState) { @@ -640,7 +649,8 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, .getLauncherAppWidgetInfo(widgetId); if (provider != null) { new WidgetAddFlowHandler(provider) - .startConfigActivity(this, widgetInfo, REQUEST_RECONFIGURE_APPWIDGET); + .startConfigActivity(this, widgetInfo, + REQUEST_RECONFIGURE_APPWIDGET); } } break; @@ -828,7 +838,8 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, } } - @Thunk void completeTwoStageWidgetDrop( + @Thunk + void completeTwoStageWidgetDrop( final int resultCode, final int appWidgetId, final PendingRequestArgs requestArgs) { CellLayout cellLayout = mWorkspace.getScreenWithId(requestArgs.screenId); Runnable onCompleteRunnable = null; @@ -925,7 +936,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, int containerType = mStateManager.getState().containerType; if (containerType == ContainerType.WORKSPACE && mWorkspace != null) { getUserEventDispatcher().logActionCommand(command, - containerType, -1, mWorkspace.isOverlayShown() ? -1 : 0); + containerType, -1, mWorkspace.isOverlayShown() ? -1 : 0); } else { getUserEventDispatcher().logActionCommand(command, containerType, -1); } @@ -1054,7 +1065,8 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, mStateManager.goToState(state, false /* animated */); } - PendingRequestArgs requestArgs = savedState.getParcelable(RUNTIME_STATE_PENDING_REQUEST_ARGS); + PendingRequestArgs requestArgs = savedState.getParcelable( + RUNTIME_STATE_PENDING_REQUEST_ARGS); if (requestArgs != null) { setWaitingForResult(requestArgs); } @@ -1124,8 +1136,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, * Creates a view representing a shortcut inflated from the specified resource. * * @param parent The group the shortcut belongs to. - * @param info The data structure describing the shortcut. - * + * @param info The data structure describing the shortcut. * @return A View inflated from layoutResId. */ public View createShortcut(ViewGroup parent, WorkspaceItemInfo info) { @@ -1227,7 +1238,8 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, * * @param appWidgetId The app widget id */ - @Thunk void completeAddAppWidget(int appWidgetId, ItemInfo itemInfo, + @Thunk + void completeAddAppWidget(int appWidgetId, ItemInfo itemInfo, AppWidgetHostView hostView, LauncherAppWidgetProviderInfo appWidgetInfo) { if (appWidgetInfo == null) { @@ -1345,7 +1357,9 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, return mSharedPrefs; } - public int getOrientation() { return mOldConfig.orientation; } + public int getOrientation() { + return mOldConfig.orientation; + } @Override protected void onNewIntent(Intent intent) { @@ -1569,7 +1583,8 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, void addAppWidgetImpl(int appWidgetId, ItemInfo info, AppWidgetHostView boundWidget, WidgetAddFlowHandler addFlowHandler, int delay) { - if (!addFlowHandler.startConfigActivity(this, appWidgetId, info, REQUEST_CREATE_APPWIDGET)) { + if (!addFlowHandler.startConfigActivity(this, appWidgetId, info, + REQUEST_CREATE_APPWIDGET)) { // If the configuration flow was not started, add the widget Runnable onComplete = new Runnable() { @@ -1579,7 +1594,8 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, mStateManager.goToState(NORMAL, SPRING_LOADED_EXIT_DELAY); } }; - completeAddAppWidget(appWidgetId, info, boundWidget, addFlowHandler.getProviderInfo(this)); + completeAddAppWidget(appWidgetId, info, boundWidget, + addFlowHandler.getProviderInfo(this)); mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete, delay, false); } } @@ -1605,7 +1621,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, break; default: throw new IllegalStateException("Unknown item type: " + info.itemType); - } + } } /** @@ -1780,7 +1796,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, @Override public int getCurrentState() { - if(mStateManager.getState() == LauncherState.ALL_APPS) { + if (mStateManager.getState() == LauncherState.ALL_APPS) { return StatsLogUtils.LAUNCHER_STATE_ALLAPPS; } else if (mStateManager.getState() == OVERVIEW) { return StatsLogUtils.LAUNCHER_STATE_OVERVIEW; @@ -2043,7 +2059,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, throw new RuntimeException("Invalid Item Type"); } - /* + /* * Remove colliding items. */ if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) { @@ -2115,6 +2131,14 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, } private View inflateAppWidget(LauncherAppWidgetInfo item) { + if (item.hasOptionFlag(LauncherAppWidgetInfo.OPTION_SEARCH_WIDGET)) { + item.providerName = QsbContainerView.getSearchComponentName(this); + if (item.providerName == null) { + getModelWriter().deleteItemFromDatabase(item); + return null; + } + } + if (mIsSafeModeEnabled) { PendingAppWidgetHostView view = new PendingAppWidgetHostView(this, item, mIconCache, true); @@ -2161,7 +2185,8 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, pendingInfo.spanY = item.spanY; pendingInfo.minSpanX = item.minSpanX; pendingInfo.minSpanY = item.minSpanY; - Bundle options = WidgetHostViewLoader.getDefaultOptionsForWidget(this, pendingInfo); + Bundle options = WidgetHostViewLoader.getDefaultOptionsForWidget(this, + pendingInfo); boolean isDirectConfig = item.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_DIRECT_CONFIG); @@ -2508,8 +2533,8 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, if (focusedView instanceof BubbleTextView && focusedView.getTag() instanceof ItemInfo && mAccessibilityDelegate.performAction(focusedView, - (ItemInfo) focusedView.getTag(), - LauncherAccessibilityDelegate.DEEP_SHORTCUTS)) { + (ItemInfo) focusedView.getTag(), + LauncherAccessibilityDelegate.DEEP_SHORTCUTS)) { PopupContainerWithArrow.getOpen(this).requestFocus(); return true; } diff --git a/src/com/android/launcher3/LauncherAppWidgetInfo.java b/src/com/android/launcher3/LauncherAppWidgetInfo.java index 051846c87..b82430184 100644 --- a/src/com/android/launcher3/LauncherAppWidgetInfo.java +++ b/src/com/android/launcher3/LauncherAppWidgetInfo.java @@ -29,6 +29,9 @@ import com.android.launcher3.util.ContentWriter; */ public class LauncherAppWidgetInfo extends ItemInfo { + public static final int OPTION_SEARCH_WIDGET = 1; + + public static final int RESTORE_COMPLETED = 0; /** @@ -97,6 +100,11 @@ public class LauncherAppWidgetInfo extends ItemInfo { public Intent bindOptions; /** + * Widget options + */ + public int options; + + /** * Nonnull for pending widgets. We use this to get the icon and title for the widget. */ public PackageItemInfo pendingItemInfo; @@ -137,6 +145,7 @@ public class LauncherAppWidgetInfo extends ItemInfo { writer.put(LauncherSettings.Favorites.APPWIDGET_ID, appWidgetId) .put(LauncherSettings.Favorites.APPWIDGET_PROVIDER, providerName.flattenToString()) .put(LauncherSettings.Favorites.RESTORED, restoreStatus) + .put(LauncherSettings.Favorites.OPTIONS, options) .put(LauncherSettings.Favorites.INTENT, bindOptions); } @@ -164,4 +173,13 @@ public class LauncherAppWidgetInfo extends ItemInfo { public final boolean hasRestoreFlag(int flag) { return (restoreStatus & flag) == flag; } + + /** + * returns if widget options include an option or not + * @param option + * @return + */ + public final boolean hasOptionFlag(int option) { + return (options & option) != 0; + } } diff --git a/src/com/android/launcher3/model/LoaderTask.java b/src/com/android/launcher3/model/LoaderTask.java index 8845ab392..60e917d1d 100644 --- a/src/com/android/launcher3/model/LoaderTask.java +++ b/src/com/android/launcher3/model/LoaderTask.java @@ -66,6 +66,7 @@ import com.android.launcher3.icons.LauncherIcons; import com.android.launcher3.icons.cache.IconCacheUpdateHandler; import com.android.launcher3.logging.FileLog; import com.android.launcher3.provider.ImportDataTask; +import com.android.launcher3.qsb.QsbContainerView; import com.android.launcher3.shortcuts.DeepShortcutManager; import com.android.launcher3.shortcuts.ShortcutKey; import com.android.launcher3.util.ComponentKey; @@ -580,10 +581,19 @@ public class LoaderTask implements Runnable { int appWidgetId = c.getInt(appWidgetIdIndex); String savedProvider = c.getString(appWidgetProviderIndex); - - final ComponentName component = - ComponentName.unflattenFromString(savedProvider); - + final ComponentName component; + + boolean isSearchWidget = (c.getInt(optionsIndex) + & LauncherAppWidgetInfo.OPTION_SEARCH_WIDGET) != 0; + if (isSearchWidget) { + component = QsbContainerView.getSearchComponentName(context); + if (component == null) { + c.markDeleted("Discarding SearchWidget without packagename "); + continue; + } + } else { + component = ComponentName.unflattenFromString(savedProvider); + } final boolean isIdValid = !c.hasRestoreFlag( LauncherAppWidgetInfo.FLAG_ID_NOT_VALID); final boolean wasProviderReady = !c.hasRestoreFlag( @@ -593,9 +603,7 @@ public class LoaderTask implements Runnable { widgetProvidersMap = mAppWidgetManager.getAllProvidersMap(); } final AppWidgetProviderInfo provider = widgetProvidersMap.get( - new ComponentKey( - ComponentName.unflattenFromString(savedProvider), - c.user)); + new ComponentKey(component, c.user)); final boolean isProviderReady = isValidProvider(provider); if (!isSafeMode && !customWidget && @@ -659,6 +667,7 @@ public class LoaderTask implements Runnable { c.applyCommonProperties(appWidgetInfo); appWidgetInfo.spanX = c.getInt(spanXIndex); appWidgetInfo.spanY = c.getInt(spanYIndex); + appWidgetInfo.options = c.getInt(optionsIndex); appWidgetInfo.user = c.user; if (appWidgetInfo.spanX <= 0 || appWidgetInfo.spanY <= 0) { diff --git a/src/com/android/launcher3/qsb/QsbContainerView.java b/src/com/android/launcher3/qsb/QsbContainerView.java index 09c6c36dd..0eb428527 100644 --- a/src/com/android/launcher3/qsb/QsbContainerView.java +++ b/src/com/android/launcher3/qsb/QsbContainerView.java @@ -39,6 +39,7 @@ import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.launcher3.AppWidgetResizeFrame; @@ -60,6 +61,72 @@ public class QsbContainerView extends FrameLayout { public static final String SEARCH_PROVIDER_SETTINGS_KEY = "SEARCH_PROVIDER_PACKAGE_NAME"; + /** + * Returns the package name for user configured search provider or from searchManager + * @param context + * @return String + */ + @Nullable + public static String getSearchWidgetPackageName(@NonNull Context context) { + String providerPkg = Settings.Global.getString(context.getContentResolver(), + SEARCH_PROVIDER_SETTINGS_KEY); + if (providerPkg == null) { + SearchManager searchManager = context.getSystemService(SearchManager.class); + ComponentName componentName = searchManager.getGlobalSearchActivity(); + if (componentName != null) { + providerPkg = searchManager.getGlobalSearchActivity().getPackageName(); + } + } + return providerPkg; + } + + /** + * returns it's AppWidgetProviderInfo using package name from getSearchWidgetPackageName + * @param context + * @return AppWidgetProviderInfo + */ + @Nullable + public static AppWidgetProviderInfo getSearchWidgetProviderInfo(@NonNull Context context) { + String providerPkg = getSearchWidgetPackageName(context); + if (providerPkg == null) { + return null; + } + + AppWidgetProviderInfo defaultWidgetForSearchPackage = null; + AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context); + for (AppWidgetProviderInfo info : + appWidgetManager.getInstalledProvidersForPackage(providerPkg, null)) { + if (info.provider.getPackageName().equals(providerPkg) && info.configure == null) { + if ((info.widgetCategory + & AppWidgetProviderInfo.WIDGET_CATEGORY_SEARCHBOX) != 0) { + return info; + } else if (defaultWidgetForSearchPackage == null) { + defaultWidgetForSearchPackage = info; + } + } + } + return defaultWidgetForSearchPackage; + } + + /** + * returns componentName for searchWidget if package name is known. + */ + @Nullable + public static ComponentName getSearchComponentName(@NonNull Context context) { + AppWidgetProviderInfo providerInfo = + QsbContainerView.getSearchWidgetProviderInfo(context); + if (providerInfo != null) { + return providerInfo.provider; + } else { + String pkgName = QsbContainerView.getSearchWidgetPackageName(context); + if (pkgName != null) { + //we don't know the class name yet. we'll put the package name as placeholder + return new ComponentName(pkgName, pkgName); + } + return null; + } + } + public QsbContainerView(Context context) { super(context); } @@ -118,6 +185,7 @@ public class QsbContainerView extends FrameLayout { mWrapper = new FrameLayout(getContext()); // Only add the view when enabled if (isQsbEnabled()) { + mQsbWidgetHost.startListening(); mWrapper.addView(createQsb(mWrapper)); } return mWrapper; @@ -159,7 +227,8 @@ public class QsbContainerView extends FrameLayout { } if (isWidgetBound) { - mQsb = (QsbWidgetHostView) mQsbWidgetHost.createView(context, widgetId, mWidgetInfo); + mQsb = (QsbWidgetHostView) mQsbWidgetHost.createView(context, widgetId, + mWidgetInfo); mQsb.setId(R.id.qsb_widget); if (!isInPreviewMode()) { @@ -167,7 +236,6 @@ public class QsbContainerView extends FrameLayout { .getAppWidgetOptions(widgetId), opts)) { mQsb.updateAppWidgetOptions(opts); } - mQsbWidgetHost.startListening(); } return mQsb; } @@ -250,24 +318,6 @@ public class QsbContainerView extends FrameLayout { return v; } - /** - * returns the package name string from global settings or from system search service. - * - * @return String (package name) or null if neither exist - */ - @Nullable - protected String getSearchProviderPackageName() { - String providerPkg = Settings.Global.getString(getContext().getContentResolver(), - SEARCH_PROVIDER_SETTINGS_KEY); - if (providerPkg == null) { - SearchManager searchManager = getContext().getSystemService(SearchManager.class); - ComponentName componentName = searchManager.getGlobalSearchActivity(); - if (componentName != null) { - providerPkg = searchManager.getGlobalSearchActivity().getPackageName(); - } - } - return providerPkg; - } /** * Returns a widget with category {@link AppWidgetProviderInfo#WIDGET_CATEGORY_SEARCHBOX} @@ -276,23 +326,7 @@ public class QsbContainerView extends FrameLayout { * provided by the package. */ protected AppWidgetProviderInfo getSearchWidgetProvider() { - String providerPkg = getSearchProviderPackageName(); - if (providerPkg == null) { - return null; - } - AppWidgetProviderInfo defaultWidgetForSearchPackage = null; - AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(getContext()); - for (AppWidgetProviderInfo info : appWidgetManager.getInstalledProviders()) { - if (info.provider.getPackageName().equals(providerPkg) && info.configure == null) { - if ((info.widgetCategory - & AppWidgetProviderInfo.WIDGET_CATEGORY_SEARCHBOX) != 0) { - return info; - } else if (defaultWidgetForSearchPackage == null) { - defaultWidgetForSearchPackage = info; - } - } - } - return defaultWidgetForSearchPackage; + return getSearchWidgetProviderInfo(getContext()); } } @@ -362,4 +396,5 @@ public class QsbContainerView extends FrameLayout { } return true; } + } |