Settings指令分析

1, 概述

Settings指令也是和ContentProvider进行交互,对系统的数据库属性值进行查询、删除和修改。

2, Settings详细流程

  SettingsCmd的main方法如下,

public static void main(String[] args) {
        if (args == null || args.length < 2) {
            printUsage();
            return;
        }

        mArgs = args;
        try {
            new SettingsCmd().run();
        } catch (Exception e) {
            System.err.println("Unable to run settings command");
        }
    } 

直接调用run方法,方法如下,

public void run() {
        boolean valid = false;
        String arg;
        try {
            while ((arg = nextArg()) != null) {
                if ("--user".equals(arg)) {
                    if (mUser != -1) {
                        // --user specified more than once; invalid
                        break;
                    }
                    mUser = Integer.parseInt(nextArg());
                } else if (mVerb == CommandVerb.UNSPECIFIED) {
                    if ("get".equalsIgnoreCase(arg)) {
                        mVerb = CommandVerb.GET;
                    } else if ("put".equalsIgnoreCase(arg)) {
                        mVerb = CommandVerb.PUT;
                    } else if ("delete".equalsIgnoreCase(arg)) {
                        mVerb = CommandVerb.DELETE;
                    } else if ("list".equalsIgnoreCase(arg)) {
                        mVerb = CommandVerb.LIST;
                    } else {
                        // invalid
                        System.err.println("Invalid command: " + arg);
                        break;
                    }
                } else if (mTable == null) {
                    if (!"system".equalsIgnoreCase(arg)
                            && !"secure".equalsIgnoreCase(arg)
                            && !"global".equalsIgnoreCase(arg)) {
                        System.err.println("Invalid namespace '" + arg + "'");
                        break;  // invalid
                    }
                    mTable = arg.toLowerCase();
                    if (mVerb == CommandVerb.LIST) {
                        valid = true;
                        break;
                    }
                } else if (mVerb == CommandVerb.GET || mVerb == CommandVerb.DELETE) {
                    mKey = arg;
                    if (mNextArg >= mArgs.length) {
                        valid = true;
                    } else {
                        System.err.println("Too many arguments");
                    }
                    break;
                } else if (mKey == null) {
                    mKey = arg;
                    // keep going; there's another PUT arg
                } else {    // PUT, final arg
                    mValue = arg;
                    if (mNextArg >= mArgs.length) {
                        valid = true;
                    } else {
                        System.err.println("Too many arguments");
                    }
                    break;
                }
            }
        } catch (Exception e) {
            valid = false;
        }

        if (valid) {
            if (mUser < 0) {
                mUser = UserHandle.USER_OWNER;
            }

            try {
                IActivityManager activityManager = ActivityManagerNative.getDefault();
                IContentProvider provider = null;
                IBinder token = new Binder();
                try {
                    ContentProviderHolder holder = activityManager.getContentProviderExternal(
                            "settings", UserHandle.USER_OWNER, token);
                    if (holder == null) {
                        throw new IllegalStateException("Could not find settings provider");
                    }
                    provider = holder.provider;

                    switch (mVerb) {
                        case GET:
                            System.out.println(getForUser(provider, mUser, mTable, mKey));
                            break;
                        case PUT:
                            putForUser(provider, mUser, mTable, mKey, mValue);
                            break;
                        case DELETE:
                            System.out.println("Deleted "
                                    + deleteForUser(provider, mUser, mTable, mKey) + " rows");
                            break;
                        case LIST:
                            for (String line : listForUser(provider, mUser, mTable)) {
                                System.out.println(line);
                            }
                            break;
                        default:
                            System.err.println("Unspecified command");
                            break;
                    }

                } finally {
                    if (provider != null) {
                        activityManager.removeContentProviderExternal("settings", token);
                    }
                }
            } catch (Exception e) {
                System.err.println("Error while accessing settings provider");
                e.printStackTrace();
            }

        } else {
            printUsage();
        }
    } 

