125872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov/* 225872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov** Copyright 2012, The Android Open Source Project 325872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov** 425872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov** Licensed under the Apache License, Version 2.0 (the "License"); 525872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov** you may not use this file except in compliance with the License. 625872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov** You may obtain a copy of the License at 725872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov** 825872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov** http://www.apache.org/licenses/LICENSE-2.0 925872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov** 1025872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov** Unless required by applicable law or agreed to in writing, software 1125872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov** distributed under the License is distributed on an "AS IS" BASIS, 1225872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1325872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov** See the License for the specific language governing permissions and 1425872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov** limitations under the License. 1525872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov*/ 1625872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov 1725872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganovpackage com.android.commands.content; 1825872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov 1925872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganovimport android.app.ActivityManagerNative; 2025872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganovimport android.app.IActivityManager; 2125872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganovimport android.app.IActivityManager.ContentProviderHolder; 2225872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganovimport android.content.ContentValues; 2325872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganovimport android.content.IContentProvider; 2425872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganovimport android.database.Cursor; 2525872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganovimport android.net.Uri; 2625872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganovimport android.os.Binder; 2725872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganovimport android.os.IBinder; 286d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkeyimport android.os.UserHandle; 2925872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganovimport android.text.TextUtils; 3025872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov 3125872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov/** 3225872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov * This class is a command line utility for manipulating content. A client 3325872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov * can insert, update, and remove records in a content provider. For example, 3425872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov * some settings may be configured before running the CTS tests, etc. 3525872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov * <p> 3625872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov * Examples: 3725872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov * <ul> 3825872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov * <li> 3925872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov * # Add "new_setting" secure setting with value "new_value".</br> 4025872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov * adb shell content insert --uri content://settings/secure --bind name:s:new_setting 4125872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov * --bind value:s:new_value 4225872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov * </li> 4325872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov * <li> 4425872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov * # Change "new_setting" secure setting to "newer_value" (You have to escape single quotes in 4525872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov * the where clause).</br> 4625872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov * adb shell content update --uri content://settings/secure --bind value:s:newer_value 4725872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov * --where "name=\'new_setting\'" 4825872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov * </li> 4925872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov * <li> 5025872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov * # Remove "new_setting" secure setting.</br> 5125872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov * adb shell content delete --uri content://settings/secure --where "name=\'new_setting\'" 5225872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov * </li> 5325872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov * <li> 5425872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov * # Query \"name\" and \"value\" columns from secure settings where \"name\" is equal to" 5525872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov * \"new_setting\" and sort the result by name in ascending order.\n" 5625872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov * adb shell content query --uri content://settings/secure --projection name:value 5725872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov * --where "name=\'new_setting\'" --sort \"name ASC\" 5825872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov * </li> 5925872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov * </ul> 6025872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov * </p> 6125872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov */ 6225872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganovpublic class Content { 6325872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov 6425872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov private static final String USAGE = 6525872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov "usage: adb shell content [subcommand] [options]\n" 6625872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov + "\n" 676d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey + "usage: adb shell content insert --uri <URI> [--user <USER_ID>]" 686d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey + " --bind <BINDING> [--bind <BINDING>...]\n" 6925872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov + " <URI> a content provider URI.\n" 7025872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov + " <BINDING> binds a typed value to a column and is formatted:\n" 7125872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov + " <COLUMN_NAME>:<TYPE>:<COLUMN_VALUE> where:\n" 7225872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov + " <TYPE> specifies data type such as:\n" 7325872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov + " b - boolean, s - string, i - integer, l - long, f - float, d - double\n" 748486bc11baa717390796f2ebd55c7b2ae9294bb7Svetoslav Ganov + " Note: Omit the value for passing an empty string, e.g column:s:\n" 7525872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov + " Example:\n" 7625872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov + " # Add \"new_setting\" secure setting with value \"new_value\".\n" 7725872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov + " adb shell content insert --uri content://settings/secure --bind name:s:new_setting" 7825872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov + " --bind value:s:new_value\n" 7925872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov + "\n" 806d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey + "usage: adb shell content update --uri <URI> [--user <USER_ID>] [--where <WHERE>]\n" 8125872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov + " <WHERE> is a SQL style where clause in quotes (You have to escape single quotes" 8225872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov + " - see example below).\n" 8325872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov + " Example:\n" 8425872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov + " # Change \"new_setting\" secure setting to \"newer_value\".\n" 8525872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov + " adb shell content update --uri content://settings/secure --bind" 8625872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov + " value:s:newer_value --where \"name=\'new_setting\'\"\n" 8725872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov + "\n" 886d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey + "usage: adb shell content delete --uri <URI> [--user <USER_ID>] --bind <BINDING>" 8925872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov + " [--bind <BINDING>...] [--where <WHERE>]\n" 9025872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov + " Example:\n" 9125872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov + " # Remove \"new_setting\" secure setting.\n" 9225872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov + " adb shell content delete --uri content://settings/secure " 9325872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov + "--where \"name=\'new_setting\'\"\n" 9425872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov + "\n" 956d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey + "usage: adb shell content query --uri <URI> [--user <USER_ID>]" 966d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey + " [--projection <PROJECTION>] [--where <WHERE>] [--sort <SORT_ORDER>]\n" 9725872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov + " <PROJECTION> is a list of colon separated column names and is formatted:\n" 9825872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov + " <COLUMN_NAME>[:<COLUMN_NAME>...]\n" 9925872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov + " <SORT_OREDER> is the order in which rows in the result should be sorted.\n" 10025872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov + " Example:\n" 10125872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov + " # Select \"name\" and \"value\" columns from secure settings where \"name\" is " 10225872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov + "equal to \"new_setting\" and sort the result by name in ascending order.\n" 10325872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov + " adb shell content query --uri content://settings/secure --projection name:value" 10425872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov + " --where \"name=\'new_setting\'\" --sort \"name ASC\"\n" 10525872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov + "\n"; 10625872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov 10725872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov private static class Parser { 10825872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov private static final String ARGUMENT_INSERT = "insert"; 10925872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov private static final String ARGUMENT_DELETE = "delete"; 11025872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov private static final String ARGUMENT_UPDATE = "update"; 11125872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov private static final String ARGUMENT_QUERY = "query"; 11225872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov private static final String ARGUMENT_WHERE = "--where"; 11325872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov private static final String ARGUMENT_BIND = "--bind"; 11425872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov private static final String ARGUMENT_URI = "--uri"; 1156d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey private static final String ARGUMENT_USER = "--user"; 11625872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov private static final String ARGUMENT_PROJECTION = "--projection"; 11725872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov private static final String ARGUMENT_SORT = "--sort"; 11825872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov private static final String TYPE_BOOLEAN = "b"; 11925872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov private static final String TYPE_STRING = "s"; 12025872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov private static final String TYPE_INTEGER = "i"; 12125872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov private static final String TYPE_LONG = "l"; 12225872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov private static final String TYPE_FLOAT = "f"; 12325872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov private static final String TYPE_DOUBLE = "d"; 12425872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov private static final String COLON = ":"; 12525872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov private static final String ARGUMENT_PREFIX = "--"; 12625872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov 12725872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov private final Tokenizer mTokenizer; 12825872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov 12925872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov public Parser(String[] args) { 13025872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov mTokenizer = new Tokenizer(args); 13125872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 13225872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov 13325872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov public Command parseCommand() { 13425872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov try { 13525872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov String operation = mTokenizer.nextArg(); 13625872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov if (ARGUMENT_INSERT.equals(operation)) { 13725872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov return parseInsertCommand(); 13825872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } else if (ARGUMENT_DELETE.equals(operation)) { 13925872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov return parseDeleteCommand(); 14025872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } else if (ARGUMENT_UPDATE.equals(operation)) { 14125872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov return parseUpdateCommand(); 14225872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } else if (ARGUMENT_QUERY.equals(operation)) { 14325872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov return parseQueryCommand(); 14425872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } else { 14525872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov throw new IllegalArgumentException("Unsupported operation: " + operation); 14625872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 14725872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } catch (IllegalArgumentException iae) { 14825872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov System.out.println(USAGE); 14925872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov System.out.println("[ERROR] " + iae.getMessage()); 15025872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov return null; 15125872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 15225872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 15325872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov 15425872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov private InsertCommand parseInsertCommand() { 15525872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov Uri uri = null; 1566d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey int userId = UserHandle.USER_OWNER; 15725872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov ContentValues values = new ContentValues(); 15825872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov for (String argument; (argument = mTokenizer.nextArg()) != null;) { 15925872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov if (ARGUMENT_URI.equals(argument)) { 16025872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov uri = Uri.parse(argumentValueRequired(argument)); 1616d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey } else if (ARGUMENT_USER.equals(argument)) { 1626d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey userId = Integer.parseInt(argumentValueRequired(argument)); 16325872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } else if (ARGUMENT_BIND.equals(argument)) { 16425872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov parseBindValue(values); 16525872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } else { 16625872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov throw new IllegalArgumentException("Unsupported argument: " + argument); 16725872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 16825872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 16925872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov if (uri == null) { 17025872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov throw new IllegalArgumentException("Content provider URI not specified." 17125872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov + " Did you specify --uri argument?"); 17225872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 17325872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov if (values.size() == 0) { 17425872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov throw new IllegalArgumentException("Bindings not specified." 17525872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov + " Did you specify --bind argument(s)?"); 17625872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 1776d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey return new InsertCommand(uri, userId, values); 17825872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 17925872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov 18025872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov private DeleteCommand parseDeleteCommand() { 18125872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov Uri uri = null; 1826d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey int userId = UserHandle.USER_OWNER; 18325872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov String where = null; 18425872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov for (String argument; (argument = mTokenizer.nextArg())!= null;) { 18525872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov if (ARGUMENT_URI.equals(argument)) { 18625872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov uri = Uri.parse(argumentValueRequired(argument)); 1876d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey } else if (ARGUMENT_USER.equals(argument)) { 1886d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey userId = Integer.parseInt(argumentValueRequired(argument)); 18925872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } else if (ARGUMENT_WHERE.equals(argument)) { 19025872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov where = argumentValueRequired(argument); 19125872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } else { 19225872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov throw new IllegalArgumentException("Unsupported argument: " + argument); 19325872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 19425872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 19525872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov if (uri == null) { 19625872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov throw new IllegalArgumentException("Content provider URI not specified." 19725872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov + " Did you specify --uri argument?"); 19825872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 1996d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey return new DeleteCommand(uri, userId, where); 20025872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 20125872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov 20225872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov private UpdateCommand parseUpdateCommand() { 20325872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov Uri uri = null; 2046d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey int userId = UserHandle.USER_OWNER; 20525872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov String where = null; 20625872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov ContentValues values = new ContentValues(); 20725872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov for (String argument; (argument = mTokenizer.nextArg())!= null;) { 20825872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov if (ARGUMENT_URI.equals(argument)) { 20925872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov uri = Uri.parse(argumentValueRequired(argument)); 2106d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey } else if (ARGUMENT_USER.equals(argument)) { 2116d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey userId = Integer.parseInt(argumentValueRequired(argument)); 21225872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } else if (ARGUMENT_WHERE.equals(argument)) { 21325872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov where = argumentValueRequired(argument); 21425872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } else if (ARGUMENT_BIND.equals(argument)) { 21525872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov parseBindValue(values); 21625872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } else { 21725872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov throw new IllegalArgumentException("Unsupported argument: " + argument); 21825872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 21925872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 22025872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov if (uri == null) { 22125872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov throw new IllegalArgumentException("Content provider URI not specified." 22225872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov + " Did you specify --uri argument?"); 22325872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 22425872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov if (values.size() == 0) { 22525872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov throw new IllegalArgumentException("Bindings not specified." 22625872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov + " Did you specify --bind argument(s)?"); 22725872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 2286d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey return new UpdateCommand(uri, userId, values, where); 22925872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 23025872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov 23125872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov public QueryCommand parseQueryCommand() { 23225872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov Uri uri = null; 2336d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey int userId = UserHandle.USER_OWNER; 23425872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov String[] projection = null; 23525872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov String sort = null; 23625872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov String where = null; 23725872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov for (String argument; (argument = mTokenizer.nextArg())!= null;) { 23825872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov if (ARGUMENT_URI.equals(argument)) { 23925872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov uri = Uri.parse(argumentValueRequired(argument)); 2406d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey } else if (ARGUMENT_USER.equals(argument)) { 2416d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey userId = Integer.parseInt(argumentValueRequired(argument)); 24225872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } else if (ARGUMENT_WHERE.equals(argument)) { 24325872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov where = argumentValueRequired(argument); 24425872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } else if (ARGUMENT_SORT.equals(argument)) { 24525872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov sort = argumentValueRequired(argument); 24625872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } else if (ARGUMENT_PROJECTION.equals(argument)) { 24725872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov projection = argumentValueRequired(argument).split("[\\s]*:[\\s]*"); 24825872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } else { 24925872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov throw new IllegalArgumentException("Unsupported argument: " + argument); 25025872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 25125872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 25225872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov if (uri == null) { 25325872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov throw new IllegalArgumentException("Content provider URI not specified." 25425872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov + " Did you specify --uri argument?"); 25525872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 2566d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey return new QueryCommand(uri, userId, projection, where, sort); 25725872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 25825872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov 25925872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov private void parseBindValue(ContentValues values) { 26025872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov String argument = mTokenizer.nextArg(); 26125872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov if (TextUtils.isEmpty(argument)) { 26225872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov throw new IllegalArgumentException("Binding not well formed: " + argument); 26325872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 2648486bc11baa717390796f2ebd55c7b2ae9294bb7Svetoslav Ganov final int firstColonIndex = argument.indexOf(COLON); 2658486bc11baa717390796f2ebd55c7b2ae9294bb7Svetoslav Ganov if (firstColonIndex < 0) { 26625872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov throw new IllegalArgumentException("Binding not well formed: " + argument); 26725872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 2688486bc11baa717390796f2ebd55c7b2ae9294bb7Svetoslav Ganov final int secondColonIndex = argument.indexOf(COLON, firstColonIndex + 1); 2698486bc11baa717390796f2ebd55c7b2ae9294bb7Svetoslav Ganov if (secondColonIndex < 0) { 2708486bc11baa717390796f2ebd55c7b2ae9294bb7Svetoslav Ganov throw new IllegalArgumentException("Binding not well formed: " + argument); 2718486bc11baa717390796f2ebd55c7b2ae9294bb7Svetoslav Ganov } 2728486bc11baa717390796f2ebd55c7b2ae9294bb7Svetoslav Ganov String column = argument.substring(0, firstColonIndex); 2738486bc11baa717390796f2ebd55c7b2ae9294bb7Svetoslav Ganov String type = argument.substring(firstColonIndex + 1, secondColonIndex); 2748486bc11baa717390796f2ebd55c7b2ae9294bb7Svetoslav Ganov String value = argument.substring(secondColonIndex + 1); 27525872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov if (TYPE_STRING.equals(type)) { 27625872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov values.put(column, value); 27725872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } else if (TYPE_BOOLEAN.equalsIgnoreCase(type)) { 27825872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov values.put(column, Boolean.parseBoolean(value)); 27925872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } else if (TYPE_INTEGER.equalsIgnoreCase(type) || TYPE_LONG.equalsIgnoreCase(type)) { 28025872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov values.put(column, Long.parseLong(value)); 28125872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } else if (TYPE_FLOAT.equalsIgnoreCase(type) || TYPE_DOUBLE.equalsIgnoreCase(type)) { 28225872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov values.put(column, Double.parseDouble(value)); 28325872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } else { 28425872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov throw new IllegalArgumentException("Unsupported type: " + type); 28525872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 28625872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 28725872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov 28825872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov private String argumentValueRequired(String argument) { 28925872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov String value = mTokenizer.nextArg(); 29025872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov if (TextUtils.isEmpty(value) || value.startsWith(ARGUMENT_PREFIX)) { 29125872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov throw new IllegalArgumentException("No value for argument: " + argument); 29225872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 29325872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov return value; 29425872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 29525872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 29625872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov 29725872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov private static class Tokenizer { 29825872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov private final String[] mArgs; 29925872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov private int mNextArg; 30025872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov 30125872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov public Tokenizer(String[] args) { 30225872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov mArgs = args; 30325872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 30425872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov 30525872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov private String nextArg() { 30625872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov if (mNextArg < mArgs.length) { 30725872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov return mArgs[mNextArg++]; 30825872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } else { 30925872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov return null; 31025872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 31125872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 31225872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 31325872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov 31425872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov private static abstract class Command { 31525872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov final Uri mUri; 3166d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey final int mUserId; 31725872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov 3186d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey public Command(Uri uri, int userId) { 31925872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov mUri = uri; 3206d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey mUserId = userId; 32125872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 32225872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov 32325872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov public final void execute() { 32425872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov String providerName = mUri.getAuthority(); 32525872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov try { 32625872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov IActivityManager activityManager = ActivityManagerNative.getDefault(); 32725872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov IContentProvider provider = null; 32825872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov IBinder token = new Binder(); 32925872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov try { 33025872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov ContentProviderHolder holder = activityManager.getContentProviderExternal( 3316d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey providerName, mUserId, token); 33225872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov if (holder == null) { 33325872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov throw new IllegalStateException("Could not find provider: " + providerName); 33425872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 33525872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov provider = holder.provider; 33625872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov onExecute(provider); 33725872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } finally { 33825872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov if (provider != null) { 33925872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov activityManager.removeContentProviderExternal(providerName, token); 34025872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 34125872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 34225872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } catch (Exception e) { 34325872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov System.err.println("Error while accessing provider:" + providerName); 34425872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov e.printStackTrace(); 34525872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 34625872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 34725872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov 34825872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov protected abstract void onExecute(IContentProvider provider) throws Exception; 34925872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 35025872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov 35125872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov private static class InsertCommand extends Command { 35225872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov final ContentValues mContentValues; 35325872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov 3546d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey public InsertCommand(Uri uri, int userId, ContentValues contentValues) { 3556d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey super(uri, userId); 35625872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov mContentValues = contentValues; 35725872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 35825872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov 35925872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov @Override 36025872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov public void onExecute(IContentProvider provider) throws Exception { 36125872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov provider.insert(mUri, mContentValues); 36225872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 36325872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 36425872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov 36525872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov private static class DeleteCommand extends Command { 36625872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov final String mWhere; 36725872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov 3686d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey public DeleteCommand(Uri uri, int userId, String where) { 3696d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey super(uri, userId); 37025872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov mWhere = where; 37125872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 37225872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov 37325872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov @Override 37425872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov public void onExecute(IContentProvider provider) throws Exception { 37525872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov provider.delete(mUri, mWhere, null); 37625872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 37725872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 37825872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov 37925872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov private static class QueryCommand extends DeleteCommand { 38025872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov final String[] mProjection; 38125872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov final String mSortOrder; 38225872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov 3836d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey public QueryCommand( 3846d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey Uri uri, int userId, String[] projection, String where, String sortOrder) { 3856d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey super(uri, userId, where); 38625872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov mProjection = projection; 38725872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov mSortOrder = sortOrder; 38825872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 38925872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov 39025872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov @Override 39125872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov public void onExecute(IContentProvider provider) throws Exception { 39225872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov Cursor cursor = provider.query(mUri, mProjection, mWhere, null, mSortOrder, null); 39325872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov if (cursor == null) { 39425872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov System.out.println("No result found."); 39525872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov return; 39625872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 39725872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov try { 39825872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov if (cursor.moveToFirst()) { 39925872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov int rowIndex = 0; 40025872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov StringBuilder builder = new StringBuilder(); 40125872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov do { 40225872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov builder.setLength(0); 40325872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov builder.append("Row: ").append(rowIndex).append(" "); 40425872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov rowIndex++; 40525872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov final int columnCount = cursor.getColumnCount(); 40625872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov for (int i = 0; i < columnCount; i++) { 40725872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov if (i > 0) { 40825872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov builder.append(", "); 40925872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 41025872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov String columnName = cursor.getColumnName(i); 41125872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov String columnValue = null; 41225872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov final int columnIndex = cursor.getColumnIndex(columnName); 41325872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov final int type = cursor.getType(columnIndex); 41425872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov switch (type) { 41525872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov case Cursor.FIELD_TYPE_FLOAT: 41625872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov columnValue = String.valueOf(cursor.getFloat(columnIndex)); 41725872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov break; 41825872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov case Cursor.FIELD_TYPE_INTEGER: 41925872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov columnValue = String.valueOf(cursor.getInt(columnIndex)); 42025872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov break; 42125872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov case Cursor.FIELD_TYPE_STRING: 42225872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov columnValue = cursor.getString(columnIndex); 42325872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov break; 42425872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov case Cursor.FIELD_TYPE_BLOB: 42525872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov columnValue = "BLOB"; 42625872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov break; 42725872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov case Cursor.FIELD_TYPE_NULL: 42825872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov columnValue = "NULL"; 42925872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov break; 43025872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 43125872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov builder.append(columnName).append("=").append(columnValue); 43225872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 43325872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov System.out.println(builder); 43425872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } while (cursor.moveToNext()); 43525872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } else { 43625872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov System.out.println("No reuslt found."); 43725872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 43825872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } finally { 43925872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov cursor.close(); 44025872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 44125872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 44225872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 44325872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov 44425872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov private static class UpdateCommand extends InsertCommand { 44525872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov final String mWhere; 44625872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov 4476d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey public UpdateCommand(Uri uri, int userId, ContentValues contentValues, String where) { 4486d51571835737c7502a2e111ee9dc2527ebad984Jeff Sharkey super(uri, userId, contentValues); 44925872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov mWhere = where; 45025872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 45125872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov 45225872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov @Override 45325872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov public void onExecute(IContentProvider provider) throws Exception { 45425872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov provider.update(mUri, mContentValues, mWhere, null); 45525872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 45625872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 45725872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov 45825872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov public static void main(String[] args) { 45925872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov Parser parser = new Parser(args); 46025872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov Command command = parser.parseCommand(); 46125872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov if (command != null) { 46225872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov command.execute(); 46325872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 46425872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov } 46525872aa3ef189ae5506a923398af11ce5eb1a9b9Svetoslav Ganov} 466