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

Commit ff2e05e1 authored by Nicolas Prevot's avatar Nicolas Prevot Committed by Android (Google) Code Review
Browse files

Merge "Introduce forwarding intents across profiles."

parents 64ab917e 10fa67c7
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -4985,8 +4985,10 @@ package android.app.admin {
  public class DevicePolicyManager {
    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 clearForwardingIntentFilters(android.content.ComponentName);
    method public void clearPackagePersistentPreferredActivities(android.content.ComponentName, java.lang.String);
    method public void clearUserRestriction(android.content.ComponentName, java.lang.String);
    method public void forwardMatchingIntents(android.content.ComponentName, android.content.IntentFilter, int);
    method public java.util.List<android.content.ComponentName> getActiveAdmins();
    method public android.os.Bundle getApplicationRestrictions(android.content.ComponentName, java.lang.String);
    method public boolean getCameraDisabled(android.content.ComponentName);
@@ -5046,6 +5048,8 @@ package android.app.admin {
    field public static final java.lang.String EXTRA_DEVICE_ADMIN = "android.app.extra.DEVICE_ADMIN";
    field public static final java.lang.String EXTRA_PROVISIONING_DEFAULT_MANAGED_PROFILE_NAME = "defaultManagedProfileName";
    field public static final java.lang.String EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME = "deviceAdminPackageName";
    field public static int FLAG_TO_MANAGED_PROFILE;
    field public static int FLAG_TO_PRIMARY_USER;
    field public static final int KEYGUARD_DISABLE_FEATURES_ALL = 2147483647; // 0x7fffffff
    field public static final int KEYGUARD_DISABLE_FEATURES_NONE = 0; // 0x0
    field public static final int KEYGUARD_DISABLE_SECURE_CAMERA = 2; // 0x2
+43 −0
Original line number Diff line number Diff line
@@ -172,6 +172,16 @@ public class DevicePolicyManager {
    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
    public static final String ACTION_SET_NEW_PASSWORD
            = "android.app.action.SET_NEW_PASSWORD";
    /**
     * Flag for {@link #forwardMatchingIntents}: the intents will forwarded to the primary user.
     */
    public static int FLAG_TO_PRIMARY_USER = 0x0001;

    /**
     * Flag for {@link #forwardMatchingIntents}: the intents will be forwarded to the managed
     * profile.
     */
    public static int FLAG_TO_MANAGED_PROFILE = 0x0002;

    /**
     * Return true if the given administrator component is currently
@@ -1952,6 +1962,39 @@ public class DevicePolicyManager {
        }
    }

    /**
     * Called by a profile owner to forward intents sent from the managed profile to the owner, or
     * from the owner to the managed profile.
     * If an intent matches this intent filter, then activities belonging to the other user can
     * respond to this intent.
     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
     * @param filter if an intent matches this IntentFilter, then it can be forwarded.
     */
    public void forwardMatchingIntents(ComponentName admin, IntentFilter filter, int flags) {
        if (mService != null) {
            try {
                mService.forwardMatchingIntents(admin, filter, flags);
            } catch (RemoteException e) {
                Log.w(TAG, "Failed talking with device policy service", e);
            }
        }
    }

    /**
     * Called by a profile owner to remove all the forwarding intent filters from the current user
     * and from the owner.
     * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
     */
    public void clearForwardingIntentFilters(ComponentName admin) {
        if (mService != null) {
            try {
                mService.clearForwardingIntentFilters(admin);
            } catch (RemoteException e) {
                Log.w(TAG, "Failed talking with device policy service", e);
            }
        }
    }

    /**
     * Called by a profile or device owner to get the application restrictions for a given target
     * application running in the managed profile.
+2 −0
Original line number Diff line number Diff line
@@ -121,4 +121,6 @@ interface IDevicePolicyManager {
    Bundle getApplicationRestrictions(in ComponentName who, in String packageName);

    void setUserRestriction(in ComponentName who, in String key, boolean enable);
    void forwardMatchingIntents(in ComponentName admin, in IntentFilter filter, int flags);
    void clearForwardingIntentFilters(in ComponentName admin);
}
+6 −0
Original line number Diff line number Diff line
@@ -111,6 +111,8 @@ interface IPackageManager {

    ResolveInfo resolveIntent(in Intent intent, String resolvedType, int flags, int userId);

    boolean canForwardTo(in Intent intent, String resolvedType, int userIdFrom, int userIdDest);

    List<ResolveInfo> queryIntentActivities(in Intent intent, 
            String resolvedType, int flags, int userId);

@@ -245,6 +247,10 @@ interface IPackageManager {

    void clearPackagePersistentPreferredActivities(String packageName, int userId);

    void addForwardingIntentFilter(in IntentFilter filter, int userIdOrig, int userIdDest);

    void clearForwardingIntentFilters(int userIdOrig);

    /**
     * Report the set of 'Home' activity candidates, plus (if any) which of them
     * is the current "always use this one" setting.
+112 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2014 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.internal.app;

import android.app.Activity;
import android.app.AppGlobals;
import android.os.Bundle;
import android.content.Context;
import android.content.Intent;
import android.content.pm.IPackageManager;
import android.content.pm.UserInfo;
import android.os.UserHandle;
import android.os.UserManager;
import android.app.ActivityManagerNative;
import android.os.RemoteException;
import android.util.Slog;
import java.util.List;
import java.util.Set;




/*
 * This is used in conjunction with DevicePolicyManager.setForwardingIntents to enable intents to be
 * passed in and out of a managed profile.
 */

public class IntentForwarderActivity extends Activity  {

    public static String TAG = "IntentForwarderActivity";

    public static String FORWARD_INTENT_TO_USER_OWNER
            = "com.android.internal.app.ForwardIntentToUserOwner";

    public static String FORWARD_INTENT_TO_MANAGED_PROFILE
            = "com.android.internal.app.ForwardIntentToManagedProfile";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Intent intentReceived = getIntent();

        String className = intentReceived.getComponent().getClassName();
        final UserHandle userDest;

        if (className.equals(FORWARD_INTENT_TO_USER_OWNER)) {
            userDest = UserHandle.OWNER;
        } else if (className.equals(FORWARD_INTENT_TO_MANAGED_PROFILE)) {
            userDest = getManagedProfile();
        } else {
            Slog.wtf(TAG, IntentForwarderActivity.class.getName() + " cannot be called directly");
            userDest = null;
        }
        if (userDest == null) { // This covers the case where there is no managed profile.
            finish();
            return;
        }
        Intent newIntent = new Intent(intentReceived);
        newIntent.setComponent(null);
        newIntent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT
                |Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP);
        int callingUserId = getUserId();
        IPackageManager ipm = AppGlobals.getPackageManager();
        String resolvedType = newIntent.resolveTypeIfNeeded(getContentResolver());
        boolean canForward = false;
        try {
            canForward = ipm.canForwardTo(newIntent, resolvedType, callingUserId,
                    userDest.getIdentifier());
        } catch (RemoteException e) {
            Slog.e(TAG, "PackageManagerService is dead?");
        }
        if (canForward) {
            startActivityAsUser(newIntent, userDest);
        } else {
            Slog.wtf(TAG, "the intent: " + newIntent + "cannot be forwarded from user "
                    + callingUserId + " to user " + userDest.getIdentifier());
        }
        finish();
    }

    /**
     * Returns the managed profile for this device or null if there is no managed
     * profile.
     *
     * TODO: Remove the assumption that there is only one managed profile
     * on the device.
     */
    private UserHandle getManagedProfile() {
        UserManager userManager = (UserManager) getSystemService(Context.USER_SERVICE);
        List<UserInfo> relatedUsers = userManager.getProfiles(UserHandle.USER_OWNER);
        for (UserInfo userInfo : relatedUsers) {
            if (userInfo.isManagedProfile()) return new UserHandle(userInfo.id);
        }
        Slog.wtf(TAG, FORWARD_INTENT_TO_MANAGED_PROFILE
                + " has been called, but there is no managed profile");
        return null;
    }
}
Loading