如果是put指令,则会调用putForUser方法

void putForUser(IContentProvider provider, int userHandle,
            final String table, final String key, final String value) {
        final String callPutCommand;
        if ("system".equals(table)) callPutCommand = Settings.CALL_METHOD_PUT_SYSTEM;
        else if ("secure".equals(table)) callPutCommand = Settings.CALL_METHOD_PUT_SECURE;
        else if ("global".equals(table)) callPutCommand = Settings.CALL_METHOD_PUT_GLOBAL;
        else {
            System.err.println("Invalid table; no put performed");
            return;
        }

        try {
            Bundle arg = new Bundle();
            arg.putString(Settings.NameValueTable.VALUE, value);
            arg.putInt(Settings.CALL_METHOD_USER_KEY, userHandle);
            provider.call(resolveCallingPackage(), callPutCommand, key, arg);
        } catch (RemoteException e) {
            System.err.println("Can't set key " + key + " in " + table + " for user " + userHandle);
        }
    }  

如果是get指令,则会调用getForUser方法,

String getForUser(IContentProvider provider, int userHandle,
            final String table, final String key) {
        final String callGetCommand;
        if ("system".equals(table)) callGetCommand = Settings.CALL_METHOD_GET_SYSTEM;
        else if ("secure".equals(table)) callGetCommand = Settings.CALL_METHOD_GET_SECURE;
        else if ("global".equals(table)) callGetCommand = Settings.CALL_METHOD_GET_GLOBAL;
        else {
            System.err.println("Invalid table; no put performed");
            throw new IllegalArgumentException("Invalid table " + table);
        }

        String result = null;
        try {
            Bundle arg = new Bundle();
            arg.putInt(Settings.CALL_METHOD_USER_KEY, userHandle);
            Bundle b = provider.call(resolveCallingPackage(), callGetCommand, key, arg);
            if (b != null) {
                result = b.getPairValue();
            }
        } catch (RemoteException e) {
            System.err.println("Can't read key " + key + " in " + table + " for user " + userHandle);
        }
        return result;
    }

如果是delete指令,则会调用deleteForUser方法,

int deleteForUser(IContentProvider provider, int userHandle,
            final String table, final String key) {
        Uri targetUri;
        if ("system".equals(table)) targetUri = Settings.System.getUriFor(key);
        else if ("secure".equals(table)) targetUri = Settings.Secure.getUriFor(key);
        else if ("global".equals(table)) targetUri = Settings.Global.getUriFor(key);
        else {
            System.err.println("Invalid table; no delete performed");
            throw new IllegalArgumentException("Invalid table " + table);
        }

        int num = 0;
        try {
            num = provider.delete(resolveCallingPackage(), targetUri, null, null);
        } catch (RemoteException e) {
            System.err.println("Can't clear key " + key + " in " + table + " for user "
                    + userHandle);
        }
        return num;
    }

如果是list指令,则会调用listForUser方法

private List<String> listForUser(IContentProvider provider, int userHandle, String table) {
        final Uri uri = "system".equals(table) ? Settings.System.CONTENT_URI
                : "secure".equals(table) ? Settings.Secure.CONTENT_URI
                : "global".equals(table) ? Settings.Global.CONTENT_URI
                : null;
        final ArrayList<String> lines = new ArrayList<String>();
        if (uri == null) {
            return lines;
        }
        try {
            final Cursor cursor = provider.query(resolveCallingPackage(), uri, null, null, null,
                    null, null);
            try {
                while (cursor != null && cursor.moveToNext()) {
                    lines.add(cursor.getString(1) + "=" + cursor.getString(2));
                }
            } finally {
                if (cursor != null) {
                    cursor.close();
                }
            }
            Collections.sort(lines);
        } catch (RemoteException e) {
            System.err.println("List failed in " + table + " for user " + userHandle);
        }
        return lines;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值