Search in sources :

Example 51 with IIntentSender

use of android.content.IIntentSender in project android_frameworks_base by crdroidandroid.

the class ActivityStarter method startActivityMayWait.

final int startActivityMayWait(IApplicationThread caller, int callingUid, String callingPackage, Intent intent, String resolvedType, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, IActivityManager.WaitResult outResult, Configuration config, Bundle bOptions, boolean ignoreTargetSecurity, int userId, IActivityContainer iContainer, TaskRecord inTask) {
    // Refuse possible leaked file descriptors
    if (intent != null && intent.hasFileDescriptors()) {
        throw new IllegalArgumentException("File descriptors passed in Intent");
    }
    mSupervisor.mActivityMetricsLogger.notifyActivityLaunching();
    boolean componentSpecified = intent.getComponent() != null;
    // Save a copy in case ephemeral needs it
    final Intent ephemeralIntent = new Intent(intent);
    // Don't modify the client's object!
    intent = new Intent(intent);
    ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId);
    if (rInfo == null) {
        UserInfo userInfo = mSupervisor.getUserInfo(userId);
        if (userInfo != null && userInfo.isManagedProfile()) {
            // Special case for managed profiles, if attempting to launch non-cryto aware
            // app in a locked managed profile from an unlocked parent allow it to resolve
            // as user will be sent via confirm credentials to unlock the profile.
            UserManager userManager = UserManager.get(mService.mContext);
            boolean profileLockedAndParentUnlockingOrUnlocked = false;
            long token = Binder.clearCallingIdentity();
            try {
                UserInfo parent = userManager.getProfileParent(userId);
                profileLockedAndParentUnlockingOrUnlocked = (parent != null) && userManager.isUserUnlockingOrUnlocked(parent.id) && !userManager.isUserUnlockingOrUnlocked(userId);
            } finally {
                Binder.restoreCallingIdentity(token);
            }
            if (profileLockedAndParentUnlockingOrUnlocked) {
                rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId, PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
            }
        }
    }
    // Collect information about the target of the Intent.
    ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
    ActivityOptions options = ActivityOptions.fromBundle(bOptions);
    ActivityStackSupervisor.ActivityContainer container = (ActivityStackSupervisor.ActivityContainer) iContainer;
    synchronized (mService) {
        if (container != null && container.mParentActivity != null && container.mParentActivity.state != RESUMED) {
            // Cannot start a child activity if the parent is not resumed.
            return ActivityManager.START_CANCELED;
        }
        try {
            //TODO: This needs to be a flushed out API in the future.
            boolean isProtected = intent.getComponent() != null && AppGlobals.getPackageManager().isComponentProtected(callingPackage, callingUid, intent.getComponent(), userId) && (intent.getFlags() & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
            if (isProtected) {
                Message msg = mService.mHandler.obtainMessage(ActivityManagerService.POST_COMPONENT_PROTECTED_MSG);
                //Store start flags, userid
                intent.setFlags(startFlags);
                intent.putExtra("com.android.settings.PROTECTED_APPS_USER_ID", userId);
                msg.obj = intent;
                mService.mHandler.sendMessage(msg);
                return ActivityManager.START_PROTECTED_APP;
            }
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        final int realCallingPid = Binder.getCallingPid();
        final int realCallingUid = Binder.getCallingUid();
        int callingPid;
        if (callingUid >= 0) {
            callingPid = -1;
        } else if (caller == null) {
            callingPid = realCallingPid;
            callingUid = realCallingUid;
        } else {
            callingPid = callingUid = -1;
        }
        final ActivityStack stack;
        if (container == null || container.mStack.isOnHomeDisplay()) {
            stack = mSupervisor.mFocusedStack;
        } else {
            stack = container.mStack;
        }
        stack.mConfigWillChange = config != null && mService.mConfiguration.diff(config) != 0;
        if (DEBUG_CONFIGURATION)
            Slog.v(TAG_CONFIGURATION, "Starting activity when config will change = " + stack.mConfigWillChange);
        final long origId = Binder.clearCallingIdentity();
        if (aInfo != null && (aInfo.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0) {
            // have another, different heavy-weight process running.
            if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
                final ProcessRecord heavy = mService.mHeavyWeightProcess;
                if (heavy != null && (heavy.info.uid != aInfo.applicationInfo.uid || !heavy.processName.equals(aInfo.processName))) {
                    int appCallingUid = callingUid;
                    if (caller != null) {
                        ProcessRecord callerApp = mService.getRecordForAppLocked(caller);
                        if (callerApp != null) {
                            appCallingUid = callerApp.info.uid;
                        } else {
                            Slog.w(TAG, "Unable to find app for caller " + caller + " (pid=" + callingPid + ") when starting: " + intent.toString());
                            ActivityOptions.abort(options);
                            return ActivityManager.START_PERMISSION_DENIED;
                        }
                    }
                    IIntentSender target = mService.getIntentSenderLocked(ActivityManager.INTENT_SENDER_ACTIVITY, "android", appCallingUid, userId, null, null, 0, new Intent[] { intent }, new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT, null);
                    Intent newIntent = new Intent();
                    if (requestCode >= 0) {
                        // Caller is requesting a result.
                        newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);
                    }
                    newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT, new IntentSender(target));
                    if (heavy.activities.size() > 0) {
                        ActivityRecord hist = heavy.activities.get(0);
                        newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP, hist.packageName);
                        newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK, hist.task.taskId);
                    }
                    newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP, aInfo.packageName);
                    newIntent.setFlags(intent.getFlags());
                    newIntent.setClassName("android", HeavyWeightSwitcherActivity.class.getName());
                    intent = newIntent;
                    resolvedType = null;
                    caller = null;
                    callingUid = Binder.getCallingUid();
                    callingPid = Binder.getCallingPid();
                    componentSpecified = true;
                    rInfo = mSupervisor.resolveIntent(intent, null, /*resolvedType*/
                    userId);
                    aInfo = rInfo != null ? rInfo.activityInfo : null;
                    if (aInfo != null) {
                        aInfo = mService.getActivityInfoForUser(aInfo, userId);
                    }
                }
            }
        }
        final ActivityRecord[] outRecord = new ActivityRecord[1];
        int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity, componentSpecified, outRecord, container, inTask);
        Binder.restoreCallingIdentity(origId);
        if (stack.mConfigWillChange) {
            // If the caller also wants to switch to a new configuration,
            // do so now.  This allows a clean switch, as we are waiting
            // for the current activity to pause (so we will not destroy
            // it), and have not yet started the next activity.
            mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, "updateConfiguration()");
            stack.mConfigWillChange = false;
            if (DEBUG_CONFIGURATION)
                Slog.v(TAG_CONFIGURATION, "Updating to new configuration after starting activity.");
            mService.updateConfigurationLocked(config, null, false);
        }
        if (outResult != null) {
            outResult.result = res;
            if (res == ActivityManager.START_SUCCESS) {
                mSupervisor.mWaitingActivityLaunched.add(outResult);
                do {
                    try {
                        mService.wait();
                    } catch (InterruptedException e) {
                    }
                } while (outResult.result != START_TASK_TO_FRONT && !outResult.timeout && outResult.who == null);
                if (outResult.result == START_TASK_TO_FRONT) {
                    res = START_TASK_TO_FRONT;
                }
            }
            if (res == START_TASK_TO_FRONT) {
                ActivityRecord r = stack.topRunningActivityLocked();
                if (r.nowVisible && r.state == RESUMED) {
                    outResult.timeout = false;
                    outResult.who = new ComponentName(r.info.packageName, r.info.name);
                    outResult.totalTime = 0;
                    outResult.thisTime = 0;
                } else {
                    outResult.thisTime = SystemClock.uptimeMillis();
                    mSupervisor.mWaitingActivityVisible.add(outResult);
                    do {
                        try {
                            mService.wait();
                        } catch (InterruptedException e) {
                        }
                    } while (!outResult.timeout && outResult.who == null);
                }
            }
        }
        final ActivityRecord launchedActivity = mReusedActivity != null ? mReusedActivity : outRecord[0];
        mSupervisor.mActivityMetricsLogger.notifyActivityLaunched(res, launchedActivity);
        return res;
    }
}
Also used : ActivityInfo(android.content.pm.ActivityInfo) Message(android.os.Message) HeavyWeightSwitcherActivity(com.android.internal.app.HeavyWeightSwitcherActivity) IActivityContainer(android.app.IActivityContainer) PendingIntent(android.app.PendingIntent) Intent(android.content.Intent) UserInfo(android.content.pm.UserInfo) ResolveInfo(android.content.pm.ResolveInfo) IIntentSender(android.content.IIntentSender) UserManager(android.os.UserManager) ComponentName(android.content.ComponentName) RemoteException(android.os.RemoteException) IntentSender(android.content.IntentSender) IIntentSender(android.content.IIntentSender) ActivityOptions(android.app.ActivityOptions)

