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