summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScott Su <scott.su@myriadgroup.com>2009-09-09 18:09:55 +0800
committerWei Huang <weih@google.com>2009-09-10 16:02:48 -0700
commitc84f5b8faa3fac30fabe6b21ff30b7c98a36832e (patch)
tree03c26ae70195bbe99fa88ca1af82edeca340169c
parent72eda8084847abf311f0024b737f6ba630faf3d8 (diff)
downloadIM-c84f5b8faa3fac30fabe6b21ff30b7c98a36832e.tar.gz
Copy ImProvider to IM app
-rw-r--r--AndroidManifest.xml46
-rw-r--r--plugin/com/android/im/plugin/ImPluginConstants.java2
-rw-r--r--res/values/strings.xml10
-rw-r--r--src/com/android/im/app/AccountActivity.java20
-rw-r--r--src/com/android/im/app/AddContactActivity.java12
-rw-r--r--src/com/android/im/app/BlockedContactsActivity.java22
-rw-r--r--src/com/android/im/app/ChatBackgroundMaker.java8
-rw-r--r--src/com/android/im/app/ChatSwitcher.java34
-rw-r--r--src/com/android/im/app/ChatView.java66
-rw-r--r--src/com/android/im/app/ChooseAccountActivity.java5
-rw-r--r--src/com/android/im/app/ContactListActivity.java36
-rw-r--r--src/com/android/im/app/ContactListFilterView.java8
-rw-r--r--src/com/android/im/app/ContactListTreeAdapter.java46
-rw-r--r--src/com/android/im/app/ContactListView.java30
-rw-r--r--src/com/android/im/app/ContactPresenceActivity.java18
-rw-r--r--src/com/android/im/app/ContactView.java38
-rw-r--r--src/com/android/im/app/ContactsPickerActivity.java10
-rw-r--r--src/com/android/im/app/DatabaseUtils.java46
-rw-r--r--src/com/android/im/app/ImApp.java42
-rw-r--r--src/com/android/im/app/ImPluginHelper.java38
-rw-r--r--src/com/android/im/app/ImRingtonePreference.java6
-rw-r--r--src/com/android/im/app/ImUrlActivity.java37
-rw-r--r--src/com/android/im/app/LandingPage.java50
-rw-r--r--src/com/android/im/app/MessageView.java10
-rw-r--r--src/com/android/im/app/NewChatActivity.java12
-rw-r--r--src/com/android/im/app/PreferenceActivity.java14
-rw-r--r--src/com/android/im/app/PresenceUtils.java36
-rw-r--r--src/com/android/im/app/ProviderListItem.java34
-rw-r--r--src/com/android/im/app/SettingActivity.java6
-rw-r--r--src/com/android/im/app/SigningInActivity.java24
-rw-r--r--src/com/android/im/app/SignoutActivity.java22
-rw-r--r--src/com/android/im/app/UserPresenceView.java12
-rw-r--r--src/com/android/im/provider/Imps.java2333
-rw-r--r--src/com/android/im/provider/ImpsProvider.java3332
-rw-r--r--src/com/android/im/receiver/ImServiceAutoStarter.java10
-rw-r--r--src/com/android/im/service/ChatSessionAdapter.java94
-rw-r--r--src/com/android/im/service/ContactListManagerAdapter.java204
-rw-r--r--src/com/android/im/service/ImConnectionAdapter.java58
-rw-r--r--src/com/android/im/service/RemoteImService.java16
-rw-r--r--src/com/android/im/service/StatusBarNotifier.java28
40 files changed, 6286 insertions, 589 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 7d4bdcd..cec0a6b 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -22,8 +22,8 @@
package="com.android.im" android:sharedUserId="android.uid.im"
android:sharedUserLabel="@string/perm_label">
- <uses-permission android:name="com.android.providers.im.permission.READ_ONLY" />
- <uses-permission android:name="com.android.providers.im.permission.WRITE_ONLY" />
+ <uses-permission android:name="com.android.providers.imps.permission.READ_ONLY" />
+ <uses-permission android:name="com.android.providers.imps.permission.WRITE_ONLY" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.INTERNET" />
@@ -40,6 +40,18 @@
android:label="@string/perm_label"
android:description="@string/perm_desc" />
+ <permission android:name="com.android.providers.imps.permission.READ_ONLY"
+ android:permissionGroup="android.permission-group.MESSAGES"
+ android:protectionLevel="dangerous"
+ android:label="@string/ro_perm_label"
+ android:description="@string/ro_perm_desc" />
+
+ <permission android:name="com.android.providers.imps.permission.WRITE_ONLY"
+ android:permissionGroup="android.permission-group.MESSAGES"
+ android:protectionLevel="dangerous"
+ android:label="@string/wo_perm_label"
+ android:description="@string/wo_perm_desc" />
+
<application android:name=".app.ImApp"
android:label="@string/im_label"
android:icon="@drawable/ic_launcher_im"
@@ -55,6 +67,14 @@
</intent-filter>
</service>
+ <provider android:name=".provider.ImpsProvider"
+ android:authorities="imps"
+ android:process="android.process.im"
+ android:multiprocess="false"
+ android:readPermission="com.android.providers.imps.permission.READ_ONLY"
+ android:writePermission="com.android.providers.imps.permission.WRITE_ONLY"
+ android:grantUriPermissions="true" />
+
<activity android:name=".app.ChooseAccountActivity"
android:theme="@android:style/Theme.NoDisplay">
<intent-filter>
@@ -93,7 +113,7 @@
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
- <data android:mimeType="vnd.android.cursor.dir/im-providers" />
+ <data android:mimeType="vnd.android.cursor.dir/imps-providers" />
</intent-filter>
</activity>
@@ -104,13 +124,13 @@
<action android:name="android.intent.action.EDIT" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="com.android.im.IMPS_CATEGORY" />
- <data android:mimeType="vnd.android.cursor.item/im-accounts" />
+ <data android:mimeType="vnd.android.cursor.item/imps-accounts" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.INSERT" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="com.android.im.IMPS_CATEGORY" />
- <data android:mimeType="vnd.android.cursor.item/im-providers" />
+ <data android:mimeType="vnd.android.cursor.item/imps-providers" />
</intent-filter>
</activity>
@@ -134,7 +154,7 @@
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="com.android.im.IMPS_CATEGORY" />
- <data android:mimeType="vnd.android.cursor.dir/im-contacts"/>
+ <data android:mimeType="vnd.android.cursor.dir/imps-contacts"/>
</intent-filter>
</activity>
@@ -148,17 +168,17 @@
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="com.android.im.IMPS_CATEGORY" />
- <data android:mimeType="vnd.android.cursor.item/im-chats" />
+ <data android:mimeType="vnd.android.cursor.item/imps-chats" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
- <data android:mimeType="vnd.android.cursor.item/im-invitations" />
+ <data android:mimeType="vnd.android.cursor.item/imps-invitations" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.IM_MANAGE_SUBSCRIPTION"/>
<category android:name="android.intent.category.DEFAULT"/>
- <data android:mimeType="vnd.android.cursor.item/im-contacts"/>
+ <data android:mimeType="vnd.android.cursor.item/imps-contacts"/>
</intent-filter>
</activity>
@@ -166,7 +186,7 @@
<intent-filter>
<action android:name="android.intent.action.PICK" />
<category android:name="android.intent.category.DEFAULT" />
- <data android:mimeType="vnd.android.cursor.dir/im-contacts" />
+ <data android:mimeType="vnd.android.cursor.dir/imps-contacts" />
</intent-filter>
</activity>
@@ -174,7 +194,7 @@
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
- <data android:mimeType="vnd.android.cursor.dir/im-blockedList" />
+ <data android:mimeType="vnd.android.cursor.dir/imps-blockedList" />
</intent-filter>
</activity>
@@ -182,7 +202,7 @@
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
- <data android:mimeType="vnd.android.cursor.item/im-contacts" />
+ <data android:mimeType="vnd.android.cursor.item/imps-contacts" />
</intent-filter>
</activity>
@@ -197,7 +217,7 @@
<action android:name="android.intent.action.VIEW" />
<category android:name="com.android.im.IMPS_CATEGORY" />
<category android:name="android.intent.category.DEFAULT" />
- <data android:mimeType="vnd.android-dir/im-providerSettings" />
+ <data android:mimeType="vnd.android-dir/imps-providerSettings" />
</intent-filter>
</activity>
diff --git a/plugin/com/android/im/plugin/ImPluginConstants.java b/plugin/com/android/im/plugin/ImPluginConstants.java
index a512744..d51e5ec 100644
--- a/plugin/com/android/im/plugin/ImPluginConstants.java
+++ b/plugin/com/android/im/plugin/ImPluginConstants.java
@@ -25,7 +25,7 @@ public class ImPluginConstants {
/**
* The name of the provider. It should match the values defined in
- * {@link android.provider.Im.ProviderNames}.
+ * {@link com.android.im.provider.Imps.ProviderNames}.
*/
public static final String METADATA_PROVIDER_NAME = "com.android.im.provider_name";
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 51462b1..3fe363a 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -18,6 +18,16 @@
*/
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="ro_perm_label">read instant messages</string>
+ <string name="ro_perm_desc">
+ Allows applications to read data from the IM content provider.
+ </string>
+
+ <string name="wo_perm_label">write instant messages</string>
+ <string name="wo_perm_desc">
+ Allows applications to write data to the IM content provider.
+ </string>
+
<!-- The application label. This appears in the application launcher on the
Home screen. This is a noun. -->
<string name="im_label">IM</string>
diff --git a/src/com/android/im/app/AccountActivity.java b/src/com/android/im/app/AccountActivity.java
index fcd1ba3..d73f446 100644
--- a/src/com/android/im/app/AccountActivity.java
+++ b/src/com/android/im/app/AccountActivity.java
@@ -19,6 +19,7 @@ package com.android.im.app;
import com.android.im.R;
import com.android.im.plugin.BrandingResourceIDs;
+import com.android.im.provider.Imps;
import android.app.Activity;
import android.app.AlertDialog;
@@ -31,7 +32,6 @@ import android.database.Cursor;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
-import android.provider.Im;
import android.text.Editable;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
@@ -59,11 +59,11 @@ public class AccountActivity extends Activity {
static final int REQUEST_SIGN_IN = RESULT_FIRST_USER + 1;
private static final String[] ACCOUNT_PROJECTION = {
- Im.Account._ID,
- Im.Account.PROVIDER,
- Im.Account.USERNAME,
- Im.Account.PASSWORD,
- Im.Account.KEEP_SIGNED_IN,
+ Imps.Account._ID,
+ Imps.Account.PROVIDER,
+ Imps.Account.USERNAME,
+ Imps.Account.PASSWORD,
+ Imps.Account.KEEP_SIGNED_IN,
};
private static final int ACCOUNT_PROVIDER_COLUMN = 1;
@@ -117,7 +117,7 @@ public class AccountActivity extends Activity {
ContentResolver cr = getContentResolver();
Uri uri = i.getData();
- if ((uri == null) || !Im.Account.CONTENT_ITEM_TYPE.equals(cr.getType(uri))) {
+ if ((uri == null) || !Imps.Account.CONTENT_ITEM_TYPE.equals(cr.getType(uri))) {
Log.w(ImApp.LOG_TAG, "<AccountActivity>Bad data");
return;
}
@@ -193,7 +193,7 @@ public class AccountActivity extends Activity {
long accountId = ImApp.insertOrUpdateAccount(cr, providerId, username,
rememberPass ? pass : null);
- mAccountUri = ContentUris.withAppendedId(Im.Account.CONTENT_URI, accountId);
+ mAccountUri = ContentUris.withAppendedId(Imps.Account.CONTENT_URI, accountId);
if (!origUserName.equals(username) && shouldShowTermOfUse(brandingRes)) {
comfirmTermsOfUse(brandingRes, new DialogInterface.OnClickListener() {
@@ -276,7 +276,7 @@ public class AccountActivity extends Activity {
updateKeepSignedIn(false);
mEditPass.setText("");
ContentValues values = new ContentValues();
- values.put(Im.Account.PASSWORD, (String) null);
+ values.put(Imps.Account.PASSWORD, (String) null);
getContentResolver().update(mAccountUri, values, null, null);
}
}
@@ -284,7 +284,7 @@ public class AccountActivity extends Activity {
void updateKeepSignedIn(boolean keepSignIn) {
ContentValues values = new ContentValues();
- values.put(Im.Account.KEEP_SIGNED_IN, keepSignIn ? 1 : 0);
+ values.put(Imps.Account.KEEP_SIGNED_IN, keepSignIn ? 1 : 0);
getContentResolver().update(mAccountUri, values, null, null);
}
diff --git a/src/com/android/im/app/AddContactActivity.java b/src/com/android/im/app/AddContactActivity.java
index 6e8a92d..a370d5f 100644
--- a/src/com/android/im/app/AddContactActivity.java
+++ b/src/com/android/im/app/AddContactActivity.java
@@ -29,7 +29,6 @@ import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
-import android.provider.Im;
import android.provider.Contacts.ContactMethods;
import android.text.Editable;
import android.text.TextUtils;
@@ -51,6 +50,7 @@ import com.android.im.R;
import com.android.im.engine.ImErrorInfo;
import com.android.im.plugin.BrandingResourceIDs;
import com.android.im.plugin.ImpsConfigNames;
+import com.android.im.provider.Imps;
import com.android.im.service.ImServiceConstants;
import java.util.List;
@@ -58,8 +58,8 @@ import java.util.List;
public class AddContactActivity extends Activity {
private static final String[] CONTACT_LIST_PROJECTION = {
- Im.ContactList._ID,
- Im.ContactList.NAME,
+ Imps.ContactList._ID,
+ Imps.ContactList.NAME,
};
private static final int CONTACT_LIST_NAME_COLUMN = 1;
@@ -102,7 +102,7 @@ public class AddContactActivity extends Activity {
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
android.R.layout.simple_spinner_item,
c,
- new String[] {Im.ContactList.NAME},
+ new String[] {Imps.ContactList.NAME},
new int[] {android.R.id.text1});
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mListSpinner.setAdapter(adapter);
@@ -116,7 +116,7 @@ public class AddContactActivity extends Activity {
}
private Cursor queryContactLists() {
- Uri uri = Im.ContactList.CONTENT_URI;
+ Uri uri = Imps.ContactList.CONTENT_URI;
uri = ContentUris.withAppendedId(uri, mProviderId);
uri = ContentUris.withAppendedId(uri, mAccountId);
Cursor c = managedQuery(uri, CONTACT_LIST_PROJECTION, null, null);
@@ -141,7 +141,7 @@ public class AddContactActivity extends Activity {
ImServiceConstants.EXTRA_INTENT_PROVIDER_ID, -1);
mAccountId = intent.getLongExtra(
ImServiceConstants.EXTRA_INTENT_ACCOUNT_ID, -1);
- mDefaultDomain = Im.ProviderSettings.getStringValue(getContentResolver(),
+ mDefaultDomain = Imps.ProviderSettings.getStringValue(getContentResolver(),
mProviderId, ImpsConfigNames.DEFAULT_DOMAIN);
}
diff --git a/src/com/android/im/app/BlockedContactsActivity.java b/src/com/android/im/app/BlockedContactsActivity.java
index 014f596..c2aa495 100644
--- a/src/com/android/im/app/BlockedContactsActivity.java
+++ b/src/com/android/im/app/BlockedContactsActivity.java
@@ -28,7 +28,6 @@ import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.RemoteException;
-import android.provider.Im;
import android.util.Log;
import android.view.View;
import android.view.Window;
@@ -40,18 +39,19 @@ import com.android.im.IContactListManager;
import com.android.im.IImConnection;
import com.android.im.R;
import com.android.im.plugin.BrandingResourceIDs;
+import com.android.im.provider.Imps;
public class BlockedContactsActivity extends ListActivity {
ImApp mApp;
SimpleAlertHandler mHandler;
private static final String[] PROJECTION = {
- Im.BlockedList._ID,
- Im.BlockedList.ACCOUNT,
- Im.BlockedList.PROVIDER,
- Im.BlockedList.NICKNAME,
- Im.BlockedList.USERNAME,
- Im.BlockedList.AVATAR_DATA,
+ Imps.BlockedList._ID,
+ Imps.BlockedList.ACCOUNT,
+ Imps.BlockedList.PROVIDER,
+ Imps.BlockedList.NICKNAME,
+ Imps.BlockedList.USERNAME,
+ Imps.BlockedList.AVATAR_DATA,
};
static final int ACCOUNT_COLUMN = 1;
@@ -99,7 +99,7 @@ public class BlockedContactsActivity extends ListActivity {
}
long accountId = ContentUris.parseId(uri);
- Uri accountUri = ContentUris.withAppendedId(Im.Account.CONTENT_URI, accountId);
+ Uri accountUri = ContentUris.withAppendedId(Imps.Account.CONTENT_URI, accountId);
Cursor accountCursor = getContentResolver().query(accountUri, null, null, null, null);
if (accountCursor == null) {
warning("Bad account");
@@ -112,9 +112,9 @@ public class BlockedContactsActivity extends ListActivity {
}
long providerId = accountCursor.getLong(
- accountCursor.getColumnIndexOrThrow(Im.Account.PROVIDER));
+ accountCursor.getColumnIndexOrThrow(Imps.Account.PROVIDER));
String username = accountCursor.getString(
- accountCursor.getColumnIndexOrThrow(Im.Account.USERNAME));
+ accountCursor.getColumnIndexOrThrow(Imps.Account.USERNAME));
BrandingResources brandingRes = mApp.getBrandingResource(providerId);
getWindow().setFeatureDrawable(Window.FEATURE_LEFT_ICON,
@@ -123,7 +123,7 @@ public class BlockedContactsActivity extends ListActivity {
setTitle(getResources().getString(R.string.blocked_list_title, username));
accountCursor.close();
- Cursor c = managedQuery(uri, PROJECTION, null, Im.BlockedList.DEFAULT_SORT_ORDER);
+ Cursor c = managedQuery(uri, PROJECTION, null, Imps.BlockedList.DEFAULT_SORT_ORDER);
if (c == null) {
warning("Database error when query " + uri);
return false;
diff --git a/src/com/android/im/app/ChatBackgroundMaker.java b/src/com/android/im/app/ChatBackgroundMaker.java
index fe340e5..12a9a85 100644
--- a/src/com/android/im/app/ChatBackgroundMaker.java
+++ b/src/com/android/im/app/ChatBackgroundMaker.java
@@ -18,12 +18,12 @@
package com.android.im.app;
import com.android.im.R;
+import com.android.im.provider.Imps;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
-import android.provider.Im;
import android.view.View;
public class ChatBackgroundMaker {
@@ -43,13 +43,13 @@ public class ChatBackgroundMaker {
View msgText = view.findViewById(R.id.message);
switch (type) {
- case Im.MessageType.INCOMING:
+ case Imps.MessageType.INCOMING:
// TODO: set color according different contact
msgText.setBackgroundDrawable(mIncomingBg);
break;
- case Im.MessageType.OUTGOING:
- case Im.MessageType.POSTPONED:
+ case Imps.MessageType.OUTGOING:
+ case Imps.MessageType.POSTPONED:
msgText.setBackgroundDrawable(null);
msgText.setPadding(mPadding.left, mPadding.top, mPadding.right,
mPadding.bottom);
diff --git a/src/com/android/im/app/ChatSwitcher.java b/src/com/android/im/app/ChatSwitcher.java
index 04d35e6..731128a 100644
--- a/src/com/android/im/app/ChatSwitcher.java
+++ b/src/com/android/im/app/ChatSwitcher.java
@@ -21,6 +21,7 @@ import java.util.List;
import com.android.im.R;
import com.android.im.plugin.BrandingResourceIDs;
+import com.android.im.provider.Imps;
import android.app.Activity;
import android.app.Dialog;
@@ -33,7 +34,6 @@ import android.content.res.Configuration;
import android.database.Cursor;
import android.database.DataSetObserver;
import android.graphics.drawable.Drawable;
-import android.provider.Im;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
@@ -51,7 +51,7 @@ public class ChatSwitcher {
private static final boolean LOCAL_DEBUG = true;
private static final String[] PROVIDER_CATEGORY_PROJECTION = new String[] {
- Im.Provider.CATEGORY
+ Imps.Provider.CATEGORY
};
private static final int PROVIDER_CATEGORY_COLUMN = 0;
@@ -130,7 +130,7 @@ public class ChatSwitcher {
mQueryHandler.startQuery(
sQueryToken,
runnable,
- Im.Contacts.CONTENT_URI_CHAT_CONTACTS,
+ Imps.Contacts.CONTENT_URI_CHAT_CONTACTS,
null, /*projection*/
mQuerySelection,
mQuerySelectionArgs,
@@ -452,17 +452,17 @@ public class ChatSwitcher {
protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
if (cursor != null) {
- mContactIdColumn = cursor.getColumnIndexOrThrow(Im.Contacts._ID);
- mProviderIdColumn = cursor.getColumnIndexOrThrow(Im.Contacts.PROVIDER);
- mAccountIdColumn = cursor.getColumnIndexOrThrow(Im.Contacts.ACCOUNT);
- mUsernameColumn = cursor.getColumnIndexOrThrow(Im.Contacts.USERNAME);
- mNicknameColumn = cursor.getColumnIndexOrThrow(Im.Contacts.NICKNAME);
- mPresenceStatusColumn = cursor.getColumnIndexOrThrow(Im.Contacts.PRESENCE_STATUS);
- mLastUnreadMessageColumn = cursor.getColumnIndexOrThrow(Im.Chats.LAST_UNREAD_MESSAGE);
- mAvatarDataColumn = cursor.getColumnIndexOrThrow(Im.Contacts.AVATAR_DATA);
- mShortcutColumn = cursor.getColumnIndexOrThrow(Im.Chats.SHORTCUT);
- mLastChatColumn = cursor.getColumnIndexOrThrow(Im.Chats.LAST_MESSAGE_DATE);
- mGroupChatColumn = cursor.getColumnIndexOrThrow(Im.Chats.GROUP_CHAT);
+ mContactIdColumn = cursor.getColumnIndexOrThrow(Imps.Contacts._ID);
+ mProviderIdColumn = cursor.getColumnIndexOrThrow(Imps.Contacts.PROVIDER);
+ mAccountIdColumn = cursor.getColumnIndexOrThrow(Imps.Contacts.ACCOUNT);
+ mUsernameColumn = cursor.getColumnIndexOrThrow(Imps.Contacts.USERNAME);
+ mNicknameColumn = cursor.getColumnIndexOrThrow(Imps.Contacts.NICKNAME);
+ mPresenceStatusColumn = cursor.getColumnIndexOrThrow(Imps.Contacts.PRESENCE_STATUS);
+ mLastUnreadMessageColumn = cursor.getColumnIndexOrThrow(Imps.Chats.LAST_UNREAD_MESSAGE);
+ mAvatarDataColumn = cursor.getColumnIndexOrThrow(Imps.Contacts.AVATAR_DATA);
+ mShortcutColumn = cursor.getColumnIndexOrThrow(Imps.Chats.SHORTCUT);
+ mLastChatColumn = cursor.getColumnIndexOrThrow(Imps.Chats.LAST_MESSAGE_DATE);
+ mGroupChatColumn = cursor.getColumnIndexOrThrow(Imps.Chats.GROUP_CHAT);
}
mOkToShowEmptyView = true;
@@ -496,7 +496,7 @@ public class ChatSwitcher {
buf.append(" OR ");
}
- buf.append(Im.Contacts.PROVIDER).append("=?");
+ buf.append(Imps.Contacts.PROVIDER).append("=?");
mQuerySelectionArgs[i] = String.valueOf(providerDef.mId);
i++;
}
@@ -510,7 +510,7 @@ public class ChatSwitcher {
private static String findCategory(ContentResolver resolver, long providerId) {
// find the provider category for this chat
Cursor providerCursor = resolver.query(
- Im.Provider.CONTENT_URI,
+ Imps.Provider.CONTENT_URI,
PROVIDER_CATEGORY_PROJECTION,
"_id = " + providerId,
null /* selection args */,
@@ -532,7 +532,7 @@ public class ChatSwitcher {
public static Intent makeChatIntent(ContentResolver resolver, long provider, long account,
String contact, long contactId, int groupChat) {
Intent i = new Intent(Intent.ACTION_VIEW,
- ContentUris.withAppendedId(Im.Chats.CONTENT_URI, contactId));
+ ContentUris.withAppendedId(Imps.Chats.CONTENT_URI, contactId));
i.addCategory(findCategory(resolver, provider));
i.putExtra("from", contact);
i.putExtra("providerId", provider);
diff --git a/src/com/android/im/app/ChatView.java b/src/com/android/im/app/ChatView.java
index 13acebb..ebc1038 100644
--- a/src/com/android/im/app/ChatView.java
+++ b/src/com/android/im/app/ChatView.java
@@ -42,7 +42,6 @@ import android.os.Bundle;
import android.os.Message;
import android.os.RemoteException;
import android.provider.Browser;
-import android.provider.Im;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
@@ -84,18 +83,19 @@ import com.android.im.engine.Contact;
import com.android.im.engine.ImConnection;
import com.android.im.engine.ImErrorInfo;
import com.android.im.plugin.BrandingResourceIDs;
+import com.android.im.provider.Imps;
public class ChatView extends LinearLayout {
// This projection and index are set for the query of active chats
static final String[] CHAT_PROJECTION = {
- Im.Contacts._ID,
- Im.Contacts.ACCOUNT,
- Im.Contacts.PROVIDER,
- Im.Contacts.USERNAME,
- Im.Contacts.NICKNAME,
- Im.Contacts.TYPE,
- Im.Presence.PRESENCE_STATUS,
- Im.Chats.LAST_UNREAD_MESSAGE,
+ Imps.Contacts._ID,
+ Imps.Contacts.ACCOUNT,
+ Imps.Contacts.PROVIDER,
+ Imps.Contacts.USERNAME,
+ Imps.Contacts.NICKNAME,
+ Imps.Contacts.TYPE,
+ Imps.Presence.PRESENCE_STATUS,
+ Imps.Chats.LAST_UNREAD_MESSAGE,
};
static final int CONTACT_ID_COLUMN = 0;
static final int ACCOUNT_COLUMN = 1;
@@ -107,9 +107,9 @@ public class ChatView extends LinearLayout {
static final int LAST_UNREAD_MESSAGE_COLUMN = 7;
static final String[] INVITATION_PROJECT = {
- Im.Invitation._ID,
- Im.Invitation.PROVIDER,
- Im.Invitation.SENDER,
+ Imps.Invitation._ID,
+ Imps.Invitation.PROVIDER,
+ Imps.Invitation.SENDER,
};
static final int INVITATION_ID_COLUMN = 0;
static final int INVITATION_PROVIDER_COLUMN = 1;
@@ -480,9 +480,9 @@ public class ChatView extends LinearLayout {
}
private void setTitle() {
- if (mType == Im.Contacts.TYPE_GROUP) {
- final String[] projection = {Im.GroupMembers.NICKNAME};
- Uri memberUri = ContentUris.withAppendedId(Im.GroupMembers.CONTENT_URI, mChatId);
+ if (mType == Imps.Contacts.TYPE_GROUP) {
+ final String[] projection = {Imps.GroupMembers.NICKNAME};
+ Uri memberUri = ContentUris.withAppendedId(Imps.GroupMembers.CONTENT_URI, mChatId);
ContentResolver cr = mScreen.getContentResolver();
Cursor c = cr.query(memberUri, projection, null, null, null);
StringBuilder buf = new StringBuilder();
@@ -502,7 +502,7 @@ public class ChatView extends LinearLayout {
}
private void setStatusIcon() {
- if (mType == Im.Contacts.TYPE_GROUP) {
+ if (mType == Imps.Contacts.TYPE_GROUP) {
// hide the status icon for group chat.
mStatusIcon.setVisibility(GONE);
} else {
@@ -517,7 +517,7 @@ public class ChatView extends LinearLayout {
if (mCursor != null) {
mCursor.deactivate();
}
- Uri contactUri = ContentUris.withAppendedId(Im.Contacts.CONTENT_URI, chatId);
+ Uri contactUri = ContentUris.withAppendedId(Imps.Contacts.CONTENT_URI, chatId);
mCursor = mScreen.managedQuery(contactUri, CHAT_PROJECTION, null, null);
if (mCursor == null || !mCursor.moveToFirst()) {
if (Log.isLoggable(ImApp.LOG_TAG, Log.DEBUG)){
@@ -533,7 +533,7 @@ public class ChatView extends LinearLayout {
}
public void bindInvitation(long invitationId) {
- Uri uri = ContentUris.withAppendedId(Im.Invitation.CONTENT_URI, invitationId);
+ Uri uri = ContentUris.withAppendedId(Imps.Invitation.CONTENT_URI, invitationId);
ContentResolver cr = mScreen.getContentResolver();
Cursor cursor = cr.query(uri, INVITATION_PROJECT, null, null, null);
if (cursor == null || !cursor.moveToFirst()) {
@@ -656,7 +656,7 @@ public class ChatView extends LinearLayout {
mQueryHandler.cancelOperation(QUERY_TOKEN);
}
- Uri uri = Im.Messages.getContentUriByThreadId(mChatId);
+ Uri uri = Imps.Messages.getContentUriByThreadId(mChatId);
if (Log.isLoggable(ImApp.LOG_TAG, Log.DEBUG)){
log("queryCursor: uri=" + uri);
@@ -723,7 +723,7 @@ public class ChatView extends LinearLayout {
} else {
// the conversation is already closed, clear data in database
ContentResolver cr = mContext.getContentResolver();
- cr.delete(ContentUris.withAppendedId(Im.Chats.CONTENT_URI, mChatId),
+ cr.delete(ContentUris.withAppendedId(Imps.Chats.CONTENT_URI, mChatId),
null, null);
}
mScreen.finish();
@@ -740,7 +740,7 @@ public class ChatView extends LinearLayout {
}
public void viewProfile() {
- Uri data = ContentUris.withAppendedId(Im.Contacts.CONTENT_URI, mChatId);
+ Uri data = ContentUris.withAppendedId(Imps.Contacts.CONTENT_URI, mChatId);
Intent intent = new Intent(Intent.ACTION_VIEW, data);
mScreen.startActivity(intent);
}
@@ -828,7 +828,7 @@ public class ChatView extends LinearLayout {
}
boolean isGroupChat() {
- return Im.Contacts.TYPE_GROUP == mType;
+ return Imps.Contacts.TYPE_GROUP == mType;
}
void sendMessage() {
@@ -938,10 +938,10 @@ public class ChatView extends LinearLayout {
}
if (isConnected) {
- if (mType == Im.Contacts.TYPE_TEMPORARY) {
+ if (mType == Imps.Contacts.TYPE_TEMPORARY) {
visibility = View.VISIBLE;
message = mContext.getString(R.string.contact_not_in_list_warning, mNickName);
- } else if (mPresenceStatus == Im.Presence.OFFLINE) {
+ } else if (mPresenceStatus == Imps.Presence.OFFLINE) {
visibility = View.VISIBLE;
message = mContext.getString(R.string.contact_offline_warning, mNickName);
}
@@ -1049,7 +1049,7 @@ public class ChatView extends LinearLayout {
for (int i = 0 ; i < len ; i++) {
mColumnNames[i] = columnNames[i];
- if (mColumnNames[i].equals(Im.Messages.DATE)) {
+ if (mColumnNames[i].equals(Imps.Messages.DATE)) {
mDateColumn = i;
}
}
@@ -1433,11 +1433,11 @@ public class ChatView extends LinearLayout {
}
private void resolveColumnIndex(Cursor c) {
- mNicknameColumn = c.getColumnIndexOrThrow(Im.Messages.NICKNAME);
- mBodyColumn = c.getColumnIndexOrThrow(Im.Messages.BODY);
- mDateColumn = c.getColumnIndexOrThrow(Im.Messages.DATE);
- mTypeColumn = c.getColumnIndexOrThrow(Im.Messages.TYPE);
- mErrCodeColumn = c.getColumnIndexOrThrow(Im.Messages.ERROR_CODE);
+ mNicknameColumn = c.getColumnIndexOrThrow(Imps.Messages.NICKNAME);
+ mBodyColumn = c.getColumnIndexOrThrow(Imps.Messages.BODY);
+ mDateColumn = c.getColumnIndexOrThrow(Imps.Messages.DATE);
+ mTypeColumn = c.getColumnIndexOrThrow(Imps.Messages.TYPE);
+ mErrCodeColumn = c.getColumnIndexOrThrow(Imps.Messages.ERROR_CODE);
mDeltaColumn = c.getColumnIndexOrThrow(DeltaCursor.DELTA_COLUMN_NAME);
}
@@ -1466,12 +1466,12 @@ public class ChatView extends LinearLayout {
Date date = showTimeStamp ? new Date(cursor.getLong(mDateColumn)) : null;
switch (type) {
- case Im.MessageType.INCOMING:
+ case Imps.MessageType.INCOMING:
chatMsgView.bindIncomingMessage(contact, body, date, mMarkup, isScrolling());
break;
- case Im.MessageType.OUTGOING:
- case Im.MessageType.POSTPONED:
+ case Imps.MessageType.OUTGOING:
+ case Imps.MessageType.POSTPONED:
int errCode = cursor.getInt(mErrCodeColumn);
if (errCode != 0) {
chatMsgView.bindErrorMessage(errCode);
diff --git a/src/com/android/im/app/ChooseAccountActivity.java b/src/com/android/im/app/ChooseAccountActivity.java
index b18b0b2..6b0b57b 100644
--- a/src/com/android/im/app/ChooseAccountActivity.java
+++ b/src/com/android/im/app/ChooseAccountActivity.java
@@ -17,10 +17,11 @@
package com.android.im.app;
+import com.android.im.provider.Imps;
+
import android.app.Activity;
import android.os.Bundle;
import android.content.Intent;
-import android.provider.Im;
public class ChooseAccountActivity extends Activity {
@Override
@@ -28,7 +29,7 @@ public class ChooseAccountActivity extends Activity {
super.onCreate(icicle);
Intent intent = new Intent(Intent.ACTION_VIEW);
- intent.setType(Im.Provider.CONTENT_TYPE);
+ intent.setType(Imps.Provider.CONTENT_TYPE);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
diff --git a/src/com/android/im/app/ContactListActivity.java b/src/com/android/im/app/ContactListActivity.java
index 544d254..a907e25 100644
--- a/src/com/android/im/app/ContactListActivity.java
+++ b/src/com/android/im/app/ContactListActivity.java
@@ -19,6 +19,7 @@ package com.android.im.app;
import com.android.im.IImConnection;
import com.android.im.R;
import com.android.im.plugin.BrandingResourceIDs;
+import com.android.im.provider.Imps;
import com.android.im.service.ImServiceConstants;
import android.app.Activity;
@@ -31,7 +32,6 @@ import android.net.Uri;
import android.os.Bundle;
import android.os.Message;
import android.os.RemoteException;
-import android.provider.Im;
import android.util.Log;
import android.view.ContextMenu;
import android.view.KeyEvent;
@@ -72,7 +72,7 @@ public class ContactListActivity extends Activity implements View.OnCreateContex
boolean mIsFiltering;
- Im.ProviderSettings.QueryMap mSettingMap;
+ Imps.ProviderSettings.QueryMap mSettingMap;
boolean mDestroyed;
@Override
@@ -96,7 +96,7 @@ public class ContactListActivity extends Activity implements View.OnCreateContex
mApp = ImApp.getApplication(this);
ContentResolver cr = getContentResolver();
- Cursor c = cr.query(ContentUris.withAppendedId(Im.Account.CONTENT_URI, mAccountId),
+ Cursor c = cr.query(ContentUris.withAppendedId(Imps.Account.CONTENT_URI, mAccountId),
null, null, null, null);
if (c == null) {
finish();
@@ -108,9 +108,9 @@ public class ContactListActivity extends Activity implements View.OnCreateContex
return;
}
- mProviderId = c.getLong(c.getColumnIndexOrThrow(Im.Account.PROVIDER));
+ mProviderId = c.getLong(c.getColumnIndexOrThrow(Imps.Account.PROVIDER));
mHandler = new MyHandler(this);
- String username = c.getString(c.getColumnIndexOrThrow(Im.Account.USERNAME));
+ String username = c.getString(c.getColumnIndexOrThrow(Imps.Account.USERNAME));
BrandingResources brandingRes = mApp.getBrandingResource(mProviderId);
setTitle(brandingRes.getString(
@@ -118,7 +118,7 @@ public class ContactListActivity extends Activity implements View.OnCreateContex
getWindow().setFeatureDrawable(Window.FEATURE_LEFT_ICON,
brandingRes.getDrawable(BrandingResourceIDs.DRAWABLE_LOGO));
- mSettingMap = new Im.ProviderSettings.QueryMap(
+ mSettingMap = new Imps.ProviderSettings.QueryMap(
getContentResolver(), mProviderId, true, null);
mApp.callWhenServiceConnected(mHandler, new Runnable(){
@@ -177,7 +177,7 @@ public class ContactListActivity extends Activity implements View.OnCreateContex
return true;
case R.id.menu_blocked_contacts:
- Uri.Builder builder = Im.BlockedList.CONTENT_URI.buildUpon();
+ Uri.Builder builder = Imps.BlockedList.CONTENT_URI.buildUpon();
ContentUris.appendId(builder, mProviderId);
ContentUris.appendId(builder, mAccountId);
startActivity(new Intent(Intent.ACTION_VIEW, builder.build()));
@@ -185,7 +185,7 @@ public class ContactListActivity extends Activity implements View.OnCreateContex
case R.id.menu_view_accounts:
Intent intent = new Intent(Intent.ACTION_VIEW);
- intent.setType(Im.Provider.CONTENT_TYPE);
+ intent.setType(Imps.Provider.CONTENT_TYPE);
startActivity(intent);
finish();
return true;
@@ -276,8 +276,8 @@ public class ContactListActivity extends Activity implements View.OnCreateContex
R.layout.contact_list_filter_view, null);
mFilterView.getListView().setOnCreateContextMenuListener(this);
}
- Uri uri = mSettingMap.getHideOfflineContacts() ? Im.Contacts.CONTENT_URI_ONLINE_CONTACTS_BY
- : Im.Contacts.CONTENT_URI_CONTACTS_BY;
+ Uri uri = mSettingMap.getHideOfflineContacts() ? Imps.Contacts.CONTENT_URI_ONLINE_CONTACTS_BY
+ : Imps.Contacts.CONTENT_URI_CONTACTS_BY;
uri = ContentUris.withAppendedId(uri, mProviderId);
uri = ContentUris.withAppendedId(uri, mAccountId);
mFilterView.doFilter(uri, null);
@@ -346,12 +346,12 @@ public class ContactListActivity extends Activity implements View.OnCreateContex
if (contactCursor != null) {
//XXX HACK: Yahoo! doesn't allow to block a friend. We can only block a temporary contact.
ProviderDef provider = mApp.getProvider(mProviderId);
- if (Im.ProviderNames.YAHOO.equals(provider.mName)) {
- int type = contactCursor.getInt(contactCursor.getColumnIndexOrThrow(Im.Contacts.TYPE));
- allowBlock = (type == Im.Contacts.TYPE_TEMPORARY);
+ if (Imps.ProviderNames.YAHOO.equals(provider.mName)) {
+ int type = contactCursor.getInt(contactCursor.getColumnIndexOrThrow(Imps.Contacts.TYPE));
+ allowBlock = (type == Imps.Contacts.TYPE_TEMPORARY);
}
- int nickNameIndex = contactCursor.getColumnIndexOrThrow(Im.Contacts.NICKNAME);
+ int nickNameIndex = contactCursor.getColumnIndexOrThrow(Imps.Contacts.NICKNAME);
menu.setHeaderTitle(contactCursor.getString(nickNameIndex));
}
@@ -402,11 +402,11 @@ public class ContactListActivity extends Activity implements View.OnCreateContex
ContentResolver cr = getContentResolver();
ContentValues values = new ContentValues(3);
- values.put(Im.AccountStatus.ACCOUNT, mAccountId);
- values.put(Im.AccountStatus.PRESENCE_STATUS, Im.Presence.OFFLINE);
- values.put(Im.AccountStatus.CONNECTION_STATUS, Im.ConnectionStatus.OFFLINE);
+ values.put(Imps.AccountStatus.ACCOUNT, mAccountId);
+ values.put(Imps.AccountStatus.PRESENCE_STATUS, Imps.Presence.OFFLINE);
+ values.put(Imps.AccountStatus.CONNECTION_STATUS, Imps.ConnectionStatus.OFFLINE);
// insert on the "account_status" uri actually replaces the existing value
- cr.insert(Im.AccountStatus.CONTENT_URI, values);
+ cr.insert(Imps.AccountStatus.CONTENT_URI, values);
}
final class ContextMenuHandler implements MenuItem.OnMenuItemClickListener {
diff --git a/src/com/android/im/app/ContactListFilterView.java b/src/com/android/im/app/ContactListFilterView.java
index 5607cde..76b410c 100644
--- a/src/com/android/im/app/ContactListFilterView.java
+++ b/src/com/android/im/app/ContactListFilterView.java
@@ -21,7 +21,6 @@ import android.content.Context;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.net.Uri;
-import android.provider.Im;
import android.util.AttributeSet;
import android.view.View;
import android.widget.AdapterView;
@@ -32,6 +31,7 @@ import android.widget.ResourceCursorAdapter;
import android.widget.AdapterView.OnItemClickListener;
import com.android.im.R;
+import com.android.im.provider.Imps;
public class ContactListFilterView extends LinearLayout {
@@ -95,18 +95,18 @@ public class ContactListFilterView extends LinearLayout {
StringBuilder buf = new StringBuilder();
// exclude chatting contact
- buf.append(Im.Chats.LAST_MESSAGE_DATE);
+ buf.append(Imps.Chats.LAST_MESSAGE_DATE);
buf.append(" IS NULL");
if (constraint != null) {
buf.append(" AND ");
- buf.append(Im.Contacts.NICKNAME);
+ buf.append(Imps.Contacts.NICKNAME);
buf.append(" LIKE ");
DatabaseUtils.appendValueToSql(buf, "%" + constraint + "%");
}
return mContext.getContentResolver().query(mUri, ContactView.CONTACT_PROJECTION,
- buf == null ? null : buf.toString(), null, Im.Contacts.DEFAULT_SORT_ORDER);
+ buf == null ? null : buf.toString(), null, Imps.Contacts.DEFAULT_SORT_ORDER);
}
private class ContactAdapter extends ResourceCursorAdapter {
diff --git a/src/com/android/im/app/ContactListTreeAdapter.java b/src/com/android/im/app/ContactListTreeAdapter.java
index be8b2d9..8b7abbb 100644
--- a/src/com/android/im/app/ContactListTreeAdapter.java
+++ b/src/com/android/im/app/ContactListTreeAdapter.java
@@ -29,7 +29,6 @@ import android.database.Cursor;
import android.database.DataSetObserver;
import android.net.Uri;
import android.os.RemoteException;
-import android.provider.Im;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
@@ -43,6 +42,7 @@ import android.widget.AbsListView.OnScrollListener;
import com.android.im.IImConnection;
import com.android.im.R;
import com.android.im.plugin.BrandingResourceIDs;
+import com.android.im.provider.Imps;
import java.util.ArrayList;
import java.util.Observable;
@@ -52,8 +52,8 @@ public class ContactListTreeAdapter extends BaseExpandableListAdapter
implements AbsListView.OnScrollListener{
private static final String[] CONTACT_LIST_PROJECTION = {
- Im.ContactList._ID,
- Im.ContactList.NAME,
+ Imps.ContactList._ID,
+ Imps.ContactList.NAME,
};
private static final int COLUMN_CONTACT_LIST_ID = 0;
@@ -80,22 +80,22 @@ public class ContactListTreeAdapter extends BaseExpandableListAdapter
private static final int TOKEN_SUBSCRITPTION = -3;
private static final String NON_CHAT_AND_BLOCKED_CONTACTS = "("
- + Im.Contacts.LAST_MESSAGE_DATE + " IS NULL) AND ("
- + Im.Contacts.TYPE + "!=" + Im.Contacts.TYPE_BLOCKED + ")";
+ + Imps.Contacts.LAST_MESSAGE_DATE + " IS NULL) AND ("
+ + Imps.Contacts.TYPE + "!=" + Imps.Contacts.TYPE_BLOCKED + ")";
- private static final String CONTACTS_SELECTION = Im.Contacts.CONTACTLIST
+ private static final String CONTACTS_SELECTION = Imps.Contacts.CONTACTLIST
+ "=? AND " + NON_CHAT_AND_BLOCKED_CONTACTS;
private static final String ONLINE_CONTACT_SELECTION = CONTACTS_SELECTION
- + " AND "+ Im.Contacts.PRESENCE_STATUS + " != " + Im.Presence.OFFLINE;
+ + " AND "+ Imps.Contacts.PRESENCE_STATUS + " != " + Imps.Presence.OFFLINE;
static final void log(String msg) {
Log.d(ImApp.LOG_TAG, "<ContactListAdapter>" + msg);
}
static final String[] CONTACT_COUNT_PROJECTION = {
- Im.Contacts.CONTACTLIST,
- Im.Contacts._COUNT,
+ Imps.Contacts.CONTACTLIST,
+ Imps.Contacts._COUNT,
};
ContentQueryMap mOnlineContactsCountMap;
@@ -211,12 +211,12 @@ public class ContactListTreeAdapter extends BaseExpandableListAdapter
log("startQueryContactLists()");
}
- Uri uri = Im.ContactList.CONTENT_URI;
+ Uri uri = Imps.ContactList.CONTENT_URI;
uri = ContentUris.withAppendedId(uri, mProviderId);
uri = ContentUris.withAppendedId(uri, mAccountId);
mQueryHandler.startQuery(TOKEN_CONTACT_LISTS, null, uri, CONTACT_LIST_PROJECTION,
- null, null, Im.ContactList.DEFAULT_SORT_ORDER);
+ null, null, Imps.ContactList.DEFAULT_SORT_ORDER);
}
void startQueryOngoingConversations() {
@@ -224,12 +224,12 @@ public class ContactListTreeAdapter extends BaseExpandableListAdapter
log("startQueryOngoingConversations()");
}
- Uri uri = Im.Contacts.CONTENT_URI_CHAT_CONTACTS_BY;
+ Uri uri = Imps.Contacts.CONTENT_URI_CHAT_CONTACTS_BY;
uri = ContentUris.withAppendedId(uri, mProviderId);
uri = ContentUris.withAppendedId(uri, mAccountId);
mQueryHandler.startQuery(TOKEN_ONGOING_CONVERSATION, null, uri,
- ContactView.CONTACT_PROJECTION, null, null, Im.Contacts.DEFAULT_SORT_ORDER);
+ ContactView.CONTACT_PROJECTION, null, null, Imps.Contacts.DEFAULT_SORT_ORDER);
}
void startQuerySubscriptions() {
@@ -237,16 +237,16 @@ public class ContactListTreeAdapter extends BaseExpandableListAdapter
log("startQuerySubscriptions()");
}
- Uri uri = Im.Contacts.CONTENT_URI_CONTACTS_BY;
+ Uri uri = Imps.Contacts.CONTENT_URI_CONTACTS_BY;
uri = ContentUris.withAppendedId(uri, mProviderId);
uri = ContentUris.withAppendedId(uri, mAccountId);
mQueryHandler.startQuery(TOKEN_SUBSCRITPTION, null, uri,
ContactView.CONTACT_PROJECTION,
String.format("%s=%d AND %s=%d",
- Im.Contacts.SUBSCRIPTION_STATUS, Im.Contacts.SUBSCRIPTION_STATUS_SUBSCRIBE_PENDING,
- Im.Contacts.SUBSCRIPTION_TYPE, Im.Contacts.SUBSCRIPTION_TYPE_FROM),
- null,Im.Contacts.DEFAULT_SORT_ORDER);
+ Imps.Contacts.SUBSCRIPTION_STATUS, Imps.Contacts.SUBSCRIPTION_STATUS_SUBSCRIBE_PENDING,
+ Imps.Contacts.SUBSCRIPTION_TYPE, Imps.Contacts.SUBSCRIPTION_TYPE_FROM),
+ null,Imps.Contacts.DEFAULT_SORT_ORDER);
}
void startQueryContacts(long listId) {
@@ -257,8 +257,8 @@ public class ContactListTreeAdapter extends BaseExpandableListAdapter
String selection = mHideOfflineContacts ? ONLINE_CONTACT_SELECTION : CONTACTS_SELECTION;
String[] args = { Long.toString(listId) };
int token = (int)listId;
- mQueryHandler.startQuery(token, null, Im.Contacts.CONTENT_URI,
- ContactView.CONTACT_PROJECTION, selection, args, Im.Contacts.DEFAULT_SORT_ORDER);
+ mQueryHandler.startQuery(token, null, Imps.Contacts.CONTENT_URI,
+ ContactView.CONTACT_PROJECTION, selection, args, Imps.Contacts.DEFAULT_SORT_ORDER);
}
public Object getChild(int groupPosition, int childPosition) {
@@ -640,20 +640,20 @@ public class ContactListTreeAdapter extends BaseExpandableListAdapter
private int getOnlineChildCount(Cursor groupCursor) {
long listId = groupCursor.getLong(COLUMN_CONTACT_LIST_ID);
if (mOnlineContactsCountMap == null) {
- String where = Im.Contacts.ACCOUNT + "=" + mAccountId;
+ String where = Imps.Contacts.ACCOUNT + "=" + mAccountId;
ContentResolver cr = mActivity.getContentResolver();
- Cursor c = cr.query(Im.Contacts.CONTENT_URI_ONLINE_COUNT,
+ Cursor c = cr.query(Imps.Contacts.CONTENT_URI_ONLINE_COUNT,
CONTACT_COUNT_PROJECTION, where, null, null);
mOnlineContactsCountMap = new ContentQueryMap(c,
- Im.Contacts.CONTACTLIST, true, mHandler);
+ Imps.Contacts.CONTACTLIST, true, mHandler);
mOnlineContactsCountMap.addObserver(new Observer(){
public void update(Observable observable, Object data) {
notifyDataSetChanged();
}});
}
ContentValues value = mOnlineContactsCountMap.getValues(String.valueOf(listId));
- return value == null ? 0 : value.getAsInteger(Im.Contacts._COUNT);
+ return value == null ? 0 : value.getAsInteger(Imps.Contacts._COUNT);
}
@Override
diff --git a/src/com/android/im/app/ContactListView.java b/src/com/android/im/app/ContactListView.java
index 5c31683..12ff110 100644
--- a/src/com/android/im/app/ContactListView.java
+++ b/src/com/android/im/app/ContactListView.java
@@ -27,6 +27,7 @@ import com.android.im.app.adapter.ContactListListenerAdapter;
import com.android.im.engine.Contact;
import com.android.im.engine.ContactListManager;
import com.android.im.engine.ImErrorInfo;
+import com.android.im.provider.Imps;
import com.android.im.service.ImServiceConstants;
import android.app.Activity;
@@ -42,7 +43,6 @@ import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.RemoteException;
-import android.provider.Im;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
@@ -176,8 +176,8 @@ public class ContactListView extends LinearLayout {
void startChat(Cursor c) {
if (c != null) {
- long id = c.getLong(c.getColumnIndexOrThrow(Im.Contacts._ID));
- String username = c.getString(c.getColumnIndexOrThrow(Im.Contacts.USERNAME));
+ long id = c.getLong(c.getColumnIndexOrThrow(Imps.Contacts._ID));
+ String username = c.getString(c.getColumnIndexOrThrow(Imps.Contacts.USERNAME));
try {
IChatSessionManager manager = mConn.getChatSessionManager();
IChatSession session = manager.getChatSession(username);
@@ -185,7 +185,7 @@ public class ContactListView extends LinearLayout {
manager.createChatSession(username);
}
- Uri data = ContentUris.withAppendedId(Im.Chats.CONTENT_URI, id);
+ Uri data = ContentUris.withAppendedId(Imps.Chats.CONTENT_URI, id);
Intent i = new Intent(Intent.ACTION_VIEW, data);
i.addCategory(ImApp.IMPS_CATEGORY);
mScreen.startActivity(i);
@@ -215,7 +215,7 @@ public class ContactListView extends LinearLayout {
void endChat(Cursor c) {
if(c != null) {
- String username = c.getString(c.getColumnIndexOrThrow(Im.Contacts.USERNAME));
+ String username = c.getString(c.getColumnIndexOrThrow(Imps.Contacts.USERNAME));
try {
IChatSessionManager manager = mConn.getChatSessionManager();
IChatSession session = manager.getChatSession(username);
@@ -239,8 +239,8 @@ public class ContactListView extends LinearLayout {
public void viewContactPresence(Cursor c) {
if (c != null) {
- long id = c.getLong(c.getColumnIndexOrThrow(Im.Contacts._ID));
- Uri data = ContentUris.withAppendedId(Im.Contacts.CONTENT_URI, id);
+ long id = c.getLong(c.getColumnIndexOrThrow(Imps.Contacts._ID));
+ Uri data = ContentUris.withAppendedId(Imps.Contacts.CONTENT_URI, id);
Intent i = new Intent(Intent.ACTION_VIEW, data);
mScreen.startActivity(i);
}
@@ -292,8 +292,8 @@ public class ContactListView extends LinearLayout {
if (c == null) {
mHandler.showAlert(R.string.error, R.string.select_contact);
} else {
- String nickname = c.getString(c.getColumnIndexOrThrow(Im.Contacts.NICKNAME));
- final String address = c.getString(c.getColumnIndexOrThrow(Im.Contacts.USERNAME));
+ String nickname = c.getString(c.getColumnIndexOrThrow(Imps.Contacts.NICKNAME));
+ final String address = c.getString(c.getColumnIndexOrThrow(Imps.Contacts.USERNAME));
DialogInterface.OnClickListener confirmListener = new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int whichButton) {
try {
@@ -334,8 +334,8 @@ public class ContactListView extends LinearLayout {
if (c == null) {
mHandler.showAlert(R.string.error, R.string.select_contact);
} else {
- String nickname = c.getString(c.getColumnIndexOrThrow(Im.Contacts.NICKNAME));
- final String address = c.getString(c.getColumnIndexOrThrow(Im.Contacts.USERNAME));
+ String nickname = c.getString(c.getColumnIndexOrThrow(Imps.Contacts.NICKNAME));
+ final String address = c.getString(c.getColumnIndexOrThrow(Imps.Contacts.USERNAME));
DialogInterface.OnClickListener confirmListener = new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int whichButton) {
try {
@@ -394,7 +394,7 @@ public class ContactListView extends LinearLayout {
if (cursor == null) {
return null;
}
- return cursor.getString(cursor.getColumnIndexOrThrow(Im.ContactList.NAME));
+ return cursor.getString(cursor.getColumnIndexOrThrow(Imps.ContactList.NAME));
}
private void registerListeners() {
@@ -432,12 +432,12 @@ public class ContactListView extends LinearLayout {
int subscriptionType = cursor.getInt(ContactView.COLUMN_SUBSCRIPTION_TYPE);
int subscriptionStatus = cursor.getInt(ContactView.COLUMN_SUBSCRIPTION_STATUS);
- if ((subscriptionType == Im.Contacts.SUBSCRIPTION_TYPE_FROM)
- && (subscriptionStatus == Im.Contacts.SUBSCRIPTION_STATUS_SUBSCRIBE_PENDING)){
+ if ((subscriptionType == Imps.Contacts.SUBSCRIPTION_TYPE_FROM)
+ && (subscriptionStatus == Imps.Contacts.SUBSCRIPTION_STATUS_SUBSCRIBE_PENDING)){
long providerId = cursor.getLong(ContactView.COLUMN_CONTACT_PROVIDER);
String username = cursor.getString(ContactView.COLUMN_CONTACT_USERNAME);
Intent intent = new Intent(ImServiceConstants.ACTION_MANAGE_SUBSCRIPTION,
- ContentUris.withAppendedId(Im.Contacts.CONTENT_URI, id));
+ ContentUris.withAppendedId(Imps.Contacts.CONTENT_URI, id));
intent.putExtra(ImServiceConstants.EXTRA_INTENT_PROVIDER_ID, providerId);
intent.putExtra(ImServiceConstants.EXTRA_INTENT_FROM_ADDRESS, username);
mScreen.startActivity(intent);
diff --git a/src/com/android/im/app/ContactPresenceActivity.java b/src/com/android/im/app/ContactPresenceActivity.java
index 6531503..55454d4 100644
--- a/src/com/android/im/app/ContactPresenceActivity.java
+++ b/src/com/android/im/app/ContactPresenceActivity.java
@@ -25,7 +25,6 @@ import android.database.Cursor;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
-import android.provider.Im;
import android.text.SpannableString;
import android.text.TextUtils;
import android.text.style.ImageSpan;
@@ -36,6 +35,7 @@ import android.widget.TextView;
import com.android.im.R;
import com.android.im.plugin.BrandingResourceIDs;
+import com.android.im.provider.Imps;
public class ContactPresenceActivity extends Activity {
@@ -70,19 +70,19 @@ public class ContactPresenceActivity extends Activity {
}
if(c.moveToFirst()) {
- long providerId = c.getLong(c.getColumnIndexOrThrow(Im.Contacts.PROVIDER));
- String username = c.getString(c.getColumnIndexOrThrow(Im.Contacts.USERNAME));
- String nickname = c.getString(c.getColumnIndexOrThrow(Im.Contacts.NICKNAME));
- int status = c.getInt(c.getColumnIndexOrThrow(Im.Contacts.PRESENCE_STATUS));
- int clientType = c.getInt(c.getColumnIndexOrThrow(Im.Contacts.CLIENT_TYPE));
- String customStatus = c.getString(c.getColumnIndexOrThrow(Im.Contacts.PRESENCE_CUSTOM_STATUS));
+ long providerId = c.getLong(c.getColumnIndexOrThrow(Imps.Contacts.PROVIDER));
+ String username = c.getString(c.getColumnIndexOrThrow(Imps.Contacts.USERNAME));
+ String nickname = c.getString(c.getColumnIndexOrThrow(Imps.Contacts.NICKNAME));
+ int status = c.getInt(c.getColumnIndexOrThrow(Imps.Contacts.PRESENCE_STATUS));
+ int clientType = c.getInt(c.getColumnIndexOrThrow(Imps.Contacts.CLIENT_TYPE));
+ String customStatus = c.getString(c.getColumnIndexOrThrow(Imps.Contacts.PRESENCE_CUSTOM_STATUS));
ImApp app = ImApp.getApplication(this);
BrandingResources brandingRes = app.getBrandingResource(providerId);
setTitle(brandingRes.getString(BrandingResourceIDs.STRING_CONTACT_INFO_TITLE));
Drawable avatar = DatabaseUtils.getAvatarFromCursor(c,
- c.getColumnIndexOrThrow(Im.Contacts.AVATAR_DATA));
+ c.getColumnIndexOrThrow(Imps.Contacts.AVATAR_DATA));
if (avatar != null) {
imgAvatar.setImageDrawable(avatar);
} else {
@@ -119,7 +119,7 @@ public class ContactPresenceActivity extends Activity {
private String getClientTypeString(int clientType) {
Resources res = getResources();
switch (clientType) {
- case Im.Contacts.CLIENT_TYPE_MOBILE:
+ case Imps.Contacts.CLIENT_TYPE_MOBILE:
return res.getString(R.string.client_type_mobile);
default:
diff --git a/src/com/android/im/app/ContactView.java b/src/com/android/im/app/ContactView.java
index 38ee6cf..08bf921 100644
--- a/src/com/android/im/app/ContactView.java
+++ b/src/com/android/im/app/ContactView.java
@@ -24,7 +24,6 @@ import android.content.Context;
import android.content.res.Resources;
import android.database.Cursor;
import android.net.Uri;
-import android.provider.Im;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
@@ -40,24 +39,25 @@ import android.graphics.drawable.Drawable;
import com.android.im.R;
import com.android.im.plugin.BrandingResourceIDs;
+import com.android.im.provider.Imps;
import java.text.DateFormat;
import java.util.Calendar;
public class ContactView extends LinearLayout {
static final String[] CONTACT_PROJECTION = {
- Im.Contacts._ID,
- Im.Contacts.PROVIDER,
- Im.Contacts.ACCOUNT,
- Im.Contacts.USERNAME,
- Im.Contacts.NICKNAME,
- Im.Contacts.TYPE,
- Im.Contacts.SUBSCRIPTION_TYPE,
- Im.Contacts.SUBSCRIPTION_STATUS,
- Im.Presence.PRESENCE_STATUS,
- Im.Presence.PRESENCE_CUSTOM_STATUS,
- Im.Chats.LAST_MESSAGE_DATE,
- Im.Chats.LAST_UNREAD_MESSAGE,
+ Imps.Contacts._ID,
+ Imps.Contacts.PROVIDER,
+ Imps.Contacts.ACCOUNT,
+ Imps.Contacts.USERNAME,
+ Imps.Contacts.NICKNAME,
+ Imps.Contacts.TYPE,
+ Imps.Contacts.SUBSCRIPTION_TYPE,
+ Imps.Contacts.SUBSCRIPTION_STATUS,
+ Imps.Presence.PRESENCE_STATUS,
+ Imps.Presence.PRESENCE_CUSTOM_STATUS,
+ Imps.Chats.LAST_MESSAGE_DATE,
+ Imps.Chats.LAST_UNREAD_MESSAGE,
};
static final int COLUMN_CONTACT_ID = 0;
@@ -116,7 +116,7 @@ public class ContactView extends LinearLayout {
// status icon
- if (Im.Contacts.TYPE_GROUP == type) {
+ if (Imps.Contacts.TYPE_GROUP == type) {
iconId = lastMsg == null ? R.drawable.group_chat : R.drawable.group_chat_new;
} else if (hasChat) {
iconId = lastMsg == null ? BrandingResourceIDs.DRAWABLE_READ_CHAT
@@ -130,7 +130,7 @@ public class ContactView extends LinearLayout {
// line1
CharSequence line1;
- if (Im.Contacts.TYPE_GROUP == type) {
+ if (Imps.Contacts.TYPE_GROUP == type) {
ContentResolver resolver = getContext().getContentResolver();
long id = cursor.getLong(ContactView.COLUMN_CONTACT_ID);
line1 = queryGroupMembers(resolver, id);
@@ -151,7 +151,7 @@ public class ContactView extends LinearLayout {
}
}
- if (Im.Contacts.TYPE_TEMPORARY == type) {
+ if (Imps.Contacts.TYPE_TEMPORARY == type) {
// Add a mark at the front of name if it's only a temporary
// contact.
SpannableStringBuilder str = new SpannableStringBuilder(
@@ -182,7 +182,7 @@ public class ContactView extends LinearLayout {
}
if (TextUtils.isEmpty(line2)){
- if (Im.Contacts.TYPE_GROUP == type) {
+ if (Imps.Contacts.TYPE_GROUP == type) {
// Show nothing in line2 if it's a group and don't
// have any unread message.
line2 = null;
@@ -214,8 +214,8 @@ public class ContactView extends LinearLayout {
}
private String queryGroupMembers(ContentResolver resolver, long groupId) {
- String[] projection = { Im.GroupMembers.NICKNAME };
- Uri uri = ContentUris.withAppendedId(Im.GroupMembers.CONTENT_URI, groupId);
+ String[] projection = { Imps.GroupMembers.NICKNAME };
+ Uri uri = ContentUris.withAppendedId(Imps.GroupMembers.CONTENT_URI, groupId);
Cursor c = resolver.query(uri, projection, null, null, null);
StringBuilder buf = new StringBuilder();
if(c != null) {
diff --git a/src/com/android/im/app/ContactsPickerActivity.java b/src/com/android/im/app/ContactsPickerActivity.java
index eb52aa3..0dfb287 100644
--- a/src/com/android/im/app/ContactsPickerActivity.java
+++ b/src/com/android/im/app/ContactsPickerActivity.java
@@ -18,6 +18,7 @@
package com.android.im.app;
import com.android.im.R;
+import com.android.im.provider.Imps;
import android.app.ListActivity;
import android.content.Context;
@@ -26,7 +27,6 @@ import android.database.Cursor;
import android.database.DatabaseUtils;
import android.net.Uri;
import android.os.Bundle;
-import android.provider.Im;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
@@ -89,7 +89,7 @@ public class ContactsPickerActivity extends ListActivity {
}
mExcludeClause = buildExcludeClause(i.getStringArrayExtra(EXTRA_EXCLUDED_CONTACTS));
Cursor cursor = managedQuery(mData, ContactView.CONTACT_PROJECTION,
- mExcludeClause, Im.Contacts.DEFAULT_SORT_ORDER);
+ mExcludeClause, Imps.Contacts.DEFAULT_SORT_ORDER);
if (cursor == null) {
return false;
}
@@ -116,7 +116,7 @@ public class ContactsPickerActivity extends ListActivity {
}
StringBuilder clause = new StringBuilder();
- clause.append(Im.Contacts.USERNAME);
+ clause.append(Imps.Contacts.USERNAME);
clause.append(" NOT IN (");
int len = excluded.length;
for (int i = 0; i < len - 1; i++) {
@@ -138,14 +138,14 @@ public class ContactsPickerActivity extends ListActivity {
buf.append(mExcludeClause).append(" AND ");
}
- buf.append(Im.Contacts.NICKNAME);
+ buf.append(Imps.Contacts.NICKNAME);
buf.append(" LIKE ");
DatabaseUtils.appendValueToSql(buf, "%" + constraint + "%");
where = buf.toString();
}
return managedQuery(mData, ContactView.CONTACT_PROJECTION, where,
- Im.Contacts.DEFAULT_SORT_ORDER);
+ Imps.Contacts.DEFAULT_SORT_ORDER);
}
private class ContactsAdapter extends ResourceCursorAdapter {
diff --git a/src/com/android/im/app/DatabaseUtils.java b/src/com/android/im/app/DatabaseUtils.java
index 503f9be..4484114 100644
--- a/src/com/android/im/app/DatabaseUtils.java
+++ b/src/com/android/im/app/DatabaseUtils.java
@@ -18,6 +18,7 @@
package com.android.im.app;
import com.android.im.plugin.ImConfigNames;
+import com.android.im.provider.Imps;
import android.content.ContentResolver;
import android.content.ContentUris;
@@ -28,7 +29,6 @@ import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
-import android.provider.Im;
import android.util.Log;
import java.util.Map;
@@ -42,9 +42,9 @@ public class DatabaseUtils {
public static Cursor queryAccountsForProvider(ContentResolver cr,
String[] projection, long providerId) {
- StringBuilder where = new StringBuilder(Im.Account.ACTIVE);
- where.append("=1 AND ").append(Im.Account.PROVIDER).append('=').append(providerId);
- Cursor c = cr.query(Im.Account.CONTENT_URI, projection, where.toString(), null, null);
+ StringBuilder where = new StringBuilder(Imps.Account.ACTIVE);
+ where.append("=1 AND ").append(Imps.Account.PROVIDER).append('=').append(providerId);
+ Cursor c = cr.query(Imps.Account.CONTENT_URI, projection, where.toString(), null, null);
if (c != null && !c.moveToFirst()) {
c.close();
return null;
@@ -116,9 +116,9 @@ public class DatabaseUtils {
private static void updateAvatarBlob(ContentResolver resolver, Uri updateUri, byte[] data,
String username) {
ContentValues values = new ContentValues(3);
- values.put(Im.Avatars.DATA, data);
+ values.put(Imps.Avatars.DATA, data);
- StringBuilder buf = new StringBuilder(Im.Avatars.CONTACT);
+ StringBuilder buf = new StringBuilder(Imps.Avatars.CONTACT);
buf.append("=?");
String[] selectionArgs = new String[] {
@@ -149,7 +149,7 @@ public class DatabaseUtils {
boolean versionChanged;
// query provider data
- long providerId = Im.Provider.getProviderIdForName(cr, providerName);
+ long providerId = Imps.Provider.getProviderIdForName(cr, providerName);
if (providerId > 0) {
// already loaded, check if version changed
String pluginVersion = config.get(ImConfigNames.PLUGIN_VERSION);
@@ -183,10 +183,10 @@ public class DatabaseUtils {
*/
private static int clearBrandingResourceMapCache(ContentResolver cr, long providerId) {
StringBuilder where = new StringBuilder();
- where.append(Im.BrandingResourceMapCache.PROVIDER_ID);
+ where.append(Imps.BrandingResourceMapCache.PROVIDER_ID);
where.append('=');
where.append(providerId);
- return cr.delete(Im.BrandingResourceMapCache.CONTENT_URI, where.toString(), null);
+ return cr.delete(Imps.BrandingResourceMapCache.CONTENT_URI, where.toString(), null);
}
/**
@@ -198,12 +198,12 @@ public class DatabaseUtils {
int index = 0;
for (Map.Entry<String, String> entry : config.entrySet()) {
ContentValues settingValue = new ContentValues();
- settingValue.put(Im.ProviderSettings.PROVIDER, providerId);
- settingValue.put(Im.ProviderSettings.NAME, entry.getKey());
- settingValue.put(Im.ProviderSettings.VALUE, entry.getValue());
+ settingValue.put(Imps.ProviderSettings.PROVIDER, providerId);
+ settingValue.put(Imps.ProviderSettings.NAME, entry.getKey());
+ settingValue.put(Imps.ProviderSettings.VALUE, entry.getValue());
settingValues[index++] = settingValue;
}
- return cr.bulkInsert(Im.ProviderSettings.CONTENT_URI, settingValues);
+ return cr.bulkInsert(Imps.ProviderSettings.CONTENT_URI, settingValues);
}
/**
@@ -212,11 +212,11 @@ public class DatabaseUtils {
private static long insertProviderRow(ContentResolver cr, String providerName,
String providerFullName, String signUpUrl) {
ContentValues values = new ContentValues(3);
- values.put(Im.Provider.NAME, providerName);
- values.put(Im.Provider.FULLNAME, providerFullName);
- values.put(Im.Provider.CATEGORY, ImApp.IMPS_CATEGORY);
- values.put(Im.Provider.SIGNUP_URL, signUpUrl);
- Uri result = cr.insert(Im.Provider.CONTENT_URI, values);
+ values.put(Imps.Provider.NAME, providerName);
+ values.put(Imps.Provider.FULLNAME, providerFullName);
+ values.put(Imps.Provider.CATEGORY, ImApp.IMPS_CATEGORY);
+ values.put(Imps.Provider.SIGNUP_URL, signUpUrl);
+ Uri result = cr.insert(Imps.Provider.CONTENT_URI, values);
return ContentUris.parseId(result);
}
@@ -231,10 +231,10 @@ public class DatabaseUtils {
// Note that we don't update the provider name because it's used as
// identifier at some place and the plugin should never change it.
ContentValues values = new ContentValues(3);
- values.put(Im.Provider.FULLNAME, providerFullName);
- values.put(Im.Provider.SIGNUP_URL, signUpUrl);
- values.put(Im.Provider.CATEGORY, ImApp.IMPS_CATEGORY);
- Uri uri = ContentUris.withAppendedId(Im.Provider.CONTENT_URI, providerId);
+ values.put(Imps.Provider.FULLNAME, providerFullName);
+ values.put(Imps.Provider.SIGNUP_URL, signUpUrl);
+ values.put(Imps.Provider.CATEGORY, ImApp.IMPS_CATEGORY);
+ Uri uri = ContentUris.withAppendedId(Imps.Provider.CONTENT_URI, providerId);
return cr.update(uri, values, null, null);
}
@@ -243,7 +243,7 @@ public class DatabaseUtils {
*/
private static boolean isPluginVersionChanged(ContentResolver cr, long providerId,
String newVersion) {
- String oldVersion = Im.ProviderSettings.getStringValue(cr, providerId,
+ String oldVersion = Imps.ProviderSettings.getStringValue(cr, providerId,
ImConfigNames.PLUGIN_VERSION);
if (oldVersion == null) {
return true;
diff --git a/src/com/android/im/app/ImApp.java b/src/com/android/im/app/ImApp.java
index c02522a..02f9cae 100644
--- a/src/com/android/im/app/ImApp.java
+++ b/src/com/android/im/app/ImApp.java
@@ -43,7 +43,6 @@ import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
-import android.provider.Im;
import android.util.Log;
import com.android.im.IConnectionCreationListener;
@@ -56,6 +55,7 @@ import com.android.im.engine.ImErrorInfo;
import com.android.im.plugin.BrandingResourceIDs;
import com.android.im.plugin.ImPlugin;
import com.android.im.plugin.ImPluginInfo;
+import com.android.im.provider.Imps;
import com.android.im.service.ImServiceConstants;
public class ImApp extends Application {
@@ -98,18 +98,18 @@ public class ImApp extends Application {
public static final int EVENT_UPDATE_USER_PRESENCE_ERROR = 301;
private static final String[] PROVIDER_PROJECTION = {
- Im.Provider._ID,
- Im.Provider.NAME,
- Im.Provider.FULLNAME,
- Im.Provider.SIGNUP_URL,
+ Imps.Provider._ID,
+ Imps.Provider.NAME,
+ Imps.Provider.FULLNAME,
+ Imps.Provider.SIGNUP_URL,
};
private static final String[] ACCOUNT_PROJECTION = {
- Im.Account._ID,
- Im.Account.PROVIDER,
- Im.Account.NAME,
- Im.Account.USERNAME,
- Im.Account.PASSWORD,
+ Imps.Account._ID,
+ Imps.Account.PROVIDER,
+ Imps.Account.NAME,
+ Imps.Account.USERNAME,
+ Imps.Account.PASSWORD,
};
static final void log(String log) {
@@ -261,27 +261,27 @@ public class ImApp extends Application {
public static long insertOrUpdateAccount(ContentResolver cr,
long providerId, String userName, String pw) {
- String selection = Im.Account.PROVIDER + "=? AND " + Im.Account.USERNAME + "=?";
+ String selection = Imps.Account.PROVIDER + "=? AND " + Imps.Account.USERNAME + "=?";
String[] selectionArgs = {Long.toString(providerId), userName };
- Cursor c = cr.query(Im.Account.CONTENT_URI, ACCOUNT_PROJECTION,
+ Cursor c = cr.query(Imps.Account.CONTENT_URI, ACCOUNT_PROJECTION,
selection, selectionArgs, null);
if (c != null && c.moveToFirst()) {
// Update the password
- c.updateString(c.getColumnIndexOrThrow(Im.Account.PASSWORD), pw);
+ c.updateString(c.getColumnIndexOrThrow(Imps.Account.PASSWORD), pw);
c.commitUpdates();
- long id = c.getLong(c.getColumnIndexOrThrow(Im.Account._ID));
+ long id = c.getLong(c.getColumnIndexOrThrow(Imps.Account._ID));
c.close();
return id;
} else {
ContentValues values = new ContentValues(4);
- values.put(Im.Account.PROVIDER, providerId);
- values.put(Im.Account.NAME, userName);
- values.put(Im.Account.USERNAME, userName);
- values.put(Im.Account.PASSWORD, pw);
+ values.put(Imps.Account.PROVIDER, providerId);
+ values.put(Imps.Account.NAME, userName);
+ values.put(Imps.Account.USERNAME, userName);
+ values.put(Imps.Account.PASSWORD, pw);
- Uri result = cr.insert(Im.Account.CONTENT_URI, values);
+ Uri result = cr.insert(Imps.Account.CONTENT_URI, values);
return ContentUris.parseId(result);
}
}
@@ -297,8 +297,8 @@ public class ImApp extends Application {
String selectionArgs[] = new String[1];
selectionArgs[0] = ImApp.IMPS_CATEGORY;
- Cursor c = cr.query(Im.Provider.CONTENT_URI, PROVIDER_PROJECTION,
- Im.Provider.CATEGORY+"=?", selectionArgs, null);
+ Cursor c = cr.query(Imps.Provider.CONTENT_URI, PROVIDER_PROJECTION,
+ Imps.Provider.CATEGORY+"=?", selectionArgs, null);
if (c == null) {
return;
}
diff --git a/src/com/android/im/app/ImPluginHelper.java b/src/com/android/im/app/ImPluginHelper.java
index 2af7633..4e9159e 100644
--- a/src/com/android/im/app/ImPluginHelper.java
+++ b/src/com/android/im/app/ImPluginHelper.java
@@ -33,7 +33,6 @@ import android.database.Cursor;
import android.database.sqlite.SQLiteFullException;
import android.net.Uri;
import android.os.Bundle;
-import android.provider.Im;
import android.text.TextUtils;
import android.util.Log;
@@ -41,6 +40,7 @@ import com.android.im.plugin.ImConfigNames;
import com.android.im.plugin.ImPlugin;
import com.android.im.plugin.ImPluginConstants;
import com.android.im.plugin.ImPluginInfo;
+import com.android.im.provider.Imps;
public class ImPluginHelper {
@@ -185,9 +185,9 @@ public class ImPluginHelper {
long providerId = 0;
ContentResolver cr = mContext.getContentResolver();
- String where = Im.Provider.NAME + "=?";
+ String where = Imps.Provider.NAME + "=?";
String[] selectionArgs = new String[]{info.mProviderName};
- Cursor c = cr.query(Im.Provider.CONTENT_URI,
+ Cursor c = cr.query(Imps.Provider.CONTENT_URI,
null /* projection */,
where,
selectionArgs,
@@ -196,7 +196,7 @@ public class ImPluginHelper {
boolean pluginChanged;
try {
if (c.moveToFirst()) {
- providerId = c.getLong(c.getColumnIndexOrThrow(Im.Provider._ID));
+ providerId = c.getLong(c.getColumnIndexOrThrow(Imps.Provider._ID));
pluginChanged = isPluginChanged(cr, providerId, config);
if (pluginChanged) {
// Update the full name, signup url and category each time when the plugin change
@@ -205,20 +205,20 @@ public class ImPluginHelper {
// Note that we don't update the provider name because it's used as
// identifier at some place and the plugin should never change it.
ContentValues values = new ContentValues(3);
- values.put(Im.Provider.FULLNAME, providerFullName);
- values.put(Im.Provider.SIGNUP_URL, signUpUrl);
- values.put(Im.Provider.CATEGORY, ImApp.IMPS_CATEGORY);
- Uri uri = ContentUris.withAppendedId(Im.Provider.CONTENT_URI, providerId);
+ values.put(Imps.Provider.FULLNAME, providerFullName);
+ values.put(Imps.Provider.SIGNUP_URL, signUpUrl);
+ values.put(Imps.Provider.CATEGORY, ImApp.IMPS_CATEGORY);
+ Uri uri = ContentUris.withAppendedId(Imps.Provider.CONTENT_URI, providerId);
cr.update(uri, values, null, null);
}
} else {
ContentValues values = new ContentValues(3);
- values.put(Im.Provider.NAME, info.mProviderName);
- values.put(Im.Provider.FULLNAME, providerFullName);
- values.put(Im.Provider.CATEGORY, ImApp.IMPS_CATEGORY);
- values.put(Im.Provider.SIGNUP_URL, signUpUrl);
+ values.put(Imps.Provider.NAME, info.mProviderName);
+ values.put(Imps.Provider.FULLNAME, providerFullName);
+ values.put(Imps.Provider.CATEGORY, ImApp.IMPS_CATEGORY);
+ values.put(Imps.Provider.SIGNUP_URL, signUpUrl);
- Uri result = cr.insert(Im.Provider.CONTENT_URI, values);
+ Uri result = cr.insert(Imps.Provider.CONTENT_URI, values);
providerId = ContentUris.parseId(result);
pluginChanged = true;
}
@@ -231,7 +231,7 @@ public class ImPluginHelper {
if (pluginChanged) {
// Remove all the old settings
cr.delete(ContentUris.withAppendedId(
- Im.ProviderSettings.CONTENT_URI, providerId),
+ Imps.ProviderSettings.CONTENT_URI, providerId),
null, /*where*/
null /*selectionArgs*/);
@@ -240,12 +240,12 @@ public class ImPluginHelper {
int index = 0;
for (Map.Entry<String, String> entry : config.entrySet()) {
ContentValues settingValue = new ContentValues();
- settingValue.put(Im.ProviderSettings.PROVIDER, providerId);
- settingValue.put(Im.ProviderSettings.NAME, entry.getKey());
- settingValue.put(Im.ProviderSettings.VALUE, entry.getValue());
+ settingValue.put(Imps.ProviderSettings.PROVIDER, providerId);
+ settingValue.put(Imps.ProviderSettings.NAME, entry.getKey());
+ settingValue.put(Imps.ProviderSettings.VALUE, entry.getValue());
settingValues[index++] = settingValue;
}
- cr.bulkInsert(Im.ProviderSettings.CONTENT_URI, settingValues);
+ cr.bulkInsert(Imps.ProviderSettings.CONTENT_URI, settingValues);
}
return providerId;
@@ -266,7 +266,7 @@ public class ImPluginHelper {
private boolean isPluginChanged(ContentResolver cr, long providerId,
Map<String, String> config) {
- String origVersion = Im.ProviderSettings.getStringValue(cr, providerId,
+ String origVersion = Imps.ProviderSettings.getStringValue(cr, providerId,
ImConfigNames.PLUGIN_VERSION);
if (origVersion == null) {
diff --git a/src/com/android/im/app/ImRingtonePreference.java b/src/com/android/im/app/ImRingtonePreference.java
index 9f89c61..59183e6 100644
--- a/src/com/android/im/app/ImRingtonePreference.java
+++ b/src/com/android/im/app/ImRingtonePreference.java
@@ -17,6 +17,7 @@
package com.android.im.app;
+import com.android.im.provider.Imps;
import com.android.im.service.ImServiceConstants;
import android.app.Activity;
@@ -24,7 +25,6 @@ import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.preference.RingtonePreference;
-import android.provider.Im;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
@@ -47,7 +47,7 @@ public class ImRingtonePreference extends RingtonePreference {
@Override
protected Uri onRestoreRingtone() {
- final Im.ProviderSettings.QueryMap settings = new Im.ProviderSettings.QueryMap(
+ final Imps.ProviderSettings.QueryMap settings = new Imps.ProviderSettings.QueryMap(
getContext().getContentResolver(), mProviderId,
false /* keep updated */, null /* no handler */);
@@ -70,7 +70,7 @@ public class ImRingtonePreference extends RingtonePreference {
@Override
protected void onSaveRingtone(Uri ringtoneUri) {
- final Im.ProviderSettings.QueryMap settings = new Im.ProviderSettings.QueryMap(
+ final Imps.ProviderSettings.QueryMap settings = new Imps.ProviderSettings.QueryMap(
getContext().getContentResolver(), mProviderId,
false /* keep updated */, null /* no handler */);
diff --git a/src/com/android/im/app/ImUrlActivity.java b/src/com/android/im/app/ImUrlActivity.java
index a23a7fd..134a83f 100644
--- a/src/com/android/im/app/ImUrlActivity.java
+++ b/src/com/android/im/app/ImUrlActivity.java
@@ -20,6 +20,8 @@ import com.android.im.IChatSession;
import com.android.im.IChatSessionManager;
import com.android.im.IImConnection;
import com.android.im.engine.ImConnection;
+import com.android.im.provider.Imps;
+
import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentUris;
@@ -29,7 +31,6 @@ import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.RemoteException;
-import android.provider.Im;
import android.text.TextUtils;
import android.util.Log;
@@ -38,8 +39,8 @@ import java.util.Set;
public class ImUrlActivity extends Activity {
private static final String[] ACCOUNT_PROJECTION = {
- Im.Account._ID,
- Im.Account.PASSWORD,
+ Imps.Account._ID,
+ Imps.Account.PASSWORD,
};
private static final int ACCOUNT_ID_COLUMN = 0;
private static final int ACCOUNT_PW_COLUMN = 1;
@@ -78,7 +79,7 @@ public class ImUrlActivity extends Activity {
void handleIntent() {
ContentResolver cr = getContentResolver();
- long providerId = Im.Provider.getProviderIdForName(cr, mProviderName);
+ long providerId = Imps.Provider.getProviderIdForName(cr, mProviderName);
long accountId;
mConn= mApp.getConnection(providerId);
@@ -119,13 +120,13 @@ public class ImUrlActivity extends Activity {
private void addAccount(long providerId) {
Intent intent = new Intent(this, AccountActivity.class);
intent.setAction(Intent.ACTION_INSERT);
- intent.setData(ContentUris.withAppendedId(Im.Provider.CONTENT_URI, providerId));
+ intent.setData(ContentUris.withAppendedId(Imps.Provider.CONTENT_URI, providerId));
intent.putExtra(ImApp.EXTRA_INTENT_SEND_TO_USER, mToAddress);
startActivity(intent);
}
private void editAccount(long accountId) {
- Uri accountUri = ContentUris.withAppendedId(Im.Account.CONTENT_URI, accountId);
+ Uri accountUri = ContentUris.withAppendedId(Imps.Account.CONTENT_URI, accountId);
Intent intent = new Intent(this, AccountActivity.class);
intent.setAction(Intent.ACTION_EDIT);
intent.setData(accountUri);
@@ -134,7 +135,7 @@ public class ImUrlActivity extends Activity {
}
private void signInAccount(long accountId) {
- Uri accountUri = ContentUris.withAppendedId(Im.Account.CONTENT_URI, accountId);
+ Uri accountUri = ContentUris.withAppendedId(Imps.Account.CONTENT_URI, accountId);
Intent intent = new Intent(this, SigningInActivity.class);
intent.setData(accountUri);
intent.putExtra(ImApp.EXTRA_INTENT_SEND_TO_USER, mToAddress);
@@ -143,7 +144,7 @@ public class ImUrlActivity extends Activity {
private void showContactList(long accountId) {
Intent intent = new Intent(Intent.ACTION_VIEW);
- intent.setData(Im.Contacts.CONTENT_URI);
+ intent.setData(Imps.Contacts.CONTENT_URI);
intent.addCategory(ImApp.IMPS_CATEGORY);
intent.putExtra("accountId", accountId);
@@ -158,7 +159,7 @@ public class ImUrlActivity extends Activity {
session = manager.createChatSession(mToAddress);
}
- Uri data = ContentUris.withAppendedId(Im.Chats.CONTENT_URI, session.getId());
+ Uri data = ContentUris.withAppendedId(Imps.Chats.CONTENT_URI, session.getId());
Intent i = new Intent(Intent.ACTION_VIEW, data);
i.putExtra("from", mToAddress);
i.putExtra("providerId", provider);
@@ -225,11 +226,11 @@ public class ImUrlActivity extends Activity {
private String getProviderNameForCategory(String providerCategory) {
if (providerCategory != null) {
if (providerCategory.equalsIgnoreCase("com.android.im.category.AIM")) {
- return Im.ProviderNames.AIM;
+ return Imps.ProviderNames.AIM;
} else if (providerCategory.equalsIgnoreCase("com.android.im.category.MSN")) {
- return Im.ProviderNames.MSN;
+ return Imps.ProviderNames.MSN;
} else if (providerCategory.equalsIgnoreCase("com.android.im.category.YAHOO")) {
- return Im.ProviderNames.YAHOO;
+ return Imps.ProviderNames.YAHOO;
}
}
@@ -241,16 +242,16 @@ public class ImUrlActivity extends Activity {
return null;
}
- if (Im.ProviderNames.AIM.equalsIgnoreCase(provider)) {
- return Im.ProviderNames.AIM;
+ if (Imps.ProviderNames.AIM.equalsIgnoreCase(provider)) {
+ return Imps.ProviderNames.AIM;
}
- if (Im.ProviderNames.MSN.equalsIgnoreCase(provider)) {
- return Im.ProviderNames.MSN;
+ if (Imps.ProviderNames.MSN.equalsIgnoreCase(provider)) {
+ return Imps.ProviderNames.MSN;
}
- if (Im.ProviderNames.YAHOO.equalsIgnoreCase(provider)) {
- return Im.ProviderNames.YAHOO;
+ if (Imps.ProviderNames.YAHOO.equalsIgnoreCase(provider)) {
+ return Imps.ProviderNames.YAHOO;
}
return null;
diff --git a/src/com/android/im/app/LandingPage.java b/src/com/android/im/app/LandingPage.java
index 8020cd0..3c9ac99 100644
--- a/src/com/android/im/app/LandingPage.java
+++ b/src/com/android/im/app/LandingPage.java
@@ -28,7 +28,6 @@ import android.net.Uri;
import android.os.Bundle;
import android.os.Message;
import android.os.RemoteException;
-import android.provider.Im;
import android.util.AttributeSet;
import android.util.Log;
import android.view.ContextMenu;
@@ -45,6 +44,7 @@ import android.widget.ListView;
import com.android.im.IImConnection;
import com.android.im.R;
import com.android.im.plugin.BrandingResourceIDs;
+import com.android.im.provider.Imps;
public class LandingPage extends ListActivity implements View.OnCreateContextMenuListener {
private static final String TAG = ImApp.LOG_TAG;
@@ -64,17 +64,17 @@ public class LandingPage extends ListActivity implements View.OnCreateContextMen
private SimpleAlertHandler mHandler;
private static final String[] PROVIDER_PROJECTION = {
- Im.Provider._ID,
- Im.Provider.NAME,
- Im.Provider.FULLNAME,
- Im.Provider.CATEGORY,
- Im.Provider.ACTIVE_ACCOUNT_ID,
- Im.Provider.ACTIVE_ACCOUNT_USERNAME,
- Im.Provider.ACTIVE_ACCOUNT_PW,
- Im.Provider.ACTIVE_ACCOUNT_LOCKED,
- Im.Provider.ACTIVE_ACCOUNT_KEEP_SIGNED_IN,
- Im.Provider.ACCOUNT_PRESENCE_STATUS,
- Im.Provider.ACCOUNT_CONNECTION_STATUS,
+ Imps.Provider._ID,
+ Imps.Provider.NAME,
+ Imps.Provider.FULLNAME,
+ Imps.Provider.CATEGORY,
+ Imps.Provider.ACTIVE_ACCOUNT_ID,
+ Imps.Provider.ACTIVE_ACCOUNT_USERNAME,
+ Imps.Provider.ACTIVE_ACCOUNT_PW,
+ Imps.Provider.ACTIVE_ACCOUNT_LOCKED,
+ Imps.Provider.ACTIVE_ACCOUNT_KEEP_SIGNED_IN,
+ Imps.Provider.ACCOUNT_PRESENCE_STATUS,
+ Imps.Provider.ACCOUNT_CONNECTION_STATUS,
};
static final int PROVIDER_ID_COLUMN = 0;
@@ -100,11 +100,11 @@ public class LandingPage extends ListActivity implements View.OnCreateContextMen
ImPluginHelper.getInstance(this).loadAvaiablePlugins();
- mProviderCursor = managedQuery(Im.Provider.CONTENT_URI_WITH_ACCOUNT,
+ mProviderCursor = managedQuery(Imps.Provider.CONTENT_URI_WITH_ACCOUNT,
PROVIDER_PROJECTION,
- Im.Provider.CATEGORY + "=?" /* selection */,
+ Imps.Provider.CATEGORY + "=?" /* selection */,
new String[]{ ImApp.IMPS_CATEGORY } /* selection args */,
- Im.Provider.DEFAULT_SORT_ORDER);
+ Imps.Provider.DEFAULT_SORT_ORDER);
mAdapter = new ProviderAdapter(this, mProviderCursor);
setListAdapter(mAdapter);
@@ -142,18 +142,18 @@ public class LandingPage extends ListActivity implements View.OnCreateContextMen
}
Intent intent = new Intent(this, SigningInActivity.class);
- intent.setData(ContentUris.withAppendedId(Im.Account.CONTENT_URI, accountId));
+ intent.setData(ContentUris.withAppendedId(Imps.Account.CONTENT_URI, accountId));
startActivity(intent);
}
boolean isSigningIn(Cursor cursor) {
int connectionStatus = cursor.getInt(ACCOUNT_CONNECTION_STATUS);
- return connectionStatus == Im.ConnectionStatus.CONNECTING;
+ return connectionStatus == Imps.ConnectionStatus.CONNECTING;
}
private boolean isSignedIn(Cursor cursor) {
int connectionStatus = cursor.getInt(ACCOUNT_CONNECTION_STATUS);
- return connectionStatus == Im.ConnectionStatus.ONLINE;
+ return connectionStatus == Imps.ConnectionStatus.ONLINE;
}
private boolean allAccountsSignedOut() {
@@ -295,7 +295,7 @@ public class LandingPage extends ListActivity implements View.OnCreateContextMen
case ID_REMOVE_ACCOUNT:
{
- Uri accountUri = ContentUris.withAppendedId(Im.Account.CONTENT_URI, accountId);
+ Uri accountUri = ContentUris.withAppendedId(Imps.Account.CONTENT_URI, accountId);
getContentResolver().delete(accountUri, null, null);
// Requery the cursor to force refreshing screen
providerCursor.requery();
@@ -329,7 +329,7 @@ public class LandingPage extends ListActivity implements View.OnCreateContextMen
case ID_SETTINGS:
{
- Intent intent = new Intent(Intent.ACTION_VIEW, Im.ProviderSettings.CONTENT_URI);
+ Intent intent = new Intent(Intent.ACTION_VIEW, Imps.ProviderSettings.CONTENT_URI);
intent.addCategory(getProviderCategory(providerCursor));
intent.putExtra("providerId", providerId);
startActivity(intent);
@@ -353,7 +353,7 @@ public class LandingPage extends ListActivity implements View.OnCreateContextMen
int state = mProviderCursor.getInt(ACCOUNT_CONNECTION_STATUS);
long accountId = mProviderCursor.getLong(ACTIVE_ACCOUNT_ID_COLUMN);
- if (state == Im.ConnectionStatus.OFFLINE) {
+ if (state == Imps.ConnectionStatus.OFFLINE) {
boolean isKeepSignedIn = mProviderCursor.getInt(ACTIVE_ACCOUNT_KEEP_SIGNED_IN) != 0;
boolean isAccountEditible = mProviderCursor.getInt(ACTIVE_ACCOUNT_LOCKED) == 0;
if (isKeepSignedIn) {
@@ -361,7 +361,7 @@ public class LandingPage extends ListActivity implements View.OnCreateContextMen
} else if(isAccountEditible) {
intent = getEditAccountIntent();
}
- } else if (state == Im.ConnectionStatus.CONNECTING) {
+ } else if (state == Imps.ConnectionStatus.CONNECTING) {
signIn(accountId);
} else {
intent = getViewContactsIntent();
@@ -378,14 +378,14 @@ public class LandingPage extends ListActivity implements View.OnCreateContextMen
intent.setAction(Intent.ACTION_INSERT);
long providerId = mProviderCursor.getLong(PROVIDER_ID_COLUMN);
- intent.setData(ContentUris.withAppendedId(Im.Provider.CONTENT_URI, providerId));
+ intent.setData(ContentUris.withAppendedId(Imps.Provider.CONTENT_URI, providerId));
intent.addCategory(getProviderCategory(mProviderCursor));
return intent;
}
Intent getEditAccountIntent() {
Intent intent = new Intent(Intent.ACTION_EDIT,
- ContentUris.withAppendedId(Im.Account.CONTENT_URI,
+ ContentUris.withAppendedId(Imps.Account.CONTENT_URI,
mProviderCursor.getLong(ACTIVE_ACCOUNT_ID_COLUMN)));
intent.addCategory(getProviderCategory(mProviderCursor));
return intent;
@@ -393,7 +393,7 @@ public class LandingPage extends ListActivity implements View.OnCreateContextMen
Intent getViewContactsIntent() {
Intent intent = new Intent(Intent.ACTION_VIEW);
- intent.setData(Im.Contacts.CONTENT_URI);
+ intent.setData(Imps.Contacts.CONTENT_URI);
intent.addCategory(getProviderCategory(mProviderCursor));
intent.putExtra("accountId", mProviderCursor.getLong(ACTIVE_ACCOUNT_ID_COLUMN));
return intent;
diff --git a/src/com/android/im/app/MessageView.java b/src/com/android/im/app/MessageView.java
index 9a42cbb..5e2424f 100644
--- a/src/com/android/im/app/MessageView.java
+++ b/src/com/android/im/app/MessageView.java
@@ -23,7 +23,6 @@ import java.util.Date;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Typeface;
-import android.provider.Im;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
@@ -36,6 +35,7 @@ import android.widget.LinearLayout;
import android.widget.TextView;
import com.android.im.R;
+import com.android.im.provider.Imps;
public class MessageView extends LinearLayout {
@@ -132,20 +132,20 @@ public class MessageView extends LinearLayout {
boolean isGroupChat, boolean scrolling) {
String body;
switch (type) {
- case Im.MessageType.PRESENCE_AVAILABLE:
+ case Imps.MessageType.PRESENCE_AVAILABLE:
body = mResources.getString(isGroupChat ? R.string.contact_joined
: R.string.contact_online, contact);
break;
- case Im.MessageType.PRESENCE_AWAY:
+ case Imps.MessageType.PRESENCE_AWAY:
body = mResources.getString(R.string.contact_away, contact);
break;
- case Im.MessageType.PRESENCE_DND:
+ case Imps.MessageType.PRESENCE_DND:
body = mResources.getString(R.string.contact_busy, contact);
break;
- case Im.MessageType.PRESENCE_UNAVAILABLE:
+ case Imps.MessageType.PRESENCE_UNAVAILABLE:
body = mResources.getString(isGroupChat ? R.string.contact_left
: R.string.contact_offline, contact);
break;
diff --git a/src/com/android/im/app/NewChatActivity.java b/src/com/android/im/app/NewChatActivity.java
index 62f1790..d8c6c1d 100644
--- a/src/com/android/im/app/NewChatActivity.java
+++ b/src/com/android/im/app/NewChatActivity.java
@@ -26,6 +26,7 @@ import com.android.im.IChatSession;
import com.android.im.R;
import com.android.im.app.adapter.ChatListenerAdapter;
import com.android.im.plugin.BrandingResourceIDs;
+import com.android.im.provider.Imps;
import android.app.Activity;
import android.app.AlertDialog;
@@ -39,7 +40,6 @@ import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.RemoteException;
-import android.provider.Im;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
@@ -134,9 +134,9 @@ public class NewChatActivity extends Activity {
} else {
Uri data = intent.getData();
String type = getContentResolver().getType(data);
- if (Im.Chats.CONTENT_ITEM_TYPE.equals(type)) {
+ if (Imps.Chats.CONTENT_ITEM_TYPE.equals(type)) {
mChatView.bindChat(ContentUris.parseId(data));
- } else if (Im.Invitation.CONTENT_ITEM_TYPE.equals(type)) {
+ } else if (Imps.Invitation.CONTENT_ITEM_TYPE.equals(type)) {
mChatView.bindInvitation(ContentUris.parseId(data));
}
}
@@ -173,8 +173,8 @@ public class NewChatActivity extends Activity {
//XXX HACK: Yahoo! doesn't allow to block a friend. We can only block a temporary contact.
ProviderDef provider = mApp.getProvider(mChatView.getProviderId());
- if ((provider != null) && Im.ProviderNames.YAHOO.equals(provider.mName)) {
- if (Im.Contacts.TYPE_TEMPORARY != mChatView.mType) {
+ if ((provider != null) && Imps.ProviderNames.YAHOO.equals(provider.mName)) {
+ if (Imps.Contacts.TYPE_TEMPORARY != mChatView.mType) {
menu.findItem(R.id.menu_block_contact).setVisible(false);
}
}
@@ -347,7 +347,7 @@ public class NewChatActivity extends Activity {
}
private void startContactPicker() {
- Uri.Builder builder = Im.Contacts.CONTENT_URI_ONLINE_CONTACTS_BY.buildUpon();
+ Uri.Builder builder = Imps.Contacts.CONTENT_URI_ONLINE_CONTACTS_BY.buildUpon();
ContentUris.appendId(builder, mChatView.getProviderId());
ContentUris.appendId(builder, mChatView.getAccountId());
Uri data = builder.build();
diff --git a/src/com/android/im/app/PreferenceActivity.java b/src/com/android/im/app/PreferenceActivity.java
index 99e3f6e..14215ec 100644
--- a/src/com/android/im/app/PreferenceActivity.java
+++ b/src/com/android/im/app/PreferenceActivity.java
@@ -24,7 +24,6 @@ import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
-import android.provider.Im;
import android.util.Log;
import android.view.View;
import android.widget.Button;
@@ -37,6 +36,7 @@ import com.android.im.imps.ImpsConnectionConfig.EncodingType;
import com.android.im.imps.ImpsConnectionConfig.TransportType;
import com.android.im.plugin.ImConfigNames;
import com.android.im.plugin.ImpsConfigNames;
+import com.android.im.provider.Imps;
public class PreferenceActivity extends Activity {
@@ -121,7 +121,7 @@ public class PreferenceActivity extends Activity {
finish();
} else {
Cursor c = getContentResolver().query(i.getData(),
- new String[]{Im.Provider._ID, Im.Provider.NAME}, null, null, null);
+ new String[]{Imps.Provider._ID, Imps.Provider.NAME}, null, null, null);
if (c == null || !c.moveToFirst()) {
Log.w(ImApp.LOG_TAG, "Can't query data from given URI.");
finish();
@@ -131,7 +131,7 @@ public class PreferenceActivity extends Activity {
c.close();
- mPref = Im.ProviderSettings.queryProviderSettings(getContentResolver(), mProviderId);
+ mPref = Imps.ProviderSettings.queryProviderSettings(getContentResolver(), mProviderId);
}
}
}
@@ -203,16 +203,16 @@ public class PreferenceActivity extends Activity {
valuesList[4] = getValues(ImpsConfigNames.HOST, host);
valuesList[6] = getValues(ImpsConfigNames.MSISDN, msisdn);
- getContentResolver().bulkInsert(Im.ProviderSettings.CONTENT_URI, valuesList);
+ getContentResolver().bulkInsert(Imps.ProviderSettings.CONTENT_URI, valuesList);
finish();
}
private ContentValues getValues(String name, String value) {
ContentValues values = new ContentValues();
- values.put(Im.ProviderSettings.PROVIDER, mProviderId);
- values.put(Im.ProviderSettings.NAME, name);
- values.put(Im.ProviderSettings.VALUE, value);
+ values.put(Imps.ProviderSettings.PROVIDER, mProviderId);
+ values.put(Imps.ProviderSettings.NAME, name);
+ values.put(Imps.ProviderSettings.VALUE, value);
return values;
}
diff --git a/src/com/android/im/app/PresenceUtils.java b/src/com/android/im/app/PresenceUtils.java
index dcc806c..49861e6 100644
--- a/src/com/android/im/app/PresenceUtils.java
+++ b/src/com/android/im/app/PresenceUtils.java
@@ -16,11 +16,11 @@
*/
package com.android.im.app;
-import android.provider.Im;
import android.util.Log;
import com.android.im.engine.Presence;
import com.android.im.plugin.BrandingResourceIDs;
+import com.android.im.provider.Imps;
public final class PresenceUtils {
private PresenceUtils() {}
@@ -28,44 +28,44 @@ public final class PresenceUtils {
public static int convertStatus(int status) {
switch (status) {
case Presence.AVAILABLE:
- return Im.Presence.AVAILABLE;
+ return Imps.Presence.AVAILABLE;
case Presence.AWAY:
- return Im.Presence.AWAY;
+ return Imps.Presence.AWAY;
case Presence.DO_NOT_DISTURB:
- return Im.Presence.DO_NOT_DISTURB;
+ return Imps.Presence.DO_NOT_DISTURB;
case Presence.IDLE:
- return Im.Presence.IDLE;
+ return Imps.Presence.IDLE;
case Presence.OFFLINE:
- return Im.Presence.OFFLINE;
+ return Imps.Presence.OFFLINE;
default:
Log.w(ImApp.LOG_TAG, "[ContactView] Unknown presence status " + status);
- return Im.Presence.AVAILABLE;
+ return Imps.Presence.AVAILABLE;
}
}
public static int getStatusStringRes(int status) {
switch (status) {
- case Im.Presence.AVAILABLE:
+ case Imps.Presence.AVAILABLE:
return BrandingResourceIDs.STRING_PRESENCE_AVAILABLE;
- case Im.Presence.AWAY:
+ case Imps.Presence.AWAY:
return BrandingResourceIDs.STRING_PRESENCE_AWAY;
- case Im.Presence.DO_NOT_DISTURB:
+ case Imps.Presence.DO_NOT_DISTURB:
return BrandingResourceIDs.STRING_PRESENCE_BUSY;
- case Im.Presence.IDLE:
+ case Imps.Presence.IDLE:
return BrandingResourceIDs.STRING_PRESENCE_IDLE;
- case Im.Presence.INVISIBLE:
+ case Imps.Presence.INVISIBLE:
return BrandingResourceIDs.STRING_PRESENCE_INVISIBLE;
- case Im.Presence.OFFLINE:
+ case Imps.Presence.OFFLINE:
return BrandingResourceIDs.STRING_PRESENCE_OFFLINE;
default:
@@ -75,19 +75,19 @@ public final class PresenceUtils {
public static int getStatusIconId(int status) {
switch (status) {
- case Im.Presence.AVAILABLE:
+ case Imps.Presence.AVAILABLE:
return BrandingResourceIDs.DRAWABLE_PRESENCE_ONLINE;
- case Im.Presence.IDLE:
+ case Imps.Presence.IDLE:
return BrandingResourceIDs.DRAWABLE_PRESENCE_AWAY;
- case Im.Presence.AWAY:
+ case Imps.Presence.AWAY:
return BrandingResourceIDs.DRAWABLE_PRESENCE_AWAY;
- case Im.Presence.DO_NOT_DISTURB:
+ case Imps.Presence.DO_NOT_DISTURB:
return BrandingResourceIDs.DRAWABLE_PRESENCE_BUSY;
- case Im.Presence.INVISIBLE:
+ case Imps.Presence.INVISIBLE:
return BrandingResourceIDs.DRAWABLE_PRESENCE_INVISIBLE;
default:
diff --git a/src/com/android/im/app/ProviderListItem.java b/src/com/android/im/app/ProviderListItem.java
index 9ddc895..00679d4 100644
--- a/src/com/android/im/app/ProviderListItem.java
+++ b/src/com/android/im/app/ProviderListItem.java
@@ -19,6 +19,7 @@ package com.android.im.app;
import com.android.im.R;
import com.android.im.plugin.BrandingResourceIDs;
+import com.android.im.provider.Imps;
import android.graphics.drawable.Drawable;
import android.widget.LinearLayout;
@@ -30,7 +31,6 @@ import android.content.res.Resources;
import android.database.Cursor;
import android.content.res.ColorStateList;
import android.view.View;
-import android.provider.Im;
import android.util.Log;
public class ProviderListItem extends LinearLayout {
@@ -72,16 +72,16 @@ public class ProviderListItem extends LinearLayout {
mBubbleDrawable = getResources().getDrawable(R.drawable.bubble);
mDefaultBackground = getResources().getDrawable(R.drawable.default_background);
- mProviderIdColumn = c.getColumnIndexOrThrow(Im.Provider._ID);
- mProviderFullnameColumn = c.getColumnIndexOrThrow(Im.Provider.FULLNAME);
+ mProviderIdColumn = c.getColumnIndexOrThrow(Imps.Provider._ID);
+ mProviderFullnameColumn = c.getColumnIndexOrThrow(Imps.Provider.FULLNAME);
mActiveAccountIdColumn = c.getColumnIndexOrThrow(
- Im.Provider.ACTIVE_ACCOUNT_ID);
+ Imps.Provider.ACTIVE_ACCOUNT_ID);
mActiveAccountUserNameColumn = c.getColumnIndexOrThrow(
- Im.Provider.ACTIVE_ACCOUNT_USERNAME);
+ Imps.Provider.ACTIVE_ACCOUNT_USERNAME);
mAccountPresenceStatusColumn = c.getColumnIndexOrThrow(
- Im.Provider.ACCOUNT_PRESENCE_STATUS);
+ Imps.Provider.ACCOUNT_PRESENCE_STATUS);
mAccountConnectionStatusColumn = c.getColumnIndexOrThrow(
- Im.Provider.ACCOUNT_CONNECTION_STATUS);
+ Imps.Provider.ACCOUNT_CONNECTION_STATUS);
mProviderNameColors = mProviderName.getTextColors();
mLoginNameColors = mLoginName.getTextColors();
@@ -124,11 +124,11 @@ public class ProviderListItem extends LinearLayout {
chatView.setVisibility(View.GONE);
switch (connectionStatus) {
- case Im.ConnectionStatus.CONNECTING:
+ case Imps.ConnectionStatus.CONNECTING:
secondRowText = r.getString(R.string.signing_in_wait);
break;
- case Im.ConnectionStatus.ONLINE:
+ case Imps.ConnectionStatus.ONLINE:
int presenceIconId = getPresenceIconId(cursor);
statusIcon.setImageDrawable(
brandingRes.getDrawable(presenceIconId));
@@ -170,14 +170,14 @@ public class ProviderListItem extends LinearLayout {
// TODO: this is code used to get Google Talk's chat count. Not sure if this will work
// for IMPS chat count.
StringBuilder where = new StringBuilder();
- where.append(Im.Chats.CONTACT_ID);
+ where.append(Imps.Chats.CONTACT_ID);
where.append(" in (select _id from contacts where ");
- where.append(Im.Contacts.ACCOUNT);
+ where.append(Imps.Contacts.ACCOUNT);
where.append("=");
where.append(accountId);
where.append(")");
- Cursor cursor = cr.query(Im.Chats.CONTENT_URI, null, where.toString(), null, null);
+ Cursor cursor = cr.query(Imps.Chats.CONTENT_URI, null, where.toString(), null, null);
try {
return cursor.getCount();
@@ -192,17 +192,17 @@ public class ProviderListItem extends LinearLayout {
if (LOCAL_DEBUG) log("getPresenceIconId: presenceStatus=" + presenceStatus);
switch (presenceStatus) {
- case Im.Presence.AVAILABLE:
+ case Imps.Presence.AVAILABLE:
return BrandingResourceIDs.DRAWABLE_PRESENCE_ONLINE;
- case Im.Presence.IDLE:
- case Im.Presence.AWAY:
+ case Imps.Presence.IDLE:
+ case Imps.Presence.AWAY:
return BrandingResourceIDs.DRAWABLE_PRESENCE_AWAY;
- case Im.Presence.DO_NOT_DISTURB:
+ case Imps.Presence.DO_NOT_DISTURB:
return BrandingResourceIDs.DRAWABLE_PRESENCE_BUSY;
- case Im.Presence.INVISIBLE:
+ case Imps.Presence.INVISIBLE:
return BrandingResourceIDs.DRAWABLE_PRESENCE_INVISIBLE;
default:
diff --git a/src/com/android/im/app/SettingActivity.java b/src/com/android/im/app/SettingActivity.java
index 1a5f73b..5e16c36 100644
--- a/src/com/android/im/app/SettingActivity.java
+++ b/src/com/android/im/app/SettingActivity.java
@@ -22,10 +22,10 @@ import android.os.Bundle;
import android.preference.Preference;
import android.preference.PreferenceScreen;
import android.preference.CheckBoxPreference;
-import android.provider.Im;
import android.util.Log;
import com.android.im.R;
+import com.android.im.provider.Imps;
import com.android.im.service.ImServiceConstants;
public class SettingActivity extends android.preference.PreferenceActivity {
@@ -50,7 +50,7 @@ public class SettingActivity extends android.preference.PreferenceActivity {
}
private void setInitialValues() {
- Im.ProviderSettings.QueryMap settings = new Im.ProviderSettings.QueryMap(
+ Imps.ProviderSettings.QueryMap settings = new Imps.ProviderSettings.QueryMap(
getContentResolver(), mProviderId,
false /* keep updated */, null /* no handler */);
@@ -71,7 +71,7 @@ public class SettingActivity extends android.preference.PreferenceActivity {
@Override
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
if (preference instanceof CheckBoxPreference) {
- final Im.ProviderSettings.QueryMap settings = new Im.ProviderSettings.QueryMap(
+ final Imps.ProviderSettings.QueryMap settings = new Imps.ProviderSettings.QueryMap(
getContentResolver(), mProviderId,
false /* keep updated */, null /* no handler */);
String key = preference.getKey();
diff --git a/src/com/android/im/app/SigningInActivity.java b/src/com/android/im/app/SigningInActivity.java
index bcd7825..1e42645 100644
--- a/src/com/android/im/app/SigningInActivity.java
+++ b/src/com/android/im/app/SigningInActivity.java
@@ -25,6 +25,7 @@ import com.android.im.app.adapter.ConnectionListenerAdapter;
import com.android.im.engine.ImConnection;
import com.android.im.engine.ImErrorInfo;
import com.android.im.plugin.BrandingResourceIDs;
+import com.android.im.provider.Imps;
import com.android.im.service.ImServiceConstants;
import android.app.Activity;
@@ -40,7 +41,6 @@ import android.net.Uri;
import android.os.Bundle;
import android.os.RemoteException;
import android.os.Handler;
-import android.provider.Im;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
@@ -102,13 +102,13 @@ public class SigningInActivity extends Activity {
return;
}
- mProviderId = c.getLong(c.getColumnIndexOrThrow(Im.Account.PROVIDER));
- mAccountId = c.getLong(c.getColumnIndexOrThrow(Im.Account._ID));
- mUserName = c.getString(c.getColumnIndexOrThrow(Im.Account.USERNAME));
+ mProviderId = c.getLong(c.getColumnIndexOrThrow(Imps.Account.PROVIDER));
+ mAccountId = c.getLong(c.getColumnIndexOrThrow(Imps.Account._ID));
+ mUserName = c.getString(c.getColumnIndexOrThrow(Imps.Account.USERNAME));
String pwExtra = intent.getStringExtra(ImApp.EXTRA_INTENT_PASSWORD);
mPassword = pwExtra != null ? pwExtra
- : c.getString(c.getColumnIndexOrThrow(Im.Account.PASSWORD));
- final boolean isActive = c.getInt(c.getColumnIndexOrThrow(Im.Account.ACTIVE)) == 1;
+ : c.getString(c.getColumnIndexOrThrow(Imps.Account.PASSWORD));
+ final boolean isActive = c.getInt(c.getColumnIndexOrThrow(Imps.Account.ACTIVE)) == 1;
c.close();
mApp = ImApp.getApplication(this);
@@ -196,13 +196,13 @@ public class SigningInActivity extends Activity {
// this provider to inactive first and then update this
// account to active.
ContentValues values = new ContentValues(1);
- values.put(Im.Account.ACTIVE, 0);
+ values.put(Imps.Account.ACTIVE, 0);
ContentResolver cr = getContentResolver();
- cr.update(Im.Account.CONTENT_URI, values,
- Im.Account.PROVIDER + "=" + providerId, null);
+ cr.update(Imps.Account.CONTENT_URI, values,
+ Imps.Account.PROVIDER + "=" + providerId, null);
- values.put(Im.Account.ACTIVE, 1);
- cr.update(ContentUris.withAppendedId(Im.Account.CONTENT_URI, accountId),
+ values.put(Imps.Account.ACTIVE, 1);
+ cr.update(ContentUris.withAppendedId(Imps.Account.CONTENT_URI, accountId),
values, null, null);
}
@@ -307,7 +307,7 @@ public class SigningInActivity extends Activity {
if(session == null) {
session = manager.createChatSession(mToAddress);
}
- Uri data = ContentUris.withAppendedId(Im.Chats.CONTENT_URI, session.getId());
+ Uri data = ContentUris.withAppendedId(Imps.Chats.CONTENT_URI, session.getId());
intent = new Intent(Intent.ACTION_VIEW, data);
intent.putExtra("from", mToAddress);
intent.putExtra("providerId", mProviderId);
diff --git a/src/com/android/im/app/SignoutActivity.java b/src/com/android/im/app/SignoutActivity.java
index 2cb3bcb..0b70b69 100644
--- a/src/com/android/im/app/SignoutActivity.java
+++ b/src/com/android/im/app/SignoutActivity.java
@@ -17,7 +17,6 @@
package com.android.im.app;
import android.app.Activity;
-import android.provider.Im;
import android.os.Handler;
import android.os.Bundle;
import android.os.RemoteException;
@@ -28,13 +27,14 @@ import android.net.Uri;
import android.util.Log;
import android.database.Cursor;
import com.android.im.IImConnection;
+import com.android.im.provider.Imps;
public class SignoutActivity extends Activity {
private String[] ACCOUNT_SELECTION = new String[] {
- Im.Account._ID,
- Im.Account.PROVIDER,
+ Imps.Account._ID,
+ Imps.Account.PROVIDER,
};
private ImApp mApp;
@@ -69,8 +69,8 @@ public class SignoutActivity extends Activity {
return;
}
- providerId = c.getLong(c.getColumnIndexOrThrow(Im.Account.PROVIDER));
- accountId = c.getLong(c.getColumnIndexOrThrow(Im.Account._ID));
+ providerId = c.getLong(c.getColumnIndexOrThrow(Imps.Account.PROVIDER));
+ accountId = c.getLong(c.getColumnIndexOrThrow(Imps.Account._ID));
} finally {
c.close();
}
@@ -94,12 +94,12 @@ public class SignoutActivity extends Activity {
// status will never be updated. Clear the status in this case
// to make it recoverable from the crash.
ContentValues values = new ContentValues(2);
- values.put(Im.AccountStatus.PRESENCE_STATUS,
- Im.Presence.OFFLINE);
- values.put(Im.AccountStatus.CONNECTION_STATUS,
- Im.ConnectionStatus.OFFLINE);
- String where = Im.AccountStatus.ACCOUNT + "=?";
- getContentResolver().update(Im.AccountStatus.CONTENT_URI,
+ values.put(Imps.AccountStatus.PRESENCE_STATUS,
+ Imps.Presence.OFFLINE);
+ values.put(Imps.AccountStatus.CONNECTION_STATUS,
+ Imps.ConnectionStatus.OFFLINE);
+ String where = Imps.AccountStatus.ACCOUNT + "=?";
+ getContentResolver().update(Imps.AccountStatus.CONTENT_URI,
values, where,
new String[] { Long.toString(accountId) });
}
diff --git a/src/com/android/im/app/UserPresenceView.java b/src/com/android/im/app/UserPresenceView.java
index 1250600..5e0e7ee 100644
--- a/src/com/android/im/app/UserPresenceView.java
+++ b/src/com/android/im/app/UserPresenceView.java
@@ -21,6 +21,7 @@ import com.android.im.R;
import com.android.im.engine.ImErrorInfo;
import com.android.im.engine.Presence;
import com.android.im.plugin.ImpsConfigNames;
+import com.android.im.provider.Imps;
import com.google.android.collect.Lists;
import android.app.Activity;
@@ -29,7 +30,6 @@ import android.content.Context;
import android.content.DialogInterface;
import android.graphics.drawable.Drawable;
import android.os.RemoteException;
-import android.provider.Im;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.KeyEvent;
@@ -100,8 +100,8 @@ public class UserPresenceView extends LinearLayout {
int[] supportedStatus = mConn.getSupportedPresenceStatus();
for (int i = 0; i < supportedStatus.length; i++) {
int s = PresenceUtils.convertStatus(supportedStatus[i]);
- if (s == Im.Presence.OFFLINE) {
- s = Im.Presence.INVISIBLE;
+ if (s == Imps.Presence.OFFLINE) {
+ s = Imps.Presence.INVISIBLE;
}
ImApp app = ImApp.getApplication((Activity)mContext);
BrandingResources brandingRes = app.getBrandingResource(mProviderId);
@@ -162,14 +162,14 @@ public class UserPresenceView extends LinearLayout {
// the AIM and MSN server don't support it now.
ProviderDef provider = app.getProvider(mProviderId);
String providerName = provider == null ? null : provider.mName;
- if (Im.ProviderNames.AIM.equals(providerName)
- || Im.ProviderNames.MSN.equals(providerName)) {
+ if (Imps.ProviderNames.AIM.equals(providerName)
+ || Imps.ProviderNames.MSN.equals(providerName)) {
mStatusBar.setFocusable(false);
}
}
private TextView initStatusBar(long providerId) {
- String value = Im.ProviderSettings.getStringValue(
+ String value = Imps.ProviderSettings.getStringValue(
mContext.getContentResolver(), providerId,
ImpsConfigNames.SUPPORT_USER_DEFINED_PRESENCE);
diff --git a/src/com/android/im/provider/Imps.java b/src/com/android/im/provider/Imps.java
new file mode 100644
index 0000000..091e993
--- /dev/null
+++ b/src/com/android/im/provider/Imps.java
@@ -0,0 +1,2333 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.im.provider;
+
+import android.content.ContentQueryMap;
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Handler;
+import android.provider.BaseColumns;
+
+import java.util.HashMap;
+
+/**
+ * The IM provider stores all information about roster contacts, chat messages, presence, etc.
+ *
+ * @hide
+ */
+public class Imps {
+ /**
+ * no public constructor since this is a utility class
+ */
+ private Imps() {}
+
+ /**
+ * The Columns for IM providers (i.e. AIM, Y!, GTalk)
+ */
+ public interface ProviderColumns {
+ /**
+ * The name of the IM provider
+ * <P>Type: TEXT</P>
+ */
+ String NAME = "name";
+
+ /**
+ * The full name of the provider
+ * <P>Type: TEXT</P>
+ */
+ String FULLNAME = "fullname";
+
+ /**
+ * The category for the provider, used to form intent.
+ * <P>Type: TEXT</P>
+ */
+ String CATEGORY = "category";
+
+ /**
+ * The url users should visit to create a new account for this provider
+ * <P>Type: TEXT</P>
+ */
+ String SIGNUP_URL = "signup_url";
+ }
+
+ /**
+ * Known names corresponding to the {@link ProviderColumns#NAME} column
+ */
+ public interface ProviderNames {
+ //
+ //NOTE: update Contacts.java with new providers when they're added.
+ //
+ String YAHOO = "Yahoo";
+ String GTALK = "GTalk";
+ String MSN = "MSN";
+ String ICQ = "ICQ";
+ String AIM = "AIM";
+ String XMPP = "XMPP";
+ String JABBER = "JABBER";
+ String SKYPE = "SKYPE";
+ String QQ = "QQ";
+ }
+
+ /**
+ * This table contains the IM providers
+ */
+ public static final class Provider implements BaseColumns, ProviderColumns {
+ private Provider() {}
+
+ public static final long getProviderIdForName(ContentResolver cr, String providerName) {
+ String[] selectionArgs = new String[1];
+ selectionArgs[0] = providerName;
+
+ Cursor cursor = cr.query(CONTENT_URI,
+ PROVIDER_PROJECTION,
+ NAME+"=?",
+ selectionArgs, null);
+
+ long retVal = 0;
+ try {
+ if (cursor.moveToFirst()) {
+ retVal = cursor.getLong(cursor.getColumnIndexOrThrow(_ID));
+ }
+ } finally {
+ cursor.close();
+ }
+
+ return retVal;
+ }
+
+ public static final String getProviderNameForId(ContentResolver cr, long providerId) {
+ Cursor cursor = cr.query(CONTENT_URI,
+ PROVIDER_PROJECTION,
+ _ID + "=" + providerId,
+ null, null);
+
+ String retVal = null;
+ try {
+ if (cursor.moveToFirst()) {
+ retVal = cursor.getString(cursor.getColumnIndexOrThrow(NAME));
+ }
+ } finally {
+ cursor.close();
+ }
+
+ return retVal;
+ }
+
+ private static final String[] PROVIDER_PROJECTION = new String[] {
+ _ID,
+ NAME
+ };
+
+ public static final String ACTIVE_ACCOUNT_ID = "account_id";
+ public static final String ACTIVE_ACCOUNT_USERNAME = "account_username";
+ public static final String ACTIVE_ACCOUNT_PW = "account_pw";
+ public static final String ACTIVE_ACCOUNT_LOCKED = "account_locked";
+ public static final String ACTIVE_ACCOUNT_KEEP_SIGNED_IN = "account_keepSignedIn";
+ public static final String ACCOUNT_PRESENCE_STATUS = "account_presenceStatus";
+ public static final String ACCOUNT_CONNECTION_STATUS = "account_connStatus";
+
+ /**
+ * The content:// style URL for this table
+ */
+ public static final Uri CONTENT_URI =
+ Uri.parse("content://imps/providers");
+
+ public static final Uri CONTENT_URI_WITH_ACCOUNT =
+ Uri.parse("content://imps/providers/account");
+
+ /**
+ * The MIME type of {@link #CONTENT_URI} providing a directory of
+ * people.
+ */
+ public static final String CONTENT_TYPE =
+ "vnd.android.cursor.dir/imps-providers";
+
+ public static final String CONTENT_ITEM_TYPE =
+ "vnd.android.cursor.item/imps-providers";
+
+ /**
+ * The default sort order for this table
+ */
+ public static final String DEFAULT_SORT_ORDER = "name ASC";
+ }
+
+ /**
+ * The columns for IM accounts. There can be more than one account for each IM provider.
+ */
+ public interface AccountColumns {
+ /**
+ * The name of the account
+ * <P>Type: TEXT</P>
+ */
+ String NAME = "name";
+
+ /**
+ * The IM provider for this account
+ * <P>Type: INTEGER</P>
+ */
+ String PROVIDER = "provider";
+
+ /**
+ * The username for this account
+ * <P>Type: TEXT</P>
+ */
+ String USERNAME = "username";
+
+ /**
+ * The password for this account
+ * <P>Type: TEXT</P>
+ */
+ String PASSWORD = "pw";
+
+ /**
+ * A boolean value indicates if the account is active.
+ * <P>Type: INTEGER</P>
+ */
+ String ACTIVE = "active";
+
+ /**
+ * A boolean value indicates if the account is locked (not editable)
+ * <P>Type: INTEGER</P>
+ */
+ String LOCKED = "locked";
+
+ /**
+ * A boolean value to indicate whether this account is kept signed in.
+ * <P>Type: INTEGER</P>
+ */
+ String KEEP_SIGNED_IN = "keep_signed_in";
+
+ /**
+ * A boolean value indiciating the last login state for this account
+ * <P>Type: INTEGER</P>
+ */
+ String LAST_LOGIN_STATE = "last_login_state";
+ }
+
+ /**
+ * This table contains the IM accounts.
+ */
+ public static final class Account implements BaseColumns, AccountColumns {
+ private Account() {}
+
+ public static final long getProviderIdForAccount(ContentResolver cr, long accountId) {
+ Cursor cursor = cr.query(CONTENT_URI,
+ PROVIDER_PROJECTION,
+ _ID + "=" + accountId,
+ null /* selection args */,
+ null /* sort order */);
+
+ long providerId = 0;
+
+ try {
+ if (cursor.moveToFirst()) {
+ providerId = cursor.getLong(PROVIDER_COLUMN);
+ }
+ } finally {
+ cursor.close();
+ }
+
+ return providerId;
+ }
+
+ private static final String[] PROVIDER_PROJECTION = new String[] { PROVIDER };
+ private static final int PROVIDER_COLUMN = 0;
+
+ /**
+ * The content:// style URL for this table
+ */
+ public static final Uri CONTENT_URI =
+ Uri.parse("content://imps/accounts");
+
+ /**
+ * The MIME type of {@link #CONTENT_URI} providing a directory of
+ * account.
+ */
+ public static final String CONTENT_TYPE =
+ "vnd.android.cursor.dir/imps-accounts";
+
+ /**
+ * The MIME type of a {@link #CONTENT_URI} subdirectory of a single
+ * account.
+ */
+ public static final String CONTENT_ITEM_TYPE =
+ "vnd.android.cursor.item/imps-accounts";
+
+ /**
+ * The default sort order for this table
+ */
+ public static final String DEFAULT_SORT_ORDER = "name ASC";
+
+ }
+
+ /**
+ * Connection status
+ */
+ public interface ConnectionStatus {
+ /**
+ * The connection is offline, not logged in.
+ */
+ int OFFLINE = 0;
+
+ /**
+ * The connection is attempting to connect.
+ */
+ int CONNECTING = 1;
+
+ /**
+ * The connection is suspended due to network not available.
+ */
+ int SUSPENDED = 2;
+
+ /**
+ * The connection is logged in and online.
+ */
+ int ONLINE = 3;
+ }
+
+ public interface AccountStatusColumns {
+ /**
+ * account id
+ * <P>Type: INTEGER</P>
+ */
+ String ACCOUNT = "account";
+
+ /**
+ * User's presence status, see definitions in {#link CommonPresenceColumn}
+ * <P>Type: INTEGER</P>
+ */
+ String PRESENCE_STATUS = "presenceStatus";
+
+ /**
+ * The connection status of this account, see {#link ConnectionStatus}
+ * <P>Type: INTEGER</P>
+ */
+ String CONNECTION_STATUS = "connStatus";
+ }
+
+ public static final class AccountStatus implements BaseColumns, AccountStatusColumns {
+ /**
+ * The content:// style URL for this table
+ */
+ public static final Uri CONTENT_URI =
+ Uri.parse("content://imps/accountStatus");
+
+ /**
+ * The MIME type of {@link #CONTENT_URI} providing a directory of account status.
+ */
+ public static final String CONTENT_TYPE =
+ "vnd.android.cursor.dir/imps-account-status";
+
+ /**
+ * The MIME type of a {@link #CONTENT_URI} subdirectory of a single account status.
+ */
+ public static final String CONTENT_ITEM_TYPE =
+ "vnd.android.cursor.item/imps-account-status";
+
+ /**
+ * The default sort order for this table
+ */
+ public static final String DEFAULT_SORT_ORDER = "name ASC";
+ }
+
+ /**
+ * Columns from the Contacts table.
+ */
+ public interface ContactsColumns {
+ /**
+ * The username
+ * <P>Type: TEXT</P>
+ */
+ String USERNAME = "username";
+
+ /**
+ * The nickname or display name
+ * <P>Type: TEXT</P>
+ */
+ String NICKNAME = "nickname";
+
+ /**
+ * The IM provider for this contact
+ * <P>Type: INTEGER</P>
+ */
+ String PROVIDER = "provider";
+
+ /**
+ * The account (within a IM provider) for this contact
+ * <P>Type: INTEGER</P>
+ */
+ String ACCOUNT = "account";
+
+ /**
+ * The contactList this contact belongs to
+ * <P>Type: INTEGER</P>
+ */
+ String CONTACTLIST = "contactList";
+
+ /**
+ * Contact type
+ * <P>Type: INTEGER</P>
+ */
+ String TYPE = "type";
+
+ /**
+ * normal IM contact
+ */
+ int TYPE_NORMAL = 0;
+ /**
+ * temporary contact, someone not in the list of contacts that we
+ * subscribe presence for. Usually created because of the user is
+ * having a chat session with this contact.
+ */
+ int TYPE_TEMPORARY = 1;
+ /**
+ * temporary contact created for group chat.
+ */
+ int TYPE_GROUP = 2;
+ /**
+ * blocked contact.
+ */
+ int TYPE_BLOCKED = 3;
+ /**
+ * the contact is hidden. The client should always display this contact to the user.
+ */
+ int TYPE_HIDDEN = 4;
+ /**
+ * the contact is pinned. The client should always display this contact to the user.
+ */
+ int TYPE_PINNED = 5;
+
+ /**
+ * Contact subscription status
+ * <P>Type: INTEGER</P>
+ */
+ String SUBSCRIPTION_STATUS = "subscriptionStatus";
+
+ /**
+ * no pending subscription
+ */
+ int SUBSCRIPTION_STATUS_NONE = 0;
+ /**
+ * requested to subscribe
+ */
+ int SUBSCRIPTION_STATUS_SUBSCRIBE_PENDING = 1;
+ /**
+ * requested to unsubscribe
+ */
+ int SUBSCRIPTION_STATUS_UNSUBSCRIBE_PENDING = 2;
+
+ /**
+ * Contact subscription type
+ * <P>Type: INTEGER </P>
+ */
+ String SUBSCRIPTION_TYPE = "subscriptionType";
+
+ /**
+ * The user and contact have no interest in each other's presence.
+ */
+ int SUBSCRIPTION_TYPE_NONE = 0;
+ /**
+ * The user wishes to stop receiving presence updates from the contact.
+ */
+ int SUBSCRIPTION_TYPE_REMOVE = 1;
+ /**
+ * The user is interested in receiving presence updates from the contact.
+ */
+ int SUBSCRIPTION_TYPE_TO = 2;
+ /**
+ * The contact is interested in receiving presence updates from the user.
+ */
+ int SUBSCRIPTION_TYPE_FROM = 3;
+ /**
+ * The user and contact have a mutual interest in each other's presence.
+ */
+ int SUBSCRIPTION_TYPE_BOTH = 4;
+ /**
+ * This is a special type reserved for pending subscription requests
+ */
+ int SUBSCRIPTION_TYPE_INVITATIONS = 5;
+
+ /**
+ * Quick Contact: derived from Google Contact Extension's "message_count" attribute.
+ * <P>Type: INTEGER</P>
+ */
+ String QUICK_CONTACT = "qc";
+
+ /**
+ * Google Contact Extension attribute
+ *
+ * Rejected: a boolean value indicating whether a subscription request from
+ * this client was ever rejected by the user. "true" indicates that it has.
+ * This is provided so that a client can block repeated subscription requests.
+ * <P>Type: INTEGER</P>
+ */
+ String REJECTED = "rejected";
+
+ /**
+ * Off The Record status: 0 for disabled, 1 for enabled
+ * <P>Type: INTEGER </P>
+ */
+ String OTR = "otr";
+ }
+
+ /**
+ * This defines the different type of values of {@link ContactsColumns#OTR}
+ */
+ public interface OffTheRecordType {
+ /*
+ * Off the record not turned on
+ */
+ int DISABLED = 0;
+ /**
+ * Off the record turned on, but we don't know who turned it on
+ */
+ int ENABLED = 1;
+ /**
+ * Off the record turned on by the user
+ */
+ int ENABLED_BY_USER = 2;
+ /**
+ * Off the record turned on by the buddy
+ */
+ int ENABLED_BY_BUDDY = 3;
+ };
+
+ /**
+ * This table contains contacts.
+ */
+ public static final class Contacts implements BaseColumns,
+ ContactsColumns, PresenceColumns, ChatsColumns {
+ /**
+ * no public constructor since this is a utility class
+ */
+ private Contacts() {}
+
+ /**
+ * The content:// style URL for this table
+ */
+ public static final Uri CONTENT_URI =
+ Uri.parse("content://imps/contacts");
+
+ /**
+ * The content:// style URL for contacts joined with presence
+ */
+ public static final Uri CONTENT_URI_WITH_PRESENCE =
+ Uri.parse("content://imps/contactsWithPresence");
+
+ /**
+ * The content:// style URL for barebone contacts, not joined with any other table
+ */
+ public static final Uri CONTENT_URI_CONTACTS_BAREBONE =
+ Uri.parse("content://imps/contactsBarebone");
+
+ /**
+ * The content:// style URL for contacts who have an open chat session
+ */
+ public static final Uri CONTENT_URI_CHAT_CONTACTS =
+ Uri.parse("content://imps/contacts/chatting");
+
+ /**
+ * The content:// style URL for contacts who have been blocked
+ */
+ public static final Uri CONTENT_URI_BLOCKED_CONTACTS =
+ Uri.parse("content://imps/contacts/blocked");
+
+ /**
+ * The content:// style URL for contacts by provider and account
+ */
+ public static final Uri CONTENT_URI_CONTACTS_BY =
+ Uri.parse("content://imps/contacts");
+
+ /**
+ * The content:// style URL for contacts by provider and account,
+ * and who have an open chat session
+ */
+ public static final Uri CONTENT_URI_CHAT_CONTACTS_BY =
+ Uri.parse("content://imps/contacts/chatting");
+
+ /**
+ * The content:// style URL for contacts by provider and account,
+ * and who are online
+ */
+ public static final Uri CONTENT_URI_ONLINE_CONTACTS_BY =
+ Uri.parse("content://imps/contacts/online");
+
+ /**
+ * The content:// style URL for contacts by provider and account,
+ * and who are offline
+ */
+ public static final Uri CONTENT_URI_OFFLINE_CONTACTS_BY =
+ Uri.parse("content://imps/contacts/offline");
+
+ /**
+ * The content:// style URL for operations on bulk contacts
+ */
+ public static final Uri BULK_CONTENT_URI =
+ Uri.parse("content://imps/bulk_contacts");
+
+ /**
+ * The content:// style URL for the count of online contacts in each
+ * contact list by provider and account.
+ */
+ public static final Uri CONTENT_URI_ONLINE_COUNT =
+ Uri.parse("content://imps/contacts/onlineCount");
+
+ /**
+ * The MIME type of {@link #CONTENT_URI} providing a directory of
+ * people.
+ */
+ public static final String CONTENT_TYPE = "vnd.android.cursor.dir/imps-contacts";
+
+ /**
+ * The MIME type of a {@link #CONTENT_URI} subdirectory of a single
+ * person.
+ */
+ public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/imps-contacts";
+
+ /**
+ * The default sort order for this table
+ */
+ public static final String DEFAULT_SORT_ORDER =
+ "subscriptionType DESC, last_message_date DESC," +
+ " mode DESC, nickname COLLATE UNICODE ASC";
+
+ public static final String CHATS_CONTACT = "chats_contact";
+
+ public static final String AVATAR_HASH = "avatars_hash";
+
+ public static final String AVATAR_DATA = "avatars_data";
+ }
+
+ /**
+ * Columns from the ContactList table.
+ */
+ public interface ContactListColumns {
+ String NAME = "name";
+ String PROVIDER = "provider";
+ String ACCOUNT = "account";
+ }
+
+ /**
+ * This table contains the contact lists.
+ */
+ public static final class ContactList implements BaseColumns,
+ ContactListColumns {
+ private ContactList() {}
+
+ /**
+ * The content:// style URL for this table
+ */
+ public static final Uri CONTENT_URI =
+ Uri.parse("content://imps/contactLists");
+
+ /**
+ * The MIME type of {@link #CONTENT_URI} providing a directory of
+ * people.
+ */
+ public static final String CONTENT_TYPE =
+ "vnd.android.cursor.dir/imps-contactLists";
+
+ /**
+ * The MIME type of a {@link #CONTENT_URI} subdirectory of a single
+ * person.
+ */
+ public static final String CONTENT_ITEM_TYPE =
+ "vnd.android.cursor.item/imps-contactLists";
+
+ /**
+ * The default sort order for this table
+ */
+ public static final String DEFAULT_SORT_ORDER = "name COLLATE UNICODE ASC";
+
+ public static final String PROVIDER_NAME = "provider_name";
+
+ public static final String ACCOUNT_NAME = "account_name";
+ }
+
+ /**
+ * Columns from the BlockedList table.
+ */
+ public interface BlockedListColumns {
+ /**
+ * The username of the blocked contact.
+ * <P>Type: TEXT</P>
+ */
+ String USERNAME = "username";
+
+ /**
+ * The nickname of the blocked contact.
+ * <P>Type: TEXT</P>
+ */
+ String NICKNAME = "nickname";
+
+ /**
+ * The provider id of the blocked contact.
+ * <P>Type: INT</P>
+ */
+ String PROVIDER = "provider";
+
+ /**
+ * The account id of the blocked contact.
+ * <P>Type: INT</P>
+ */
+ String ACCOUNT = "account";
+ }
+
+ /**
+ * This table contains blocked lists
+ */
+ public static final class BlockedList implements BaseColumns, BlockedListColumns {
+ private BlockedList() {}
+
+ /**
+ * The content:// style URL for this table
+ */
+ public static final Uri CONTENT_URI =
+ Uri.parse("content://imps/blockedList");
+
+ /**
+ * The MIME type of {@link #CONTENT_URI} providing a directory of
+ * people.
+ */
+ public static final String CONTENT_TYPE =
+ "vnd.android.cursor.dir/imps-blockedList";
+
+ /**
+ * The MIME type of a {@link #CONTENT_URI} subdirectory of a single
+ * person.
+ */
+ public static final String CONTENT_ITEM_TYPE =
+ "vnd.android.cursor.item/imps-blockedList";
+
+ /**
+ * The default sort order for this table
+ */
+ public static final String DEFAULT_SORT_ORDER = "nickname ASC";
+
+ public static final String PROVIDER_NAME = "provider_name";
+
+ public static final String ACCOUNT_NAME = "account_name";
+
+ public static final String AVATAR_DATA = "avatars_data";
+ }
+
+ /**
+ * Columns from the contactsEtag table
+ */
+ public interface ContactsEtagColumns {
+ /**
+ * The roster etag, computed by the server, stored on the client. There is one etag
+ * per account roster.
+ * <P>Type: TEXT</P>
+ */
+ String ETAG = "etag";
+
+ /**
+ * The OTR etag, computed by the server, stored on the client. There is one OTR etag
+ * per account roster.
+ * <P>Type: TEXT</P>
+ */
+ String OTR_ETAG = "otr_etag";
+
+ /**
+ * The account id for the etag.
+ * <P> Type: INTEGER </P>
+ */
+ String ACCOUNT = "account";
+ }
+
+ public static final class ContactsEtag implements BaseColumns, ContactsEtagColumns {
+ private ContactsEtag() {}
+
+ public static final Cursor query(ContentResolver cr,
+ String[] projection) {
+ return cr.query(CONTENT_URI, projection, null, null, null);
+ }
+
+ public static final Cursor query(ContentResolver cr,
+ String[] projection, String where, String orderBy) {
+ return cr.query(CONTENT_URI, projection, where,
+ null, orderBy == null ? null : orderBy);
+ }
+
+ public static final String getRosterEtag(ContentResolver resolver, long accountId) {
+ String retVal = null;
+
+ Cursor c = resolver.query(CONTENT_URI,
+ CONTACT_ETAG_PROJECTION,
+ ACCOUNT + "=" + accountId,
+ null /* selection args */,
+ null /* sort order */);
+
+ try {
+ if (c.moveToFirst()) {
+ retVal = c.getString(COLUMN_ETAG);
+ }
+ } finally {
+ c.close();
+ }
+
+ return retVal;
+ }
+
+ public static final String getOtrEtag(ContentResolver resolver, long accountId) {
+ String retVal = null;
+
+ Cursor c = resolver.query(CONTENT_URI,
+ CONTACT_OTR_ETAG_PROJECTION,
+ ACCOUNT + "=" + accountId,
+ null /* selection args */,
+ null /* sort order */);
+
+ try {
+ if (c.moveToFirst()) {
+ retVal = c.getString(COLUMN_OTR_ETAG);
+ }
+ } finally {
+ c.close();
+ }
+
+ return retVal;
+ }
+
+ private static final String[] CONTACT_ETAG_PROJECTION = new String[] {
+ Imps.ContactsEtag.ETAG // 0
+ };
+
+ private static int COLUMN_ETAG = 0;
+
+ private static final String[] CONTACT_OTR_ETAG_PROJECTION = new String[] {
+ Imps.ContactsEtag.OTR_ETAG // 0
+ };
+
+ private static int COLUMN_OTR_ETAG = 0;
+
+ /**
+ * The content:// style URL for this table
+ */
+ public static final Uri CONTENT_URI =
+ Uri.parse("content://imps/contactsEtag");
+
+ /**
+ * The MIME type of {@link #CONTENT_URI} providing a directory of
+ * people.
+ */
+ public static final String CONTENT_TYPE =
+ "vnd.android.cursor.dir/imps-contactsEtag";
+
+ /**
+ * The MIME type of a {@link #CONTENT_URI} subdirectory of a single
+ * person.
+ */
+ public static final String CONTENT_ITEM_TYPE =
+ "vnd.android.cursor.item/imps-contactsEtag";
+ }
+
+ /**
+ * Message type definition
+ */
+ public interface MessageType {
+ /* sent message */
+ int OUTGOING = 0;
+ /* received message */
+ int INCOMING = 1;
+ /* presence became available */
+ int PRESENCE_AVAILABLE = 2;
+ /* presence became away */
+ int PRESENCE_AWAY = 3;
+ /* presence became DND (busy) */
+ int PRESENCE_DND = 4;
+ /* presence became unavailable */
+ int PRESENCE_UNAVAILABLE = 5;
+ /* the message is converted to a group chat */
+ int CONVERT_TO_GROUPCHAT = 6;
+ /* generic status */
+ int STATUS = 7;
+ /* the message cannot be sent now, but will be sent later */
+ int POSTPONED = 8;
+ /* off The Record status is turned off */
+ int OTR_IS_TURNED_OFF = 9;
+ /* off the record status is turned on */
+ int OTR_IS_TURNED_ON = 10;
+ /* off the record status turned on by user */
+ int OTR_TURNED_ON_BY_USER = 11;
+ /* off the record status turned on by buddy */
+ int OTR_TURNED_ON_BY_BUDDY = 12;
+ }
+
+ /**
+ * The common columns for messages table
+ */
+ public interface MessageColumns {
+ /**
+ * The thread_id column stores the contact id of the contact the message belongs to.
+ * For groupchat messages, the thread_id stores the group id, which is the contact id
+ * of the temporary group contact created for the groupchat. So there should be no
+ * collision between groupchat message thread id and regular message thread id.
+ */
+ String THREAD_ID = "thread_id";
+
+ /**
+ * The nickname. This is used for groupchat messages to indicate the participant's
+ * nickname. For non groupchat messages, this field should be left empty.
+ */
+ String NICKNAME = "nickname";
+
+ /**
+ * The body
+ * <P>Type: TEXT</P>
+ */
+ String BODY = "body";
+
+ /**
+ * The date this message is sent or received
+ * <P>Type: INTEGER</P>
+ */
+ String DATE = "date";
+
+ /**
+ * Message Type, see {@link MessageType}
+ * <P>Type: INTEGER</P>
+ */
+ String TYPE = "type";
+
+ /**
+ * Error Code: 0 means no error.
+ * <P>Type: INTEGER </P>
+ */
+ String ERROR_CODE = "err_code";
+
+ /**
+ * Error Message
+ * <P>Type: TEXT</P>
+ */
+ String ERROR_MESSAGE = "err_msg";
+
+ /**
+ * Packet ID, auto assigned by the GTalkService for outgoing messages or the
+ * GTalk server for incoming messages. The packet id field is optional for messages,
+ * so it could be null.
+ * <P>Type: STRING</P>
+ */
+ String PACKET_ID = "packet_id";
+
+ /**
+ * Is groupchat message or not
+ * <P>Type: INTEGER</P>
+ */
+ String IS_GROUP_CHAT = "is_muc";
+
+ /**
+ * A hint that the UI should show the sent time of this message
+ * <P>Type: INTEGER</P>
+ */
+ String DISPLAY_SENT_TIME = "show_ts";
+ }
+
+ /**
+ * This table contains messages.
+ */
+ public static final class Messages implements BaseColumns, MessageColumns {
+ /**
+ * no public constructor since this is a utility class
+ */
+ private Messages() {}
+
+ /**
+ * Gets the Uri to query messages by thread id.
+ *
+ * @param threadId the thread id of the message.
+ * @return the Uri
+ */
+ public static final Uri getContentUriByThreadId(long threadId) {
+ Uri.Builder builder = CONTENT_URI_MESSAGES_BY_THREAD_ID.buildUpon();
+ ContentUris.appendId(builder, threadId);
+ return builder.build();
+ }
+
+ /**
+ * @deprecated
+ *
+ * Gets the Uri to query messages by account and contact.
+ *
+ * @param accountId the account id of the contact.
+ * @param username the user name of the contact.
+ * @return the Uri
+ */
+ public static final Uri getContentUriByContact(long accountId, String username) {
+ Uri.Builder builder = CONTENT_URI_MESSAGES_BY_ACCOUNT_AND_CONTACT.buildUpon();
+ ContentUris.appendId(builder, accountId);
+ builder.appendPath(username);
+ return builder.build();
+ }
+
+ /**
+ * Gets the Uri to query messages by provider.
+ *
+ * @param providerId the service provider id.
+ * @return the Uri
+ */
+ public static final Uri getContentUriByProvider(long providerId) {
+ Uri.Builder builder = CONTENT_URI_MESSAGES_BY_PROVIDER.buildUpon();
+ ContentUris.appendId(builder, providerId);
+ return builder.build();
+ }
+
+ /**
+ * Gets the Uri to query off the record messages by account.
+ *
+ * @param accountId the account id.
+ * @return the Uri
+ */
+ public static final Uri getContentUriByAccount(long accountId) {
+ Uri.Builder builder = CONTENT_URI_BY_ACCOUNT.buildUpon();
+ ContentUris.appendId(builder, accountId);
+ return builder.build();
+ }
+
+ /**
+ * Gets the Uri to query off the record messages by thread id.
+ *
+ * @param threadId the thread id of the message.
+ * @return the Uri
+ */
+ public static final Uri getOtrMessagesContentUriByThreadId(long threadId) {
+ Uri.Builder builder = OTR_MESSAGES_CONTENT_URI_BY_THREAD_ID.buildUpon();
+ ContentUris.appendId(builder, threadId);
+ return builder.build();
+ }
+
+ /**
+ * @deprecated
+ *
+ * Gets the Uri to query off the record messages by account and contact.
+ *
+ * @param accountId the account id of the contact.
+ * @param username the user name of the contact.
+ * @return the Uri
+ */
+ public static final Uri getOtrMessagesContentUriByContact(long accountId, String username) {
+ Uri.Builder builder = OTR_MESSAGES_CONTENT_URI_BY_ACCOUNT_AND_CONTACT.buildUpon();
+ ContentUris.appendId(builder, accountId);
+ builder.appendPath(username);
+ return builder.build();
+ }
+
+ /**
+ * Gets the Uri to query off the record messages by provider.
+ *
+ * @param providerId the service provider id.
+ * @return the Uri
+ */
+ public static final Uri getOtrMessagesContentUriByProvider(long providerId) {
+ Uri.Builder builder = OTR_MESSAGES_CONTENT_URI_BY_PROVIDER.buildUpon();
+ ContentUris.appendId(builder, providerId);
+ return builder.build();
+ }
+
+ /**
+ * Gets the Uri to query off the record messages by account.
+ *
+ * @param accountId the account id.
+ * @return the Uri
+ */
+ public static final Uri getOtrMessagesContentUriByAccount(long accountId) {
+ Uri.Builder builder = OTR_MESSAGES_CONTENT_URI_BY_ACCOUNT.buildUpon();
+ ContentUris.appendId(builder, accountId);
+ return builder.build();
+ }
+
+ /**
+ * The content:// style URL for this table
+ */
+ public static final Uri CONTENT_URI =
+ Uri.parse("content://imps/messages");
+
+ /**
+ * The content:// style URL for messages by thread id
+ */
+ public static final Uri CONTENT_URI_MESSAGES_BY_THREAD_ID =
+ Uri.parse("content://imps/messagesByThreadId");
+
+ /**
+ * The content:// style URL for messages by account and contact
+ */
+ public static final Uri CONTENT_URI_MESSAGES_BY_ACCOUNT_AND_CONTACT =
+ Uri.parse("content://imps/messagesByAcctAndContact");
+
+ /**
+ * The content:// style URL for messages by provider
+ */
+ public static final Uri CONTENT_URI_MESSAGES_BY_PROVIDER =
+ Uri.parse("content://imps/messagesByProvider");
+
+ /**
+ * The content:// style URL for messages by account
+ */
+ public static final Uri CONTENT_URI_BY_ACCOUNT =
+ Uri.parse("content://imps/messagesByAccount");
+
+ /**
+ * The content:// style url for off the record messages
+ */
+ public static final Uri OTR_MESSAGES_CONTENT_URI =
+ Uri.parse("content://imps/otrMessages");
+
+ /**
+ * The content:// style url for off the record messages by thread id
+ */
+ public static final Uri OTR_MESSAGES_CONTENT_URI_BY_THREAD_ID =
+ Uri.parse("content://imps/otrMessagesByThreadId");
+
+ /**
+ * The content:// style url for off the record messages by account and contact
+ */
+ public static final Uri OTR_MESSAGES_CONTENT_URI_BY_ACCOUNT_AND_CONTACT =
+ Uri.parse("content://imps/otrMessagesByAcctAndContact");
+
+ /**
+ * The content:// style URL for off the record messages by provider
+ */
+ public static final Uri OTR_MESSAGES_CONTENT_URI_BY_PROVIDER =
+ Uri.parse("content://imps/otrMessagesByProvider");
+
+ /**
+ * The content:// style URL for off the record messages by account
+ */
+ public static final Uri OTR_MESSAGES_CONTENT_URI_BY_ACCOUNT =
+ Uri.parse("content://imps/otrMessagesByAccount");
+
+ /**
+ * The MIME type of {@link #CONTENT_URI} providing a directory of
+ * people.
+ */
+ public static final String CONTENT_TYPE = "vnd.android.cursor.dir/imps-messages";
+
+ /**
+ * The MIME type of a {@link #CONTENT_URI} subdirectory of a single
+ * person.
+ */
+ public static final String CONTENT_ITEM_TYPE =
+ "vnd.android.cursor.item/imps-messages";
+
+ /**
+ * The default sort order for this table
+ */
+ public static final String DEFAULT_SORT_ORDER = "date ASC";
+
+ /**
+ * The "contact" column. This is not a real column in the messages table, but a
+ * temoprary column created when querying for messages (joined with the contacts table)
+ */
+ public static final String CONTACT = "contact";
+ }
+
+ /**
+ * Columns for the GroupMember table.
+ */
+ public interface GroupMemberColumns {
+ /**
+ * The id of the group this member belongs to.
+ * <p>Type: INTEGER</p>
+ */
+ String GROUP = "groupId";
+
+ /**
+ * The full name of this member.
+ * <p>Type: TEXT</p>
+ */
+ String USERNAME = "username";
+
+ /**
+ * The nick name of this member.
+ * <p>Type: TEXT</p>
+ */
+ String NICKNAME = "nickname";
+ }
+
+ public final static class GroupMembers implements GroupMemberColumns {
+ private GroupMembers(){}
+
+ public static final Uri CONTENT_URI =
+ Uri.parse("content://imps/groupMembers");
+
+ /**
+ * The MIME type of {@link #CONTENT_URI} providing a directory of
+ * group members.
+ */
+ public static final String CONTENT_TYPE =
+ "vnd.android.cursor.dir/imps-groupMembers";
+
+ /**
+ * The MIME type of a {@link #CONTENT_URI} subdirectory of a single
+ * group member.
+ */
+ public static final String CONTENT_ITEM_TYPE =
+ "vnd.android.cursor.item/imps-groupMembers";
+ }
+
+ /**
+ * Columns from the Invitation table.
+ */
+ public interface InvitationColumns {
+ /**
+ * The provider id.
+ * <p>Type: INTEGER</p>
+ */
+ String PROVIDER = "providerId";
+
+ /**
+ * The account id.
+ * <p>Type: INTEGER</p>
+ */
+ String ACCOUNT = "accountId";
+
+ /**
+ * The invitation id.
+ * <p>Type: TEXT</p>
+ */
+ String INVITE_ID = "inviteId";
+
+ /**
+ * The name of the sender of the invitation.
+ * <p>Type: TEXT</p>
+ */
+ String SENDER = "sender";
+
+ /**
+ * The name of the group which the sender invite you to join.
+ * <p>Type: TEXT</p>
+ */
+ String GROUP_NAME = "groupName";
+
+ /**
+ * A note
+ * <p>Type: TEXT</p>
+ */
+ String NOTE = "note";
+
+ /**
+ * The current status of the invitation.
+ * <p>Type: TEXT</p>
+ */
+ String STATUS = "status";
+
+ int STATUS_PENDING = 0;
+ int STATUS_ACCEPTED = 1;
+ int STATUS_REJECTED = 2;
+ }
+
+ /**
+ * This table contains the invitations received from others.
+ */
+ public final static class Invitation implements InvitationColumns,
+ BaseColumns {
+ private Invitation() {
+ }
+
+ /**
+ * The content:// style URL for this table
+ */
+ public static final Uri CONTENT_URI =
+ Uri.parse("content://imps/invitations");
+
+ /**
+ * The MIME type of {@link #CONTENT_URI} providing a directory of
+ * invitations.
+ */
+ public static final String CONTENT_TYPE =
+ "vnd.android.cursor.dir/imps-invitations";
+
+ /**
+ * The MIME type of a {@link #CONTENT_URI} subdirectory of a single
+ * invitation.
+ */
+ public static final String CONTENT_ITEM_TYPE =
+ "vnd.android.cursor.item/imps-invitations";
+ }
+
+ /**
+ * Columns from the Avatars table
+ */
+ public interface AvatarsColumns {
+ /**
+ * The contact this avatar belongs to
+ * <P>Type: TEXT</P>
+ */
+ String CONTACT = "contact";
+
+ String PROVIDER = "provider_id";
+
+ String ACCOUNT = "account_id";
+
+ /**
+ * The hash of the image data
+ * <P>Type: TEXT</P>
+ */
+ String HASH = "hash";
+
+ /**
+ * raw image data
+ * <P>Type: BLOB</P>
+ */
+ String DATA = "data";
+ }
+
+ /**
+ * This table contains avatars.
+ */
+ public static final class Avatars implements BaseColumns, AvatarsColumns {
+ /**
+ * no public constructor since this is a utility class
+ */
+ private Avatars() {}
+
+ /**
+ * The content:// style URL for this table
+ */
+ public static final Uri CONTENT_URI = Uri.parse("content://imps/avatars");
+
+ /**
+ * The content:// style URL for avatars by provider, account and contact
+ */
+ public static final Uri CONTENT_URI_AVATARS_BY =
+ Uri.parse("content://imps/avatarsBy");
+
+ /**
+ * The MIME type of {@link #CONTENT_URI} providing the avatars
+ */
+ public static final String CONTENT_TYPE = "vnd.android.cursor.dir/imps-avatars";
+
+ /**
+ * The MIME type of a {@link #CONTENT_URI}
+ */
+ public static final String CONTENT_ITEM_TYPE =
+ "vnd.android.cursor.item/imps-avatars";
+
+ /**
+ * The default sort order for this table
+ */
+ public static final String DEFAULT_SORT_ORDER = "contact ASC";
+
+ }
+
+ /**
+ * Common presence columns shared between the IM and contacts presence tables
+ */
+ public interface CommonPresenceColumns {
+ /**
+ * The priority, an integer, used by XMPP presence
+ * <P>Type: INTEGER</P>
+ */
+ String PRIORITY = "priority";
+
+ /**
+ * The server defined status.
+ * <P>Type: INTEGER (one of the values below)</P>
+ */
+ String PRESENCE_STATUS = "mode";
+
+ /**
+ * Presence Status definition
+ */
+ int OFFLINE = 0;
+ int INVISIBLE = 1;
+ int AWAY = 2;
+ int IDLE = 3;
+ int DO_NOT_DISTURB = 4;
+ int AVAILABLE = 5;
+
+ /**
+ * The user defined status line.
+ * <P>Type: TEXT</P>
+ */
+ String PRESENCE_CUSTOM_STATUS = "status";
+ }
+
+ /**
+ * Columns from the Presence table.
+ */
+ public interface PresenceColumns extends CommonPresenceColumns {
+ /**
+ * The contact id
+ * <P>Type: INTEGER</P>
+ */
+ String CONTACT_ID = "contact_id";
+
+ /**
+ * The contact's JID resource, only relevant for XMPP contact
+ * <P>Type: TEXT</P>
+ */
+ String JID_RESOURCE = "jid_resource";
+
+ /**
+ * The contact's client type
+ */
+ String CLIENT_TYPE = "client_type";
+
+ /**
+ * client type definitions
+ */
+ int CLIENT_TYPE_DEFAULT = 0;
+ int CLIENT_TYPE_MOBILE = 1;
+ int CLIENT_TYPE_ANDROID = 2;
+ }
+
+ /**
+ * Contains presence infomation for contacts.
+ */
+ public static final class Presence implements BaseColumns, PresenceColumns {
+ /**
+ * The content:// style URL for this table
+ */
+ public static final Uri CONTENT_URI = Uri.parse("content://imps/presence");
+
+ /**
+ * The content URL for IM presences for an account
+ */
+ public static final Uri CONTENT_URI_BY_ACCOUNT = Uri.parse("content://imps/presence/account");
+
+ /**
+ * The content:// style URL for operations on bulk contacts
+ */
+ public static final Uri BULK_CONTENT_URI = Uri.parse("content://imps/bulk_presence");
+
+ /**
+ * The content:// style URL for seeding presences for a given account id.
+ */
+ public static final Uri SEED_PRESENCE_BY_ACCOUNT_CONTENT_URI =
+ Uri.parse("content://imps/seed_presence/account");
+
+ /**
+ * The MIME type of a {@link #CONTENT_URI} providing a directory of presence
+ */
+ public static final String CONTENT_TYPE = "vnd.android.cursor.dir/imps-presence";
+
+ /**
+ * The default sort order for this table
+ */
+ public static final String DEFAULT_SORT_ORDER = "mode DESC";
+ }
+
+ /**
+ * Columns from the Chats table.
+ */
+ public interface ChatsColumns {
+ /**
+ * The contact ID this chat belongs to. The value is a long.
+ * <P>Type: INT</P>
+ */
+ String CONTACT_ID = "contact_id";
+
+ /**
+ * The GTalk JID resource. The value is a string.
+ * <P>Type: TEXT</P>
+ */
+ String JID_RESOURCE = "jid_resource";
+
+ /**
+ * Whether this is a groupchat or not.
+ * <P>Type: INT</P>
+ */
+ String GROUP_CHAT = "groupchat";
+
+ /**
+ * The last unread message. This both indicates that there is an
+ * unread message, and what the message is.
+ * <P>Type: TEXT</P>
+ */
+ String LAST_UNREAD_MESSAGE = "last_unread_message";
+
+ /**
+ * The last message timestamp
+ * <P>Type: INT</P>
+ */
+ String LAST_MESSAGE_DATE = "last_message_date";
+
+ /**
+ * A message that is being composed. This indicates that there was a
+ * message being composed when the chat screen was shutdown, and what the
+ * message is.
+ * <P>Type: TEXT</P>
+ */
+ String UNSENT_COMPOSED_MESSAGE = "unsent_composed_message";
+
+ /**
+ * A value from 0-9 indicating which quick-switch chat screen slot this
+ * chat is occupying. If none (for instance, this is the 12th active chat)
+ * then the value is -1.
+ * <P>Type: INT</P>
+ */
+ String SHORTCUT = "shortcut";
+ }
+
+ /**
+ * Contains ongoing chat sessions.
+ */
+ public static final class Chats implements BaseColumns, ChatsColumns {
+ /**
+ * no public constructor since this is a utility class
+ */
+ private Chats() {}
+
+ /**
+ * The content:// style URL for this table
+ */
+ public static final Uri CONTENT_URI =
+ Uri.parse("content://imps/chats");
+
+ /**
+ * The content URL for all chats that belong to the account
+ */
+ public static final Uri CONTENT_URI_BY_ACCOUNT = Uri.parse("content://imps/chats/account");
+
+ /**
+ * The MIME type of {@link #CONTENT_URI} providing a directory of chats.
+ */
+ public static final String CONTENT_TYPE = "vnd.android.cursor.dir/imps-chats";
+
+ /**
+ * The MIME type of a {@link #CONTENT_URI} subdirectory of a single chat.
+ */
+ public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/imps-chats";
+
+ /**
+ * The default sort order for this table
+ */
+ public static final String DEFAULT_SORT_ORDER = "last_message_date ASC";
+ }
+
+ /**
+ * Columns from session cookies table. Used for IMPS.
+ */
+ public static interface SessionCookiesColumns {
+ String NAME = "name";
+ String VALUE = "value";
+ String PROVIDER = "provider";
+ String ACCOUNT = "account";
+ }
+
+ /**
+ * Contains IMPS session cookies.
+ */
+ public static class SessionCookies implements SessionCookiesColumns, BaseColumns {
+ private SessionCookies() {
+ }
+
+ /**
+ * The content:// style URI for this table
+ */
+ public static final Uri CONTENT_URI = Uri.parse("content://imps/sessionCookies");
+
+ /**
+ * The content:// style URL for session cookies by provider and account
+ */
+ public static final Uri CONTENT_URI_SESSION_COOKIES_BY =
+ Uri.parse("content://imps/sessionCookiesBy");
+
+ /**
+ * The MIME type of {@link #CONTENT_URI} providing a directory of
+ * people.
+ */
+ public static final String CONTENT_TYPE = "vnd.android-dir/imps-sessionCookies";
+ }
+
+ /**
+ * Columns from ProviderSettings table
+ */
+ public static interface ProviderSettingsColumns {
+ /**
+ * The id in database of the related provider
+ *
+ * <P>Type: INT</P>
+ */
+ String PROVIDER = "provider";
+
+ /**
+ * The name of the setting
+ * <P>Type: TEXT</P>
+ */
+ String NAME = "name";
+
+ /**
+ * The value of the setting
+ * <P>Type: TEXT</P>
+ */
+ String VALUE = "value";
+ }
+
+ public static class ProviderSettings implements ProviderSettingsColumns {
+ private ProviderSettings() {
+ }
+
+ /**
+ * The content:// style URI for this table
+ */
+ public static final Uri CONTENT_URI =
+ Uri.parse("content://imps/providerSettings");
+
+ /**
+ * The MIME type of {@link #CONTENT_URI} providing provider settings
+ */
+ public static final String CONTENT_TYPE = "vnd.android-dir/imps-providerSettings";
+
+ /**
+ * A boolean value to indicate whether this provider should show the offline contacts
+ */
+ public static final String SHOW_OFFLINE_CONTACTS = "show_offline_contacts";
+
+ /** controls whether or not the GTalk service automatically connect to server. */
+ public static final String SETTING_AUTOMATICALLY_CONNECT_GTALK = "gtalk_auto_connect";
+
+ /** controls whether or not the IM service will be automatically started after boot */
+ public static final String SETTING_AUTOMATICALLY_START_SERVICE = "auto_start_service";
+
+ /** controls whether or not the offline contacts will be hided */
+ public static final String SETTING_HIDE_OFFLINE_CONTACTS = "hide_offline_contacts";
+
+ /** controls whether or not enable the IM notification */
+ public static final String SETTING_ENABLE_NOTIFICATION = "enable_notification";
+
+ /** specifies whether or not to vibrate */
+ public static final String SETTING_VIBRATE = "vibrate";
+
+ /** specifies the Uri string of the ringtone */
+ public static final String SETTING_RINGTONE = "ringtone";
+
+ /** specifies the Uri of the default ringtone */
+ public static final String SETTING_RINGTONE_DEFAULT =
+ "content://settings/system/notification_sound";
+
+ /** specifies whether or not to show mobile indicator to friends */
+ public static final String SETTING_SHOW_MOBILE_INDICATOR = "mobile_indicator";
+
+ /** specifies whether or not to show as away when device is idle */
+ public static final String SETTING_SHOW_AWAY_ON_IDLE = "show_away_on_idle";
+
+ /** specifies whether or not to upload heartbeat stat upon login */
+ public static final String SETTING_UPLOAD_HEARTBEAT_STAT = "upload_heartbeat_stat";
+
+ /** specifies the last heartbeat interval received from the server */
+ public static final String SETTING_HEARTBEAT_INTERVAL = "heartbeat_interval";
+
+ /** specifiy the JID resource used for Google Talk connection */
+ public static final String SETTING_JID_RESOURCE = "jid_resource";
+
+ /**
+ * Used for reliable message queue (RMQ). This is for storing the last rmq id received
+ * from the GTalk server
+ */
+ public static final String LAST_RMQ_RECEIVED = "last_rmq_rec";
+
+ /**
+ * Query the settings of the provider specified by id
+ *
+ * @param cr
+ * the relative content resolver
+ * @param providerId
+ * the specified id of provider
+ * @return a HashMap which contains all the settings for the specified
+ * provider
+ */
+ public static HashMap<String, String> queryProviderSettings(ContentResolver cr,
+ long providerId) {
+ HashMap<String, String> settings = new HashMap<String, String>();
+
+ String[] projection = { NAME, VALUE };
+ Cursor c = cr.query(ContentUris.withAppendedId(CONTENT_URI, providerId), projection, null, null, null);
+ if (c == null) {
+ return null;
+ }
+
+ while(c.moveToNext()) {
+ settings.put(c.getString(0), c.getString(1));
+ }
+
+ c.close();
+
+ return settings;
+ }
+
+ /**
+ * Get the string value of setting which is specified by provider id and the setting name.
+ *
+ * @param cr The ContentResolver to use to access the settings table.
+ * @param providerId The id of the provider.
+ * @param settingName The name of the setting.
+ * @return The value of the setting if the setting exist, otherwise return null.
+ */
+ public static String getStringValue(ContentResolver cr, long providerId, String settingName) {
+ String ret = null;
+ Cursor c = getSettingValue(cr, providerId, settingName);
+ if (c != null) {
+ ret = c.getString(0);
+ c.close();
+ }
+
+ return ret;
+ }
+
+ /**
+ * Get the boolean value of setting which is specified by provider id and the setting name.
+ *
+ * @param cr The ContentResolver to use to access the settings table.
+ * @param providerId The id of the provider.
+ * @param settingName The name of the setting.
+ * @return The value of the setting if the setting exist, otherwise return false.
+ */
+ public static boolean getBooleanValue(ContentResolver cr, long providerId, String settingName) {
+ boolean ret = false;
+ Cursor c = getSettingValue(cr, providerId, settingName);
+ if (c != null) {
+ ret = c.getInt(0) != 0;
+ c.close();
+ }
+ return ret;
+ }
+
+ private static Cursor getSettingValue(ContentResolver cr, long providerId, String settingName) {
+ Cursor c = cr.query(ContentUris.withAppendedId(CONTENT_URI, providerId), new String[]{VALUE}, NAME + "=?",
+ new String[]{settingName}, null);
+ if (c != null) {
+ if (!c.moveToFirst()) {
+ c.close();
+ return null;
+ }
+ }
+ return c;
+ }
+
+ /**
+ * Save a long value of setting in the table providerSetting.
+ *
+ * @param cr The ContentProvider used to access the providerSetting table.
+ * @param providerId The id of the provider.
+ * @param name The name of the setting.
+ * @param value The value of the setting.
+ */
+ public static void putLongValue(ContentResolver cr, long providerId, String name,
+ long value) {
+ ContentValues v = new ContentValues(3);
+ v.put(PROVIDER, providerId);
+ v.put(NAME, name);
+ v.put(VALUE, value);
+
+ cr.insert(CONTENT_URI, v);
+ }
+
+ /**
+ * Save a boolean value of setting in the table providerSetting.
+ *
+ * @param cr The ContentProvider used to access the providerSetting table.
+ * @param providerId The id of the provider.
+ * @param name The name of the setting.
+ * @param value The value of the setting.
+ */
+ public static void putBooleanValue(ContentResolver cr, long providerId, String name,
+ boolean value) {
+ ContentValues v = new ContentValues(3);
+ v.put(PROVIDER, providerId);
+ v.put(NAME, name);
+ v.put(VALUE, Boolean.toString(value));
+
+ cr.insert(CONTENT_URI, v);
+ }
+
+ /**
+ * Save a string value of setting in the table providerSetting.
+ *
+ * @param cr The ContentProvider used to access the providerSetting table.
+ * @param providerId The id of the provider.
+ * @param name The name of the setting.
+ * @param value The value of the setting.
+ */
+ public static void putStringValue(ContentResolver cr, long providerId, String name,
+ String value) {
+ ContentValues v = new ContentValues(3);
+ v.put(PROVIDER, providerId);
+ v.put(NAME, name);
+ v.put(VALUE, value);
+
+ cr.insert(CONTENT_URI, v);
+ }
+
+ /**
+ * A convenience method to set whether or not the GTalk service should be started
+ * automatically.
+ *
+ * @param contentResolver The ContentResolver to use to access the settings table
+ * @param autoConnect Whether the GTalk service should be started automatically.
+ */
+ public static void setAutomaticallyConnectGTalk(ContentResolver contentResolver,
+ long providerId, boolean autoConnect) {
+ putBooleanValue(contentResolver, providerId, SETTING_AUTOMATICALLY_CONNECT_GTALK,
+ autoConnect);
+ }
+
+ /**
+ * A convenience method to set whether or not the offline contacts should be hided
+ *
+ * @param contentResolver The ContentResolver to use to access the setting table
+ * @param hideOfflineContacts Whether the offline contacts should be hided
+ */
+ public static void setHideOfflineContacts(ContentResolver contentResolver,
+ long providerId, boolean hideOfflineContacts) {
+ putBooleanValue(contentResolver, providerId, SETTING_HIDE_OFFLINE_CONTACTS,
+ hideOfflineContacts);
+ }
+
+ /**
+ * A convenience method to set whether or not enable the IM notification.
+ *
+ * @param contentResolver The ContentResolver to use to access the setting table.
+ * @param enable Whether enable the IM notification
+ */
+ public static void setEnableNotification(ContentResolver contentResolver, long providerId,
+ boolean enable) {
+ putBooleanValue(contentResolver, providerId, SETTING_ENABLE_NOTIFICATION, enable);
+ }
+
+ /**
+ * A convenience method to set whether or not to vibrate.
+ *
+ * @param contentResolver The ContentResolver to use to access the setting table.
+ * @param vibrate Whether or not to vibrate
+ */
+ public static void setVibrate(ContentResolver contentResolver, long providerId,
+ boolean vibrate) {
+ putBooleanValue(contentResolver, providerId, SETTING_VIBRATE, vibrate);
+ }
+
+ /**
+ * A convenience method to set the Uri String of the ringtone.
+ *
+ * @param contentResolver The ContentResolver to use to access the setting table.
+ * @param ringtoneUri The Uri String of the ringtone to be set.
+ */
+ public static void setRingtoneURI(ContentResolver contentResolver, long providerId,
+ String ringtoneUri) {
+ putStringValue(contentResolver, providerId, SETTING_RINGTONE, ringtoneUri);
+ }
+
+ /**
+ * A convenience method to set whether or not to show mobile indicator.
+ *
+ * @param contentResolver The ContentResolver to use to access the setting table.
+ * @param showMobileIndicator Whether or not to show mobile indicator.
+ */
+ public static void setShowMobileIndicator(ContentResolver contentResolver, long providerId,
+ boolean showMobileIndicator) {
+ putBooleanValue(contentResolver, providerId, SETTING_SHOW_MOBILE_INDICATOR,
+ showMobileIndicator);
+ }
+
+ /**
+ * A convenience method to set whether or not to show as away when device is idle.
+ *
+ * @param contentResolver The ContentResolver to use to access the setting table.
+ * @param showAway Whether or not to show as away when device is idle.
+ */
+ public static void setShowAwayOnIdle(ContentResolver contentResolver,
+ long providerId, boolean showAway) {
+ putBooleanValue(contentResolver, providerId, SETTING_SHOW_AWAY_ON_IDLE, showAway);
+ }
+
+ /**
+ * A convenience method to set whether or not to upload heartbeat stat.
+ *
+ * @param contentResolver The ContentResolver to use to access the setting table.
+ * @param uploadStat Whether or not to upload heartbeat stat.
+ */
+ public static void setUploadHeartbeatStat(ContentResolver contentResolver,
+ long providerId, boolean uploadStat) {
+ putBooleanValue(contentResolver, providerId, SETTING_UPLOAD_HEARTBEAT_STAT, uploadStat);
+ }
+
+ /**
+ * A convenience method to set the heartbeat interval last received from the server.
+ *
+ * @param contentResolver The ContentResolver to use to access the setting table.
+ * @param interval The heartbeat interval last received from the server.
+ */
+ public static void setHeartbeatInterval(ContentResolver contentResolver,
+ long providerId, long interval) {
+ putLongValue(contentResolver, providerId, SETTING_HEARTBEAT_INTERVAL, interval);
+ }
+
+ /**
+ * A convenience method to set the jid resource.
+ */
+ public static void setJidResource(ContentResolver contentResolver,
+ long providerId, String jidResource) {
+ putStringValue(contentResolver, providerId, SETTING_JID_RESOURCE, jidResource);
+ }
+
+ public static class QueryMap extends ContentQueryMap {
+ private ContentResolver mContentResolver;
+ private long mProviderId;
+
+ public QueryMap(ContentResolver contentResolver, long providerId, boolean keepUpdated,
+ Handler handlerForUpdateNotifications) {
+ super(contentResolver.query(CONTENT_URI,
+ new String[] {NAME,VALUE},
+ PROVIDER + "=" + providerId,
+ null, // no selection args
+ null), // no sort order
+ NAME, keepUpdated, handlerForUpdateNotifications);
+ mContentResolver = contentResolver;
+ mProviderId = providerId;
+ }
+
+ /**
+ * Set if the GTalk service should automatically connect to server.
+ *
+ * @param autoConnect if the GTalk service should auto connect to server.
+ */
+ public void setAutomaticallyConnectToGTalkServer(boolean autoConnect) {
+ ProviderSettings.setAutomaticallyConnectGTalk(mContentResolver, mProviderId,
+ autoConnect);
+ }
+
+ /**
+ * Check if the GTalk service should automatically connect to server.
+ * @return if the GTalk service should automatically connect to server.
+ */
+ public boolean getAutomaticallyConnectToGTalkServer() {
+ return getBoolean(SETTING_AUTOMATICALLY_CONNECT_GTALK,
+ true /* default to automatically sign in */);
+ }
+
+ /**
+ * Set whether or not the offline contacts should be hided.
+ *
+ * @param hideOfflineContacts Whether or not the offline contacts should be hided.
+ */
+ public void setHideOfflineContacts(boolean hideOfflineContacts) {
+ ProviderSettings.setHideOfflineContacts(mContentResolver, mProviderId,
+ hideOfflineContacts);
+ }
+
+ /**
+ * Check if the offline contacts should be hided.
+ *
+ * @return Whether or not the offline contacts should be hided.
+ */
+ public boolean getHideOfflineContacts() {
+ return getBoolean(SETTING_HIDE_OFFLINE_CONTACTS,
+ false/* by default not hide the offline contacts*/);
+ }
+
+ /**
+ * Set whether or not enable the IM notification.
+ *
+ * @param enable Whether or not enable the IM notification.
+ */
+ public void setEnableNotification(boolean enable) {
+ ProviderSettings.setEnableNotification(mContentResolver, mProviderId, enable);
+ }
+
+ /**
+ * Check if the IM notification is enabled.
+ *
+ * @return Whether or not enable the IM notification.
+ */
+ public boolean getEnableNotification() {
+ return getBoolean(SETTING_ENABLE_NOTIFICATION,
+ true/* by default enable the notification */);
+ }
+
+ /**
+ * Set whether or not to vibrate on IM notification.
+ *
+ * @param vibrate Whether or not to vibrate.
+ */
+ public void setVibrate(boolean vibrate) {
+ ProviderSettings.setVibrate(mContentResolver, mProviderId, vibrate);
+ }
+
+ /**
+ * Gets whether or not to vibrate on IM notification.
+ *
+ * @return Whether or not to vibrate.
+ */
+ public boolean getVibrate() {
+ return getBoolean(SETTING_VIBRATE, false /* by default disable vibrate */);
+ }
+
+ /**
+ * Set the Uri for the ringtone.
+ *
+ * @param ringtoneUri The Uri of the ringtone to be set.
+ */
+ public void setRingtoneURI(String ringtoneUri) {
+ ProviderSettings.setRingtoneURI(mContentResolver, mProviderId, ringtoneUri);
+ }
+
+ /**
+ * Get the Uri String of the current ringtone.
+ *
+ * @return The Uri String of the current ringtone.
+ */
+ public String getRingtoneURI() {
+ return getString(SETTING_RINGTONE, SETTING_RINGTONE_DEFAULT);
+ }
+
+ /**
+ * Set whether or not to show mobile indicator to friends.
+ *
+ * @param showMobile whether or not to show mobile indicator.
+ */
+ public void setShowMobileIndicator(boolean showMobile) {
+ ProviderSettings.setShowMobileIndicator(mContentResolver, mProviderId, showMobile);
+ }
+
+ /**
+ * Gets whether or not to show mobile indicator.
+ *
+ * @return Whether or not to show mobile indicator.
+ */
+ public boolean getShowMobileIndicator() {
+ return getBoolean(SETTING_SHOW_MOBILE_INDICATOR,
+ true /* by default show mobile indicator */);
+ }
+
+ /**
+ * Set whether or not to show as away when device is idle.
+ *
+ * @param showAway whether or not to show as away when device is idle.
+ */
+ public void setShowAwayOnIdle(boolean showAway) {
+ ProviderSettings.setShowAwayOnIdle(mContentResolver, mProviderId, showAway);
+ }
+
+ /**
+ * Get whether or not to show as away when device is idle.
+ *
+ * @return Whether or not to show as away when device is idle.
+ */
+ public boolean getShowAwayOnIdle() {
+ return getBoolean(SETTING_SHOW_AWAY_ON_IDLE,
+ true /* by default show as away on idle*/);
+ }
+
+ /**
+ * Set whether or not to upload heartbeat stat.
+ *
+ * @param uploadStat whether or not to upload heartbeat stat.
+ */
+ public void setUploadHeartbeatStat(boolean uploadStat) {
+ ProviderSettings.setUploadHeartbeatStat(mContentResolver, mProviderId, uploadStat);
+ }
+
+ /**
+ * Get whether or not to upload heartbeat stat.
+ *
+ * @return Whether or not to upload heartbeat stat.
+ */
+ public boolean getUploadHeartbeatStat() {
+ return getBoolean(SETTING_UPLOAD_HEARTBEAT_STAT,
+ false /* by default do not upload */);
+ }
+
+ /**
+ * Set the last received heartbeat interval from the server.
+ *
+ * @param interval the last received heartbeat interval from the server.
+ */
+ public void setHeartbeatInterval(long interval) {
+ ProviderSettings.setHeartbeatInterval(mContentResolver, mProviderId, interval);
+ }
+
+ /**
+ * Get the last received heartbeat interval from the server.
+ *
+ * @return the last received heartbeat interval from the server.
+ */
+ public long getHeartbeatInterval() {
+ return getLong(SETTING_HEARTBEAT_INTERVAL, 0L /* an invalid default interval */);
+ }
+
+ /**
+ * Set the JID resource.
+ *
+ * @param jidResource the jid resource to be stored.
+ */
+ public void setJidResource(String jidResource) {
+ ProviderSettings.setJidResource(mContentResolver, mProviderId, jidResource);
+ }
+ /**
+ * Get the JID resource used for the Google Talk connection
+ *
+ * @return the JID resource stored.
+ */
+ public String getJidResource() {
+ return getString(SETTING_JID_RESOURCE, null);
+ }
+
+ /**
+ * Convenience function for retrieving a single settings value
+ * as a boolean.
+ *
+ * @param name The name of the setting to retrieve.
+ * @param def Value to return if the setting is not defined.
+ * @return The setting's current value, or 'def' if it is not defined.
+ */
+ private boolean getBoolean(String name, boolean def) {
+ ContentValues values = getValues(name);
+ return values != null ? values.getAsBoolean(VALUE) : def;
+ }
+
+ /**
+ * Convenience function for retrieving a single settings value
+ * as a String.
+ *
+ * @param name The name of the setting to retrieve.
+ * @param def The value to return if the setting is not defined.
+ * @return The setting's current value or 'def' if it is not defined.
+ */
+ private String getString(String name, String def) {
+ ContentValues values = getValues(name);
+ return values != null ? values.getAsString(VALUE) : def;
+ }
+
+ /**
+ * Convenience function for retrieving a single settings value
+ * as an Integer.
+ *
+ * @param name The name of the setting to retrieve.
+ * @param def The value to return if the setting is not defined.
+ * @return The setting's current value or 'def' if it is not defined.
+ */
+ private int getInteger(String name, int def) {
+ ContentValues values = getValues(name);
+ return values != null ? values.getAsInteger(VALUE) : def;
+ }
+
+ /**
+ * Convenience function for retrieving a single settings value
+ * as a Long.
+ *
+ * @param name The name of the setting to retrieve.
+ * @param def The value to return if the setting is not defined.
+ * @return The setting's current value or 'def' if it is not defined.
+ */
+ private long getLong(String name, long def) {
+ ContentValues values = getValues(name);
+ return values != null ? values.getAsLong(VALUE) : def;
+ }
+ }
+
+ }
+
+
+ /**
+ * Columns for IM branding resource map cache table. This table caches the result of
+ * loading the branding resources to speed up IM landing page start.
+ */
+ public interface BrandingResourceMapCacheColumns {
+ /**
+ * The provider ID
+ * <P>Type: INTEGER</P>
+ */
+ String PROVIDER_ID = "provider_id";
+ /**
+ * The application resource ID
+ * <P>Type: INTEGER</P>
+ */
+ String APP_RES_ID = "app_res_id";
+ /**
+ * The plugin resource ID
+ * <P>Type: INTEGER</P>
+ */
+ String PLUGIN_RES_ID = "plugin_res_id";
+ }
+
+ /**
+ * The table for caching the result of loading IM branding resources.
+ */
+ public static final class BrandingResourceMapCache
+ implements BaseColumns, BrandingResourceMapCacheColumns {
+ /**
+ * The content:// style URL for this table.
+ */
+ public static final Uri CONTENT_URI = Uri.parse("content://imps/brandingResMapCache");
+ }
+
+
+
+ /**
+ * //TODO: move these to MCS specific provider.
+ * The following are MCS stuff, and should really live in a separate provider specific to
+ * MCS code.
+ */
+
+ /**
+ * Columns from OutgoingRmq table
+ */
+ public interface OutgoingRmqColumns {
+ String RMQ_ID = "rmq_id";
+ String TIMESTAMP = "ts";
+ String DATA = "data";
+ String PROTOBUF_TAG = "type";
+ }
+
+ /**
+ * //TODO: we should really move these to their own provider and database.
+ * The table for storing outgoing rmq packets.
+ */
+ public static final class OutgoingRmq implements BaseColumns, OutgoingRmqColumns {
+ private static String[] RMQ_ID_PROJECTION = new String[] {
+ RMQ_ID,
+ };
+
+ /**
+ * queryHighestRmqId
+ *
+ * @param resolver the content resolver
+ * @return the highest rmq id assigned to the rmq packet, or 0 if there are no rmq packets
+ * in the OutgoingRmq table.
+ */
+ public static final long queryHighestRmqId(ContentResolver resolver) {
+ Cursor cursor = resolver.query(Imps.OutgoingRmq.CONTENT_URI_FOR_HIGHEST_RMQ_ID,
+ RMQ_ID_PROJECTION,
+ null, // selection
+ null, // selection args
+ null // sort
+ );
+
+ long retVal = 0;
+ try {
+ //if (DBG) log("initializeRmqid: cursor.count= " + cursor.count());
+
+ if (cursor.moveToFirst()) {
+ retVal = cursor.getLong(cursor.getColumnIndexOrThrow(RMQ_ID));
+ }
+ } finally {
+ cursor.close();
+ }
+
+ return retVal;
+ }
+
+ /**
+ * The content:// style URL for this table.
+ */
+ public static final Uri CONTENT_URI = Uri.parse("content://imps/outgoingRmqMessages");
+
+ /**
+ * The content:// style URL for the highest rmq id for the outgoing rmq messages
+ */
+ public static final Uri CONTENT_URI_FOR_HIGHEST_RMQ_ID =
+ Uri.parse("content://imps/outgoingHighestRmqId");
+
+ /**
+ * The default sort order for this table.
+ */
+ public static final String DEFAULT_SORT_ORDER = "rmq_id ASC";
+ }
+
+ /**
+ * Columns for the LastRmqId table, which stores a single row for the last client rmq id
+ * sent to the server.
+ */
+ public interface LastRmqIdColumns {
+ String RMQ_ID = "rmq_id";
+ }
+
+ /**
+ * //TODO: move these out into their own provider and database
+ * The table for storing the last client rmq id sent to the server.
+ */
+ public static final class LastRmqId implements BaseColumns, LastRmqIdColumns {
+ private static String[] PROJECTION = new String[] {
+ RMQ_ID,
+ };
+
+ /**
+ * queryLastRmqId
+ *
+ * queries the last rmq id saved in the LastRmqId table.
+ *
+ * @param resolver the content resolver.
+ * @return the last rmq id stored in the LastRmqId table, or 0 if not found.
+ */
+ public static final long queryLastRmqId(ContentResolver resolver) {
+ Cursor cursor = resolver.query(Imps.LastRmqId.CONTENT_URI,
+ PROJECTION,
+ null, // selection
+ null, // selection args
+ null // sort
+ );
+
+ long retVal = 0;
+ try {
+ if (cursor.moveToFirst()) {
+ retVal = cursor.getLong(cursor.getColumnIndexOrThrow(RMQ_ID));
+ }
+ } finally {
+ cursor.close();
+ }
+
+ return retVal;
+ }
+
+ /**
+ * saveLastRmqId
+ *
+ * saves the rmqId to the lastRmqId table. This will override the existing row if any,
+ * as we only keep one row of data in this table.
+ *
+ * @param resolver the content resolver.
+ * @param rmqId the rmq id to be saved.
+ */
+ public static final void saveLastRmqId(ContentResolver resolver, long rmqId) {
+ ContentValues values = new ContentValues();
+
+ // always replace the first row.
+ values.put(_ID, 1);
+ values.put(RMQ_ID, rmqId);
+ resolver.insert(CONTENT_URI, values);
+ }
+
+ /**
+ * The content:// style URL for this table.
+ */
+ public static final Uri CONTENT_URI = Uri.parse("content://imps/lastRmqId");
+ }
+
+ /**
+ * Columns for the s2dRmqIds table, which stores the server-to-device message
+ * persistent ids. These are used in the RMQ2 protocol, where in the login request, the
+ * client selective acks these s2d ids to the server.
+ */
+ public interface ServerToDeviceRmqIdsColumn {
+ String RMQ_ID = "rmq_id";
+ }
+
+ public static final class ServerToDeviceRmqIds implements BaseColumns,
+ ServerToDeviceRmqIdsColumn {
+
+ /**
+ * The content:// style URL for this table.
+ */
+ public static final Uri CONTENT_URI = Uri.parse("content://imps/s2dids");
+ }
+
+}
diff --git a/src/com/android/im/provider/ImpsProvider.java b/src/com/android/im/provider/ImpsProvider.java
new file mode 100644
index 0000000..0a32d50
--- /dev/null
+++ b/src/com/android/im/provider/ImpsProvider.java
@@ -0,0 +1,3332 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.im.provider;
+
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.UriMatcher;
+import android.content.ContentResolver;
+import android.database.Cursor;
+import android.database.DatabaseUtils;
+import android.database.sqlite.SQLiteConstraintException;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.database.sqlite.SQLiteQueryBuilder;
+import android.net.Uri;
+import android.os.ParcelFileDescriptor;
+import android.text.TextUtils;
+import android.util.Log;
+
+
+import java.io.FileNotFoundException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+/**
+ * A content provider for IM
+ */
+public class ImpsProvider extends ContentProvider {
+ private static final String LOG_TAG = "imProvider";
+ private static final boolean DBG = false;
+
+ private static final String AUTHORITY = "imps";
+
+ private static final String TABLE_ACCOUNTS = "accounts";
+ private static final String TABLE_PROVIDERS = "providers";
+ private static final String TABLE_PROVIDER_SETTINGS = "providerSettings";
+
+ private static final String TABLE_CONTACTS = "contacts";
+ private static final String TABLE_CONTACTS_ETAG = "contactsEtag";
+ private static final String TABLE_BLOCKED_LIST = "blockedList";
+ private static final String TABLE_CONTACT_LIST = "contactList";
+ private static final String TABLE_INVITATIONS = "invitations";
+ private static final String TABLE_GROUP_MEMBERS = "groupMembers";
+ private static final String TABLE_PRESENCE = "presence";
+ private static final String USERNAME = "username";
+ private static final String TABLE_CHATS = "chats";
+ private static final String TABLE_AVATARS = "avatars";
+ private static final String TABLE_SESSION_COOKIES = "sessionCookies";
+ private static final String TABLE_MESSAGES = "messages";
+ private static final String TABLE_IN_MEMORY_MESSAGES = "inMemoryMessages";
+ private static final String TABLE_ACCOUNT_STATUS = "accountStatus";
+ private static final String TABLE_BRANDING_RESOURCE_MAP_CACHE = "brandingResMapCache";
+
+ // tables for mcs and rmq
+ private static final String TABLE_OUTGOING_RMQ_MESSAGES = "outgoingRmqMessages";
+ private static final String TABLE_LAST_RMQ_ID = "lastrmqid";
+ private static final String TABLE_S2D_RMQ_IDS = "s2dRmqIds";
+
+
+ private static final String DATABASE_NAME = "imps.db";
+ private static final int DATABASE_VERSION = 1;
+
+ protected static final int MATCH_PROVIDERS = 1;
+ protected static final int MATCH_PROVIDERS_BY_ID = 2;
+ protected static final int MATCH_PROVIDERS_WITH_ACCOUNT = 3;
+ protected static final int MATCH_ACCOUNTS = 10;
+ protected static final int MATCH_ACCOUNTS_BY_ID = 11;
+ protected static final int MATCH_CONTACTS = 18;
+ protected static final int MATCH_CONTACTS_JOIN_PRESENCE = 19;
+ protected static final int MATCH_CONTACTS_BAREBONE = 20;
+ protected static final int MATCH_CHATTING_CONTACTS = 21;
+ protected static final int MATCH_CONTACTS_BY_PROVIDER = 22;
+ protected static final int MATCH_CHATTING_CONTACTS_BY_PROVIDER = 23;
+ protected static final int MATCH_NO_CHATTING_CONTACTS_BY_PROVIDER = 24;
+ protected static final int MATCH_ONLINE_CONTACTS_BY_PROVIDER = 25;
+ protected static final int MATCH_OFFLINE_CONTACTS_BY_PROVIDER = 26;
+ protected static final int MATCH_CONTACT = 27;
+ protected static final int MATCH_CONTACTS_BULK = 28;
+ protected static final int MATCH_ONLINE_CONTACT_COUNT = 30;
+ protected static final int MATCH_BLOCKED_CONTACTS = 31;
+ protected static final int MATCH_CONTACTLISTS = 32;
+ protected static final int MATCH_CONTACTLISTS_BY_PROVIDER = 33;
+ protected static final int MATCH_CONTACTLIST = 34;
+ protected static final int MATCH_BLOCKEDLIST = 35;
+ protected static final int MATCH_BLOCKEDLIST_BY_PROVIDER = 36;
+ protected static final int MATCH_CONTACTS_ETAGS = 37;
+ protected static final int MATCH_CONTACTS_ETAG = 38;
+ protected static final int MATCH_PRESENCE = 40;
+ protected static final int MATCH_PRESENCE_ID = 41;
+ protected static final int MATCH_PRESENCE_BY_ACCOUNT = 42;
+ protected static final int MATCH_PRESENCE_SEED_BY_ACCOUNT = 43;
+ protected static final int MATCH_PRESENCE_BULK = 44;
+
+ protected static final int MATCH_MESSAGES = 50;
+ protected static final int MATCH_MESSAGES_BY_CONTACT = 51;
+ protected static final int MATCH_MESSAGES_BY_THREAD_ID = 52;
+ protected static final int MATCH_MESSAGES_BY_PROVIDER = 53;
+ protected static final int MATCH_MESSAGES_BY_ACCOUNT = 54;
+ protected static final int MATCH_MESSAGE = 55;
+ protected static final int MATCH_OTR_MESSAGES = 56;
+ protected static final int MATCH_OTR_MESSAGES_BY_CONTACT = 57;
+ protected static final int MATCH_OTR_MESSAGES_BY_THREAD_ID = 58;
+ protected static final int MATCH_OTR_MESSAGES_BY_PROVIDER = 59;
+ protected static final int MATCH_OTR_MESSAGES_BY_ACCOUNT = 60;
+ protected static final int MATCH_OTR_MESSAGE = 61;
+
+ protected static final int MATCH_GROUP_MEMBERS = 65;
+ protected static final int MATCH_GROUP_MEMBERS_BY_GROUP = 66;
+ protected static final int MATCH_AVATARS = 70;
+ protected static final int MATCH_AVATAR = 71;
+ protected static final int MATCH_AVATAR_BY_PROVIDER = 72;
+ protected static final int MATCH_CHATS = 80;
+ protected static final int MATCH_CHATS_BY_ACCOUNT = 81;
+ protected static final int MATCH_CHATS_ID = 82;
+ protected static final int MATCH_SESSIONS = 83;
+ protected static final int MATCH_SESSIONS_BY_PROVIDER = 84;
+ protected static final int MATCH_PROVIDER_SETTINGS = 90;
+ protected static final int MATCH_PROVIDER_SETTINGS_BY_ID = 91;
+ protected static final int MATCH_PROVIDER_SETTINGS_BY_ID_AND_NAME = 92;
+ protected static final int MATCH_INVITATIONS = 100;
+ protected static final int MATCH_INVITATION = 101;
+ protected static final int MATCH_ACCOUNTS_STATUS = 104;
+ protected static final int MATCH_ACCOUNT_STATUS = 105;
+ protected static final int MATCH_BRANDING_RESOURCE_MAP_CACHE = 106;
+
+ // mcs url matcher
+ protected static final int MATCH_OUTGOING_RMQ_MESSAGES = 200;
+ protected static final int MATCH_OUTGOING_RMQ_MESSAGE = 201;
+ protected static final int MATCH_OUTGOING_HIGHEST_RMQ_ID = 202;
+ protected static final int MATCH_LAST_RMQ_ID = 203;
+ protected static final int MATCH_S2D_RMQ_IDS = 204;
+
+
+ protected final UriMatcher mUrlMatcher = new UriMatcher(UriMatcher.NO_MATCH);
+ private final String mTransientDbName;
+
+ private static final HashMap<String, String> sProviderAccountsProjectionMap;
+ private static final HashMap<String, String> sContactsProjectionMap;
+ private static final HashMap<String, String> sContactListProjectionMap;
+ private static final HashMap<String, String> sBlockedListProjectionMap;
+ private static final HashMap<String, String> sMessagesProjectionMap;
+ private static final HashMap<String, String> sInMemoryMessagesProjectionMap;
+
+
+ private static final String PROVIDER_JOIN_ACCOUNT_TABLE =
+ "providers LEFT OUTER JOIN accounts ON " +
+ "(providers._id = accounts.provider AND accounts.active = 1) " +
+ "LEFT OUTER JOIN accountStatus ON (accounts._id = accountStatus.account)";
+
+
+ private static final String CONTACT_JOIN_PRESENCE_TABLE =
+ "contacts LEFT OUTER JOIN presence ON (contacts._id = presence.contact_id)";
+
+ private static final String CONTACT_JOIN_PRESENCE_CHAT_TABLE =
+ CONTACT_JOIN_PRESENCE_TABLE +
+ " LEFT OUTER JOIN chats ON (contacts._id = chats.contact_id)";
+
+ private static final String CONTACT_JOIN_PRESENCE_CHAT_AVATAR_TABLE =
+ CONTACT_JOIN_PRESENCE_CHAT_TABLE +
+ " LEFT OUTER JOIN avatars ON (contacts.username = avatars.contact" +
+ " AND contacts.account = avatars.account_id)";
+
+ private static final String BLOCKEDLIST_JOIN_AVATAR_TABLE =
+ "blockedList LEFT OUTER JOIN avatars ON (blockedList.username = avatars.contact" +
+ " AND blockedList.account = avatars.account_id)";
+
+ private static final String MESSAGE_JOIN_CONTACT_TABLE =
+ "messages LEFT OUTER JOIN contacts ON (contacts._id = messages.thread_id)";
+
+ private static final String IN_MEMORY_MESSAGES_JOIN_CONTACT_TABLE =
+ "inMemoryMessages LEFT OUTER JOIN contacts ON " +
+ "(contacts._id = inMemoryMessages.thread_id)";
+
+ /**
+ * The where clause for filtering out blocked contacts
+ */
+ private static final String NON_BLOCKED_CONTACTS_WHERE_CLAUSE = "("
+ + Imps.Contacts.TYPE + " IS NULL OR "
+ + Imps.Contacts.TYPE + "!="
+ + String.valueOf(Imps.Contacts.TYPE_BLOCKED)
+ + ")";
+
+ private static final String BLOCKED_CONTACTS_WHERE_CLAUSE =
+ "(contacts." + Imps.Contacts.TYPE + "=" + Imps.Contacts.TYPE_BLOCKED + ")";
+
+ private static final String CONTACT_ID = TABLE_CONTACTS + '.' + Imps.Contacts._ID;
+ private static final String PRESENCE_CONTACT_ID = TABLE_PRESENCE + '.' + Imps.Presence.CONTACT_ID;
+
+ protected SQLiteOpenHelper mOpenHelper;
+ private final String mDatabaseName;
+ private final int mDatabaseVersion;
+
+ private final String[] BACKFILL_PROJECTION = {
+ Imps.Chats._ID, Imps.Chats.SHORTCUT, Imps.Chats.LAST_MESSAGE_DATE
+ };
+
+ private final String[] FIND_SHORTCUT_PROJECTION = {
+ Imps.Chats._ID, Imps.Chats.SHORTCUT
+ };
+
+ // contact id query projection
+ private static final String[] CONTACT_ID_PROJECTION = new String[] {
+ Imps.Contacts._ID, // 0
+ };
+ private static final int CONTACT_ID_COLUMN = 0;
+
+ // contact id query selection for "seed presence" operation
+ private static final String CONTACTS_WITH_NO_PRESENCE_SELECTION =
+ Imps.Contacts.ACCOUNT + "=?" + " AND " + Imps.Contacts._ID +
+ " in (select " + CONTACT_ID + " from " + TABLE_CONTACTS +
+ " left outer join " + TABLE_PRESENCE + " on " + CONTACT_ID + '=' +
+ PRESENCE_CONTACT_ID + " where " + PRESENCE_CONTACT_ID + " IS NULL)";
+
+ // contact id query selection args 1
+ private String[] mQueryContactIdSelectionArgs1 = new String[1];
+
+ // contact id query selection for getContactId()
+ private static final String CONTACT_ID_QUERY_SELECTION =
+ Imps.Contacts.ACCOUNT + "=? AND " + Imps.Contacts.USERNAME + "=?";
+
+ // contact id query selection args 2
+ private String[] mQueryContactIdSelectionArgs2 = new String[2];
+
+
+
+ private class DatabaseHelper extends SQLiteOpenHelper {
+
+ DatabaseHelper(Context context) {
+ super(context, mDatabaseName, null, mDatabaseVersion);
+ }
+
+ @Override
+ public void onCreate(SQLiteDatabase db) {
+
+ if (DBG) log("DatabaseHelper.onCreate");
+
+ db.execSQL("CREATE TABLE " + TABLE_PROVIDERS + " (" +
+ "_id INTEGER PRIMARY KEY," +
+ "name TEXT," + // eg AIM
+ "fullname TEXT," + // eg AOL Instance Messenger
+ "category TEXT," + // a category used for forming intent
+ "signup_url TEXT" + // web url to visit to create a new account
+ ");");
+
+ db.execSQL("CREATE TABLE " + TABLE_ACCOUNTS + " (" +
+ "_id INTEGER PRIMARY KEY," +
+ "name TEXT," +
+ "provider INTEGER," +
+ "username TEXT," +
+ "pw TEXT," +
+ "active INTEGER NOT NULL DEFAULT 0," +
+ "locked INTEGER NOT NULL DEFAULT 0," +
+ "keep_signed_in INTEGER NOT NULL DEFAULT 0," +
+ "last_login_state INTEGER NOT NULL DEFAULT 0," +
+ "UNIQUE (provider, username)" +
+ ");");
+
+ createContactsTables(db);
+ createMessageChatTables(db, true /* create show_ts column */);
+
+ db.execSQL("CREATE TABLE " + TABLE_AVATARS + " (" +
+ "_id INTEGER PRIMARY KEY," +
+ "contact TEXT," +
+ "provider_id INTEGER," +
+ "account_id INTEGER," +
+ "hash TEXT," +
+ "data BLOB," + // raw image data
+ "UNIQUE (account_id, contact)" +
+ ");");
+
+ db.execSQL("CREATE TABLE " + TABLE_PROVIDER_SETTINGS + " (" +
+ "_id INTEGER PRIMARY KEY," +
+ "provider INTEGER," +
+ "name TEXT," +
+ "value TEXT," +
+ "UNIQUE (provider, name)" +
+ ");");
+
+ db.execSQL("create TABLE " + TABLE_BRANDING_RESOURCE_MAP_CACHE + " (" +
+ "_id INTEGER PRIMARY KEY," +
+ "provider_id INTEGER," +
+ "app_res_id INTEGER," +
+ "plugin_res_id INTEGER" +
+ ");");
+
+ // clean up account specific data when an account is deleted.
+ db.execSQL("CREATE TRIGGER account_cleanup " +
+ "DELETE ON " + TABLE_ACCOUNTS +
+ " BEGIN " +
+ "DELETE FROM " + TABLE_AVATARS + " WHERE account_id= OLD._id;" +
+ "END");
+
+ // add a database trigger to clean up associated provider settings
+ // while deleting a provider
+ db.execSQL("CREATE TRIGGER provider_cleanup " +
+ "DELETE ON " + TABLE_PROVIDERS +
+ " BEGIN " +
+ "DELETE FROM " + TABLE_PROVIDER_SETTINGS + " WHERE provider= OLD._id;" +
+ "END");
+
+ // the following are tables for mcs
+ db.execSQL("create TABLE " + TABLE_OUTGOING_RMQ_MESSAGES + " (" +
+ "_id INTEGER PRIMARY KEY," +
+ "rmq_id INTEGER," +
+ "type INTEGER," +
+ "ts INTEGER," +
+ "data TEXT" +
+ ");");
+
+ db.execSQL("create TABLE " + TABLE_LAST_RMQ_ID + " (" +
+ "_id INTEGER PRIMARY KEY," +
+ "rmq_id INTEGER" +
+ ");");
+
+ db.execSQL("create TABLE " + TABLE_S2D_RMQ_IDS + " (" +
+ "_id INTEGER PRIMARY KEY," +
+ "rmq_id INTEGER" +
+ ");");
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+ Log.d(LOG_TAG, "Upgrading database from version " + oldVersion + " to " + newVersion);
+
+ switch (oldVersion) {
+ case 43: // this is the db version shipped in Dream 1.0
+ // no-op: no schema changed from 43 to 44. The db version was changed to flush
+ // old provider settings, so new provider setting (including new name/value
+ // pairs) could be inserted by the plugins.
+
+ // follow thru.
+ case 44:
+ if (newVersion <= 44) {
+ return;
+ }
+
+ db.beginTransaction();
+ try {
+ // add category column to the providers table
+ db.execSQL("ALTER TABLE " + TABLE_PROVIDERS + " ADD COLUMN category TEXT;");
+ // add otr column to the contacts table
+ db.execSQL("ALTER TABLE " + TABLE_CONTACTS + " ADD COLUMN otr INTEGER;");
+
+ db.setTransactionSuccessful();
+ } catch (Throwable ex) {
+ Log.e(LOG_TAG, ex.getMessage(), ex);
+ break; // force to destroy all old data;
+ } finally {
+ db.endTransaction();
+ }
+
+ case 45:
+ if (newVersion <= 45) {
+ return;
+ }
+
+ db.beginTransaction();
+ try {
+ // add an otr_etag column to contact etag table
+ db.execSQL(
+ "ALTER TABLE " + TABLE_CONTACTS_ETAG + " ADD COLUMN otr_etag TEXT;");
+ db.setTransactionSuccessful();
+ } catch (Throwable ex) {
+ Log.e(LOG_TAG, ex.getMessage(), ex);
+ break; // force to destroy all old data;
+ } finally {
+ db.endTransaction();
+ }
+
+ case 46:
+ if (newVersion <= 46) {
+ return;
+ }
+
+ db.beginTransaction();
+ try {
+ // add branding resource map cache table
+ db.execSQL("create TABLE " + TABLE_BRANDING_RESOURCE_MAP_CACHE + " (" +
+ "_id INTEGER PRIMARY KEY," +
+ "provider_id INTEGER," +
+ "app_res_id INTEGER," +
+ "plugin_res_id INTEGER" +
+ ");");
+ db.setTransactionSuccessful();
+ } catch (Throwable ex) {
+ Log.e(LOG_TAG, ex.getMessage(), ex);
+ break; // force to destroy all old data;
+ } finally {
+ db.endTransaction();
+ }
+
+ case 47:
+ if (newVersion <= 47) {
+ return;
+ }
+
+ db.beginTransaction();
+ try {
+ // when upgrading from version 47, don't create the show_ts column
+ // here. The upgrade step in 51 will add the show_ts column to the
+ // messages table. If we created the messages table with show_ts here,
+ // we'll get a duplicate column error later.
+ createMessageChatTables(db, false /* don't create show_ts column */);
+ db.setTransactionSuccessful();
+ } catch (Throwable ex) {
+ Log.e(LOG_TAG, ex.getMessage(), ex);
+ break; // force to destroy all old data;
+ } finally {
+ db.endTransaction();
+ }
+
+ // fall thru.
+
+ case 48:
+ case 49:
+ case 50:
+ if (newVersion <= 50) {
+ return;
+ }
+
+ db.beginTransaction();
+ try {
+ // add rmq2 s2d ids table
+ db.execSQL("create TABLE " + TABLE_S2D_RMQ_IDS + " (" +
+ "_id INTEGER PRIMARY KEY," +
+ "rmq_id INTEGER" +
+ ");");
+ db.setTransactionSuccessful();
+ } catch (Throwable ex) {
+ Log.e(LOG_TAG, ex.getMessage(), ex);
+ break; // force to destroy all old data;
+ } finally {
+ db.endTransaction();
+ }
+
+ case 51:
+ if (newVersion <= 51) {
+ return;
+ }
+
+ db.beginTransaction();
+ try {
+ db.execSQL(
+ "ALTER TABLE " + TABLE_MESSAGES + " ADD COLUMN show_ts INTEGER;");
+ db.setTransactionSuccessful();
+ } catch (Throwable ex) {
+ Log.e(LOG_TAG, ex.getMessage(), ex);
+ break; // force to destroy all old data;
+ } finally {
+ db.endTransaction();
+ }
+
+ return;
+ }
+
+ Log.w(LOG_TAG, "Couldn't upgrade db to " + newVersion + ". Destroying old data.");
+ destroyOldTables(db);
+ onCreate(db);
+ }
+
+ private void destroyOldTables(SQLiteDatabase db) {
+ db.execSQL("DROP TABLE IF EXISTS " + TABLE_PROVIDERS);
+ db.execSQL("DROP TABLE IF EXISTS " + TABLE_ACCOUNTS);
+ db.execSQL("DROP TABLE IF EXISTS " + TABLE_CONTACT_LIST);
+ db.execSQL("DROP TABLE IF EXISTS " + TABLE_BLOCKED_LIST);
+ db.execSQL("DROP TABLE IF EXISTS " + TABLE_CONTACTS);
+ db.execSQL("DROP TABLE IF EXISTS " + TABLE_CONTACTS_ETAG);
+ db.execSQL("DROP TABLE IF EXISTS " + TABLE_AVATARS);
+ db.execSQL("DROP TABLE IF EXISTS " + TABLE_PROVIDER_SETTINGS);
+ db.execSQL("DROP TABLE IF EXISTS " + TABLE_BRANDING_RESOURCE_MAP_CACHE);
+ db.execSQL("DROP TABLE IF EXISTS " + TABLE_MESSAGES);
+ db.execSQL("DROP TABLE IF EXISTS " + TABLE_CHATS);
+
+ // mcs/rmq stuff
+ db.execSQL("DROP TABLE IF EXISTS " + TABLE_OUTGOING_RMQ_MESSAGES);
+ db.execSQL("DROP TABLE IF EXISTS " + TABLE_LAST_RMQ_ID);
+ db.execSQL("DROP TABLE IF EXISTS " + TABLE_S2D_RMQ_IDS);
+ }
+
+ private void createContactsTables(SQLiteDatabase db) {
+ if (DBG) log("createContactsTables");
+
+ StringBuilder buf = new StringBuilder();
+ String contactsTableName = TABLE_CONTACTS;
+
+ // creating the "contacts" table
+ buf.append("CREATE TABLE IF NOT EXISTS ");
+ buf.append(contactsTableName);
+ buf.append(" (");
+ buf.append("_id INTEGER PRIMARY KEY,");
+ buf.append("username TEXT,");
+ buf.append("nickname TEXT,");
+
+ buf.append("provider INTEGER,");
+ buf.append("account INTEGER,");
+ buf.append("contactList INTEGER,");
+ buf.append("type INTEGER,");
+ buf.append("subscriptionStatus INTEGER,");
+ buf.append("subscriptionType INTEGER,");
+
+ // the following are derived from Google Contact Extension, we don't include all
+ // the attributes, just the ones we can use.
+ // (see http://code.google.com/apis/talk/jep_extensions/roster_attributes.html)
+ //
+ // qc: quick contact (derived from message count)
+ // rejected: if the contact has ever been rejected by the user
+ buf.append("qc INTEGER,");
+ buf.append("rejected INTEGER,");
+
+ // Off the record status
+ buf.append("otr INTEGER");
+
+ buf.append(");");
+
+ db.execSQL(buf.toString());
+
+ buf.delete(0, buf.length());
+
+ // creating contact etag table
+ buf.append("CREATE TABLE IF NOT EXISTS ");
+ buf.append(TABLE_CONTACTS_ETAG);
+ buf.append(" (");
+ buf.append("_id INTEGER PRIMARY KEY,");
+ buf.append("etag TEXT,");
+ buf.append("otr_etag TEXT,");
+ buf.append("account INTEGER UNIQUE");
+ buf.append(");");
+
+ db.execSQL(buf.toString());
+
+ buf.delete(0, buf.length());
+
+ // creating the "contactList" table
+ buf.append("CREATE TABLE IF NOT EXISTS ");
+ buf.append(TABLE_CONTACT_LIST);
+ buf.append(" (");
+ buf.append("_id INTEGER PRIMARY KEY,");
+ buf.append("name TEXT,");
+ buf.append("provider INTEGER,");
+ buf.append("account INTEGER");
+ buf.append(");");
+
+ db.execSQL(buf.toString());
+
+ buf.delete(0, buf.length());
+
+ // creating the "blockedList" table
+ buf.append("CREATE TABLE IF NOT EXISTS ");
+ buf.append(TABLE_BLOCKED_LIST);
+ buf.append(" (");
+ buf.append("_id INTEGER PRIMARY KEY,");
+ buf.append("username TEXT,");
+ buf.append("nickname TEXT,");
+ buf.append("provider INTEGER,");
+ buf.append("account INTEGER");
+ buf.append(");");
+
+ db.execSQL(buf.toString());
+ }
+
+ private void createMessageChatTables(SQLiteDatabase db,
+ boolean addShowTsColumnForMessagesTable) {
+ if (DBG) log("createMessageChatTables");
+
+ // message table
+ StringBuilder buf = new StringBuilder();
+ buf.append("CREATE TABLE IF NOT EXISTS ");
+ buf.append(TABLE_MESSAGES);
+ buf.append(" (_id INTEGER PRIMARY KEY,");
+ buf.append("thread_id INTEGER,");
+ buf.append("nickname TEXT,");
+ buf.append("body TEXT,");
+ buf.append("date INTEGER,");
+ buf.append("type INTEGER,");
+ buf.append("packet_id TEXT UNIQUE,");
+ buf.append("err_code INTEGER NOT NULL DEFAULT 0,");
+ buf.append("err_msg TEXT,");
+ buf.append("is_muc INTEGER");
+
+ if (addShowTsColumnForMessagesTable) {
+ buf.append(",show_ts INTEGER");
+ }
+
+ buf.append(");");
+
+ String sqlStatement = buf.toString();
+
+ if (DBG) log("create message table: " + sqlStatement);
+ db.execSQL(sqlStatement);
+
+ buf.delete(0, buf.length());
+ buf.append("CREATE TABLE IF NOT EXISTS ");
+ buf.append(TABLE_CHATS);
+ buf.append(" (_id INTEGER PRIMARY KEY,");
+ buf.append("contact_id INTEGER UNIQUE,");
+ buf.append("jid_resource TEXT,"); // the JID resource for the user, for non-group chats
+ buf.append("groupchat INTEGER,"); // 1 if group chat, 0 if not TODO: remove this column
+ buf.append("last_unread_message TEXT,"); // the last unread message
+ buf.append("last_message_date INTEGER,"); // in seconds
+ buf.append("unsent_composed_message TEXT,"); // a composed, but not sent message
+ buf.append("shortcut INTEGER);"); // which of 10 slots (if any) this chat occupies
+
+ // chat sessions, including single person chats and group chats
+ sqlStatement = buf.toString();
+
+ if (DBG) log("create chat table: " + sqlStatement);
+ db.execSQL(sqlStatement);
+
+ buf.delete(0, buf.length());
+ buf.append("CREATE TRIGGER IF NOT EXISTS contact_cleanup ");
+ buf.append("DELETE ON contacts ");
+ buf.append("BEGIN ");
+ buf.append("DELETE FROM ").append(TABLE_CHATS).append(" WHERE contact_id = OLD._id;");
+ buf.append("DELETE FROM ").append(TABLE_MESSAGES).append(" WHERE thread_id = OLD._id;");
+ buf.append("END");
+
+ sqlStatement = buf.toString();
+
+ if (DBG) log("create trigger: " + sqlStatement);
+ db.execSQL(sqlStatement);
+ }
+
+ private void createInMemoryMessageTables(SQLiteDatabase db, String tablePrefix) {
+ String tableName = (tablePrefix != null) ?
+ tablePrefix+TABLE_IN_MEMORY_MESSAGES : TABLE_IN_MEMORY_MESSAGES;
+
+ db.execSQL("CREATE TABLE IF NOT EXISTS " + tableName + " (" +
+ "_id INTEGER PRIMARY KEY," +
+ "thread_id INTEGER," +
+ "nickname TEXT," +
+ "body TEXT," +
+ "date INTEGER," + // in millisec
+ "type INTEGER," +
+ "packet_id TEXT UNIQUE," +
+ "err_code INTEGER NOT NULL DEFAULT 0," +
+ "err_msg TEXT," +
+ "is_muc INTEGER," +
+ "show_ts INTEGER" +
+ ");");
+
+ }
+
+ @Override
+ public void onOpen(SQLiteDatabase db) {
+ if (db.isReadOnly()) {
+ Log.w(LOG_TAG, "ImProvider database opened in read only mode.");
+ Log.w(LOG_TAG, "Transient tables not created.");
+ return;
+ }
+
+ if (DBG) log("##### createTransientTables");
+
+ // Create transient tables
+ String cpDbName;
+ db.execSQL("ATTACH DATABASE ':memory:' AS " + mTransientDbName + ";");
+ cpDbName = mTransientDbName + ".";
+
+ // in-memory message table
+ createInMemoryMessageTables(db, cpDbName);
+
+ // presence
+ db.execSQL("CREATE TABLE IF NOT EXISTS " + cpDbName + TABLE_PRESENCE + " ("+
+ "_id INTEGER PRIMARY KEY," +
+ "contact_id INTEGER UNIQUE," +
+ "jid_resource TEXT," + // jid resource for the presence
+ "client_type INTEGER," + // client type
+ "priority INTEGER," + // presence priority (XMPP)
+ "mode INTEGER," + // presence mode
+ "status TEXT" + // custom status
+ ");");
+
+ // group chat invitations
+ db.execSQL("CREATE TABLE IF NOT EXISTS " + cpDbName + TABLE_INVITATIONS + " (" +
+ "_id INTEGER PRIMARY KEY," +
+ "providerId INTEGER," +
+ "accountId INTEGER," +
+ "inviteId TEXT," +
+ "sender TEXT," +
+ "groupName TEXT," +
+ "note TEXT," +
+ "status INTEGER" +
+ ");");
+
+ // group chat members
+ db.execSQL("CREATE TABLE IF NOT EXISTS " + cpDbName + TABLE_GROUP_MEMBERS + " (" +
+ "_id INTEGER PRIMARY KEY," +
+ "groupId INTEGER," +
+ "username TEXT," +
+ "nickname TEXT" +
+ ");");
+
+ db.execSQL("CREATE TABLE IF NOT EXISTS " + cpDbName + TABLE_ACCOUNT_STATUS + " (" +
+ "_id INTEGER PRIMARY KEY," +
+ "account INTEGER UNIQUE," +
+ "presenceStatus INTEGER," +
+ "connStatus INTEGER" +
+ ");"
+ );
+
+ /* when we moved the contact table out of transient_db and into the main db, the
+ presence and groupchat cleanup triggers don't work anymore. It seems we can't
+ create triggers that reference objects in a different database!
+
+ // Insert a default presence for newly inserted contact
+ db.execSQL("CREATE TRIGGER IF NOT EXISTS contact_create_presence " +
+ "AFTER INSERT ON " + contactsTableName +
+ " WHEN NEW.type != " + Im.Contacts.TYPE_GROUP +
+ " BEGIN " +
+ "INSERT INTO presence (contact_id) VALUES (NEW._id);" +
+ " END");
+
+ // Remove the presence when the contact is removed.
+ db.execSQL("CREATE TRIGGER IF NOT EXISTS contact_presence_cleanup " +
+ "DELETE ON " + contactsTableName +
+ " BEGIN " +
+ "DELETE FROM presence WHERE contact_id = OLD._id;" +
+ "END");
+
+ // Cleans up group members and group messages when a group chat is deleted
+ db.execSQL("CREATE TRIGGER IF NOT EXISTS " + cpDbName + "group_cleanup " +
+ "DELETE ON " + cpDbName + contactsTableName +
+ " FOR EACH ROW WHEN OLD.type = " + Im.Contacts.TYPE_GROUP +
+ " BEGIN " +
+ "DELETE FROM groupMembers WHERE groupId = OLD._id;" +
+ "DELETE FROM groupMessages WHERE groupId = OLD._id;" +
+ " END");
+ */
+
+ // only store the session cookies in memory right now. This means
+ // that we don't persist them across device reboot
+ db.execSQL("CREATE TABLE IF NOT EXISTS " + cpDbName + TABLE_SESSION_COOKIES + " ("+
+ "_id INTEGER PRIMARY KEY," +
+ "provider INTEGER," +
+ "account INTEGER," +
+ "name TEXT," +
+ "value TEXT" +
+ ");");
+
+ }
+ }
+
+ static {
+ sProviderAccountsProjectionMap = new HashMap<String, String>();
+ sProviderAccountsProjectionMap.put(Imps.Provider._ID,
+ "providers._id AS _id");
+ sProviderAccountsProjectionMap.put(Imps.Provider._COUNT,
+ "COUNT(*) AS _account");
+ sProviderAccountsProjectionMap.put(Imps.Provider.NAME,
+ "providers.name AS name");
+ sProviderAccountsProjectionMap.put(Imps.Provider.FULLNAME,
+ "providers.fullname AS fullname");
+ sProviderAccountsProjectionMap.put(Imps.Provider.CATEGORY,
+ "providers.category AS category");
+ sProviderAccountsProjectionMap.put(Imps.Provider.ACTIVE_ACCOUNT_ID,
+ "accounts._id AS account_id");
+ sProviderAccountsProjectionMap.put(Imps.Provider.ACTIVE_ACCOUNT_USERNAME,
+ "accounts.username AS account_username");
+ sProviderAccountsProjectionMap.put(Imps.Provider.ACTIVE_ACCOUNT_PW,
+ "accounts.pw AS account_pw");
+ sProviderAccountsProjectionMap.put(Imps.Provider.ACTIVE_ACCOUNT_LOCKED,
+ "accounts.locked AS account_locked");
+ sProviderAccountsProjectionMap.put(Imps.Provider.ACTIVE_ACCOUNT_KEEP_SIGNED_IN,
+ "accounts.keep_signed_in AS account_keepSignedIn");
+ sProviderAccountsProjectionMap.put(Imps.Provider.ACCOUNT_PRESENCE_STATUS,
+ "accountStatus.presenceStatus AS account_presenceStatus");
+ sProviderAccountsProjectionMap.put(Imps.Provider.ACCOUNT_CONNECTION_STATUS,
+ "accountStatus.connStatus AS account_connStatus");
+
+ // contacts projection map
+ sContactsProjectionMap = new HashMap<String, String>();
+
+ // Base column
+ sContactsProjectionMap.put(Imps.Contacts._ID, "contacts._id AS _id");
+ sContactsProjectionMap.put(Imps.Contacts._COUNT, "COUNT(*) AS _count");
+
+ // contacts column
+ sContactsProjectionMap.put(Imps.Contacts._ID, "contacts._id as _id");
+ sContactsProjectionMap.put(Imps.Contacts.USERNAME, "contacts.username as username");
+ sContactsProjectionMap.put(Imps.Contacts.NICKNAME, "contacts.nickname as nickname");
+ sContactsProjectionMap.put(Imps.Contacts.PROVIDER, "contacts.provider as provider");
+ sContactsProjectionMap.put(Imps.Contacts.ACCOUNT, "contacts.account as account");
+ sContactsProjectionMap.put(Imps.Contacts.CONTACTLIST, "contacts.contactList as contactList");
+ sContactsProjectionMap.put(Imps.Contacts.TYPE, "contacts.type as type");
+ sContactsProjectionMap.put(Imps.Contacts.SUBSCRIPTION_STATUS,
+ "contacts.subscriptionStatus as subscriptionStatus");
+ sContactsProjectionMap.put(Imps.Contacts.SUBSCRIPTION_TYPE,
+ "contacts.subscriptionType as subscriptionType");
+ sContactsProjectionMap.put(Imps.Contacts.QUICK_CONTACT, "contacts.qc as qc");
+ sContactsProjectionMap.put(Imps.Contacts.REJECTED, "contacts.rejected as rejected");
+
+ // Presence columns
+ sContactsProjectionMap.put(Imps.Presence.CONTACT_ID,
+ "presence.contact_id AS contact_id");
+ sContactsProjectionMap.put(Imps.Contacts.PRESENCE_STATUS,
+ "presence.mode AS mode");
+ sContactsProjectionMap.put(Imps.Contacts.PRESENCE_CUSTOM_STATUS,
+ "presence.status AS status");
+ sContactsProjectionMap.put(Imps.Contacts.CLIENT_TYPE,
+ "presence.client_type AS client_type");
+
+ // Chats columns
+ sContactsProjectionMap.put(Imps.Contacts.CHATS_CONTACT,
+ "chats.contact_id AS chats_contact_id");
+ sContactsProjectionMap.put(Imps.Chats.JID_RESOURCE,
+ "chats.jid_resource AS jid_resource");
+ sContactsProjectionMap.put(Imps.Chats.GROUP_CHAT,
+ "chats.groupchat AS groupchat");
+ sContactsProjectionMap.put(Imps.Contacts.LAST_UNREAD_MESSAGE,
+ "chats.last_unread_message AS last_unread_message");
+ sContactsProjectionMap.put(Imps.Contacts.LAST_MESSAGE_DATE,
+ "chats.last_message_date AS last_message_date");
+ sContactsProjectionMap.put(Imps.Contacts.UNSENT_COMPOSED_MESSAGE,
+ "chats.unsent_composed_message AS unsent_composed_message");
+ sContactsProjectionMap.put(Imps.Contacts.SHORTCUT, "chats.SHORTCUT AS shortcut");
+
+ // Avatars columns
+ sContactsProjectionMap.put(Imps.Contacts.AVATAR_HASH, "avatars.hash AS avatars_hash");
+ sContactsProjectionMap.put(Imps.Contacts.AVATAR_DATA, "avatars.data AS avatars_data");
+
+ // contactList projection map
+ sContactListProjectionMap = new HashMap<String, String>();
+ sContactListProjectionMap.put(Imps.ContactList._ID, "contactList._id AS _id");
+ sContactListProjectionMap.put(Imps.ContactList._COUNT, "COUNT(*) AS _count");
+ sContactListProjectionMap.put(Imps.ContactList.NAME, "name");
+ sContactListProjectionMap.put(Imps.ContactList.PROVIDER, "provider");
+ sContactListProjectionMap.put(Imps.ContactList.ACCOUNT, "account");
+
+ // blockedList projection map
+ sBlockedListProjectionMap = new HashMap<String, String>();
+ sBlockedListProjectionMap.put(Imps.BlockedList._ID, "blockedList._id AS _id");
+ sBlockedListProjectionMap.put(Imps.BlockedList._COUNT, "COUNT(*) AS _count");
+ sBlockedListProjectionMap.put(Imps.BlockedList.USERNAME, "username");
+ sBlockedListProjectionMap.put(Imps.BlockedList.NICKNAME, "nickname");
+ sBlockedListProjectionMap.put(Imps.BlockedList.PROVIDER, "provider");
+ sBlockedListProjectionMap.put(Imps.BlockedList.ACCOUNT, "account");
+ sBlockedListProjectionMap.put(Imps.BlockedList.AVATAR_DATA,
+ "avatars.data AS avatars_data");
+
+ // messages projection map
+ sMessagesProjectionMap = new HashMap<String, String>();
+ sMessagesProjectionMap.put(Imps.Messages._ID, "messages._id AS _id");
+ sMessagesProjectionMap.put(Imps.Messages._COUNT, "COUNT(*) AS _count");
+ sMessagesProjectionMap.put(Imps.Messages.THREAD_ID, "messages.thread_id AS thread_id");
+ sMessagesProjectionMap.put(Imps.Messages.PACKET_ID, "messages.packet_id AS packet_id");
+ sMessagesProjectionMap.put(Imps.Messages.NICKNAME, "messages.nickname AS nickname");
+ sMessagesProjectionMap.put(Imps.Messages.BODY, "messages.body AS body");
+ sMessagesProjectionMap.put(Imps.Messages.DATE, "messages.date AS date");
+ sMessagesProjectionMap.put(Imps.Messages.TYPE, "messages.type AS type");
+ sMessagesProjectionMap.put(Imps.Messages.ERROR_CODE, "messages.err_code AS err_code");
+ sMessagesProjectionMap.put(Imps.Messages.ERROR_MESSAGE, "messages.err_msg AS err_msg");
+ sMessagesProjectionMap.put(Imps.Messages.IS_GROUP_CHAT, "messages.is_muc AS is_muc");
+ sMessagesProjectionMap.put(Imps.Messages.DISPLAY_SENT_TIME, "messages.show_ts AS show_ts");
+ // contacts columns
+ sMessagesProjectionMap.put(Imps.Messages.CONTACT, "contacts.username AS contact");
+ sMessagesProjectionMap.put(Imps.Contacts.PROVIDER, "contacts.provider AS provider");
+ sMessagesProjectionMap.put(Imps.Contacts.ACCOUNT, "contacts.account AS account");
+ sMessagesProjectionMap.put("contact_type", "contacts.type AS contact_type");
+
+ sInMemoryMessagesProjectionMap = new HashMap<String, String>();
+ sInMemoryMessagesProjectionMap.put(Imps.Messages._ID,
+ "inMemoryMessages._id AS _id");
+ sInMemoryMessagesProjectionMap.put(Imps.Messages._COUNT,
+ "COUNT(*) AS _count");
+ sInMemoryMessagesProjectionMap.put(Imps.Messages.THREAD_ID,
+ "inMemoryMessages.thread_id AS thread_id");
+ sInMemoryMessagesProjectionMap.put(Imps.Messages.PACKET_ID,
+ "inMemoryMessages.packet_id AS packet_id");
+ sInMemoryMessagesProjectionMap.put(Imps.Messages.NICKNAME,
+ "inMemoryMessages.nickname AS nickname");
+ sInMemoryMessagesProjectionMap.put(Imps.Messages.BODY,
+ "inMemoryMessages.body AS body");
+ sInMemoryMessagesProjectionMap.put(Imps.Messages.DATE,
+ "inMemoryMessages.date AS date");
+ sInMemoryMessagesProjectionMap.put(Imps.Messages.TYPE,
+ "inMemoryMessages.type AS type");
+ sInMemoryMessagesProjectionMap.put(Imps.Messages.ERROR_CODE,
+ "inMemoryMessages.err_code AS err_code");
+ sInMemoryMessagesProjectionMap.put(Imps.Messages.ERROR_MESSAGE,
+ "inMemoryMessages.err_msg AS err_msg");
+ sInMemoryMessagesProjectionMap.put(Imps.Messages.IS_GROUP_CHAT,
+ "inMemoryMessages.is_muc AS is_muc");
+ sInMemoryMessagesProjectionMap.put(Imps.Messages.DISPLAY_SENT_TIME,
+ "inMemoryMessages.show_ts AS show_ts");
+ // contacts columns
+ sInMemoryMessagesProjectionMap.put(Imps.Messages.CONTACT, "contacts.username AS contact");
+ sInMemoryMessagesProjectionMap.put(Imps.Contacts.PROVIDER, "contacts.provider AS provider");
+ sInMemoryMessagesProjectionMap.put(Imps.Contacts.ACCOUNT, "contacts.account AS account");
+ sInMemoryMessagesProjectionMap.put("contact_type", "contacts.type AS contact_type");
+ }
+
+ public ImpsProvider() {
+ this(DATABASE_NAME, DATABASE_VERSION);
+
+ setupImUrlMatchers(AUTHORITY);
+ setupMcsUrlMatchers(AUTHORITY);
+ }
+
+ protected ImpsProvider(String dbName, int dbVersion) {
+ mDatabaseName = dbName;
+ mDatabaseVersion = dbVersion;
+ mTransientDbName = "transient_" + dbName.replace(".", "_");
+ }
+
+ private void setupImUrlMatchers(String authority) {
+ 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, "messagesByAcctAndContact/#/*", MATCH_MESSAGES_BY_CONTACT);
+ mUrlMatcher.addURI(authority, "messagesByThreadId/#", MATCH_MESSAGES_BY_THREAD_ID);
+ mUrlMatcher.addURI(authority, "messagesByProvider/#", MATCH_MESSAGES_BY_PROVIDER);
+ mUrlMatcher.addURI(authority, "messagesByAccount/#", MATCH_MESSAGES_BY_ACCOUNT);
+ mUrlMatcher.addURI(authority, "messages/#", MATCH_MESSAGE);
+
+ mUrlMatcher.addURI(authority, "otrMessages", MATCH_OTR_MESSAGES);
+ mUrlMatcher.addURI(authority, "otrMessagesByAcctAndContact/#/*",
+ MATCH_OTR_MESSAGES_BY_CONTACT);
+ mUrlMatcher.addURI(authority, "otrMessagesByThreadId/#", MATCH_OTR_MESSAGES_BY_THREAD_ID);
+ mUrlMatcher.addURI(authority, "otrMessagesByProvider/#", MATCH_OTR_MESSAGES_BY_PROVIDER);
+ mUrlMatcher.addURI(authority, "otrMessagesByAccount/#", MATCH_OTR_MESSAGES_BY_ACCOUNT);
+ mUrlMatcher.addURI(authority, "otrMessages/#", MATCH_OTR_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, "accountStatus", MATCH_ACCOUNTS_STATUS);
+ mUrlMatcher.addURI(authority, "accountStatus/#", MATCH_ACCOUNT_STATUS);
+
+ mUrlMatcher.addURI(authority, "brandingResMapCache", MATCH_BRANDING_RESOURCE_MAP_CACHE);
+ }
+
+ private void setupMcsUrlMatchers(String authority) {
+ 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, "s2dids", MATCH_S2D_RMQ_IDS);
+ }
+
+ @Override
+ public boolean onCreate() {
+ mOpenHelper = new DatabaseHelper(getContext());
+ return true;
+ }
+
+ @Override
+ public final int update(final Uri url, final ContentValues values,
+ final String selection, final 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;
+ }
+
+ @Override
+ public final int delete(final Uri url, final String selection,
+ final 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;
+ }
+
+ @Override
+ public final Uri insert(final Uri url, final 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;
+ }
+
+ @Override
+ public final Cursor query(final Uri url, final String[] projection,
+ final String selection, final String[] selectionArgs,
+ final String sortOrder) {
+ return queryInternal(url, projection, selection, selectionArgs, sortOrder);
+ }
+
+ public Cursor queryInternal(Uri url, String[] projectionIn,
+ String selection, String[] selectionArgs, 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, Imps.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, Imps.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, Imps.Contacts.PRESENCE_STATUS, "!=", Imps.Presence.OFFLINE);
+ appendWhere(whereClause, NON_BLOCKED_CONTACTS_WHERE_CLAUSE);
+ break;
+
+ case MATCH_OFFLINE_CONTACTS_BY_PROVIDER:
+ buildQueryContactsByProvider(qb, whereClause, url);
+ appendWhere(whereClause, Imps.Contacts.PRESENCE_STATUS, "=", Imps.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, Imps.Contacts.PRESENCE_STATUS, "!=", Imps.Presence.OFFLINE);
+ appendWhere(whereClause, "chats.last_message_date IS NULL");
+ appendWhere(whereClause, NON_BLOCKED_CONTACTS_WHERE_CLAUSE);
+ groupBy = Imps.Contacts.CONTACTLIST;
+ break;
+
+ case MATCH_CONTACTLISTS_BY_PROVIDER:
+ appendWhere(whereClause, Imps.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, Imps.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, Imps.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_BY_THREAD_ID:
+ appendWhere(whereClause, Imps.Messages.THREAD_ID, "=", url.getPathSegments().get(1));
+ // fall thru.
+
+ case MATCH_MESSAGES:
+ qb.setTables(TABLE_MESSAGES);
+
+ final String selectionClause = whereClause.toString();
+ final String query1 = qb.buildQuery(projectionIn, selectionClause,
+ null, null, null, null, null /* limit */);
+
+ // Build the second query for frequent
+ qb = new SQLiteQueryBuilder();
+ qb.setTables(TABLE_IN_MEMORY_MESSAGES);
+ final String query2 = qb.buildQuery(projectionIn,
+ selectionClause, null, null, null, null, null /* limit */);
+
+ // Put them together
+ final String query = qb.buildUnionQuery(new String[] {query1, query2}, sort, null);
+ final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+ Cursor c = db.rawQueryWithFactory(null, query, null, TABLE_MESSAGES);
+ if ((c != null) && !isTemporary()) {
+ c.setNotificationUri(getContext().getContentResolver(), url);
+ }
+ return c;
+
+ case MATCH_MESSAGE:
+ qb.setTables(TABLE_MESSAGES);
+ appendWhere(whereClause, Imps.Messages._ID, "=", url.getPathSegments().get(1));
+ break;
+
+ case MATCH_MESSAGES_BY_CONTACT:
+ qb.setTables(MESSAGE_JOIN_CONTACT_TABLE);
+ qb.setProjectionMap(sMessagesProjectionMap);
+
+ appendWhere(whereClause, Imps.Contacts.ACCOUNT, "=", url.getPathSegments().get(1));
+ appendWhere(whereClause, "contacts.username", "=",
+ decodeURLSegment(url.getPathSegments().get(2)));
+
+ final String sel = whereClause.toString();
+ final String q1 = qb.buildQuery(projectionIn, sel, null, null, null, null, null);
+
+ // Build the second query for frequent
+ qb = new SQLiteQueryBuilder();
+ qb.setTables(IN_MEMORY_MESSAGES_JOIN_CONTACT_TABLE);
+ qb.setProjectionMap(sInMemoryMessagesProjectionMap);
+ final String q2 = qb.buildQuery(projectionIn, sel, null, null, null, null, null);
+
+ // Put them together
+ final String q3 = qb.buildUnionQuery(new String[] {q1, q2}, sort, null);
+ final SQLiteDatabase db2 = mOpenHelper.getWritableDatabase();
+ Cursor c2 = db2.rawQueryWithFactory(null, q3, null, MESSAGE_JOIN_CONTACT_TABLE);
+ if ((c2 != null) && !isTemporary()) {
+ c2.setNotificationUri(getContext().getContentResolver(), url);
+ }
+ return c2;
+
+ case MATCH_INVITATIONS:
+ qb.setTables(TABLE_INVITATIONS);
+ break;
+
+ case MATCH_INVITATION:
+ qb.setTables(TABLE_INVITATIONS);
+ appendWhere(whereClause, Imps.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, Imps.GroupMembers.GROUP, "=", url.getPathSegments().get(1));
+ break;
+
+ case MATCH_AVATARS:
+ qb.setTables(TABLE_AVATARS);
+ break;
+
+ case MATCH_AVATAR_BY_PROVIDER:
+ qb.setTables(TABLE_AVATARS);
+ appendWhere(whereClause, Imps.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, Imps.Chats.CONTACT_ID, "=", url.getPathSegments().get(1));
+ break;
+
+ case MATCH_CHATS_BY_ACCOUNT:
+ qb.setTables(TABLE_CHATS);
+ String accountStr = decodeURLSegment(url.getLastPathSegment());
+ appendWhere(whereClause, buildContactIdSelection(Imps.Chats.CONTACT_ID,
+ Imps.Contacts.ACCOUNT + "='" + accountStr + "'"));
+ break;
+
+ case MATCH_PRESENCE:
+ qb.setTables(TABLE_PRESENCE);
+ break;
+
+ case MATCH_PRESENCE_ID:
+ qb.setTables(TABLE_PRESENCE);
+ appendWhere(whereClause, Imps.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, Imps.SessionCookies.ACCOUNT, "=", url.getPathSegments().get(2));
+ break;
+
+ case MATCH_PROVIDER_SETTINGS_BY_ID_AND_NAME:
+ appendWhere(whereClause, Imps.ProviderSettings.NAME, "=", url.getPathSegments().get(2));
+ // fall through
+ case MATCH_PROVIDER_SETTINGS_BY_ID:
+ appendWhere(whereClause, Imps.ProviderSettings.PROVIDER, "=", url.getPathSegments().get(1));
+ // fall through
+ case MATCH_PROVIDER_SETTINGS:
+ qb.setTables(TABLE_PROVIDER_SETTINGS);
+ break;
+
+ case MATCH_ACCOUNTS_STATUS:
+ qb.setTables(TABLE_ACCOUNT_STATUS);
+ break;
+
+ case MATCH_ACCOUNT_STATUS:
+ qb.setTables(TABLE_ACCOUNT_STATUS);
+ appendWhere(whereClause, Imps.AccountStatus.ACCOUNT, "=",
+ url.getPathSegments().get(1));
+ break;
+
+ case MATCH_BRANDING_RESOURCE_MAP_CACHE:
+ qb.setTables(TABLE_BRANDING_RESOURCE_MAP_CACHE);
+ break;
+
+ // mcs and rmq queries
+ 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_S2D_RMQ_IDS:
+ qb.setTables(TABLE_S2D_RMQ_IDS);
+ 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 = Imps.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 buildQueryContactsByProvider(SQLiteQueryBuilder qb,
+ StringBuilder whereClause, 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, Imps.Contacts.ACCOUNT, "=", url.getLastPathSegment());
+ }
+
+ @Override
+ public String getType(Uri url) {
+ int match = mUrlMatcher.match(url);
+ switch (match) {
+ case MATCH_PROVIDERS:
+ return Imps.Provider.CONTENT_TYPE;
+
+ case MATCH_PROVIDERS_BY_ID:
+ return Imps.Provider.CONTENT_ITEM_TYPE;
+
+ case MATCH_ACCOUNTS:
+ return Imps.Account.CONTENT_TYPE;
+
+ case MATCH_ACCOUNTS_BY_ID:
+ return Imps.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 Imps.Contacts.CONTENT_TYPE;
+
+ case MATCH_CONTACT:
+ return Imps.Contacts.CONTENT_ITEM_TYPE;
+
+ case MATCH_CONTACTLISTS:
+ case MATCH_CONTACTLISTS_BY_PROVIDER:
+ return Imps.ContactList.CONTENT_TYPE;
+
+ case MATCH_CONTACTLIST:
+ return Imps.ContactList.CONTENT_ITEM_TYPE;
+
+ case MATCH_BLOCKEDLIST:
+ case MATCH_BLOCKEDLIST_BY_PROVIDER:
+ return Imps.BlockedList.CONTENT_TYPE;
+
+ case MATCH_CONTACTS_ETAGS:
+ case MATCH_CONTACTS_ETAG:
+ return Imps.ContactsEtag.CONTENT_TYPE;
+
+ case MATCH_MESSAGES:
+ case MATCH_MESSAGES_BY_CONTACT:
+ case MATCH_MESSAGES_BY_THREAD_ID:
+ case MATCH_MESSAGES_BY_PROVIDER:
+ case MATCH_MESSAGES_BY_ACCOUNT:
+ case MATCH_OTR_MESSAGES:
+ case MATCH_OTR_MESSAGES_BY_CONTACT:
+ case MATCH_OTR_MESSAGES_BY_THREAD_ID:
+ case MATCH_OTR_MESSAGES_BY_PROVIDER:
+ case MATCH_OTR_MESSAGES_BY_ACCOUNT:
+ return Imps.Messages.CONTENT_TYPE;
+
+ case MATCH_MESSAGE:
+ case MATCH_OTR_MESSAGE:
+ return Imps.Messages.CONTENT_ITEM_TYPE;
+
+ case MATCH_PRESENCE:
+ case MATCH_PRESENCE_BULK:
+ return Imps.Presence.CONTENT_TYPE;
+
+ case MATCH_AVATARS:
+ return Imps.Avatars.CONTENT_TYPE;
+
+ case MATCH_AVATAR:
+ return Imps.Avatars.CONTENT_ITEM_TYPE;
+
+ case MATCH_CHATS:
+ return Imps.Chats.CONTENT_TYPE;
+
+ case MATCH_CHATS_ID:
+ return Imps.Chats.CONTENT_ITEM_TYPE;
+
+ case MATCH_INVITATIONS:
+ return Imps.Invitation.CONTENT_TYPE;
+
+ case MATCH_INVITATION:
+ return Imps.Invitation.CONTENT_ITEM_TYPE;
+
+ case MATCH_GROUP_MEMBERS:
+ case MATCH_GROUP_MEMBERS_BY_GROUP:
+ return Imps.GroupMembers.CONTENT_TYPE;
+
+ case MATCH_SESSIONS:
+ case MATCH_SESSIONS_BY_PROVIDER:
+ return Imps.SessionCookies.CONTENT_TYPE;
+
+ case MATCH_PROVIDER_SETTINGS:
+ return Imps.ProviderSettings.CONTENT_TYPE;
+
+ case MATCH_ACCOUNTS_STATUS:
+ return Imps.AccountStatus.CONTENT_TYPE;
+
+ case MATCH_ACCOUNT_STATUS:
+ return Imps.AccountStatus.CONTENT_ITEM_TYPE;
+
+ default:
+ throw new IllegalArgumentException("Unknown URL");
+ }
+ }
+
+ // package scope for testing.
+ boolean insertBulkContacts(ContentValues values) {
+ //if (DBG) log("insertBulkContacts: begin");
+
+ ArrayList<String> usernames = values.getStringArrayList(Imps.Contacts.USERNAME);
+ ArrayList<String> nicknames = values.getStringArrayList(Imps.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(Imps.Contacts.TYPE);
+ ArrayList<String> subscriptionStatusArray =
+ values.getStringArrayList(Imps.Contacts.SUBSCRIPTION_STATUS);
+ ArrayList<String> subscriptionTypeArray =
+ values.getStringArrayList(Imps.Contacts.SUBSCRIPTION_TYPE);
+ ArrayList<String> quickContactArray = values.getStringArrayList(Imps.Contacts.QUICK_CONTACT);
+ ArrayList<String> rejectedArray = values.getStringArrayList(Imps.Contacts.REJECTED);
+ int sum = 0;
+
+ final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+
+ db.beginTransaction();
+ try {
+ Long provider = values.getAsLong(Imps.Contacts.PROVIDER);
+ Long account = values.getAsLong(Imps.Contacts.ACCOUNT);
+ Long listId = values.getAsLong(Imps.Contacts.CONTACTLIST);
+
+ ContentValues contactValues = new ContentValues();
+ contactValues.put(Imps.Contacts.PROVIDER, provider);
+ contactValues.put(Imps.Contacts.ACCOUNT, account);
+ contactValues.put(Imps.Contacts.CONTACTLIST, listId);
+ ContentValues presenceValues = new ContentValues();
+ presenceValues.put(Imps.Presence.PRESENCE_STATUS,
+ Imps.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(Imps.Contacts.USERNAME, username);
+ contactValues.put(Imps.Contacts.NICKNAME, nickname);
+ contactValues.put(Imps.Contacts.TYPE, type);
+ if (subscriptionStatusArray != null) {
+ contactValues.put(Imps.Contacts.SUBSCRIPTION_STATUS, subscriptionStatus);
+ }
+ if (subscriptionTypeArray != null) {
+ contactValues.put(Imps.Contacts.SUBSCRIPTION_TYPE, subscriptionType);
+ }
+ if (quickContactArray != null) {
+ contactValues.put(Imps.Contacts.QUICK_CONTACT, quickContact);
+ }
+ if (rejectedArray != null) {
+ contactValues.put(Imps.Contacts.REJECTED, rejected);
+ }
+
+ long rowId;
+
+ /* 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++;
+
+ // seed the presence for the new contact
+ if (DBG) log("### seedPresence for contact id " + rowId);
+ presenceValues.put(Imps.Presence.CONTACT_ID, rowId);
+
+ try {
+ db.insert(TABLE_PRESENCE, null, presenceValues);
+ } catch (android.database.sqlite.SQLiteConstraintException ex) {
+ Log.w(LOG_TAG, "insertBulkContacts: seeding presence caught " + ex);
+ }
+ }
+
+ // 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;
+ }
+
+ // package scope for testing.
+ int updateBulkContacts(ContentValues values, String userWhere) {
+ ArrayList<String> usernames = values.getStringArrayList(Imps.Contacts.USERNAME);
+ ArrayList<String> nicknames = values.getStringArrayList(Imps.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(Imps.Contacts.TYPE);
+ ArrayList<String> subscriptionStatusArray =
+ values.getStringArrayList(Imps.Contacts.SUBSCRIPTION_STATUS);
+ ArrayList<String> subscriptionTypeArray =
+ values.getStringArrayList(Imps.Contacts.SUBSCRIPTION_TYPE);
+ ArrayList<String> quickContactArray = values.getStringArrayList(Imps.Contacts.QUICK_CONTACT);
+ ArrayList<String> rejectedArray = values.getStringArrayList(Imps.Contacts.REJECTED);
+ final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+
+ db.beginTransaction();
+ int sum = 0;
+
+ try {
+ Long provider = values.getAsLong(Imps.Contacts.PROVIDER);
+ Long account = values.getAsLong(Imps.Contacts.ACCOUNT);
+
+ ContentValues contactValues = new ContentValues();
+ contactValues.put(Imps.Contacts.PROVIDER, provider);
+ contactValues.put(Imps.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(Imps.Contacts.USERNAME, username);
+ contactValues.put(Imps.Contacts.NICKNAME, nickname);
+ contactValues.put(Imps.Contacts.TYPE, type);
+ contactValues.put(Imps.Contacts.SUBSCRIPTION_STATUS, subscriptionStatus);
+ contactValues.put(Imps.Contacts.SUBSCRIPTION_TYPE, subscriptionType);
+ contactValues.put(Imps.Contacts.QUICK_CONTACT, quickContact);
+ contactValues.put(Imps.Contacts.REJECTED, rejected);
+
+ // append username to the selection clause
+ updateSelection.delete(0, updateSelection.length());
+ updateSelection.append(userWhere);
+ updateSelection.append(" AND ");
+ updateSelection.append(Imps.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;
+ }
+
+ /**
+ * make sure the presence for all contacts of a given account is set to offline, and
+ * each contact has a presence row associated with it. However, this method does not remove
+ * presences for which the corresponding contacts no longer exist. That's probably ok since
+ * presence is kept in memory, so it won't stay around for too long. Here is the algorithm.
+ *
+ * 1. for all presence that have a corresponding contact, make it OFFLINE. This is one sqlite
+ * call.
+ * 2. query for all the contacts that don't have a presence, and add a presence row for them.
+ *
+ * TODO simplify the presence management! The desire is to have a presence row for each
+ * TODO contact in the database, so later we can just call update() on the presence rows
+ * TODO instead of checking for the existence of presence first. The assumption is we get
+ * TODO presence updates much more frequently. However, the logic to maintain that goal is
+ * TODO overly complicated. One possible solution is to use insert_or_replace the presence rows
+ * TODO when updating the presence. That way we don't always need to maintain an empty presence
+ * TODO row for each contact.
+ *
+ * @param account the account of the contacts for which we want to create seed presence rows.
+ */
+ private void seedInitialPresenceByAccount(long account) {
+ SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
+ qb.setTables(TABLE_CONTACTS);
+ qb.setProjectionMap(sContactsProjectionMap);
+
+ mQueryContactIdSelectionArgs1[0] = String.valueOf(account);
+
+ final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+ db.beginTransaction();
+
+ Cursor c = null;
+
+ try {
+ ContentValues presenceValues = new ContentValues();
+ presenceValues.put(Imps.Presence.PRESENCE_STATUS, Imps.Presence.OFFLINE);
+ presenceValues.put(Imps.Presence.PRESENCE_CUSTOM_STATUS, "");
+
+ // update all the presence for the account so they are offline
+ StringBuilder buf = new StringBuilder();
+ buf.append(Imps.Presence.CONTACT_ID);
+ buf.append(" in (select ");
+ buf.append(Imps.Contacts._ID);
+ buf.append(" from ");
+ buf.append(TABLE_CONTACTS);
+ buf.append(" where ");
+ buf.append(Imps.Contacts.ACCOUNT);
+ buf.append("=?) ");
+
+ String selection = buf.toString();
+ if (DBG) log("seedInitialPresence: reset presence selection=" + selection);
+
+ int count = db.update(TABLE_PRESENCE, presenceValues, selection,
+ mQueryContactIdSelectionArgs1);
+ if (DBG) log("seedInitialPresence: reset " + count + " presence rows to OFFLINE");
+
+ // for in-memory presence table, add a presence row for each contact that
+ // doesn't have a presence. in-memory presence table isn't reliable, and goes away
+ // when device reboot or IMProvider process dies, so we can't rely on each contact
+ // have a corresponding 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,
+ mQueryContactIdSelectionArgs1,
+ null, null, null, null);
+
+ if (DBG) log("seedInitialPresence: found " + c.getCount() + " contacts w/o presence");
+
+ count = 0;
+
+ while (c.moveToNext()) {
+ long id = c.getLong(CONTACT_ID_COLUMN);
+ presenceValues.put(Imps.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);
+ }
+ }
+
+ if (DBG) log("seedInitialPresence: added " + count + " new presence rows");
+
+ db.setTransactionSuccessful();
+ } finally {
+ if (c != null) {
+ c.close();
+ }
+ db.endTransaction();
+ }
+ }
+
+ private int updateBulkPresence(ContentValues values, String userWhere, String[] whereArgs) {
+ ArrayList<String> usernames = values.getStringArrayList(Imps.Contacts.USERNAME);
+ int count = usernames.size();
+ Long account = values.getAsLong(Imps.Contacts.ACCOUNT);
+
+ ArrayList<String> priorityArray = values.getStringArrayList(Imps.Presence.PRIORITY);
+ ArrayList<String> modeArray = values.getStringArrayList(Imps.Presence.PRESENCE_STATUS);
+ ArrayList<String> statusArray = values.getStringArrayList(
+ Imps.Presence.PRESENCE_CUSTOM_STATUS);
+ ArrayList<String> clientTypeArray = values.getStringArrayList(Imps.Presence.CLIENT_TYPE);
+ ArrayList<String> resourceArray = values.getStringArrayList(Imps.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(Imps.Presence.CONTACT_ID);
+ buf.append(" in (select ");
+ buf.append(Imps.Contacts._ID);
+ buf.append(" from ");
+ buf.append(TABLE_CONTACTS);
+ buf.append(" where ");
+ buf.append(Imps.Contacts.ACCOUNT);
+ buf.append("=? AND ");
+
+ // use username LIKE ? for case insensitive comparison
+ buf.append(Imps.Contacts.USERNAME);
+ buf.append(" LIKE ?) AND (");
+
+ buf.append(Imps.Presence.PRIORITY);
+ buf.append("<=? OR ");
+ buf.append(Imps.Presence.PRIORITY);
+ buf.append(" IS NULL OR ");
+ buf.append(Imps.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 = Imps.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(Imps.Presence.PRESENCE_STATUS, mode);
+ }
+ if (priorityArray != null) {
+ presenceValues.put(Imps.Presence.PRIORITY, priority);
+ }
+ presenceValues.put(Imps.Presence.PRESENCE_CUSTOM_STATUS, status);
+ if (clientTypeArray != null) {
+ presenceValues.put(Imps.Presence.CLIENT_TYPE, clientType);
+ }
+
+ if (!TextUtils.isEmpty(jidResource)) {
+ presenceValues.put(Imps.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;
+ }
+
+ private Uri insertInternal(Uri url, ContentValues initialValues) {
+ Uri resultUri = null;
+ long rowID = 0;
+ long account = 0;
+ String contact = null;
+ long threadId = 0;
+
+ boolean notifyContactListContentUri = false;
+ boolean notifyContactContentUri = false;
+ boolean notifyMessagesContentUri = false;
+ boolean notifyMessagesByContactContentUri = false;
+ boolean notifyMessagesByThreadIdContentUri = 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(Imps.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(Imps.Account.CONTENT_URI + "/" + rowID);
+ }
+ notifyProviderAccountContentUri = true;
+ break;
+
+ case MATCH_CONTACTS_BY_PROVIDER:
+ appendValuesFromUrl(initialValues, url, Imps.Contacts.PROVIDER,
+ Imps.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(Imps.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 = Imps.Contacts.CONTENT_URI;
+ }
+ notifyContactContentUri = true;
+ break;
+
+ case MATCH_CONTACTLISTS_BY_PROVIDER:
+ appendValuesFromUrl(initialValues, url, Imps.ContactList.PROVIDER,
+ Imps.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(Imps.ContactList.CONTENT_URI + "/" + rowID);
+ }
+ notifyContactListContentUri = true;
+ break;
+
+ case MATCH_BLOCKEDLIST_BY_PROVIDER:
+ appendValuesFromUrl(initialValues, url, Imps.BlockedList.PROVIDER,
+ Imps.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(Imps.BlockedList.CONTENT_URI + "/" + rowID);
+ }
+
+ break;
+
+ case MATCH_CONTACTS_ETAGS:
+ rowID = db.replace(TABLE_CONTACTS_ETAG, Imps.ContactsEtag.ETAG, initialValues);
+ if (rowID > 0) {
+ resultUri = Uri.parse(Imps.ContactsEtag.CONTENT_URI + "/" + rowID);
+ }
+ break;
+
+ case MATCH_MESSAGES_BY_CONTACT:
+ String accountStr = decodeURLSegment(url.getPathSegments().get(1));
+ try {
+ account = Long.parseLong(accountStr);
+ } catch (NumberFormatException ex) {
+ throw new IllegalArgumentException();
+ }
+
+ contact = decodeURLSegment(url.getPathSegments().get(2));
+ initialValues.put(Imps.Messages.THREAD_ID, getContactId(db, accountStr, contact));
+
+ notifyMessagesContentUri = true;
+
+ // Insert into the messages table.
+ rowID = db.insert(TABLE_MESSAGES, "thread_id", initialValues);
+ if (rowID > 0) {
+ resultUri = Uri.parse(Imps.Messages.CONTENT_URI + "/" + rowID);
+ }
+
+ break;
+
+ case MATCH_MESSAGES_BY_THREAD_ID:
+ appendValuesFromUrl(initialValues, url, Imps.Messages.THREAD_ID);
+ // fall through
+
+ case MATCH_MESSAGES:
+ // Insert into the messages table.
+ notifyMessagesContentUri = true;
+ rowID = db.insert(TABLE_MESSAGES, "thread_id", initialValues);
+ if (rowID > 0) {
+ resultUri = Uri.parse(Imps.Messages.CONTENT_URI + "/" + rowID);
+ }
+
+ break;
+
+ case MATCH_OTR_MESSAGES_BY_CONTACT:
+ String accountStr2 = decodeURLSegment(url.getPathSegments().get(1));
+
+ try {
+ account = Long.parseLong(accountStr2);
+ } catch (NumberFormatException ex) {
+ throw new IllegalArgumentException();
+ }
+
+ contact = decodeURLSegment(url.getPathSegments().get(2));
+ initialValues.put(Imps.Messages.THREAD_ID, getContactId(db, accountStr2, contact));
+
+ notifyMessagesByContactContentUri = true;
+
+ // Insert into the in-memory messages table.
+ rowID = db.insert(TABLE_IN_MEMORY_MESSAGES, "thread_id", initialValues);
+ if (rowID > 0) {
+ resultUri = Uri.parse(Imps.Messages.OTR_MESSAGES_CONTENT_URI + "/" + rowID);
+ }
+
+ break;
+
+ case MATCH_OTR_MESSAGES_BY_THREAD_ID:
+ try {
+ threadId = Long.parseLong(decodeURLSegment(url.getPathSegments().get(1)));
+ } catch (NumberFormatException ex) {
+ throw new IllegalArgumentException();
+ }
+
+ initialValues.put(Imps.Messages.THREAD_ID, threadId);
+
+ notifyMessagesByThreadIdContentUri = true;
+ // fall through
+
+ case MATCH_OTR_MESSAGES:
+ // Insert into the messages table.
+ rowID = db.insert(TABLE_IN_MEMORY_MESSAGES, "thread_id", initialValues);
+ if (rowID > 0) {
+ resultUri = Uri.parse(Imps.Messages.OTR_MESSAGES_CONTENT_URI + "/" + rowID);
+ }
+
+ break;
+
+ case MATCH_INVITATIONS:
+ rowID = db.insert(TABLE_INVITATIONS, null, initialValues);
+ if (rowID > 0) {
+ resultUri = Uri.parse(Imps.Invitation.CONTENT_URI + "/" + rowID);
+ }
+ break;
+
+ case MATCH_GROUP_MEMBERS:
+ rowID = db.insert(TABLE_GROUP_MEMBERS, "nickname", initialValues);
+ if (rowID > 0) {
+ resultUri = Uri.parse(Imps.GroupMembers.CONTENT_URI + "/" + rowID);
+ }
+ break;
+
+ case MATCH_GROUP_MEMBERS_BY_GROUP:
+ appendValuesFromUrl(initialValues, url, Imps.GroupMembers.GROUP);
+ rowID = db.insert(TABLE_GROUP_MEMBERS, "nickname", initialValues);
+ if (rowID > 0) {
+ resultUri = Uri.parse(Imps.GroupMembers.CONTENT_URI + "/" + rowID);
+ }
+ break;
+
+ case MATCH_AVATAR_BY_PROVIDER:
+ appendValuesFromUrl(initialValues, url, Imps.Avatars.PROVIDER, Imps.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(Imps.Avatars.CONTENT_URI + "/" + rowID);
+ }
+ break;
+
+ case MATCH_CHATS_ID:
+ appendValuesFromUrl(initialValues, url, Imps.Chats.CONTACT_ID);
+ // fall through
+ case MATCH_CHATS:
+ // Insert into the chats table
+ initialValues.put(Imps.Chats.SHORTCUT, -1);
+ rowID = db.replace(TABLE_CHATS, Imps.Chats.CONTACT_ID, initialValues);
+ if (rowID > 0) {
+ resultUri = Uri.parse(Imps.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(Imps.Presence.CONTENT_URI + "/" + rowID);
+ }
+ notifyContactContentUri = true;
+ break;
+
+ case MATCH_PRESENCE_SEED_BY_ACCOUNT:
+ try {
+ seedInitialPresenceByAccount(Long.parseLong(url.getLastPathSegment()));
+ resultUri = Imps.Presence.CONTENT_URI;
+ } catch (NumberFormatException ex) {
+ throw new IllegalArgumentException();
+ }
+ break;
+
+ case MATCH_SESSIONS_BY_PROVIDER:
+ appendValuesFromUrl(initialValues, url, Imps.SessionCookies.PROVIDER,
+ Imps.SessionCookies.ACCOUNT);
+ // fall through
+ case MATCH_SESSIONS:
+ rowID = db.insert(TABLE_SESSION_COOKIES, null, initialValues);
+ if(rowID > 0) {
+ resultUri = Uri.parse(Imps.SessionCookies.CONTENT_URI + "/" + rowID);
+ }
+ break;
+
+ case MATCH_PROVIDER_SETTINGS:
+ rowID = db.replace(TABLE_PROVIDER_SETTINGS, null, initialValues);
+ if (rowID > 0) {
+ resultUri = Uri.parse(Imps.ProviderSettings.CONTENT_URI + "/" + rowID);
+ }
+ break;
+
+ case MATCH_ACCOUNTS_STATUS:
+ rowID = db.replace(TABLE_ACCOUNT_STATUS, null, initialValues);
+ if (rowID > 0) {
+ resultUri = Uri.parse(Imps.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(Imps.BrandingResourceMapCache.CONTENT_URI + "/" + rowID);
+ }
+ break;
+
+ // mcs/rmq stuff
+ case MATCH_OUTGOING_RMQ_MESSAGES:
+ rowID = db.insert(TABLE_OUTGOING_RMQ_MESSAGES, null, initialValues);
+ if (rowID > 0) {
+ resultUri = Uri.parse(Imps.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(Imps.LastRmqId.CONTENT_URI + "/" + rowID);
+ }
+ break;
+
+ case MATCH_S2D_RMQ_IDS:
+ rowID = db.insert(TABLE_S2D_RMQ_IDS, null, initialValues);
+ if (rowID > 0) {
+ resultUri = Uri.parse(Imps.ServerToDeviceRmqIds.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(Imps.Contacts.CONTENT_URI, null);
+ }
+
+ if (notifyContactListContentUri) {
+ resolver.notifyChange(Imps.ContactList.CONTENT_URI, null);
+ }
+
+ if (notifyMessagesContentUri) {
+ resolver.notifyChange(Imps.Messages.CONTENT_URI, null);
+ }
+
+ if (notifyMessagesByContactContentUri) {
+ resolver.notifyChange(Imps.Messages.CONTENT_URI, null);
+ resolver.notifyChange(Imps.Messages.getContentUriByContact(account, contact), null);
+ }
+
+ if (notifyMessagesByThreadIdContentUri) {
+ resolver.notifyChange(Imps.Messages.CONTENT_URI, null);
+ resolver.notifyChange(Imps.Messages.getContentUriByThreadId(threadId), null);
+ }
+
+ if (notifyProviderAccountContentUri) {
+ if (DBG) log("notify insert for " + Imps.Provider.CONTENT_URI_WITH_ACCOUNT);
+ resolver.notifyChange(Imps.Provider.CONTENT_URI_WITH_ACCOUNT, null);
+ }
+ }
+ return resultUri;
+ }
+
+ private void appendValuesFromUrl(ContentValues values, Uri url, 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 long getContactId(final SQLiteDatabase db,
+ final String accountId, final String contact) {
+ SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
+ qb.setTables(TABLE_CONTACTS);
+ qb.setProjectionMap(sContactsProjectionMap);
+
+ mQueryContactIdSelectionArgs2[0] = accountId;
+ mQueryContactIdSelectionArgs2[1] = contact;
+
+ Cursor c = qb.query(db,
+ CONTACT_ID_PROJECTION,
+ CONTACT_ID_QUERY_SELECTION,
+ mQueryContactIdSelectionArgs2,
+ null, null, null, null);
+
+ long contactId = 0;
+
+ try {
+ if (c.moveToFirst()) {
+ contactId = c.getLong(CONTACT_ID_COLUMN);
+ }
+ } finally {
+ c.close();
+ }
+
+ return contactId;
+ }
+
+ // Quick-switch management
+ // The chat UI provides slots (0, 9, .., 1) for the first 10 chats. This allows you to
+ // quickly switch between these chats by chording menu+#. We number from the right end of
+ // the number row and move leftward to make an easier two-hand chord with the menu button
+ // on the left side of the keyboard.
+ 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);
+ }
+
+ // If there are more than 10 chats and one with a quick switch slot ends then pick a chat
+ // that doesn't have a slot and have it inhabit the newly emptied slot.
+ private void backfillQuickSwitchSlots() {
+ // Find all the chats without a quick switch slot, and order
+ Cursor c = query(Imps.Chats.CONTENT_URI,
+ BACKFILL_PROJECTION,
+ Imps.Chats.SHORTCUT + "=-1", null, Imps.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(Imps.Chats._ID));
+
+ updateSlotForChat(id, slot);
+ }
+ } finally {
+ c.close();
+ }
+ }
+
+ private int updateSlotForChat(long chatId, int slot) {
+ ContentValues values = new ContentValues();
+
+ values.put(Imps.Chats.SHORTCUT, slot);
+
+ return update(Imps.Chats.CONTENT_URI, values, Imps.Chats._ID + "=?",
+ new String[] { Long.toString(chatId) });
+ }
+
+ private int findEmptyQuickSwitchSlot() {
+ Cursor c = queryInternal(Imps.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(Imps.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();
+ }
+ }
+
+ /**
+ * manual trigger for deleting contacts
+ */
+ private static final String DELETE_PRESENCE_SELECTION =
+ Imps.Presence.CONTACT_ID + " in (select " +
+ PRESENCE_CONTACT_ID + " from " + TABLE_PRESENCE + " left outer join " + TABLE_CONTACTS +
+ " on " + PRESENCE_CONTACT_ID + '=' + CONTACT_ID + " where " + CONTACT_ID + " IS NULL)";
+
+ private static final String CHATS_CONTACT_ID = TABLE_CHATS + '.' + Imps.Chats.CONTACT_ID;
+ private static final String DELETE_CHATS_SELECTION = Imps.Chats.CONTACT_ID + " in (select "+
+ CHATS_CONTACT_ID + " from " + TABLE_CHATS + " left outer join " + TABLE_CONTACTS +
+ " on " + CHATS_CONTACT_ID + '=' + CONTACT_ID + " where " + CONTACT_ID + " IS NULL)";
+
+ private static final String GROUP_MEMBER_ID = TABLE_GROUP_MEMBERS + '.' + Imps.GroupMembers.GROUP;
+ private static final String DELETE_GROUP_MEMBER_SELECTION =
+ Imps.GroupMembers.GROUP + " in (select "+
+ GROUP_MEMBER_ID + " from " + TABLE_GROUP_MEMBERS + " left outer join " + TABLE_CONTACTS +
+ " on " + GROUP_MEMBER_ID + '=' + CONTACT_ID + " where " + CONTACT_ID + " IS NULL)";
+
+ private static final String GROUP_MESSAGES_ID = TABLE_MESSAGES + '.' + Imps.Messages.THREAD_ID;
+ private static final String DELETE_GROUP_MESSAGES_SELECTION =
+ Imps.Messages.THREAD_ID + " in (select "+ GROUP_MESSAGES_ID + " from " +
+ TABLE_MESSAGES + " left outer join " + TABLE_CONTACTS + " on " +
+ GROUP_MESSAGES_ID + '=' + CONTACT_ID + " where " + CONTACT_ID + " IS NULL)";
+
+ private void performContactRemovalCleanup(long contactId) {
+ final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+
+ if (contactId > 0) {
+ StringBuilder buf = new StringBuilder();
+
+ // delete presence
+ buf.append(Imps.Presence.CONTACT_ID).append('=').append(contactId);
+ deleteWithSelection(db, TABLE_PRESENCE, buf.toString(), null);
+
+ // delete group memebers
+ buf.delete(0, buf.length());
+ buf.append(Imps.GroupMembers.GROUP).append('=').append(contactId);
+ deleteWithSelection(db, TABLE_GROUP_MEMBERS, buf.toString(), null);
+ } else {
+ // delete presence
+ deleteWithSelection(db, TABLE_PRESENCE, DELETE_PRESENCE_SELECTION, null);
+
+ // delete group members
+ deleteWithSelection(db, TABLE_GROUP_MEMBERS, DELETE_GROUP_MEMBER_SELECTION, null);
+ }
+ }
+
+ private void deleteWithSelection(SQLiteDatabase db, String tableName,
+ String selection, String[] selectionArgs) {
+ if (DBG) log("deleteWithSelection: table " + tableName + ", selection => " + selection);
+ int count = db.delete(tableName, selection, selectionArgs);
+ if (DBG) log("deleteWithSelection: deleted " + count + " rows");
+ }
+
+ private String buildContactIdSelection(String columnName, String contactSelection) {
+ StringBuilder buf = new StringBuilder();
+
+ buf.append(columnName);
+ buf.append(" in (select ");
+ buf.append(Imps.Contacts._ID);
+ buf.append(" from ");
+ buf.append(TABLE_CONTACTS);
+ buf.append(" where ");
+ buf.append(contactSelection);
+ buf.append(")");
+
+ return buf.toString();
+ }
+
+ private int deleteInternal(Uri url, String userWhere, String[] whereArgs) {
+ String tableToChange;
+
+ // In some cases a given url requires that we delete rows from more than one
+ // table. The motivating example is deleting messages from both the on disk
+ // and in memory messages tables.
+ String tableToChange2 = null;
+ String idColumnName = null;
+ String changedItemId = null;
+ String provider = null;
+ String accountStr = null;
+ long account = 0;
+ String contact = null;
+ long threadId = 0;
+
+ StringBuilder whereClause = new StringBuilder();
+ if(userWhere != null) {
+ whereClause.append(userWhere);
+ }
+
+ boolean notifyMessagesContentUri = false;
+ boolean notifyMessagesByContactContentUri = false;
+ boolean notifyMessagesByThreadIdContentUri = false;
+ boolean notifyContactListContentUri = false;
+ boolean notifyProviderAccountContentUri = false;
+ int match = mUrlMatcher.match(url);
+
+ boolean contactDeleted = false;
+ long deletedContactId = 0;
+
+ boolean backfillQuickSwitchSlots = false;
+
+ final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+
+ 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) {
+ throw new IllegalArgumentException();
+ }
+
+ contactDeleted = true;
+ break;
+
+ case MATCH_CONTACTS_BY_PROVIDER:
+ tableToChange = TABLE_CONTACTS;
+ appendWhere(whereClause, Imps.Contacts.ACCOUNT, "=", url.getPathSegments().get(2));
+ contactDeleted = true;
+ break;
+
+ case MATCH_CONTACTLISTS_BY_PROVIDER:
+ appendWhere(whereClause, Imps.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, Imps.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;
+ tableToChange2 = TABLE_IN_MEMORY_MESSAGES;
+
+ accountStr = decodeURLSegment(url.getPathSegments().get(1));
+ try {
+ account = Long.parseLong(accountStr);
+ } catch (NumberFormatException ex) {
+ throw new IllegalArgumentException();
+ }
+
+ contact = decodeURLSegment(url.getPathSegments().get(2));
+ appendWhere(whereClause, Imps.Messages.THREAD_ID, "=",
+ getContactId(db, accountStr, contact));
+
+ notifyMessagesContentUri = true;
+ break;
+
+ case MATCH_MESSAGES_BY_THREAD_ID:
+ tableToChange = TABLE_MESSAGES;
+ tableToChange2 = TABLE_IN_MEMORY_MESSAGES;
+
+ try {
+ threadId = Long.parseLong(decodeURLSegment(url.getPathSegments().get(1)));
+ } catch (NumberFormatException ex) {
+ throw new IllegalArgumentException();
+ }
+
+ appendWhere(whereClause, Imps.Messages.THREAD_ID, "=", threadId);
+
+ notifyMessagesContentUri = true;
+ break;
+
+ case MATCH_MESSAGES_BY_PROVIDER:
+ tableToChange = TABLE_MESSAGES;
+
+ provider = decodeURLSegment(url.getPathSegments().get(1));
+ appendWhere(whereClause, buildContactIdSelection(Imps.Messages.THREAD_ID,
+ Imps.Contacts.PROVIDER + "='" + provider + "'"));
+
+ notifyMessagesContentUri = true;
+ break;
+
+ case MATCH_MESSAGES_BY_ACCOUNT:
+ tableToChange = TABLE_MESSAGES;
+
+ accountStr = decodeURLSegment(url.getPathSegments().get(1));
+ appendWhere(whereClause, buildContactIdSelection(Imps.Messages.THREAD_ID,
+ Imps.Contacts.ACCOUNT + "='" + accountStr + "'"));
+
+ notifyMessagesContentUri = true;
+ break;
+
+ case MATCH_MESSAGE:
+ tableToChange = TABLE_MESSAGES;
+ changedItemId = url.getPathSegments().get(1);
+ notifyMessagesContentUri = true;
+ break;
+
+ case MATCH_OTR_MESSAGES:
+ tableToChange = TABLE_IN_MEMORY_MESSAGES;
+ break;
+
+ case MATCH_OTR_MESSAGES_BY_CONTACT:
+ tableToChange = TABLE_IN_MEMORY_MESSAGES;
+
+ accountStr = decodeURLSegment(url.getPathSegments().get(1));
+ try {
+ account = Long.parseLong(accountStr);
+ } catch (NumberFormatException ex) {
+ throw new IllegalArgumentException();
+ }
+
+ contact = decodeURLSegment(url.getPathSegments().get(2));
+ appendWhere(whereClause, Imps.Messages.THREAD_ID, "=",
+ getContactId(db, accountStr, contact));
+
+ notifyMessagesByContactContentUri = true;
+ break;
+
+ case MATCH_OTR_MESSAGES_BY_THREAD_ID:
+ tableToChange = TABLE_IN_MEMORY_MESSAGES;
+
+ try {
+ threadId = Long.parseLong(decodeURLSegment(url.getPathSegments().get(1)));
+ } catch (NumberFormatException ex) {
+ throw new IllegalArgumentException();
+ }
+
+ appendWhere(whereClause, Imps.Messages.THREAD_ID, "=", threadId);
+
+ notifyMessagesByThreadIdContentUri = true;
+ break;
+
+ case MATCH_OTR_MESSAGES_BY_PROVIDER:
+ tableToChange = TABLE_IN_MEMORY_MESSAGES;
+
+ provider = decodeURLSegment(url.getPathSegments().get(1));
+ appendWhere(whereClause, buildContactIdSelection(Imps.Messages.THREAD_ID,
+ Imps.Contacts.PROVIDER + "='" + provider + "'"));
+
+ if (DBG) log("delete (MATCH_OTR_MESSAGES_BY_PROVIDER) sel => " + whereClause);
+ notifyMessagesContentUri = true;
+ break;
+
+ case MATCH_OTR_MESSAGES_BY_ACCOUNT:
+ tableToChange = TABLE_IN_MEMORY_MESSAGES;
+
+ accountStr = decodeURLSegment(url.getPathSegments().get(1));
+ appendWhere(whereClause, buildContactIdSelection(Imps.Messages.THREAD_ID,
+ Imps.Contacts.ACCOUNT + "='" + accountStr + "'"));
+
+ if (DBG) log("delete (MATCH_OTR_MESSAGES_BY_ACCOUNT) sel => " + whereClause);
+ notifyMessagesContentUri = true;
+ break;
+
+ case MATCH_OTR_MESSAGE:
+ tableToChange = TABLE_IN_MEMORY_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, Imps.GroupMembers.GROUP, "=", url.getPathSegments().get(1));
+ 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 = Imps.Avatars.ACCOUNT;
+ break;
+
+ case MATCH_CHATS:
+ tableToChange = TABLE_CHATS;
+ backfillQuickSwitchSlots = true;
+ break;
+
+ case MATCH_CHATS_BY_ACCOUNT:
+ tableToChange = TABLE_CHATS;
+
+ accountStr = decodeURLSegment(url.getLastPathSegment());
+ appendWhere(whereClause, buildContactIdSelection(Imps.Chats.CONTACT_ID,
+ Imps.Contacts.ACCOUNT + "='" + accountStr + "'"));
+
+ if (DBG) log("delete (MATCH_CHATS_BY_ACCOUNT) sel => " + whereClause);
+
+ changedItemId = null;
+ break;
+
+ case MATCH_CHATS_ID:
+ tableToChange = TABLE_CHATS;
+ changedItemId = url.getPathSegments().get(1);
+ idColumnName = Imps.Chats.CONTACT_ID;
+ break;
+
+ case MATCH_PRESENCE:
+ tableToChange = TABLE_PRESENCE;
+ break;
+
+ case MATCH_PRESENCE_ID:
+ tableToChange = TABLE_PRESENCE;
+ changedItemId = url.getPathSegments().get(1);
+ idColumnName = Imps.Presence.CONTACT_ID;
+ break;
+
+ case MATCH_PRESENCE_BY_ACCOUNT:
+ tableToChange = TABLE_PRESENCE;
+
+ accountStr = decodeURLSegment(url.getLastPathSegment());
+ appendWhere(whereClause, buildContactIdSelection(Imps.Presence.CONTACT_ID,
+ Imps.Contacts.ACCOUNT + "='" + accountStr + "'"));
+
+ if (DBG) log("delete (MATCH_PRESENCE_BY_ACCOUNT): sel => " + whereClause);
+ 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 = Imps.SessionCookies.ACCOUNT;
+ break;
+
+ case MATCH_PROVIDER_SETTINGS_BY_ID:
+ tableToChange = TABLE_PROVIDER_SETTINGS;
+ changedItemId = url.getPathSegments().get(1);
+ idColumnName = Imps.ProviderSettings.PROVIDER;
+ 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, Imps.ProviderSettings.PROVIDER, "=", providerId);
+ appendWhere(whereClause, Imps.ProviderSettings.NAME, "=", name);
+ break;
+
+ case MATCH_BRANDING_RESOURCE_MAP_CACHE:
+ tableToChange = TABLE_BRANDING_RESOURCE_MAP_CACHE;
+ break;
+
+ // mcs/rmq stuff
+ case MATCH_OUTGOING_RMQ_MESSAGES:
+ tableToChange = TABLE_OUTGOING_RMQ_MESSAGES;
+ break;
+
+ case MATCH_LAST_RMQ_ID:
+ tableToChange = TABLE_LAST_RMQ_ID;
+ break;
+
+ case MATCH_S2D_RMQ_IDS:
+ tableToChange = TABLE_S2D_RMQ_IDS;
+ 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);
+
+ int count = db.delete(tableToChange, whereClause.toString(), whereArgs);
+
+ // see the comment at the declaration of tableToChange2 for an explanation
+ if (tableToChange2 != null){
+ count += db.delete(tableToChange2, 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) {
+ 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 (match == MATCH_CHATS || match == MATCH_CHATS_ID
+ || match == MATCH_PRESENCE || match == MATCH_PRESENCE_ID
+ || match == MATCH_CONTACTS_BAREBONE) {
+ resolver.notifyChange(Imps.Contacts.CONTENT_URI, null);
+ }
+
+ if (notifyMessagesContentUri) {
+ resolver.notifyChange(Imps.Messages.CONTENT_URI, null);
+ }
+
+ if (notifyMessagesByContactContentUri) {
+ resolver.notifyChange(Imps.Messages.CONTENT_URI, null);
+ resolver.notifyChange(Imps.Messages.getContentUriByContact(account, contact), null);
+ }
+
+ if (notifyMessagesByThreadIdContentUri) {
+ resolver.notifyChange(Imps.Messages.CONTENT_URI, null);
+ resolver.notifyChange(Imps.Messages.getContentUriByThreadId(threadId), null);
+ }
+
+ if (notifyContactListContentUri) {
+ resolver.notifyChange(Imps.ContactList.CONTENT_URI, null);
+ }
+
+ if (notifyProviderAccountContentUri) {
+ if (DBG) log("notify delete for " + Imps.Provider.CONTENT_URI_WITH_ACCOUNT);
+ resolver.notifyChange(Imps.Provider.CONTENT_URI_WITH_ACCOUNT, null);
+ }
+
+ if (backfillQuickSwitchSlots) {
+ backfillQuickSwitchSlots();
+ }
+ }
+
+ return count;
+ }
+
+ private int updateInternal(Uri url, ContentValues values, String userWhere,
+ String[] whereArgs) {
+ String tableToChange;
+ String idColumnName = null;
+ String changedItemId = null;
+ String accountStr = null;
+ long account = 0;
+ String contact = null;
+ long threadId = 0;
+ int count;
+
+ StringBuilder whereClause = new StringBuilder();
+ if(userWhere != null) {
+ whereClause.append(userWhere);
+ }
+
+ boolean notifyMessagesContentUri = false;
+ boolean notifyMessagesByContactContentUri = false;
+ boolean notifyMessagesByThreadIdContentUri = false;
+ boolean notifyContactListContentUri = false;
+ boolean notifyProviderAccountContentUri = false;
+
+ int match = mUrlMatcher.match(url);
+ final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+
+ 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 = Imps.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(
+ Imps.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;
+
+ accountStr = decodeURLSegment(url.getPathSegments().get(1));
+ try {
+ account = Long.parseLong(accountStr);
+ } catch (NumberFormatException ex) {
+ throw new IllegalArgumentException();
+ }
+
+ contact = decodeURLSegment(url.getPathSegments().get(2));
+ appendWhere(whereClause, Imps.Messages.THREAD_ID, "=",
+ getContactId(db, accountStr, contact));
+
+ notifyMessagesContentUri = true;
+ break;
+
+ case MATCH_MESSAGES_BY_THREAD_ID:
+ tableToChange = TABLE_MESSAGES;
+
+ try {
+ threadId = Long.parseLong(decodeURLSegment(url.getPathSegments().get(1)));
+ } catch (NumberFormatException ex) {
+ throw new IllegalArgumentException();
+ }
+
+ appendWhere(whereClause, Imps.Messages.THREAD_ID, "=", threadId);
+
+ notifyMessagesContentUri = true;
+ break;
+
+ case MATCH_MESSAGE:
+ tableToChange = TABLE_MESSAGES;
+ changedItemId = url.getPathSegments().get(1);
+ notifyMessagesContentUri = true;
+ break;
+
+ case MATCH_OTR_MESSAGES:
+ tableToChange = TABLE_IN_MEMORY_MESSAGES;
+ break;
+
+ case MATCH_OTR_MESSAGES_BY_CONTACT:
+ tableToChange = TABLE_IN_MEMORY_MESSAGES;
+
+ accountStr = decodeURLSegment(url.getPathSegments().get(1));
+ try {
+ account = Long.parseLong(accountStr);
+ } catch (NumberFormatException ex) {
+ throw new IllegalArgumentException();
+ }
+
+ contact = decodeURLSegment(url.getPathSegments().get(2));
+ appendWhere(whereClause, Imps.Messages.THREAD_ID, "=",
+ getContactId(db, accountStr, contact));
+
+ notifyMessagesByContactContentUri = true;
+ break;
+
+ case MATCH_OTR_MESSAGES_BY_THREAD_ID:
+ tableToChange = TABLE_IN_MEMORY_MESSAGES;
+
+ try {
+ threadId = Long.parseLong(decodeURLSegment(url.getPathSegments().get(1)));
+ } catch (NumberFormatException ex) {
+ throw new IllegalArgumentException();
+ }
+
+ appendWhere(whereClause, Imps.Messages.THREAD_ID, "=", threadId);
+
+ notifyMessagesByThreadIdContentUri = true;
+ break;
+
+ case MATCH_OTR_MESSAGE:
+ tableToChange = TABLE_IN_MEMORY_MESSAGES;
+ changedItemId = url.getPathSegments().get(1);
+ notifyMessagesContentUri = 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 = Imps.Avatars.ACCOUNT;
+ break;
+
+ case MATCH_CHATS:
+ tableToChange = TABLE_CHATS;
+ break;
+
+ case MATCH_CHATS_ID:
+ tableToChange = TABLE_CHATS;
+ changedItemId = url.getPathSegments().get(1);
+ idColumnName = Imps.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 = Imps.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(Imps.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(Imps.ProviderSettings.PROVIDER) ||
+ values.containsKey(Imps.ProviderSettings.NAME)) {
+ throw new SecurityException("Cannot override the value for provider|name");
+ }
+
+ appendWhere(whereClause, Imps.ProviderSettings.PROVIDER, "=", providerId);
+ appendWhere(whereClause, Imps.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_S2D_RMQ_IDS:
+ tableToChange = TABLE_S2D_RMQ_IDS;
+ 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);
+
+ count = db.update(tableToChange, values, whereClause.toString(), whereArgs);
+
+ if (count > 0) {
+ 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 (match == MATCH_CHATS || match == MATCH_CHATS_ID
+ || match == MATCH_PRESENCE || match == MATCH_PRESENCE_ID
+ || match == MATCH_CONTACTS_BAREBONE) {
+ resolver.notifyChange(Imps.Contacts.CONTENT_URI, null);
+ }
+
+ if (notifyMessagesContentUri) {
+ if (DBG) log("notify change for " + Imps.Messages.CONTENT_URI);
+ resolver.notifyChange(Imps.Messages.CONTENT_URI, null);
+ }
+
+ if (notifyMessagesByContactContentUri) {
+ resolver.notifyChange(Imps.Messages.CONTENT_URI, null);
+ resolver.notifyChange(Imps.Messages.getContentUriByContact(account, contact), null);
+ }
+
+ if (notifyMessagesByThreadIdContentUri) {
+ resolver.notifyChange(Imps.Messages.CONTENT_URI, null);
+ resolver.notifyChange(Imps.Messages.getContentUriByThreadId(threadId), null);
+ }
+
+ if (notifyContactListContentUri) {
+ resolver.notifyChange(Imps.ContactList.CONTENT_URI, null);
+ }
+
+ if (notifyProviderAccountContentUri) {
+ if (DBG) log("notify change for " + Imps.Provider.CONTENT_URI_WITH_ACCOUNT);
+ resolver.notifyChange(Imps.Provider.CONTENT_URI_WITH_ACCOUNT, null);
+ }
+ }
+
+ return count;
+ }
+
+ @Override
+ public ParcelFileDescriptor openFile(Uri uri, String mode)
+ throws FileNotFoundException {
+ return openFileHelper(uri, mode);
+ }
+
+ private static void appendWhere(StringBuilder where, String columnName,
+ String condition, 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(StringBuilder where, String clause) {
+ if (where.length() > 0) {
+ where.append(" AND ");
+ }
+ where.append(clause);
+ }
+
+ private static String decodeURLSegment(String segment) {
+ try {
+ return URLDecoder.decode(segment, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ // impossible
+ return segment;
+ }
+ }
+
+ static void log(String message) {
+ Log.d(LOG_TAG, message);
+ }
+}
diff --git a/src/com/android/im/receiver/ImServiceAutoStarter.java b/src/com/android/im/receiver/ImServiceAutoStarter.java
index 7f1992f..519e0f3 100644
--- a/src/com/android/im/receiver/ImServiceAutoStarter.java
+++ b/src/com/android/im/receiver/ImServiceAutoStarter.java
@@ -17,13 +17,13 @@
package com.android.im.receiver;
+import com.android.im.provider.Imps;
import com.android.im.service.ImServiceConstants;
import android.content.Context;
import android.content.Intent;
import android.content.BroadcastReceiver;
import android.database.Cursor;
-import android.provider.Im;
import android.util.Log;
public class ImServiceAutoStarter extends BroadcastReceiver {
@@ -34,10 +34,10 @@ public class ImServiceAutoStarter extends BroadcastReceiver {
// Received intent only when the system boot is completed
Log.d(TAG, "onReceiveIntent");
- String selection = Im.Account.KEEP_SIGNED_IN + "=1 AND "
- + Im.Account.ACTIVE + "=1";
- Cursor cursor = context.getContentResolver().query(Im.Account.CONTENT_URI,
- new String[]{Im.Account._ID}, selection, null, null);
+ String selection = Imps.Account.KEEP_SIGNED_IN + "=1 AND "
+ + Imps.Account.ACTIVE + "=1";
+ Cursor cursor = context.getContentResolver().query(Imps.Account.CONTENT_URI,
+ new String[]{Imps.Account._ID}, selection, null, null);
if (cursor != null) {
if (cursor.getCount() > 0) {
Log.d(TAG, "start service");
diff --git a/src/com/android/im/service/ChatSessionAdapter.java b/src/com/android/im/service/ChatSessionAdapter.java
index 257d81e..3ac6c60 100644
--- a/src/com/android/im/service/ChatSessionAdapter.java
+++ b/src/com/android/im/service/ChatSessionAdapter.java
@@ -31,6 +31,7 @@ import com.android.im.engine.ImErrorInfo;
import com.android.im.engine.Message;
import com.android.im.engine.MessageListener;
import com.android.im.engine.Presence;
+import com.android.im.provider.Imps;
import android.content.ContentResolver;
import android.content.ContentValues;
@@ -40,7 +41,6 @@ import android.net.Uri;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.provider.BaseColumns;
-import android.provider.Im;
import android.util.Log;
import java.util.ArrayList;
@@ -49,9 +49,9 @@ import java.util.List;
public class ChatSessionAdapter extends IChatSession.Stub {
- private static final String NON_CHAT_MESSAGE_SELECTION = Im.Messages.TYPE
- + "!=" + Im.MessageType.INCOMING + " AND " + Im.Messages.TYPE
- + "!=" + Im.MessageType.OUTGOING;
+ private static final String NON_CHAT_MESSAGE_SELECTION = Imps.Messages.TYPE
+ + "!=" + Imps.MessageType.INCOMING + " AND " + Imps.Messages.TYPE
+ + "!=" + Imps.MessageType.OUTGOING;
static final String TAG = RemoteImService.TAG;
@@ -106,8 +106,8 @@ public class ChatSessionAdapter extends IChatSession.Stub {
mIsGroupChat = true;
long groupId = insertGroupContactInDb(group);
group.addMemberListener(mListenerAdapter);
- mMessageURI = Im.Messages.getContentUriByThreadId(groupId);
- mChatURI = ContentUris.withAppendedId(Im.Chats.CONTENT_URI, groupId);
+ mMessageURI = Imps.Messages.getContentUriByThreadId(groupId);
+ mChatURI = ContentUris.withAppendedId(Imps.Chats.CONTENT_URI, groupId);
insertOrUpdateChat(null);
for (Contact c : group.getMembers()) {
@@ -121,8 +121,8 @@ public class ChatSessionAdapter extends IChatSession.Stub {
(ContactListManagerAdapter) mConnection.getContactListManager();
long contactId = listManager.queryOrInsertContact(contact);
- mMessageURI = Im.Messages.getContentUriByThreadId(contactId);
- mChatURI = ContentUris.withAppendedId(Im.Chats.CONTENT_URI, contactId);
+ mMessageURI = Imps.Messages.getContentUriByThreadId(contactId);
+ mChatURI = ContentUris.withAppendedId(Imps.Chats.CONTENT_URI, contactId);
insertOrUpdateChat(null);
mContactStatusMap.put(contact.getName(), contact.getPresence().getStatus());
@@ -229,27 +229,27 @@ public class ChatSessionAdapter extends IChatSession.Stub {
public void sendMessage(String text) {
if (mConnection.getState() == ImConnection.SUSPENDED) {
// connection has been suspended, save the message without send it
- insertMessageInDb(null, text, -1, Im.MessageType.POSTPONED);
+ insertMessageInDb(null, text, -1, Imps.MessageType.POSTPONED);
return;
}
Message msg = new Message(text);
mAdaptee.sendMessageAsync(msg);
long now = System.currentTimeMillis();
- insertMessageInDb(null, text, now, Im.MessageType.OUTGOING);
+ insertMessageInDb(null, text, now, Imps.MessageType.OUTGOING);
}
void sendPostponedMessages() {
String[] projection = new String[] {
BaseColumns._ID,
- Im.Messages.BODY,
- Im.Messages.DATE,
- Im.Messages.TYPE,
+ Imps.Messages.BODY,
+ Imps.Messages.DATE,
+ Imps.Messages.TYPE,
};
String selection = "messages.type=?";
Cursor c = mContentResolver.query(mMessageURI, projection, selection,
- new String[]{Integer.toString(Im.MessageType.POSTPONED)}, null);
+ new String[]{Integer.toString(Imps.MessageType.POSTPONED)}, null);
if (c == null) {
Log.e(TAG, "Query error while querying postponed messages");
return;
@@ -260,7 +260,7 @@ public class ChatSessionAdapter extends IChatSession.Stub {
mAdaptee.sendMessageAsync(new Message(body));
c.updateLong(2, System.currentTimeMillis());
- c.updateInt(3, Im.MessageType.OUTGOING);
+ c.updateInt(3, Imps.MessageType.OUTGOING);
}
c.commitUpdates();
c.close();
@@ -281,7 +281,7 @@ public class ChatSessionAdapter extends IChatSession.Stub {
public void markAsRead() {
if (mHasUnreadMessages) {
ContentValues values = new ContentValues(1);
- values.put(Im.Chats.LAST_UNREAD_MESSAGE, (String) null);
+ values.put(Imps.Chats.LAST_UNREAD_MESSAGE, (String) null);
mConnection.getContext().getContentResolver().update(mChatURI, values, null, null);
mStatusBarNotifier.dismissChatNotification(mConnection.getProviderId(), getAddress());
@@ -335,15 +335,15 @@ public class ChatSessionAdapter extends IChatSession.Stub {
String contact = incoming ? oldParticipant.getName() : null;
long time = msg.getDateTime().getTime();
insertMessageInDb(contact, msg.getBody(), time,
- incoming ? Im.MessageType.INCOMING : Im.MessageType.OUTGOING);
+ incoming ? Imps.MessageType.INCOMING : Imps.MessageType.OUTGOING);
}
}
void insertOrUpdateChat(String message) {
ContentValues values = new ContentValues(2);
- values.put(Im.Chats.LAST_MESSAGE_DATE, System.currentTimeMillis());
- values.put(Im.Chats.LAST_UNREAD_MESSAGE, message);
+ values.put(Imps.Chats.LAST_MESSAGE_DATE, System.currentTimeMillis());
+ values.put(Imps.Chats.LAST_UNREAD_MESSAGE, message);
// ImProvider.insert() will replace the chat if it already exist.
mContentResolver.insert(mChatURI, values);
}
@@ -351,13 +351,13 @@ public class ChatSessionAdapter extends IChatSession.Stub {
private long insertGroupContactInDb(ChatGroup group) {
// Insert a record in contacts table
ContentValues values = new ContentValues(4);
- values.put(Im.Contacts.USERNAME, group.getAddress().getFullName());
- values.put(Im.Contacts.NICKNAME, group.getName());
- values.put(Im.Contacts.CONTACTLIST, ContactListManagerAdapter.FAKE_TEMPORARY_LIST_ID);
- values.put(Im.Contacts.TYPE, Im.Contacts.TYPE_GROUP);
+ values.put(Imps.Contacts.USERNAME, group.getAddress().getFullName());
+ values.put(Imps.Contacts.NICKNAME, group.getName());
+ values.put(Imps.Contacts.CONTACTLIST, ContactListManagerAdapter.FAKE_TEMPORARY_LIST_ID);
+ values.put(Imps.Contacts.TYPE, Imps.Contacts.TYPE_GROUP);
Uri contactUri = ContentUris.withAppendedId(ContentUris.withAppendedId(
- Im.Contacts.CONTENT_URI, mConnection.mProviderId), mConnection.mAccountId);
+ Imps.Contacts.CONTENT_URI, mConnection.mProviderId), mConnection.mAccountId);
long id = ContentUris.parseId(mContentResolver.insert(contactUri, values));
ArrayList<ContentValues> memberValues = new ArrayList<ContentValues>();
@@ -365,9 +365,9 @@ public class ChatSessionAdapter extends IChatSession.Stub {
for (Contact member : group.getMembers()) {
if (!member.equals(self)) { // avoid to insert the user himself
ContentValues memberValue = new ContentValues(2);
- memberValue.put(Im.GroupMembers.USERNAME,
+ memberValue.put(Imps.GroupMembers.USERNAME,
member.getAddress().getFullName());
- memberValue.put(Im.GroupMembers.NICKNAME,
+ memberValue.put(Imps.GroupMembers.NICKNAME,
member.getName());
memberValues.add(memberValue);
}
@@ -375,7 +375,7 @@ public class ChatSessionAdapter extends IChatSession.Stub {
if (!memberValues.isEmpty()) {
ContentValues[] result = new ContentValues[memberValues.size()];
memberValues.toArray(result);
- Uri memberUri = ContentUris.withAppendedId(Im.GroupMembers.CONTENT_URI, id);
+ Uri memberUri = ContentUris.withAppendedId(Imps.GroupMembers.CONTENT_URI, id);
mContentResolver.bulkInsert(memberUri, result);
}
return id;
@@ -383,27 +383,27 @@ public class ChatSessionAdapter extends IChatSession.Stub {
void insertGroupMemberInDb(Contact member) {
ContentValues values1 = new ContentValues(2);
- values1.put(Im.GroupMembers.USERNAME, member.getAddress().getFullName());
- values1.put(Im.GroupMembers.NICKNAME, member.getName());
+ values1.put(Imps.GroupMembers.USERNAME, member.getAddress().getFullName());
+ values1.put(Imps.GroupMembers.NICKNAME, member.getName());
ContentValues values = values1;
long groupId = ContentUris.parseId(mChatURI);
- Uri uri = ContentUris.withAppendedId(Im.GroupMembers.CONTENT_URI, groupId);
+ Uri uri = ContentUris.withAppendedId(Imps.GroupMembers.CONTENT_URI, groupId);
mContentResolver.insert(uri, values);
insertMessageInDb(member.getName(), null, System.currentTimeMillis(),
- Im.MessageType.PRESENCE_AVAILABLE);
+ Imps.MessageType.PRESENCE_AVAILABLE);
}
void deleteGroupMemberInDb(Contact member) {
- String where = Im.GroupMembers.USERNAME + "=?";
+ String where = Imps.GroupMembers.USERNAME + "=?";
String[] selectionArgs = { member.getAddress().getFullName() };
long groupId = ContentUris.parseId(mChatURI);
- Uri uri = ContentUris.withAppendedId(Im.GroupMembers.CONTENT_URI, groupId);
+ Uri uri = ContentUris.withAppendedId(Imps.GroupMembers.CONTENT_URI, groupId);
mContentResolver.delete(uri, where, selectionArgs);
insertMessageInDb(member.getName(), null, System.currentTimeMillis(),
- Im.MessageType.PRESENCE_UNAVAILABLE);
+ Imps.MessageType.PRESENCE_UNAVAILABLE);
}
void insertPresenceUpdatesMsg(String contact, Presence presence) {
@@ -420,20 +420,20 @@ public class ChatSessionAdapter extends IChatSession.Stub {
int messageType;
switch (status) {
case Presence.AVAILABLE:
- messageType = Im.MessageType.PRESENCE_AVAILABLE;
+ messageType = Imps.MessageType.PRESENCE_AVAILABLE;
break;
case Presence.AWAY:
case Presence.IDLE:
- messageType = Im.MessageType.PRESENCE_AWAY;
+ messageType = Imps.MessageType.PRESENCE_AWAY;
break;
case Presence.DO_NOT_DISTURB:
- messageType = Im.MessageType.PRESENCE_DND;
+ messageType = Imps.MessageType.PRESENCE_DND;
break;
default:
- messageType = Im.MessageType.PRESENCE_UNAVAILABLE;
+ messageType = Imps.MessageType.PRESENCE_UNAVAILABLE;
break;
}
@@ -445,7 +445,7 @@ public class ChatSessionAdapter extends IChatSession.Stub {
}
void removeMessageInDb(int type) {
- mContentResolver.delete(mMessageURI, Im.Messages.TYPE + "=?",
+ mContentResolver.delete(mMessageURI, Imps.Messages.TYPE + "=?",
new String[]{Integer.toString(type)});
}
@@ -455,13 +455,13 @@ public class ChatSessionAdapter extends IChatSession.Stub {
Uri insertMessageInDb(String contact, String body, long time, int type, int errCode) {
ContentValues values = new ContentValues(mIsGroupChat ? 4 : 3);
- values.put(Im.Messages.BODY, body);
- values.put(Im.Messages.DATE, time);
- values.put(Im.Messages.TYPE, type);
- values.put(Im.Messages.ERROR_CODE, errCode);
+ values.put(Imps.Messages.BODY, body);
+ values.put(Imps.Messages.DATE, time);
+ values.put(Imps.Messages.TYPE, type);
+ values.put(Imps.Messages.ERROR_CODE, errCode);
if (mIsGroupChat) {
- values.put(Im.Messages.NICKNAME, contact);
- values.put(Im.Messages.IS_GROUP_CHAT, 1);
+ values.put(Imps.Messages.NICKNAME, contact);
+ values.put(Imps.Messages.IS_GROUP_CHAT, 1);
}
return mContentResolver.insert(mMessageURI, values);
@@ -479,7 +479,7 @@ public class ChatSessionAdapter extends IChatSession.Stub {
} else {
insertOrUpdateChat(body);
}
- insertMessageInDb(nickname, body, time, Im.MessageType.INCOMING);
+ insertMessageInDb(nickname, body, time, Imps.MessageType.INCOMING);
int N = mRemoteListeners.beginBroadcast();
for (int i = 0; i < N; i++) {
@@ -502,7 +502,7 @@ public class ChatSessionAdapter extends IChatSession.Stub {
public void onSendMessageError(ChatSession ses, final Message msg,
final ImErrorInfo error) {
insertMessageInDb(null, null, System.currentTimeMillis(),
- Im.MessageType.OUTGOING, error.getCode());
+ Imps.MessageType.OUTGOING, error.getCode());
final int N = mRemoteListeners.beginBroadcast();
for (int i = 0; i < N; i++) {
diff --git a/src/com/android/im/service/ContactListManagerAdapter.java b/src/com/android/im/service/ContactListManagerAdapter.java
index 3454385..47c1615 100644
--- a/src/com/android/im/service/ContactListManagerAdapter.java
+++ b/src/com/android/im/service/ContactListManagerAdapter.java
@@ -33,7 +33,6 @@ import android.database.Cursor;
import android.net.Uri;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
-import android.provider.Im;
import android.util.Log;
import android.widget.Toast;
@@ -52,6 +51,7 @@ import com.android.im.engine.ImErrorInfo;
import com.android.im.engine.ImException;
import com.android.im.engine.Presence;
import com.android.im.engine.SubscriptionRequestListener;
+import com.android.im.provider.Imps;
public class ContactListManagerAdapter extends IContactListManager.Stub {
static final String TAG = RemoteImService.TAG;
@@ -82,7 +82,7 @@ public class ContactListManagerAdapter extends IContactListManager.Stub {
private Uri mContactUrl;
static final long FAKE_TEMPORARY_LIST_ID = -1;
- static final String[] CONTACT_LIST_ID_PROJECTION = { Im.ContactList._ID };
+ static final String[] CONTACT_LIST_ID_PROJECTION = { Imps.ContactList._ID };
RemoteImService mContext;
@@ -106,13 +106,13 @@ public class ContactListManagerAdapter extends IContactListManager.Stub {
mAccountId = mConn.getAccountId();
mProviderId = mConn.getProviderId();
- Uri.Builder builder = Im.Avatars.CONTENT_URI_AVATARS_BY.buildUpon();
+ Uri.Builder builder = Imps.Avatars.CONTENT_URI_AVATARS_BY.buildUpon();
ContentUris.appendId(builder, mProviderId);
ContentUris.appendId(builder, mAccountId);
mAvatarUrl = builder.build();
- builder = Im.Contacts.CONTENT_URI_CONTACTS_BY.buildUpon();
+ builder = Imps.Contacts.CONTENT_URI_CONTACTS_BY.buildUpon();
ContentUris.appendId(builder, mProviderId);
ContentUris.appendId(builder, mAccountId);
@@ -151,7 +151,7 @@ public class ContactListManagerAdapter extends IContactListManager.Stub {
// database.
closeChatSession(address);
- String selection = Im.Contacts.USERNAME + "=?";
+ String selection = Imps.Contacts.USERNAME + "=?";
String[] selectionArgs = { address };
mResolver.delete(mContactUrl, selection, selectionArgs);
synchronized (mTemporaryContacts) {
@@ -274,9 +274,9 @@ public class ContactListManagerAdapter extends IContactListManager.Stub {
long result;
String username = c.getAddress().getFullName();
- String selection = Im.Contacts.USERNAME + "=?";
+ String selection = Imps.Contacts.USERNAME + "=?";
String[] selectionArgs = { username };
- String[] projection = {Im.Contacts._ID};
+ String[] projection = {Imps.Contacts._ID};
Cursor cursor = mResolver.query(mContactUrl, projection, selection,
selectionArgs, null);
@@ -370,13 +370,13 @@ public class ContactListManagerAdapter extends IContactListManager.Stub {
private void removeObsoleteContactsAndLists() {
// remove all contacts for this provider & account which have not been
// added since login, yet still exist in db from a prior login
- Exclusion exclusion = new Exclusion(Im.Contacts.USERNAME, mValidatedContacts);
+ Exclusion exclusion = new Exclusion(Imps.Contacts.USERNAME, mValidatedContacts);
mResolver.delete(mContactUrl, exclusion.getSelection(), exclusion.getSelectionArgs());
// remove all blocked contacts for this provider & account which have not been
// added since login, yet still exist in db from a prior login
- exclusion = new Exclusion(Im.BlockedList.USERNAME, mValidatedBlockedContacts);
- Uri.Builder builder = Im.BlockedList.CONTENT_URI.buildUpon();
+ exclusion = new Exclusion(Imps.BlockedList.USERNAME, mValidatedBlockedContacts);
+ Uri.Builder builder = Imps.BlockedList.CONTENT_URI.buildUpon();
ContentUris.appendId(builder, mProviderId);
ContentUris.appendId(builder, mAccountId);
Uri uri = builder.build();
@@ -384,8 +384,8 @@ public class ContactListManagerAdapter extends IContactListManager.Stub {
// remove all contact lists for this provider & account which have not been
// added since login, yet still exist in db from a prior login
- exclusion = new Exclusion(Im.ContactList.NAME, mValidatedContactLists);
- builder = Im.ContactList.CONTENT_URI.buildUpon();
+ exclusion = new Exclusion(Imps.ContactList.NAME, mValidatedContactLists);
+ builder = Imps.ContactList.CONTENT_URI.buildUpon();
ContentUris.appendId(builder, mProviderId);
ContentUris.appendId(builder, mAccountId);
uri = builder.build();
@@ -514,7 +514,7 @@ public class ContactListManagerAdapter extends IContactListManager.Stub {
case CONTACT_BLOCKED:
insertBlockedContactToDataBase(contact);
address = contact.getAddress().getFullName();
- updateContactType(address, Im.Contacts.TYPE_BLOCKED);
+ updateContactType(address, Imps.Contacts.TYPE_BLOCKED);
closeChatSession(address);
notificationText = mContext.getResources().getString(
R.string.block_contact_success, contact.getName());
@@ -613,8 +613,8 @@ public class ContactListManagerAdapter extends IContactListManager.Stub {
String username = from.getAddress().getFullName();
String nickname = from.getName();
Uri uri = insertOrUpdateSubscription(username, nickname,
- Im.Contacts.SUBSCRIPTION_TYPE_FROM,
- Im.Contacts.SUBSCRIPTION_STATUS_SUBSCRIBE_PENDING);
+ Imps.Contacts.SUBSCRIPTION_TYPE_FROM,
+ Imps.Contacts.SUBSCRIPTION_STATUS_SUBSCRIBE_PENDING);
mContext.getStatusBarNotifier().notifySubscriptionRequest(mProviderId, mAccountId,
ContentUris.parseId(uri), username, nickname);
final int N = mRemoteSubscriptionListeners.beginBroadcast();
@@ -633,8 +633,8 @@ public class ContactListManagerAdapter extends IContactListManager.Stub {
public void onSubscriptionApproved(final String contact) {
insertOrUpdateSubscription(contact, null,
- Im.Contacts.SUBSCRIPTION_TYPE_NONE,
- Im.Contacts.SUBSCRIPTION_STATUS_NONE);
+ Imps.Contacts.SUBSCRIPTION_TYPE_NONE,
+ Imps.Contacts.SUBSCRIPTION_STATUS_NONE);
final int N = mRemoteSubscriptionListeners.beginBroadcast();
for (int i = 0; i < N; i++) {
@@ -652,8 +652,8 @@ public class ContactListManagerAdapter extends IContactListManager.Stub {
public void onSubscriptionDeclined(final String contact) {
insertOrUpdateSubscription(contact, null,
- Im.Contacts.SUBSCRIPTION_TYPE_NONE,
- Im.Contacts.SUBSCRIPTION_STATUS_NONE);
+ Imps.Contacts.SUBSCRIPTION_TYPE_NONE,
+ Imps.Contacts.SUBSCRIPTION_STATUS_NONE);
final int N = mRemoteSubscriptionListeners.beginBroadcast();
for (int i = 0; i < N; i++) {
@@ -694,15 +694,15 @@ public class ContactListManagerAdapter extends IContactListManager.Stub {
// handle the odd case where a blocked contact's nickname has changed
removeBlockedContactFromDataBase(contact);
- Uri.Builder builder = Im.BlockedList.CONTENT_URI.buildUpon();
+ Uri.Builder builder = Imps.BlockedList.CONTENT_URI.buildUpon();
ContentUris.appendId(builder, mProviderId);
ContentUris.appendId(builder, mAccountId);
Uri uri = builder.build();
String username = contact.getAddress().getFullName();
ContentValues values = new ContentValues(2);
- values.put(Im.BlockedList.USERNAME, username);
- values.put(Im.BlockedList.NICKNAME, contact.getName());
+ values.put(Imps.BlockedList.USERNAME, username);
+ values.put(Imps.BlockedList.NICKNAME, contact.getName());
mResolver.insert(uri, values);
@@ -712,15 +712,15 @@ public class ContactListManagerAdapter extends IContactListManager.Stub {
void removeBlockedContactFromDataBase(Contact contact) {
String address = contact.getAddress().getFullName();
- Uri.Builder builder = Im.BlockedList.CONTENT_URI.buildUpon();
+ Uri.Builder builder = Imps.BlockedList.CONTENT_URI.buildUpon();
ContentUris.appendId(builder, mProviderId);
ContentUris.appendId(builder, mAccountId);
Uri uri = builder.build();
- mResolver.delete(uri, Im.BlockedList.USERNAME + "=?", new String[]{ address });
+ mResolver.delete(uri, Imps.BlockedList.USERNAME + "=?", new String[]{ address });
- int type = isTemporary(address) ? Im.Contacts.TYPE_TEMPORARY
- : Im.Contacts.TYPE_NORMAL;
+ int type = isTemporary(address) ? Imps.Contacts.TYPE_TEMPORARY
+ : Imps.Contacts.TYPE_NORMAL;
updateContactType(address, type);
}
@@ -729,11 +729,11 @@ public class ContactListManagerAdapter extends IContactListManager.Stub {
mTemporaryContacts.remove(address);
}
ContentValues values = new ContentValues(2);
- values.put(Im.Contacts.TYPE, Im.Contacts.TYPE_NORMAL);
- values.put(Im.Contacts.CONTACTLIST, listId);
+ values.put(Imps.Contacts.TYPE, Imps.Contacts.TYPE_NORMAL);
+ values.put(Imps.Contacts.CONTACTLIST, listId);
- String selection = Im.Contacts.USERNAME + "=? AND " + Im.Contacts.TYPE + "="
- + Im.Contacts.TYPE_TEMPORARY;
+ String selection = Imps.Contacts.USERNAME + "=? AND " + Imps.Contacts.TYPE + "="
+ + Imps.Contacts.TYPE_TEMPORARY;
String[] selectionArgs = { address };
mResolver.update(mContactUrl, values, selection, selectionArgs);
@@ -741,7 +741,7 @@ public class ContactListManagerAdapter extends IContactListManager.Stub {
void updateContactType(String address, int type) {
ContentValues values = new ContentValues(1);
- values.put(Im.Contacts.TYPE, type);
+ values.put(Imps.Contacts.TYPE, type);
updateContact(address, values);
}
@@ -755,8 +755,8 @@ public class ContactListManagerAdapter extends IContactListManager.Stub {
*/
Uri insertOrUpdateSubscription(String username, String nickname, int subscriptionType,
int subscriptionStatus) {
- Cursor cursor = mResolver.query(mContactUrl, new String[]{ Im.Contacts._ID },
- Im.Contacts.USERNAME + "=?", new String[]{username}, null);
+ Cursor cursor = mResolver.query(mContactUrl, new String[]{ Imps.Contacts._ID },
+ Imps.Contacts.USERNAME + "=?", new String[]{username}, null);
if (cursor == null) {
Log.w(TAG, "query contact " + username + " failed");
return null;
@@ -765,20 +765,20 @@ public class ContactListManagerAdapter extends IContactListManager.Stub {
Uri uri;
if (cursor.moveToFirst()) {
ContentValues values = new ContentValues(2);
- values.put(Im.Contacts.SUBSCRIPTION_TYPE, subscriptionType);
- values.put(Im.Contacts.SUBSCRIPTION_STATUS, subscriptionStatus);
+ values.put(Imps.Contacts.SUBSCRIPTION_TYPE, subscriptionType);
+ values.put(Imps.Contacts.SUBSCRIPTION_STATUS, subscriptionStatus);
long contactId = cursor.getLong(0);
- uri = ContentUris.withAppendedId(Im.Contacts.CONTENT_URI, contactId);
+ uri = ContentUris.withAppendedId(Imps.Contacts.CONTENT_URI, contactId);
mResolver.update(uri, values, null, null);
} else {
ContentValues values = new ContentValues(6);
- values.put(Im.Contacts.USERNAME, username);
- values.put(Im.Contacts.NICKNAME, nickname);
- values.put(Im.Contacts.TYPE, Im.Contacts.TYPE_NORMAL);
- values.put(Im.Contacts.CONTACTLIST, FAKE_TEMPORARY_LIST_ID);
- values.put(Im.Contacts.SUBSCRIPTION_TYPE, subscriptionType);
- values.put(Im.Contacts.SUBSCRIPTION_STATUS, subscriptionStatus);
+ values.put(Imps.Contacts.USERNAME, username);
+ values.put(Imps.Contacts.NICKNAME, nickname);
+ values.put(Imps.Contacts.TYPE, Imps.Contacts.TYPE_NORMAL);
+ values.put(Imps.Contacts.CONTACTLIST, FAKE_TEMPORARY_LIST_ID);
+ values.put(Imps.Contacts.SUBSCRIPTION_TYPE, subscriptionType);
+ values.put(Imps.Contacts.SUBSCRIPTION_STATUS, subscriptionStatus);
uri = mResolver.insert(mContactUrl, values);
}
@@ -787,7 +787,7 @@ public class ContactListManagerAdapter extends IContactListManager.Stub {
}
void updateContact(String username, ContentValues values) {
- String selection = Im.Contacts.USERNAME + "=?";
+ String selection = Imps.Contacts.USERNAME + "=?";
String[] selectionArgs = { username };
mResolver.update(mContactUrl, values, selection, selectionArgs);
}
@@ -812,13 +812,13 @@ public class ContactListManagerAdapter extends IContactListManager.Stub {
}
ContentValues values = new ContentValues();
- values.put(Im.Contacts.ACCOUNT, mAccountId);
- values.putStringArrayList(Im.Contacts.USERNAME, usernames);
- values.putStringArrayList(Im.Presence.PRESENCE_STATUS, statusArray);
- values.putStringArrayList(Im.Presence.PRESENCE_CUSTOM_STATUS, customStatusArray);
- values.putStringArrayList(Im.Presence.CONTENT_TYPE, clientTypeArray);
+ values.put(Imps.Contacts.ACCOUNT, mAccountId);
+ values.putStringArrayList(Imps.Contacts.USERNAME, usernames);
+ values.putStringArrayList(Imps.Presence.PRESENCE_STATUS, statusArray);
+ values.putStringArrayList(Imps.Presence.PRESENCE_CUSTOM_STATUS, customStatusArray);
+ values.putStringArrayList(Imps.Presence.CONTENT_TYPE, clientTypeArray);
- mResolver.update(Im.Presence.BULK_CONTENT_URI, values, null, null);
+ mResolver.update(Imps.Presence.BULK_CONTENT_URI, values, null, null);
}
void updateAvatarsContent(Contact[] contacts) {
@@ -834,8 +834,8 @@ public class ContactListManagerAdapter extends IContactListManager.Stub {
String username = contact.getAddress().getFullName();
ContentValues values = new ContentValues(2);
- values.put(Im.Avatars.CONTACT, username);
- values.put(Im.Avatars.DATA, avatarData);
+ values.put(Imps.Avatars.CONTACT, username);
+ values.put(Imps.Avatars.DATA, avatarData);
avatars.add(values);
usernames.add(username);
}
@@ -862,22 +862,22 @@ public class ContactListManagerAdapter extends IContactListManager.Stub {
// delete contacts of this list first
mResolver.delete(mContactUrl,
- Im.Contacts.CONTACTLIST + "=?", new String[]{Long.toString(id)});
+ Imps.Contacts.CONTACTLIST + "=?", new String[]{Long.toString(id)});
- mResolver.delete(ContentUris.withAppendedId(Im.ContactList.CONTENT_URI, id), null, null);
+ mResolver.delete(ContentUris.withAppendedId(Imps.ContactList.CONTENT_URI, id), null, null);
synchronized (mContactLists) {
return mContactLists.remove(listAdapter.getAddress());
}
}
void addContactListContent(ContactList list) {
- String selection = Im.ContactList.NAME + "=? AND "
- + Im.ContactList.PROVIDER + "=? AND "
- + Im.ContactList.ACCOUNT + "=?";
+ String selection = Imps.ContactList.NAME + "=? AND "
+ + Imps.ContactList.PROVIDER + "=? AND "
+ + Imps.ContactList.ACCOUNT + "=?";
String[] selectionArgs = { list.getName(),
Long.toString(mProviderId),
Long.toString(mAccountId) };
- Cursor cursor = mResolver.query(Im.ContactList.CONTENT_URI,
+ Cursor cursor = mResolver.query(Imps.ContactList.CONTENT_URI,
CONTACT_LIST_ID_PROJECTION,
selection,
selectionArgs,
@@ -887,7 +887,7 @@ public class ContactListManagerAdapter extends IContactListManager.Stub {
try {
if (cursor.moveToFirst()) {
listId = cursor.getLong(0);
- uri = ContentUris.withAppendedId(Im.ContactList.CONTENT_URI, listId);
+ uri = ContentUris.withAppendedId(Imps.ContactList.CONTENT_URI, listId);
//Log.d(TAG,"Found and removing ContactList with name "+list.getName());
}
} finally {
@@ -896,19 +896,19 @@ public class ContactListManagerAdapter extends IContactListManager.Stub {
if (uri != null) {
// remove existing ContactList and Contacts of that list for replacement by the newly
// downloaded list
- mResolver.delete(mContactUrl, Im.Contacts.CONTACTLIST + "=?",
+ mResolver.delete(mContactUrl, Imps.Contacts.CONTACTLIST + "=?",
new String[]{Long.toString(listId)});
mResolver.delete(uri, selection, selectionArgs);
}
ContentValues contactListValues = new ContentValues(3);
- contactListValues.put(Im.ContactList.NAME, list.getName());
- contactListValues.put(Im.ContactList.PROVIDER, mProviderId);
- contactListValues.put(Im.ContactList.ACCOUNT, mAccountId);
+ contactListValues.put(Imps.ContactList.NAME, list.getName());
+ contactListValues.put(Imps.ContactList.PROVIDER, mProviderId);
+ contactListValues.put(Imps.ContactList.ACCOUNT, mAccountId);
//Log.d(TAG, "Adding ContactList name="+list.getName());
mValidatedContactLists.add(list.getName());
- uri = mResolver.insert(Im.ContactList.CONTENT_URI, contactListValues);
+ uri = mResolver.insert(Imps.ContactList.CONTENT_URI, contactListValues);
listId = ContentUris.parseId(uri);
synchronized (mContactLists) {
@@ -938,12 +938,12 @@ public class ContactListManagerAdapter extends IContactListManager.Stub {
for (Contact c : contacts) {
String username = c.getAddress().getFullName();
String nickname = c.getName();
- int type = Im.Contacts.TYPE_NORMAL;
+ int type = Imps.Contacts.TYPE_NORMAL;
if(isTemporary(username)) {
- type = Im.Contacts.TYPE_TEMPORARY;
+ type = Imps.Contacts.TYPE_TEMPORARY;
}
if (isBlocked(username)) {
- type = Im.Contacts.TYPE_BLOCKED;
+ type = Imps.Contacts.TYPE_BLOCKED;
}
usernames.add(username);
@@ -952,29 +952,29 @@ public class ContactListManagerAdapter extends IContactListManager.Stub {
}
ContentValues values = new ContentValues(6);
- values.put(Im.Contacts.PROVIDER, mProviderId);
- values.put(Im.Contacts.ACCOUNT, mAccountId);
- values.put(Im.Contacts.CONTACTLIST, listId);
- values.putStringArrayList(Im.Contacts.USERNAME, usernames);
- values.putStringArrayList(Im.Contacts.NICKNAME, nicknames);
- values.putStringArrayList(Im.Contacts.TYPE, contactTypeArray);
+ values.put(Imps.Contacts.PROVIDER, mProviderId);
+ values.put(Imps.Contacts.ACCOUNT, mAccountId);
+ values.put(Imps.Contacts.CONTACTLIST, listId);
+ values.putStringArrayList(Imps.Contacts.USERNAME, usernames);
+ values.putStringArrayList(Imps.Contacts.NICKNAME, nicknames);
+ values.putStringArrayList(Imps.Contacts.TYPE, contactTypeArray);
- mResolver.insert(Im.Contacts.BULK_CONTENT_URI, values);
+ mResolver.insert(Imps.Contacts.BULK_CONTENT_URI, values);
}
void updateListNameInDataBase(ContactList list) {
ContactListAdapter listAdapter = getContactListAdapter(list.getAddress());
- Uri uri = ContentUris.withAppendedId(Im.ContactList.CONTENT_URI, listAdapter.getDataBaseId());
+ Uri uri = ContentUris.withAppendedId(Imps.ContactList.CONTENT_URI, listAdapter.getDataBaseId());
ContentValues values = new ContentValues(1);
- values.put(Im.ContactList.NAME, list.getName());
+ values.put(Imps.ContactList.NAME, list.getName());
mResolver.update(uri, values, null, null);
}
void deleteContactFromDataBase(Contact contact, ContactList list) {
- String selection = Im.Contacts.USERNAME
- + "=? AND " + Im.Contacts.CONTACTLIST + "=?";
+ String selection = Imps.Contacts.USERNAME
+ + "=? AND " + Imps.Contacts.CONTACTLIST + "=?";
long listId = getContactListAdapter(list.getAddress()).getDataBaseId();
String username = contact.getAddress().getFullName();
String[] selectionArgs = {username, Long.toString(listId)};
@@ -996,7 +996,7 @@ public class ContactListManagerAdapter extends IContactListManager.Stub {
ContentValues presenceValues = getPresenceValues(ContentUris.parseId(uri),
contact.getPresence());
- mResolver.insert(Im.Presence.CONTENT_URI, presenceValues);
+ mResolver.insert(Imps.Presence.CONTENT_URI, presenceValues);
return uri;
}
@@ -1004,33 +1004,33 @@ public class ContactListManagerAdapter extends IContactListManager.Stub {
private ContentValues getContactContentValues(Contact contact, long listId) {
final String username = contact.getAddress().getFullName();
final String nickname = contact.getName();
- int type = Im.Contacts.TYPE_NORMAL;
+ int type = Imps.Contacts.TYPE_NORMAL;
if(isTemporary(username)) {
- type = Im.Contacts.TYPE_TEMPORARY;
+ type = Imps.Contacts.TYPE_TEMPORARY;
}
if (isBlocked(username)) {
- type = Im.Contacts.TYPE_BLOCKED;
+ type = Imps.Contacts.TYPE_BLOCKED;
}
ContentValues values = new ContentValues(4);
- values.put(Im.Contacts.USERNAME, username);
- values.put(Im.Contacts.NICKNAME, nickname);
- values.put(Im.Contacts.CONTACTLIST, listId);
- values.put(Im.Contacts.TYPE, type);
+ values.put(Imps.Contacts.USERNAME, username);
+ values.put(Imps.Contacts.NICKNAME, nickname);
+ values.put(Imps.Contacts.CONTACTLIST, listId);
+ values.put(Imps.Contacts.TYPE, type);
return values;
}
void clearHistoryMessages(String contact) {
- Uri uri = Im.Messages.getContentUriByContact(mAccountId, contact);
+ Uri uri = Imps.Messages.getContentUriByContact(mAccountId, contact);
mResolver.delete(uri, null, null);
}
private ContentValues getPresenceValues(long contactId, Presence p) {
ContentValues values = new ContentValues(3);
- values.put(Im.Presence.CONTACT_ID, contactId);
- values.put(Im.Contacts.PRESENCE_STATUS, convertPresenceStatus(p));
- values.put(Im.Contacts.PRESENCE_CUSTOM_STATUS, p.getStatusText());
- values.put(Im.Presence.CLIENT_TYPE, translateClientType(p));
+ values.put(Imps.Presence.CONTACT_ID, contactId);
+ values.put(Imps.Contacts.PRESENCE_STATUS, convertPresenceStatus(p));
+ values.put(Imps.Contacts.PRESENCE_CUSTOM_STATUS, p.getStatusText());
+ values.put(Imps.Presence.CLIENT_TYPE, translateClientType(p));
return values;
}
@@ -1038,9 +1038,9 @@ public class ContactListManagerAdapter extends IContactListManager.Stub {
int clientType = presence.getClientType();
switch (clientType) {
case Presence.CLIENT_TYPE_MOBILE:
- return Im.Presence.CLIENT_TYPE_MOBILE;
+ return Imps.Presence.CLIENT_TYPE_MOBILE;
default:
- return Im.Presence.CLIENT_TYPE_DEFAULT;
+ return Imps.Presence.CLIENT_TYPE_DEFAULT;
}
}
@@ -1053,24 +1053,24 @@ public class ContactListManagerAdapter extends IContactListManager.Stub {
public static int convertPresenceStatus(Presence presence) {
switch (presence.getStatus()) {
case Presence.AVAILABLE:
- return Im.Presence.AVAILABLE;
+ return Imps.Presence.AVAILABLE;
case Presence.IDLE:
- return Im.Presence.IDLE;
+ return Imps.Presence.IDLE;
case Presence.AWAY:
- return Im.Presence.AWAY;
+ return Imps.Presence.AWAY;
case Presence.DO_NOT_DISTURB:
- return Im.Presence.DO_NOT_DISTURB;
+ return Imps.Presence.DO_NOT_DISTURB;
case Presence.OFFLINE:
- return Im.Presence.OFFLINE;
+ return Imps.Presence.OFFLINE;
}
// impossible...
Log.e(TAG, "Illegal presence status value " + presence.getStatus());
- return Im.Presence.AVAILABLE;
+ return Imps.Presence.AVAILABLE;
}
public void clearOnLogout() {
@@ -1098,7 +1098,7 @@ public class ContactListManagerAdapter extends IContactListManager.Stub {
* IM sessions, the temporary contacts need to be cleared after logout.
*/
private void clearTemporaryContacts() {
- String selection = Im.Contacts.CONTACTLIST + "=" + FAKE_TEMPORARY_LIST_ID;
+ String selection = Imps.Contacts.CONTACTLIST + "=" + FAKE_TEMPORARY_LIST_ID;
mResolver.delete(mContactUrl, selection, null);
}
@@ -1108,13 +1108,13 @@ public class ContactListManagerAdapter extends IContactListManager.Stub {
*/
void clearPresence() {
StringBuilder where = new StringBuilder();
- where.append(Im.Presence.CONTACT_ID);
+ where.append(Imps.Presence.CONTACT_ID);
where.append(" in (select _id from contacts where ");
- where.append(Im.Contacts.ACCOUNT);
+ where.append(Imps.Contacts.ACCOUNT);
where.append("=");
where.append(mAccountId);
where.append(")");
- mResolver.delete(Im.Presence.CONTENT_URI, where.toString(), null);
+ mResolver.delete(Imps.Presence.CONTENT_URI, where.toString(), null);
}
void closeChatSession(String address) {
diff --git a/src/com/android/im/service/ImConnectionAdapter.java b/src/com/android/im/service/ImConnectionAdapter.java
index 7b97ac6..e8bbc31 100644
--- a/src/com/android/im/service/ImConnectionAdapter.java
+++ b/src/com/android/im/service/ImConnectionAdapter.java
@@ -27,7 +27,6 @@ import android.database.Cursor;
import android.net.Uri;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
-import android.provider.Im;
import android.util.Log;
import com.android.im.IChatSessionManager;
@@ -46,13 +45,14 @@ import com.android.im.engine.Invitation;
import com.android.im.engine.InvitationListener;
import com.android.im.engine.LoginInfo;
import com.android.im.engine.Presence;
+import com.android.im.provider.Imps;
public class ImConnectionAdapter extends IImConnection.Stub {
private static final String TAG = RemoteImService.TAG;
private static final String[] SESSION_COOKIE_PROJECTION = {
- Im.SessionCookies.NAME,
- Im.SessionCookies.VALUE,
+ Imps.SessionCookies.NAME,
+ Imps.SessionCookies.VALUE,
};
private static final int COLUMN_SESSION_COOKIE_NAME = 0;
@@ -133,7 +133,7 @@ public class ImConnectionAdapter extends IImConnection.Stub {
}
private Uri getSessionCookiesUri() {
- Uri.Builder builder = Im.SessionCookies.CONTENT_URI_SESSION_COOKIES_BY.buildUpon();
+ Uri.Builder builder = Imps.SessionCookies.CONTENT_URI_SESSION_COOKIES_BY.buildUpon();
ContentUris.appendId(builder, mProviderId);
ContentUris.appendId(builder, mAccountId);
@@ -258,21 +258,21 @@ public class ImConnectionAdapter extends IImConnection.Stub {
return;
}
ContentResolver cr = mService.getContentResolver();
- Cursor c = cr.query(ContentUris.withAppendedId(Im.Invitation.CONTENT_URI, id), null, null, null, null);
+ Cursor c = cr.query(ContentUris.withAppendedId(Imps.Invitation.CONTENT_URI, id), null, null, null, null);
if(c == null) {
return;
}
if(c.moveToFirst()) {
- String inviteId = c.getString(c.getColumnIndexOrThrow(Im.Invitation.INVITE_ID));
+ String inviteId = c.getString(c.getColumnIndexOrThrow(Imps.Invitation.INVITE_ID));
int status;
if(accept) {
mGroupManager.acceptInvitationAsync(inviteId);
- status = Im.Invitation.STATUS_ACCEPTED;
+ status = Imps.Invitation.STATUS_ACCEPTED;
} else {
mGroupManager.rejectInvitationAsync(inviteId);
- status = Im.Invitation.STATUS_REJECTED;
+ status = Imps.Invitation.STATUS_REJECTED;
}
- c.updateInt(c.getColumnIndexOrThrow(Im.Invitation.STATUS), status);
+ c.updateInt(c.getColumnIndexOrThrow(Imps.Invitation.STATUS), status);
c.commitUpdates();
}
c.close();
@@ -287,8 +287,8 @@ public class ImConnectionAdapter extends IImConnection.Stub {
for(Map.Entry<String,String> entry : cookies.entrySet()){
ContentValues values = new ContentValues(2);
- values.put(Im.SessionCookies.NAME, entry.getKey());
- values.put(Im.SessionCookies.VALUE, entry.getValue());
+ values.put(Imps.SessionCookies.NAME, entry.getKey());
+ values.put(Imps.SessionCookies.VALUE, entry.getValue());
valuesList[i++] = values;
}
@@ -302,7 +302,7 @@ public class ImConnectionAdapter extends IImConnection.Stub {
void updateAccountStatusInDb() {
Presence p = getUserPresence();
- int presenceStatus = Im.Presence.OFFLINE;
+ int presenceStatus = Imps.Presence.OFFLINE;
int connectionStatus = convertConnStateForDb(mConnectionState);
if (p != null) {
@@ -310,12 +310,12 @@ public class ImConnectionAdapter extends IImConnection.Stub {
}
ContentResolver cr = mService.getContentResolver();
- Uri uri = Im.AccountStatus.CONTENT_URI;
+ Uri uri = Imps.AccountStatus.CONTENT_URI;
ContentValues values = new ContentValues();
- values.put(Im.AccountStatus.ACCOUNT, mAccountId);
- values.put(Im.AccountStatus.PRESENCE_STATUS, presenceStatus);
- values.put(Im.AccountStatus.CONNECTION_STATUS, connectionStatus);
+ values.put(Imps.AccountStatus.ACCOUNT, mAccountId);
+ values.put(Imps.AccountStatus.PRESENCE_STATUS, presenceStatus);
+ values.put(Imps.AccountStatus.CONNECTION_STATUS, connectionStatus);
cr.insert(uri, values);
}
@@ -324,20 +324,20 @@ public class ImConnectionAdapter extends IImConnection.Stub {
switch (state) {
case ImConnection.DISCONNECTED:
case ImConnection.LOGGING_OUT:
- return Im.ConnectionStatus.OFFLINE;
+ return Imps.ConnectionStatus.OFFLINE;
case ImConnection.LOGGING_IN:
- return Im.ConnectionStatus.CONNECTING;
+ return Imps.ConnectionStatus.CONNECTING;
case ImConnection.LOGGED_IN:
- return Im.ConnectionStatus.ONLINE;
+ return Imps.ConnectionStatus.ONLINE;
case ImConnection.SUSPENDED:
case ImConnection.SUSPENDING:
- return Im.ConnectionStatus.SUSPENDED;
+ return Imps.ConnectionStatus.SUSPENDED;
default:
- return Im.ConnectionStatus.OFFLINE;
+ return Imps.ConnectionStatus.OFFLINE;
}
}
@@ -449,15 +449,15 @@ public class ImConnectionAdapter extends IImConnection.Stub {
public void onGroupInvitation(Invitation invitation) {
String sender = invitation.getSender().getScreenName();
ContentValues values = new ContentValues(7);
- values.put(Im.Invitation.PROVIDER, mProviderId);
- values.put(Im.Invitation.ACCOUNT, mAccountId);
- values.put(Im.Invitation.INVITE_ID, invitation.getInviteID());
- values.put(Im.Invitation.SENDER, sender);
- values.put(Im.Invitation.GROUP_NAME, invitation.getGroupAddress().getScreenName());
- values.put(Im.Invitation.NOTE, invitation.getReason());
- values.put(Im.Invitation.STATUS, Im.Invitation.STATUS_PENDING);
+ values.put(Imps.Invitation.PROVIDER, mProviderId);
+ values.put(Imps.Invitation.ACCOUNT, mAccountId);
+ values.put(Imps.Invitation.INVITE_ID, invitation.getInviteID());
+ values.put(Imps.Invitation.SENDER, sender);
+ values.put(Imps.Invitation.GROUP_NAME, invitation.getGroupAddress().getScreenName());
+ values.put(Imps.Invitation.NOTE, invitation.getReason());
+ values.put(Imps.Invitation.STATUS, Imps.Invitation.STATUS_PENDING);
ContentResolver resolver = mService.getContentResolver();
- Uri uri = resolver.insert(Im.Invitation.CONTENT_URI, values);
+ Uri uri = resolver.insert(Imps.Invitation.CONTENT_URI, values);
long id = ContentUris.parseId(uri);
try {
if (mRemoteListener != null) {
diff --git a/src/com/android/im/service/RemoteImService.java b/src/com/android/im/service/RemoteImService.java
index ea1cb85..5764f1e 100644
--- a/src/com/android/im/service/RemoteImService.java
+++ b/src/com/android/im/service/RemoteImService.java
@@ -44,7 +44,6 @@ import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.SystemProperties;
-import android.provider.Im;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
@@ -61,15 +60,16 @@ import com.android.im.imps.ImpsConnectionConfig;
import com.android.im.plugin.ImConfigNames;
import com.android.im.plugin.ImPluginInfo;
import com.android.im.plugin.ImpsConfigNames;
+import com.android.im.provider.Imps;
public class RemoteImService extends Service {
private static final String[] ACCOUNT_PROJECTION = {
- Im.Account._ID,
- Im.Account.PROVIDER,
- Im.Account.USERNAME,
- Im.Account.PASSWORD,
+ Imps.Account._ID,
+ Imps.Account.PROVIDER,
+ Imps.Account.USERNAME,
+ Imps.Account.PASSWORD,
};
private static final int ACCOUNT_ID_COLUMN = 0;
private static final int ACCOUNT_PROVIDER_COLUMN = 1;
@@ -146,8 +146,8 @@ public class RemoteImService extends Service {
ContentResolver resolver = getContentResolver();
- String where = Im.Account.KEEP_SIGNED_IN + "=1 AND " + Im.Account.ACTIVE + "=1";
- Cursor cursor = resolver.query(Im.Account.CONTENT_URI,
+ String where = Imps.Account.KEEP_SIGNED_IN + "=1 AND " + Imps.Account.ACTIVE + "=1";
+ Cursor cursor = resolver.query(Imps.Account.CONTENT_URI,
ACCOUNT_PROJECTION, where, null, null);
if (cursor == null) {
Log.w(TAG, "Can't query account!");
@@ -172,7 +172,7 @@ public class RemoteImService extends Service {
private Map<String, String> loadProviderSettings(long providerId) {
ContentResolver cr = getContentResolver();
- Map<String, String> settings = Im.ProviderSettings.queryProviderSettings(cr, providerId);
+ Map<String, String> settings = Imps.ProviderSettings.queryProviderSettings(cr, providerId);
NetworkInfo networkInfo = mNetworkConnectivityListener.getNetworkInfo();
// Insert a fake msisdn on emulator. We don't need this on device
diff --git a/src/com/android/im/service/StatusBarNotifier.java b/src/com/android/im/service/StatusBarNotifier.java
index fb3d1ba..071969e 100644
--- a/src/com/android/im/service/StatusBarNotifier.java
+++ b/src/com/android/im/service/StatusBarNotifier.java
@@ -28,13 +28,13 @@ import android.content.Intent;
import android.net.Uri;
import android.os.Handler;
import android.os.SystemClock;
-import android.provider.Im;
import android.text.TextUtils;
import android.util.Log;
import com.android.im.R;
import com.android.im.app.ContactListActivity;
import com.android.im.app.NewChatActivity;
+import com.android.im.provider.Imps;
public class StatusBarNotifier {
private static final boolean DBG = false;
@@ -46,7 +46,7 @@ public class StatusBarNotifier {
private Context mContext;
private NotificationManager mNotificationManager;
- private HashMap<Long, Im.ProviderSettings.QueryMap> mSettings;
+ private HashMap<Long, Imps.ProviderSettings.QueryMap> mSettings;
private Handler mHandler;
private HashMap<Long, NotificationInfo> mNotificationInfos;
private long mLastSoundPlayedMs;
@@ -55,13 +55,13 @@ public class StatusBarNotifier {
mContext = context;
mNotificationManager = (NotificationManager) context.getSystemService(
Context.NOTIFICATION_SERVICE);
- mSettings = new HashMap<Long, Im.ProviderSettings.QueryMap>();
+ mSettings = new HashMap<Long, Imps.ProviderSettings.QueryMap>();
mHandler = new Handler();
mNotificationInfos = new HashMap<Long, NotificationInfo>();
}
public void onServiceStop() {
- for(Im.ProviderSettings.QueryMap queryMap : mSettings.values()) {
+ for(Imps.ProviderSettings.QueryMap queryMap : mSettings.values()) {
queryMap.close();
}
}
@@ -76,7 +76,7 @@ public class StatusBarNotifier {
String title = nickname;
String snippet = nickname + ": " + msg;
Intent intent = new Intent(Intent.ACTION_VIEW,
- ContentUris.withAppendedId(Im.Chats.CONTENT_URI, chatId));
+ ContentUris.withAppendedId(Imps.Chats.CONTENT_URI, chatId));
intent.addCategory(com.android.im.app.ImApp.IMPS_CATEGORY);
notify(username, title, snippet, msg, providerId, accountId, intent, lightWeightNotify);
}
@@ -90,7 +90,7 @@ public class StatusBarNotifier {
String title = nickname;
String message = mContext.getString(R.string.subscription_notify_text, nickname);
Intent intent = new Intent(ImServiceConstants.ACTION_MANAGE_SUBSCRIPTION,
- ContentUris.withAppendedId(Im.Contacts.CONTENT_URI, contactId));
+ ContentUris.withAppendedId(Imps.Contacts.CONTENT_URI, contactId));
intent.putExtra(ImServiceConstants.EXTRA_INTENT_PROVIDER_ID, providerId);
intent.putExtra(ImServiceConstants.EXTRA_INTENT_FROM_ADDRESS, username);
notify(username, title, message, message, providerId, accountId, intent, false);
@@ -100,7 +100,7 @@ public class StatusBarNotifier {
long invitationId, String username) {
Intent intent = new Intent(Intent.ACTION_VIEW,
- ContentUris.withAppendedId(Im.Invitation.CONTENT_URI, invitationId));
+ ContentUris.withAppendedId(Imps.Invitation.CONTENT_URI, invitationId));
String title = mContext.getString(R.string.notify_groupchat_label);
String message = mContext.getString(
@@ -146,10 +146,10 @@ public class StatusBarNotifier {
}
}
- private Im.ProviderSettings.QueryMap getProviderSettings(long providerId) {
- Im.ProviderSettings.QueryMap res = mSettings.get(providerId);
+ private Imps.ProviderSettings.QueryMap getProviderSettings(long providerId) {
+ Imps.ProviderSettings.QueryMap res = mSettings.get(providerId);
if (res == null) {
- res = new Im.ProviderSettings.QueryMap(mContext.getContentResolver(),
+ res = new Imps.ProviderSettings.QueryMap(mContext.getContentResolver(),
providerId, true, mHandler);
mSettings.put(providerId, res);
}
@@ -157,7 +157,7 @@ public class StatusBarNotifier {
}
private boolean isNotificationEnabled(long providerId) {
- Im.ProviderSettings.QueryMap settings = getProviderSettings(providerId);
+ Imps.ProviderSettings.QueryMap settings = getProviderSettings(providerId);
return settings.getEnableNotification();
}
@@ -178,7 +178,7 @@ public class StatusBarNotifier {
}
private void setRinger(long providerId, Notification notification) {
- Im.ProviderSettings.QueryMap settings = getProviderSettings(providerId);
+ Imps.ProviderSettings.QueryMap settings = getProviderSettings(providerId);
String ringtoneUri = settings.getRingtoneURI();
boolean vibrate = settings.getVibrate();
@@ -262,7 +262,7 @@ public class StatusBarNotifier {
private Intent getDefaultIntent() {
Intent intent = new Intent(Intent.ACTION_VIEW);
- intent.setType(Im.Contacts.CONTENT_TYPE);
+ intent.setType(Imps.Contacts.CONTENT_TYPE);
intent.setClass(mContext, ContactListActivity.class);
intent.putExtra(ImServiceConstants.EXTRA_INTENT_ACCOUNT_ID, mAccountId);
@@ -287,7 +287,7 @@ public class StatusBarNotifier {
return item.mTitle;
} else {
return mContext.getString(R.string.newMessages_label,
- Im.Provider.getProviderNameForId(mContext.getContentResolver(), mProviderId));
+ Imps.Provider.getProviderNameForId(mContext.getContentResolver(), mProviderId));
}
}