Search in sources :

Example 1 with TransactionTooLargeException

use of android.os.TransactionTooLargeException in project platform_frameworks_base by android.

the class PendingIntentRecord method sendInner.

int sendInner(int code, Intent intent, String resolvedType, IIntentReceiver finishedReceiver, String requiredPermission, IBinder resultTo, String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle options, IActivityContainer container) {
    if (intent != null)
        intent.setDefusable(true);
    if (options != null)
        options.setDefusable(true);
    if (whitelistDuration > 0 && !canceled) {
        // Must call before acquiring the lock. It's possible the method return before sending
        // the intent due to some validations inside the lock, in which case the UID shouldn't
        // be whitelisted, but since the whitelist is temporary, that would be ok.
        owner.tempWhitelistAppForPowerSave(Binder.getCallingPid(), Binder.getCallingUid(), uid, whitelistDuration);
    }
    synchronized (owner) {
        final ActivityContainer activityContainer = (ActivityContainer) container;
        if (activityContainer != null && activityContainer.mParentActivity != null && activityContainer.mParentActivity.state != ActivityStack.ActivityState.RESUMED) {
            // Cannot start a child activity if the parent is not resumed.
            return ActivityManager.START_CANCELED;
        }
        if (!canceled) {
            sent = true;
            if ((key.flags & PendingIntent.FLAG_ONE_SHOT) != 0) {
                owner.cancelIntentSenderLocked(this, true);
                canceled = true;
            }
            Intent finalIntent = key.requestIntent != null ? new Intent(key.requestIntent) : new Intent();
            final boolean immutable = (key.flags & PendingIntent.FLAG_IMMUTABLE) != 0;
            if (!immutable) {
                if (intent != null) {
                    int changes = finalIntent.fillIn(intent, key.flags);
                    if ((changes & Intent.FILL_IN_DATA) == 0) {
                        resolvedType = key.requestResolvedType;
                    }
                } else {
                    resolvedType = key.requestResolvedType;
                }
                flagsMask &= ~Intent.IMMUTABLE_FLAGS;
                flagsValues &= flagsMask;
                finalIntent.setFlags((finalIntent.getFlags() & ~flagsMask) | flagsValues);
            } else {
                resolvedType = key.requestResolvedType;
            }
            final long origId = Binder.clearCallingIdentity();
            boolean sendFinish = finishedReceiver != null;
            int userId = key.userId;
            if (userId == UserHandle.USER_CURRENT) {
                userId = owner.mUserController.getCurrentOrTargetUserIdLocked();
            }
            int res = 0;
            switch(key.type) {
                case ActivityManager.INTENT_SENDER_ACTIVITY:
                    if (options == null) {
                        options = key.options;
                    } else if (key.options != null) {
                        Bundle opts = new Bundle(key.options);
                        opts.putAll(options);
                        options = opts;
                    }
                    try {
                        if (key.allIntents != null && key.allIntents.length > 1) {
                            Intent[] allIntents = new Intent[key.allIntents.length];
                            String[] allResolvedTypes = new String[key.allIntents.length];
                            System.arraycopy(key.allIntents, 0, allIntents, 0, key.allIntents.length);
                            if (key.allResolvedTypes != null) {
                                System.arraycopy(key.allResolvedTypes, 0, allResolvedTypes, 0, key.allResolvedTypes.length);
                            }
                            allIntents[allIntents.length - 1] = finalIntent;
                            allResolvedTypes[allResolvedTypes.length - 1] = resolvedType;
                            owner.startActivitiesInPackage(uid, key.packageName, allIntents, allResolvedTypes, resultTo, options, userId);
                        } else {
                            owner.startActivityInPackage(uid, key.packageName, finalIntent, resolvedType, resultTo, resultWho, requestCode, 0, options, userId, container, null);
                        }
                    } catch (RuntimeException e) {
                        Slog.w(TAG, "Unable to send startActivity intent", e);
                    }
                    break;
                case ActivityManager.INTENT_SENDER_ACTIVITY_RESULT:
                    if (key.activity.task.stack != null) {
                        key.activity.task.stack.sendActivityResultLocked(-1, key.activity, key.who, key.requestCode, code, finalIntent);
                    }
                    break;
                case ActivityManager.INTENT_SENDER_BROADCAST:
                    try {
                        // If a completion callback has been requested, require
                        // that the broadcast be delivered synchronously
                        int sent = owner.broadcastIntentInPackage(key.packageName, uid, finalIntent, resolvedType, finishedReceiver, code, null, null, requiredPermission, options, (finishedReceiver != null), false, userId);
                        if (sent == ActivityManager.BROADCAST_SUCCESS) {
                            sendFinish = false;
                        }
                    } catch (RuntimeException e) {
                        Slog.w(TAG, "Unable to send startActivity intent", e);
                    }
                    break;
                case ActivityManager.INTENT_SENDER_SERVICE:
                    try {
                        owner.startServiceInPackage(uid, finalIntent, resolvedType, key.packageName, userId);
                    } catch (RuntimeException e) {
                        Slog.w(TAG, "Unable to send startService intent", e);
                    } catch (TransactionTooLargeException e) {
                        res = ActivityManager.START_CANCELED;
                    }
                    break;
            }
            if (sendFinish && res != ActivityManager.START_CANCELED) {
                try {
                    finishedReceiver.performReceive(new Intent(finalIntent), 0, null, null, false, false, key.userId);
                } catch (RemoteException e) {
                }
            }
            Binder.restoreCallingIdentity(origId);
            return res;
        }
    }
    return ActivityManager.START_CANCELED;
}
Also used : Bundle(android.os.Bundle) ActivityContainer(com.android.server.am.ActivityStackSupervisor.ActivityContainer) IActivityContainer(android.app.IActivityContainer) Intent(android.content.Intent) PendingIntent(android.app.PendingIntent) TransactionTooLargeException(android.os.TransactionTooLargeException) RemoteException(android.os.RemoteException)

