CustomLocale.apk所需要的权限"android.permission.CHANGE_CONFIGURATION"自Android 4.2,4.2.2起系统定义为android:protectionLevel="signature|system|development",这就需要在已root的android设置上运行命令:

adb shell pm grant application_package android.permission.CHANGE_CONFIGURATION

下面具体说说pm grant的调用路径。

Pm.java

View Codepublic void run(String[] args) {        boolean validCommand = false;        if (args.length < 1) {            showUsage();            return;        }...if ("grant".equals(op)) {            runGrantRevokePermission(true);            return;        }...private void runGrantRevokePermission(boolean grant) {        String pkg = nextArg();        if (pkg == null) {            System.err.println("Error: no package specified");            showUsage();            return;        }        String perm = nextArg();        if (perm == null) {            System.err.println("Error: no permission specified");            showUsage();            return;        }        try {            if (grant) {                mPm.grantPermission(pkg, perm);            } else {                mPm.revokePermission(pkg, perm);            }        } catch (RemoteException e) {            System.err.println(e.toString());            System.err.println(PM_NOT_RUNNING_ERR);        } catch (IllegalArgumentException e) {            System.err.println("Bad argument: " + e.toString());            showUsage();        } catch (SecurityException e) {            System.err.println("Operation not allowed: " + e.toString());        }    }

PackageManagerService.java

View Codepublic class PackageManagerService extends IPackageManager.Stub {...public void grantPermission(String packageName, String permissionName) {        mContext.enforceCallingOrSelfPermission(                android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, null);        synchronized (mPackages) {            final PackageParser.Package pkg = mPackages.get(packageName);            if (pkg == null) {                throw new IllegalArgumentException("Unknown package: " + packageName);            }            final BasePermission bp = mSettings.mPermissions.get(permissionName);            if (bp == null) {                throw new IllegalArgumentException("Unknown permission: " + permissionName);            }            checkGrantRevokePermissions(pkg, bp);            final PackageSetting ps = (PackageSetting) pkg.mExtras;            if (ps == null) {                return;            }            final GrantedPermissions gp = (ps.sharedUser != null) ? ps.sharedUser : ps;            if (gp.grantedPermissions.add(permissionName)) {                if (ps.haveGids) {                    gp.gids = appendInts(gp.gids, bp.gids);                }                mSettings.writeLPr();            }        }    }...

Settings.java

View Codefinal class Settings {...private final File mSettingsFilename;...Settings(Context context, File dataDir) {        mContext = context;        mSystemDir = new File(dataDir, "system");        mSystemDir.mkdirs();        FileUtils.setPermissions(mSystemDir.toString(),                FileUtils.S_IRWXU|FileUtils.S_IRWXG                |FileUtils.S_IROTH|FileUtils.S_IXOTH,                -1, -1);        mSettingsFilename = new File(mSystemDir, "packages.xml");        mBackupSettingsFilename = new File(mSystemDir, "packages-backup.xml");        mPackageListFilename = new File(mSystemDir, "packages.list");        FileUtils.setPermissions(mPackageListFilename, 0660, SYSTEM_UID, PACKAGE_INFO_GID);        // Deprecated: Needed for migration        mStoppedPackagesFilename = new File(mSystemDir, "packages-stopped.xml");        mBackupStoppedPackagesFilename = new File(mSystemDir, "packages-stopped-backup.xml");    }... void writeLPr() {        //Debug.startMethodTracing("/data/system/packageprof", 8 * 1024 * 1024);        // Keep the old settings around until we know the new ones have        // been successfully written.        if (mSettingsFilename.exists()) {            // Presence of backup settings file indicates that we failed            // to persist settings earlier. So preserve the older            // backup for future reference since the current settings            // might have been corrupted.            if (!mBackupSettingsFilename.exists()) {                if (!mSettingsFilename.renameTo(mBackupSettingsFilename)) {                    Log.wtf(PackageManagerService.TAG, "Unable to backup package manager settings, "                            + " current changes will be lost at reboot");                    return;                }            } else {                mSettingsFilename.delete();                Slog.w(PackageManagerService.TAG, "Preserving older settings backup");            }        }        mPastSignatures.clear();        try {            FileOutputStream fstr = new FileOutputStream(mSettingsFilename);            BufferedOutputStream str = new BufferedOutputStream(fstr);            //XmlSerializer serializer = XmlUtils.serializerInstance();            XmlSerializer serializer = new FastXmlSerializer();            serializer.setOutput(str, "utf-8");            serializer.startDocument(null, true);            serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);            serializer.startTag(null, "packages");            serializer.startTag(null, "last-platform-version");            serializer.attribute(null, "internal", Integer.toString(mInternalSdkPlatform));            serializer.attribute(null, "external", Integer.toString(mExternalSdkPlatform));            serializer.endTag(null, "last-platform-version");            if (mVerifierDeviceIdentity != null) {                serializer.startTag(null, "verifier");                serializer.attribute(null, "device", mVerifierDeviceIdentity.toString());                serializer.endTag(null, "verifier");            }            if (mReadExternalStorageEnforced != null) {                serializer.startTag(null, TAG_READ_EXTERNAL_STORAGE);                serializer.attribute(                        null, ATTR_ENFORCEMENT, mReadExternalStorageEnforced ? "1" : "0");                serializer.endTag(null, TAG_READ_EXTERNAL_STORAGE);            }            serializer.startTag(null, "permission-trees");            for (BasePermission bp : mPermissionTrees.values()) {                writePermissionLPr(serializer, bp);            }            serializer.endTag(null, "permission-trees");            serializer.startTag(null, "permissions");            for (BasePermission bp : mPermissions.values()) {                writePermissionLPr(serializer, bp);            }            serializer.endTag(null, "permissions");            for (final PackageSetting pkg : mPackages.values()) {                writePackageLPr(serializer, pkg);            }            for (final PackageSetting pkg : mDisabledSysPackages.values()) {                writeDisabledSysPackageLPr(serializer, pkg);            }            for (final SharedUserSetting usr : mSharedUsers.values()) {                serializer.startTag(null, "shared-user");                serializer.attribute(null, ATTR_NAME, usr.name);                serializer.attribute(null, "userId",                        Integer.toString(usr.userId));                usr.signatures.writeXml(serializer, "sigs", mPastSignatures);                serializer.startTag(null, "perms");                for (String name : usr.grantedPermissions) {                    serializer.startTag(null, TAG_ITEM);                    serializer.attribute(null, ATTR_NAME, name);                    serializer.endTag(null, TAG_ITEM);                }                serializer.endTag(null, "perms");                serializer.endTag(null, "shared-user");            }            if (mPackagesToBeCleaned.size() > 0) {                for (PackageCleanItem item : mPackagesToBeCleaned) {                    final String userStr = Integer.toString(item.userId);                    serializer.startTag(null, "cleaning-package");                    serializer.attribute(null, ATTR_NAME, item.packageName);                    serializer.attribute(null, ATTR_CODE, item.andCode ? "true" : "false");                    serializer.attribute(null, ATTR_USER, userStr);                    serializer.endTag(null, "cleaning-package");                }            }                        if (mRenamedPackages.size() > 0) {                for (Map.Entry e : mRenamedPackages.entrySet()) {                    serializer.startTag(null, "renamed-package");                    serializer.attribute(null, "new", e.getKey());                    serializer.attribute(null, "old", e.getValue());                    serializer.endTag(null, "renamed-package");                }            }                        mKeySetManager.writeKeySetManagerLPr(serializer);            serializer.endTag(null, "packages");            serializer.endDocument();            str.flush();            FileUtils.sync(fstr);            str.close();            // New settings successfully written, old ones are no longer            // needed.            mBackupSettingsFilename.delete();            FileUtils.setPermissions(mSettingsFilename.toString(),                    FileUtils.S_IRUSR|FileUtils.S_IWUSR                    |FileUtils.S_IRGRP|FileUtils.S_IWGRP,                    -1, -1);            // Write package list file now, use a JournaledFile.            File tempFile = new File(mPackageListFilename.getAbsolutePath() + ".tmp");            JournaledFile journal = new JournaledFile(mPackageListFilename, tempFile);            final File writeTarget = journal.chooseForWrite();            fstr = new FileOutputStream(writeTarget);            str = new BufferedOutputStream(fstr);            try {                FileUtils.setPermissions(fstr.getFD(), 0660, SYSTEM_UID, PACKAGE_INFO_GID);                StringBuilder sb = new StringBuilder();                for (final PackageSetting pkg : mPackages.values()) {                    if (pkg.pkg == null || pkg.pkg.applicationInfo == null) {                        Slog.w(TAG, "Skipping " + pkg + " due to missing metadata");                        continue;                    }                    final ApplicationInfo ai = pkg.pkg.applicationInfo;                    final String dataPath = ai.dataDir;                    final boolean isDebug = (ai.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;                    final int[] gids = pkg.getGids();                    // Avoid any application that has a space in its path.                    if (dataPath.indexOf("") >= 0)                        continue;                    // we store on each line the following information for now:                    //                    // pkgName    - package name                    // userId     - application-specific user id                    // debugFlag  - 0 or 1 if the package is debuggable.                    // dataPath   - path to package's data path                    // seinfo     - seinfo label for the app (assigned at install time)                    // gids       - supplementary gids this app launches with                    //                    // NOTE: We prefer not to expose all ApplicationInfo flags for now.                    //                    // DO NOT MODIFY THIS FORMAT UNLESS YOU CAN ALSO MODIFY ITS USERS                    // FROM NATIVE CODE. AT THE MOMENT, LOOK AT THE FOLLOWING SOURCES:                    //   system/core/run-as/run-as.c                    //   system/core/sdcard/sdcard.c                    //                    sb.setLength(0);                    sb.append(ai.packageName);                    sb.append("");                    sb.append((int)ai.uid);                    sb.append(isDebug ? " 1 " : " 0 ");                    sb.append(dataPath);                    sb.append("");                    sb.append(ai.seinfo);                    sb.append("");                    if (gids != null && gids.length > 0) {                        sb.append(gids[0]);                        for (int i = 1; i < gids.length; i++) {                            sb.append(",");                            sb.append(gids[i]);                        }                    } else {                        sb.append("none");                    }                    sb.append("\n");                    str.write(sb.toString().getBytes());                }                str.flush();                FileUtils.sync(fstr);                str.close();                journal.commit();            } catch (Exception e) {                Log.wtf(TAG, "Failed to write packages.list", e);                IoUtils.closeQuietly(str);                journal.rollback();            }            writeAllUsersPackageRestrictionsLPr();            return;        } catch(XmlPullParserException e) {            Log.wtf(PackageManagerService.TAG, "Unable to write package manager settings, "                    + "current changes will be lost at reboot", e);        } catch(java.io.IOException e) {            Log.wtf(PackageManagerService.TAG, "Unable to write package manager settings, "                    + "current changes will be lost at reboot", e);        }        // Clean up partially written files        if (mSettingsFilename.exists()) {            if (!mSettingsFilename.delete()) {                Log.wtf(PackageManagerService.TAG, "Failed to clean up mangled file: "                        + mSettingsFilename);            }        }        //Debug.stopMethodTracing();    }...

转载于:https://www.cnblogs.com/fanfeng/p/3575129.html

更多相关文章

  1. android 命令获取手机中项目数据库
  2. gerrit 常用命令记录
  3. Android录屏命令screenrecord命令的使用
  4. Android studio 修改git路径
  5. android emulator 命令详解
  6. android获取CPU参数(命令行方式)

随机推荐

  1. 必读:Spark与kafka010整合
  2. Mapreduce shuffle详解
  3. 【深度学习】⑤--自然语言处理的相关应用
  4. 自动安装nginx脚本
  5. 最强指南!超级全面的企业报表平台建设白皮
  6. Python 内置模块之 random
  7. 【深度学习】③--神经网络细节与训练注意
  8. RHEL7.6安装Oracle11g数据库--4、创建数
  9. 2021年国内BI厂商推荐_大数据分析工具
  10. 程序员职业发展方向有哪些?