• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /*
2   * Copyright (C) 2007 The Android Open Source Project
3   *
4   * Licensed under the Apache License, Version 2.0 (the "License");
5   * you may not use this file except in compliance with the License.
6   * You may obtain a copy of the License at
7   *
8   *      http://www.apache.org/licenses/LICENSE-2.0
9   *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package com.android.im.provider;
18  
19  import android.content.ContentQueryMap;
20  import android.content.ContentResolver;
21  import android.content.ContentUris;
22  import android.content.ContentValues;
23  import android.database.Cursor;
24  import android.net.Uri;
25  import android.os.Handler;
26  import android.provider.BaseColumns;
27  
28  import java.util.HashMap;
29  
30  /**
31   * The IM provider stores all information about roster contacts, chat messages, presence, etc.
32   *
33   * @hide
34   */
35  public class Imps {
36      /**
37       * no public constructor since this is a utility class
38       */
Imps()39      private Imps() {}
40  
41      /**
42       * The Columns for IM providers (i.e. AIM, Y!, GTalk)
43       */
44      public interface ProviderColumns {
45          /**
46           * The name of the IM provider
47           * <P>Type: TEXT</P>
48           */
49          String NAME = "name";
50  
51          /**
52           * The full name of the provider
53           * <P>Type: TEXT</P>
54           */
55          String FULLNAME = "fullname";
56  
57          /**
58           * The category for the provider, used to form intent.
59           * <P>Type: TEXT</P>
60           */
61          String CATEGORY = "category";
62  
63          /**
64           * The url users should visit to create a new account for this provider
65           * <P>Type: TEXT</P>
66           */
67          String SIGNUP_URL = "signup_url";
68      }
69  
70      /**
71       * Known names corresponding to the {@link ProviderColumns#NAME} column
72       */
73      public interface ProviderNames {
74          //
75          //NOTE: update Contacts.java with new providers when they're added.
76          //
77          String YAHOO = "Yahoo";
78          String GTALK = "GTalk";
79          String MSN = "MSN";
80          String ICQ = "ICQ";
81          String AIM = "AIM";
82          String XMPP = "XMPP";
83          String JABBER = "JABBER";
84          String SKYPE = "SKYPE";
85          String QQ = "QQ";
86      }
87  
88      /**
89       * This table contains the IM providers
90       */
91      public static final class Provider implements BaseColumns, ProviderColumns {
Provider()92          private Provider() {}
93  
getProviderIdForName(ContentResolver cr, String providerName)94          public static final long getProviderIdForName(ContentResolver cr, String providerName) {
95              String[] selectionArgs = new String[1];
96              selectionArgs[0] = providerName;
97  
98              Cursor cursor = cr.query(CONTENT_URI,
99                      PROVIDER_PROJECTION,
100                      NAME+"=?",
101                      selectionArgs, null);
102  
103              long retVal = 0;
104              try {
105                  if (cursor.moveToFirst()) {
106                      retVal = cursor.getLong(cursor.getColumnIndexOrThrow(_ID));
107                  }
108              } finally {
109                  cursor.close();
110              }
111  
112              return retVal;
113          }
114  
getProviderNameForId(ContentResolver cr, long providerId)115          public static final String getProviderNameForId(ContentResolver cr, long providerId) {
116              Cursor cursor = cr.query(CONTENT_URI,
117                      PROVIDER_PROJECTION,
118                      _ID + "=" + providerId,
119                      null, null);
120  
121              String retVal = null;
122              try {
123                  if (cursor.moveToFirst()) {
124                      retVal = cursor.getString(cursor.getColumnIndexOrThrow(NAME));
125                  }
126              } finally {
127                  cursor.close();
128              }
129  
130              return retVal;
131          }
132  
133          private static final String[] PROVIDER_PROJECTION = new String[] {
134                  _ID,
135                  NAME
136          };
137  
138          public static final String ACTIVE_ACCOUNT_ID = "account_id";
139          public static final String ACTIVE_ACCOUNT_USERNAME = "account_username";
140          public static final String ACTIVE_ACCOUNT_PW = "account_pw";
141          public static final String ACTIVE_ACCOUNT_LOCKED = "account_locked";
142          public static final String ACTIVE_ACCOUNT_KEEP_SIGNED_IN = "account_keepSignedIn";
143          public static final String ACCOUNT_PRESENCE_STATUS = "account_presenceStatus";
144          public static final String ACCOUNT_CONNECTION_STATUS = "account_connStatus";
145  
146          /**
147           * The content:// style URL for this table
148           */
149          public static final Uri CONTENT_URI =
150              Uri.parse("content://imps/providers");
151  
152          public static final Uri CONTENT_URI_WITH_ACCOUNT =
153              Uri.parse("content://imps/providers/account");
154  
155          /**
156           * The MIME type of {@link #CONTENT_URI} providing a directory of
157           * people.
158           */
159          public static final String CONTENT_TYPE =
160                  "vnd.android.cursor.dir/imps-providers";
161  
162          public static final String CONTENT_ITEM_TYPE =
163                  "vnd.android.cursor.item/imps-providers";
164  
165          /**
166           * The default sort order for this table
167           */
168          public static final String DEFAULT_SORT_ORDER = "name ASC";
169      }
170  
171      /**
172       * The columns for IM accounts. There can be more than one account for each IM provider.
173       */
174      public interface AccountColumns {
175          /**
176           * The name of the account
177           * <P>Type: TEXT</P>
178           */
179          String NAME = "name";
180  
181          /**
182           * The IM provider for this account
183           * <P>Type: INTEGER</P>
184           */
185          String PROVIDER = "provider";
186  
187          /**
188           * The username for this account
189           * <P>Type: TEXT</P>
190           */
191          String USERNAME = "username";
192  
193          /**
194           * The password for this account
195           * <P>Type: TEXT</P>
196           */
197          String PASSWORD = "pw";
198  
199          /**
200           * A boolean value indicates if the account is active.
201           * <P>Type: INTEGER</P>
202           */
203          String ACTIVE = "active";
204  
205          /**
206           * A boolean value indicates if the account is locked (not editable)
207           * <P>Type: INTEGER</P>
208           */
209          String LOCKED = "locked";
210  
211          /**
212           * A boolean value to indicate whether this account is kept signed in.
213           * <P>Type: INTEGER</P>
214           */
215          String KEEP_SIGNED_IN = "keep_signed_in";
216  
217          /**
218           * A boolean value indiciating the last login state for this account
219           * <P>Type: INTEGER</P>
220           */
221          String LAST_LOGIN_STATE = "last_login_state";
222      }
223  
224      /**
225       * This table contains the IM accounts.
226       */
227      public static final class Account implements BaseColumns, AccountColumns {
Account()228          private Account() {}
229  
getProviderIdForAccount(ContentResolver cr, long accountId)230          public static final long getProviderIdForAccount(ContentResolver cr, long accountId) {
231              Cursor cursor = cr.query(CONTENT_URI,
232                      PROVIDER_PROJECTION,
233                      _ID + "=" + accountId,
234                      null /* selection args */,
235                      null /* sort order */);
236  
237              long providerId = 0;
238  
239              try {
240                  if (cursor.moveToFirst()) {
241                      providerId = cursor.getLong(PROVIDER_COLUMN);
242                  }
243              } finally {
244                  cursor.close();
245              }
246  
247              return providerId;
248          }
249  
250          private static final String[] PROVIDER_PROJECTION = new String[] { PROVIDER };
251          private static final int PROVIDER_COLUMN = 0;
252  
253          /**
254           * The content:// style URL for this table
255           */
256          public static final Uri CONTENT_URI =
257              Uri.parse("content://imps/accounts");
258  
259          /**
260           * The MIME type of {@link #CONTENT_URI} providing a directory of
261           * account.
262           */
263          public static final String CONTENT_TYPE =
264                  "vnd.android.cursor.dir/imps-accounts";
265  
266          /**
267           * The MIME type of a {@link #CONTENT_URI} subdirectory of a single
268           * account.
269           */
270          public static final String CONTENT_ITEM_TYPE =
271                  "vnd.android.cursor.item/imps-accounts";
272  
273          /**
274           * The default sort order for this table
275           */
276          public static final String DEFAULT_SORT_ORDER = "name ASC";
277  
278      }
279  
280      /**
281       * Connection status
282       */
283      public interface ConnectionStatus {
284          /**
285           * The connection is offline, not logged in.
286           */
287          int OFFLINE = 0;
288  
289          /**
290           * The connection is attempting to connect.
291           */
292          int CONNECTING = 1;
293  
294          /**
295           * The connection is suspended due to network not available.
296           */
297          int SUSPENDED = 2;
298  
299          /**
300           * The connection is logged in and online.
301           */
302          int ONLINE = 3;
303      }
304  
305      public interface AccountStatusColumns {
306          /**
307           * account id
308           * <P>Type: INTEGER</P>
309           */
310          String ACCOUNT = "account";
311  
312          /**
313           * User's presence status, see definitions in {#link CommonPresenceColumn}
314           * <P>Type: INTEGER</P>
315           */
316          String PRESENCE_STATUS = "presenceStatus";
317  
318          /**
319           * The connection status of this account, see {#link ConnectionStatus}
320           * <P>Type: INTEGER</P>
321           */
322          String CONNECTION_STATUS = "connStatus";
323      }
324  
325      public static final class AccountStatus implements BaseColumns, AccountStatusColumns {
326          /**
327           * The content:// style URL for this table
328           */
329          public static final Uri CONTENT_URI =
330              Uri.parse("content://imps/accountStatus");
331  
332          /**
333           * The MIME type of {@link #CONTENT_URI} providing a directory of account status.
334           */
335          public static final String CONTENT_TYPE =
336                  "vnd.android.cursor.dir/imps-account-status";
337  
338          /**
339           * The MIME type of a {@link #CONTENT_URI} subdirectory of a single account status.
340           */
341          public static final String CONTENT_ITEM_TYPE =
342                  "vnd.android.cursor.item/imps-account-status";
343  
344          /**
345           * The default sort order for this table
346           */
347          public static final String DEFAULT_SORT_ORDER = "name ASC";
348      }
349  
350      /**
351       * Columns from the Contacts table.
352       */
353      public interface ContactsColumns {
354          /**
355           * The username
356           * <P>Type: TEXT</P>
357           */
358          String USERNAME = "username";
359  
360          /**
361           * The nickname or display name
362           * <P>Type: TEXT</P>
363           */
364          String NICKNAME = "nickname";
365  
366          /**
367           * The IM provider for this contact
368           * <P>Type: INTEGER</P>
369           */
370          String PROVIDER = "provider";
371  
372          /**
373           * The account (within a IM provider) for this contact
374           * <P>Type: INTEGER</P>
375           */
376          String ACCOUNT = "account";
377  
378          /**
379           * The contactList this contact belongs to
380           * <P>Type: INTEGER</P>
381           */
382          String CONTACTLIST = "contactList";
383  
384          /**
385           * Contact type
386           * <P>Type: INTEGER</P>
387           */
388          String TYPE = "type";
389  
390          /**
391           * normal IM contact
392           */
393          int TYPE_NORMAL = 0;
394          /**
395           * temporary contact, someone not in the list of contacts that we
396           * subscribe presence for. Usually created because of the user is
397           * having a chat session with this contact.
398           */
399          int TYPE_TEMPORARY = 1;
400          /**
401           * temporary contact created for group chat.
402           */
403          int TYPE_GROUP = 2;
404          /**
405           * blocked contact.
406           */
407          int TYPE_BLOCKED = 3;
408          /**
409           * the contact is hidden. The client should always display this contact to the user.
410           */
411          int TYPE_HIDDEN = 4;
412          /**
413           * the contact is pinned. The client should always display this contact to the user.
414           */
415          int TYPE_PINNED = 5;
416  
417          /**
418           * Contact subscription status
419           * <P>Type: INTEGER</P>
420           */
421          String SUBSCRIPTION_STATUS = "subscriptionStatus";
422  
423          /**
424           * no pending subscription
425           */
426          int SUBSCRIPTION_STATUS_NONE = 0;
427          /**
428           * requested to subscribe
429           */
430          int SUBSCRIPTION_STATUS_SUBSCRIBE_PENDING = 1;
431          /**
432           * requested to unsubscribe
433           */
434          int SUBSCRIPTION_STATUS_UNSUBSCRIBE_PENDING = 2;
435  
436          /**
437           * Contact subscription type
438           * <P>Type: INTEGER </P>
439           */
440          String SUBSCRIPTION_TYPE = "subscriptionType";
441  
442          /**
443           * The user and contact have no interest in each other's presence.
444           */
445          int SUBSCRIPTION_TYPE_NONE = 0;
446          /**
447           * The user wishes to stop receiving presence updates from the contact.
448           */
449          int SUBSCRIPTION_TYPE_REMOVE = 1;
450          /**
451           * The user is interested in receiving presence updates from the contact.
452           */
453          int SUBSCRIPTION_TYPE_TO = 2;
454          /**
455           * The contact is interested in receiving presence updates from the user.
456           */
457          int SUBSCRIPTION_TYPE_FROM = 3;
458          /**
459           * The user and contact have a mutual interest in each other's presence.
460           */
461          int SUBSCRIPTION_TYPE_BOTH = 4;
462          /**
463           * This is a special type reserved for pending subscription requests
464           */
465          int SUBSCRIPTION_TYPE_INVITATIONS = 5;
466  
467          /**
468           * Quick Contact: derived from Google Contact Extension's "message_count" attribute.
469           * <P>Type: INTEGER</P>
470           */
471          String QUICK_CONTACT = "qc";
472  
473          /**
474           * Google Contact Extension attribute
475           *
476           * Rejected: a boolean value indicating whether a subscription request from
477           * this client was ever rejected by the user. "true" indicates that it has.
478           * This is provided so that a client can block repeated subscription requests.
479           * <P>Type: INTEGER</P>
480           */
481          String REJECTED = "rejected";
482  
483          /**
484           * Off The Record status: 0 for disabled, 1 for enabled
485           * <P>Type: INTEGER </P>
486           */
487          String OTR = "otr";
488      }
489  
490      /**
491       * This defines the different type of values of {@link ContactsColumns#OTR}
492       */
493      public interface OffTheRecordType {
494          /*
495           * Off the record not turned on
496           */
497          int DISABLED = 0;
498          /**
499           * Off the record turned on, but we don't know who turned it on
500           */
501          int ENABLED = 1;
502          /**
503           * Off the record turned on by the user
504           */
505          int ENABLED_BY_USER = 2;
506          /**
507           * Off the record turned on by the buddy
508           */
509          int ENABLED_BY_BUDDY = 3;
510      };
511  
512      /**
513       * This table contains contacts.
514       */
515      public static final class Contacts implements BaseColumns,
516              ContactsColumns, PresenceColumns, ChatsColumns {
517          /**
518           * no public constructor since this is a utility class
519           */
Contacts()520          private Contacts() {}
521  
522          /**
523           * The content:// style URL for this table
524           */
525          public static final Uri CONTENT_URI =
526              Uri.parse("content://imps/contacts");
527  
528          /**
529           * The content:// style URL for contacts joined with presence
530           */
531          public static final Uri CONTENT_URI_WITH_PRESENCE =
532              Uri.parse("content://imps/contactsWithPresence");
533  
534          /**
535           * The content:// style URL for barebone contacts, not joined with any other table
536           */
537          public static final Uri CONTENT_URI_CONTACTS_BAREBONE =
538              Uri.parse("content://imps/contactsBarebone");
539  
540          /**
541           * The content:// style URL for contacts who have an open chat session
542           */
543          public static final Uri CONTENT_URI_CHAT_CONTACTS =
544              Uri.parse("content://imps/contacts/chatting");
545  
546          /**
547           * The content:// style URL for contacts who have been blocked
548           */
549          public static final Uri CONTENT_URI_BLOCKED_CONTACTS =
550              Uri.parse("content://imps/contacts/blocked");
551  
552          /**
553           * The content:// style URL for contacts by provider and account
554           */
555          public static final Uri CONTENT_URI_CONTACTS_BY =
556              Uri.parse("content://imps/contacts");
557  
558          /**
559           * The content:// style URL for contacts by provider and account,
560           * and who have an open chat session
561           */
562          public static final Uri CONTENT_URI_CHAT_CONTACTS_BY =
563              Uri.parse("content://imps/contacts/chatting");
564  
565          /**
566           * The content:// style URL for contacts by provider and account,
567           * and who are online
568           */
569          public static final Uri CONTENT_URI_ONLINE_CONTACTS_BY =
570              Uri.parse("content://imps/contacts/online");
571  
572          /**
573           * The content:// style URL for contacts by provider and account,
574           * and who are offline
575           */
576          public static final Uri CONTENT_URI_OFFLINE_CONTACTS_BY =
577              Uri.parse("content://imps/contacts/offline");
578  
579          /**
580           * The content:// style URL for operations on bulk contacts
581           */
582          public static final Uri BULK_CONTENT_URI =
583                  Uri.parse("content://imps/bulk_contacts");
584  
585          /**
586           * The content:// style URL for the count of online contacts in each
587           * contact list by provider and account.
588           */
589          public static final Uri CONTENT_URI_ONLINE_COUNT =
590              Uri.parse("content://imps/contacts/onlineCount");
591  
592          /**
593           * The MIME type of {@link #CONTENT_URI} providing a directory of
594           * people.
595           */
596          public static final String CONTENT_TYPE = "vnd.android.cursor.dir/imps-contacts";
597  
598          /**
599           * The MIME type of a {@link #CONTENT_URI} subdirectory of a single
600           * person.
601           */
602          public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/imps-contacts";
603  
604          /**
605           * The default sort order for this table
606           */
607          public static final String DEFAULT_SORT_ORDER =
608                  "subscriptionType DESC, last_message_date DESC," +
609                          " mode DESC, nickname COLLATE UNICODE ASC";
610  
611          public static final String CHATS_CONTACT = "chats_contact";
612  
613          public static final String AVATAR_HASH = "avatars_hash";
614  
615          public static final String AVATAR_DATA = "avatars_data";
616      }
617  
618      /**
619       * Columns from the ContactList table.
620       */
621      public interface ContactListColumns {
622          String NAME = "name";
623          String PROVIDER = "provider";
624          String ACCOUNT = "account";
625      }
626  
627      /**
628       * This table contains the contact lists.
629       */
630      public static final class ContactList implements BaseColumns,
631              ContactListColumns {
ContactList()632          private ContactList() {}
633  
634          /**
635           * The content:// style URL for this table
636           */
637          public static final Uri CONTENT_URI =
638              Uri.parse("content://imps/contactLists");
639  
640          /**
641           * The MIME type of {@link #CONTENT_URI} providing a directory of
642           * people.
643           */
644          public static final String CONTENT_TYPE =
645                  "vnd.android.cursor.dir/imps-contactLists";
646  
647          /**
648           * The MIME type of a {@link #CONTENT_URI} subdirectory of a single
649           * person.
650           */
651          public static final String CONTENT_ITEM_TYPE =
652                  "vnd.android.cursor.item/imps-contactLists";
653  
654          /**
655           * The default sort order for this table
656           */
657          public static final String DEFAULT_SORT_ORDER = "name COLLATE UNICODE ASC";
658  
659          public static final String PROVIDER_NAME = "provider_name";
660  
661          public static final String ACCOUNT_NAME = "account_name";
662      }
663  
664      /**
665       * Columns from the BlockedList table.
666       */
667      public interface BlockedListColumns {
668          /**
669           * The username of the blocked contact.
670           * <P>Type: TEXT</P>
671           */
672          String USERNAME = "username";
673  
674          /**
675           * The nickname of the blocked contact.
676           * <P>Type: TEXT</P>
677           */
678          String NICKNAME = "nickname";
679  
680          /**
681           * The provider id of the blocked contact.
682           * <P>Type: INT</P>
683           */
684          String PROVIDER = "provider";
685  
686          /**
687           * The account id of the blocked contact.
688           * <P>Type: INT</P>
689           */
690          String ACCOUNT = "account";
691      }
692  
693      /**
694       * This table contains blocked lists
695       */
696      public static final class BlockedList implements BaseColumns, BlockedListColumns {
BlockedList()697          private BlockedList() {}
698  
699          /**
700           * The content:// style URL for this table
701           */
702          public static final Uri CONTENT_URI =
703              Uri.parse("content://imps/blockedList");
704  
705          /**
706           * The MIME type of {@link #CONTENT_URI} providing a directory of
707           * people.
708           */
709          public static final String CONTENT_TYPE =
710                  "vnd.android.cursor.dir/imps-blockedList";
711  
712          /**
713           * The MIME type of a {@link #CONTENT_URI} subdirectory of a single
714           * person.
715           */
716          public static final String CONTENT_ITEM_TYPE =
717                  "vnd.android.cursor.item/imps-blockedList";
718  
719          /**
720           * The default sort order for this table
721           */
722          public static final String DEFAULT_SORT_ORDER = "nickname ASC";
723  
724          public static final String PROVIDER_NAME = "provider_name";
725  
726          public static final String ACCOUNT_NAME = "account_name";
727  
728          public static final String AVATAR_DATA = "avatars_data";
729      }
730  
731      /**
732       * Columns from the contactsEtag table
733       */
734      public interface ContactsEtagColumns {
735          /**
736           * The roster etag, computed by the server, stored on the client. There is one etag
737           * per account roster.
738           * <P>Type: TEXT</P>
739           */
740          String ETAG = "etag";
741  
742          /**
743           * The OTR etag, computed by the server, stored on the client. There is one OTR etag
744           * per account roster.
745           * <P>Type: TEXT</P>
746           */
747          String OTR_ETAG = "otr_etag";
748  
749          /**
750           * The account id for the etag.
751           * <P> Type: INTEGER </P>
752           */
753          String ACCOUNT = "account";
754      }
755  
756      public static final class ContactsEtag implements BaseColumns, ContactsEtagColumns {
ContactsEtag()757          private ContactsEtag() {}
758  
query(ContentResolver cr, String[] projection)759          public static final Cursor query(ContentResolver cr,
760                  String[] projection) {
761              return cr.query(CONTENT_URI, projection, null, null, null);
762          }
763  
query(ContentResolver cr, String[] projection, String where, String orderBy)764          public static final Cursor query(ContentResolver cr,
765                  String[] projection, String where, String orderBy) {
766              return cr.query(CONTENT_URI, projection, where,
767                      null, orderBy == null ? null : orderBy);
768          }
769  
getRosterEtag(ContentResolver resolver, long accountId)770          public static final String getRosterEtag(ContentResolver resolver, long accountId) {
771              String retVal = null;
772  
773              Cursor c = resolver.query(CONTENT_URI,
774                      CONTACT_ETAG_PROJECTION,
775                      ACCOUNT + "=" + accountId,
776                      null /* selection args */,
777                      null /* sort order */);
778  
779              try {
780                  if (c.moveToFirst()) {
781                      retVal = c.getString(COLUMN_ETAG);
782                  }
783              } finally {
784                  c.close();
785              }
786  
787              return retVal;
788          }
789  
getOtrEtag(ContentResolver resolver, long accountId)790          public static final String getOtrEtag(ContentResolver resolver, long accountId) {
791              String retVal = null;
792  
793              Cursor c = resolver.query(CONTENT_URI,
794                      CONTACT_OTR_ETAG_PROJECTION,
795                      ACCOUNT + "=" + accountId,
796                      null /* selection args */,
797                      null /* sort order */);
798  
799              try {
800                  if (c.moveToFirst()) {
801                      retVal = c.getString(COLUMN_OTR_ETAG);
802                  }
803              } finally {
804                  c.close();
805              }
806  
807              return retVal;
808          }
809  
810          private static final String[] CONTACT_ETAG_PROJECTION = new String[] {
811                  Imps.ContactsEtag.ETAG    // 0
812          };
813  
814          private static int COLUMN_ETAG = 0;
815  
816          private static final String[] CONTACT_OTR_ETAG_PROJECTION = new String[] {
817                  Imps.ContactsEtag.OTR_ETAG    // 0
818          };
819  
820          private static int COLUMN_OTR_ETAG = 0;
821  
822          /**
823           * The content:// style URL for this table
824           */
825          public static final Uri CONTENT_URI =
826              Uri.parse("content://imps/contactsEtag");
827  
828          /**
829           * The MIME type of {@link #CONTENT_URI} providing a directory of
830           * people.
831           */
832          public static final String CONTENT_TYPE =
833                  "vnd.android.cursor.dir/imps-contactsEtag";
834  
835          /**
836           * The MIME type of a {@link #CONTENT_URI} subdirectory of a single
837           * person.
838           */
839          public static final String CONTENT_ITEM_TYPE =
840                  "vnd.android.cursor.item/imps-contactsEtag";
841      }
842  
843      /**
844       * Message type definition
845       */
846      public interface MessageType {
847          /* sent message */
848          int OUTGOING = 0;
849          /* received message */
850          int INCOMING = 1;
851          /* presence became available */
852          int PRESENCE_AVAILABLE = 2;
853          /* presence became away */
854          int PRESENCE_AWAY = 3;
855          /* presence became DND (busy) */
856          int PRESENCE_DND = 4;
857          /* presence became unavailable */
858          int PRESENCE_UNAVAILABLE = 5;
859          /* the message is converted to a group chat */
860          int CONVERT_TO_GROUPCHAT = 6;
861          /* generic status */
862          int STATUS = 7;
863          /* the message cannot be sent now, but will be sent later */
864          int POSTPONED = 8;
865          /* off The Record status is turned off */
866          int OTR_IS_TURNED_OFF = 9;
867          /* off the record status is turned on */
868          int OTR_IS_TURNED_ON = 10;
869          /* off the record status turned on by user */
870          int OTR_TURNED_ON_BY_USER = 11;
871          /* off the record status turned on by buddy */
872          int OTR_TURNED_ON_BY_BUDDY = 12;
873      }
874  
875      /**
876       * The common columns for messages table
877       */
878      public interface MessageColumns {
879          /**
880           * The thread_id column stores the contact id of the contact the message belongs to.
881           * For groupchat messages, the thread_id stores the group id, which is the contact id
882           * of the temporary group contact created for the groupchat. So there should be no
883           * collision between groupchat message thread id and regular message thread id.
884           */
885          String THREAD_ID = "thread_id";
886  
887          /**
888           * The nickname. This is used for groupchat messages to indicate the participant's
889           * nickname. For non groupchat messages, this field should be left empty.
890           */
891          String NICKNAME = "nickname";
892  
893          /**
894           * The body
895           * <P>Type: TEXT</P>
896           */
897          String BODY = "body";
898  
899          /**
900           * The date this message is sent or received
901           * <P>Type: INTEGER</P>
902           */
903          String DATE = "date";
904  
905          /**
906           * Message Type, see {@link MessageType}
907           * <P>Type: INTEGER</P>
908           */
909          String TYPE = "type";
910  
911          /**
912           * Error Code: 0 means no error.
913           * <P>Type: INTEGER </P>
914           */
915          String ERROR_CODE = "err_code";
916  
917          /**
918           * Error Message
919           * <P>Type: TEXT</P>
920           */
921          String ERROR_MESSAGE = "err_msg";
922  
923          /**
924           * Packet ID, auto assigned by the GTalkService for outgoing messages or the
925           * GTalk server for incoming messages. The packet id field is optional for messages,
926           * so it could be null.
927           * <P>Type: STRING</P>
928           */
929          String PACKET_ID = "packet_id";
930  
931          /**
932           * Is groupchat message or not
933           * <P>Type: INTEGER</P>
934           */
935          String IS_GROUP_CHAT = "is_muc";
936  
937          /**
938           * A hint that the UI should show the sent time of this message
939           * <P>Type: INTEGER</P>
940           */
941          String DISPLAY_SENT_TIME = "show_ts";
942      }
943  
944      /**
945       * This table contains messages.
946       */
947      public static final class Messages implements BaseColumns, MessageColumns {
948          /**
949           * no public constructor since this is a utility class
950           */
Messages()951          private Messages() {}
952  
953          /**
954           * Gets the Uri to query messages by thread id.
955           *
956           * @param threadId the thread id of the message.
957           * @return the Uri
958           */
getContentUriByThreadId(long threadId)959          public static final Uri getContentUriByThreadId(long threadId) {
960              Uri.Builder builder = CONTENT_URI_MESSAGES_BY_THREAD_ID.buildUpon();
961              ContentUris.appendId(builder, threadId);
962              return builder.build();
963          }
964  
965          /**
966           * @deprecated
967           *
968           * Gets the Uri to query messages by account and contact.
969           *
970           * @param accountId the account id of the contact.
971           * @param username the user name of the contact.
972           * @return the Uri
973           */
getContentUriByContact(long accountId, String username)974          public static final Uri getContentUriByContact(long accountId, String username) {
975              Uri.Builder builder = CONTENT_URI_MESSAGES_BY_ACCOUNT_AND_CONTACT.buildUpon();
976              ContentUris.appendId(builder, accountId);
977              builder.appendPath(username);
978              return builder.build();
979          }
980  
981          /**
982           * Gets the Uri to query messages by provider.
983           *
984           * @param providerId the service provider id.
985           * @return the Uri
986           */
getContentUriByProvider(long providerId)987          public static final Uri getContentUriByProvider(long providerId) {
988              Uri.Builder builder = CONTENT_URI_MESSAGES_BY_PROVIDER.buildUpon();
989              ContentUris.appendId(builder, providerId);
990              return builder.build();
991          }
992  
993          /**
994           * Gets the Uri to query off the record messages by account.
995           *
996           * @param accountId the account id.
997           * @return the Uri
998           */
getContentUriByAccount(long accountId)999          public static final Uri getContentUriByAccount(long accountId) {
1000              Uri.Builder builder = CONTENT_URI_BY_ACCOUNT.buildUpon();
1001              ContentUris.appendId(builder, accountId);
1002              return builder.build();
1003          }
1004  
1005          /**
1006           * Gets the Uri to query off the record messages by thread id.
1007           *
1008           * @param threadId the thread id of the message.
1009           * @return the Uri
1010           */
getOtrMessagesContentUriByThreadId(long threadId)1011          public static final Uri getOtrMessagesContentUriByThreadId(long threadId) {
1012              Uri.Builder builder = OTR_MESSAGES_CONTENT_URI_BY_THREAD_ID.buildUpon();
1013              ContentUris.appendId(builder, threadId);
1014              return builder.build();
1015          }
1016  
1017          /**
1018           * @deprecated
1019           *
1020           * Gets the Uri to query off the record messages by account and contact.
1021           *
1022           * @param accountId the account id of the contact.
1023           * @param username the user name of the contact.
1024           * @return the Uri
1025           */
getOtrMessagesContentUriByContact(long accountId, String username)1026          public static final Uri getOtrMessagesContentUriByContact(long accountId, String username) {
1027              Uri.Builder builder = OTR_MESSAGES_CONTENT_URI_BY_ACCOUNT_AND_CONTACT.buildUpon();
1028              ContentUris.appendId(builder, accountId);
1029              builder.appendPath(username);
1030              return builder.build();
1031          }
1032  
1033          /**
1034           * Gets the Uri to query off the record messages by provider.
1035           *
1036           * @param providerId the service provider id.
1037           * @return the Uri
1038           */
getOtrMessagesContentUriByProvider(long providerId)1039          public static final Uri getOtrMessagesContentUriByProvider(long providerId) {
1040              Uri.Builder builder = OTR_MESSAGES_CONTENT_URI_BY_PROVIDER.buildUpon();
1041              ContentUris.appendId(builder, providerId);
1042              return builder.build();
1043          }
1044  
1045          /**
1046           * Gets the Uri to query off the record messages by account.
1047           *
1048           * @param accountId the account id.
1049           * @return the Uri
1050           */
getOtrMessagesContentUriByAccount(long accountId)1051          public static final Uri getOtrMessagesContentUriByAccount(long accountId) {
1052              Uri.Builder builder = OTR_MESSAGES_CONTENT_URI_BY_ACCOUNT.buildUpon();
1053              ContentUris.appendId(builder, accountId);
1054              return builder.build();
1055          }
1056  
1057          /**
1058           * The content:// style URL for this table
1059           */
1060          public static final Uri CONTENT_URI =
1061                  Uri.parse("content://imps/messages");
1062  
1063          /**
1064           * The content:// style URL for messages by thread id
1065           */
1066          public static final Uri CONTENT_URI_MESSAGES_BY_THREAD_ID =
1067                  Uri.parse("content://imps/messagesByThreadId");
1068  
1069          /**
1070           * The content:// style URL for messages by account and contact
1071           */
1072          public static final Uri CONTENT_URI_MESSAGES_BY_ACCOUNT_AND_CONTACT =
1073                  Uri.parse("content://imps/messagesByAcctAndContact");
1074  
1075          /**
1076           * The content:// style URL for messages by provider
1077           */
1078          public static final Uri CONTENT_URI_MESSAGES_BY_PROVIDER =
1079                  Uri.parse("content://imps/messagesByProvider");
1080  
1081          /**
1082           * The content:// style URL for messages by account
1083           */
1084          public static final Uri CONTENT_URI_BY_ACCOUNT =
1085                  Uri.parse("content://imps/messagesByAccount");
1086  
1087          /**
1088           * The content:// style url for off the record messages
1089           */
1090          public static final Uri OTR_MESSAGES_CONTENT_URI =
1091                  Uri.parse("content://imps/otrMessages");
1092  
1093          /**
1094           * The content:// style url for off the record messages by thread id
1095           */
1096          public static final Uri OTR_MESSAGES_CONTENT_URI_BY_THREAD_ID =
1097                  Uri.parse("content://imps/otrMessagesByThreadId");
1098  
1099          /**
1100           * The content:// style url for off the record messages by account and contact
1101           */
1102          public static final Uri OTR_MESSAGES_CONTENT_URI_BY_ACCOUNT_AND_CONTACT =
1103                  Uri.parse("content://imps/otrMessagesByAcctAndContact");
1104  
1105          /**
1106           * The content:// style URL for off the record messages by provider
1107           */
1108          public static final Uri OTR_MESSAGES_CONTENT_URI_BY_PROVIDER =
1109                  Uri.parse("content://imps/otrMessagesByProvider");
1110  
1111          /**
1112           * The content:// style URL for off the record messages by account
1113           */
1114          public static final Uri OTR_MESSAGES_CONTENT_URI_BY_ACCOUNT =
1115                  Uri.parse("content://imps/otrMessagesByAccount");
1116  
1117          /**
1118           * The MIME type of {@link #CONTENT_URI} providing a directory of
1119           * people.
1120           */
1121          public static final String CONTENT_TYPE = "vnd.android.cursor.dir/imps-messages";
1122  
1123          /**
1124           * The MIME type of a {@link #CONTENT_URI} subdirectory of a single
1125           * person.
1126           */
1127          public static final String CONTENT_ITEM_TYPE =
1128                  "vnd.android.cursor.item/imps-messages";
1129  
1130          /**
1131           * The default sort order for this table
1132           */
1133          public static final String DEFAULT_SORT_ORDER = "date ASC";
1134  
1135          /**
1136           * The "contact" column. This is not a real column in the messages table, but a
1137           * temoprary column created when querying for messages (joined with the contacts table)
1138           */
1139          public static final String CONTACT = "contact";
1140      }
1141  
1142      /**
1143       * Columns for the GroupMember table.
1144       */
1145      public interface GroupMemberColumns {
1146          /**
1147           * The id of the group this member belongs to.
1148           * <p>Type: INTEGER</p>
1149           */
1150          String GROUP = "groupId";
1151  
1152          /**
1153           * The full name of this member.
1154           * <p>Type: TEXT</p>
1155           */
1156          String USERNAME = "username";
1157  
1158          /**
1159           * The nick name of this member.
1160           * <p>Type: TEXT</p>
1161           */
1162          String NICKNAME = "nickname";
1163      }
1164  
1165      public final static class GroupMembers implements GroupMemberColumns {
GroupMembers()1166          private GroupMembers(){}
1167  
1168          public static final Uri CONTENT_URI =
1169              Uri.parse("content://imps/groupMembers");
1170  
1171          /**
1172           * The MIME type of {@link #CONTENT_URI} providing a directory of
1173           * group members.
1174           */
1175          public static final String CONTENT_TYPE =
1176              "vnd.android.cursor.dir/imps-groupMembers";
1177  
1178          /**
1179           * The MIME type of a {@link #CONTENT_URI} subdirectory of a single
1180           * group member.
1181           */
1182          public static final String CONTENT_ITEM_TYPE =
1183                  "vnd.android.cursor.item/imps-groupMembers";
1184      }
1185  
1186      /**
1187       * Columns from the Invitation table.
1188       */
1189      public interface InvitationColumns {
1190          /**
1191           * The provider id.
1192           * <p>Type: INTEGER</p>
1193           */
1194          String PROVIDER = "providerId";
1195  
1196          /**
1197           * The account id.
1198           * <p>Type: INTEGER</p>
1199           */
1200          String ACCOUNT = "accountId";
1201  
1202          /**
1203           * The invitation id.
1204           * <p>Type: TEXT</p>
1205           */
1206          String INVITE_ID = "inviteId";
1207  
1208          /**
1209           * The name of the sender of the invitation.
1210           * <p>Type: TEXT</p>
1211           */
1212          String SENDER = "sender";
1213  
1214          /**
1215           * The name of the group which the sender invite you to join.
1216           * <p>Type: TEXT</p>
1217           */
1218          String GROUP_NAME = "groupName";
1219  
1220          /**
1221           * A note
1222           * <p>Type: TEXT</p>
1223           */
1224          String NOTE = "note";
1225  
1226          /**
1227           * The current status of the invitation.
1228           * <p>Type: TEXT</p>
1229           */
1230          String STATUS = "status";
1231  
1232          int STATUS_PENDING = 0;
1233          int STATUS_ACCEPTED = 1;
1234          int STATUS_REJECTED = 2;
1235      }
1236  
1237      /**
1238       * This table contains the invitations received from others.
1239       */
1240      public final static class Invitation implements InvitationColumns,
1241              BaseColumns {
Invitation()1242          private Invitation() {
1243          }
1244  
1245          /**
1246           * The content:// style URL for this table
1247           */
1248          public static final Uri CONTENT_URI =
1249              Uri.parse("content://imps/invitations");
1250  
1251          /**
1252           * The MIME type of {@link #CONTENT_URI} providing a directory of
1253           * invitations.
1254           */
1255          public static final String CONTENT_TYPE =
1256              "vnd.android.cursor.dir/imps-invitations";
1257  
1258          /**
1259           * The MIME type of a {@link #CONTENT_URI} subdirectory of a single
1260           * invitation.
1261           */
1262          public static final String CONTENT_ITEM_TYPE =
1263                  "vnd.android.cursor.item/imps-invitations";
1264      }
1265  
1266      /**
1267       * Columns from the Avatars table
1268       */
1269      public interface AvatarsColumns {
1270          /**
1271           * The contact this avatar belongs to
1272           * <P>Type: TEXT</P>
1273           */
1274          String CONTACT = "contact";
1275  
1276          String PROVIDER = "provider_id";
1277  
1278          String ACCOUNT = "account_id";
1279  
1280          /**
1281           * The hash of the image data
1282           * <P>Type: TEXT</P>
1283           */
1284          String HASH = "hash";
1285  
1286          /**
1287           * raw image data
1288           * <P>Type: BLOB</P>
1289           */
1290          String DATA = "data";
1291      }
1292  
1293      /**
1294       * This table contains avatars.
1295       */
1296      public static final class Avatars implements BaseColumns, AvatarsColumns {
1297          /**
1298           * no public constructor since this is a utility class
1299           */
Avatars()1300          private Avatars() {}
1301  
1302          /**
1303           * The content:// style URL for this table
1304           */
1305          public static final Uri CONTENT_URI = Uri.parse("content://imps/avatars");
1306  
1307          /**
1308           * The content:// style URL for avatars by provider, account and contact
1309           */
1310          public static final Uri CONTENT_URI_AVATARS_BY =
1311                  Uri.parse("content://imps/avatarsBy");
1312  
1313          /**
1314           * The MIME type of {@link #CONTENT_URI} providing the avatars
1315           */
1316          public static final String CONTENT_TYPE = "vnd.android.cursor.dir/imps-avatars";
1317  
1318          /**
1319           * The MIME type of a {@link #CONTENT_URI}
1320           */
1321          public static final String CONTENT_ITEM_TYPE =
1322                  "vnd.android.cursor.item/imps-avatars";
1323  
1324          /**
1325           * The default sort order for this table
1326           */
1327          public static final String DEFAULT_SORT_ORDER = "contact ASC";
1328  
1329      }
1330  
1331      /**
1332       * Common presence columns shared between the IM and contacts presence tables
1333       */
1334      public interface CommonPresenceColumns {
1335          /**
1336           * The priority, an integer, used by XMPP presence
1337           * <P>Type: INTEGER</P>
1338           */
1339          String PRIORITY = "priority";
1340  
1341          /**
1342           * The server defined status.
1343           * <P>Type: INTEGER (one of the values below)</P>
1344           */
1345          String PRESENCE_STATUS = "mode";
1346  
1347          /**
1348           * Presence Status definition
1349           */
1350          int OFFLINE = 0;
1351          int INVISIBLE = 1;
1352          int AWAY = 2;
1353          int IDLE = 3;
1354          int DO_NOT_DISTURB = 4;
1355          int AVAILABLE = 5;
1356  
1357          /**
1358           * The user defined status line.
1359           * <P>Type: TEXT</P>
1360           */
1361          String PRESENCE_CUSTOM_STATUS = "status";
1362      }
1363  
1364      /**
1365       * Columns from the Presence table.
1366       */
1367      public interface PresenceColumns extends CommonPresenceColumns {
1368          /**
1369           * The contact id
1370           * <P>Type: INTEGER</P>
1371           */
1372          String CONTACT_ID = "contact_id";
1373  
1374          /**
1375           * The contact's JID resource, only relevant for XMPP contact
1376           * <P>Type: TEXT</P>
1377           */
1378          String JID_RESOURCE = "jid_resource";
1379  
1380          /**
1381           * The contact's client type
1382           */
1383          String CLIENT_TYPE = "client_type";
1384  
1385          /**
1386           * client type definitions
1387           */
1388          int CLIENT_TYPE_DEFAULT = 0;
1389          int CLIENT_TYPE_MOBILE = 1;
1390          int CLIENT_TYPE_ANDROID = 2;
1391      }
1392  
1393      /**
1394       * Contains presence infomation for contacts.
1395       */
1396      public static final class Presence implements BaseColumns, PresenceColumns {
1397          /**
1398           * The content:// style URL for this table
1399           */
1400          public static final Uri CONTENT_URI = Uri.parse("content://imps/presence");
1401  
1402          /**
1403           * The content URL for IM presences for an account
1404           */
1405          public static final Uri CONTENT_URI_BY_ACCOUNT = Uri.parse("content://imps/presence/account");
1406  
1407          /**
1408           * The content:// style URL for operations on bulk contacts
1409           */
1410          public static final Uri BULK_CONTENT_URI = Uri.parse("content://imps/bulk_presence");
1411  
1412          /**
1413           * The content:// style URL for seeding presences for a given account id.
1414           */
1415          public static final Uri SEED_PRESENCE_BY_ACCOUNT_CONTENT_URI =
1416                  Uri.parse("content://imps/seed_presence/account");
1417  
1418          /**
1419           * The MIME type of a {@link #CONTENT_URI} providing a directory of presence
1420           */
1421          public static final String CONTENT_TYPE = "vnd.android.cursor.dir/imps-presence";
1422  
1423          /**
1424           * The default sort order for this table
1425           */
1426          public static final String DEFAULT_SORT_ORDER = "mode DESC";
1427      }
1428  
1429      /**
1430       * Columns from the Chats table.
1431       */
1432      public interface ChatsColumns {
1433          /**
1434           * The contact ID this chat belongs to. The value is a long.
1435           * <P>Type: INT</P>
1436           */
1437          String CONTACT_ID = "contact_id";
1438  
1439          /**
1440           * The GTalk JID resource. The value is a string.
1441           * <P>Type: TEXT</P>
1442           */
1443          String JID_RESOURCE = "jid_resource";
1444  
1445          /**
1446           * Whether this is a groupchat or not.
1447           * <P>Type: INT</P>
1448           */
1449          String GROUP_CHAT = "groupchat";
1450  
1451          /**
1452           * The last unread message. This both indicates that there is an
1453           * unread message, and what the message is.
1454           * <P>Type: TEXT</P>
1455           */
1456          String LAST_UNREAD_MESSAGE = "last_unread_message";
1457  
1458          /**
1459           * The last message timestamp
1460           * <P>Type: INT</P>
1461           */
1462          String LAST_MESSAGE_DATE = "last_message_date";
1463  
1464          /**
1465           * A message that is being composed.  This indicates that there was a
1466           * message being composed when the chat screen was shutdown, and what the
1467           * message is.
1468           * <P>Type: TEXT</P>
1469           */
1470          String UNSENT_COMPOSED_MESSAGE = "unsent_composed_message";
1471  
1472          /**
1473           * A value from 0-9 indicating which quick-switch chat screen slot this
1474           * chat is occupying.  If none (for instance, this is the 12th active chat)
1475           * then the value is -1.
1476           * <P>Type: INT</P>
1477           */
1478          String SHORTCUT = "shortcut";
1479      }
1480  
1481      /**
1482       * Contains ongoing chat sessions.
1483       */
1484      public static final class Chats implements BaseColumns, ChatsColumns {
1485          /**
1486           * no public constructor since this is a utility class
1487           */
Chats()1488          private Chats() {}
1489  
1490          /**
1491           * The content:// style URL for this table
1492           */
1493          public static final Uri CONTENT_URI =
1494              Uri.parse("content://imps/chats");
1495  
1496          /**
1497           * The content URL for all chats that belong to the account
1498           */
1499          public static final Uri CONTENT_URI_BY_ACCOUNT = Uri.parse("content://imps/chats/account");
1500  
1501          /**
1502           * The MIME type of {@link #CONTENT_URI} providing a directory of chats.
1503           */
1504          public static final String CONTENT_TYPE = "vnd.android.cursor.dir/imps-chats";
1505  
1506          /**
1507           * The MIME type of a {@link #CONTENT_URI} subdirectory of a single chat.
1508           */
1509          public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/imps-chats";
1510  
1511          /**
1512           * The default sort order for this table
1513           */
1514          public static final String DEFAULT_SORT_ORDER = "last_message_date ASC";
1515      }
1516  
1517      /**
1518       * Columns from session cookies table. Used for IMPS.
1519       */
1520      public static interface SessionCookiesColumns {
1521          String NAME = "name";
1522          String VALUE = "value";
1523          String PROVIDER = "provider";
1524          String ACCOUNT = "account";
1525      }
1526  
1527      /**
1528       * Contains IMPS session cookies.
1529       */
1530      public static class SessionCookies implements SessionCookiesColumns, BaseColumns {
SessionCookies()1531          private SessionCookies() {
1532          }
1533  
1534          /**
1535           * The content:// style URI for this table
1536           */
1537          public static final Uri CONTENT_URI = Uri.parse("content://imps/sessionCookies");
1538  
1539          /**
1540           * The content:// style URL for session cookies by provider and account
1541           */
1542          public static final Uri CONTENT_URI_SESSION_COOKIES_BY =
1543              Uri.parse("content://imps/sessionCookiesBy");
1544  
1545          /**
1546           * The MIME type of {@link #CONTENT_URI} providing a directory of
1547           * people.
1548           */
1549          public static final String CONTENT_TYPE = "vnd.android-dir/imps-sessionCookies";
1550      }
1551  
1552      /**
1553       * Columns from ProviderSettings table
1554       */
1555      public static interface ProviderSettingsColumns {
1556           /**
1557            * The id in database of the related provider
1558            *
1559            * <P>Type: INT</P>
1560            */
1561          String PROVIDER = "provider";
1562  
1563          /**
1564           * The name of the setting
1565           * <P>Type: TEXT</P>
1566           */
1567          String NAME = "name";
1568  
1569          /**
1570           * The value of the setting
1571           * <P>Type: TEXT</P>
1572           */
1573          String VALUE = "value";
1574      }
1575  
1576      public static class ProviderSettings implements ProviderSettingsColumns {
ProviderSettings()1577          private ProviderSettings() {
1578          }
1579  
1580          /**
1581           * The content:// style URI for this table
1582           */
1583          public static final Uri CONTENT_URI =
1584                  Uri.parse("content://imps/providerSettings");
1585  
1586          /**
1587           * The MIME type of {@link #CONTENT_URI} providing provider settings
1588           */
1589          public static final String CONTENT_TYPE = "vnd.android-dir/imps-providerSettings";
1590  
1591          /**
1592           * A boolean value to indicate whether this provider should show the offline contacts
1593           */
1594          public static final String SHOW_OFFLINE_CONTACTS = "show_offline_contacts";
1595  
1596          /** controls whether or not the GTalk service automatically connect to server. */
1597          public static final String SETTING_AUTOMATICALLY_CONNECT_GTALK = "gtalk_auto_connect";
1598  
1599          /** controls whether or not the IM service will be automatically started after boot */
1600          public static final String SETTING_AUTOMATICALLY_START_SERVICE = "auto_start_service";
1601  
1602          /** controls whether or not the offline contacts will be hided */
1603          public static final String SETTING_HIDE_OFFLINE_CONTACTS = "hide_offline_contacts";
1604  
1605          /** controls whether or not enable the IM notification */
1606          public static final String SETTING_ENABLE_NOTIFICATION = "enable_notification";
1607  
1608          /** specifies whether or not to vibrate */
1609          public static final String SETTING_VIBRATE = "vibrate";
1610  
1611          /** specifies the Uri string of the ringtone */
1612          public static final String SETTING_RINGTONE = "ringtone";
1613  
1614          /** specifies the Uri of the default ringtone */
1615          public static final String SETTING_RINGTONE_DEFAULT =
1616                  "content://settings/system/notification_sound";
1617  
1618          /** specifies whether or not to show mobile indicator to friends */
1619          public static final String SETTING_SHOW_MOBILE_INDICATOR = "mobile_indicator";
1620  
1621          /** specifies whether or not to show as away when device is idle */
1622          public static final String SETTING_SHOW_AWAY_ON_IDLE = "show_away_on_idle";
1623  
1624          /** specifies whether or not to upload heartbeat stat upon login */
1625          public static final String SETTING_UPLOAD_HEARTBEAT_STAT = "upload_heartbeat_stat";
1626  
1627          /** specifies the last heartbeat interval received from the server */
1628          public static final String SETTING_HEARTBEAT_INTERVAL = "heartbeat_interval";
1629  
1630          /** specifiy the JID resource used for Google Talk connection */
1631          public static final String SETTING_JID_RESOURCE = "jid_resource";
1632  
1633          /**
1634           * Used for reliable message queue (RMQ). This is for storing the last rmq id received
1635           * from the GTalk server
1636           */
1637          public static final String LAST_RMQ_RECEIVED = "last_rmq_rec";
1638  
1639          /**
1640           * Query the settings of the provider specified by id
1641           *
1642           * @param cr
1643           *            the relative content resolver
1644           * @param providerId
1645           *            the specified id of provider
1646           * @return a HashMap which contains all the settings for the specified
1647           *         provider
1648           */
queryProviderSettings(ContentResolver cr, long providerId)1649          public static HashMap<String, String> queryProviderSettings(ContentResolver cr,
1650                  long providerId) {
1651              HashMap<String, String> settings = new HashMap<String, String>();
1652  
1653              String[] projection = { NAME, VALUE };
1654              Cursor c = cr.query(ContentUris.withAppendedId(CONTENT_URI, providerId), projection, null, null, null);
1655              if (c == null) {
1656                  return null;
1657              }
1658  
1659              while(c.moveToNext()) {
1660                  settings.put(c.getString(0), c.getString(1));
1661              }
1662  
1663              c.close();
1664  
1665              return settings;
1666          }
1667  
1668          /**
1669           * Get the string value of setting which is specified by provider id and the setting name.
1670           *
1671           * @param cr The ContentResolver to use to access the settings table.
1672           * @param providerId The id of the provider.
1673           * @param settingName The name of the setting.
1674           * @return The value of the setting if the setting exist, otherwise return null.
1675           */
getStringValue(ContentResolver cr, long providerId, String settingName)1676          public static String getStringValue(ContentResolver cr, long providerId, String settingName) {
1677              String ret = null;
1678              Cursor c = getSettingValue(cr, providerId, settingName);
1679              if (c != null) {
1680                  ret = c.getString(0);
1681                  c.close();
1682              }
1683  
1684              return ret;
1685          }
1686  
1687          /**
1688           * Get the boolean value of setting which is specified by provider id and the setting name.
1689           *
1690           * @param cr The ContentResolver to use to access the settings table.
1691           * @param providerId The id of the provider.
1692           * @param settingName The name of the setting.
1693           * @return The value of the setting if the setting exist, otherwise return false.
1694           */
getBooleanValue(ContentResolver cr, long providerId, String settingName)1695          public static boolean getBooleanValue(ContentResolver cr, long providerId, String settingName) {
1696              boolean ret = false;
1697              Cursor c = getSettingValue(cr, providerId, settingName);
1698              if (c != null) {
1699                  ret = c.getInt(0) != 0;
1700                  c.close();
1701              }
1702              return ret;
1703          }
1704  
getSettingValue(ContentResolver cr, long providerId, String settingName)1705          private static Cursor getSettingValue(ContentResolver cr, long providerId, String settingName) {
1706              Cursor c = cr.query(ContentUris.withAppendedId(CONTENT_URI, providerId), new String[]{VALUE}, NAME + "=?",
1707                      new String[]{settingName}, null);
1708              if (c != null) {
1709                  if (!c.moveToFirst()) {
1710                      c.close();
1711                      return null;
1712                  }
1713              }
1714              return c;
1715          }
1716  
1717          /**
1718           * Save a long value of setting in the table providerSetting.
1719           *
1720           * @param cr The ContentProvider used to access the providerSetting table.
1721           * @param providerId The id of the provider.
1722           * @param name The name of the setting.
1723           * @param value The value of the setting.
1724           */
putLongValue(ContentResolver cr, long providerId, String name, long value)1725          public static void putLongValue(ContentResolver cr, long providerId, String name,
1726                  long value) {
1727              ContentValues v = new ContentValues(3);
1728              v.put(PROVIDER, providerId);
1729              v.put(NAME, name);
1730              v.put(VALUE, value);
1731  
1732              cr.insert(CONTENT_URI, v);
1733          }
1734  
1735          /**
1736           * Save a boolean value of setting in the table providerSetting.
1737           *
1738           * @param cr The ContentProvider used to access the providerSetting table.
1739           * @param providerId The id of the provider.
1740           * @param name The name of the setting.
1741           * @param value The value of the setting.
1742           */
putBooleanValue(ContentResolver cr, long providerId, String name, boolean value)1743          public static void putBooleanValue(ContentResolver cr, long providerId, String name,
1744                  boolean value) {
1745              ContentValues v = new ContentValues(3);
1746              v.put(PROVIDER, providerId);
1747              v.put(NAME, name);
1748              v.put(VALUE, Boolean.toString(value));
1749  
1750              cr.insert(CONTENT_URI, v);
1751          }
1752  
1753          /**
1754           * Save a string value of setting in the table providerSetting.
1755           *
1756           * @param cr The ContentProvider used to access the providerSetting table.
1757           * @param providerId The id of the provider.
1758           * @param name The name of the setting.
1759           * @param value The value of the setting.
1760           */
putStringValue(ContentResolver cr, long providerId, String name, String value)1761          public static void putStringValue(ContentResolver cr, long providerId, String name,
1762                  String value) {
1763              ContentValues v = new ContentValues(3);
1764              v.put(PROVIDER, providerId);
1765              v.put(NAME, name);
1766              v.put(VALUE, value);
1767  
1768              cr.insert(CONTENT_URI, v);
1769          }
1770  
1771          /**
1772           * A convenience method to set whether or not the GTalk service should be started
1773           * automatically.
1774           *
1775           * @param contentResolver The ContentResolver to use to access the settings table
1776           * @param autoConnect Whether the GTalk service should be started automatically.
1777           */
setAutomaticallyConnectGTalk(ContentResolver contentResolver, long providerId, boolean autoConnect)1778          public static void setAutomaticallyConnectGTalk(ContentResolver contentResolver,
1779                  long providerId, boolean autoConnect) {
1780              putBooleanValue(contentResolver, providerId, SETTING_AUTOMATICALLY_CONNECT_GTALK,
1781                      autoConnect);
1782          }
1783  
1784          /**
1785           * A convenience method to set whether or not the offline contacts should be hided
1786           *
1787           * @param contentResolver The ContentResolver to use to access the setting table
1788           * @param hideOfflineContacts Whether the offline contacts should be hided
1789           */
setHideOfflineContacts(ContentResolver contentResolver, long providerId, boolean hideOfflineContacts)1790          public static void setHideOfflineContacts(ContentResolver contentResolver,
1791                  long providerId, boolean hideOfflineContacts) {
1792              putBooleanValue(contentResolver, providerId, SETTING_HIDE_OFFLINE_CONTACTS,
1793                      hideOfflineContacts);
1794          }
1795  
1796          /**
1797           * A convenience method to set whether or not enable the IM notification.
1798           *
1799           * @param contentResolver The ContentResolver to use to access the setting table.
1800           * @param enable Whether enable the IM notification
1801           */
setEnableNotification(ContentResolver contentResolver, long providerId, boolean enable)1802          public static void setEnableNotification(ContentResolver contentResolver, long providerId,
1803                  boolean enable) {
1804              putBooleanValue(contentResolver, providerId, SETTING_ENABLE_NOTIFICATION, enable);
1805          }
1806  
1807          /**
1808           * A convenience method to set whether or not to vibrate.
1809           *
1810           * @param contentResolver The ContentResolver to use to access the setting table.
1811           * @param vibrate Whether or not to vibrate
1812           */
setVibrate(ContentResolver contentResolver, long providerId, boolean vibrate)1813          public static void setVibrate(ContentResolver contentResolver, long providerId,
1814                  boolean vibrate) {
1815              putBooleanValue(contentResolver, providerId, SETTING_VIBRATE, vibrate);
1816          }
1817  
1818          /**
1819           * A convenience method to set the Uri String of the ringtone.
1820           *
1821           * @param contentResolver The ContentResolver to use to access the setting table.
1822           * @param ringtoneUri The Uri String of the ringtone to be set.
1823           */
setRingtoneURI(ContentResolver contentResolver, long providerId, String ringtoneUri)1824          public static void setRingtoneURI(ContentResolver contentResolver, long providerId,
1825                  String ringtoneUri) {
1826              putStringValue(contentResolver, providerId, SETTING_RINGTONE, ringtoneUri);
1827          }
1828  
1829          /**
1830           * A convenience method to set whether or not to show mobile indicator.
1831           *
1832           * @param contentResolver The ContentResolver to use to access the setting table.
1833           * @param showMobileIndicator Whether or not to show mobile indicator.
1834           */
setShowMobileIndicator(ContentResolver contentResolver, long providerId, boolean showMobileIndicator)1835          public static void setShowMobileIndicator(ContentResolver contentResolver, long providerId,
1836                  boolean showMobileIndicator) {
1837              putBooleanValue(contentResolver, providerId, SETTING_SHOW_MOBILE_INDICATOR,
1838                      showMobileIndicator);
1839          }
1840  
1841          /**
1842           * A convenience method to set whether or not to show as away when device is idle.
1843           *
1844           * @param contentResolver The ContentResolver to use to access the setting table.
1845           * @param showAway Whether or not to show as away when device is idle.
1846           */
setShowAwayOnIdle(ContentResolver contentResolver, long providerId, boolean showAway)1847          public static void setShowAwayOnIdle(ContentResolver contentResolver,
1848                  long providerId, boolean showAway) {
1849              putBooleanValue(contentResolver, providerId, SETTING_SHOW_AWAY_ON_IDLE, showAway);
1850          }
1851  
1852          /**
1853           * A convenience method to set whether or not to upload heartbeat stat.
1854           *
1855           * @param contentResolver The ContentResolver to use to access the setting table.
1856           * @param uploadStat Whether or not to upload heartbeat stat.
1857           */
setUploadHeartbeatStat(ContentResolver contentResolver, long providerId, boolean uploadStat)1858          public static void setUploadHeartbeatStat(ContentResolver contentResolver,
1859                  long providerId, boolean uploadStat) {
1860              putBooleanValue(contentResolver, providerId, SETTING_UPLOAD_HEARTBEAT_STAT, uploadStat);
1861          }
1862  
1863          /**
1864           * A convenience method to set the heartbeat interval last received from the server.
1865           *
1866           * @param contentResolver The ContentResolver to use to access the setting table.
1867           * @param interval The heartbeat interval last received from the server.
1868           */
setHeartbeatInterval(ContentResolver contentResolver, long providerId, long interval)1869          public static void setHeartbeatInterval(ContentResolver contentResolver,
1870                  long providerId, long interval) {
1871              putLongValue(contentResolver, providerId, SETTING_HEARTBEAT_INTERVAL, interval);
1872          }
1873  
1874          /**
1875           * A convenience method to set the jid resource.
1876           */
setJidResource(ContentResolver contentResolver, long providerId, String jidResource)1877          public static void setJidResource(ContentResolver contentResolver,
1878                                            long providerId, String jidResource) {
1879              putStringValue(contentResolver, providerId, SETTING_JID_RESOURCE, jidResource);
1880          }
1881  
1882          public static class QueryMap extends ContentQueryMap {
1883              private ContentResolver mContentResolver;
1884              private long mProviderId;
1885  
QueryMap(ContentResolver contentResolver, long providerId, boolean keepUpdated, Handler handlerForUpdateNotifications)1886              public QueryMap(ContentResolver contentResolver, long providerId, boolean keepUpdated,
1887                      Handler handlerForUpdateNotifications) {
1888                  super(contentResolver.query(CONTENT_URI,
1889                              new String[] {NAME,VALUE},
1890                              PROVIDER + "=" + providerId,
1891                              null, // no selection args
1892                              null), // no sort order
1893                          NAME, keepUpdated, handlerForUpdateNotifications);
1894                  mContentResolver = contentResolver;
1895                  mProviderId = providerId;
1896              }
1897  
1898              /**
1899               * Set if the GTalk service should automatically connect to server.
1900               *
1901               * @param autoConnect if the GTalk service should auto connect to server.
1902               */
setAutomaticallyConnectToGTalkServer(boolean autoConnect)1903              public void setAutomaticallyConnectToGTalkServer(boolean autoConnect) {
1904                  ProviderSettings.setAutomaticallyConnectGTalk(mContentResolver, mProviderId,
1905                          autoConnect);
1906              }
1907  
1908              /**
1909               * Check if the GTalk service should automatically connect to server.
1910               * @return if the GTalk service should automatically connect to server.
1911               */
getAutomaticallyConnectToGTalkServer()1912              public boolean getAutomaticallyConnectToGTalkServer() {
1913                  return getBoolean(SETTING_AUTOMATICALLY_CONNECT_GTALK,
1914                          true /* default to automatically sign in */);
1915              }
1916  
1917              /**
1918               * Set whether or not the offline contacts should be hided.
1919               *
1920               * @param hideOfflineContacts Whether or not the offline contacts should be hided.
1921               */
setHideOfflineContacts(boolean hideOfflineContacts)1922              public void setHideOfflineContacts(boolean hideOfflineContacts) {
1923                  ProviderSettings.setHideOfflineContacts(mContentResolver, mProviderId,
1924                          hideOfflineContacts);
1925              }
1926  
1927              /**
1928               * Check if the offline contacts should be hided.
1929               *
1930               * @return Whether or not the offline contacts should be hided.
1931               */
getHideOfflineContacts()1932              public boolean getHideOfflineContacts() {
1933                  return getBoolean(SETTING_HIDE_OFFLINE_CONTACTS,
1934                          false/* by default not hide the offline contacts*/);
1935              }
1936  
1937              /**
1938               * Set whether or not enable the IM notification.
1939               *
1940               * @param enable Whether or not enable the IM notification.
1941               */
setEnableNotification(boolean enable)1942              public void setEnableNotification(boolean enable) {
1943                  ProviderSettings.setEnableNotification(mContentResolver, mProviderId, enable);
1944              }
1945  
1946              /**
1947               * Check if the IM notification is enabled.
1948               *
1949               * @return Whether or not enable the IM notification.
1950               */
getEnableNotification()1951              public boolean getEnableNotification() {
1952                  return getBoolean(SETTING_ENABLE_NOTIFICATION,
1953                          true/* by default enable the notification */);
1954              }
1955  
1956              /**
1957               * Set whether or not to vibrate on IM notification.
1958               *
1959               * @param vibrate Whether or not to vibrate.
1960               */
setVibrate(boolean vibrate)1961              public void setVibrate(boolean vibrate) {
1962                  ProviderSettings.setVibrate(mContentResolver, mProviderId, vibrate);
1963              }
1964  
1965              /**
1966               * Gets whether or not to vibrate on IM notification.
1967               *
1968               * @return Whether or not to vibrate.
1969               */
getVibrate()1970              public boolean getVibrate() {
1971                  return getBoolean(SETTING_VIBRATE, false /* by default disable vibrate */);
1972              }
1973  
1974              /**
1975               * Set the Uri for the ringtone.
1976               *
1977               * @param ringtoneUri The Uri of the ringtone to be set.
1978               */
setRingtoneURI(String ringtoneUri)1979              public void setRingtoneURI(String ringtoneUri) {
1980                  ProviderSettings.setRingtoneURI(mContentResolver, mProviderId, ringtoneUri);
1981              }
1982  
1983              /**
1984               * Get the Uri String of the current ringtone.
1985               *
1986               * @return The Uri String of the current ringtone.
1987               */
getRingtoneURI()1988              public String getRingtoneURI() {
1989                  return getString(SETTING_RINGTONE, SETTING_RINGTONE_DEFAULT);
1990              }
1991  
1992              /**
1993               * Set whether or not to show mobile indicator to friends.
1994               *
1995               * @param showMobile whether or not to show mobile indicator.
1996               */
setShowMobileIndicator(boolean showMobile)1997              public void setShowMobileIndicator(boolean showMobile) {
1998                  ProviderSettings.setShowMobileIndicator(mContentResolver, mProviderId, showMobile);
1999              }
2000  
2001              /**
2002               * Gets whether or not to show mobile indicator.
2003               *
2004               * @return Whether or not to show mobile indicator.
2005               */
getShowMobileIndicator()2006              public boolean getShowMobileIndicator() {
2007                  return getBoolean(SETTING_SHOW_MOBILE_INDICATOR,
2008                          true /* by default show mobile indicator */);
2009              }
2010  
2011              /**
2012               * Set whether or not to show as away when device is idle.
2013               *
2014               * @param showAway whether or not to show as away when device is idle.
2015               */
setShowAwayOnIdle(boolean showAway)2016              public void setShowAwayOnIdle(boolean showAway) {
2017                  ProviderSettings.setShowAwayOnIdle(mContentResolver, mProviderId, showAway);
2018              }
2019  
2020              /**
2021               * Get whether or not to show as away when device is idle.
2022               *
2023               * @return Whether or not to show as away when device is idle.
2024               */
getShowAwayOnIdle()2025              public boolean getShowAwayOnIdle() {
2026                  return getBoolean(SETTING_SHOW_AWAY_ON_IDLE,
2027                          true /* by default show as away on idle*/);
2028              }
2029  
2030              /**
2031               * Set whether or not to upload heartbeat stat.
2032               *
2033               * @param uploadStat whether or not to upload heartbeat stat.
2034               */
setUploadHeartbeatStat(boolean uploadStat)2035              public void setUploadHeartbeatStat(boolean uploadStat) {
2036                  ProviderSettings.setUploadHeartbeatStat(mContentResolver, mProviderId, uploadStat);
2037              }
2038  
2039              /**
2040               * Get whether or not to upload heartbeat stat.
2041               *
2042               * @return Whether or not to upload heartbeat stat.
2043               */
getUploadHeartbeatStat()2044              public boolean getUploadHeartbeatStat() {
2045                  return getBoolean(SETTING_UPLOAD_HEARTBEAT_STAT,
2046                          false /* by default do not upload */);
2047              }
2048  
2049              /**
2050               * Set the last received heartbeat interval from the server.
2051               *
2052               * @param interval the last received heartbeat interval from the server.
2053               */
setHeartbeatInterval(long interval)2054              public void setHeartbeatInterval(long interval) {
2055                  ProviderSettings.setHeartbeatInterval(mContentResolver, mProviderId, interval);
2056              }
2057  
2058              /**
2059               * Get the last received heartbeat interval from the server.
2060               *
2061               * @return the last received heartbeat interval from the server.
2062               */
getHeartbeatInterval()2063              public long getHeartbeatInterval() {
2064                  return getLong(SETTING_HEARTBEAT_INTERVAL, 0L /* an invalid default interval */);
2065              }
2066  
2067              /**
2068               * Set the JID resource.
2069               *
2070               * @param jidResource the jid resource to be stored.
2071               */
setJidResource(String jidResource)2072              public void setJidResource(String jidResource) {
2073                  ProviderSettings.setJidResource(mContentResolver, mProviderId, jidResource);
2074              }
2075              /**
2076               * Get the JID resource used for the Google Talk connection
2077               *
2078               * @return the JID resource stored.
2079               */
getJidResource()2080              public String getJidResource() {
2081                  return getString(SETTING_JID_RESOURCE, null);
2082              }
2083  
2084              /**
2085               * Convenience function for retrieving a single settings value
2086               * as a boolean.
2087               *
2088               * @param name The name of the setting to retrieve.
2089               * @param def Value to return if the setting is not defined.
2090               * @return The setting's current value, or 'def' if it is not defined.
2091               */
getBoolean(String name, boolean def)2092              private boolean getBoolean(String name, boolean def) {
2093                  ContentValues values = getValues(name);
2094                  return values != null ? values.getAsBoolean(VALUE) : def;
2095              }
2096  
2097              /**
2098               * Convenience function for retrieving a single settings value
2099               * as a String.
2100               *
2101               * @param name The name of the setting to retrieve.
2102               * @param def The value to return if the setting is not defined.
2103               * @return The setting's current value or 'def' if it is not defined.
2104               */
getString(String name, String def)2105              private String getString(String name, String def) {
2106                  ContentValues values = getValues(name);
2107                  return values != null ? values.getAsString(VALUE) : def;
2108              }
2109  
2110              /**
2111               * Convenience function for retrieving a single settings value
2112               * as an Integer.
2113               *
2114               * @param name The name of the setting to retrieve.
2115               * @param def The value to return if the setting is not defined.
2116               * @return The setting's current value or 'def' if it is not defined.
2117               */
getInteger(String name, int def)2118              private int getInteger(String name, int def) {
2119                  ContentValues values = getValues(name);
2120                  return values != null ? values.getAsInteger(VALUE) : def;
2121              }
2122  
2123              /**
2124               * Convenience function for retrieving a single settings value
2125               * as a Long.
2126               *
2127               * @param name The name of the setting to retrieve.
2128               * @param def The value to return if the setting is not defined.
2129               * @return The setting's current value or 'def' if it is not defined.
2130               */
getLong(String name, long def)2131              private long getLong(String name, long def) {
2132                  ContentValues values = getValues(name);
2133                  return values != null ? values.getAsLong(VALUE) : def;
2134              }
2135          }
2136  
2137      }
2138  
2139  
2140      /**
2141       * Columns for IM branding resource map cache table. This table caches the result of
2142       * loading the branding resources to speed up IM landing page start.
2143       */
2144      public interface BrandingResourceMapCacheColumns {
2145          /**
2146           * The provider ID
2147           * <P>Type: INTEGER</P>
2148           */
2149          String PROVIDER_ID = "provider_id";
2150          /**
2151           * The application resource ID
2152           * <P>Type: INTEGER</P>
2153           */
2154          String APP_RES_ID = "app_res_id";
2155          /**
2156           * The plugin resource ID
2157           * <P>Type: INTEGER</P>
2158           */
2159          String PLUGIN_RES_ID = "plugin_res_id";
2160      }
2161  
2162      /**
2163       * The table for caching the result of loading IM branding resources.
2164       */
2165      public static final class BrandingResourceMapCache
2166          implements BaseColumns, BrandingResourceMapCacheColumns {
2167          /**
2168           * The content:// style URL for this table.
2169           */
2170          public static final Uri CONTENT_URI = Uri.parse("content://imps/brandingResMapCache");
2171      }
2172  
2173  
2174  
2175      /**
2176       * //TODO: move these to MCS specific provider.
2177       * The following are MCS stuff, and should really live in a separate provider specific to
2178       * MCS code.
2179       */
2180  
2181      /**
2182       * Columns from OutgoingRmq table
2183       */
2184      public interface OutgoingRmqColumns {
2185          String RMQ_ID = "rmq_id";
2186          String TIMESTAMP = "ts";
2187          String DATA = "data";
2188          String PROTOBUF_TAG = "type";
2189      }
2190  
2191      /**
2192       * //TODO: we should really move these to their own provider and database.
2193       * The table for storing outgoing rmq packets.
2194       */
2195      public static final class OutgoingRmq implements BaseColumns, OutgoingRmqColumns {
2196          private static String[] RMQ_ID_PROJECTION = new String[] {
2197                  RMQ_ID,
2198          };
2199  
2200          /**
2201           * queryHighestRmqId
2202           *
2203           * @param resolver the content resolver
2204           * @return the highest rmq id assigned to the rmq packet, or 0 if there are no rmq packets
2205           *         in the OutgoingRmq table.
2206           */
queryHighestRmqId(ContentResolver resolver)2207          public static final long queryHighestRmqId(ContentResolver resolver) {
2208              Cursor cursor = resolver.query(Imps.OutgoingRmq.CONTENT_URI_FOR_HIGHEST_RMQ_ID,
2209                      RMQ_ID_PROJECTION,
2210                      null, // selection
2211                      null, // selection args
2212                      null  // sort
2213                      );
2214  
2215              long retVal = 0;
2216              try {
2217                  //if (DBG) log("initializeRmqid: cursor.count= " + cursor.count());
2218  
2219                  if (cursor.moveToFirst()) {
2220                      retVal = cursor.getLong(cursor.getColumnIndexOrThrow(RMQ_ID));
2221                  }
2222              } finally {
2223                  cursor.close();
2224              }
2225  
2226              return retVal;
2227          }
2228  
2229          /**
2230           * The content:// style URL for this table.
2231           */
2232          public static final Uri CONTENT_URI = Uri.parse("content://imps/outgoingRmqMessages");
2233  
2234          /**
2235           * The content:// style URL for the highest rmq id for the outgoing rmq messages
2236           */
2237          public static final Uri CONTENT_URI_FOR_HIGHEST_RMQ_ID =
2238                  Uri.parse("content://imps/outgoingHighestRmqId");
2239  
2240          /**
2241           * The default sort order for this table.
2242           */
2243          public static final String DEFAULT_SORT_ORDER = "rmq_id ASC";
2244      }
2245  
2246      /**
2247       * Columns for the LastRmqId table, which stores a single row for the last client rmq id
2248       * sent to the server.
2249       */
2250      public interface LastRmqIdColumns {
2251          String RMQ_ID = "rmq_id";
2252      }
2253  
2254      /**
2255       * //TODO: move these out into their own provider and database
2256       * The table for storing the last client rmq id sent to the server.
2257       */
2258      public static final class LastRmqId implements BaseColumns, LastRmqIdColumns {
2259          private static String[] PROJECTION = new String[] {
2260                  RMQ_ID,
2261          };
2262  
2263          /**
2264           * queryLastRmqId
2265           *
2266           * queries the last rmq id saved in the LastRmqId table.
2267           *
2268           * @param resolver the content resolver.
2269           * @return the last rmq id stored in the LastRmqId table, or 0 if not found.
2270           */
queryLastRmqId(ContentResolver resolver)2271          public static final long queryLastRmqId(ContentResolver resolver) {
2272              Cursor cursor = resolver.query(Imps.LastRmqId.CONTENT_URI,
2273                      PROJECTION,
2274                      null, // selection
2275                      null, // selection args
2276                      null  // sort
2277                      );
2278  
2279              long retVal = 0;
2280              try {
2281                  if (cursor.moveToFirst()) {
2282                      retVal = cursor.getLong(cursor.getColumnIndexOrThrow(RMQ_ID));
2283                  }
2284              } finally {
2285                  cursor.close();
2286              }
2287  
2288              return retVal;
2289          }
2290  
2291          /**
2292           * saveLastRmqId
2293           *
2294           * saves the rmqId to the lastRmqId table. This will override the existing row if any,
2295           * as we only keep one row of data in this table.
2296           *
2297           * @param resolver the content resolver.
2298           * @param rmqId the rmq id to be saved.
2299           */
saveLastRmqId(ContentResolver resolver, long rmqId)2300          public static final void saveLastRmqId(ContentResolver resolver, long rmqId) {
2301              ContentValues values = new ContentValues();
2302  
2303              // always replace the first row.
2304              values.put(_ID, 1);
2305              values.put(RMQ_ID, rmqId);
2306              resolver.insert(CONTENT_URI, values);
2307          }
2308  
2309          /**
2310           * The content:// style URL for this table.
2311           */
2312          public static final Uri CONTENT_URI = Uri.parse("content://imps/lastRmqId");
2313      }
2314  
2315      /**
2316       * Columns for the s2dRmqIds table, which stores the server-to-device message
2317       * persistent ids. These are used in the RMQ2 protocol, where in the login request, the
2318       * client selective acks these s2d ids to the server.
2319       */
2320      public interface ServerToDeviceRmqIdsColumn {
2321          String RMQ_ID = "rmq_id";
2322      }
2323  
2324      public static final class ServerToDeviceRmqIds implements BaseColumns,
2325              ServerToDeviceRmqIdsColumn {
2326  
2327          /**
2328           * The content:// style URL for this table.
2329           */
2330          public static final Uri CONTENT_URI = Uri.parse("content://imps/s2dids");
2331      }
2332  
2333  }
2334