andorid4.4 USB默认权限修改

最近在Android4.4上调试一个Usb指纹模块,记录下系统默认权限修改.

Usb Device具体操作流程这里就不写了,网上有很多例子,

正常流程:首先是UsbManager申请权限,这时会出现一个提示框,如下图:

andorid4.4 USB默认权限修改_第1张图片

勾选默认情况下用于该设备后,点击确定。这时会在/data/system/users/0/目录下生成一个xml文件

usb_device_manager.xml

内容如下:


会保存package应用程序的包名,设备vid,pid,以及相关协议.

知道这些后,开始跟踪代码找相关函数.

UsbManager的requestPermission最后是调用Usbservice的requestDevicePermission函数然后到UsbSettingsManager里的requestPermission函数,这个最后的requestPermissionDialog就是调用Systemui的UsbPermissionActivity弹出的第一个申请权限的对话框.

由于我要在裁剪过的系统里进行修改,这里面已经删除了SystemUi所以,只能在requestPermissionDialog之前进行处理.

查看Systemui中UsbPermissionActivity申请权限点击后主要作了两件事

                    intent = new Intent(UsbManager.ACTION_USB_DEVICE_ATTACHED);
                    intent.putExtra(UsbManager.EXTRA_DEVICE, mDevice);

                    // grant permission for the device
                    service.grantDevicePermission(mDevice, uid);
                    // set or clear default setting
                    if (alwaysUse) {
                        service.setDevicePackage(
                                mDevice, mResolveInfo.activityInfo.packageName, userId);
                    } else {
                        service.setDevicePackage(mDevice, null, userId);
                    }

首先调用UsbService的grantDevicePermission,然后调用了setDevicePackage

对应查看UsbSettingsManager的两个函数,然后对UsbSettingsManager进行了如下修改

修改构造函数

    public UsbSettingsManager(Context context, UserHandle user) {
        if (DEBUG) Slog.v(TAG, "Creating settings for " + user);

        try {
            mUserContext = context.createPackageContextAsUser("android", 0, user);
        } catch (NameNotFoundException e) {
            throw new RuntimeException("Missing android package");
        }

        mContext = context;
        mPackageManager = mUserContext.getPackageManager();

        mUser = user;
        mSettingsFile = new AtomicFile(new File(
                Environment.getUserSystemDirectory(user.getIdentifier()),
                "usb_device_manager.xml"));

        synchronized (mLock) {
            if (UserHandle.OWNER.equals(user)) {
                upgradeSingleUserLocked();
            }
            readSettingsLocked();
        }

		//add by hclydao
        DeviceFilter myfilter = new DeviceFilter(pid, vid,0, 0, 0);
		String pak = mDevicePreferenceMap.get(myfilter);
		if(pak == null) {
			mDevicePreferenceMap.put(myfilter, mypakname);//mypakname是应用程序包名 String类型
			writeSettingsLocked();
		}
            //add end
        mPackageMonitor.register(mUserContext, null, true);
    }

其中pid,vid在之前测试的usb_device_manager.xml中可以找到,一般产家都会直接提供,这里的操作是直接启动后,直接将相关信息写到usb_device_manager.xml文件中,这里相当于调用了一次setDevicePackage.

然后修改requestPermission函数

    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;
        }
		//hclydao
		if(packageName.equals(mypakname)) {
			int uid = Binder.getCallingUid();
            SparseBooleanArray uidList = new SparseBooleanArray(1);
            mDevicePermissionMap.put(device.getDeviceName(), uidList);
			uidList.put(uid, true);

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

如果当前申请权限的包名与默认设置的包名一致就直接给权限返回.直接相当于调用了一次grantDevicePermission

修改完成后,编译系统更新,解决问题.

======================================
作者:hclydao
http://blog.csdn.net/hclydao
版权没有,但是转载请保留此段声明

===========================================

你可能感兴趣的:(android系统)