Search in sources :

Example 6 with RemoteCallback

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

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 7 with RemoteCallback

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

the class SyncManager method scheduleSync.

/**
     * @param minDelayMillis The sync can't land before this delay expires.
     */
private void scheduleSync(Account requestedAccount, int userId, int reason, String requestedAuthority, Bundle extras, int targetSyncState, final long minDelayMillis) {
    final boolean isLoggable = Log.isLoggable(TAG, Log.VERBOSE);
    if (extras == null) {
        extras = new Bundle();
    }
    if (isLoggable) {
        Log.d(TAG, "one-time sync for: " + requestedAccount + " " + extras.toString() + " " + requestedAuthority);
    }
    AccountAndUser[] accounts = null;
    if (requestedAccount != null) {
        if (userId != UserHandle.USER_ALL) {
            accounts = new AccountAndUser[] { new AccountAndUser(requestedAccount, userId) };
        } else {
            for (AccountAndUser runningAccount : mRunningAccounts) {
                if (requestedAccount.equals(runningAccount.account)) {
                    accounts = ArrayUtils.appendElement(AccountAndUser.class, accounts, runningAccount);
                }
            }
        }
    } else {
        accounts = mRunningAccounts;
    }
    if (ArrayUtils.isEmpty(accounts)) {
        if (isLoggable) {
            Slog.v(TAG, "scheduleSync: no accounts configured, dropping");
        }
        return;
    }
    final boolean uploadOnly = extras.getBoolean(ContentResolver.SYNC_EXTRAS_UPLOAD, false);
    final boolean manualSync = extras.getBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, false);
    if (manualSync) {
        extras.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_BACKOFF, true);
        extras.putBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, true);
    }
    final boolean ignoreSettings = extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, false);
    int source;
    if (uploadOnly) {
        source = SyncStorageEngine.SOURCE_LOCAL;
    } else if (manualSync) {
        source = SyncStorageEngine.SOURCE_USER;
    } else if (requestedAuthority == null) {
        source = SyncStorageEngine.SOURCE_POLL;
    } else {
        // This isn't strictly server, since arbitrary callers can (and do) request
        // a non-forced two-way sync on a specific url.
        source = SyncStorageEngine.SOURCE_SERVER;
    }
    for (AccountAndUser account : accounts) {
        // If userId is specified, do not sync accounts of other users
        if (userId >= UserHandle.USER_SYSTEM && account.userId >= UserHandle.USER_SYSTEM && userId != account.userId) {
            continue;
        }
        // Compile a list of authorities that have sync adapters.
        // For each authority sync each account that matches a sync adapter.
        final HashSet<String> syncableAuthorities = new HashSet<String>();
        for (RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapter : mSyncAdapters.getAllServices(account.userId)) {
            syncableAuthorities.add(syncAdapter.type.authority);
        }
        // syncable.
        if (requestedAuthority != null) {
            final boolean hasSyncAdapter = syncableAuthorities.contains(requestedAuthority);
            syncableAuthorities.clear();
            if (hasSyncAdapter)
                syncableAuthorities.add(requestedAuthority);
        }
        for (String authority : syncableAuthorities) {
            int isSyncable = computeSyncable(account.account, account.userId, authority);
            if (isSyncable == AuthorityInfo.NOT_SYNCABLE) {
                continue;
            }
            final RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo = mSyncAdapters.getServiceInfo(SyncAdapterType.newKey(authority, account.account.type), account.userId);
            if (syncAdapterInfo == null) {
                continue;
            }
            final int owningUid = syncAdapterInfo.uid;
            if (isSyncable == AuthorityInfo.SYNCABLE_NO_ACCOUNT_ACCESS) {
                if (isLoggable) {
                    Slog.v(TAG, "    Not scheduling sync operation: " + "isSyncable == SYNCABLE_NO_ACCOUNT_ACCESS");
                }
                Bundle finalExtras = new Bundle(extras);
                String packageName = syncAdapterInfo.componentName.getPackageName();
                // If the app did not run and has no account access, done
                if (!mPackageManagerInternal.wasPackageEverLaunched(packageName, userId)) {
                    continue;
                }
                mAccountManagerInternal.requestAccountAccess(account.account, packageName, userId, new RemoteCallback((Bundle result) -> {
                    if (result != null && result.getBoolean(AccountManager.KEY_BOOLEAN_RESULT)) {
                        scheduleSync(account.account, userId, reason, authority, finalExtras, targetSyncState, minDelayMillis);
                    }
                }));
                continue;
            }
            final boolean allowParallelSyncs = syncAdapterInfo.type.allowParallelSyncs();
            final boolean isAlwaysSyncable = syncAdapterInfo.type.isAlwaysSyncable();
            if (isSyncable < 0 && isAlwaysSyncable) {
                mSyncStorageEngine.setIsSyncable(account.account, account.userId, authority, AuthorityInfo.SYNCABLE);
                isSyncable = AuthorityInfo.SYNCABLE;
            }
            if (targetSyncState != AuthorityInfo.UNDEFINED && targetSyncState != isSyncable) {
                continue;
            }
            if (!syncAdapterInfo.type.supportsUploading() && uploadOnly) {
                continue;
            }
            boolean syncAllowed = // Always allow if the isSyncable state is unknown.
            (isSyncable < 0) || ignoreSettings || (mSyncStorageEngine.getMasterSyncAutomatically(account.userId) && mSyncStorageEngine.getSyncAutomatically(account.account, account.userId, authority));
            if (!syncAllowed) {
                if (isLoggable) {
                    Log.d(TAG, "scheduleSync: sync of " + account + ", " + authority + " is not allowed, dropping request");
                }
                continue;
            }
            SyncStorageEngine.EndPoint info = new SyncStorageEngine.EndPoint(account.account, authority, account.userId);
            long delayUntil = mSyncStorageEngine.getDelayUntilTime(info);
            final String owningPackage = syncAdapterInfo.componentName.getPackageName();
            if (isSyncable == AuthorityInfo.NOT_INITIALIZED) {
                // Initialisation sync.
                Bundle newExtras = new Bundle();
                newExtras.putBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE, true);
                if (isLoggable) {
                    Slog.v(TAG, "schedule initialisation Sync:" + ", delay until " + delayUntil + ", run by " + 0 + ", flexMillis " + 0 + ", source " + source + ", account " + account + ", authority " + authority + ", extras " + newExtras);
                }
                postScheduleSyncMessage(new SyncOperation(account.account, account.userId, owningUid, owningPackage, reason, source, authority, newExtras, allowParallelSyncs), minDelayMillis);
            } else if (targetSyncState == AuthorityInfo.UNDEFINED || targetSyncState == isSyncable) {
                if (isLoggable) {
                    Slog.v(TAG, "scheduleSync:" + " delay until " + delayUntil + ", source " + source + ", account " + account + ", authority " + authority + ", extras " + extras);
                }
                postScheduleSyncMessage(new SyncOperation(account.account, account.userId, owningUid, owningPackage, reason, source, authority, extras, allowParallelSyncs), minDelayMillis);
            }
        }
    }
}
Also used : Bundle(android.os.Bundle) SyncAdapterType(android.content.SyncAdapterType) EndPoint(com.android.server.content.SyncStorageEngine.EndPoint) RemoteCallback(android.os.RemoteCallback) EndPoint(com.android.server.content.SyncStorageEngine.EndPoint) EndPoint(com.android.server.content.SyncStorageEngine.EndPoint) AccountAndUser(android.accounts.AccountAndUser) RegisteredServicesCache(android.content.pm.RegisteredServicesCache) HashSet(java.util.HashSet)

