Skip user consent popup when sending a personal intent into profile owner app

[This is a late temporary fix - in the next release we would probably want to work with Custom DPCs to prevent such communication after the work profile is enabeld]

Bug: 288965420
Test: manual BYOD provisioning using VMWare AirWatch
Change-Id: Ib3a0686b31a11ab7067abf22793d1e114b6135a7
This commit is contained in:
Liahav Eitan
2023-06-29 15:07:25 +00:00
parent a02a2d0dee
commit b1cafd1e3b

View File

@@ -56,6 +56,7 @@ import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
import android.telecom.TelecomManager;
import android.util.Log;
import android.util.Slog;
import android.view.View;
import android.widget.Button;
@@ -124,16 +125,19 @@ public class IntentForwarderActivity extends Activity {
String className = intentReceived.getComponent().getClassName();
final int targetUserId;
final String userMessage;
final UserInfo managedProfile;
if (className.equals(FORWARD_INTENT_TO_PARENT)) {
userMessage = getForwardToPersonalMessage();
targetUserId = getProfileParent();
managedProfile = null;
getMetricsLogger().write(
new LogMaker(MetricsEvent.ACTION_SWITCH_SHARE_PROFILE)
.setSubtype(MetricsEvent.PARENT_PROFILE));
} else if (className.equals(FORWARD_INTENT_TO_MANAGED_PROFILE)) {
userMessage = getForwardToWorkMessage();
targetUserId = getManagedProfile();
managedProfile = getManagedProfile();
targetUserId = managedProfile == null ? UserHandle.USER_NULL : managedProfile.id;
getMetricsLogger().write(
new LogMaker(MetricsEvent.ACTION_SWITCH_SHARE_PROFILE)
@@ -142,6 +146,7 @@ public class IntentForwarderActivity extends Activity {
Slog.wtf(TAG, IntentForwarderActivity.class.getName() + " cannot be called directly");
userMessage = null;
targetUserId = UserHandle.USER_NULL;
managedProfile = null;
}
if (targetUserId == UserHandle.USER_NULL) {
// This covers the case where there is no parent / managed profile.
@@ -185,27 +190,49 @@ public class IntentForwarderActivity extends Activity {
finish();
// When switching to the work profile, ask the user for consent before launching
} else if (className.equals(FORWARD_INTENT_TO_MANAGED_PROFILE)) {
maybeShowUserConsentMiniResolver(result, newIntent, targetUserId);
maybeShowUserConsentMiniResolver(result, newIntent, managedProfile);
}
}, getApplicationContext().getMainExecutor());
}
private void maybeShowUserConsentMiniResolver(
ResolveInfo target, Intent launchIntent, int targetUserId) {
ResolveInfo target, Intent launchIntent, UserInfo managedProfile) {
if (target == null || isIntentForwarderResolveInfo(target) || !isDeviceProvisioned()) {
finish();
return;
}
if (launchIntent.getBooleanExtra(EXTRA_SKIP_USER_CONFIRMATION, /* defaultValue= */ false)
&& getCallingPackage() != null
&& PERMISSION_GRANTED == getPackageManager().checkPermission(
INTERACT_ACROSS_USERS, getCallingPackage())) {
int targetUserId = managedProfile == null ? UserHandle.USER_NULL : managedProfile.id;
String callingPackage = getCallingPackage();
boolean privilegedCallerAskedToSkipUserConsent =
launchIntent.getBooleanExtra(
EXTRA_SKIP_USER_CONFIRMATION, /* defaultValue= */ false)
&& callingPackage != null
&& PERMISSION_GRANTED == getPackageManager().checkPermission(
INTERACT_ACROSS_USERS, callingPackage);
DevicePolicyManager devicePolicyManager =
getSystemService(DevicePolicyManager.class);
ComponentName profileOwnerName = devicePolicyManager.getProfileOwnerAsUser(targetUserId);
boolean intentToLaunchProfileOwner = profileOwnerName != null
&& profileOwnerName.getPackageName().equals(target.getComponentInfo().packageName);
if (privilegedCallerAskedToSkipUserConsent || intentToLaunchProfileOwner) {
Log.i("IntentForwarderActivity", String.format(
"Skipping user consent for redirection into the managed profile for intent [%s]"
+ ", privilegedCallerAskedToSkipUserConsent=[%s]"
+ ", intentToLaunchProfileOwner=[%s]",
launchIntent, privilegedCallerAskedToSkipUserConsent,
intentToLaunchProfileOwner));
startActivityAsCaller(launchIntent, targetUserId);
finish();
return;
}
Log.i("IntentForwarderActivity", String.format(
"Showing user consent for redirection into the managed profile for intent [%s] and "
+ " calling package [%s]",
launchIntent, callingPackage));
int layoutId = R.layout.miniresolver;
setContentView(layoutId);
@@ -245,8 +272,7 @@ public class IntentForwarderActivity extends Activity {
View telephonyInfo = findViewById(R.id.miniresolver_info_section);
DevicePolicyManager devicePolicyManager =
getSystemService(DevicePolicyManager.class);
// Additional information section is work telephony specific. Therefore, it is only shown
// for telephony related intents, when all sim subscriptions are in the work profile.
if ((isDialerIntent(launchIntent) || isTextMessageIntent(launchIntent))
@@ -507,20 +533,18 @@ public class IntentForwarderActivity extends Activity {
}
/**
* Returns the userId of the managed profile for this device or UserHandle.USER_NULL if there is
* no managed profile.
* 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.
* TODO: Remove the assumption that there is only one managed profile on the device.
*/
private int getManagedProfile() {
@Nullable private UserInfo getManagedProfile() {
List<UserInfo> relatedUsers = mInjector.getUserManager().getProfiles(UserHandle.myUserId());
for (UserInfo userInfo : relatedUsers) {
if (userInfo.isManagedProfile()) return userInfo.id;
if (userInfo.isManagedProfile()) return userInfo;
}
Slog.wtf(TAG, FORWARD_INTENT_TO_MANAGED_PROFILE
+ " has been called, but there is no managed profile");
return UserHandle.USER_NULL;
return null;
}
/**