ImProviderpublic class ImProvider extends android.content.ContentProvider A content provider for IM |
Fields Summary |
---|
private static final String | LOG_TAG | private static final boolean | DBG | private static final String | AUTHORITY | private static final boolean | USE_CONTACT_PRESENCE_TRIGGER | private static final String | TABLE_ACCOUNTS | private static final String | TABLE_PROVIDERS | private static final String | TABLE_PROVIDER_SETTINGS | private static final String | TABLE_CONTACTS | private static final String | TABLE_CONTACTS_ETAG | private static final String | TABLE_BLOCKED_LIST | private static final String | TABLE_CONTACT_LIST | private static final String | TABLE_INVITATIONS | private static final String | TABLE_GROUP_MEMBERS | private static final String | TABLE_GROUP_MESSAGES | private static final String | TABLE_PRESENCE | private static final String | USERNAME | private static final String | TABLE_CHATS | private static final String | TABLE_AVATARS | private static final String | TABLE_SESSION_COOKIES | private static final String | TABLE_MESSAGES | private static final String | TABLE_OUTGOING_RMQ_MESSAGES | private static final String | TABLE_LAST_RMQ_ID | private static final String | TABLE_ACCOUNT_STATUS | private static final String | TABLE_BRANDING_RESOURCE_MAP_CACHE | private static final String | DATABASE_NAME | private static final int | DATABASE_VERSION | protected static final int | MATCH_PROVIDERS | protected static final int | MATCH_PROVIDERS_BY_ID | protected static final int | MATCH_PROVIDERS_WITH_ACCOUNT | protected static final int | MATCH_ACCOUNTS | protected static final int | MATCH_ACCOUNTS_BY_ID | protected static final int | MATCH_CONTACTS | protected static final int | MATCH_CONTACTS_JOIN_PRESENCE | protected static final int | MATCH_CONTACTS_BAREBONE | protected static final int | MATCH_CHATTING_CONTACTS | protected static final int | MATCH_CONTACTS_BY_PROVIDER | protected static final int | MATCH_CHATTING_CONTACTS_BY_PROVIDER | protected static final int | MATCH_NO_CHATTING_CONTACTS_BY_PROVIDER | protected static final int | MATCH_ONLINE_CONTACTS_BY_PROVIDER | protected static final int | MATCH_OFFLINE_CONTACTS_BY_PROVIDER | protected static final int | MATCH_CONTACT | protected static final int | MATCH_CONTACTS_BULK | protected static final int | MATCH_ONLINE_CONTACT_COUNT | protected static final int | MATCH_BLOCKED_CONTACTS | protected static final int | MATCH_CONTACTLISTS | protected static final int | MATCH_CONTACTLISTS_BY_PROVIDER | protected static final int | MATCH_CONTACTLIST | protected static final int | MATCH_BLOCKEDLIST | protected static final int | MATCH_BLOCKEDLIST_BY_PROVIDER | protected static final int | MATCH_CONTACTS_ETAGS | protected static final int | MATCH_CONTACTS_ETAG | protected static final int | MATCH_PRESENCE | protected static final int | MATCH_PRESENCE_ID | protected static final int | MATCH_PRESENCE_BY_ACCOUNT | protected static final int | MATCH_PRESENCE_SEED_BY_ACCOUNT | protected static final int | MATCH_PRESENCE_BULK | protected static final int | MATCH_MESSAGES | protected static final int | MATCH_MESSAGES_BY_CONTACT | protected static final int | MATCH_MESSAGE | protected static final int | MATCH_GROUP_MESSAGES | protected static final int | MATCH_GROUP_MESSAGE_BY | protected static final int | MATCH_GROUP_MESSAGE | protected static final int | MATCH_GROUP_MEMBERS | protected static final int | MATCH_GROUP_MEMBERS_BY_GROUP | protected static final int | MATCH_AVATARS | protected static final int | MATCH_AVATAR | protected static final int | MATCH_AVATAR_BY_PROVIDER | protected static final int | MATCH_CHATS | protected static final int | MATCH_CHATS_BY_ACCOUNT | protected static final int | MATCH_CHATS_ID | protected static final int | MATCH_SESSIONS | protected static final int | MATCH_SESSIONS_BY_PROVIDER | protected static final int | MATCH_PROVIDER_SETTINGS | protected static final int | MATCH_PROVIDER_SETTINGS_BY_ID | protected static final int | MATCH_PROVIDER_SETTINGS_BY_ID_AND_NAME | protected static final int | MATCH_INVITATIONS | protected static final int | MATCH_INVITATION | protected static final int | MATCH_OUTGOING_RMQ_MESSAGES | protected static final int | MATCH_OUTGOING_RMQ_MESSAGE | protected static final int | MATCH_OUTGOING_HIGHEST_RMQ_ID | protected static final int | MATCH_LAST_RMQ_ID | protected static final int | MATCH_ACCOUNTS_STATUS | protected static final int | MATCH_ACCOUNT_STATUS | protected static final int | MATCH_BRANDING_RESOURCE_MAP_CACHE | protected final android.content.UriMatcher | mUrlMatcher | private final String | mTransientDbName | private static final HashMap | sProviderAccountsProjectionMap | private static final HashMap | sContactsProjectionMap | private static final HashMap | sContactListProjectionMap | private static final HashMap | sBlockedListProjectionMap | private static final String | PROVIDER_JOIN_ACCOUNT_TABLE | private static final String | CONTACT_JOIN_PRESENCE_TABLE | private static final String | CONTACT_JOIN_PRESENCE_CHAT_TABLE | private static final String | CONTACT_JOIN_PRESENCE_CHAT_AVATAR_TABLE | private static final String | BLOCKEDLIST_JOIN_AVATAR_TABLE | private static final String | NON_BLOCKED_CONTACTS_WHERE_CLAUSEThe where clause for filtering out blocked contacts | private static final String | BLOCKED_CONTACTS_WHERE_CLAUSE | private static final String | CONTACT_ID | private static final String | PRESENCE_CONTACT_ID | protected android.database.sqlite.SQLiteOpenHelper | mOpenHelper | private final String | mDatabaseName | private final int | mDatabaseVersion | private final String[] | BACKFILL_PROJECTION | private final String[] | FIND_SHORTCUT_PROJECTION | private static final String[] | CONTACT_ID_PROJECTION | private static final int | COLUMN_ID | private static final String | CONTACTS_WITH_NO_PRESENCE_SELECTION | private String[] | mQueryContactPresenceSelectionArgs | private static final String | DELETE_PRESENCE_SELECTIONmanual trigger for deleting contacts | private static final String | CHATS_CONTACT_ID | private static final String | DELETE_CHATS_SELECTION | private static final String | GROUP_MEMBER_ID | private static final String | DELETE_GROUP_MEMBER_SELECTION | private static final String | GROUP_MESSAGES_ID | private static final String | DELETE_GROUP_MESSAGES_SELECTION |
Constructors Summary |
---|
public ImProvider()
sProviderAccountsProjectionMap = new HashMap<String, String>();
sProviderAccountsProjectionMap.put(Im.Provider._ID,
"providers._id AS _id");
sProviderAccountsProjectionMap.put(Im.Provider._COUNT,
"COUNT(*) AS _account");
sProviderAccountsProjectionMap.put(Im.Provider.NAME,
"providers.name AS name");
sProviderAccountsProjectionMap.put(Im.Provider.FULLNAME,
"providers.fullname AS fullname");
sProviderAccountsProjectionMap.put(Im.Provider.CATEGORY,
"providers.category AS category");
sProviderAccountsProjectionMap.put(Im.Provider.ACTIVE_ACCOUNT_ID,
"accounts._id AS account_id");
sProviderAccountsProjectionMap.put(Im.Provider.ACTIVE_ACCOUNT_USERNAME,
"accounts.username AS account_username");
sProviderAccountsProjectionMap.put(Im.Provider.ACTIVE_ACCOUNT_PW,
"accounts.pw AS account_pw");
sProviderAccountsProjectionMap.put(Im.Provider.ACTIVE_ACCOUNT_LOCKED,
"accounts.locked AS account_locked");
sProviderAccountsProjectionMap.put(Im.Provider.ACCOUNT_PRESENCE_STATUS,
"accountStatus.presenceStatus AS account_presenceStatus");
sProviderAccountsProjectionMap.put(Im.Provider.ACCOUNT_CONNECTION_STATUS,
"accountStatus.connStatus AS account_connStatus");
// contacts projection map
sContactsProjectionMap = new HashMap<String, String>();
// Base column
sContactsProjectionMap.put(Im.Contacts._ID, "contacts._id AS _id");
sContactsProjectionMap.put(Im.Contacts._COUNT, "COUNT(*) AS _count");
// contacts column
sContactsProjectionMap.put(Im.Contacts._ID, "contacts._id as _id");
sContactsProjectionMap.put(Im.Contacts.USERNAME, "contacts.username as username");
sContactsProjectionMap.put(Im.Contacts.NICKNAME, "contacts.nickname as nickname");
sContactsProjectionMap.put(Im.Contacts.PROVIDER, "contacts.provider as provider");
sContactsProjectionMap.put(Im.Contacts.ACCOUNT, "contacts.account as account");
sContactsProjectionMap.put(Im.Contacts.CONTACTLIST, "contacts.contactList as contactList");
sContactsProjectionMap.put(Im.Contacts.TYPE, "contacts.type as type");
sContactsProjectionMap.put(Im.Contacts.SUBSCRIPTION_STATUS,
"contacts.subscriptionStatus as subscriptionStatus");
sContactsProjectionMap.put(Im.Contacts.SUBSCRIPTION_TYPE,
"contacts.subscriptionType as subscriptionType");
sContactsProjectionMap.put(Im.Contacts.QUICK_CONTACT, "contacts.qc as qc");
sContactsProjectionMap.put(Im.Contacts.REJECTED, "contacts.rejected as rejected");
// Presence columns
sContactsProjectionMap.put(Im.Presence.CONTACT_ID,
"presence.contact_id AS contact_id");
sContactsProjectionMap.put(Im.Contacts.PRESENCE_STATUS,
"presence.mode AS mode");
sContactsProjectionMap.put(Im.Contacts.PRESENCE_CUSTOM_STATUS,
"presence.status AS status");
sContactsProjectionMap.put(Im.Contacts.CLIENT_TYPE,
"presence.client_type AS client_type");
// Chats columns
sContactsProjectionMap.put(Im.Contacts.CHATS_CONTACT,
"chats.contact_id AS chats_contact_id");
sContactsProjectionMap.put(Im.Chats.JID_RESOURCE,
"chats.jid_resource AS jid_resource");
sContactsProjectionMap.put(Im.Chats.GROUP_CHAT,
"chats.groupchat AS groupchat");
sContactsProjectionMap.put(Im.Contacts.LAST_UNREAD_MESSAGE,
"chats.last_unread_message AS last_unread_message");
sContactsProjectionMap.put(Im.Contacts.LAST_MESSAGE_DATE,
"chats.last_message_date AS last_message_date");
sContactsProjectionMap.put(Im.Contacts.UNSENT_COMPOSED_MESSAGE,
"chats.unsent_composed_message AS unsent_composed_message");
sContactsProjectionMap.put(Im.Contacts.SHORTCUT, "chats.SHORTCUT AS shortcut");
// Avatars columns
sContactsProjectionMap.put(Im.Contacts.AVATAR_HASH, "avatars.hash AS avatars_hash");
sContactsProjectionMap.put(Im.Contacts.AVATAR_DATA, "avatars.data AS avatars_data");
// contactList projection map
sContactListProjectionMap = new HashMap<String, String>();
sContactListProjectionMap.put(Im.ContactList._ID,
"contactList._id AS _id");
sContactListProjectionMap.put(Im.ContactList._COUNT,
"COUNT(*) AS _count");
sContactListProjectionMap.put(Im.ContactList.NAME, "name");
sContactListProjectionMap.put(Im.ContactList.PROVIDER, "provider");
sContactListProjectionMap.put(Im.ContactList.ACCOUNT, "account");
// blockedList projection map
sBlockedListProjectionMap = new HashMap<String, String>();
sBlockedListProjectionMap.put(Im.BlockedList._ID,
"blockedList._id AS _id");
sBlockedListProjectionMap.put(Im.BlockedList._COUNT,
"COUNT(*) AS _count");
sBlockedListProjectionMap.put(Im.BlockedList.USERNAME, "username");
sBlockedListProjectionMap.put(Im.BlockedList.NICKNAME, "nickname");
sBlockedListProjectionMap.put(Im.BlockedList.PROVIDER, "provider");
sBlockedListProjectionMap.put(Im.BlockedList.ACCOUNT, "account");
sBlockedListProjectionMap.put(Im.BlockedList.AVATAR_DATA,
"avatars.data AS avatars_data");
this(AUTHORITY, DATABASE_NAME, DATABASE_VERSION);
| protected ImProvider(String authority, String dbName, int dbVersion)
mDatabaseName = dbName;
mDatabaseVersion = dbVersion;
mTransientDbName = "transient_" + dbName.replace(".", "_");
mUrlMatcher.addURI(authority, "providers", MATCH_PROVIDERS);
mUrlMatcher.addURI(authority, "providers/#", MATCH_PROVIDERS_BY_ID);
mUrlMatcher.addURI(authority, "providers/account", MATCH_PROVIDERS_WITH_ACCOUNT);
mUrlMatcher.addURI(authority, "accounts", MATCH_ACCOUNTS);
mUrlMatcher.addURI(authority, "accounts/#", MATCH_ACCOUNTS_BY_ID);
mUrlMatcher.addURI(authority, "contacts", MATCH_CONTACTS);
mUrlMatcher.addURI(authority, "contactsWithPresence", MATCH_CONTACTS_JOIN_PRESENCE);
mUrlMatcher.addURI(authority, "contactsBarebone", MATCH_CONTACTS_BAREBONE);
mUrlMatcher.addURI(authority, "contacts/#/#", MATCH_CONTACTS_BY_PROVIDER);
mUrlMatcher.addURI(authority, "contacts/chatting", MATCH_CHATTING_CONTACTS);
mUrlMatcher.addURI(authority, "contacts/chatting/#/#", MATCH_CHATTING_CONTACTS_BY_PROVIDER);
mUrlMatcher.addURI(authority, "contacts/online/#/#", MATCH_ONLINE_CONTACTS_BY_PROVIDER);
mUrlMatcher.addURI(authority, "contacts/offline/#/#", MATCH_OFFLINE_CONTACTS_BY_PROVIDER);
mUrlMatcher.addURI(authority, "contacts/#", MATCH_CONTACT);
mUrlMatcher.addURI(authority, "contacts/blocked", MATCH_BLOCKED_CONTACTS);
mUrlMatcher.addURI(authority, "bulk_contacts", MATCH_CONTACTS_BULK);
mUrlMatcher.addURI(authority, "contacts/onlineCount", MATCH_ONLINE_CONTACT_COUNT);
mUrlMatcher.addURI(authority, "contactLists", MATCH_CONTACTLISTS);
mUrlMatcher.addURI(authority, "contactLists/#/#", MATCH_CONTACTLISTS_BY_PROVIDER);
mUrlMatcher.addURI(authority, "contactLists/#", MATCH_CONTACTLIST);
mUrlMatcher.addURI(authority, "blockedList", MATCH_BLOCKEDLIST);
mUrlMatcher.addURI(authority, "blockedList/#/#", MATCH_BLOCKEDLIST_BY_PROVIDER);
mUrlMatcher.addURI(authority, "contactsEtag", MATCH_CONTACTS_ETAGS);
mUrlMatcher.addURI(authority, "contactsEtag/#", MATCH_CONTACTS_ETAG);
mUrlMatcher.addURI(authority, "presence", MATCH_PRESENCE);
mUrlMatcher.addURI(authority, "presence/#", MATCH_PRESENCE_ID);
mUrlMatcher.addURI(authority, "presence/account/#", MATCH_PRESENCE_BY_ACCOUNT);
mUrlMatcher.addURI(authority, "seed_presence/account/#", MATCH_PRESENCE_SEED_BY_ACCOUNT);
mUrlMatcher.addURI(authority, "bulk_presence", MATCH_PRESENCE_BULK);
mUrlMatcher.addURI(authority, "messages", MATCH_MESSAGES);
mUrlMatcher.addURI(authority, "messagesBy/#/#/*", MATCH_MESSAGES_BY_CONTACT);
mUrlMatcher.addURI(authority, "messages/#", MATCH_MESSAGE);
mUrlMatcher.addURI(authority, "groupMessages", MATCH_GROUP_MESSAGES);
mUrlMatcher.addURI(authority, "groupMessagesBy/#", MATCH_GROUP_MESSAGE_BY);
mUrlMatcher.addURI(authority, "groupMessages/#", MATCH_GROUP_MESSAGE);
mUrlMatcher.addURI(authority, "groupMembers", MATCH_GROUP_MEMBERS);
mUrlMatcher.addURI(authority, "groupMembers/#", MATCH_GROUP_MEMBERS_BY_GROUP);
mUrlMatcher.addURI(authority, "avatars", MATCH_AVATARS);
mUrlMatcher.addURI(authority, "avatars/#", MATCH_AVATAR);
mUrlMatcher.addURI(authority, "avatarsBy/#/#", MATCH_AVATAR_BY_PROVIDER);
mUrlMatcher.addURI(authority, "chats", MATCH_CHATS);
mUrlMatcher.addURI(authority, "chats/account/#", MATCH_CHATS_BY_ACCOUNT);
mUrlMatcher.addURI(authority, "chats/#", MATCH_CHATS_ID);
mUrlMatcher.addURI(authority, "sessionCookies", MATCH_SESSIONS);
mUrlMatcher.addURI(authority, "sessionCookiesBy/#/#", MATCH_SESSIONS_BY_PROVIDER);
mUrlMatcher.addURI(authority, "providerSettings", MATCH_PROVIDER_SETTINGS);
mUrlMatcher.addURI(authority, "providerSettings/#", MATCH_PROVIDER_SETTINGS_BY_ID);
mUrlMatcher.addURI(authority, "providerSettings/#/*",
MATCH_PROVIDER_SETTINGS_BY_ID_AND_NAME);
mUrlMatcher.addURI(authority, "invitations", MATCH_INVITATIONS);
mUrlMatcher.addURI(authority, "invitations/#", MATCH_INVITATION);
mUrlMatcher.addURI(authority, "outgoingRmqMessages", MATCH_OUTGOING_RMQ_MESSAGES);
mUrlMatcher.addURI(authority, "outgoingRmqMessages/#", MATCH_OUTGOING_RMQ_MESSAGE);
mUrlMatcher.addURI(authority, "outgoingHighestRmqId", MATCH_OUTGOING_HIGHEST_RMQ_ID);
mUrlMatcher.addURI(authority, "lastRmqId", MATCH_LAST_RMQ_ID);
mUrlMatcher.addURI(authority, "accountStatus", MATCH_ACCOUNTS_STATUS);
mUrlMatcher.addURI(authority, "accountStatus/#", MATCH_ACCOUNT_STATUS);
mUrlMatcher.addURI(authority, "brandingResMapCache", MATCH_BRANDING_RESOURCE_MAP_CACHE);
|
Methods Summary |
---|
private void | addToQuickSwitch(long newRow)
// Since there are fewer than 10, there must be an empty slot. Let's find it.
int slot = findEmptyQuickSwitchSlot();
if (slot == -1) {
return;
}
updateSlotForChat(newRow, slot);
| private void | appendValuesFromUrl(android.content.ContentValues values, android.net.Uri url, java.lang.String columns)
if(url.getPathSegments().size() <= columns.length) {
throw new IllegalArgumentException("Not enough values in url");
}
for(int i = 0; i < columns.length; i++){
if(values.containsKey(columns[i])){
throw new UnsupportedOperationException("Cannot override the value for " + columns[i]);
}
values.put(columns[i], decodeURLSegment(url.getPathSegments().get(i + 1)));
}
| private static void | appendWhere(java.lang.StringBuilder where, java.lang.String columnName, java.lang.String condition, java.lang.Object value)
if (where.length() > 0) {
where.append(" AND ");
}
where.append(columnName).append(condition);
if(value != null) {
DatabaseUtils.appendValueToSql(where, value);
}
| private static void | appendWhere(java.lang.StringBuilder where, java.lang.String clause)
if (where.length() > 0) {
where.append(" AND ");
}
where.append(clause);
| private void | backfillQuickSwitchSlots()
// Find all the chats without a quick switch slot, and order
Cursor c = query(Im.Chats.CONTENT_URI,
BACKFILL_PROJECTION,
Im.Chats.SHORTCUT + "=-1", null, Im.Chats.LAST_MESSAGE_DATE + " DESC");
try {
if (c.getCount() < 1) {
return;
}
int slot = findEmptyQuickSwitchSlot();
if (slot != -1) {
c.moveToFirst();
long id = c.getLong(c.getColumnIndex(Im.Chats._ID));
updateSlotForChat(id, slot);
}
} finally {
c.close();
}
| private void | buildQueryContactsByProvider(android.database.sqlite.SQLiteQueryBuilder qb, java.lang.StringBuilder whereClause, android.net.Uri url)
qb.setTables(CONTACT_JOIN_PRESENCE_CHAT_AVATAR_TABLE);
qb.setProjectionMap(sContactsProjectionMap);
// we don't really need the provider id in query. account id
// is enough.
appendWhere(whereClause, Im.Contacts.ACCOUNT, "=", url.getLastPathSegment());
| private static java.lang.String | decodeURLSegment(java.lang.String segment)
try {
return URLDecoder.decode(segment, "UTF-8");
} catch (UnsupportedEncodingException e) {
// impossible
return segment;
}
| public final int | delete(android.net.Uri url, java.lang.String selection, java.lang.String[] selectionArgs)
int result;
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
db.beginTransaction();
try {
result = deleteInternal(url, selection, selectionArgs);
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
if (result > 0) {
getContext().getContentResolver()
.notifyChange(url, null /* observer */, false /* sync */);
}
return result;
| public int | deleteInternal(android.net.Uri url, java.lang.String userWhere, java.lang.String[] whereArgs)
String tableToChange;
String idColumnName = null;
String changedItemId = null;
StringBuilder whereClause = new StringBuilder();
if(userWhere != null) {
whereClause.append(userWhere);
}
boolean notifyMessagesContentUri = false;
boolean notifyGroupMessagesContentUri = false;
boolean notifyContactListContentUri = false;
boolean notifyProviderAccountContentUri = false;
int match = mUrlMatcher.match(url);
boolean contactDeleted = false;
long deletedContactId = 0;
boolean backfillQuickSwitchSlots = false;
switch (match) {
case MATCH_PROVIDERS:
tableToChange = TABLE_PROVIDERS;
notifyProviderAccountContentUri = true;
break;
case MATCH_ACCOUNTS_BY_ID:
changedItemId = url.getPathSegments().get(1);
// fall through
case MATCH_ACCOUNTS:
tableToChange = TABLE_ACCOUNTS;
notifyProviderAccountContentUri = true;
break;
case MATCH_ACCOUNT_STATUS:
changedItemId = url.getPathSegments().get(1);
// fall through
case MATCH_ACCOUNTS_STATUS:
tableToChange = TABLE_ACCOUNT_STATUS;
notifyProviderAccountContentUri = true;
break;
case MATCH_CONTACTS:
case MATCH_CONTACTS_BAREBONE:
tableToChange = TABLE_CONTACTS;
contactDeleted = true;
break;
case MATCH_CONTACT:
tableToChange = TABLE_CONTACTS;
changedItemId = url.getPathSegments().get(1);
try {
deletedContactId = Long.parseLong(changedItemId);
} catch (NumberFormatException ex) {
}
contactDeleted = true;
break;
case MATCH_CONTACTS_BY_PROVIDER:
tableToChange = TABLE_CONTACTS;
appendWhere(whereClause, Im.Contacts.ACCOUNT, "=", url.getPathSegments().get(2));
contactDeleted = true;
break;
case MATCH_CONTACTLISTS_BY_PROVIDER:
appendWhere(whereClause, Im.ContactList.ACCOUNT, "=",
url.getPathSegments().get(2));
// fall through
case MATCH_CONTACTLISTS:
tableToChange = TABLE_CONTACT_LIST;
notifyContactListContentUri = true;
break;
case MATCH_CONTACTLIST:
tableToChange = TABLE_CONTACT_LIST;
changedItemId = url.getPathSegments().get(1);
break;
case MATCH_BLOCKEDLIST:
tableToChange = TABLE_BLOCKED_LIST;
break;
case MATCH_BLOCKEDLIST_BY_PROVIDER:
tableToChange = TABLE_BLOCKED_LIST;
appendWhere(whereClause, Im.BlockedList.ACCOUNT, "=", url.getPathSegments().get(2));
break;
case MATCH_CONTACTS_ETAGS:
tableToChange = TABLE_CONTACTS_ETAG;
break;
case MATCH_CONTACTS_ETAG:
tableToChange = TABLE_CONTACTS_ETAG;
changedItemId = url.getPathSegments().get(1);
break;
case MATCH_MESSAGES:
tableToChange = TABLE_MESSAGES;
break;
case MATCH_MESSAGES_BY_CONTACT:
tableToChange = TABLE_MESSAGES;
appendWhere(whereClause, Im.Messages.ACCOUNT, "=",
url.getPathSegments().get(2));
appendWhere(whereClause, Im.Messages.CONTACT, "=",
decodeURLSegment(url.getPathSegments().get(3)));
notifyMessagesContentUri = true;
break;
case MATCH_MESSAGE:
tableToChange = TABLE_MESSAGES;
changedItemId = url.getPathSegments().get(1);
notifyMessagesContentUri = true;
break;
case MATCH_GROUP_MEMBERS:
tableToChange = TABLE_GROUP_MEMBERS;
break;
case MATCH_GROUP_MEMBERS_BY_GROUP:
tableToChange = TABLE_GROUP_MEMBERS;
appendWhere(whereClause, Im.GroupMembers.GROUP, "=", url.getPathSegments().get(1));
break;
case MATCH_GROUP_MESSAGES:
tableToChange = TABLE_GROUP_MESSAGES;
break;
case MATCH_GROUP_MESSAGE_BY:
tableToChange = TABLE_GROUP_MESSAGES;
changedItemId = url.getPathSegments().get(1);
idColumnName = Im.GroupMessages.GROUP;
notifyGroupMessagesContentUri = true;
break;
case MATCH_GROUP_MESSAGE:
tableToChange = TABLE_GROUP_MESSAGES;
changedItemId = url.getPathSegments().get(1);
notifyGroupMessagesContentUri = true;
break;
case MATCH_INVITATIONS:
tableToChange = TABLE_INVITATIONS;
break;
case MATCH_INVITATION:
tableToChange = TABLE_INVITATIONS;
changedItemId = url.getPathSegments().get(1);
break;
case MATCH_AVATARS:
tableToChange = TABLE_AVATARS;
break;
case MATCH_AVATAR:
tableToChange = TABLE_AVATARS;
changedItemId = url.getPathSegments().get(1);
break;
case MATCH_AVATAR_BY_PROVIDER:
tableToChange = TABLE_AVATARS;
changedItemId = url.getPathSegments().get(2);
idColumnName = Im.Avatars.ACCOUNT;
break;
case MATCH_CHATS:
tableToChange = TABLE_CHATS;
backfillQuickSwitchSlots = true;
break;
case MATCH_CHATS_BY_ACCOUNT:
tableToChange = TABLE_CHATS;
if (whereClause.length() > 0) {
whereClause.append(" AND ");
}
whereClause.append(Im.Chats.CONTACT_ID);
whereClause.append(" in (select ");
whereClause.append(Im.Contacts._ID);
whereClause.append(" from ");
whereClause.append(TABLE_CONTACTS);
whereClause.append(" where ");
whereClause.append(Im.Contacts.ACCOUNT);
whereClause.append("='");
whereClause.append(url.getLastPathSegment());
whereClause.append("')");
if (DBG) log("deleteInternal (MATCH_CHATS_BY_ACCOUNT): sel => " +
whereClause.toString());
changedItemId = null;
break;
case MATCH_CHATS_ID:
tableToChange = TABLE_CHATS;
changedItemId = url.getPathSegments().get(1);
idColumnName = Im.Chats.CONTACT_ID;
break;
case MATCH_PRESENCE:
tableToChange = TABLE_PRESENCE;
break;
case MATCH_PRESENCE_ID:
tableToChange = TABLE_PRESENCE;
changedItemId = url.getPathSegments().get(1);
idColumnName = Im.Presence.CONTACT_ID;
break;
case MATCH_PRESENCE_BY_ACCOUNT:
tableToChange = TABLE_PRESENCE;
if (whereClause.length() > 0) {
whereClause.append(" AND ");
}
whereClause.append(Im.Presence.CONTACT_ID);
whereClause.append(" in (select ");
whereClause.append(Im.Contacts._ID);
whereClause.append(" from ");
whereClause.append(TABLE_CONTACTS);
whereClause.append(" where ");
whereClause.append(Im.Contacts.ACCOUNT);
whereClause.append("='");
whereClause.append(url.getLastPathSegment());
whereClause.append("')");
if (DBG) log("deleteInternal (MATCH_PRESENCE_BY_ACCOUNT): sel => " +
whereClause.toString());
changedItemId = null;
break;
case MATCH_SESSIONS:
tableToChange = TABLE_SESSION_COOKIES;
break;
case MATCH_SESSIONS_BY_PROVIDER:
tableToChange = TABLE_SESSION_COOKIES;
changedItemId = url.getPathSegments().get(2);
idColumnName = Im.SessionCookies.ACCOUNT;
break;
case MATCH_PROVIDER_SETTINGS_BY_ID_AND_NAME:
tableToChange = TABLE_PROVIDER_SETTINGS;
String providerId = url.getPathSegments().get(1);
String name = url.getPathSegments().get(2);
appendWhere(whereClause, Im.ProviderSettings.PROVIDER, "=", providerId);
appendWhere(whereClause, Im.ProviderSettings.NAME, "=", name);
break;
case MATCH_OUTGOING_RMQ_MESSAGES:
tableToChange = TABLE_OUTGOING_RMQ_MESSAGES;
break;
case MATCH_LAST_RMQ_ID:
tableToChange = TABLE_LAST_RMQ_ID;
break;
case MATCH_BRANDING_RESOURCE_MAP_CACHE:
tableToChange = TABLE_BRANDING_RESOURCE_MAP_CACHE;
break;
default:
throw new UnsupportedOperationException("Cannot delete that URL: " + url);
}
if (idColumnName == null) {
idColumnName = "_id";
}
if (changedItemId != null) {
appendWhere(whereClause, idColumnName, "=", changedItemId);
}
if (DBG) log("delete from " + url + " WHERE " + whereClause);
final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
int count = db.delete(tableToChange, whereClause.toString(), whereArgs);
if (contactDeleted && count > 0) {
// since the contact cleanup triggers no longer work for cross database tables,
// we have to do it by hand here.
performContactRemovalCleanup(deletedContactId);
}
if (count > 0) {
// In most case, we query contacts with presence and chats joined, thus
// we should also notify that contacts changes when presence or chats changed.
if (match == MATCH_CHATS || match == MATCH_CHATS_ID
|| match == MATCH_PRESENCE || match == MATCH_PRESENCE_ID
|| match == MATCH_CONTACTS_BAREBONE) {
getContext().getContentResolver().notifyChange(Im.Contacts.CONTENT_URI, null);
} else if (notifyMessagesContentUri) {
getContext().getContentResolver().notifyChange(Im.Messages.CONTENT_URI, null);
} else if (notifyGroupMessagesContentUri) {
getContext().getContentResolver().notifyChange(Im.GroupMessages.CONTENT_URI, null);
} else if (notifyContactListContentUri) {
getContext().getContentResolver().notifyChange(Im.ContactList.CONTENT_URI, null);
} else if (notifyProviderAccountContentUri) {
if (DBG) log("notify delete for " + Im.Provider.CONTENT_URI_WITH_ACCOUNT);
getContext().getContentResolver().notifyChange(Im.Provider.CONTENT_URI_WITH_ACCOUNT,
null);
}
if (backfillQuickSwitchSlots) {
backfillQuickSwitchSlots();
}
}
return count;
| private void | deleteWithContactId(android.database.sqlite.SQLiteDatabase db, long contactId, java.lang.String tableName, java.lang.String columnName)
db.delete(tableName, columnName + '=" + contactId, null /* selection args */);
| private int | findEmptyQuickSwitchSlot()
Cursor c = queryInternal(Im.Chats.CONTENT_URI, FIND_SHORTCUT_PROJECTION, null, null, null);
final int N = c.getCount();
try {
// If there are 10 or more chats then all the quick switch slots are already filled
if (N >= 10) {
return -1;
}
int slots = 0;
int column = c.getColumnIndex(Im.Chats.SHORTCUT);
// The map is here because numbers go from 0-9, but we want to assign slots in
// 0, 9, 8, ..., 1 order to match the right-to-left reading of the number row
// on the keyboard.
int[] map = new int[] { 0, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
// Mark all the slots that are in use
// The shortcuts represent actual keyboard number row keys, and not ordinals.
// So 7 would mean the shortcut is the 7 key on the keyboard and NOT the 7th
// shortcut. The passing of slot through map[] below maps these keyboard key
// shortcuts into an ordinal bit position in the 'slots' bitfield.
for (c.moveToFirst(); ! c.isAfterLast(); c.moveToNext()) {
int slot = c.getInt(column);
if (slot != -1) {
slots |= (1 << map[slot]);
}
}
// Try to find an empty one
// As we exit this, the push of i through map[] maps the ordinal bit position
// in the 'slots' bitfield onto a key on the number row of the device keyboard.
// The keyboard key is what is used to designate the shortcut.
for (int i = 0; i < 10; i++) {
if ((slots & (1 << i)) == 0) {
return map[i];
}
}
return -1;
} finally {
c.close();
}
| public java.lang.String | getType(android.net.Uri url)
int match = mUrlMatcher.match(url);
switch (match) {
case MATCH_PROVIDERS:
return Im.Provider.CONTENT_TYPE;
case MATCH_PROVIDERS_BY_ID:
return Im.Provider.CONTENT_ITEM_TYPE;
case MATCH_ACCOUNTS:
return Im.Account.CONTENT_TYPE;
case MATCH_ACCOUNTS_BY_ID:
return Im.Account.CONTENT_ITEM_TYPE;
case MATCH_CONTACTS:
case MATCH_CONTACTS_BY_PROVIDER:
case MATCH_ONLINE_CONTACTS_BY_PROVIDER:
case MATCH_OFFLINE_CONTACTS_BY_PROVIDER:
case MATCH_CONTACTS_BULK:
case MATCH_CONTACTS_BAREBONE:
case MATCH_CONTACTS_JOIN_PRESENCE:
return Im.Contacts.CONTENT_TYPE;
case MATCH_CONTACT:
return Im.Contacts.CONTENT_ITEM_TYPE;
case MATCH_CONTACTLISTS:
case MATCH_CONTACTLISTS_BY_PROVIDER:
return Im.ContactList.CONTENT_TYPE;
case MATCH_CONTACTLIST:
return Im.ContactList.CONTENT_ITEM_TYPE;
case MATCH_BLOCKEDLIST:
case MATCH_BLOCKEDLIST_BY_PROVIDER:
return Im.BlockedList.CONTENT_TYPE;
case MATCH_CONTACTS_ETAGS:
case MATCH_CONTACTS_ETAG:
return Im.ContactsEtag.CONTENT_TYPE;
case MATCH_MESSAGES:
case MATCH_MESSAGES_BY_CONTACT:
return Im.Messages.CONTENT_TYPE;
case MATCH_MESSAGE:
return Im.Messages.CONTENT_ITEM_TYPE;
case MATCH_GROUP_MESSAGES:
case MATCH_GROUP_MESSAGE_BY:
return Im.GroupMessages.CONTENT_TYPE;
case MATCH_GROUP_MESSAGE:
return Im.GroupMessages.CONTENT_ITEM_TYPE;
case MATCH_PRESENCE:
case MATCH_PRESENCE_BULK:
return Im.Presence.CONTENT_TYPE;
case MATCH_AVATARS:
return Im.Avatars.CONTENT_TYPE;
case MATCH_AVATAR:
return Im.Avatars.CONTENT_ITEM_TYPE;
case MATCH_CHATS:
return Im.Chats.CONTENT_TYPE;
case MATCH_CHATS_ID:
return Im.Chats.CONTENT_ITEM_TYPE;
case MATCH_INVITATIONS:
return Im.Invitation.CONTENT_TYPE;
case MATCH_INVITATION:
return Im.Invitation.CONTENT_ITEM_TYPE;
case MATCH_GROUP_MEMBERS:
case MATCH_GROUP_MEMBERS_BY_GROUP:
return Im.GroupMembers.CONTENT_TYPE;
case MATCH_SESSIONS:
case MATCH_SESSIONS_BY_PROVIDER:
return Im.SessionCookies.CONTENT_TYPE;
case MATCH_PROVIDER_SETTINGS:
return Im.ProviderSettings.CONTENT_TYPE;
case MATCH_ACCOUNTS_STATUS:
return Im.AccountStatus.CONTENT_TYPE;
case MATCH_ACCOUNT_STATUS:
return Im.AccountStatus.CONTENT_ITEM_TYPE;
default:
throw new IllegalArgumentException("Unknown URL");
}
| public final android.net.Uri | insert(android.net.Uri url, android.content.ContentValues values)
Uri result;
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
db.beginTransaction();
try {
result = insertInternal(url, values);
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
if (result != null) {
getContext().getContentResolver()
.notifyChange(url, null /* observer */, false /* sync */);
}
return result;
| boolean | insertBulkContacts(android.content.ContentValues values)
//if (DBG) log("insertBulkContacts: begin");
ArrayList<String> usernames = values.getStringArrayList(Im.Contacts.USERNAME);
ArrayList<String> nicknames = values.getStringArrayList(Im.Contacts.NICKNAME);
int usernameCount = usernames.size();
int nicknameCount = nicknames.size();
if (usernameCount != nicknameCount) {
Log.e(LOG_TAG, "[ImProvider] insertBulkContacts: input bundle " +
"username & nickname lists have diff. length!");
return false;
}
ArrayList<String> contactTypeArray = values.getStringArrayList(Im.Contacts.TYPE);
ArrayList<String> subscriptionStatusArray =
values.getStringArrayList(Im.Contacts.SUBSCRIPTION_STATUS);
ArrayList<String> subscriptionTypeArray =
values.getStringArrayList(Im.Contacts.SUBSCRIPTION_TYPE);
ArrayList<String> quickContactArray = values.getStringArrayList(Im.Contacts.QUICK_CONTACT);
ArrayList<String> rejectedArray = values.getStringArrayList(Im.Contacts.REJECTED);
int sum = 0;
final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
db.beginTransaction();
try {
Long provider = values.getAsLong(Im.Contacts.PROVIDER);
Long account = values.getAsLong(Im.Contacts.ACCOUNT);
Long listId = values.getAsLong(Im.Contacts.CONTACTLIST);
ContentValues contactValues = new ContentValues();
contactValues.put(Im.Contacts.PROVIDER, provider);
contactValues.put(Im.Contacts.ACCOUNT, account);
contactValues.put(Im.Contacts.CONTACTLIST, listId);
ContentValues presenceValues = new ContentValues();
presenceValues.put(Im.Presence.PRESENCE_STATUS,
Im.Presence.OFFLINE);
for (int i=0; i<usernameCount; i++) {
String username = usernames.get(i);
String nickname = nicknames.get(i);
int type = 0;
int subscriptionStatus = 0;
int subscriptionType = 0;
int quickContact = 0;
int rejected = 0;
try {
type = Integer.parseInt(contactTypeArray.get(i));
if (subscriptionStatusArray != null) {
subscriptionStatus = Integer.parseInt(subscriptionStatusArray.get(i));
}
if (subscriptionTypeArray != null) {
subscriptionType = Integer.parseInt(subscriptionTypeArray.get(i));
}
if (quickContactArray != null) {
quickContact = Integer.parseInt(quickContactArray.get(i));
}
if (rejectedArray != null) {
rejected = Integer.parseInt(rejectedArray.get(i));
}
} catch (NumberFormatException ex) {
Log.e(LOG_TAG, "insertBulkContacts: caught " + ex);
}
/*
if (DBG) log("insertBulkContacts[" + i + "] username=" +
username + ", nickname=" + nickname + ", type=" + type +
", subscriptionStatus=" + subscriptionStatus + ", subscriptionType=" +
subscriptionType + ", qc=" + quickContact);
*/
contactValues.put(Im.Contacts.USERNAME, username);
contactValues.put(Im.Contacts.NICKNAME, nickname);
contactValues.put(Im.Contacts.TYPE, type);
if (subscriptionStatusArray != null) {
contactValues.put(Im.Contacts.SUBSCRIPTION_STATUS, subscriptionStatus);
}
if (subscriptionTypeArray != null) {
contactValues.put(Im.Contacts.SUBSCRIPTION_TYPE, subscriptionType);
}
if (quickContactArray != null) {
contactValues.put(Im.Contacts.QUICK_CONTACT, quickContact);
}
if (rejectedArray != null) {
contactValues.put(Im.Contacts.REJECTED, rejected);
}
long rowId = 0;
/* save this code for when we add constraint (account, username) to the contacts
table
try {
rowId = db.insertOrThrow(TABLE_CONTACTS, USERNAME, contactValues);
} catch (android.database.sqlite.SQLiteConstraintException ex) {
if (DBG) log("insertBulkContacts: insert " + username + " caught " + ex);
// append username to the selection clause
updateSelection.delete(0, updateSelection.length());
updateSelection.append(Im.Contacts.USERNAME);
updateSelection.append("=?");
updateSelectionArgs[0] = username;
int updated = db.update(TABLE_CONTACTS, contactValues,
updateSelection.toString(), updateSelectionArgs);
if (DBG && updated != 1) {
log("insertBulkContacts: update " + username + " failed!");
}
}
*/
rowId = db.insert(TABLE_CONTACTS, USERNAME, contactValues);
if (rowId > 0) {
sum++;
if (!USE_CONTACT_PRESENCE_TRIGGER) {
// seed the presence for the new contact
//if (DBG) log("seedPresence for pid " + rowId);
presenceValues.put(Im.Presence.CONTACT_ID, rowId);
db.insert(TABLE_PRESENCE, null, presenceValues);
}
}
// yield the lock if anyone else is trying to
// perform a db operation here.
db.yieldIfContended();
}
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
// We know that we succeeded becuase endTransaction throws if the transaction failed.
if (DBG) log("insertBulkContacts: added " + sum + " contacts!");
return true;
| public android.net.Uri | insertInternal(android.net.Uri url, android.content.ContentValues initialValues)
Uri resultUri = null;
long rowID = 0;
boolean notifyContactListContentUri = false;
boolean notifyContactContentUri = false;
boolean notifyMessagesContentUri = false;
boolean notifyGroupMessagesContentUri = false;
boolean notifyProviderAccountContentUri = false;
final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
int match = mUrlMatcher.match(url);
if (DBG) log("insert to " + url + ", match " + match);
switch (match) {
case MATCH_PROVIDERS:
// Insert into the providers table
rowID = db.insert(TABLE_PROVIDERS, "name", initialValues);
if (rowID > 0) {
resultUri = Uri.parse(Im.Provider.CONTENT_URI + "/" + rowID);
}
notifyProviderAccountContentUri = true;
break;
case MATCH_ACCOUNTS:
// Insert into the accounts table
rowID = db.insert(TABLE_ACCOUNTS, "name", initialValues);
if (rowID > 0) {
resultUri = Uri.parse(Im.Account.CONTENT_URI + "/" + rowID);
}
notifyProviderAccountContentUri = true;
break;
case MATCH_CONTACTS_BY_PROVIDER:
appendValuesFromUrl(initialValues, url, Im.Contacts.PROVIDER,
Im.Contacts.ACCOUNT);
// fall through
case MATCH_CONTACTS:
case MATCH_CONTACTS_BAREBONE:
// Insert into the contacts table
rowID = db.insert(TABLE_CONTACTS, "username", initialValues);
if (rowID > 0) {
resultUri = Uri.parse(Im.Contacts.CONTENT_URI + "/" + rowID);
}
notifyContactContentUri = true;
break;
case MATCH_CONTACTS_BULK:
if (insertBulkContacts(initialValues)) {
// notify change using the "content://im/contacts" url,
// so the change will be observed by listeners interested
// in contacts changes.
resultUri = Im.Contacts.CONTENT_URI;
}
notifyContactContentUri = true;
break;
case MATCH_CONTACTLISTS_BY_PROVIDER:
appendValuesFromUrl(initialValues, url, Im.ContactList.PROVIDER,
Im.ContactList.ACCOUNT);
// fall through
case MATCH_CONTACTLISTS:
// Insert into the contactList table
rowID = db.insert(TABLE_CONTACT_LIST, "name", initialValues);
if (rowID > 0) {
resultUri = Uri.parse(Im.ContactList.CONTENT_URI + "/" + rowID);
}
notifyContactListContentUri = true;
break;
case MATCH_BLOCKEDLIST_BY_PROVIDER:
appendValuesFromUrl(initialValues, url, Im.BlockedList.PROVIDER,
Im.BlockedList.ACCOUNT);
// fall through
case MATCH_BLOCKEDLIST:
// Insert into the blockedList table
rowID = db.insert(TABLE_BLOCKED_LIST, "username", initialValues);
if (rowID > 0) {
resultUri = Uri.parse(Im.BlockedList.CONTENT_URI + "/" + rowID);
}
break;
case MATCH_CONTACTS_ETAGS:
rowID = db.replace(TABLE_CONTACTS_ETAG, Im.ContactsEtag.ETAG, initialValues);
if (rowID > 0) {
resultUri = Uri.parse(Im.ContactsEtag.CONTENT_URI + "/" + rowID);
}
break;
case MATCH_MESSAGES_BY_CONTACT:
appendValuesFromUrl(initialValues, url, Im.Messages.PROVIDER,
Im.Messages.ACCOUNT, Im.Messages.CONTACT);
notifyMessagesContentUri = true;
// fall through
case MATCH_MESSAGES:
// Insert into the messages table.
rowID = db.insert(TABLE_MESSAGES, "contact", initialValues);
if (rowID > 0) {
resultUri = Uri.parse(Im.Messages.CONTENT_URI + "/" + rowID);
}
break;
case MATCH_INVITATIONS:
rowID = db.insert(TABLE_INVITATIONS, null, initialValues);
if (rowID > 0) {
resultUri = Uri.parse(Im.Invitation.CONTENT_URI + "/" + rowID);
}
break;
case MATCH_GROUP_MEMBERS:
rowID = db.insert(TABLE_GROUP_MEMBERS, "nickname", initialValues);
if (rowID > 0) {
resultUri = Uri.parse(Im.GroupMembers.CONTENT_URI + "/" + rowID);
}
break;
case MATCH_GROUP_MEMBERS_BY_GROUP:
appendValuesFromUrl(initialValues, url, Im.GroupMembers.GROUP);
rowID = db.insert(TABLE_GROUP_MEMBERS, "nickname", initialValues);
if (rowID > 0) {
resultUri = Uri.parse(Im.GroupMembers.CONTENT_URI + "/" + rowID);
}
break;
case MATCH_GROUP_MESSAGE_BY:
appendValuesFromUrl(initialValues, url, Im.GroupMembers.GROUP);
notifyGroupMessagesContentUri = true;
// fall through
case MATCH_GROUP_MESSAGES:
rowID = db.insert(TABLE_GROUP_MESSAGES, "group", initialValues);
if (rowID > 0) {
resultUri = Uri.parse(Im.GroupMessages.CONTENT_URI + "/" + rowID);
}
break;
case MATCH_AVATAR_BY_PROVIDER:
appendValuesFromUrl(initialValues, url, Im.Avatars.PROVIDER, Im.Avatars.ACCOUNT);
// fall through
case MATCH_AVATARS:
// Insert into the avatars table
rowID = db.replace(TABLE_AVATARS, "contact", initialValues);
if (rowID > 0) {
resultUri = Uri.parse(Im.Avatars.CONTENT_URI + "/" + rowID);
}
break;
case MATCH_CHATS_ID:
appendValuesFromUrl(initialValues, url, Im.Chats.CONTACT_ID);
// fall through
case MATCH_CHATS:
// Insert into the chats table
initialValues.put(Im.Chats.SHORTCUT, -1);
rowID = db.replace(TABLE_CHATS, Im.Chats.CONTACT_ID, initialValues);
if (rowID > 0) {
resultUri = Uri.parse(Im.Chats.CONTENT_URI + "/" + rowID);
addToQuickSwitch(rowID);
}
notifyContactContentUri = true;
break;
case MATCH_PRESENCE:
rowID = db.replace(TABLE_PRESENCE, null, initialValues);
if (rowID > 0) {
resultUri = Uri.parse(Im.Presence.CONTENT_URI + "/" + rowID);
}
notifyContactContentUri = true;
break;
case MATCH_PRESENCE_SEED_BY_ACCOUNT:
try {
seedInitialPresenceByAccount(Long.parseLong(url.getLastPathSegment()));
resultUri = Im.Presence.CONTENT_URI;
} catch (NumberFormatException ex) {
throw new IllegalArgumentException();
}
break;
case MATCH_SESSIONS_BY_PROVIDER:
appendValuesFromUrl(initialValues, url, Im.SessionCookies.PROVIDER,
Im.SessionCookies.ACCOUNT);
// fall through
case MATCH_SESSIONS:
rowID = db.insert(TABLE_SESSION_COOKIES, null, initialValues);
if(rowID > 0) {
resultUri = Uri.parse(Im.SessionCookies.CONTENT_URI + "/" + rowID);
}
break;
case MATCH_PROVIDER_SETTINGS:
rowID = db.replace(TABLE_PROVIDER_SETTINGS, null, initialValues);
if (rowID > 0) {
resultUri = Uri.parse(Im.ProviderSettings.CONTENT_URI + "/" + rowID);
}
break;
case MATCH_OUTGOING_RMQ_MESSAGES:
rowID = db.insert(TABLE_OUTGOING_RMQ_MESSAGES, null, initialValues);
if (rowID > 0) {
resultUri = Uri.parse(Im.OutgoingRmq.CONTENT_URI + "/" + rowID);
}
break;
case MATCH_LAST_RMQ_ID:
rowID = db.replace(TABLE_LAST_RMQ_ID, null, initialValues);
if (rowID > 0) {
resultUri = Uri.parse(Im.LastRmqId.CONTENT_URI + "/" + rowID);
}
break;
case MATCH_ACCOUNTS_STATUS:
rowID = db.replace(TABLE_ACCOUNT_STATUS, null, initialValues);
if (rowID > 0) {
resultUri = Uri.parse(Im.AccountStatus.CONTENT_URI + "/" + rowID);
}
notifyProviderAccountContentUri = true;
break;
case MATCH_BRANDING_RESOURCE_MAP_CACHE:
rowID = db.insert(TABLE_BRANDING_RESOURCE_MAP_CACHE, null, initialValues);
if (rowID > 0) {
resultUri = Uri.parse(Im.BrandingResourceMapCache.CONTENT_URI + "/" + rowID);
}
break;
default:
throw new UnsupportedOperationException("Cannot insert into URL: " + url);
}
// TODO: notify the data change observer?
if (resultUri != null) {
ContentResolver resolver = getContext().getContentResolver();
// In most case, we query contacts with presence and chats joined, thus
// we should also notify that contacts changes when presence or chats changed.
if (notifyContactContentUri) {
resolver.notifyChange(Im.Contacts.CONTENT_URI, null);
}
if (notifyContactListContentUri) {
resolver.notifyChange(Im.ContactList.CONTENT_URI, null);
}
if (notifyMessagesContentUri) {
resolver.notifyChange(Im.Messages.CONTENT_URI, null);
}
if (notifyGroupMessagesContentUri) {
resolver.notifyChange(Im.GroupMessages.CONTENT_URI, null);
}
if (notifyProviderAccountContentUri) {
if (DBG) log("notify insert for " + Im.Provider.CONTENT_URI_WITH_ACCOUNT);
resolver.notifyChange(Im.Provider.CONTENT_URI_WITH_ACCOUNT,
null);
}
}
return resultUri;
| static void | log(java.lang.String message)
Log.d(LOG_TAG, message);
| public boolean | onCreate()
mOpenHelper = new DatabaseHelper(getContext());
return true;
| public android.os.ParcelFileDescriptor | openFile(android.net.Uri uri, java.lang.String mode)
return openFileHelper(uri, mode);
| private void | performComplexDelete(android.database.sqlite.SQLiteDatabase db, java.lang.String tableName, java.lang.String selection, java.lang.String[] selectionArgs)
if (DBG) log("performComplexDelete for table " + tableName + ", selection => " + selection);
int count = db.delete(tableName, selection, selectionArgs);
if (DBG) log("performComplexDelete: deleted " + count + " rows");
| private void | performContactRemovalCleanup(long contactId)
final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
if (contactId > 0) {
deleteWithContactId(db, contactId, TABLE_PRESENCE, Im.Presence.CONTACT_ID);
deleteWithContactId(db, contactId, TABLE_CHATS, Im.Chats.CONTACT_ID);
deleteWithContactId(db, contactId, TABLE_GROUP_MEMBERS, Im.GroupMembers.GROUP);
deleteWithContactId(db, contactId, TABLE_GROUP_MESSAGES, Im.GroupMessages.GROUP);
} else {
performComplexDelete(db, TABLE_PRESENCE, DELETE_PRESENCE_SELECTION, null);
performComplexDelete(db, TABLE_CHATS, DELETE_CHATS_SELECTION, null);
performComplexDelete(db, TABLE_GROUP_MEMBERS, DELETE_GROUP_MEMBER_SELECTION, null);
performComplexDelete(db, TABLE_GROUP_MESSAGES, DELETE_GROUP_MESSAGES_SELECTION, null);
}
| public final android.database.Cursor | query(android.net.Uri url, java.lang.String[] projection, java.lang.String selection, java.lang.String[] selectionArgs, java.lang.String sortOrder)
return queryInternal(url, projection, selection, selectionArgs, sortOrder);
| public android.database.Cursor | queryInternal(android.net.Uri url, java.lang.String[] projectionIn, java.lang.String selection, java.lang.String[] selectionArgs, java.lang.String sort)
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
StringBuilder whereClause = new StringBuilder();
if(selection != null) {
whereClause.append(selection);
}
String groupBy = null;
String limit = null;
// Generate the body of the query
int match = mUrlMatcher.match(url);
if (DBG) {
log("query " + url + ", match " + match + ", where " + selection);
if (selectionArgs != null) {
for (String selectionArg : selectionArgs) {
log(" selectionArg: " + selectionArg);
}
}
}
switch (match) {
case MATCH_PROVIDERS_BY_ID:
appendWhere(whereClause, Im.Provider._ID, "=", url.getPathSegments().get(1));
// fall thru.
case MATCH_PROVIDERS:
qb.setTables(TABLE_PROVIDERS);
break;
case MATCH_PROVIDERS_WITH_ACCOUNT:
qb.setTables(PROVIDER_JOIN_ACCOUNT_TABLE);
qb.setProjectionMap(sProviderAccountsProjectionMap);
break;
case MATCH_ACCOUNTS_BY_ID:
appendWhere(whereClause, Im.Account._ID, "=", url.getPathSegments().get(1));
// falls down
case MATCH_ACCOUNTS:
qb.setTables(TABLE_ACCOUNTS);
break;
case MATCH_CONTACTS:
qb.setTables(CONTACT_JOIN_PRESENCE_CHAT_AVATAR_TABLE);
qb.setProjectionMap(sContactsProjectionMap);
break;
case MATCH_CONTACTS_JOIN_PRESENCE:
qb.setTables(CONTACT_JOIN_PRESENCE_TABLE);
qb.setProjectionMap(sContactsProjectionMap);
break;
case MATCH_CONTACTS_BAREBONE:
qb.setTables(TABLE_CONTACTS);
break;
case MATCH_CHATTING_CONTACTS:
qb.setTables(CONTACT_JOIN_PRESENCE_CHAT_AVATAR_TABLE);
qb.setProjectionMap(sContactsProjectionMap);
appendWhere(whereClause, "chats.last_message_date IS NOT NULL");
// no need to add the non blocked contacts clause because
// blocked contacts can't have conversations.
break;
case MATCH_CONTACTS_BY_PROVIDER:
buildQueryContactsByProvider(qb, whereClause, url);
appendWhere(whereClause, NON_BLOCKED_CONTACTS_WHERE_CLAUSE);
break;
case MATCH_CHATTING_CONTACTS_BY_PROVIDER:
buildQueryContactsByProvider(qb, whereClause, url);
appendWhere(whereClause, "chats.last_message_date IS NOT NULL");
// no need to add the non blocked contacts clause because
// blocked contacts can't have conversations.
break;
case MATCH_NO_CHATTING_CONTACTS_BY_PROVIDER:
buildQueryContactsByProvider(qb, whereClause, url);
appendWhere(whereClause, "chats.last_message_date IS NULL");
appendWhere(whereClause, NON_BLOCKED_CONTACTS_WHERE_CLAUSE);
break;
case MATCH_ONLINE_CONTACTS_BY_PROVIDER:
buildQueryContactsByProvider(qb, whereClause, url);
appendWhere(whereClause, Im.Contacts.PRESENCE_STATUS, "!=", Im.Presence.OFFLINE);
appendWhere(whereClause, NON_BLOCKED_CONTACTS_WHERE_CLAUSE);
break;
case MATCH_OFFLINE_CONTACTS_BY_PROVIDER:
buildQueryContactsByProvider(qb, whereClause, url);
appendWhere(whereClause, Im.Contacts.PRESENCE_STATUS, "=", Im.Presence.OFFLINE);
appendWhere(whereClause, NON_BLOCKED_CONTACTS_WHERE_CLAUSE);
break;
case MATCH_BLOCKED_CONTACTS:
qb.setTables(CONTACT_JOIN_PRESENCE_CHAT_AVATAR_TABLE);
qb.setProjectionMap(sContactsProjectionMap);
appendWhere(whereClause, BLOCKED_CONTACTS_WHERE_CLAUSE);
break;
case MATCH_CONTACT:
qb.setTables(CONTACT_JOIN_PRESENCE_CHAT_AVATAR_TABLE);
qb.setProjectionMap(sContactsProjectionMap);
appendWhere(whereClause, "contacts._id", "=", url.getPathSegments().get(1));
break;
case MATCH_ONLINE_CONTACT_COUNT:
qb.setTables(CONTACT_JOIN_PRESENCE_CHAT_TABLE);
qb.setProjectionMap(sContactsProjectionMap);
appendWhere(whereClause, Im.Contacts.PRESENCE_STATUS, "!=", Im.Presence.OFFLINE);
appendWhere(whereClause, "chats.last_message_date IS NULL");
appendWhere(whereClause, NON_BLOCKED_CONTACTS_WHERE_CLAUSE);
groupBy = Im.Contacts.CONTACTLIST;
break;
case MATCH_CONTACTLISTS_BY_PROVIDER:
appendWhere(whereClause, Im.ContactList.ACCOUNT, "=",
url.getPathSegments().get(2));
// fall through
case MATCH_CONTACTLISTS:
qb.setTables(TABLE_CONTACT_LIST);
qb.setProjectionMap(sContactListProjectionMap);
break;
case MATCH_CONTACTLIST:
qb.setTables(TABLE_CONTACT_LIST);
appendWhere(whereClause, Im.ContactList._ID, "=", url.getPathSegments().get(1));
break;
case MATCH_BLOCKEDLIST:
qb.setTables(BLOCKEDLIST_JOIN_AVATAR_TABLE);
qb.setProjectionMap(sBlockedListProjectionMap);
break;
case MATCH_BLOCKEDLIST_BY_PROVIDER:
qb.setTables(BLOCKEDLIST_JOIN_AVATAR_TABLE);
qb.setProjectionMap(sBlockedListProjectionMap);
appendWhere(whereClause, Im.BlockedList.ACCOUNT, "=",
url.getPathSegments().get(2));
break;
case MATCH_CONTACTS_ETAGS:
qb.setTables(TABLE_CONTACTS_ETAG);
break;
case MATCH_CONTACTS_ETAG:
qb.setTables(TABLE_CONTACTS_ETAG);
appendWhere(whereClause, "_id", "=", url.getPathSegments().get(1));
break;
case MATCH_MESSAGES:
qb.setTables(TABLE_MESSAGES);
break;
case MATCH_MESSAGES_BY_CONTACT:
// we don't really need the provider id in query. account id
// is enough.
qb.setTables(TABLE_MESSAGES);
appendWhere(whereClause, Im.Messages.ACCOUNT, "=",
url.getPathSegments().get(2));
appendWhere(whereClause, Im.Messages.CONTACT, "=",
decodeURLSegment(url.getPathSegments().get(3)));
break;
case MATCH_MESSAGE:
qb.setTables(TABLE_MESSAGES);
appendWhere(whereClause, Im.Messages._ID, "=", url.getPathSegments().get(1));
break;
case MATCH_INVITATIONS:
qb.setTables(TABLE_INVITATIONS);
break;
case MATCH_INVITATION:
qb.setTables(TABLE_INVITATIONS);
appendWhere(whereClause, Im.Invitation._ID, "=", url.getPathSegments().get(1));
break;
case MATCH_GROUP_MEMBERS:
qb.setTables(TABLE_GROUP_MEMBERS);
break;
case MATCH_GROUP_MEMBERS_BY_GROUP:
qb.setTables(TABLE_GROUP_MEMBERS);
appendWhere(whereClause, Im.GroupMembers.GROUP, "=", url.getPathSegments().get(1));
break;
case MATCH_GROUP_MESSAGES:
qb.setTables(TABLE_GROUP_MESSAGES);
break;
case MATCH_GROUP_MESSAGE_BY:
qb.setTables(TABLE_GROUP_MESSAGES);
appendWhere(whereClause, Im.GroupMessages.GROUP, "=",
url.getPathSegments().get(1));
break;
case MATCH_GROUP_MESSAGE:
qb.setTables(TABLE_GROUP_MESSAGES);
appendWhere(whereClause, Im.GroupMessages._ID, "=",
url.getPathSegments().get(1));
break;
case MATCH_AVATARS:
qb.setTables(TABLE_AVATARS);
break;
case MATCH_AVATAR_BY_PROVIDER:
qb.setTables(TABLE_AVATARS);
appendWhere(whereClause, Im.Avatars.ACCOUNT, "=", url.getPathSegments().get(2));
break;
case MATCH_CHATS:
qb.setTables(TABLE_CHATS);
break;
case MATCH_CHATS_ID:
qb.setTables(TABLE_CHATS);
appendWhere(whereClause, Im.Chats.CONTACT_ID, "=", url.getPathSegments().get(1));
break;
case MATCH_PRESENCE:
qb.setTables(TABLE_PRESENCE);
break;
case MATCH_PRESENCE_ID:
qb.setTables(TABLE_PRESENCE);
appendWhere(whereClause, Im.Presence.CONTACT_ID, "=", url.getPathSegments().get(1));
break;
case MATCH_SESSIONS:
qb.setTables(TABLE_SESSION_COOKIES);
break;
case MATCH_SESSIONS_BY_PROVIDER:
qb.setTables(TABLE_SESSION_COOKIES);
appendWhere(whereClause, Im.SessionCookies.ACCOUNT, "=", url.getPathSegments().get(2));
break;
case MATCH_PROVIDER_SETTINGS_BY_ID_AND_NAME:
appendWhere(whereClause, Im.ProviderSettings.NAME, "=", url.getPathSegments().get(2));
// fall through
case MATCH_PROVIDER_SETTINGS_BY_ID:
appendWhere(whereClause, Im.ProviderSettings.PROVIDER, "=", url.getPathSegments().get(1));
// fall through
case MATCH_PROVIDER_SETTINGS:
qb.setTables(TABLE_PROVIDER_SETTINGS);
break;
case MATCH_OUTGOING_RMQ_MESSAGES:
qb.setTables(TABLE_OUTGOING_RMQ_MESSAGES);
break;
case MATCH_OUTGOING_HIGHEST_RMQ_ID:
qb.setTables(TABLE_OUTGOING_RMQ_MESSAGES);
sort = "rmq_id DESC";
limit = "1";
break;
case MATCH_LAST_RMQ_ID:
qb.setTables(TABLE_LAST_RMQ_ID);
limit = "1";
break;
case MATCH_ACCOUNTS_STATUS:
qb.setTables(TABLE_ACCOUNT_STATUS);
break;
case MATCH_ACCOUNT_STATUS:
qb.setTables(TABLE_ACCOUNT_STATUS);
appendWhere(whereClause, Im.AccountStatus.ACCOUNT, "=",
url.getPathSegments().get(1));
break;
case MATCH_BRANDING_RESOURCE_MAP_CACHE:
qb.setTables(TABLE_BRANDING_RESOURCE_MAP_CACHE);
break;
default:
throw new IllegalArgumentException("Unknown URL " + url);
}
// run the query
final SQLiteDatabase db = mOpenHelper.getReadableDatabase();
Cursor c = null;
try {
c = qb.query(db, projectionIn, whereClause.toString(), selectionArgs,
groupBy, null, sort, limit);
if (c != null) {
switch(match) {
case MATCH_CHATTING_CONTACTS:
case MATCH_CONTACTS_BY_PROVIDER:
case MATCH_CHATTING_CONTACTS_BY_PROVIDER:
case MATCH_ONLINE_CONTACTS_BY_PROVIDER:
case MATCH_OFFLINE_CONTACTS_BY_PROVIDER:
case MATCH_CONTACTS_BAREBONE:
case MATCH_CONTACTS_JOIN_PRESENCE:
case MATCH_ONLINE_CONTACT_COUNT:
url = Im.Contacts.CONTENT_URI;
break;
}
if (DBG) log("set notify url " + url);
c.setNotificationUri(getContext().getContentResolver(), url);
}
} catch (Exception ex) {
Log.e(LOG_TAG, "query db caught ", ex);
}
return c;
| private void | seedInitialPresenceByAccount(long account)This method first performs a query for all the contacts (for the given account) that
don't have a presence entry in the presence table. Then for each of those contacts,
the method creates a presence row. The whole thing is done inside one database transaction
to increase performance.
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
qb.setTables(TABLE_CONTACTS);
qb.setProjectionMap(sContactsProjectionMap);
mQueryContactPresenceSelectionArgs[0] = String.valueOf(account);
final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
db.beginTransaction();
Cursor c = null;
try {
ContentValues presenceValues = new ContentValues();
presenceValues.put(Im.Presence.PRESENCE_STATUS, Im.Presence.OFFLINE);
presenceValues.put(Im.Presence.PRESENCE_CUSTOM_STATUS, "");
// First: update all the presence for the account so they are offline
StringBuilder buf = new StringBuilder();
buf.append(Im.Presence.CONTACT_ID);
buf.append(" in (select ");
buf.append(Im.Contacts._ID);
buf.append(" from ");
buf.append(TABLE_CONTACTS);
buf.append(" where ");
buf.append(Im.Contacts.ACCOUNT);
buf.append("=?) ");
String selection = buf.toString();
if (DBG) log("seedInitialPresence: reset presence selection=" + selection);
int count = db.update(TABLE_PRESENCE, presenceValues, selection,
mQueryContactPresenceSelectionArgs);
if (DBG) log("seedInitialPresence: reset " + count + " presence rows to OFFLINE");
// second: add a presence row for each contact that doesn't have a presence
if (DBG) {
log("seedInitialPresence: contacts_with_no_presence_selection => " +
CONTACTS_WITH_NO_PRESENCE_SELECTION);
}
c = qb.query(db,
CONTACT_ID_PROJECTION,
CONTACTS_WITH_NO_PRESENCE_SELECTION,
mQueryContactPresenceSelectionArgs,
null, null, null, null);
if (DBG) log("seedInitialPresence: found " + c.getCount() + " contacts w/o presence");
count = 0;
while (c.moveToNext()) {
long id = c.getLong(COLUMN_ID);
presenceValues.put(Im.Presence.CONTACT_ID, id);
try {
if (db.insert(TABLE_PRESENCE, null, presenceValues) > 0) {
count++;
}
} catch (SQLiteConstraintException ex) {
// we could possibly catch this exception, since there could be a presence
// row with the same contact_id. That's fine, just ignore the error
if (DBG) log("seedInitialPresence: insert presence for contact_id " + id +
" failed, caught " + ex);
}
}
db.setTransactionSuccessful();
if (DBG) log("seedInitialPresence: added " + count + " new presence rows");
} finally {
c.close();
db.endTransaction();
}
| public final int | update(android.net.Uri url, android.content.ContentValues values, java.lang.String selection, java.lang.String[] selectionArgs)
int result = 0;
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
db.beginTransaction();
try {
result = updateInternal(url, values, selection, selectionArgs);
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
if (result > 0) {
getContext().getContentResolver()
.notifyChange(url, null /* observer */, false /* sync */);
}
return result;
| int | updateBulkContacts(android.content.ContentValues values, java.lang.String userWhere)
ArrayList<String> usernames = values.getStringArrayList(Im.Contacts.USERNAME);
ArrayList<String> nicknames = values.getStringArrayList(Im.Contacts.NICKNAME);
int usernameCount = usernames.size();
int nicknameCount = nicknames.size();
if (usernameCount != nicknameCount) {
Log.e(LOG_TAG, "[ImProvider] updateBulkContacts: input bundle " +
"username & nickname lists have diff. length!");
return 0;
}
ArrayList<String> contactTypeArray = values.getStringArrayList(Im.Contacts.TYPE);
ArrayList<String> subscriptionStatusArray =
values.getStringArrayList(Im.Contacts.SUBSCRIPTION_STATUS);
ArrayList<String> subscriptionTypeArray =
values.getStringArrayList(Im.Contacts.SUBSCRIPTION_TYPE);
ArrayList<String> quickContactArray = values.getStringArrayList(Im.Contacts.QUICK_CONTACT);
ArrayList<String> rejectedArray = values.getStringArrayList(Im.Contacts.REJECTED);
final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
db.beginTransaction();
int sum = 0;
try {
Long provider = values.getAsLong(Im.Contacts.PROVIDER);
Long account = values.getAsLong(Im.Contacts.ACCOUNT);
ContentValues contactValues = new ContentValues();
contactValues.put(Im.Contacts.PROVIDER, provider);
contactValues.put(Im.Contacts.ACCOUNT, account);
StringBuilder updateSelection = new StringBuilder();
String[] updateSelectionArgs = new String[1];
for (int i=0; i<usernameCount; i++) {
String username = usernames.get(i);
String nickname = nicknames.get(i);
int type = 0;
int subscriptionStatus = 0;
int subscriptionType = 0;
int quickContact = 0;
int rejected = 0;
try {
type = Integer.parseInt(contactTypeArray.get(i));
subscriptionStatus = Integer.parseInt(subscriptionStatusArray.get(i));
subscriptionType = Integer.parseInt(subscriptionTypeArray.get(i));
quickContact = Integer.parseInt(quickContactArray.get(i));
rejected = Integer.parseInt(rejectedArray.get(i));
} catch (NumberFormatException ex) {
Log.e(LOG_TAG, "insertBulkContacts: caught " + ex);
}
if (DBG) log("updateBulkContacts[" + i + "] username=" +
username + ", nickname=" + nickname + ", type=" + type +
", subscriptionStatus=" + subscriptionStatus + ", subscriptionType=" +
subscriptionType + ", qc=" + quickContact);
contactValues.put(Im.Contacts.USERNAME, username);
contactValues.put(Im.Contacts.NICKNAME, nickname);
contactValues.put(Im.Contacts.TYPE, type);
contactValues.put(Im.Contacts.SUBSCRIPTION_STATUS, subscriptionStatus);
contactValues.put(Im.Contacts.SUBSCRIPTION_TYPE, subscriptionType);
contactValues.put(Im.Contacts.QUICK_CONTACT, quickContact);
contactValues.put(Im.Contacts.REJECTED, rejected);
// append username to the selection clause
updateSelection.delete(0, updateSelection.length());
updateSelection.append(userWhere);
updateSelection.append(" AND ");
updateSelection.append(Im.Contacts.USERNAME);
updateSelection.append("=?");
updateSelectionArgs[0] = username;
int numUpdated = db.update(TABLE_CONTACTS, contactValues,
updateSelection.toString(), updateSelectionArgs);
if (numUpdated == 0) {
Log.e(LOG_TAG, "[ImProvider] updateBulkContacts: " +
" update failed for selection = " + updateSelection);
} else {
sum += numUpdated;
}
// yield the lock if anyone else is trying to
// perform a db operation here.
db.yieldIfContended();
}
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
if (DBG) log("updateBulkContacts: " + sum + " entries updated");
return sum;
| private int | updateBulkPresence(android.content.ContentValues values, java.lang.String userWhere, java.lang.String[] whereArgs)
ArrayList<String> usernames = values.getStringArrayList(Im.Contacts.USERNAME);
int count = usernames.size();
Long account = values.getAsLong(Im.Contacts.ACCOUNT);
ArrayList<String> priorityArray = values.getStringArrayList(Im.Presence.PRIORITY);
ArrayList<String> modeArray = values.getStringArrayList(Im.Presence.PRESENCE_STATUS);
ArrayList<String> statusArray = values.getStringArrayList(
Im.Presence.PRESENCE_CUSTOM_STATUS);
ArrayList<String> clientTypeArray = values.getStringArrayList(Im.Presence.CLIENT_TYPE);
ArrayList<String> resourceArray = values.getStringArrayList(Im.Presence.JID_RESOURCE);
// append username to the selection clause
StringBuilder buf = new StringBuilder();
if (!TextUtils.isEmpty(userWhere)) {
buf.append(userWhere);
buf.append(" AND ");
}
buf.append(Im.Presence.CONTACT_ID);
buf.append(" in (select ");
buf.append(Im.Contacts._ID);
buf.append(" from ");
buf.append(TABLE_CONTACTS);
buf.append(" where ");
buf.append(Im.Contacts.ACCOUNT);
buf.append("=? AND ");
// use username LIKE ? for case insensitive comparison
buf.append(Im.Contacts.USERNAME);
buf.append(" LIKE ?) AND (");
buf.append(Im.Presence.PRIORITY);
buf.append("<=? OR ");
buf.append(Im.Presence.PRIORITY);
buf.append(" IS NULL OR ");
buf.append(Im.Presence.JID_RESOURCE);
buf.append("=?)");
String selection = buf.toString();
if (DBG) log("updateBulkPresence: selection => " + selection);
int numArgs = (whereArgs != null ? whereArgs.length + 4 : 4);
String[] selectionArgs = new String[numArgs];
int selArgsIndex = 0;
if (whereArgs != null) {
for (selArgsIndex=0; selArgsIndex<numArgs-1; selArgsIndex++) {
selectionArgs[selArgsIndex] = whereArgs[selArgsIndex];
}
}
final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
db.beginTransaction();
int sum = 0;
try {
ContentValues presenceValues = new ContentValues();
for (int i=0; i<count; i++) {
String username = usernames.get(i);
int priority = 0;
int mode = 0;
String status = statusArray.get(i);
String jidResource = resourceArray == null ? "" : resourceArray.get(i);
int clientType = Im.Presence.CLIENT_TYPE_DEFAULT;
try {
if (priorityArray != null) {
priority = Integer.parseInt(priorityArray.get(i));
}
if (modeArray != null) {
mode = Integer.parseInt(modeArray.get(i));
}
if (clientTypeArray != null) {
clientType = Integer.parseInt(clientTypeArray.get(i));
}
} catch (NumberFormatException ex) {
Log.e(LOG_TAG, "[ImProvider] updateBulkPresence: caught " + ex);
}
/*
if (DBG) {
log("updateBulkPresence[" + i + "] username=" + username + ", priority=" +
priority + ", mode=" + mode + ", status=" + status + ", resource=" +
jidResource + ", clientType=" + clientType);
}
*/
if (modeArray != null) {
presenceValues.put(Im.Presence.PRESENCE_STATUS, mode);
}
if (priorityArray != null) {
presenceValues.put(Im.Presence.PRIORITY, priority);
}
presenceValues.put(Im.Presence.PRESENCE_CUSTOM_STATUS, status);
if (clientTypeArray != null) {
presenceValues.put(Im.Presence.CLIENT_TYPE, clientType);
}
if (!TextUtils.isEmpty(jidResource)) {
presenceValues.put(Im.Presence.JID_RESOURCE, jidResource);
}
// fill in the selection args
int idx = selArgsIndex;
selectionArgs[idx++] = String.valueOf(account);
selectionArgs[idx++] = username;
selectionArgs[idx++] = String.valueOf(priority);
selectionArgs[idx] = jidResource;
int numUpdated = db.update(TABLE_PRESENCE,
presenceValues, selection, selectionArgs);
if (numUpdated == 0) {
Log.e(LOG_TAG, "[ImProvider] updateBulkPresence: failed for " + username);
} else {
sum += numUpdated;
}
// yield the lock if anyone else is trying to
// perform a db operation here.
db.yieldIfContended();
}
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
if (DBG) log("updateBulkPresence: " + sum + " entries updated");
return sum;
| public int | updateInternal(android.net.Uri url, android.content.ContentValues values, java.lang.String userWhere, java.lang.String[] whereArgs)
String tableToChange;
String idColumnName = null;
String changedItemId = null;
int count;
StringBuilder whereClause = new StringBuilder();
if(userWhere != null) {
whereClause.append(userWhere);
}
boolean notifyMessagesContentUri = false;
boolean notifyGroupMessagesContentUri = false;
boolean notifyContactListContentUri = false;
boolean notifyProviderAccountContentUri = false;
int match = mUrlMatcher.match(url);
switch (match) {
case MATCH_PROVIDERS_BY_ID:
changedItemId = url.getPathSegments().get(1);
// fall through
case MATCH_PROVIDERS:
tableToChange = TABLE_PROVIDERS;
break;
case MATCH_ACCOUNTS_BY_ID:
changedItemId = url.getPathSegments().get(1);
// fall through
case MATCH_ACCOUNTS:
tableToChange = TABLE_ACCOUNTS;
notifyProviderAccountContentUri = true;
break;
case MATCH_ACCOUNT_STATUS:
changedItemId = url.getPathSegments().get(1);
// fall through
case MATCH_ACCOUNTS_STATUS:
tableToChange = TABLE_ACCOUNT_STATUS;
notifyProviderAccountContentUri = true;
break;
case MATCH_CONTACTS:
case MATCH_CONTACTS_BAREBONE:
tableToChange = TABLE_CONTACTS;
break;
case MATCH_CONTACTS_BY_PROVIDER:
tableToChange = TABLE_CONTACTS;
changedItemId = url.getPathSegments().get(2);
idColumnName = Im.Contacts.ACCOUNT;
break;
case MATCH_CONTACT:
tableToChange = TABLE_CONTACTS;
changedItemId = url.getPathSegments().get(1);
break;
case MATCH_CONTACTS_BULK:
count = updateBulkContacts(values, userWhere);
// notify change using the "content://im/contacts" url,
// so the change will be observed by listeners interested
// in contacts changes.
if (count > 0) {
getContext().getContentResolver().notifyChange(
Im.Contacts.CONTENT_URI, null);
}
return count;
case MATCH_CONTACTLIST:
tableToChange = TABLE_CONTACT_LIST;
changedItemId = url.getPathSegments().get(1);
notifyContactListContentUri = true;
break;
case MATCH_CONTACTS_ETAGS:
tableToChange = TABLE_CONTACTS_ETAG;
break;
case MATCH_CONTACTS_ETAG:
tableToChange = TABLE_CONTACTS_ETAG;
changedItemId = url.getPathSegments().get(1);
break;
case MATCH_MESSAGES:
tableToChange = TABLE_MESSAGES;
break;
case MATCH_MESSAGES_BY_CONTACT:
tableToChange = TABLE_MESSAGES;
appendWhere(whereClause, Im.Messages.ACCOUNT, "=",
url.getPathSegments().get(2));
appendWhere(whereClause, Im.Messages.CONTACT, "=",
decodeURLSegment(url.getPathSegments().get(3)));
notifyMessagesContentUri = true;
break;
case MATCH_MESSAGE:
tableToChange = TABLE_MESSAGES;
changedItemId = url.getPathSegments().get(1);
notifyMessagesContentUri = true;
break;
case MATCH_GROUP_MESSAGES:
tableToChange = TABLE_GROUP_MESSAGES;
break;
case MATCH_GROUP_MESSAGE_BY:
tableToChange = TABLE_GROUP_MESSAGES;
changedItemId = url.getPathSegments().get(1);
idColumnName = Im.GroupMessages.GROUP;
notifyGroupMessagesContentUri = true;
break;
case MATCH_GROUP_MESSAGE:
tableToChange = TABLE_GROUP_MESSAGES;
changedItemId = url.getPathSegments().get(1);
notifyGroupMessagesContentUri = true;
break;
case MATCH_AVATARS:
tableToChange = TABLE_AVATARS;
break;
case MATCH_AVATAR:
tableToChange = TABLE_AVATARS;
changedItemId = url.getPathSegments().get(1);
break;
case MATCH_AVATAR_BY_PROVIDER:
tableToChange = TABLE_AVATARS;
changedItemId = url.getPathSegments().get(2);
idColumnName = Im.Avatars.ACCOUNT;
break;
case MATCH_CHATS:
tableToChange = TABLE_CHATS;
break;
case MATCH_CHATS_ID:
tableToChange = TABLE_CHATS;
changedItemId = url.getPathSegments().get(1);
idColumnName = Im.Chats.CONTACT_ID;
break;
case MATCH_PRESENCE:
//if (DBG) log("update presence: where='" + userWhere + "'");
tableToChange = TABLE_PRESENCE;
break;
case MATCH_PRESENCE_ID:
tableToChange = TABLE_PRESENCE;
changedItemId = url.getPathSegments().get(1);
idColumnName = Im.Presence.CONTACT_ID;
break;
case MATCH_PRESENCE_BULK:
count = updateBulkPresence(values, userWhere, whereArgs);
// notify change using the "content://im/contacts" url,
// so the change will be observed by listeners interested
// in contacts changes.
if (count > 0) {
getContext().getContentResolver().notifyChange(Im.Contacts.CONTENT_URI, null);
}
return count;
case MATCH_INVITATION:
tableToChange = TABLE_INVITATIONS;
changedItemId = url.getPathSegments().get(1);
break;
case MATCH_SESSIONS:
tableToChange = TABLE_SESSION_COOKIES;
break;
case MATCH_PROVIDER_SETTINGS_BY_ID_AND_NAME:
tableToChange = TABLE_PROVIDER_SETTINGS;
String providerId = url.getPathSegments().get(1);
String name = url.getPathSegments().get(2);
if (values.containsKey(Im.ProviderSettings.PROVIDER) ||
values.containsKey(Im.ProviderSettings.NAME)) {
throw new SecurityException("Cannot override the value for provider|name");
}
appendWhere(whereClause, Im.ProviderSettings.PROVIDER, "=", providerId);
appendWhere(whereClause, Im.ProviderSettings.NAME, "=", name);
break;
case MATCH_OUTGOING_RMQ_MESSAGES:
tableToChange = TABLE_OUTGOING_RMQ_MESSAGES;
break;
case MATCH_LAST_RMQ_ID:
tableToChange = TABLE_LAST_RMQ_ID;
break;
default:
throw new UnsupportedOperationException("Cannot update URL: " + url);
}
if (idColumnName == null) {
idColumnName = "_id";
}
if(changedItemId != null) {
appendWhere(whereClause, idColumnName, "=", changedItemId);
}
if (DBG) log("update " + url + " WHERE " + whereClause);
final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
count = db.update(tableToChange, values, whereClause.toString(), whereArgs);
if (count > 0) {
// In most case, we query contacts with presence and chats joined, thus
// we should also notify that contacts changes when presence or chats changed.
if (match == MATCH_CHATS || match == MATCH_CHATS_ID
|| match == MATCH_PRESENCE || match == MATCH_PRESENCE_ID
|| match == MATCH_CONTACTS_BAREBONE) {
getContext().getContentResolver().notifyChange(Im.Contacts.CONTENT_URI, null);
} else if (notifyMessagesContentUri) {
if (DBG) log("notify change for " + Im.Messages.CONTENT_URI);
getContext().getContentResolver().notifyChange(Im.Messages.CONTENT_URI, null);
} else if (notifyGroupMessagesContentUri) {
getContext().getContentResolver().notifyChange(Im.GroupMessages.CONTENT_URI, null);
} else if (notifyContactListContentUri) {
getContext().getContentResolver().notifyChange(Im.ContactList.CONTENT_URI, null);
} else if (notifyProviderAccountContentUri) {
if (DBG) log("notify change for " + Im.Provider.CONTENT_URI_WITH_ACCOUNT);
getContext().getContentResolver().notifyChange(Im.Provider.CONTENT_URI_WITH_ACCOUNT,
null);
}
}
return count;
| private int | updateSlotForChat(long chatId, int slot)
ContentValues values = new ContentValues();
values.put(Im.Chats.SHORTCUT, slot);
return update(Im.Chats.CONTENT_URI, values, Im.Chats._ID + "=?",
new String[] { Long.toString(chatId) });
|
|