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

Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Settings/+/20704230

Change-Id: Ic7b667e5d12c125769feabc0ac13f79eaafab771
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Arc Wang
2022-12-15 05:16:14 +00:00
committed by Automerger Merge Worker

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;
@@ -448,20 +450,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;
} }
@@ -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 @VisibleForTesting
boolean isCallingAppPermitted(String permission) { boolean isCallingAppPermitted(String permission) {
return TextUtils.isEmpty(permission) || PasswordUtils.isCallingAppPermitted( return TextUtils.isEmpty(permission) || PasswordUtils.isCallingAppPermitted(