Superuser总结一

来源:互联网 发布:java调用百度地图api 编辑:程序博客网 时间:2024/04/30 20:46

一、请求

1、在控制台切换用户 如“su”或应用程序请求获取时都会在SuReceiver中收到信息,并将数据保存到数据库

其中SuDatabaseHelper操作的uid_policy是保存root授权“允许”或“拒绝”的数据库

SuperUserDatabaseHelper操作的log数据库是记录log日志的数库

 public void onReceive(final Context context, Intent intent) {
        if (intent == null)
            return;
       
        String command = intent.getStringExtra("command");
        if (command == null)
            return;
        int uid = intent.getIntExtra("uid", -1);
        if (uid == -1)
            return;
        int desiredUid = intent.getIntExtra("desired_uid", -1);
        if (desiredUid == -1)
            return;
        String action = intent.getStringExtra("action");
        if (action == null)
            return;
        String fromName = intent.getStringExtra("from_name");
        String desiredName = intent.getStringExtra("desired_name");

        final LogEntry le = new LogEntry();
        le.uid = uid;
        le.command = command;
        le.action = action;
        le.desiredUid = desiredUid;
        le.desiredName = desiredName;
        le.username = fromName;
        le.date = (int)(System.currentTimeMillis() / 1000);
        le.getPackageInfo(context);

        UidPolicy u = SuperuserDatabaseHelper.addLog(context, le);//将日志信息保存到数据库

        String toast;

      //弹出授权或者拒绝的土司
        if (UidPolicy.ALLOW.equals(action)) {
            toast = context.getString(R.string.superuser_granted, le.getName());
        }
        else {
            toast = context.getString(R.string.superuser_denied, le.getName());
        }

............

}

二、授权

1、在控制台输入su获取权root限或者是应用程序请求root权限时,会启动com.koushikdutta.superuser.MultitaskSuRequestActivity这个类,并传入一个带有通信地址的intent,通过该intent可以获取到与su交互的socket的路径
    Intent intent = getIntent();
    if (intent == null) {
        finish();
        return;
    }

    mSocketPath = intent.getStringExtra("socket");
    if (mSocketPath == null) {
        finish();
        return;
    }
    
    
2、在manageSocket() 方法中,通过intent中获取到的路径,创建socket与su交互

mSocket = new LocalSocket();
mSocket.connect(new LocalSocketAddress(mSocketPath, Namespace.FILESYSTEM));

 

3、在弹出的界面中点击“允许”会执行下面的方法

 mAllow.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                 if (!Settings.isPinProtected(MultitaskSuRequestActivity.this)) {
                    approve();
                    return;
                }
                .......
});

在approve()方法中

void approve() {
        mAllow.setEnabled(false);//设置“允许”键不可用
        mDeny.setEnabled(false);//设置“拒绝”键不可用
        handleAction(true, null);//真正处理逻辑的方法
 }

 

 

4、在弹出的界面中点击“拒绝”会执行下面的方法

  mDeny.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                    deny();
            }
        });

 

void deny() {
        mAllow.setEnabled(false);
        mDeny.setEnabled(false);
        handleAction(false, null);//第一个参数是false
    }

 

5、如果不处理,会通过下面的方法过一段时间后关闭该activity

 mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                if (isFinishing())
                    return;
                if (!mHandled)
                  handleAction(false, -1);//第二个参数为-1
            }
        }, Settings.getRequestTimeout(this) * 1000);

6、当按“返回键”或其它情况执行onDestroy()方法时,

 @Override
    protected void onDestroy() {
        super.onDestroy();
        if (!mHandled)
           handleAction(false, -1);//与延迟关闭时执行相同的方法,第二个参数为-1
        try {
            if (mSocket != null)//关闭此次socket连接
                mSocket.close();
        }
        catch (Exception ex) {
        }
        new File(mSocketPath).delete();
    }

 

7、  void handleAction(boolean action, Integer until) {
     System.out.println("mSocket传入的mHandled:"+mHandled);
        Assert.assertTrue(!mHandled);
        System.out.println("mSocket断定以后mHandled:"+mHandled);
        mHandled = true;
        try {
            mSocket.getOutputStream().write((action ? "socket:ALLOW" : "socket:DENY").getBytes());
            System.out.println("mSocket写了action:"+action);
        }
        catch (Exception ex) {
         ex.printStackTrace();
        }
        try {
            if (until == null) {
                until = getUntil();
            }
            // got a policy? let's set it.
            //延迟关闭即第5步骤的方法或onDestory()中的方法,第二个参数为-1,不会执行下面的方法,不会保存到数据库,即不会记录此次“同意”或“拒绝”的条目,在
           //首界面的同意或拒绝条目中不会看到该应用的数据

             if (until != -1) {         

               UidPolicy policy = new UidPolicy();
                policy.policy = action ? UidPolicy.ALLOW : UidPolicy.DENY;
                policy.uid = mCallerUid;
                // for now just approve all commands, since per command approval is stupid
                policy.command = null;
                policy.until = until;
                policy.desiredUid = mDesiredUid;
                SuDatabaseHelper.setPolicy(this, policy);//将数据保存到数据库中
            }
            // TODO: logging? or should su binary handle that via broadcast?
            // Probably the latter, so it is consolidated and from the system of record.
        }
        catch (Exception ex) {
        }
        finish();
    }

0 0
原创粉丝点击