Binder 源码分析

Binder 源码分析

AIDL

SDK自动生成的AIDL类

  • DESCRIPTOR

    private static final java.lang.String DESCRIPTOR = "com.rxt.bindersample.aidl.ICellPhoneManager";

    Binder的唯一标识




  • asInterface

    /**
     * Cast an IBinder object into an com.rxt.bindersample.aidl.ICellPhoneManager interface,
     * generating a proxy if needed.
     */
    public static com.rxt.bindersample.aidl.ICellPhoneManager asInterface(android.os.IBinder obj) {
        if ((obj == null)) {
            return null;
        }
        android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
        if (((iin != null) && (iin instanceof com.rxt.bindersample.aidl.ICellPhoneManager))) {
            return ((com.rxt.bindersample.aidl.ICellPhoneManager) iin);
        }
        return new com.rxt.bindersample.aidl.ICellPhoneManager.Stub.Proxy(obj);
    }
    

    将服务端的Binder转换成客户端的AIDL接口对象,当服务端和客户端在同一进程中时,返回服务端的Stub,反之,返回系统封装的Proxy代理对象




  • asBinder

    public android.os.IBinder asBinder() {
        return this;
    }
    

    返回Binder对象




  • onTransact

    public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException {
            switch (code) {
                case INTERFACE_TRANSACTION: {
                    reply.writeString(DESCRIPTOR);
                    return true;
                }
                case TRANSACTION_getCellPhoneList: {
                    data.enforceInterface(DESCRIPTOR);
                    java.util.List<com.rxt.bindersample.aidl.CellPhone> _result = this.getCellPhoneList();
                    reply.writeNoException();
                    reply.writeTypedList(_result);
                    return true;
                }
                case TRANSACTION_addCellPhone: {
                    data.enforceInterface(DESCRIPTOR);
                    com.rxt.bindersample.aidl.CellPhone _arg0;
                    if ((0 != data.readInt())) {
                        _arg0 = com.rxt.bindersample.aidl.CellPhone.CREATOR.createFromParcel(data);
                    } else {
                        _arg0 = null;
                    }
                    this.addCellPhone(_arg0);
                    reply.writeNoException();
                    return true;
                }
                case TRANSACTION_registerOnNewDataReceivedListner: {
                    data.enforceInterface(DESCRIPTOR);
                    com.rxt.bindersample.aidl.IOnNewDataReceivedListner _arg0;
                    _arg0 = com.rxt.bindersample.aidl.IOnNewDataReceivedListner.Stub.asInterface(data.readStrongBinder());
                    this.registerOnNewDataReceivedListner(_arg0);
                    reply.writeNoException();
                    return true;
                }
                case TRANSACTION_unRegisterOnNewDataReceivedListner: {
                    data.enforceInterface(DESCRIPTOR);
                    com.rxt.bindersample.aidl.IOnNewDataReceivedListner _arg0;
                    _arg0 = com.rxt.bindersample.aidl.IOnNewDataReceivedListner.Stub.asInterface(data.readStrongBinder());
                    this.unRegisterOnNewDataReceivedListner(_arg0);
                    reply.writeNoException();
                    return true;
                }
            }
            return super.onTransact(code, data, reply, flags);
        }
    

    该方法运行在服务端,当客户端向服务端发起跨进程请求时调用。code为方法的唯一标识,服务端根据code来确定调用哪个方法;data为客户端传输的数据,服务端取出data中的数据执行目标方法,然后向reply中写入返回数据。该方法返回false时会导致客户端请求失败,由此可在服务端service的Binder对象中重写此方法进行客户端权限验证等操作

    public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
        //客户端权限验证
        int permissionVal = checkCallingOrSelfPermission("com.rxt.binder");
        if (permissionVal == PackageManager.PERMISSION_DENIED) {
            //客户端没有声明权限
            Log.i(TAG, "onTransact: " + "客户端没有权限");
            return false;
        }
    
        //客户端包名验证
        String packageName = null;
        String[] packages = getPackageManager().getPackagesForUid(getCallingUid());
        if (packages != null && packages.length > 0) {
            packageName = packages[0];
        }
        if (packageName != null && !packageName.startsWith("com.rxt")) {
            Log.i(TAG, "onTransact: " + "客户端包名不对");
            return false;
        }
        return super.onTransact(code, data, reply, flags);
    }
    



  • Proxy中实现的接口中的方法

    如:

    public java.util.List<com.rxt.bindersample.aidl.CellPhone> getCellPhoneList() throws android.os.RemoteException {
        android.os.Parcel _data = android.os.Parcel.obtain();
        android.os.Parcel _reply = android.os.Parcel.obtain();
        java.util.List<com.rxt.bindersample.aidl.CellPhone> _result;
        try {
            _data.writeInterfaceToken(DESCRIPTOR);
            mRemote.transact(Stub.TRANSACTION_getCellPhoneList, _data, _reply, 0);
            _reply.readException();
            _result = _reply.createTypedArrayList(com.rxt.bindersample.aidl.CellPhone.CREATOR);
        } finally {
            _reply.recycle();
            _data.recycle();
        }
        return _result;
    }
    

    该方法运行在客户端中。首先创建输入型parcel对象_data,输出型parcel对象_reply,以及返回结果_result(如果有的话),然后把输入参数(如果有的话)写入_data,再调用transact方法发起远程调用。此时客户端线程挂起直到_result结果返回,所以,如果服务端方法为耗时操作,该方法不应放在UI线程中执行。