Example 52 with IIntentSender

use of android.content.IIntentSender in project android_frameworks_base by crdroidandroid.

the class ActivityStarter method buildEphemeralInstallerIntent.

/**
     * Builds and returns an intent to launch the ephemeral installer.
     */
private Intent buildEphemeralInstallerIntent(Intent launchIntent, Intent origIntent, String ephemeralPackage, String callingPackage, String resolvedType, int userId) {
    final Intent nonEphemeralIntent = new Intent(origIntent);
    nonEphemeralIntent.setFlags(nonEphemeralIntent.getFlags() | Intent.FLAG_IGNORE_EPHEMERAL);
    // Intent that is launched if the ephemeral package couldn't be installed
    // for any reason.
    final IIntentSender failureIntentTarget = mService.getIntentSenderLocked(ActivityManager.INTENT_SENDER_ACTIVITY, callingPackage, Binder.getCallingUid(), userId, null, /*token*/
    null, /*resultWho*/
    1, new Intent[] { nonEphemeralIntent }, new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE, null);
    final Intent ephemeralIntent;
    if (USE_DEFAULT_EPHEMERAL_LAUNCHER) {
        // Force the intent to be directed to the ephemeral package
        ephemeralIntent = new Intent(origIntent);
        ephemeralIntent.setPackage(ephemeralPackage);
    } else {
        // Success intent goes back to the installer
        ephemeralIntent = new Intent(launchIntent);
    }
    // Intent that is eventually launched if the ephemeral package was
    // installed successfully. This will actually be launched by a platform
    // broadcast receiver.
    final IIntentSender successIntentTarget = mService.getIntentSenderLocked(ActivityManager.INTENT_SENDER_ACTIVITY, callingPackage, Binder.getCallingUid(), userId, null, /*token*/
    null, /*resultWho*/
    0, new Intent[] { ephemeralIntent }, new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE, null);
    // Finally build the actual intent to launch the ephemeral installer
    int flags = launchIntent.getFlags();
    final Intent intent = new Intent();
    intent.setFlags(flags | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
    intent.putExtra(Intent.EXTRA_PACKAGE_NAME, ephemeralPackage);
    intent.putExtra(Intent.EXTRA_EPHEMERAL_FAILURE, new IntentSender(failureIntentTarget));
    intent.putExtra(Intent.EXTRA_EPHEMERAL_SUCCESS, new IntentSender(successIntentTarget));
    // TODO: Remove when the platform has fully implemented ephemeral apps
    intent.setData(origIntent.getData().buildUpon().clearQuery().build());
    return intent;
}
Also used : IIntentSender(android.content.IIntentSender) PendingIntent(android.app.PendingIntent) Intent(android.content.Intent) IntentSender(android.content.IntentSender) IIntentSender(android.content.IIntentSender)

Example 53 with IIntentSender

use of android.content.IIntentSender in project android_frameworks_base by crdroidandroid.

the class ActivityStartInterceptor method interceptQuietProfileIfNeeded.

private boolean interceptQuietProfileIfNeeded() {
    // Do not intercept if the user has not turned off the profile
    if (!mUserManager.isQuietModeEnabled(UserHandle.of(mUserId))) {
        return false;
    }
    IIntentSender target = mService.getIntentSenderLocked(INTENT_SENDER_ACTIVITY, mCallingPackage, mCallingUid, mUserId, null, null, 0, new Intent[] { mIntent }, new String[] { mResolvedType }, FLAG_CANCEL_CURRENT | FLAG_ONE_SHOT, null);
    mIntent = UnlaunchableAppActivity.createInQuietModeDialogIntent(mUserId, new IntentSender(target));
    mCallingPid = mRealCallingPid;
    mCallingUid = mRealCallingUid;
    mResolvedType = null;
    final UserInfo parent = mUserManager.getProfileParent(mUserId);
    mRInfo = mSupervisor.resolveIntent(mIntent, mResolvedType, parent.id);
    mAInfo = mSupervisor.resolveActivity(mIntent, mRInfo, mStartFlags, null);
    return true;
}
Also used : IIntentSender(android.content.IIntentSender) UserInfo(android.content.pm.UserInfo) IIntentSender(android.content.IIntentSender) IntentSender(android.content.IntentSender)

Example 54 with IIntentSender

use of android.content.IIntentSender in project android_frameworks_base by crdroidandroid.

the class ActivityStartInterceptor method interceptWithConfirmCredentialsIfNeeded.

/**
     * Creates an intent to intercept the current activity start with Confirm Credentials if needed.
     *
     * @return The intercepting intent if needed.
     */
private Intent interceptWithConfirmCredentialsIfNeeded(Intent intent, String resolvedType, ActivityInfo aInfo, String callingPackage, int userId) {
    if (!mService.mUserController.shouldConfirmCredentials(userId)) {
        return null;
    }
    // Allow direct boot aware activity to be displayed before the user is unlocked.
    if (aInfo.directBootAware && mService.mUserController.isUserRunningLocked(userId, ActivityManager.FLAG_AND_LOCKED)) {
        return null;
    }
    final IIntentSender target = mService.getIntentSenderLocked(INTENT_SENDER_ACTIVITY, callingPackage, Binder.getCallingUid(), userId, null, null, 0, new Intent[] { intent }, new String[] { resolvedType }, FLAG_CANCEL_CURRENT | FLAG_ONE_SHOT | FLAG_IMMUTABLE, null);
    final KeyguardManager km = (KeyguardManager) mService.mContext.getSystemService(KEYGUARD_SERVICE);
    final Intent newIntent = km.createConfirmDeviceCredentialIntent(null, null, userId);
    if (newIntent == null) {
        return null;
    }
    newIntent.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS | FLAG_ACTIVITY_TASK_ON_HOME);
    newIntent.putExtra(EXTRA_PACKAGE_NAME, aInfo.packageName);
    newIntent.putExtra(EXTRA_INTENT, new IntentSender(target));
    return newIntent;
}
Also used : IIntentSender(android.content.IIntentSender) Intent(android.content.Intent) IIntentSender(android.content.IIntentSender) IntentSender(android.content.IntentSender) KeyguardManager(android.app.KeyguardManager)

