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

Commit e8e2d9c6 authored by Arc Wang's avatar Arc Wang Committed by Android (Google) Code Review
Browse files

Merge "Allow 2-pane deep link to access unexported Activity" into tm-qpr-dev

parents 0b0d8ace f964b68f
Loading
Loading
Loading
Loading
+53 −12
Original line number Diff line number Diff line
@@ -32,6 +32,8 @@ import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
import android.content.res.Configuration;
import android.os.Bundle;
import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
import android.text.TextUtils;
@@ -448,8 +450,6 @@ public class SettingsHomepageActivity extends FragmentActivity implements
            return;
        }

        if (!TextUtils.equals(PasswordUtils.getCallingAppPackageName(getActivityToken()),
                getPackageName())) {
        ActivityInfo targetActivityInfo = null;
        try {
            targetActivityInfo = getPackageManager().getActivityInfo(targetComponentName,
@@ -460,8 +460,9 @@ public class SettingsHomepageActivity extends FragmentActivity implements
            return;
        }

        if (!hasPrivilegedAccess(targetActivityInfo)) {
            if (!targetActivityInfo.exported) {
                Log.e(TAG, "Must not launch an unexported Actvity for deep link");
                Log.e(TAG, "Target Activity is not exported");
                finish();
                return;
            }
@@ -514,6 +515,46 @@ public class SettingsHomepageActivity extends FragmentActivity implements
        }
    }

    // Check if calling app has privileged access to launch Activity of activityInfo.
    private boolean hasPrivilegedAccess(ActivityInfo activityInfo) {
        if (TextUtils.equals(PasswordUtils.getCallingAppPackageName(getActivityToken()),
                    getPackageName())) {
            return true;
        }

        int callingUid = -1;
        try {
            callingUid = ActivityManager.getService().getLaunchedFromUid(getActivityToken());
        } catch (RemoteException re) {
            Log.e(TAG, "Not able to get callingUid: " + re);
            return false;
        }

        int targetUid = -1;
        try {
            targetUid = getPackageManager().getApplicationInfo(activityInfo.packageName,
                    /* flags= */ 0).uid;
        } catch (PackageManager.NameNotFoundException nnfe) {
            Log.e(TAG, "Not able to get targetUid: " + nnfe);
            return false;
        }

        // When activityInfo.exported is false, Activity still can be launched if applications have
        // the same user ID.
        if (UserHandle.isSameApp(callingUid, targetUid)) {
            return true;
        }

        // When activityInfo.exported is false, Activity still can be launched if calling app has
        // root or system privilege.
        int callingAppId = UserHandle.getAppId(callingUid);
        if (callingAppId == Process.ROOT_UID || callingAppId == Process.SYSTEM_UID) {
            return true;
        }

        return false;
    }

    @VisibleForTesting
    boolean isCallingAppPermitted(String permission) {
        return TextUtils.isEmpty(permission) || PasswordUtils.isCallingAppPermitted(