19cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee/* 29cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee * Copyright (C) 2011 The Android Open Source Project 39cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee * 49cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee * Licensed under the Apache License, Version 2.0 (the "License"); 59cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee * you may not use this file except in compliance with the License. 69cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee * You may obtain a copy of the License at 79cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee * 89cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee * http://www.apache.org/licenses/LICENSE-2.0 99cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee * 109cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee * Unless required by applicable law or agreed to in writing, software 119cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee * distributed under the License is distributed on an "AS IS" BASIS, 129cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee * See the License for the specific language governing permissions and 149cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee * limitations under the License 159cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee */ 169cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee 179cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjeepackage com.android.providers.contacts; 189cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee 199cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjeeimport static com.android.providers.contacts.util.DbQueryUtils.concatenateClauses; 209cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee 219cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjeeimport android.content.ContentUris; 229cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjeeimport android.content.ContentValues; 239cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjeeimport android.content.Context; 249cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjeeimport android.database.Cursor; 259cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjeeimport android.database.sqlite.SQLiteDatabase; 269cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjeeimport android.database.sqlite.SQLiteQueryBuilder; 279cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjeeimport android.net.Uri; 289cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjeeimport android.os.ParcelFileDescriptor; 299cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjeeimport android.provider.VoicemailContract.Status; 3038210445730ee04c351c7cc1b3800cfe23e34325Makoto Onukiimport com.android.common.content.ProjectionMap; 3138210445730ee04c351c7cc1b3800cfe23e34325Makoto Onukiimport com.android.providers.contacts.VoicemailContentProvider.UriData; 3238210445730ee04c351c7cc1b3800cfe23e34325Makoto Onuki 339cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee/** 349cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee * Implementation of {@link VoicemailTable.Delegate} for the voicemail status table. 35155ff44c5809da846b841011923b7e81dede303dTa-wei Yen * 36155ff44c5809da846b841011923b7e81dede303dTa-wei Yen * Public methods of this class are thread-safe as it is used in a content provider, which should 37155ff44c5809da846b841011923b7e81dede303dTa-wei Yen * be thread-safe. 389cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee */ 399cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjeepublic class VoicemailStatusTable implements VoicemailTable.Delegate { 4052cb1f8391fdf93ad90d675585a9c7e385e4a8d6Ta-wei Yen 419cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee private static final ProjectionMap sStatusProjectionMap = new ProjectionMap.Builder() 429cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee .add(Status._ID) 43579bcb61285c36b31668cfffc1931afaeb12f12eTa-wei Yen .add(Status.PHONE_ACCOUNT_COMPONENT_NAME) 44579bcb61285c36b31668cfffc1931afaeb12f12eTa-wei Yen .add(Status.PHONE_ACCOUNT_ID) 459cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee .add(Status.CONFIGURATION_STATE) 469cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee .add(Status.DATA_CHANNEL_STATE) 479cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee .add(Status.NOTIFICATION_CHANNEL_STATE) 489cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee .add(Status.SETTINGS_URI) 499cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee .add(Status.SOURCE_PACKAGE) 509cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee .add(Status.VOICEMAIL_ACCESS_URI) 5152cb1f8391fdf93ad90d675585a9c7e385e4a8d6Ta-wei Yen .add(Status.QUOTA_OCCUPIED) 5252cb1f8391fdf93ad90d675585a9c7e385e4a8d6Ta-wei Yen .add(Status.QUOTA_TOTAL) 5321c692d49ce7ad6f9414d46ac2410d3f2e4c4d20Ta-wei Yen .add(Status.SOURCE_TYPE) 549cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee .build(); 559cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee 56155ff44c5809da846b841011923b7e81dede303dTa-wei Yen private static final Object DATABASE_LOCK = new Object(); 57155ff44c5809da846b841011923b7e81dede303dTa-wei Yen 589cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee private final String mTableName; 599cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee private final Context mContext; 60dc653a5c1bed274512ce41e4a6129a65d2b0eeacMakoto Onuki private final CallLogDatabaseHelper mDbHelper; 619cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee private final VoicemailTable.DelegateHelper mDelegateHelper; 629cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee 63dc653a5c1bed274512ce41e4a6129a65d2b0eeacMakoto Onuki public VoicemailStatusTable(String tableName, Context context, CallLogDatabaseHelper dbHelper, 649cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee VoicemailTable.DelegateHelper delegateHelper) { 659cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee mTableName = tableName; 669cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee mContext = context; 679cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee mDbHelper = dbHelper; 689cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee mDelegateHelper = delegateHelper; 699cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee } 709cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee 719cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee @Override 729cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee public Uri insert(UriData uriData, ContentValues values) { 73155ff44c5809da846b841011923b7e81dede303dTa-wei Yen synchronized (DATABASE_LOCK) { 74155ff44c5809da846b841011923b7e81dede303dTa-wei Yen SQLiteDatabase db = mDbHelper.getWritableDatabase(); 75155ff44c5809da846b841011923b7e81dede303dTa-wei Yen // Try to update before insert. 76155ff44c5809da846b841011923b7e81dede303dTa-wei Yen String combinedClause = uriData.getWhereClause(); 77155ff44c5809da846b841011923b7e81dede303dTa-wei Yen int rowsChanged = getDatabaseModifier(db) 78a0722de4886cdc06acf344052b70954415d25d80Ta-wei Yen .update(uriData.getUri(), mTableName, values, combinedClause, null); 79155ff44c5809da846b841011923b7e81dede303dTa-wei Yen if (rowsChanged != 0) { 80155ff44c5809da846b841011923b7e81dede303dTa-wei Yen final String[] selection = new String[] {Status._ID}; 81155ff44c5809da846b841011923b7e81dede303dTa-wei Yen Cursor c = db.query(mTableName, selection, combinedClause, null, null, null, null); 82155ff44c5809da846b841011923b7e81dede303dTa-wei Yen c.moveToFirst(); 83155ff44c5809da846b841011923b7e81dede303dTa-wei Yen int rowId = c.getInt(0); 8400fc3f9350bab201a3fd5659422c0ba85bf7d7efTa-wei Yen c.close(); 85155ff44c5809da846b841011923b7e81dede303dTa-wei Yen return ContentUris.withAppendedId(uriData.getUri(), rowId); 86155ff44c5809da846b841011923b7e81dede303dTa-wei Yen } 87155ff44c5809da846b841011923b7e81dede303dTa-wei Yen ContentValues copiedValues = new ContentValues(values); 88155ff44c5809da846b841011923b7e81dede303dTa-wei Yen mDelegateHelper.checkAndAddSourcePackageIntoValues(uriData, copiedValues); 89155ff44c5809da846b841011923b7e81dede303dTa-wei Yen long rowId = getDatabaseModifier(db).insert(mTableName, null, copiedValues); 90155ff44c5809da846b841011923b7e81dede303dTa-wei Yen if (rowId > 0) { 91155ff44c5809da846b841011923b7e81dede303dTa-wei Yen return ContentUris.withAppendedId(uriData.getUri(), rowId); 92155ff44c5809da846b841011923b7e81dede303dTa-wei Yen } else { 93155ff44c5809da846b841011923b7e81dede303dTa-wei Yen return null; 94155ff44c5809da846b841011923b7e81dede303dTa-wei Yen } 959cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee } 969cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee } 979cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee 989cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee @Override 999cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee public int delete(UriData uriData, String selection, String[] selectionArgs) { 100155ff44c5809da846b841011923b7e81dede303dTa-wei Yen synchronized (DATABASE_LOCK) { 101155ff44c5809da846b841011923b7e81dede303dTa-wei Yen SQLiteDatabase db = mDbHelper.getWritableDatabase(); 102155ff44c5809da846b841011923b7e81dede303dTa-wei Yen String combinedClause = concatenateClauses(selection, uriData.getWhereClause()); 103155ff44c5809da846b841011923b7e81dede303dTa-wei Yen return getDatabaseModifier(db).delete(mTableName, combinedClause, 104155ff44c5809da846b841011923b7e81dede303dTa-wei Yen selectionArgs); 105155ff44c5809da846b841011923b7e81dede303dTa-wei Yen } 1069cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee } 1079cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee 1089cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee @Override 1099cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee public Cursor query(UriData uriData, String[] projection, String selection, 1109cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee String[] selectionArgs, String sortOrder) { 111155ff44c5809da846b841011923b7e81dede303dTa-wei Yen synchronized (DATABASE_LOCK) { 112155ff44c5809da846b841011923b7e81dede303dTa-wei Yen SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); 113155ff44c5809da846b841011923b7e81dede303dTa-wei Yen qb.setTables(mTableName); 114155ff44c5809da846b841011923b7e81dede303dTa-wei Yen qb.setProjectionMap(sStatusProjectionMap); 115155ff44c5809da846b841011923b7e81dede303dTa-wei Yen qb.setStrict(true); 116155ff44c5809da846b841011923b7e81dede303dTa-wei Yen 117155ff44c5809da846b841011923b7e81dede303dTa-wei Yen String combinedClause = concatenateClauses(selection, uriData.getWhereClause()); 118155ff44c5809da846b841011923b7e81dede303dTa-wei Yen SQLiteDatabase db = mDbHelper.getReadableDatabase(); 119155ff44c5809da846b841011923b7e81dede303dTa-wei Yen Cursor c = qb 120155ff44c5809da846b841011923b7e81dede303dTa-wei Yen .query(db, projection, combinedClause, selectionArgs, null, null, sortOrder); 121155ff44c5809da846b841011923b7e81dede303dTa-wei Yen if (c != null) { 122155ff44c5809da846b841011923b7e81dede303dTa-wei Yen c.setNotificationUri(mContext.getContentResolver(), Status.CONTENT_URI); 123155ff44c5809da846b841011923b7e81dede303dTa-wei Yen } 124155ff44c5809da846b841011923b7e81dede303dTa-wei Yen return c; 1259cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee } 1269cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee } 1279cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee 1289cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee @Override 1299cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee public int update(UriData uriData, ContentValues values, String selection, 1309cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee String[] selectionArgs) { 131155ff44c5809da846b841011923b7e81dede303dTa-wei Yen synchronized (DATABASE_LOCK) { 132155ff44c5809da846b841011923b7e81dede303dTa-wei Yen SQLiteDatabase db = mDbHelper.getWritableDatabase(); 133155ff44c5809da846b841011923b7e81dede303dTa-wei Yen String combinedClause = concatenateClauses(selection, uriData.getWhereClause()); 134a0722de4886cdc06acf344052b70954415d25d80Ta-wei Yen return getDatabaseModifier(db) 135a0722de4886cdc06acf344052b70954415d25d80Ta-wei Yen .update(uriData.getUri(), mTableName, values, combinedClause, selectionArgs); 136155ff44c5809da846b841011923b7e81dede303dTa-wei Yen } 1379cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee } 1389cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee 1399cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee @Override 1409cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee public String getType(UriData uriData) { 1419cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee if (uriData.hasId()) { 1429cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee return Status.ITEM_TYPE; 1439cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee } else { 1449cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee return Status.DIR_TYPE; 1459cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee } 1469cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee } 1479cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee 1489cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee @Override 1499cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee public ParcelFileDescriptor openFile(UriData uriData, String mode) { 1509cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee throw new UnsupportedOperationException("File operation is not supported for status table"); 1519cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee } 152929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee 153929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee private DatabaseModifier getDatabaseModifier(SQLiteDatabase db) { 1542e757d904e62dbf5bc0b028626fa9319ccc38c45Debashish Chatterjee return new DbModifierWithNotification(mTableName, db, mContext); 155929a04e2830e30718930d96335dfb0a729b6ab91Debashish Chatterjee } 1569cf06e7bcb0be759f1c930412fd2e41eba4f5f03Debashish Chatterjee} 157