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

Commit 17137e8b authored by Sihua Ma's avatar Sihua Ma Committed by Android (Google) Code Review
Browse files

Merge "Created LauncherWidgetHolder as a wrapper for LauncherAppWidgetHost" into tm-qpr-dev

parents b3ab6f50 0593a0d3
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -77,6 +77,7 @@ import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.LauncherState;
import com.android.launcher3.LauncherWidgetHolder;
import com.android.launcher3.QuickstepAccessibilityDelegate;
import com.android.launcher3.QuickstepTransitionManager;
import com.android.launcher3.R;
@@ -123,7 +124,6 @@ import com.android.launcher3.util.PendingSplitSelectInfo;
import com.android.launcher3.util.RunnableList;
import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption;
import com.android.launcher3.util.TouchController;
import com.android.launcher3.widget.LauncherAppWidgetHost;
import com.android.quickstep.OverviewCommandHelper;
import com.android.quickstep.RecentsModel;
import com.android.quickstep.SystemUiProxy;
@@ -487,11 +487,11 @@ public class QuickstepLauncher extends Launcher {
        return new QuickstepAtomicAnimationFactory(this);
    }

    protected LauncherAppWidgetHost createAppWidgetHost() {
        LauncherAppWidgetHost appWidgetHost = super.createAppWidgetHost();
        ApiWrapper.setHostInteractionHandler(appWidgetHost,
                new QuickstepInteractionHandler(this));
        return appWidgetHost;
    @Override
    protected LauncherWidgetHolder createAppWidgetHolder() {
        LauncherWidgetHolder appWidgetHolder = super.createAppWidgetHolder();
        appWidgetHolder.setInteractionHandler(new QuickstepInteractionHandler(this));
        return appWidgetHolder;
    }

    @Override
+5 −5
Original line number Diff line number Diff line
@@ -249,7 +249,7 @@ public class AppWidgetResizeFrame extends AbstractFloatingView implements View.O
                                /* widgetHandler= */ null,
                                (ItemInfo) mWidgetView.getTag()));
                mLauncher
                    .getAppWidgetHost()
                        .getAppWidgetHolder()
                        .startConfigActivity(
                                mLauncher,
                                mWidgetView.getAppWidgetId(),
+26 −26
Original line number Diff line number Diff line
@@ -205,7 +205,6 @@ import com.android.launcher3.views.FloatingIconView;
import com.android.launcher3.views.FloatingSurfaceView;
import com.android.launcher3.views.OptionsPopupView;
import com.android.launcher3.views.ScrimView;
import com.android.launcher3.widget.LauncherAppWidgetHost;
import com.android.launcher3.widget.LauncherAppWidgetHostView;
import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
import com.android.launcher3.widget.PendingAddShortcutInfo;
@@ -317,7 +316,7 @@ public class Launcher extends StatefulActivity<LauncherState>
    DragLayer mDragLayer;

    private WidgetManagerHelper mAppWidgetManager;
    private LauncherAppWidgetHost mAppWidgetHost;
    private LauncherWidgetHolder mAppWidgetHolder;

    private final int[] mTmpAddItemCellCoordinates = new int[2];

@@ -482,8 +481,8 @@ public class Launcher extends StatefulActivity<LauncherState>
        mOnboardingPrefs = createOnboardingPrefs(mSharedPrefs);

        mAppWidgetManager = new WidgetManagerHelper(this);
        mAppWidgetHost = createAppWidgetHost();
        mAppWidgetHost.startListening();
        mAppWidgetHolder = createAppWidgetHolder();
        mAppWidgetHolder.startListening();

        setupViews();
        crossFadeWithPreviousAppearance();
@@ -963,7 +962,7 @@ public class Launcher extends StatefulActivity<LauncherState>
        AppWidgetHostView boundWidget = null;
        if (resultCode == RESULT_OK) {
            animationType = Workspace.COMPLETE_TWO_STAGE_WIDGET_DROP_ANIMATION;
            final AppWidgetHostView layout = mAppWidgetHost.createView(this, appWidgetId,
            final AppWidgetHostView layout = mAppWidgetHolder.createView(this, appWidgetId,
                    requestArgs.getWidgetHandler().getProviderInfo(this));
            boundWidget = layout;
            onCompleteRunnable = new Runnable() {
@@ -974,7 +973,7 @@ public class Launcher extends StatefulActivity<LauncherState>
                }
            };
        } else if (resultCode == RESULT_CANCELED) {
            mAppWidgetHost.deleteAppWidgetId(appWidgetId);
            mAppWidgetHolder.deleteAppWidgetId(appWidgetId);
            animationType = Workspace.CANCEL_TWO_STAGE_WIDGET_DROP_ANIMATION;
        }
        if (mDragLayer.getAnimatedView() != null) {
@@ -997,7 +996,7 @@ public class Launcher extends StatefulActivity<LauncherState>
        }
        hideKeyboard();
        logStopAndResume(false /* isResume */);
        mAppWidgetHost.setActivityStarted(false);
        mAppWidgetHolder.setActivityStarted(false);
        NotificationListener.removeNotificationsChangedListener(getPopupDataProvider());
    }

