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

Commit 0e2b73f6 authored by Nicolas Prevot's avatar Nicolas Prevot
Browse files

An intent forwarded from a chooser intent will be a chooser too.

If a chooser intent is fired:
If the user picks "work" or "personal apps":
send a chooser intent to the other profile instead of sending a normal intent.

Also using a userId instead of a userHandle for the target user.

BUG:16514027

Change-Id: I2e45cd57ad72e9b7280e772b31fc10938642ba59
parent 5b820a8a
Loading
Loading
Loading
Loading
+11 −5
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.IntentSender;
import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.Log;
@@ -75,16 +76,21 @@ public class ChooserActivity extends ResolverActivity {
    }

    @Override
    public Intent getReplacementIntent(String packageName, Intent defIntent) {
    public Intent getReplacementIntent(ActivityInfo aInfo, Intent defIntent) {
        Intent result = defIntent;
        if (mReplacementExtras != null) {
            final Bundle replExtras = mReplacementExtras.getBundle(packageName);
            final Bundle replExtras = mReplacementExtras.getBundle(aInfo.packageName);
            if (replExtras != null) {
                final Intent result = new Intent(defIntent);
                result = new Intent(defIntent);
                result.putExtras(replExtras);
                return result;
            }
        }
        return defIntent;
        if (aInfo.name.equals(IntentForwarderActivity.FORWARD_INTENT_TO_USER_OWNER)
                || aInfo.name.equals(IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE)) {
            result = Intent.createChooser(result,
                    getIntent().getCharSequenceExtra(Intent.EXTRA_TITLE));
        }
        return result;
    }

    @Override
+51 −28
Original line number Diff line number Diff line
@@ -58,21 +58,22 @@ public class IntentForwarderActivity extends Activity {
        Intent intentReceived = getIntent();

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

        if (className.equals(FORWARD_INTENT_TO_USER_OWNER)) {
            userMessageId = com.android.internal.R.string.forward_intent_to_owner;
            userDest = UserHandle.OWNER;
            targetUserId = UserHandle.USER_OWNER;
        } else if (className.equals(FORWARD_INTENT_TO_MANAGED_PROFILE)) {
            userMessageId = com.android.internal.R.string.forward_intent_to_work;
            userDest = getManagedProfile();
            targetUserId = getManagedProfile();
        } else {
            Slog.wtf(TAG, IntentForwarderActivity.class.getName() + " cannot be called directly");
            userMessageId = -1;
            userDest = null;
            targetUserId = UserHandle.USER_NULL;
        }
        if (userDest == null) { // This covers the case where there is no managed profile.
        if (targetUserId == UserHandle.USER_NULL) {
            // This covers the case where there is no managed profile.
            finish();
            return;
        }
@@ -83,31 +84,24 @@ public class IntentForwarderActivity extends Activity {
        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;
        Intent selector = newIntent.getSelector();
        if (selector == null) {
            selector = newIntent;
        }
        try {
            canForward = ipm.canForwardTo(selector, resolvedType, callingUserId,
                    userDest.getIdentifier());
        } catch (RemoteException e) {
            Slog.e(TAG, "PackageManagerService is dead?");
        }
        if (canForward) {

        if (canForward(newIntent, targetUserId)) {
            if (newIntent.getAction().equals(Intent.ACTION_CHOOSER)) {
                Intent innerIntent = (Intent) newIntent.getParcelableExtra(Intent.EXTRA_INTENT);
                innerIntent.setContentUserHint(callingUserId);
            } else {
                newIntent.setContentUserHint(callingUserId);
            }

            final android.content.pm.ResolveInfo ri = getPackageManager().resolveActivityAsUser(
                        newIntent, MATCH_DEFAULT_ONLY, userDest.getIdentifier());
                        newIntent, MATCH_DEFAULT_ONLY, targetUserId);

            // Only show a disclosure if this is a normal (non-OS) app
            final boolean shouldShowDisclosure =
                    !UserHandle.isSameApp(ri.activityInfo.applicationInfo.uid, Process.SYSTEM_UID);

            try {
                startActivityAsCaller(newIntent, null, userDest.getIdentifier());
                startActivityAsCaller(newIntent, null, targetUserId);
            } catch (RuntimeException e) {
                int launchedFromUid = -1;
                String launchedFromPackage = "?";
@@ -129,26 +123,55 @@ public class IntentForwarderActivity extends Activity {
            }
        } else {
            Slog.wtf(TAG, "the intent: " + newIntent + "cannot be forwarded from user "
                    + callingUserId + " to user " + userDest.getIdentifier());
                    + callingUserId + " to user " + targetUserId);
        }
        finish();
    }

    boolean canForward(Intent intent, int targetUserId)  {
        IPackageManager ipm = AppGlobals.getPackageManager();
        if (intent.getAction().equals(Intent.ACTION_CHOOSER)) {
            // The EXTRA_INITIAL_INTENTS may not be allowed to be forwarded.
            if (intent.hasExtra(Intent.EXTRA_INITIAL_INTENTS)) {
                Slog.wtf(TAG, "An chooser intent with extra initial intents cannot be forwarded to"
                        + " a different user");
                return false;
            }
            if (intent.hasExtra(Intent.EXTRA_REPLACEMENT_EXTRAS)) {
                Slog.wtf(TAG, "A chooser intent with replacement extras cannot be forwarded to a"
                        + " different user");
                return false;
            }
            intent = (Intent) intent.getParcelableExtra(Intent.EXTRA_INTENT);
        }
        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
        if (intent.getSelector() != null) {
            intent = intent.getSelector();
        }
        try {
            return ipm.canForwardTo(intent, resolvedType, getUserId(),
                    targetUserId);
        } catch (RemoteException e) {
            Slog.e(TAG, "PackageManagerService is dead?");
            return false;
        }
    }

    /**
     * Returns the managed profile for this device or null if there is no managed
     * profile.
     * Returns the userId of the managed profile for this device or UserHandle.USER_NULL if there is
     * no managed profile.
     *
     * TODO: Remove the assumption that there is only one managed profile
     * on the device.
     */
    private UserHandle getManagedProfile() {
    private int 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);
            if (userInfo.isManagedProfile()) return userInfo.id;
        }
        Slog.wtf(TAG, FORWARD_INTENT_TO_MANAGED_PROFILE
                + " has been called, but there is no managed profile");
        return null;
        return UserHandle.USER_NULL;
    }
}
+2 −2
Original line number Diff line number Diff line
@@ -529,7 +529,7 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
    /**
     * Replace me in subclasses!
     */
    public Intent getReplacementIntent(String packageName, Intent defIntent) {
    public Intent getReplacementIntent(ActivityInfo aInfo, Intent defIntent) {
        return defIntent;
    }

@@ -943,7 +943,7 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
            DisplayResolveInfo dri = filtered ? getItem(position) : mList.get(position);

            Intent intent = new Intent(dri.origIntent != null ? dri.origIntent :
                    getReplacementIntent(dri.ri.activityInfo.packageName, mIntent));
                    getReplacementIntent(dri.ri.activityInfo, mIntent));
            intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT
                    |Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP);
            ActivityInfo ai = dri.ri.activityInfo;