Binder工作机制流程图

Binder FrameWork层源码分析

binder framework流程图

关键的类

  • ContextImpl

    ContextWrapper实现类,bindService方法

  • IActivityManager

    客户端与系统进程之间的aidl

  • ActivityManagerNative

    IActivityManager的Stub

  • ActivityManagerProxy

    IActivityManager的Proxy

  • ActivityManagerService

    ActivityManagerNative的实现类

  • ActiveServices

  • ActivityThread

ContextImpl#bindServiceCommon

int res = ActivityManagerNative.getDefault().bindService(
        mMainThread.getApplicationThread(), getActivityToken(), service,
        service.resolveTypeIfNeeded(getContentResolver()),
        sd, flags, getOpPackageName(), user.getIdentifier());    

ActivityManagerNative.getDefault()可以发现IActivityManager,ActivityManagerNative,ActivityManagerProxy,ActivityManagerNative这几个客户端与系统进程间aidl相关的类

AcitivityManagerService#bindService

synchronized(this) {
        ----------关键代码-----------
        return mServices.bindServiceLocked(caller, token, service,
                resolvedType, connection, flags, callingPackage, userId);
    }

由这段代码进入ActiveServices中的bindServiceLocked方法

ActiveServices#bindServiceLocked

  • bindServiceLocked (关键方法)

    判断调用者是否为空(进程意外结束的情况)

    if (callerApp == null) {
    throw new SecurityException(
            "Unable to find app for caller " + caller
            + " (pid=" + Binder.getCallingPid()
            + ") when binding service " + service);
    }
    

    判断调用者是否为系统进程

    if (callerApp.info.uid == Process.SYSTEM_UID) {
        ......
    }
    

    保存Connection

    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);
    

    如果flag是Context.BIND_AUTO_CREATE,调用bringUpServiceLocked方法唤起服务

    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 && b.intent.received) {
            // Service is already running, so we can immediately
            // 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);
            }
    
            // 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);
            }
        } else if (!b.intent.requested) {
            requestServiceBindingLocked(s, b.intent, callerFg, false);
        }
    

ActiveServices#bringupServiceLocked

即将唤起服务,把r从重启Service的list中移除,r的状态不再为重启状态

// We are now bringing the service up, so no longer in the
    // restarting state.
    if (mRestartingServices.remove(r)) {
        r.resetRestartCounter();
        clearRestartingIfNeededLocked(r);
    }

服务的状态不再为延迟启动,我们现在就要启动服务了

// Make sure this service is no longer considered delayed, we are starting it now.
    if (r.delayed) {
        if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "REM FR DELAY LIST (bring up): " + r);
        getServiceMap(r.userId).mDelayedStartList.remove(r);
        r.delayed = false;
    }