Example 8 with RemoteCallback

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

the class NetworkScoreServiceTest method setUp.

@Before
public void setUp() throws Exception {
    MockitoAnnotations.initMocks(this);
    when(mNetworkScoreCache.asBinder()).thenReturn(mIBinder);
    when(mNetworkScoreCache2.asBinder()).thenReturn(mIBinder2);
    mContentResolver = InstrumentationRegistry.getContext().getContentResolver();
    when(mContext.getContentResolver()).thenReturn(mContentResolver);
    when(mContext.getResources()).thenReturn(mResources);
    mHandlerThread = new HandlerThread("NetworkScoreServiceTest");
    mHandlerThread.start();
    mNetworkScoreService = new NetworkScoreService(mContext, mNetworkScorerAppManager, mHandlerThread.getLooper());
    WifiConfiguration configuration = new WifiConfiguration();
    configuration.SSID = "NetworkScoreServiceTest_SSID";
    configuration.BSSID = "NetworkScoreServiceTest_BSSID";
    mRecommendationRequest = new RecommendationRequest.Builder().setDefaultWifiConfig(configuration).build();
    mOnResultListener = new OnResultListener();
    mRemoteCallback = new RemoteCallback(mOnResultListener);
    Settings.Global.putLong(mContentResolver, Settings.Global.NETWORK_RECOMMENDATION_REQUEST_TIMEOUT_MS, -1L);
    mNetworkScoreService.refreshRecommendationRequestTimeoutMs();
}
Also used : HandlerThread(android.os.HandlerThread) WifiConfiguration(android.net.wifi.WifiConfiguration) RecommendationRequest(android.net.RecommendationRequest) RemoteCallback(android.os.RemoteCallback) IRemoteCallback(android.os.IRemoteCallback) Before(org.junit.Before)

