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

Commit 87a563e0 authored by Sunny Goyal's avatar Sunny Goyal
Browse files

AppWidgetManager: direct add widget support.

Test: Manual test and all the unit tests:
adb shell am instrument -e class com.android.server.pm.ShortcutManagerTest1 -w com.android.frameworks.servicestests
... to test9
adb shell am instrument -e class com.android.server.appwidget.AppWidgetServiceImplTest -w com.android.frameworks.servicestests

Bug 32404406
Change-Id: Icd6d4cbd25d9cdf4508da725d95d6401cc3a46a7
parent 564e802a
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -6778,6 +6778,7 @@ package android.appwidget {
    method public void notifyAppWidgetViewDataChanged(int, int);
    method public void partiallyUpdateAppWidget(int[], android.widget.RemoteViews);
    method public void partiallyUpdateAppWidget(int, android.widget.RemoteViews);
    method public boolean requestPinAppWidget(android.content.ComponentName, android.app.PendingIntent);
    method public void updateAppWidget(int[], android.widget.RemoteViews);
    method public void updateAppWidget(int, android.widget.RemoteViews);
    method public void updateAppWidget(android.content.ComponentName, android.widget.RemoteViews);
@@ -9761,11 +9762,13 @@ package android.content.pm {
    method public boolean accept(android.os.Bundle);
    method public boolean accept();
    method public int describeContents();
    method public android.appwidget.AppWidgetProviderInfo getAppWidgetProviderInfo();
    method public int getRequestType();
    method public android.content.pm.ShortcutInfo getShortcutInfo();
    method public boolean isValid();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator<android.content.pm.LauncherApps.PinItemRequest> CREATOR;
    field public static final int REQUEST_TYPE_APPWIDGET = 2; // 0x2
    field public static final int REQUEST_TYPE_SHORTCUT = 1; // 0x1
  }
+3 −0
Original line number Diff line number Diff line
@@ -7091,6 +7091,7 @@ package android.appwidget {
    method public void notifyAppWidgetViewDataChanged(int, int);
    method public void partiallyUpdateAppWidget(int[], android.widget.RemoteViews);
    method public void partiallyUpdateAppWidget(int, android.widget.RemoteViews);
    method public boolean requestPinAppWidget(android.content.ComponentName, android.app.PendingIntent);
    method public void updateAppWidget(int[], android.widget.RemoteViews);
    method public void updateAppWidget(int, android.widget.RemoteViews);
    method public void updateAppWidget(android.content.ComponentName, android.widget.RemoteViews);
@@ -10171,11 +10172,13 @@ package android.content.pm {
    method public boolean accept(android.os.Bundle);
    method public boolean accept();
    method public int describeContents();
    method public android.appwidget.AppWidgetProviderInfo getAppWidgetProviderInfo();
    method public int getRequestType();
    method public android.content.pm.ShortcutInfo getShortcutInfo();
    method public boolean isValid();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator<android.content.pm.LauncherApps.PinItemRequest> CREATOR;
    field public static final int REQUEST_TYPE_APPWIDGET = 2; // 0x2
    field public static final int REQUEST_TYPE_SHORTCUT = 1; // 0x1
  }
+3 −0
Original line number Diff line number Diff line
@@ -6800,6 +6800,7 @@ package android.appwidget {
    method public void notifyAppWidgetViewDataChanged(int, int);
    method public void partiallyUpdateAppWidget(int[], android.widget.RemoteViews);
    method public void partiallyUpdateAppWidget(int, android.widget.RemoteViews);
    method public boolean requestPinAppWidget(android.content.ComponentName, android.app.PendingIntent);
    method public void updateAppWidget(int[], android.widget.RemoteViews);
    method public void updateAppWidget(int, android.widget.RemoteViews);
    method public void updateAppWidget(android.content.ComponentName, android.widget.RemoteViews);
@@ -9789,11 +9790,13 @@ package android.content.pm {
    method public boolean accept(android.os.Bundle);
    method public boolean accept();
    method public int describeContents();
    method public android.appwidget.AppWidgetProviderInfo getAppWidgetProviderInfo();
    method public int getRequestType();
    method public android.content.pm.ShortcutInfo getShortcutInfo();
    method public boolean isValid();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator<android.content.pm.LauncherApps.PinItemRequest> CREATOR;
    field public static final int REQUEST_TYPE_APPWIDGET = 2; // 0x2
    field public static final int REQUEST_TYPE_SHORTCUT = 1; // 0x1
  }
+41 −0
Original line number Diff line number Diff line
@@ -16,11 +16,15 @@

package android.appwidget;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
import android.content.pm.ParceledListSlice;
import android.content.pm.ShortcutInfo;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Process;
@@ -1079,4 +1083,41 @@ public class AppWidgetManager {
        info.minResizeHeight = TypedValue.complexToDimensionPixelSize(info.minResizeHeight,
                mDisplayMetrics);
    }

    /**
     * Request to pin an app widget on the current launcher. It's up to the launcher to accept this
     * request (optionally showing a user confirmation). If the request is accepted, the caller will
     * get a confirmation with extra {@link #EXTRA_APPWIDGET_ID}.
     *
     * <p>When a request is denied by the user, the caller app will not get any response.
     *
     * <p>Only apps with a foreground activity or a foreground service can call it.  Otherwise
     * it'll throw {@link IllegalStateException}.
     *
     * <p>When an app calls this API when a previous request is still waiting for a response,
     * the previous request will be canceled.
     *
     * @param provider The {@link ComponentName} for the {@link
     *    android.content.BroadcastReceiver BroadcastReceiver} provider for your AppWidget.
     * @param successCallback If not null, this intent will be sent when the widget is created.
     *
     * @return {@code TRUE} if the launcher supports this feature. Note the API will return without
     *    waiting for the user to respond, so getting {@code TRUE} from this API does *not* mean
     *    the shortcut is pinned. {@code FALSE} if the launcher doesn't support this feature.
     *
     * @see android.content.pm.ShortcutManager#isRequestPinShortcutSupported()
     * @see android.content.pm.ShortcutManager#requestPinShortcut(ShortcutInfo, IntentSender)
     *
     * @throws IllegalStateException The caller doesn't have a foreground activity or a foreground
     * service or when the user is locked.
     */
    public boolean requestPinAppWidget(@NonNull ComponentName provider,
            @Nullable PendingIntent successCallback) {
        try {
            return mService.requestPinAppWidget(mPackageName, provider,
                successCallback == null ? null : successCallback.getIntentSender());
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }
}
+37 −5
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.annotation.Nullable;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.TestApi;
import android.appwidget.AppWidgetProviderInfo;
import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.Context;
@@ -1138,21 +1139,35 @@ public class LauncherApps {
        /** This is a request to pin shortcut. */
        public static final int REQUEST_TYPE_SHORTCUT = 1;

        /** This is a request to pin app widget. */
        public static final int REQUEST_TYPE_APPWIDGET = 2;

        @IntDef(value = {REQUEST_TYPE_SHORTCUT})
        @Retention(RetentionPolicy.SOURCE)
        public @interface RequestType {}

        private final int mRequestType;
        private final ShortcutInfo mShortcutInfo;
        private final AppWidgetProviderInfo mAppWidgetInfo;
        private final IPinItemRequest mInner;

        /**
         * @hide
         */
        public PinItemRequest(@RequestType int requestType, ShortcutInfo shortcutInfo,
                IPinItemRequest inner) {
            mRequestType = requestType;
        public PinItemRequest(ShortcutInfo shortcutInfo, IPinItemRequest inner) {
            mRequestType = REQUEST_TYPE_SHORTCUT;
            mShortcutInfo = shortcutInfo;
            mAppWidgetInfo = null;
            mInner = inner;
        }

        /**
         * @hide
         */
        public PinItemRequest(AppWidgetProviderInfo appWidgetInfo, IPinItemRequest inner) {
            mRequestType = REQUEST_TYPE_APPWIDGET;
            mShortcutInfo = null;
            mAppWidgetInfo = appWidgetInfo;
            mInner = inner;
        }

@@ -1174,6 +1189,15 @@ public class LauncherApps {
            return mShortcutInfo;
        }

        /**
         * {@link AppWidgetProviderInfo} sent by the requesting app.  Always non-null for a
         * {@link #REQUEST_TYPE_APPWIDGET} request.
         */
        @Nullable
        public AppWidgetProviderInfo getAppWidgetProviderInfo() {
            return mAppWidgetInfo;
        }

        /**
         * Return {@code TRUE} if a request is valid -- i.e. {@link #accept(Bundle)} has not been
         * called, and it has not been canceled.
@@ -1208,14 +1232,22 @@ public class LauncherApps {
            final ClassLoader cl = getClass().getClassLoader();

            mRequestType = source.readInt();
            mShortcutInfo = source.readParcelable(cl);
            mShortcutInfo = mRequestType == REQUEST_TYPE_SHORTCUT ?
                (ShortcutInfo) source.readParcelable(cl) : null;
            mAppWidgetInfo = mRequestType == REQUEST_TYPE_APPWIDGET ?
                (AppWidgetProviderInfo) source.readParcelable(cl) : null;
            mInner = IPinItemRequest.Stub.asInterface(source.readStrongBinder());
        }

        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeInt(mRequestType);
            if (mRequestType == REQUEST_TYPE_SHORTCUT) {
                dest.writeParcelable(mShortcutInfo, flags);
            }
            if (mRequestType == REQUEST_TYPE_APPWIDGET) {
                dest.writeParcelable(mAppWidgetInfo, flags);
            }
            dest.writeStrongBinder(mInner.asBinder());
        }

Loading