确保服务所在的进程(即服务端进程)已经启动,如果没有,不让服务启动

// Make sure that the user who owns this service is started.  If not,
    // we don't want to allow it to run.
    if (mAm.mStartedUsers.get(r.userId) == null) {
        String msg = "Unable to launch app "
                + r.appInfo.packageName + "/"
                + r.appInfo.uid + " for service "
                + r.intent.getIntent() + ": user " + r.userId + " is stopped";
        Slog.w(TAG, msg);
        bringDownServiceLocked(r);
        return msg;
    }

服务已启动

// Service is now being launched, its package can't be stopped.
    try {
        AppGlobals.getPackageManager().setPackageStoppedState(
                r.packageName, false, r.userId);
    } catch (RemoteException e) {
    } catch (IllegalArgumentException e) {
        Slog.w(TAG, "Failed trying to unstop package "
                + r.packageName + ": " + e);
    }

判断服务在服务端是否为单独的进程,如果不是,再进一步判断进程是否已经启动,如果已启动,则执行realStartServiceLocked。

final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
final String procName = r.processName;
ProcessRecord app;

if (!isolated) {
    app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
    if (DEBUG_MU) Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid
                + " app=" + app);
    if (app != null && app.thread != null) {
        try {
            app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats);
            realStartServiceLocked(r, app, execInFg);
            return null;
        } catch (TransactionTooLargeException e) {
            throw e;
        } catch (RemoteException e) {
            Slog.w(TAG, "Exception when starting service " + r.shortName, e);
        }

        // If a dead object exception was thrown -- fall through to
        // restart the application.
    }
} else {
    // If this service runs in an isolated process, then each time
    // we call startProcessLocked() we will get a new isolated
    // process, starting another process if we are currently waiting
    // for a previous process to come up.  To deal with this, we store
    // in the service any current isolated process it is running in or
    // waiting to have come up.
    app = r.isolatedProc;
}

如果服务端进程没有运行,则调用startProcessLocked启动进程,并在进程启动后启动服务

// Not running -- get it started, and enqueue this service record
    // to be executed when the app comes up.
    if (app == null) {
        if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
                "service", r.name, false, isolated, false)) == null) {
            String msg = "Unable to launch app "
                    + r.appInfo.packageName + "/"
                    + r.appInfo.uid + " for service "
                    + r.intent.getIntent() + ": process is bad";
            Slog.w(TAG, msg);
            bringDownServiceLocked(r);
            return msg;
        }
        if (isolated) {
            r.isolatedProc = app;
        }
    }

ActiveServices#realStartServiceLocked

app.thread.scheduleCreateService(r, r.serviceInfo,
                mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
                app.repProcState);

......
requestServiceBindingsLocked(r, execInFg);

ActivityThread#scheduleCreateService

调用创建服务方法

ActivityThread#handleCreateService

创建服务

LoadedApk packageInfo = getPackageInfoNoCheck(data.info.applicationInfo, data.compatInfo);
    Service service = null;
    try {
        java.lang.ClassLoader cl = packageInfo.getClassLoader();
        service = (Service) cl.loadClass(data.info.name).newInstance();
    } catch (Exception e) {
        if (!mInstrumentation.onException(service, e)) {
            throw new RuntimeException(
                "Unable to instantiate service " + data.info.name
                + ": " + e.toString(), e);
        }
}

ActiveServices#requestServiceBindingLocked

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.repProcState);
        if (!rebind) {
            i.requested = true;
        }
        i.hasBound = true;
        i.doRebind = false;
    } catch (TransactionTooLargeException e) {
        // Keep the executeNesting count accurate.
        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Crashed while binding " + r, e);
        final boolean inDestroying = mDestroyingServices.contains(r);
        serviceDoneExecutingLocked(r, inDestroying, inDestroying);
        throw e;
    } catch (RemoteException e) {
        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Crashed while binding " + r);
        // Keep the executeNesting count accurate.
        final boolean inDestroying = mDestroyingServices.contains(r);
        serviceDoneExecutingLocked(r, inDestroying, inDestroying);
        return false;
    }
}