Example 55 with IIntentSender

use of android.content.IIntentSender in project platform_frameworks_base by android.

the class ActivityManagerProxy method getIntentSender.

public IIntentSender getIntentSender(int type, String packageName, IBinder token, String resultWho, int requestCode, Intent[] intents, String[] resolvedTypes, int flags, Bundle options, int userId) throws RemoteException {
    Parcel data = Parcel.obtain();
    Parcel reply = Parcel.obtain();
    data.writeInterfaceToken(IActivityManager.descriptor);
    data.writeInt(type);
    data.writeString(packageName);
    data.writeStrongBinder(token);
    data.writeString(resultWho);
    data.writeInt(requestCode);
    if (intents != null) {
        data.writeInt(1);
        data.writeTypedArray(intents, 0);
        data.writeStringArray(resolvedTypes);
    } else {
        data.writeInt(0);
    }
    data.writeInt(flags);
    if (options != null) {
        data.writeInt(1);
        options.writeToParcel(data, 0);
    } else {
        data.writeInt(0);
    }
    data.writeInt(userId);
    mRemote.transact(GET_INTENT_SENDER_TRANSACTION, data, reply, 0);
    reply.readException();
    IIntentSender res = IIntentSender.Stub.asInterface(reply.readStrongBinder());
    data.recycle();
    reply.recycle();
    return res;
}
Also used : IIntentSender(android.content.IIntentSender) Parcel(android.os.Parcel)

Aggregations

IIntentSender (android.content.IIntentSender)106 RemoteException (android.os.RemoteException)57 IntentSender (android.content.IntentSender)43 Intent (android.content.Intent)38 PendingIntent (android.app.PendingIntent)33 KeyguardManager (android.app.KeyguardManager)10 ResolveInfo (android.content.pm.ResolveInfo)10 UserInfo (android.content.pm.UserInfo)10 UserHandle (android.os.UserHandle)10 Parcel (android.os.Parcel)9 ComponentName (android.content.ComponentName)8 ActivityInfo (android.content.pm.ActivityInfo)8 HeavyWeightSwitcherActivity (com.android.internal.app.HeavyWeightSwitcherActivity)8 ActivityOptions (android.app.ActivityOptions)5 IActivityContainer (android.app.IActivityContainer)5 UserManager (android.os.UserManager)5 PendingActivityLaunch (com.android.server.am.ActivityStackSupervisor.PendingActivityLaunch)5 Point (android.graphics.Point)4 Message (android.os.Message)4