Merge "Allow 2-pane deep link to access unexported Activity"

This commit is contained in:
Arc Wang
2022-12-14 05:52:15 +00:00
committed by Android (Google) Code Review

View File

@@ -32,6 +32,8 @@ import android.content.pm.PackageManager;
import android.content.pm.UserInfo; import android.content.pm.UserInfo;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.os.Bundle; import android.os.Bundle;
import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle; import android.os.UserHandle;
import android.os.UserManager; import android.os.UserManager;
import android.text.TextUtils; import android.text.TextUtils;
@@ -466,20 +468,19 @@ public class SettingsHomepageActivity extends FragmentActivity implements
return; return;
} }
if (!TextUtils.equals(PasswordUtils.getCallingAppPackageName(getActivityToken()), ActivityInfo targetActivityInfo = null;
getPackageName())) { try {
ActivityInfo targetActivityInfo = null; targetActivityInfo = getPackageManager().getActivityInfo(targetComponentName,
try { /* flags= */ 0);
targetActivityInfo = getPackageManager().getActivityInfo(targetComponentName, } catch (PackageManager.NameNotFoundException e) {
/* flags= */ 0); Log.e(TAG, "Failed to get target ActivityInfo: " + e);
} catch (PackageManager.NameNotFoundException e) { finish();
Log.e(TAG, "Failed to get target ActivityInfo: " + e); return;
finish(); }
return;
}
if (!hasPrivilegedAccess(targetActivityInfo)) {
if (!targetActivityInfo.exported) { if (!targetActivityInfo.exported) {
Log.e(TAG, "Must not launch an unexported Actvity for deep link"); Log.e(TAG, "Target Activity is not exported");
finish(); finish();
return; return;
} }
@@ -529,6 +530,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 @VisibleForTesting
boolean isCallingAppPermitted(String permission) { boolean isCallingAppPermitted(String permission) {
return TextUtils.isEmpty(permission) || PasswordUtils.isCallingAppPermitted( return TextUtils.isEmpty(permission) || PasswordUtils.isCallingAppPermitted(