Example 9 with RemoteCallback

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

the class NetworkScoreManager method requestRecommendation.

/**
     * Request a recommendation for which network to connect to.
     *
     * <p>The callback will be run on the thread associated with provided {@link Handler}.
     *
     * @param request a {@link RecommendationRequest} instance containing additional
     *                request details
     * @param handler a {@link Handler} instance representing the thread to complete the future on.
     *                If null the responding binder thread will be used.
     * @return a {@link CompletableFuture} instance that will eventually receive the
     *         {@link RecommendationResult}.
     * @throws SecurityException
     * @hide
     */
public CompletableFuture<RecommendationResult> requestRecommendation(@NonNull final RecommendationRequest request, @Nullable final Handler handler) {
    Preconditions.checkNotNull(request, "RecommendationRequest cannot be null.");
    final CompletableFuture<RecommendationResult> futureResult = new CompletableFuture<>();
    RemoteCallback remoteCallback = new RemoteCallback(new RemoteCallback.OnResultListener() {

        @Override
        public void onResult(Bundle data) {
            RecommendationResult result = data.getParcelable(EXTRA_RECOMMENDATION_RESULT);
            futureResult.complete(result);
        }
    }, handler);
    try {
        mService.requestRecommendationAsync(request, remoteCallback);
    } catch (RemoteException e) {
        throw e.rethrowFromSystemServer();
    }
    return futureResult;
}
Also used : CompletableFuture(java.util.concurrent.CompletableFuture) Bundle(android.os.Bundle) RemoteException(android.os.RemoteException) RemoteCallback(android.os.RemoteCallback)

Example 10 with RemoteCallback

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

the class RuntimePermissionPresenterService method onBind.

@Override
public final IBinder onBind(Intent intent) {
    return new IRuntimePermissionPresenter.Stub() {

        @Override
        public void getAppPermissions(String packageName, RemoteCallback callback) {
            SomeArgs args = SomeArgs.obtain();
            args.arg1 = packageName;
            args.arg2 = callback;
            mHandler.obtainMessage(MyHandler.MSG_GET_APP_PERMISSIONS, args).sendToTarget();
        }

        @Override
        public void getAppsUsingPermissions(boolean system, RemoteCallback callback) {
            mHandler.obtainMessage(MyHandler.MSG_GET_APPS_USING_PERMISSIONS, system ? 1 : 0, 0, callback).sendToTarget();
        }
    };
}
Also used : SomeArgs(com.android.internal.os.SomeArgs) RemoteCallback(android.os.RemoteCallback)

Aggregations

RemoteCallback (android.os.RemoteCallback)18 Bundle (android.os.Bundle)12 RemoteException (android.os.RemoteException)7 Intent (android.content.Intent)6 IOException (java.io.IOException)6 AccountAndUser (android.accounts.AccountAndUser)5 PendingIntent (android.app.PendingIntent)5 SyncAdapterType (android.content.SyncAdapterType)5 RegisteredServicesCache (android.content.pm.RegisteredServicesCache)5 DeadObjectException (android.os.DeadObjectException)5 IBinder (android.os.IBinder)5 TransactionTooLargeException (android.os.TransactionTooLargeException)5 UserHandle (android.os.UserHandle)5 ServiceState (com.android.internal.app.procstats.ServiceState)5 SomeArgs (com.android.internal.os.SomeArgs)5 EndPoint (com.android.server.content.SyncStorageEngine.EndPoint)5 HashSet (java.util.HashSet)5 DeviceAdminInfo (android.app.admin.DeviceAdminInfo)1 ComponentName (android.content.ComponentName)1 DialogInterface (android.content.DialogInterface)1