Example 2 with TransactionTooLargeException

use of android.os.TransactionTooLargeException in project platform_frameworks_base by android.

the class ApplicationThreadProxy method scheduleCreateService.

public final void scheduleCreateService(IBinder token, ServiceInfo info, CompatibilityInfo compatInfo, int processState) throws RemoteException {
    Parcel data = Parcel.obtain();
    data.writeInterfaceToken(IApplicationThread.descriptor);
    data.writeStrongBinder(token);
    info.writeToParcel(data, 0);
    compatInfo.writeToParcel(data, 0);
    data.writeInt(processState);
    try {
        mRemote.transact(SCHEDULE_CREATE_SERVICE_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
    } catch (TransactionTooLargeException e) {
        Log.e("CREATE_SERVICE", "Binder failure starting service; service=" + info);
        throw e;
    }
    data.recycle();
}
Also used : Parcel(android.os.Parcel) TransactionTooLargeException(android.os.TransactionTooLargeException)

Example 3 with TransactionTooLargeException

use of android.os.TransactionTooLargeException in project android_frameworks_base by DirtyUnicorns.

the class ApplicationThreadProxy method scheduleCreateService.

public final void scheduleCreateService(IBinder token, ServiceInfo info, CompatibilityInfo compatInfo, int processState) throws RemoteException {
    Parcel data = Parcel.obtain();
    data.writeInterfaceToken(IApplicationThread.descriptor);
    data.writeStrongBinder(token);
    info.writeToParcel(data, 0);
    compatInfo.writeToParcel(data, 0);
    data.writeInt(processState);
    try {
        mRemote.transact(SCHEDULE_CREATE_SERVICE_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
    } catch (TransactionTooLargeException e) {
        Log.e("CREATE_SERVICE", "Binder failure starting service; service=" + info);
        throw e;
    }
    data.recycle();
}
Also used : Parcel(android.os.Parcel) TransactionTooLargeException(android.os.TransactionTooLargeException)

Example 4 with TransactionTooLargeException

use of android.os.TransactionTooLargeException in project android_frameworks_base by DirtyUnicorns.

the class ActiveServices method bindServiceLocked.

int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service, String resolvedType, final IServiceConnection connection, int flags, String callingPackage, final int userId) throws TransactionTooLargeException {
    if (DEBUG_SERVICE)
        Slog.v(TAG_SERVICE, "bindService: " + service + " type=" + resolvedType + " conn=" + connection.asBinder() + " flags=0x" + Integer.toHexString(flags));
    final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
    if (callerApp == null) {
        throw new SecurityException("Unable to find app for caller " + caller + " (pid=" + Binder.getCallingPid() + ") when binding service " + service);
    }
    ActivityRecord activity = null;
    if (token != null) {
        activity = ActivityRecord.isInStackLocked(token);
        if (activity == null) {
            Slog.w(TAG, "Binding with unknown activity: " + token);
            return 0;
        }
    }
    int clientLabel = 0;
    PendingIntent clientIntent = null;
    final boolean isCallerSystem = callerApp.info.uid == Process.SYSTEM_UID;
    if (isCallerSystem) {
        // Hacky kind of thing -- allow system stuff to tell us
        // what they are, so we can report this elsewhere for
        // others to know why certain services are running.
        service.setDefusable(true);
        clientIntent = service.getParcelableExtra(Intent.EXTRA_CLIENT_INTENT);
        if (clientIntent != null) {
            clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
            if (clientLabel != 0) {
                // There are no useful extras in the intent, trash them.
                // System code calling with this stuff just needs to know
                // this will happen.
                service = service.cloneFilter();
            }
        }
    }
    if ((flags & Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
        mAm.enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, "BIND_TREAT_LIKE_ACTIVITY");
    }
    if ((flags & Context.BIND_ALLOW_WHITELIST_MANAGEMENT) != 0 && !isCallerSystem) {
        throw new SecurityException("Non-system caller " + caller + " (pid=" + Binder.getCallingPid() + ") set BIND_ALLOW_WHITELIST_MANAGEMENT when binding service " + service);
    }
    final boolean callerFg = callerApp.setSchedGroup != ProcessList.SCHED_GROUP_BACKGROUND;
    final boolean isBindExternal = (flags & Context.BIND_EXTERNAL_SERVICE) != 0;
    ServiceLookupResult res = retrieveServiceLocked(service, resolvedType, callingPackage, Binder.getCallingPid(), Binder.getCallingUid(), userId, true, callerFg, isBindExternal);
    if (res == null) {
        return 0;
    }
    if (res.record == null) {
        return -1;
    }
    ServiceRecord s = res.record;
    boolean permissionsReviewRequired = false;
    // when done to start the bound service's process to completing the binding.
    if (mAm.mPermissionReviewRequired || Build.PERMISSIONS_REVIEW_REQUIRED) {
        if (mAm.getPackageManagerInternalLocked().isPermissionsReviewRequired(s.packageName, s.userId)) {
            permissionsReviewRequired = true;
            // Show a permission review UI only for binding from a foreground app
            if (!callerFg) {
                Slog.w(TAG, "u" + s.userId + " Binding to a service in package" + s.packageName + " requires a permissions review");
                return 0;
            }
            final ServiceRecord serviceRecord = s;
            final Intent serviceIntent = service;
            RemoteCallback callback = new RemoteCallback(new RemoteCallback.OnResultListener() {

                @Override
                public void onResult(Bundle result) {
                    synchronized (mAm) {
                        final long identity = Binder.clearCallingIdentity();
                        try {
                            if (!mPendingServices.contains(serviceRecord)) {
                                return;
                            }
                            // otherwise we unbind because the user didn't approve.
                            if (!mAm.getPackageManagerInternalLocked().isPermissionsReviewRequired(serviceRecord.packageName, serviceRecord.userId)) {
                                try {
                                    bringUpServiceLocked(serviceRecord, serviceIntent.getFlags(), callerFg, false, false);
                                } catch (RemoteException e) {
                                /* ignore - local call */
                                }
                            } else {
                                unbindServiceLocked(connection);
                            }
                        } finally {
                            Binder.restoreCallingIdentity(identity);
                        }
                    }
                }
            });
            final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
            intent.putExtra(Intent.EXTRA_PACKAGE_NAME, s.packageName);
            intent.putExtra(Intent.EXTRA_REMOTE_CALLBACK, callback);
            if (DEBUG_PERMISSIONS_REVIEW) {
                Slog.i(TAG, "u" + s.userId + " Launching permission review for package " + s.packageName);
            }
            mAm.mHandler.post(new Runnable() {

                @Override
                public void run() {
                    mAm.mContext.startActivityAsUser(intent, new UserHandle(userId));
                }
            });
        }
    }
    final long origId = Binder.clearCallingIdentity();
    try {
        if (unscheduleServiceRestartLocked(s, callerApp.info.uid, false)) {
            if (DEBUG_SERVICE)
                Slog.v(TAG_SERVICE, "BIND SERVICE WHILE RESTART PENDING: " + s);
        }
        if ((flags & Context.BIND_AUTO_CREATE) != 0) {
            s.lastActivity = SystemClock.uptimeMillis();
            if (!s.hasAutoCreateConnections()) {
                // This is the first binding, let the tracker know.
                ServiceState stracker = s.getTracker();
                if (stracker != null) {
                    stracker.setBound(true, mAm.mProcessStats.getMemFactorLocked(), s.lastActivity);
                }
            }
        }
        mAm.startAssociationLocked(callerApp.uid, callerApp.processName, callerApp.curProcState, s.appInfo.uid, s.name, s.processName);
        AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
        ConnectionRecord c = new ConnectionRecord(b, activity, connection, flags, clientLabel, clientIntent);
        IBinder binder = connection.asBinder();
        ArrayList<ConnectionRecord> clist = s.connections.get(binder);
        if (clist == null) {
            clist = new ArrayList<ConnectionRecord>();
            s.connections.put(binder, clist);
        }
        clist.add(c);
        b.connections.add(c);
        if (activity != null) {
            if (activity.connections == null) {
                activity.connections = new HashSet<ConnectionRecord>();
            }
            activity.connections.add(c);
        }
        b.client.connections.add(c);
        if ((c.flags & Context.BIND_ABOVE_CLIENT) != 0) {
            b.client.hasAboveClient = true;
        }
        if ((c.flags & Context.BIND_ALLOW_WHITELIST_MANAGEMENT) != 0) {
            s.whitelistManager = true;
        }
        if (s.app != null) {
            updateServiceClientActivitiesLocked(s.app, c, true);
        }
        clist = mServiceConnections.get(binder);
        if (clist == null) {
            clist = new ArrayList<ConnectionRecord>();
            mServiceConnections.put(binder, clist);
        }
        clist.add(c);
        if ((flags & Context.BIND_AUTO_CREATE) != 0) {
            s.lastActivity = SystemClock.uptimeMillis();
            if (bringUpServiceLocked(s, service.getFlags(), callerFg, false, permissionsReviewRequired) != null) {
                return 0;
            }
        }
        if (s.app != null) {
            if ((flags & Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
                s.app.treatLikeActivity = true;
            }
            if (s.whitelistManager) {
                s.app.whitelistManager = true;
            }
            // This could have made the service more important.
            mAm.updateLruProcessLocked(s.app, s.app.hasClientActivities || s.app.treatLikeActivity, b.client);
            mAm.updateOomAdjLocked(s.app);
        }
        if (DEBUG_SERVICE)
            Slog.v(TAG_SERVICE, "Bind " + s + " with " + b + ": received=" + b.intent.received + " apps=" + b.intent.apps.size() + " doRebind=" + b.intent.doRebind);
        if (s.app != null && b.intent.received) {
            // publish the connection.
            try {
                c.conn.connected(s.name, b.intent.binder);
            } catch (Exception e) {
                Slog.w(TAG, "Failure sending service " + s.shortName + " to connection " + c.conn.asBinder() + " (in " + c.binding.client.processName + ")", e);
            }
            // rebound, then do so.
            if (b.intent.apps.size() == 1 && b.intent.doRebind) {
                requestServiceBindingLocked(s, b.intent, callerFg, true);
            }
        } else if (!b.intent.requested) {
            requestServiceBindingLocked(s, b.intent, callerFg, false);
        }
        getServiceMap(s.userId).ensureNotStartingBackground(s);
    } finally {
        Binder.restoreCallingIdentity(origId);
    }
    return 1;
}
Also used : ServiceState(com.android.internal.app.procstats.ServiceState) Bundle(android.os.Bundle) PendingIntent(android.app.PendingIntent) Intent(android.content.Intent) RemoteCallback(android.os.RemoteCallback) RemoteException(android.os.RemoteException) TransactionTooLargeException(android.os.TransactionTooLargeException) IOException(java.io.IOException) DeadObjectException(android.os.DeadObjectException) IBinder(android.os.IBinder) UserHandle(android.os.UserHandle) PendingIntent(android.app.PendingIntent) RemoteException(android.os.RemoteException)

Example 5 with TransactionTooLargeException

use of android.os.TransactionTooLargeException in project android_frameworks_base by DirtyUnicorns.

the class ActiveServices method sendServiceArgsLocked.

private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg, boolean oomAdjusted) throws TransactionTooLargeException {
    final int N = r.pendingStarts.size();
    if (N == 0) {
        return;
    }
    while (r.pendingStarts.size() > 0) {
        Exception caughtException = null;
        ServiceRecord.StartItem si = null;
        try {
            si = r.pendingStarts.remove(0);
            if (DEBUG_SERVICE)
                Slog.v(TAG_SERVICE, "Sending arguments to: " + r + " " + r.intent + " args=" + si.intent);
            if (si.intent == null && N > 1) {
                // onStartCommand(null) case.
                continue;
            }
            si.deliveredTime = SystemClock.uptimeMillis();
            r.deliveredStarts.add(si);
            si.deliveryCount++;
            if (si.neededGrants != null) {
                mAm.grantUriPermissionUncheckedFromIntentLocked(si.neededGrants, si.getUriPermissionsLocked());
            }
            bumpServiceExecutingLocked(r, execInFg, "start");
            if (!oomAdjusted) {
                oomAdjusted = true;
                mAm.updateOomAdjLocked(r.app);
            }
            int flags = 0;
            if (si.deliveryCount > 1) {
                flags |= Service.START_FLAG_RETRY;
            }
            if (si.doneExecutingCount > 0) {
                flags |= Service.START_FLAG_REDELIVERY;
            }
            r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
        } catch (TransactionTooLargeException e) {
            if (DEBUG_SERVICE)
                Slog.v(TAG_SERVICE, "Transaction too large: intent=" + si.intent);
            caughtException = e;
        } catch (RemoteException e) {
            // Remote process gone...  we'll let the normal cleanup take care of this.
            if (DEBUG_SERVICE)
                Slog.v(TAG_SERVICE, "Crashed while sending args: " + r);
            caughtException = e;
        } catch (Exception e) {
            Slog.w(TAG, "Unexpected exception", e);
            caughtException = e;
        }
        if (caughtException != null) {
            // Keep nesting count correct
            final boolean inDestroying = mDestroyingServices.contains(r);
            serviceDoneExecutingLocked(r, inDestroying, inDestroying);
            if (caughtException instanceof TransactionTooLargeException) {
                throw (TransactionTooLargeException) caughtException;
            }
            break;
        }
    }
}
Also used : TransactionTooLargeException(android.os.TransactionTooLargeException) RemoteException(android.os.RemoteException) RemoteException(android.os.RemoteException) TransactionTooLargeException(android.os.TransactionTooLargeException) IOException(java.io.IOException) DeadObjectException(android.os.DeadObjectException)

Aggregations

TransactionTooLargeException (android.os.TransactionTooLargeException)21 RemoteException (android.os.RemoteException)15 PendingIntent (android.app.PendingIntent)10 Intent (android.content.Intent)10 Bundle (android.os.Bundle)10 DeadObjectException (android.os.DeadObjectException)10 IOException (java.io.IOException)10 IActivityContainer (android.app.IActivityContainer)5 IBinder (android.os.IBinder)5 Parcel (android.os.Parcel)5 RemoteCallback (android.os.RemoteCallback)5 UserHandle (android.os.UserHandle)5 ServiceState (com.android.internal.app.procstats.ServiceState)5 ActivityContainer (com.android.server.am.ActivityStackSupervisor.ActivityContainer)5 SuppressLint (android.annotation.SuppressLint)1 NameNotFoundException (android.content.pm.PackageManager.NameNotFoundException)1 FileNotFoundException (java.io.FileNotFoundException)1 RuntimeException (java.lang.RuntimeException)1 StackOverflowError (java.lang.StackOverflowError)1 InvocationTargetException (java.lang.reflect.InvocationTargetException)1