1af75948cddd40a0fde5af051b700306744eae64cChristopher Tate/*
2af75948cddd40a0fde5af051b700306744eae64cChristopher Tate * Copyright (C) 2012 The Android Open Source Project
3af75948cddd40a0fde5af051b700306744eae64cChristopher Tate *
4af75948cddd40a0fde5af051b700306744eae64cChristopher Tate * Licensed under the Apache License, Version 2.0 (the "License");
5af75948cddd40a0fde5af051b700306744eae64cChristopher Tate * you may not use this file except in compliance with the License.
6af75948cddd40a0fde5af051b700306744eae64cChristopher Tate * You may obtain a copy of the License at
7af75948cddd40a0fde5af051b700306744eae64cChristopher Tate *
8af75948cddd40a0fde5af051b700306744eae64cChristopher Tate *      http://www.apache.org/licenses/LICENSE-2.0
9af75948cddd40a0fde5af051b700306744eae64cChristopher Tate *
10af75948cddd40a0fde5af051b700306744eae64cChristopher Tate * Unless required by applicable law or agreed to in writing, software
11af75948cddd40a0fde5af051b700306744eae64cChristopher Tate * distributed under the License is distributed on an "AS IS" BASIS,
12af75948cddd40a0fde5af051b700306744eae64cChristopher Tate * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13af75948cddd40a0fde5af051b700306744eae64cChristopher Tate * See the License for the specific language governing permissions and
14af75948cddd40a0fde5af051b700306744eae64cChristopher Tate * limitations under the License.
15af75948cddd40a0fde5af051b700306744eae64cChristopher Tate */
16af75948cddd40a0fde5af051b700306744eae64cChristopher Tate
17af75948cddd40a0fde5af051b700306744eae64cChristopher Tatepackage com.android.commands.settings;
18af75948cddd40a0fde5af051b700306744eae64cChristopher Tate
19af75948cddd40a0fde5af051b700306744eae64cChristopher Tateimport android.app.ActivityManagerNative;
20af75948cddd40a0fde5af051b700306744eae64cChristopher Tateimport android.app.IActivityManager;
21af75948cddd40a0fde5af051b700306744eae64cChristopher Tateimport android.app.IActivityManager.ContentProviderHolder;
22af75948cddd40a0fde5af051b700306744eae64cChristopher Tateimport android.content.IContentProvider;
2314272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackbornimport android.net.Uri;
24af75948cddd40a0fde5af051b700306744eae64cChristopher Tateimport android.os.Binder;
25af75948cddd40a0fde5af051b700306744eae64cChristopher Tateimport android.os.Bundle;
26af75948cddd40a0fde5af051b700306744eae64cChristopher Tateimport android.os.IBinder;
27af75948cddd40a0fde5af051b700306744eae64cChristopher Tateimport android.os.RemoteException;
28af75948cddd40a0fde5af051b700306744eae64cChristopher Tateimport android.os.UserHandle;
29af75948cddd40a0fde5af051b700306744eae64cChristopher Tateimport android.provider.Settings;
30af75948cddd40a0fde5af051b700306744eae64cChristopher Tate
31af75948cddd40a0fde5af051b700306744eae64cChristopher Tatepublic final class SettingsCmd {
32af75948cddd40a0fde5af051b700306744eae64cChristopher Tate    static final String TAG = "settings";
33af75948cddd40a0fde5af051b700306744eae64cChristopher Tate
34af75948cddd40a0fde5af051b700306744eae64cChristopher Tate    enum CommandVerb {
35af75948cddd40a0fde5af051b700306744eae64cChristopher Tate        UNSPECIFIED,
36af75948cddd40a0fde5af051b700306744eae64cChristopher Tate        GET,
3714272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn        PUT,
3814272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn        DELETE
39af75948cddd40a0fde5af051b700306744eae64cChristopher Tate    }
40af75948cddd40a0fde5af051b700306744eae64cChristopher Tate
41af75948cddd40a0fde5af051b700306744eae64cChristopher Tate    static String[] mArgs;
42af75948cddd40a0fde5af051b700306744eae64cChristopher Tate    int mNextArg;
43af75948cddd40a0fde5af051b700306744eae64cChristopher Tate    int mUser = -1;     // unspecified
44af75948cddd40a0fde5af051b700306744eae64cChristopher Tate    CommandVerb mVerb = CommandVerb.UNSPECIFIED;
45af75948cddd40a0fde5af051b700306744eae64cChristopher Tate    String mTable = null;
46af75948cddd40a0fde5af051b700306744eae64cChristopher Tate    String mKey = null;
47af75948cddd40a0fde5af051b700306744eae64cChristopher Tate    String mValue = null;
48af75948cddd40a0fde5af051b700306744eae64cChristopher Tate
49af75948cddd40a0fde5af051b700306744eae64cChristopher Tate    public static void main(String[] args) {
50af75948cddd40a0fde5af051b700306744eae64cChristopher Tate        if (args == null || args.length < 3) {
51af75948cddd40a0fde5af051b700306744eae64cChristopher Tate            printUsage();
52af75948cddd40a0fde5af051b700306744eae64cChristopher Tate            return;
53af75948cddd40a0fde5af051b700306744eae64cChristopher Tate        }
54af75948cddd40a0fde5af051b700306744eae64cChristopher Tate
55af75948cddd40a0fde5af051b700306744eae64cChristopher Tate        mArgs = args;
56af75948cddd40a0fde5af051b700306744eae64cChristopher Tate        try {
57af75948cddd40a0fde5af051b700306744eae64cChristopher Tate            new SettingsCmd().run();
58af75948cddd40a0fde5af051b700306744eae64cChristopher Tate        } catch (Exception e) {
59af75948cddd40a0fde5af051b700306744eae64cChristopher Tate            System.err.println("Unable to run settings command");
60af75948cddd40a0fde5af051b700306744eae64cChristopher Tate        }
61af75948cddd40a0fde5af051b700306744eae64cChristopher Tate    }
62af75948cddd40a0fde5af051b700306744eae64cChristopher Tate
63af75948cddd40a0fde5af051b700306744eae64cChristopher Tate    public void run() {
64af75948cddd40a0fde5af051b700306744eae64cChristopher Tate        boolean valid = false;
65af75948cddd40a0fde5af051b700306744eae64cChristopher Tate        String arg;
66af75948cddd40a0fde5af051b700306744eae64cChristopher Tate        try {
67af75948cddd40a0fde5af051b700306744eae64cChristopher Tate            while ((arg = nextArg()) != null) {
68af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                if ("--user".equals(arg)) {
69af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                    if (mUser != -1) {
70af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                        // --user specified more than once; invalid
71af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                        break;
72af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                    }
73af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                    mUser = Integer.parseInt(nextArg());
74af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                } else if (mVerb == CommandVerb.UNSPECIFIED) {
75af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                    if ("get".equalsIgnoreCase(arg)) {
76af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                        mVerb = CommandVerb.GET;
77af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                    } else if ("put".equalsIgnoreCase(arg)) {
78af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                        mVerb = CommandVerb.PUT;
7914272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn                    } else if ("delete".equalsIgnoreCase(arg)) {
8014272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn                        mVerb = CommandVerb.DELETE;
81af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                    } else {
82af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                        // invalid
83af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                        System.err.println("Invalid command: " + arg);
84af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                        break;
85af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                    }
86af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                } else if (mTable == null) {
87af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                    if (!"system".equalsIgnoreCase(arg)
88af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                            && !"secure".equalsIgnoreCase(arg)
89af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                            && !"global".equalsIgnoreCase(arg)) {
90af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                        System.err.println("Invalid namespace '" + arg + "'");
91af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                        break;  // invalid
92af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                    }
93af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                    mTable = arg.toLowerCase();
9414272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn                } else if (mVerb == CommandVerb.GET || mVerb == CommandVerb.DELETE) {
95af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                    mKey = arg;
96af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                    if (mNextArg >= mArgs.length) {
97af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                        valid = true;
98af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                    } else {
99af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                        System.err.println("Too many arguments");
100af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                    }
101af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                    break;
102af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                } else if (mKey == null) {
103af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                    mKey = arg;
104af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                    // keep going; there's another PUT arg
105af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                } else {    // PUT, final arg
106af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                    mValue = arg;
107af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                    if (mNextArg >= mArgs.length) {
108af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                        valid = true;
109af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                    } else {
110af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                        System.err.println("Too many arguments");
111af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                    }
112af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                    break;
113af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                }
114af75948cddd40a0fde5af051b700306744eae64cChristopher Tate            }
115af75948cddd40a0fde5af051b700306744eae64cChristopher Tate        } catch (Exception e) {
116af75948cddd40a0fde5af051b700306744eae64cChristopher Tate            valid = false;
117af75948cddd40a0fde5af051b700306744eae64cChristopher Tate        }
118af75948cddd40a0fde5af051b700306744eae64cChristopher Tate
119af75948cddd40a0fde5af051b700306744eae64cChristopher Tate        if (valid) {
120af75948cddd40a0fde5af051b700306744eae64cChristopher Tate            if (mUser < 0) {
121af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                mUser = UserHandle.USER_OWNER;
122af75948cddd40a0fde5af051b700306744eae64cChristopher Tate            }
123af75948cddd40a0fde5af051b700306744eae64cChristopher Tate
124af75948cddd40a0fde5af051b700306744eae64cChristopher Tate            try {
125af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                IActivityManager activityManager = ActivityManagerNative.getDefault();
126af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                IContentProvider provider = null;
127af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                IBinder token = new Binder();
128af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                try {
129af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                    ContentProviderHolder holder = activityManager.getContentProviderExternal(
130af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                            "settings", UserHandle.USER_OWNER, token);
131af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                    if (holder == null) {
132af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                        throw new IllegalStateException("Could not find settings provider");
133af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                    }
134af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                    provider = holder.provider;
135af75948cddd40a0fde5af051b700306744eae64cChristopher Tate
136af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                    switch (mVerb) {
137af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                        case GET:
138af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                            System.out.println(getForUser(provider, mUser, mTable, mKey));
139af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                            break;
140af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                        case PUT:
141af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                            putForUser(provider, mUser, mTable, mKey, mValue);
142af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                            break;
14314272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn                        case DELETE:
14414272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn                            System.out.println("Deleted "
14514272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn                                    + deleteForUser(provider, mUser, mTable, mKey) + " rows");
14614272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn                            break;
147af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                        default:
148af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                            System.err.println("Unspecified command");
149af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                            break;
150af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                    }
151af75948cddd40a0fde5af051b700306744eae64cChristopher Tate
152af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                } finally {
153af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                    if (provider != null) {
154af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                        activityManager.removeContentProviderExternal("settings", token);
155af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                    }
156af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                }
157af75948cddd40a0fde5af051b700306744eae64cChristopher Tate            } catch (Exception e) {
158af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                System.err.println("Error while accessing settings provider");
159af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                e.printStackTrace();
160af75948cddd40a0fde5af051b700306744eae64cChristopher Tate            }
161af75948cddd40a0fde5af051b700306744eae64cChristopher Tate
162af75948cddd40a0fde5af051b700306744eae64cChristopher Tate        } else {
163af75948cddd40a0fde5af051b700306744eae64cChristopher Tate            printUsage();
164af75948cddd40a0fde5af051b700306744eae64cChristopher Tate        }
165af75948cddd40a0fde5af051b700306744eae64cChristopher Tate    }
166af75948cddd40a0fde5af051b700306744eae64cChristopher Tate
167af75948cddd40a0fde5af051b700306744eae64cChristopher Tate    private String nextArg() {
168af75948cddd40a0fde5af051b700306744eae64cChristopher Tate        if (mNextArg >= mArgs.length) {
169af75948cddd40a0fde5af051b700306744eae64cChristopher Tate            return null;
170af75948cddd40a0fde5af051b700306744eae64cChristopher Tate        }
171af75948cddd40a0fde5af051b700306744eae64cChristopher Tate        String arg = mArgs[mNextArg];
172af75948cddd40a0fde5af051b700306744eae64cChristopher Tate        mNextArg++;
173af75948cddd40a0fde5af051b700306744eae64cChristopher Tate        return arg;
174af75948cddd40a0fde5af051b700306744eae64cChristopher Tate    }
175af75948cddd40a0fde5af051b700306744eae64cChristopher Tate
176af75948cddd40a0fde5af051b700306744eae64cChristopher Tate    String getForUser(IContentProvider provider, int userHandle,
177af75948cddd40a0fde5af051b700306744eae64cChristopher Tate            final String table, final String key) {
178af75948cddd40a0fde5af051b700306744eae64cChristopher Tate        final String callGetCommand;
179af75948cddd40a0fde5af051b700306744eae64cChristopher Tate        if ("system".equals(table)) callGetCommand = Settings.CALL_METHOD_GET_SYSTEM;
180af75948cddd40a0fde5af051b700306744eae64cChristopher Tate        else if ("secure".equals(table)) callGetCommand = Settings.CALL_METHOD_GET_SECURE;
181af75948cddd40a0fde5af051b700306744eae64cChristopher Tate        else if ("global".equals(table)) callGetCommand = Settings.CALL_METHOD_GET_GLOBAL;
182af75948cddd40a0fde5af051b700306744eae64cChristopher Tate        else {
183af75948cddd40a0fde5af051b700306744eae64cChristopher Tate            System.err.println("Invalid table; no put performed");
184af75948cddd40a0fde5af051b700306744eae64cChristopher Tate            throw new IllegalArgumentException("Invalid table " + table);
185af75948cddd40a0fde5af051b700306744eae64cChristopher Tate        }
186af75948cddd40a0fde5af051b700306744eae64cChristopher Tate
187af75948cddd40a0fde5af051b700306744eae64cChristopher Tate        String result = null;
188af75948cddd40a0fde5af051b700306744eae64cChristopher Tate        try {
189af75948cddd40a0fde5af051b700306744eae64cChristopher Tate            Bundle arg = new Bundle();
190af75948cddd40a0fde5af051b700306744eae64cChristopher Tate            arg.putInt(Settings.CALL_METHOD_USER_KEY, userHandle);
19135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn            Bundle b = provider.call(null, callGetCommand, key, arg);
192af75948cddd40a0fde5af051b700306744eae64cChristopher Tate            if (b != null) {
193af75948cddd40a0fde5af051b700306744eae64cChristopher Tate                result = b.getPairValue();
194af75948cddd40a0fde5af051b700306744eae64cChristopher Tate            }
195af75948cddd40a0fde5af051b700306744eae64cChristopher Tate        } catch (RemoteException e) {
196af75948cddd40a0fde5af051b700306744eae64cChristopher Tate            System.err.println("Can't read key " + key + " in " + table + " for user " + userHandle);
197af75948cddd40a0fde5af051b700306744eae64cChristopher Tate        }
198af75948cddd40a0fde5af051b700306744eae64cChristopher Tate        return result;
199af75948cddd40a0fde5af051b700306744eae64cChristopher Tate    }
200af75948cddd40a0fde5af051b700306744eae64cChristopher Tate
201af75948cddd40a0fde5af051b700306744eae64cChristopher Tate    void putForUser(IContentProvider provider, int userHandle,
202af75948cddd40a0fde5af051b700306744eae64cChristopher Tate            final String table, final String key, final String value) {
203af75948cddd40a0fde5af051b700306744eae64cChristopher Tate        final String callPutCommand;
204af75948cddd40a0fde5af051b700306744eae64cChristopher Tate        if ("system".equals(table)) callPutCommand = Settings.CALL_METHOD_PUT_SYSTEM;
205af75948cddd40a0fde5af051b700306744eae64cChristopher Tate        else if ("secure".equals(table)) callPutCommand = Settings.CALL_METHOD_PUT_SECURE;
206af75948cddd40a0fde5af051b700306744eae64cChristopher Tate        else if ("global".equals(table)) callPutCommand = Settings.CALL_METHOD_PUT_GLOBAL;
207af75948cddd40a0fde5af051b700306744eae64cChristopher Tate        else {
208af75948cddd40a0fde5af051b700306744eae64cChristopher Tate            System.err.println("Invalid table; no put performed");
209af75948cddd40a0fde5af051b700306744eae64cChristopher Tate            return;
210af75948cddd40a0fde5af051b700306744eae64cChristopher Tate        }
211af75948cddd40a0fde5af051b700306744eae64cChristopher Tate
212af75948cddd40a0fde5af051b700306744eae64cChristopher Tate        try {
213af75948cddd40a0fde5af051b700306744eae64cChristopher Tate            Bundle arg = new Bundle();
214af75948cddd40a0fde5af051b700306744eae64cChristopher Tate            arg.putString(Settings.NameValueTable.VALUE, value);
215af75948cddd40a0fde5af051b700306744eae64cChristopher Tate            arg.putInt(Settings.CALL_METHOD_USER_KEY, userHandle);
21635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn            provider.call(null, callPutCommand, key, arg);
217af75948cddd40a0fde5af051b700306744eae64cChristopher Tate        } catch (RemoteException e) {
218af75948cddd40a0fde5af051b700306744eae64cChristopher Tate            System.err.println("Can't set key " + key + " in " + table + " for user " + userHandle);
219af75948cddd40a0fde5af051b700306744eae64cChristopher Tate        }
220af75948cddd40a0fde5af051b700306744eae64cChristopher Tate    }
221af75948cddd40a0fde5af051b700306744eae64cChristopher Tate
22214272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn    int deleteForUser(IContentProvider provider, int userHandle,
22314272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn            final String table, final String key) {
22414272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn        Uri targetUri;
22514272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn        if ("system".equals(table)) targetUri = Settings.System.getUriFor(key);
22614272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn        else if ("secure".equals(table)) targetUri = Settings.Secure.getUriFor(key);
22714272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn        else if ("global".equals(table)) targetUri = Settings.Global.getUriFor(key);
22814272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn        else {
22914272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn            System.err.println("Invalid table; no delete performed");
23014272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn            throw new IllegalArgumentException("Invalid table " + table);
23114272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn        }
23214272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn
23314272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn        int num = 0;
23414272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn        try {
23514272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn            num = provider.delete(null, targetUri, null, null);
23614272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn        } catch (RemoteException e) {
23714272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn            System.err.println("Can't clear key " + key + " in " + table + " for user "
23814272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn                    + userHandle);
23914272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn        }
24014272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn        return num;
24114272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn    }
24214272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn
243af75948cddd40a0fde5af051b700306744eae64cChristopher Tate    private static void printUsage() {
244af75948cddd40a0fde5af051b700306744eae64cChristopher Tate        System.err.println("usage:  settings [--user NUM] get namespace key");
245af75948cddd40a0fde5af051b700306744eae64cChristopher Tate        System.err.println("        settings [--user NUM] put namespace key value");
24614272302a8b635bd8e9267c1411d0a7ef11bff45Dianne Hackborn        System.err.println("        settings [--user NUM] delete namespace key");
247af75948cddd40a0fde5af051b700306744eae64cChristopher Tate        System.err.println("\n'namespace' is one of {system, secure, global}, case-insensitive");
248af75948cddd40a0fde5af051b700306744eae64cChristopher Tate        System.err.println("If '--user NUM' is not given, the operations are performed on the owner user.");
249af75948cddd40a0fde5af051b700306744eae64cChristopher Tate    }
250af75948cddd40a0fde5af051b700306744eae64cChristopher Tate}
251