ActivityThread#handleBindService

private void handleBindService(BindServiceData data) {
    Service s = mServices.get(data.token);
    if (DEBUG_SERVICE)
        Slog.v(TAG, "handleBindService s=" + s + " rebind=" + data.rebind);
    if (s != null) {
        try {
            data.intent.setExtrasClassLoader(s.getClassLoader());
            data.intent.prepareToEnterProcess();
            try {
                if (!data.rebind) {
                    IBinder binder = s.onBind(data.intent);
                    ActivityManagerNative.getDefault().publishService(
                            data.token, data.intent, binder);
                } else {
                    s.onRebind(data.intent);
                    ActivityManagerNative.getDefault().serviceDoneExecuting(
                            data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
                }
                ensureJitEnabled();
            } catch (RemoteException ex) {
            }
        } catch (Exception e) {
            if (!mInstrumentation.onException(s, e)) {
                throw new RuntimeException(
                        "Unable to bind to service " + s
                        + " with " + data.intent + ": " + e.toString(), e);
            }
        }
    }
}

ActiveServices#publishServiceLocked

void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {
    final long origId = Binder.clearCallingIdentity();
    try {
        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "PUBLISHING " + r
                + " " + intent + ": " + service);
        if (r != null) {
            Intent.FilterComparison filter
                    = new Intent.FilterComparison(intent);
            IntentBindRecord b = r.bindings.get(filter);
        -------- 对b的一些属性进行赋值,这些将在ActiveServices#bindServiceLocked的判断中用到----------
            if (b != null && !b.received) {
                b.binder = service;
                b.requested = true;
                b.received = true;
                for (int conni=r.connections.size()-1; conni>=0; conni--) {
                    ArrayList<ConnectionRecord> clist = r.connections.valueAt(conni);
                    for (int i=0; i<clist.size(); i++) {
                        ConnectionRecord c = clist.get(i);
                        if (!filter.equals(c.binding.intent.intent)) {
                            if (DEBUG_SERVICE) Slog.v(
                                    TAG_SERVICE, "Not publishing to: " + c);
                            if (DEBUG_SERVICE) Slog.v(
                                    TAG_SERVICE, "Bound intent: " + c.binding.intent.intent);
                            if (DEBUG_SERVICE) Slog.v(
                                    TAG_SERVICE, "Published intent: " + intent);
                            continue;
                        }
                        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Publishing to: " + c);
                        try {
                        ----------把binder返回到客户端-----
                            c.conn.connected(r.name, service);
                        } catch (Exception e) {
                            Slog.w(TAG, "Failure sending service " + r.name +
                                  " to connection " + c.conn.asBinder() +
                                  " (in " + c.binding.client.processName + ")", e);
                        }
                    }
                }
            }

            serviceDoneExecutingLocked(r, mDestroyingServices.contains(r), false);
        }
    } finally {
        Binder.restoreCallingIdentity(origId);
    }

ActivityManagerService#startProcessLocked

ActiveServices#bringupServiceLocked中调用,经过N次重载之后找到如下启动进程的代码

// Start the process.  It will either succeed and return a result containing
// the PID of the new process, or else throw a RuntimeException.
boolean isActivityProcess = (entryPoint == null);
if (entryPoint == null) entryPoint = "android.app.ActivityThread";
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
        app.processName);
checkTime(startTime, "startProcess: asking zygote to start proc");
Process.ProcessStartResult startResult = Process.start(entryPoint,
        app.processName, uid, uid, gids, debugFlags, mountExternal,
        app.info.targetSdkVersion, app.info.seinfo, requiredAbi, 
        instructionSet,app.info.dataDir, entryPointArgs);

之后的过程回到ActiveServices#bindServiceLocked方法中

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);
    } catch (Exception e) {
        Slog.w(TAG, "Failure sending service " + s.shortName
                + " 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);
    }
} else if (!b.intent.requested) {
    -----------在此处执行了绑定服务并把Binder返回给客户端的过程-----------
    requestServiceBindingLocked(s, b.intent, callerFg, false);
}

至此,Binder 源码解析结束!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值