Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ca37b8af authored by Samuel Fufa's avatar Samuel Fufa
Browse files

Add support for searchwidget in layout files.

Test: Manual
Bug:139703885
Change-Id: I86b36187d95bb5db59dbf6ae2e20373d23e55aa1
parent 6fe3eec9
Loading
Loading
Loading
Loading
+60 −25
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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;
    }
@@ -355,8 +363,8 @@ public class AutoInstallsLayout {
                    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);
                            .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                                    | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);

                    return addShortcut(info.loadLabel(mPackageManager).toString(),
                            intent, Favorites.ITEM_TYPE_APPLICATION);
@@ -396,8 +404,8 @@ public class AutoInstallsLayout {
            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);
                    .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);
        }
@@ -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));
    }
}
+13 −6
Original line number Diff line number Diff line
@@ -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,
+49 −24
Original line number Diff line number Diff line
@@ -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;
@@ -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);
        }
@@ -1125,7 +1137,6 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns,
     *
     * @param parent The group the shortcut belongs to.
     * @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);
        }
    }
@@ -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);
+18 −0
Original line number Diff line number Diff line
@@ -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;

    /**
@@ -96,6 +99,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.
     */
@@ -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;
    }
}
+16 −7
Original line number Diff line number Diff line
@@ -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) {
Loading