@OverridepublicbooleanbindService(Intent service,ServiceConnection conn,int flags){warnIfCallingFromSystemProcess();returnbindServiceCommon(service, conn, flags,null, mMainThread.getHandler(),null,getUser());}privatebooleanbindServiceCommon(Intent service,ServiceConnection conn,int flags,String instanceName,Handler handler,Executor executor,UserHandle user){// Keep this in sync with DevicePolicyManager.bindDeviceAdminServiceAsUser.IServiceConnection sd;if(conn ==null){thrownewIllegalArgumentException("connection is null");}if(handler !=null&& executor !=null){thrownewIllegalArgumentException("Handler and Executor both supplied");}if(mPackageInfo !=null){if(executor !=null){sd = mPackageInfo.getServiceDispatcher(conn,getOuterContext(), executor, flags);}else{sd = mPackageInfo.getServiceDispatcher(conn,getOuterContext(), handler, flags);}}else{thrownewRuntimeException("Not supported in system context");}validateServiceIntent(service);try{IBinder token =getActivityToken();if(token ==null&&(flags&BIND_AUTO_CREATE)==0&& mPackageInfo !=null&& mPackageInfo.getApplicationInfo().targetSdkVersion<android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH){flags |=BIND_WAIVE_PRIORITY;}service.prepareToLeaveProcess(this);int res =ActivityManager.getService().bindIsolatedService(mMainThread.getApplicationThread(),getActivityToken(), service,service.resolveTypeIfNeeded(getContentResolver()),sd, flags, instanceName,getOpPackageName(), user.getIdentifier());if(res <0){thrownewSecurityException("Not allowed to bind to service "+ service);}return res !=0;}catch(RemoteException e){throw e.rethrowFromSystemServer();}}
调用AMS的bindIsolatedService
publicintbindIsolatedService(IApplicationThread caller,IBinder token,Intent service,String resolvedType,IServiceConnection connection,int flags,String instanceName,String callingPackage,int userId)throwsTransactionTooLargeException{enforceNotIsolatedCaller("bindService");// Refuse possible leaked file descriptorsif(service !=null&& service.hasFileDescriptors()==true){thrownewIllegalArgumentException("File descriptors passed in Intent");}if(callingPackage ==null){thrownewIllegalArgumentException("callingPackage cannot be null");}// Ensure that instanceName, which is caller provided, does not contain// unusual characters.if(instanceName !=null){for(int i =0; i < instanceName.length();++i){char c = instanceName.charAt(i);if(!((c >='a'&& c <='z')||(c >='A'&& c <='Z')||(c >='0'&& c <='9')|| c =='_'|| c =='.')){thrownewIllegalArgumentException("Illegal instanceName");}}}synchronized(this){return mServices.bindServiceLocked(caller, token, service,resolvedType, connection, flags, instanceName, callingPackage, userId);}}
intbindServiceLocked(IApplicationThread caller,IBinder token,Intent service,if(s.app !=null&& b.intent.received){// Service is already running, so we can immediately// publish the connection.try {c.conn.connected(s.name, b.intent.binder,false);}catch(Exception e){Slog.w(TAG,"Failure sending service "+ s.shortInstanceName+" to connection "+ c.conn.asBinder()+" (in "+ c.binding.client.processName +")", e);}// If this is the first app connected back to this binding,// and the service had previously asked to be told when// rebound, then do so.if (b.intent.apps.size() == 1 && b.intent.doRebind) {requestServiceBindingLocked(s, b.intent, callerFg,true);}}elseif(!b.intent.requested){requestServiceBindingLocked(s, b.intent, callerFg,false);}}privatefinalbooleanrequestServiceBindingLocked(ServiceRecord r,IntentBindRecord i,boolean execInFg,boolean rebind)throwsTransactionTooLargeException{if((!i.requested || rebind)&& i.apps.size()>0){try{bumpServiceExecutingLocked(r, execInFg,"bind");r.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,r.app.getReportedProcState());if(!rebind){i.requested =true;}i.hasBound =true;i.doRebind =false;}catch(TransactionTooLargeException e){}catch(RemoteException e){}}returntrue;}