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

Commit 976e8bd2 authored by Svetoslav's avatar Svetoslav Committed by Svetoslav Ganov
Browse files

Allow adding widgets from user profiles.

The goal of this change is to enable support for appwidget from
user profiles to the user main profile. A user profile is a user
which is associated as a child of the main user profile. For example,
a user may have a personal (parent) and corporate (child) profile.
The device policy should be able to control whether adding a widget
from a child profile and given packages is allowed. This change
assumes that all packages from managed profiles are white listed.
Another change will add the device policy changes.

Change-Id: I267260b55d74c48b112a29979a9f59eef7a8194e
parent c79eabcd
Loading
Loading
Loading
Loading
+15 −3
Original line number Diff line number Diff line
@@ -5380,6 +5380,7 @@ package android.app.admin {
  public class DevicePolicyManager {
    method public void addCrossProfileIntentFilter(android.content.ComponentName, android.content.IntentFilter, int);
    method public boolean addCrossProfileWidgetProvider(android.content.ComponentName, java.lang.String);
    method public void addPersistentPreferredActivity(android.content.ComponentName, android.content.IntentFilter, android.content.ComponentName);
    method public void addUserRestriction(android.content.ComponentName, java.lang.String);
    method public void clearCrossProfileIntentFilters(android.content.ComponentName);
@@ -5396,6 +5397,7 @@ package android.app.admin {
    method public boolean getBlockUninstall(android.content.ComponentName, java.lang.String);
    method public boolean getCameraDisabled(android.content.ComponentName);
    method public boolean getCrossProfileCallerIdDisabled(android.content.ComponentName);
    method public java.util.List<java.lang.String> getCrossProfileWidgetProviders(android.content.ComponentName);
    method public int getCurrentFailedPasswordAttempts();
    method public int getKeyguardDisabledFeatures(android.content.ComponentName);
    method public int getMaximumFailedPasswordsForWipe(android.content.ComponentName);
@@ -5429,6 +5431,7 @@ package android.app.admin {
    method public boolean isProfileOwnerApp(java.lang.String);
    method public void lockNow();
    method public void removeActiveAdmin(android.content.ComponentName);
    method public boolean removeCrossProfileWidgetProvider(android.content.ComponentName, java.lang.String);
    method public boolean removeUser(android.content.ComponentName, android.os.UserHandle);
    method public boolean resetPassword(java.lang.String, int);
    method public void setAccountManagementDisabled(android.content.ComponentName, java.lang.String, boolean);
@@ -5734,6 +5737,7 @@ package android.appwidget {
    method protected android.appwidget.AppWidgetHostView onCreateView(android.content.Context, int, android.appwidget.AppWidgetProviderInfo);
    method protected void onProviderChanged(int, android.appwidget.AppWidgetProviderInfo);
    method protected void onProvidersChanged();
    method public final void startAppWidgetConfigureActivityForResult(android.app.Activity, android.content.Intent, int);
    method public void startListening();
    method public void stopListening();
  }
@@ -5756,10 +5760,12 @@ package android.appwidget {
  public class AppWidgetManager {
    method public boolean bindAppWidgetIdIfAllowed(int, android.content.ComponentName);
    method public boolean bindAppWidgetIdIfAllowed(int, android.content.ComponentName, android.os.Bundle);
    method public boolean bindAppWidgetIdIfAllowed(int, android.os.UserHandle, android.content.ComponentName, android.os.Bundle);
    method public int[] getAppWidgetIds(android.content.ComponentName);
    method public android.appwidget.AppWidgetProviderInfo getAppWidgetInfo(int);
    method public android.os.Bundle getAppWidgetOptions(int);
    method public java.util.List<android.appwidget.AppWidgetProviderInfo> getInstalledProviders();
    method public java.util.List<android.appwidget.AppWidgetProviderInfo> getInstalledProvidersForProfiles(android.os.UserHandle[]);
    method public static android.appwidget.AppWidgetManager getInstance(android.content.Context);
    method public void notifyAppWidgetViewDataChanged(int[], int);
    method public void notifyAppWidgetViewDataChanged(int, int);
@@ -5784,6 +5790,7 @@ package android.appwidget {
    field public static final java.lang.String EXTRA_APPWIDGET_OLD_IDS = "appWidgetOldIds";
    field public static final java.lang.String EXTRA_APPWIDGET_OPTIONS = "appWidgetOptions";
    field public static final java.lang.String EXTRA_APPWIDGET_PROVIDER = "appWidgetProvider";
    field public static final java.lang.String EXTRA_APPWIDGET_PROVIDER_PROFILE = "appWidgetProviderProfile";
    field public static final java.lang.String EXTRA_CUSTOM_EXTRAS = "customExtras";
    field public static final java.lang.String EXTRA_CUSTOM_INFO = "customInfo";
    field public static final java.lang.String EXTRA_HOST_ID = "hostId";
@@ -5812,6 +5819,10 @@ package android.appwidget {
    ctor public AppWidgetProviderInfo(android.os.Parcel);
    method public android.appwidget.AppWidgetProviderInfo clone();
    method public int describeContents();
    method public final android.os.UserHandle getProfile();
    method public final android.graphics.drawable.Drawable loadIcon(android.content.Context, int);
    method public final java.lang.String loadLabel(android.content.pm.PackageManager);
    method public final android.graphics.drawable.Drawable loadPreviewImage(android.content.Context, int);
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator CREATOR;
    field public static final int RESIZE_BOTH = 3; // 0x3
@@ -5823,15 +5834,15 @@ package android.appwidget {
    field public static final int WIDGET_CATEGORY_RECENTS = 4; // 0x4
    field public int autoAdvanceViewId;
    field public android.content.ComponentName configure;
    field public int icon;
    field public deprecated int icon;
    field public int initialKeyguardLayout;
    field public int initialLayout;
    field public java.lang.String label;
    field public deprecated java.lang.String label;
    field public int minHeight;
    field public int minResizeHeight;
    field public int minResizeWidth;
    field public int minWidth;
    field public int previewImage;
    field public deprecated int previewImage;
    field public android.content.ComponentName provider;
    field public int resizeMode;
    field public int updatePeriodMillis;
@@ -7277,6 +7288,7 @@ package android.content {
    field public static final java.lang.String ACCOUNT_SERVICE = "account";
    field public static final java.lang.String ACTIVITY_SERVICE = "activity";
    field public static final java.lang.String ALARM_SERVICE = "alarm";
    field public static final java.lang.String APPWIDGET_SERVICE = "appwidget";
    field public static final java.lang.String APP_OPS_SERVICE = "appops";
    field public static final java.lang.String AUDIO_SERVICE = "audio";
    field public static final java.lang.String BATTERY_SERVICE = "batterymanager";
+1 −1
Original line number Diff line number Diff line
@@ -150,7 +150,7 @@ public class AppWidget {
            IBinder binder = ServiceManager.getService(Context.APPWIDGET_SERVICE);
            IAppWidgetService appWidgetService = IAppWidgetService.Stub.asInterface(binder);
            try {
                appWidgetService.setBindAppWidgetPermission(mPackageName, mGranted, mUserId);
                appWidgetService.setBindAppWidgetPermission(mPackageName, mUserId, mGranted);
            } catch (RemoteException re) {
                re.printStackTrace();
            }
+27 −1
Original line number Diff line number Diff line
@@ -18,10 +18,12 @@ package android.app;

import android.app.usage.IUsageStatsManager;
import android.app.usage.UsageStatsManager;
import android.appwidget.AppWidgetManager;
import android.os.Build;

import android.service.persistentdata.IPersistentDataBlockService;
import android.service.persistentdata.PersistentDataBlockManager;
import com.android.internal.appwidget.IAppWidgetService;
import com.android.internal.policy.PolicyManager;
import com.android.internal.util.Preconditions;

@@ -148,7 +150,6 @@ import android.app.trust.TrustManager;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.app.IAppOpsService;
import com.android.internal.appwidget.IAppWidgetService.Stub;
import com.android.internal.os.IDropBoxManagerService;
import com.android.internal.telecomm.ITelecommService;

@@ -771,6 +772,12 @@ class ContextImpl extends Context {
                    return new MediaProjectionManager(ctx);
                }
        });

        registerService(APPWIDGET_SERVICE, new ServiceFetcher() {
            public Object createService(ContextImpl ctx) {
                IBinder b = ServiceManager.getService(APPWIDGET_SERVICE);
                return new AppWidgetManager(ctx, IAppWidgetService.Stub.asInterface(b));
            }});
    }

    static ContextImpl getImpl(Context context) {
@@ -2099,6 +2106,25 @@ class ContextImpl extends Context {
        }
    }

    @Override
    public Context createApplicationContext(ApplicationInfo application, int flags)
            throws NameNotFoundException {
        LoadedApk pi = mMainThread.getPackageInfo(application, mResources.getCompatibilityInfo(),
                flags | CONTEXT_REGISTER_PACKAGE);
        if (pi != null) {
            final boolean restricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
            ContextImpl c = new ContextImpl(this, mMainThread, pi, mActivityToken,
                    new UserHandle(UserHandle.getUserId(application.uid)), restricted,
                    mDisplay, mOverrideConfiguration);
            if (c.mResources != null) {
                return c;
            }
        }

        throw new PackageManager.NameNotFoundException(
                "Application package " + application.packageName + " not found");
    }

    @Override
    public Context createPackageContext(String packageName, int flags)
            throws NameNotFoundException {
+0 −22
Original line number Diff line number Diff line
@@ -1707,28 +1707,6 @@ public class Notification implements Parcelable
        }
    }

    /** {@hide} */
    public void setUser(UserHandle user) {
        if (user.getIdentifier() == UserHandle.USER_ALL) {
            user = UserHandle.OWNER;
        }
        if (tickerView != null) {
            tickerView.setUser(user);
        }
        if (contentView != null) {
            contentView.setUser(user);
        }
        if (bigContentView != null) {
            bigContentView.setUser(user);
        }
        if (headsUpContentView != null) {
            headsUpContentView.setUser(user);
        }
        if (publicVersion != null) {
            publicVersion.setUser(user);
        }
    }

    /**
     * @hide
     */
+83 −3
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SystemApi;
import android.app.Activity;
import android.app.admin.IDevicePolicyManager;
import android.content.AbstractRestrictionsProvider;
import android.content.ComponentName;
import android.content.Context;
@@ -28,8 +29,6 @@ import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.RestrictionsManager;
import android.media.AudioService;
import android.net.ProxyInfo;
import android.os.Bundle;
import android.os.Handler;
@@ -40,7 +39,6 @@ import android.os.ServiceManager;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
import android.service.trust.TrustAgentService;
import android.util.Log;

import com.android.org.conscrypt.TrustedCertificateStore;
@@ -55,6 +53,7 @@ import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;

@@ -3079,4 +3078,85 @@ public class DevicePolicyManager {
        }
        return false;
    }

    /**
     * Called by the profile owner to enable widget providers from a given package
     * to be available in the parent profile. As a result the user will be able to
     * add widgets from the white-listed package running under the profile to a widget
     * host which runs under the device owner, for example the home screen. Note that
     * a package may have zero or more provider components, where each component
     * provides a different widget type.
     * <p>
     * <strong>Note:</strong> By default no widget provider package is white-listed.
     * </p>
     *
     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
     * @param packageName The package from which widget providers are white-listed.
     * @return Whether the package was added.
     *
     * @see #removeCrossProfileWidgetProvider(android.content.ComponentName, String)
     * @see #getCrossProfileWidgetProviders(android.content.ComponentName)
     */
    public boolean addCrossProfileWidgetProvider(ComponentName admin, String packageName) {
        if (mService != null) {
            try {
                return mService.addCrossProfileWidgetProvider(admin, packageName);
            } catch (RemoteException re) {
                Log.w(TAG, "Error calling addCrossProfileWidgetProvider", re);
            }
        }
        return false;
    }

    /**
     * Called by the profile owner to disable widget providers from a given package
     * to be available in the parent profile. For this method to take effect the
     * package should have been added via {@link #addCrossProfileWidgetProvider(
     * android.content.ComponentName, String)}.
     * <p>
     * <strong>Note:</strong> By default no widget provider package is white-listed.
     * </p>
     *
     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
     * @param packageName The package from which widget providers are no longer
     *     white-listed.
     * @return Whether the package was removed.
     *
     * @see #addCrossProfileWidgetProvider(android.content.ComponentName, String)
     * @see #getCrossProfileWidgetProviders(android.content.ComponentName)
     */
    public boolean removeCrossProfileWidgetProvider(ComponentName admin, String packageName) {
        if (mService != null) {
            try {
                return mService.removeCrossProfileWidgetProvider(admin, packageName);
            } catch (RemoteException re) {
                Log.w(TAG, "Error calling removeCrossProfileWidgetProvider", re);
            }
        }
        return false;
    }

    /**
     * Called by the profile owner to query providers from which packages are
     * available in the parent profile.
     *
     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
     * @return The white-listed package list.
     *
     * @see #addCrossProfileWidgetProvider(android.content.ComponentName, String)
     * @see #removeCrossProfileWidgetProvider(android.content.ComponentName, String)
     */
    public List<String> getCrossProfileWidgetProviders(ComponentName admin) {
        if (mService != null) {
            try {
                List<String> providers = mService.getCrossProfileWidgetProviders(admin);
                if (providers != null) {
                    return providers;
                }
            } catch (RemoteException re) {
                Log.w(TAG, "Error calling getCrossProfileWidgetProviders", re);
            }
        }
        return Collections.emptyList();
    }
}
Loading