@@ -1010,7 +1009,7 @@ public class Launcher extends StatefulActivity<LauncherState>
            mOverlayManager.onActivityStarted(this);
        }

        mAppWidgetHost.setActivityStarted(true);
        mAppWidgetHolder.setActivityStarted(true);
        TraceHelper.INSTANCE.endSection(traceToken);
    }

@@ -1030,7 +1029,7 @@ public class Launcher extends StatefulActivity<LauncherState>
        NotificationListener.addNotificationsChangedListener(mPopupDataProvider);

        DiscoveryBounce.showForHomeIfNeeded(this);
        mAppWidgetHost.setActivityResumed(true);
        mAppWidgetHolder.setActivityResumed(true);
    }

    private void logStopAndResume(boolean isResume) {
@@ -1145,7 +1144,7 @@ public class Launcher extends StatefulActivity<LauncherState>
    @Override
    public void onStateSetEnd(LauncherState state) {
        super.onStateSetEnd(state);
        getAppWidgetHost().setStateIsNormal(state == LauncherState.NORMAL);
        getAppWidgetHolder().setStateIsNormal(state == LauncherState.NORMAL);
        getWorkspace().setClipChildren(!state.hasFlag(FLAG_MULTI_PAGE));

        finishAutoCancelActionMode();
@@ -1210,7 +1209,7 @@ public class Launcher extends StatefulActivity<LauncherState>
        if (!mDeferOverlayCallbacks) {
            mOverlayManager.onActivityPaused(this);
        }
        mAppWidgetHost.setActivityResumed(false);
        mAppWidgetHolder.setActivityResumed(false);
    }

    /**
@@ -1435,7 +1434,7 @@ public class Launcher extends StatefulActivity<LauncherState>

        if (hostView == null) {
            // Perform actual inflation because we're live
            hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);
            hostView = mAppWidgetHolder.createView(this, appWidgetId, appWidgetInfo);
        }

        LauncherAppWidgetInfo launcherInfo;
@@ -1566,12 +1565,12 @@ public class Launcher extends StatefulActivity<LauncherState>
        return mScrimView;
    }

    public LauncherAppWidgetHost getAppWidgetHost() {
        return mAppWidgetHost;
    public LauncherWidgetHolder getAppWidgetHolder() {
        return mAppWidgetHolder;
    }

    protected LauncherAppWidgetHost createAppWidgetHost() {
        return new LauncherAppWidgetHost(this,
    protected LauncherWidgetHolder createAppWidgetHolder() {
        return new LauncherWidgetHolder(this,
                appWidgetId -> getWorkspace().removeWidget(appWidgetId));
    }

@@ -1733,7 +1732,7 @@ public class Launcher extends StatefulActivity<LauncherState>
        mRotationHelper.destroy();

        try {
            mAppWidgetHost.stopListening();
            mAppWidgetHolder.stopListening();
        } catch (NullPointerException ex) {
            Log.w(TAG, "problem while stopping AppWidgetHost during Launcher destruction", ex);
        }
@@ -1908,7 +1907,7 @@ public class Launcher extends StatefulActivity<LauncherState>
                appWidgetId = CustomWidgetManager.INSTANCE.get(this).getWidgetIdForCustomProvider(
                        info.componentName);
            } else {
                appWidgetId = getAppWidgetHost().allocateAppWidgetId();
                appWidgetId = getAppWidgetHolder().allocateAppWidgetId();
            }
            Bundle options = info.bindOptions;

@@ -2022,7 +2021,7 @@ public class Launcher extends StatefulActivity<LauncherState>
            final LauncherAppWidgetInfo widgetInfo = (LauncherAppWidgetInfo) itemInfo;
            mWorkspace.removeWorkspaceItem(v);
            if (deleteFromDb) {
                getModelWriter().deleteWidgetInfo(widgetInfo, getAppWidgetHost(), reason);
                getModelWriter().deleteWidgetInfo(widgetInfo, getAppWidgetHolder(), reason);
            }
        } else {
            return false;
@@ -2280,7 +2279,7 @@ public class Launcher extends StatefulActivity<LauncherState>

        mWorkspace.clearDropTargets();
        mWorkspace.removeAllWorkspaceScreens();
        mAppWidgetHost.clearViews();
        mAppWidgetHolder.clearViews();

        if (mHotseat != null) {
            mHotseat.resetLayout(getDeviceProfile().isVerticalBarLayout());
@@ -2587,7 +2586,7 @@ public class Launcher extends StatefulActivity<LauncherState>
                if (item.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_ID_NOT_VALID)) {
                    if (!item.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_ID_ALLOCATED)) {
                        // Id has not been allocated yet. Allocate a new id.
                        item.appWidgetId = mAppWidgetHost.allocateAppWidgetId();
                        item.appWidgetId = mAppWidgetHolder.allocateAppWidgetId();
                        item.restoreStatus |= LauncherAppWidgetInfo.FLAG_ID_ALLOCATED;

                        // Also try to bind the widget. If the bind fails, the user will be shown
@@ -2649,18 +2648,18 @@ public class Launcher extends StatefulActivity<LauncherState>
                // Verify that we own the widget
                if (appWidgetInfo == null) {
                    FileLog.e(TAG, "Removing invalid widget: id=" + item.appWidgetId);
                    getModelWriter().deleteWidgetInfo(item, getAppWidgetHost(), removalReason);
                    getModelWriter().deleteWidgetInfo(item, getAppWidgetHolder(), removalReason);
                    return null;
                }

                item.minSpanX = appWidgetInfo.minSpanX;
                item.minSpanY = appWidgetInfo.minSpanY;
                view = mAppWidgetHost.createView(this, item.appWidgetId, appWidgetInfo);
                view = mAppWidgetHolder.createView(this, item.appWidgetId, appWidgetInfo);
            } else if (!item.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_ID_NOT_VALID)
                    && appWidgetInfo != null) {
                mAppWidgetHost.addPendingView(item.appWidgetId,
                mAppWidgetHolder.addPendingView(item.appWidgetId,
                        new PendingAppWidgetHostView(this, item, mIconCache, false));
                view = mAppWidgetHost.createView(this, item.appWidgetId, appWidgetInfo);
                view = mAppWidgetHolder.createView(this, item.appWidgetId, appWidgetInfo);
            } else {
                view = new PendingAppWidgetHostView(this, item, mIconCache, false);
            }
@@ -3018,7 +3017,8 @@ public class Launcher extends StatefulActivity<LauncherState>
        writer.println(prefix + "\tmPendingRequestArgs=" + mPendingRequestArgs
                + " mPendingActivityResult=" + mPendingActivityResult);
        writer.println(prefix + "\tmRotationHelper: " + mRotationHelper);
        writer.println(prefix + "\tmAppWidgetHost.isListening: " + mAppWidgetHost.isListening());
        writer.println(prefix + "\tmAppWidgetHolder.isListening: "
                + mAppWidgetHolder.isListening());

        // Extra logging for general debugging
        mDragLayer.dump(prefix, writer);
+187 −0
Original line number Diff line number Diff line
/**
 * Copyright (C) 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.launcher3;

import android.appwidget.AppWidgetHostView;
import android.appwidget.AppWidgetProviderInfo;
import android.content.Context;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.android.launcher3.uioverrides.ApiWrapper;
import com.android.launcher3.widget.LauncherAppWidgetHost;
import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
import com.android.launcher3.widget.PendingAppWidgetHostView;

import java.util.function.IntConsumer;

/**
 * A wrapper for LauncherAppWidgetHost. This class is created so the AppWidgetHost could run in
 * background.
 */
public class LauncherWidgetHolder {
    @NonNull
    private final LauncherAppWidgetHost mWidgetHost;

    public LauncherWidgetHolder(@NonNull Context context) {
        this(context, null);
    }

    public LauncherWidgetHolder(@NonNull Context context,
            @Nullable IntConsumer appWidgetRemovedCallback) {
        mWidgetHost = new LauncherAppWidgetHost(context, appWidgetRemovedCallback);
    }

    /**
     * Starts listening to the widget updates from the server side
     */
    public void startListening() {
        mWidgetHost.startListening();
    }

    /**
     * Set the STARTED state of the widget host
     * @param isStarted True if setting the host as started, false otherwise
     */
    public void setActivityStarted(boolean isStarted) {
        mWidgetHost.setActivityStarted(isStarted);
    }

    /**
     * Set the RESUMED state of the widget host
     * @param isResumed True if setting the host as resumed, false otherwise
     */
    public void setActivityResumed(boolean isResumed) {
        mWidgetHost.setActivityResumed(isResumed);
    }

    /**
     * Set the NORMAL state of the widget host
     * @param isNormal True if setting the host to be in normal state, false otherwise
     */
    public void setStateIsNormal(boolean isNormal) {
        mWidgetHost.setStateIsNormal(isNormal);
    }

    /**
     * Delete the specified app widget from the host
     * @param appWidgetId The ID of the app widget to be deleted
     */
    public void deleteAppWidgetId(int appWidgetId) {
        mWidgetHost.deleteAppWidgetId(appWidgetId);
    }

    /**
     * Add the pending view to the host for complete configuration in further steps
     * @param appWidgetId The ID of the specified app widget
     * @param view The {@link PendingAppWidgetHostView} of the app widget
     */
    public void addPendingView(int appWidgetId, @NonNull PendingAppWidgetHostView view) {
        mWidgetHost.addPendingView(appWidgetId, view);
    }

    /**
     * @return True if the host is listening to the widget updates, false otherwise
     */
    public boolean isListening() {
        return mWidgetHost.isListening();
    }

    /**
     * @return The allocated app widget id if allocation is successful, returns -1 otherwise
     */
    public int allocateAppWidgetId() {
        return mWidgetHost.allocateAppWidgetId();
    }

    /**
     * Add a listener that is triggered when the providers of the widgets are changed
     * @param listener The listener that notifies when the providers changed
     */
    public void addProviderChangeListener(
            @NonNull LauncherAppWidgetHost.ProviderChangedListener listener) {
        mWidgetHost.addProviderChangeListener(listener);
    }

    /**
     * Remove the specified listener from the host
     * @param listener The listener that is to be removed from the host
     */
    public void removeProviderChangeListener(
            LauncherAppWidgetHost.ProviderChangedListener listener) {
        mWidgetHost.removeProviderChangeListener(listener);
    }

    /**
     * Starts the configuration activity for the widget
     * @param activity The activity in which to start the configuration page
     * @param widgetId The ID of the widget
     * @param requestCode The request code
     */
    public void startConfigActivity(@NonNull BaseDraggingActivity activity, int widgetId,
            int requestCode) {
        mWidgetHost.startConfigActivity(activity, widgetId, requestCode);
    }

    /**
     * Starts the binding flow for the widget
     * @param activity The activity for which to bind the widget
     * @param appWidgetId The ID of the widget
     * @param info The {@link AppWidgetProviderInfo} of the widget
     * @param requestCode The request code
     */
    public void startBindFlow(@NonNull BaseActivity activity,
            int appWidgetId, @NonNull AppWidgetProviderInfo info, int requestCode) {
        mWidgetHost.startBindFlow(activity, appWidgetId, info, requestCode);
    }

    /**
     * Stop the host from listening to the widget updates
     */
    public void stopListening() {
        mWidgetHost.stopListening();
    }

    /**
     * Create a view for the specified app widget
     * @param context The activity context for which the view is created
     * @param appWidgetId The ID of the widget
     * @param info The {@link LauncherAppWidgetProviderInfo} of the widget
     * @return A view for the widget
     */
    @NonNull
    public AppWidgetHostView createView(@NonNull Context context, int appWidgetId,
            @NonNull LauncherAppWidgetProviderInfo info) {
        return mWidgetHost.createView(context, appWidgetId, info);
    }

    /**
     * Set the interaction handler for the widget host
     * @param handler The interaction handler
     */
    public void setInteractionHandler(
            @Nullable LauncherAppWidgetHost.LauncherWidgetInteractionHandler handler) {
        ApiWrapper.setHostInteractionHandler(mWidgetHost, handler);
    }

    /**
     * Clears all the views from the host
     */
    public void clearViews() {
        mWidgetHost.clearViews();
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -288,7 +288,7 @@ public class SecondaryDropTarget extends ButtonDropTarget implements OnAlarmList
            if (widgetId != INVALID_APPWIDGET_ID) {
                mLauncher.setWaitingForResult(
                        PendingRequestArgs.forWidgetInfo(widgetId, null, info));
                mLauncher.getAppWidgetHost().startConfigActivity(mLauncher, widgetId,
                mLauncher.getAppWidgetHolder().startConfigActivity(mLauncher, widgetId,
                        REQUEST_RECONFIGURE_APPWIDGET);
            }
            return null;
Loading