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

Commit 0f61179f authored by Pinyao Ting's avatar Pinyao Ting
Browse files

Allow settings app to request pin appwidgets from other apps.

Bug: 301963214
Test: manually verified with a test app and a non-privileged permission
Change-Id: If8a5a28afe98e5c6dc57e063c2015fa8279f24b4
parent 0fa092ac
Loading
Loading
Loading
Loading
+27 −5
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import static android.provider.DeviceConfig.NAMESPACE_SYSTEMUI;

import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;

import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
@@ -1668,8 +1669,21 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
        synchronized (mLock) {
            ensureGroupStateLoadedLocked(userId);

            final String pkg = componentName.getPackageName();
            final ProviderId id;
            if (!mPackageManagerInternal.isSameApp(pkg, callingUid, userId)) {
                // If the calling process is requesting to pin appwidgets from another process,
                // check if the calling process has the necessary permission.
                if (!injectHasAccessWidgetsPermission(Binder.getCallingPid(), callingUid)) {
                    return false;
                }
                id = new ProviderId(mPackageManagerInternal.getPackageUid(
                        pkg, 0 /* flags */, userId), componentName);
            } else {
                id = new ProviderId(callingUid, componentName);
            }
            // Look for the widget associated with the caller.
            Provider provider = lookupProviderLocked(new ProviderId(callingUid, componentName));
            Provider provider = lookupProviderLocked(id);
            if (provider == null || provider.zombie) {
                return false;
            }
@@ -1683,6 +1697,14 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
                .requestPinAppWidget(callingPackage, info, extras, resultSender, userId);
    }

    /**
     * Returns true if the caller has the proper permission to access app widgets.
     */
    private boolean injectHasAccessWidgetsPermission(int callingPid, int callingUid) {
        return mContext.checkPermission(Manifest.permission.CLEAR_APP_USER_DATA,
                callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
    }

    @Override
    public ParceledListSlice<AppWidgetProviderInfo> getInstalledProvidersForProfile(int categoryFilter,
            int profileId, String packageName) {
@@ -4160,7 +4182,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
            return false;
        }

        @GuardedBy("mLock")
        @GuardedBy("AppWidgetServiceImpl.mLock")
        public AppWidgetProviderInfo getInfoLocked(Context context) {
            if (!mInfoParsed) {
                // parse
@@ -4188,18 +4210,18 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
         * be completely parsed and only contain placeHolder information like
         * {@link AppWidgetProviderInfo#providerInfo}
         */
        @GuardedBy("mLock")
        @GuardedBy("AppWidgetServiceImpl.mLock")
        public AppWidgetProviderInfo getPartialInfoLocked() {
            return info;
        }

        @GuardedBy("mLock")
        @GuardedBy("AppWidgetServiceImpl.mLock")
        public void setPartialInfoLocked(AppWidgetProviderInfo info) {
            this.info = info;
            mInfoParsed = false;
        }

        @GuardedBy("mLock")
        @GuardedBy("AppWidgetServiceImpl.mLock")
        public void setInfoLocked(AppWidgetProviderInfo info) {
            this.info = info;
            mInfoParsed = true;