从usb 实际应用分析源码之usb权限

1.第二步就是判断权限是否开放,因为在open 是会对权限检验所以必要的: 
mUsbManager.hasPermission(mDevice)); 
mUsbManager.requestPermission(mDevice,
           mPermissionIntent);

 2.直接看UsbService 吧


    public boolean hasDevicePermission(UsbDevice device) {
// 不同应用用有不同usbId,除非是系统应用
        final int userId = UserHandle.getCallingUserId();
        return getSettingsForUser(userId).hasPermission(device);
    }
//UsbSettiongManager
public boolean hasPermission(UsbDevice device) {
        synchronized (mLock) {
            int uid = Binder.getCallingUid();
            if (uid == Process.SYSTEM_UID) {
                return true; //是系统应用直接返回true
            }
            SparseBooleanArray uidList = mDevicePermissionMap.get(device.getDeviceName()); //在已经授权的集合中能查到返回true否则false;
            if (uidList == null) {
                return false;
            }
            return uidList.get(uid);
        }
    }
//申请权限

    public void requestDevicePermission(UsbDevice device, String packageName, PendingIntent pi) {
        final int userId = UserHandle.getCallingUserId();
        
        getSettingsForUser(userId).requestPermission(device, packageName, pi);
    }

//UsbSettingManager

  public void requestPermission(UsbDevice device, String packageName, PendingIntent pi) {
      Intent intent = new Intent();

        // respond immediately if permission has already been granted
      if (hasPermission(device)) {
//如果已经申请权限 直接发广播
            intent.putExtra(UsbManager.EXTRA_DEVICE, device);
            intent.putExtra(UsbManager.EXTRA_PERMISSION_GRANTED, true);
            try {
                pi.send(mUserContext, 0, intent);
            } catch (PendingIntent.CanceledException e) {
                if (DEBUG) Slog.d(TAG, "requestPermission PendingIntent was cancelled");
            }
            return;
        }

        // start UsbPermissionActivity so user can choose an activity
        intent.putExtra(UsbManager.EXTRA_DEVICE, device);
        requestPermissionDialog(intent, packageName, pi);
    }

//就调起UsbPermissionActivity 没有什么别的
private void requestPermissionDialog(Intent intent, String packageName, PendingIntent pi) {
        final int uid = Binder.getCallingUid();

        // compare uid with packageName to foil apps pretending to be someone else
        try {
            ApplicationInfo aInfo = mPackageManager.getApplicationInfo(packageName, 0);
            if (aInfo.uid != uid) {
                throw new IllegalArgumentException("package " + packageName +
                        " does not match caller's uid " + uid);
            }
        } catch (PackageManager.NameNotFoundException e) {
            throw new IllegalArgumentException("package " + packageName + " not found");
        }

        long identity = Binder.clearCallingIdentity();
        intent.setClassName("com.android.systemui",
                "com.android.systemui.usb.UsbPermissionActivity");
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.putExtra(Intent.EXTRA_INTENT, pi);
        intent.putExtra("package", packageName);
        intent.putExtra(Intent.EXTRA_UID, uid);
        try {
            mUserContext.startActivityAsUser(intent, mUser);
        } catch (ActivityNotFoundException e) {
            Slog.e(TAG, "unable to start UsbPermissionActivity");
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
    }
//UsbPermissionActivity 关键部分

    public void onClick(DialogInterface dialog, int which) {
        if (which == AlertDialog.BUTTON_POSITIVE) {  //点击确定按钮就确认授权

            mPermissionGranted = true; 
        }
        finish();
    }

    public void onDestroy() {
        IBinder b = ServiceManager.getService(USB_SERVICE);
        IUsbManager service = IUsbManager.Stub.asInterface(b);

        // send response via pending intent
        Intent intent = new Intent();
        try {
            if (mDevice != null) {
                intent.putExtra(UsbManager.EXTRA_DEVICE, mDevice);
                if (mPermissionGranted) {
       //填充UsbSettingManager 授权集合 ,之前在做无权限弹窗时使用aidl(将IUsbManager.adil拷贝到自己工程目录下,能执行这个方法却报我应用没有manger_usb权限 也是需要系统应用才能分配这个权限.是系统应用要你干啥)
                    service.grantDevicePermission(mDevice, mUid);
                    if (mAlwaysUse.isChecked()) {
                        final int userId = UserHandle.getUserId(mUid);
                //然后发广播....完
                        service.setDevicePackage(mDevice, mPackageName, userId);
                    }
                }
            }
            if (mAccessory != null) {
                intent.putExtra(UsbManager.EXTRA_ACCESSORY, mAccessory);
                if (mPermissionGranted) {
                    service.grantAccessoryPermission(mAccessory, mUid);
                    if (mAlwaysUse.isChecked()) {
                        final int userId = UserHandle.getUserId(mUid);
                        service.setAccessoryPackage(mAccessory, mPackageName, userId);
                    }
                }
            }
            intent.putExtra(UsbManager.EXTRA_PERMISSION_GRANTED, mPermissionGranted);
            mPendingIntent.send(this, 0, intent);
        } catch (PendingIntent.CanceledException e) {
            Log.w(TAG, "PendingIntent was cancelled");
        } catch (RemoteException e) {
            Log.e(TAG, "IUsbService connection failed", e);
        }

        if (mDisconnectedReceiver != null) {
            unregisterReceiver(mDisconnectedReceiver);
        }
        super.onDestroy();
    }

3.无权限弹窗常见方法:1.root 可以用libusb库2.系统应用3.自己修改系统源码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值