android 添加安装权限白名单

点击打开链接

有些项目不允许所有APK都拥有安装权限,例如apk只能通过应用商城来安装或者升级,只允许某些特定的apk自升级,不允许pm install等。这就需要添加安装权限白名单来控制。

1、packageManagerService修改

安装肯定绕不开packageManagerService,我们在其中添加几个接口及代码来控制apk安装。

1)增加以下函数:

       /*add for installer white list*/
    private boolean isInstallerEnable(String packagename){
        ArrayList<String> whiteListApp = new ArrayList<String>();

        try{
            BufferedReader br = new BufferedReader(new InputStreamReader(
            new FileInputStream("/system/etc/WhiteListAppFilter.properties")));

            String line ="";
            while ((line = br.readLine()) != null){
                whiteListApp.add(line);
            }

            br.close();
        }catch(java.io.FileNotFoundException ex){
            return false;
        }catch(java.io.IOException ex){
            return false;
        }

        Iterator<String> it = whiteListApp.iterator();

        while (it.hasNext()) {
            String whitelisItem = it.next();
            if (whitelisItem.equals(packagename)) {
                return true;
            }
        }
        return false;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

isInstallerEnable函数会去读取白名单文件/system/etc/WhiteListAppFilter.properties,然后和我们传进来的包名进行匹配,在白名单中返回true,其他情况均返回false。

2)获取调用的包名 
这个可以在installPackageWithVerificationAndEncryption函数中来获取,


        if (uid == Process.SHELL_UID || uid == 0) {
            if (DEBUG_INSTALL) {
                Slog.v(TAG, "Install from ADB");
            }
            filteredFlags = flags | PackageManager.INSTALL_FROM_ADB;
        } else {
            filteredFlags = flags & ~PackageManager.INSTALL_FROM_ADB;
        }

        verificationParams.setInstallerUid(uid);

        //add for installer white list
        mCallingApp = mContext.getPackageManager().getNameForUid(uid);
        Log.d(TAG, "!!!!!!!!!!!!!callingApp = " + mCallingApp);
        //end

        final Message msg = mHandler.obtainMessage(INIT_COPY);
        msg.obj = new InstallParams(packageURI, observer, filteredFlags, installerPackageName,
                verificationParams, encryptionParams, user);
        mHandler.sendMessage(msg);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

接下来要在installPackageLI函数对调用安装的apk进行匹配,判断是否在白名单中,如果不在的话则提示错误,错误码是-xxx(自己定义),这个错误码会给packageInstaller,packageInstaller中需要做什么,就由自己定义了。

        //add for installer white list
        boolean caninstall =false;
        if(mCallingApp != null && isInstallerEnable(mCallingApp)){
            caninstall = true;
        }

        if(!caninstall){
            Toast.makeText(mContext, R.string.install_error, Toast.LENGTH_LONG).show();
            res.returnCode = -xxx;
            return;
        }
        //end

        if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
        // Retrieve PackageSettings and parse package
        int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
                | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
                | (onSd ? PackageParser.PARSE_ON_SDCARD : 0);
    ...省略
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

3) 
/system/etc/WhiteListAppFilter.properties内容如下,在编译时可以在mk中修改拷贝到etc目录下,例如下面就是允许这三个包名有安装权限。

com.xxx.xxx1 
com.xxx.xxx2 
com.xxx.xxx3

2、pm install的修改

上面说了,还要禁止pm install,因为有些APK安装竟然是调用pm install命令去安装的。。。。 
修改要在pm.java修改,修改方法和上面基本一致。 
可以看到,pm install其实调用的是run再去判断参数。

    public static void main(String[] args) {
        new Pm().run(args);
    }

public void run(String[] args) {
 ...省略
        if ("install".equals(op)) {
            runInstall();
            return;
        }
 ...省略
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

那我们要添加的话,先获取app名,再和packageManagerService一样,增加isInstallerEnable去判断是不是要调用runInstall()就OK了。

            String callingApp = "";
            try {
                callingApp = mPm.getNameForUid(Binder.getCallingUid());
            } catch(RemoteException re) {
                Log.e("Pm", Log.getStackTraceString(new Throwable())); 
            }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

你可能感兴趣的:(Android应用开发,Android操作系统)