Merge "An intent forwarded from a chooser intent will be a chooser too." into lmp-mr1-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
8da8ab5cf2
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
newIntent.setContentUserHint(callingUserId);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -551,7 +551,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;
|
||||
}
|
||||
|
||||
@@ -970,7 +970,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;
|
||||
|
||||
Reference in New Issue
Block a user