blob: 651b1cd67b54f0d780797f26080d33b458eb6f8c [file] [log] [blame]
/*
* Copyright (c) 2015, Motorola Mobility LLC
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - Neither the name of Motorola Mobility nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MOTOROLA MOBILITY LLC BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*/
package com.android.service.ims.presence;
import java.io.FileNotFoundException;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Intent;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
import android.provider.BaseColumns;
import android.provider.ContactsContract.Contacts;
import android.content.ComponentName;
import com.android.ims.RcsPresenceInfo;
import com.android.ims.internal.EABContract;
import com.android.ims.internal.Logger;
/**
* @author Vishal Patil (A22809)
*/
public class EABProvider extends DatabaseContentProvider{
private Logger logger = Logger.getLogger(this.getClass().getName());
private static final String EAB_DB_NAME = "rcseab.db";
private static final int EAB_DB_VERSION = 2;
private static final int EAB_TABLE = 1;
private static final int EAB_TABLE_ID = 2;
private static final int EAB_GROUPITEMS_TABLE = 3;
private static final UriMatcher URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH) {
{
addURI(EABContract.AUTHORITY, EABContract.EABColumns.TABLE_NAME, EAB_TABLE);
addURI(EABContract.AUTHORITY, EABContract.EABColumns.TABLE_NAME + "/#", EAB_TABLE_ID);
addURI(EABContract.AUTHORITY, EABContract.EABColumns.GROUPITEMS_NAME,
EAB_GROUPITEMS_TABLE);
}
};
/* Statement to create VMM Album table. */
private static final String EAB_CREATE_STATEMENT = "create table if not exists "
+ EABContract.EABColumns.TABLE_NAME
+ "("
+ EABContract.EABColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ EABContract.EABColumns.CONTACT_NAME + " TEXT, "
+ EABContract.EABColumns.CONTACT_NUMBER + " TEXT, "
+ EABContract.EABColumns.RAW_CONTACT_ID + " TEXT, "
+ EABContract.EABColumns.CONTACT_ID + " TEXT, "
+ EABContract.EABColumns.DATA_ID + " TEXT, "
+ EABContract.EABColumns.ACCOUNT_TYPE + " TEXT, "
+ EABContract.EABColumns.VOLTE_CALL_SERVICE_CONTACT_ADDRESS + " TEXT, "
+ EABContract.EABColumns.VOLTE_CALL_CAPABILITY + " INTEGER, "
+ EABContract.EABColumns.VOLTE_CALL_CAPABILITY_TIMESTAMP + " LONG, "
+ EABContract.EABColumns.VOLTE_CALL_AVAILABILITY + " INTEGER, "
+ EABContract.EABColumns.VOLTE_CALL_AVAILABILITY_TIMESTAMP + " LONG, "
+ EABContract.EABColumns.VIDEO_CALL_SERVICE_CONTACT_ADDRESS + " TEXT, "
+ EABContract.EABColumns.VIDEO_CALL_CAPABILITY + " INTEGER, "
+ EABContract.EABColumns.VIDEO_CALL_CAPABILITY_TIMESTAMP + " LONG, "
+ EABContract.EABColumns.VIDEO_CALL_AVAILABILITY + " INTEGER, "
+ EABContract.EABColumns.VIDEO_CALL_AVAILABILITY_TIMESTAMP + " LONG, "
+ EABContract.EABColumns.CONTACT_LAST_UPDATED_TIMESTAMP + " LONG "
+ ");";
private static final String EAB_DROP_STATEMENT = "drop table if exists "
+ EABContract.EABColumns.TABLE_NAME + ";";
public EABProvider() {
super(EAB_DB_NAME, EAB_DB_VERSION);
}
@Override
public void bootstrapDatabase(SQLiteDatabase db) {
logger.info("Enter: bootstrapDatabase() Creating new EAB database");
upgradeDatabase(db, 0, EAB_DB_VERSION);
logger.info("Exit: bootstrapDatabase()");
}
/*
* In upgradeDatabase,
* oldVersion - the current version of Provider on the phone.
* newVersion - the version of Provider where the phone will be upgraded to.
*/
@Override
public boolean upgradeDatabase(SQLiteDatabase db, int oldVersion, int newVersion) {
logger.debug("Enter: upgradeDatabase() - oldVersion = " + oldVersion +
" newVersion = " + newVersion);
if (oldVersion == newVersion) {
logger.debug("upgradeDatabase oldVersion == newVersion, No Upgrade Required");
return true;
}
try {
if (oldVersion == 0) {
db.execSQL(EAB_CREATE_STATEMENT);
oldVersion++;
logger.debug("upgradeDatabase : DB has been upgraded to " + oldVersion);
}
if (oldVersion == 1) {
addColumn(db, EABContract.EABColumns.TABLE_NAME,
EABContract.EABColumns.VOLTE_STATUS, "INTEGER NOT NULL DEFAULT -1");
oldVersion++;
logger.debug("upgradeDatabase : DB has been upgraded to " + oldVersion);
}
} catch (SQLException exception) {
logger.error("Exception during upgradeDatabase. " + exception.getMessage());
// DB file had problem
throw new InvalidDBException();
}
// add further upgrade code above this
if (oldVersion == newVersion) {
logger.debug("DB upgrade complete : to " + newVersion);
}
logger.debug("Exit: upgradeDatabase()");
return true;
}
@Override
protected boolean downgradeDatabase(SQLiteDatabase db, int oldVersion, int newVersion) {
// throwing the custom created Exception to catch it in
// getWritableDatabase or getReadableDatabase
throw new InvalidDBException();
}
@Override
protected int deleteInternal(SQLiteDatabase db, Uri uri, String selection,
String[] selectionArgs) {
logger.info("Enter: deleteInternal()");
final int match = URI_MATCHER.match(uri);
String table = null;
switch (match) {
case EAB_TABLE_ID:
if (selection == null) {
selection = "_id=?";
selectionArgs = new String[] {uri.getPathSegments().get(1)};
}
case EAB_TABLE:
table = EABContract.EABColumns.TABLE_NAME;
break;
default:
logger.info("No match for " + uri);
logger.info("Exit: deleteInternal()");
return 0;
}
logger.debug("Deleting from the table" + table + " selection= " + selection);
printDeletingValues(uri, selection, selectionArgs);
logger.info("Exit: deleteInternal()");
return db.delete(table, selection, selectionArgs);
}
@Override
protected Uri insertInternal(SQLiteDatabase db, Uri uri, ContentValues values) {
logger.info("Enter: insertInternal()");
final int match = URI_MATCHER.match(uri);
String table = null;
String nullColumnHack = null;
switch (match) {
case EAB_TABLE:
table = EABContract.EABColumns.TABLE_NAME;
break;
default:
logger.warn("No match for " + uri);
logger.info("Exit: insertInternal() with null");
return null;
}
values = verifyIfMdnExists(values);
// Do the insert.
logger.debug("Inserting to the table" + table + " values=" + values.toString());
final long id = db.insert(table, nullColumnHack, values);
if (id > 0) {
String contactNumber = values.getAsString(EABContract.EABColumns.CONTACT_NUMBER);
sendInsertBroadcast(contactNumber);
logger.info("Exit: insertInternal()");
return ContentUris.withAppendedId(uri, id);
} else {
logger.info("Exit: insertInternal() with null");
return null;
}
}
@Override
protected Cursor queryInternal(SQLiteDatabase db, Uri uri, String[] projection,
String selection, String[] selectionArgs, String sortOrder) {
logger.info("Enter: queryInternal()");
final int match = URI_MATCHER.match(uri);
switch (match) {
case EAB_TABLE_ID:
long id = ContentUris.parseId(uri);
logger.debug("queryInternal id=" + id);
String idSelection = BaseColumns._ID + "=" + id;
if(null != selection) {
selection = "((" + idSelection + ") AND (" + selection + "))";
} else {
selection = idSelection;
}
break;
case EAB_GROUPITEMS_TABLE:
SQLiteQueryBuilder sqb = new SQLiteQueryBuilder();
sqb.setTables(EABContract.EABColumns.TABLE_NAME);
String rawquery = "select DISTINCT " + EABContract.EABColumns.CONTACT_ID
+ " from " + EABContract.EABColumns.TABLE_NAME
+ " where " + EABContract.EABColumns.VOLTE_CALL_CAPABILITY + " >'" +
RcsPresenceInfo.ServiceState.OFFLINE+"' AND "
+ EABContract.EABColumns.VIDEO_CALL_CAPABILITY + " >'"
+ RcsPresenceInfo.ServiceState.OFFLINE + "'";
StringBuffer sb = new StringBuffer();
Cursor cursor = db.rawQuery(rawquery, null);
if (cursor != null && cursor.moveToFirst()) {
do {
if (sb.length() != 0) sb.append(",");
String contactId = cursor.getString(cursor
.getColumnIndex(EABContract.EABColumns.CONTACT_ID));
sb.append(contactId);
} while (cursor.moveToNext());
}
if (cursor != null) cursor.close();
String contactSel = Contacts._ID + " IN ( " + sb.toString() + ")";
return getContext().getContentResolver().query(Contacts.CONTENT_URI, projection,
contactSel, null, sortOrder);
}
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
String groupBy = uri.getQueryParameter("groupby");
String having = null;
switch (match) {
case EAB_TABLE:
case EAB_TABLE_ID:
qb.setTables(EABContract.EABColumns.TABLE_NAME);
break;
default:
logger.warn("No match for " + uri);
logger.info("Exit: queryInternal()");
return null;
}
logger.info("Exit: queryInternal()");
return qb.query(db, projection, selection, selectionArgs, groupBy, having, sortOrder);
}
@Override
protected int updateInternal(SQLiteDatabase db, Uri uri, ContentValues values,
String selection, String[] selectionArgs) {
logger.info("Enter: updateInternal()");
int result = 0;
final int match = URI_MATCHER.match(uri);
switch (match) {
case EAB_TABLE_ID:
long id = ContentUris.parseId(uri);
logger.debug("updateInternal id=" + id);
String idSelection = BaseColumns._ID + "=" + id;
if(null != selection){
selection = "((" + idSelection + ") AND (" + selection + "))";
} else {
selection = idSelection;
}
break;
}
String table = null;
switch (match) {
case EAB_TABLE:
case EAB_TABLE_ID:
table = EABContract.EABColumns.TABLE_NAME;
break;
default:
logger.warn("No match for " + uri);
break;
}
if (table != null && values != null) {
logger.debug("Updating the table " + table + " values= " + values.toString());
result = db.update(table, values, selection, selectionArgs);
}
logger.info("Exit: updateInternal()");
return result;
}
@Override
public String getType(Uri uri) {
logger.info("Enter: getType()");
final int match = URI_MATCHER.match(uri);
switch (match) {
case EAB_TABLE:
return EABContract.EABColumns.CONTENT_TYPE;
case EAB_TABLE_ID:
return EABContract.EABColumns.CONTENT_ITEM_TYPE;
default:
throw (new IllegalArgumentException("EABProvider URI: " + uri));
}
}
@Override
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
return null;
}
private void sendInsertBroadcast(String contactNumber) {
Intent intent = new Intent(com.android.service.ims.presence.Contacts
.ACTION_NEW_CONTACT_INSERTED);
ComponentName component = new ComponentName("com.android.service.ims.presence",
"com.android.service.ims.presence.AlarmBroadcastReceiver");
intent.setComponent(component);
intent.putExtra(com.android.service.ims.presence.Contacts.NEW_PHONE_NUMBER, contactNumber);
getContext().sendBroadcast(intent);
}
private ContentValues verifyIfMdnExists(ContentValues cvalues) {
String phoneNumber = null;
if (cvalues.containsKey(EABContract.EABColumns.CONTACT_NUMBER)) {
phoneNumber = cvalues.getAsString(EABContract.EABColumns.CONTACT_NUMBER);
} else {
return cvalues;
}
if (null == phoneNumber) {
return cvalues;
}
String[] projection = new String[] {
EABContract.EABColumns.VOLTE_CALL_SERVICE_CONTACT_ADDRESS,
EABContract.EABColumns.VOLTE_CALL_CAPABILITY,
EABContract.EABColumns.VOLTE_CALL_CAPABILITY_TIMESTAMP,
EABContract.EABColumns.VOLTE_CALL_AVAILABILITY,
EABContract.EABColumns.VOLTE_CALL_AVAILABILITY_TIMESTAMP,
EABContract.EABColumns.VIDEO_CALL_SERVICE_CONTACT_ADDRESS,
EABContract.EABColumns.VIDEO_CALL_CAPABILITY,
EABContract.EABColumns.VIDEO_CALL_CAPABILITY_TIMESTAMP,
EABContract.EABColumns.VIDEO_CALL_AVAILABILITY,
EABContract.EABColumns.VIDEO_CALL_AVAILABILITY_TIMESTAMP};
String whereClause = "PHONE_NUMBERS_EQUAL(" +
EABContract.EABColumns.CONTACT_NUMBER + ", ?, 0)";
String[] selectionArgs = new String[] { phoneNumber };
Cursor cursor = getContext().getContentResolver().query(EABContract.EABColumns.CONTENT_URI,
projection, whereClause, selectionArgs, null);
if ((null != cursor) && (cursor.getCount() > 0)) {
logger.debug("Number : " + phoneNumber +
" is already stored in EAB DB - cursor count is " + cursor.getCount());
logger.error("Inserting another copy of MDN to EAB DB.");
// Update data only from first cursor element.
cursor.moveToNext();
cvalues.put(EABContract.EABColumns.VOLTE_CALL_SERVICE_CONTACT_ADDRESS,
cursor.getString(cursor.
getColumnIndex(EABContract.EABColumns.VOLTE_CALL_SERVICE_CONTACT_ADDRESS)));
cvalues.put(EABContract.EABColumns.VOLTE_CALL_CAPABILITY, cursor.getString(cursor
.getColumnIndex(EABContract.EABColumns.VOLTE_CALL_CAPABILITY)));
cvalues.put(EABContract.EABColumns.VOLTE_CALL_CAPABILITY_TIMESTAMP,
cursor.getLong(cursor
.getColumnIndex(EABContract.EABColumns.VOLTE_CALL_CAPABILITY_TIMESTAMP)));
cvalues.put(EABContract.EABColumns.VOLTE_CALL_AVAILABILITY, cursor.getString(cursor
.getColumnIndex(EABContract.EABColumns.VOLTE_CALL_AVAILABILITY)));
cvalues.put(EABContract.EABColumns.VOLTE_CALL_AVAILABILITY_TIMESTAMP,
cursor.getLong(cursor
.getColumnIndex(EABContract.EABColumns.VOLTE_CALL_AVAILABILITY_TIMESTAMP)));
cvalues.put(EABContract.EABColumns.VIDEO_CALL_SERVICE_CONTACT_ADDRESS,
cursor.getString(cursor
.getColumnIndex(EABContract.EABColumns.VIDEO_CALL_SERVICE_CONTACT_ADDRESS)));
cvalues.put(EABContract.EABColumns.VIDEO_CALL_CAPABILITY, cursor.getString(cursor
.getColumnIndex(EABContract.EABColumns.VIDEO_CALL_CAPABILITY)));
cvalues.put(EABContract.EABColumns.VIDEO_CALL_CAPABILITY_TIMESTAMP,
cursor.getLong(cursor
.getColumnIndex(EABContract.EABColumns.VIDEO_CALL_CAPABILITY_TIMESTAMP)));
cvalues.put(EABContract.EABColumns.VIDEO_CALL_AVAILABILITY, cursor.getString(cursor
.getColumnIndex(EABContract.EABColumns.VIDEO_CALL_AVAILABILITY)));
cvalues.put(EABContract.EABColumns.VIDEO_CALL_AVAILABILITY_TIMESTAMP,
cursor.getLong(cursor
.getColumnIndex(EABContract.EABColumns.VIDEO_CALL_AVAILABILITY_TIMESTAMP)));
cvalues.put(EABContract.EABColumns.CONTACT_LAST_UPDATED_TIMESTAMP, 0);
}
if (null != cursor) {
cursor.close();
}
return cvalues;
}
private void printDeletingValues(Uri uri, String selection, String[] selectionArgs) {
String[] projection = new String[] {
EABContract.EABColumns.CONTACT_NUMBER,
EABContract.EABColumns.CONTACT_NAME,
EABContract.EABColumns.RAW_CONTACT_ID,
EABContract.EABColumns.CONTACT_ID,
EABContract.EABColumns.DATA_ID};
Cursor cursor = getContext().getContentResolver().query(EABContract.EABColumns.CONTENT_URI,
projection, selection, selectionArgs, null);
if ((null != cursor) && (cursor.getCount() > 0)) {
logger.debug("Before deleting the cursor count is " + cursor.getCount());
// Update data only from first cursor element.
while (cursor.moveToNext()) {
long dataId = cursor.getLong(cursor.getColumnIndex(
EABContract.EABColumns.DATA_ID));
long contactId = cursor.getLong(cursor.getColumnIndex(
EABContract.EABColumns.CONTACT_ID));
long rawContactId = cursor.getLong(cursor.getColumnIndex(
EABContract.EABColumns.RAW_CONTACT_ID));
String phoneNumber = cursor.getString(cursor.getColumnIndex(
EABContract.EABColumns.CONTACT_NUMBER));
String displayName = cursor.getString(cursor.getColumnIndex(
EABContract.EABColumns.CONTACT_NAME));
logger.debug("Deleting : dataId : " + dataId + " contactId :" + contactId +
" rawContactId :" + rawContactId + " phoneNumber :" + phoneNumber +
" displayName :" + displayName);
}
} else {
logger.error("cursor is null!");
}
if (null != cursor) {
cursor.close();
}
}
}