public ManagedServiceInfo checkServiceTokenLocked(IInterface service) { checkNotNull(service); final IBinder token = service.asBinder(); final int N = mServices.size(); for (int i = 0; i < N; i++) { final ManagedServiceInfo info = mServices.get(i); if (info.service.asBinder() == token) return info; } throw new SecurityException("Disallowed call from unknown " + getCaption() + ": " + service); }
/** * Register record for application from voice service. * * @param pid process id * @param uid user id * @param listener a callback that receive asynchronous notification from swip * @param featureType feature type * @param commonState common state or main state * @param featureState feture state or sub state * @param handler FeatureManager instance * @return result */ public int registerListenerLocked( int pid, int uid, Object listener, int featureType, int commonState, int featureState, FeatureManager handler) { int result = VoiceCommonState.SUCCESS; ProcessRecord processRecord = createProcessRecordLocked(pid, uid); String featureName = getFeatureName(featureType); if (processRecord == null) { result = VoiceCommonState.PROCESS_ILLEGAL; } else { ListenerRecord record = processRecord.getListenerRecord(featureName); if (record == null) { record = processRecord.createListenerRecord(); try { ((IInterface) listener).asBinder().linkToDeath(processRecord, 0); processRecord.addListenerRecord(featureName, record); } catch (RemoteException ex) { result = VoiceCommonState.PROCESS_ILLEGAL; } } else { // This case only can be happened while service didn't // receive // the died notification. // We need to notify native if possible if (CommonManager.DEBUG) { Log.d( TAG, "Register listener old pid=" + processRecord.getPid() + " old uid=" + processRecord.getUid() + " old processName=" + processRecord.getProcssName()); } } if (result == VoiceCommonState.SUCCESS) { record.init(listener, featureType, featureName, commonState, featureState, handler); } } return result; }
@Override public Object onHook(Object who, Method method, Object... args) throws Throwable { HookUtils.replaceFirstAppPkg(args); args[IDX_RequiredPermission] = null; IntentFilter filter = (IntentFilter) args[IDX_IntentFilter]; modifyIntentFilter(filter); if (args.length > IDX_IIntentReceiver && IIntentReceiver.class.isInstance(args[IDX_IIntentReceiver])) { final IInterface old = (IInterface) args[IDX_IIntentReceiver]; if (!ProxyIIntentReceiver.class.isInstance(old)) { final IBinder token = old.asBinder(); if (token != null) { token.linkToDeath( new IBinder.DeathRecipient() { @Override public void binderDied() { token.unlinkToDeath(this, 0); mProxyIIntentReceiver.remove(token); } }, 0); IIntentReceiver proxyIIntentReceiver = mProxyIIntentReceiver.get(token); if (proxyIIntentReceiver == null) { proxyIIntentReceiver = new ProxyIIntentReceiver(old); mProxyIIntentReceiver.put(token, proxyIIntentReceiver); } WeakReference mDispatcher = LoadedApk.ReceiverDispatcher.InnerReceiver.mDispatcher.get(old); LoadedApk.ReceiverDispatcher.mIIntentReceiver.set( mDispatcher.get(), proxyIIntentReceiver); args[IDX_IIntentReceiver] = proxyIIntentReceiver; } } } return method.invoke(who, args); }
/** * Removes a service from the list but does not unbind * * @return the removed service. */ private ManagedServiceInfo removeServiceImpl(IInterface service, final int userid) { if (DEBUG) Slog.d(TAG, "removeServiceImpl service=" + service + " u=" + userid); ManagedServiceInfo serviceInfo = null; synchronized (mMutex) { final int N = mServices.size(); for (int i = N - 1; i >= 0; i--) { final ManagedServiceInfo info = mServices.get(i); if (info.service.asBinder() == service.asBinder() && info.userid == userid) { if (DEBUG) Slog.d(TAG, "Removing active service " + info.component); serviceInfo = removeServiceLocked(i); } } } return serviceInfo; }
private ManagedServiceInfo registerServiceImpl( final IInterface service, final ComponentName component, final int userid) { synchronized (mMutex) { try { ManagedServiceInfo info = newServiceInfo( service, component, userid, true /*isSystem*/, null, Build.VERSION_CODES.LOLLIPOP); service.asBinder().linkToDeath(info, 0); mServices.add(info); return info; } catch (RemoteException e) { // already dead } } return null; }