Account.java revision 7418e4b9942f291b8de8bc7b1b72a7ef7130a8b6
1/**
2 * Copyright (c) 2012, Google Inc.
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
17package com.android.mail.providers;
18
19import android.database.Cursor;
20import android.net.Uri;
21import android.os.Parcel;
22import android.os.Parcelable;
23import android.text.TextUtils;
24
25import java.util.regex.Pattern;
26
27import com.android.mail.utils.LogUtils;
28
29public class Account extends android.accounts.Account implements Parcelable {
30    /**
31     * The version of the UI provider schema from which this account provider
32     * will return results.
33     */
34    public final int providerVersion;
35
36    /**
37     * The uri to directly access the information for this account.
38     */
39    public final Uri uri;
40
41    /**
42     * The possible capabilities that this account supports.
43     */
44    public final int capabilities;
45
46    /**
47     * The content provider uri to return the list of top level folders for this
48     * account.
49     */
50    public final Uri folderListUri;
51
52    /**
53     * The content provider uri that can be queried for search results.
54     */
55    public final Uri searchUri;
56
57    /**
58     * The content provider uri that can be queried to access the from addresses
59     * for this account.
60     */
61    public final Uri accountFromAddressesUri;
62
63    /**
64     * The content provider uri that can be used to save (insert) new draft
65     * messages for this account. NOTE: This might be better to be an update
66     * operation on the messageUri.
67     */
68    public final Uri saveDraftUri;
69
70    /**
71     * The content provider uri that can be used to send a message for this
72     * account.
73     * NOTE: This might be better to be an update operation on the
74     * messageUri.
75     */
76    public final Uri sendMessageUri;
77
78    /**
79     * The content provider uri that can be used to expunge message from this
80     * account. NOTE: This might be better to be an update operation on the
81     * messageUri.
82     */
83    public final Uri expungeMessageUri;
84
85    /**
86     * The content provider uri that can be used to undo the last operation
87     * performed.
88     */
89    public final Uri undoUri;
90
91    /**
92     * Uri for EDIT intent that will cause the settings screens for this account type to be
93     * shown.
94     */
95    public final Uri settingIntentUri;
96
97    /**
98     * The content provider uri that can be used to query user settings/preferences
99     */
100    public final Uri settingQueryUri;
101
102    /**
103     * Uri for VIEW intent that will cause the help screens for this account type to be
104     * shown.
105     */
106    public final Uri helpIntentUri;
107
108    /**
109     * The sync status of the account
110     */
111    public final int syncStatus;
112
113    /**
114     * Uri for VIEW intent that will cause the compose screen for this account type to be
115     * shown.
116     */
117    public final Uri composeIntentUri;
118
119    /**
120     * Total number of members that comprise an instance of an account. This is
121     * the number of members that need to be serialized or parceled. This
122     * includes the members described above and name and type from the
123     * superclass.
124     */
125    private static final int NUMBER_MEMBERS = 17;
126
127    /**
128     * Examples of expected format for the joined account strings
129     *
130     * Example of a joined account string:
131     *       630107622^*^^i^*^^i^*^0
132     *       <id>^*^<canonical name>^*^<name>^*^<color index>
133     *
134     */
135    private static final String ACCOUNT_COMPONENT_SEPARATOR = "^*^";
136    private static final Pattern ACCOUNT_COMPONENT_SEPARATOR_PATTERN =
137            Pattern.compile("\\^\\*\\^");
138    private static final String LOG_TAG = new LogUtils().getLogTag();
139
140    /**
141     * Return a serialized String for this folder.
142     */
143    public synchronized String serialize() {
144        StringBuilder out = new StringBuilder();
145        out.append(name).append(ACCOUNT_COMPONENT_SEPARATOR);
146        out.append(type).append(ACCOUNT_COMPONENT_SEPARATOR);
147        out.append(providerVersion).append(ACCOUNT_COMPONENT_SEPARATOR);
148        out.append(uri).append(ACCOUNT_COMPONENT_SEPARATOR);
149        out.append(capabilities).append(ACCOUNT_COMPONENT_SEPARATOR);
150        out.append(folderListUri).append(ACCOUNT_COMPONENT_SEPARATOR);
151        out.append(searchUri).append(ACCOUNT_COMPONENT_SEPARATOR);
152        out.append(accountFromAddressesUri).append(ACCOUNT_COMPONENT_SEPARATOR);
153        out.append(saveDraftUri).append(ACCOUNT_COMPONENT_SEPARATOR);
154        out.append(sendMessageUri).append(ACCOUNT_COMPONENT_SEPARATOR);
155        out.append(expungeMessageUri).append(ACCOUNT_COMPONENT_SEPARATOR);
156        out.append(undoUri).append(ACCOUNT_COMPONENT_SEPARATOR);
157        out.append(settingIntentUri).append(ACCOUNT_COMPONENT_SEPARATOR);
158        out.append(settingQueryUri).append(ACCOUNT_COMPONENT_SEPARATOR);
159        out.append(helpIntentUri).append(ACCOUNT_COMPONENT_SEPARATOR);
160        out.append(syncStatus).append(ACCOUNT_COMPONENT_SEPARATOR);
161        out.append(composeIntentUri);
162        return out.toString();
163    }
164
165    /**
166     * Construct a new Account instance from a previously serialized string.
167     * @param serializedAccount string obtained from {@link #serialize()} on a valid account.
168     */
169    public Account(String serializedAccount) {
170        super(TextUtils.split(serializedAccount, ACCOUNT_COMPONENT_SEPARATOR_PATTERN)[0], TextUtils
171                .split(serializedAccount, ACCOUNT_COMPONENT_SEPARATOR_PATTERN)[1]);
172        String[] accountMembers = TextUtils.split(serializedAccount,
173                ACCOUNT_COMPONENT_SEPARATOR_PATTERN);
174        if (accountMembers.length != NUMBER_MEMBERS) {
175            throw new IllegalArgumentException(
176                    "Account de-serializing failed. Wrong number of members detected.");
177        }
178        providerVersion = Integer.valueOf(accountMembers[2]);
179        uri = Uri.parse(accountMembers[3]);
180        capabilities = Integer.valueOf(accountMembers[4]);
181        folderListUri = Uri.parse(accountMembers[5]);
182        searchUri = Uri.parse(accountMembers[6]);
183        accountFromAddressesUri = Uri.parse(accountMembers[7]);
184        saveDraftUri = Uri.parse(accountMembers[8]);
185        sendMessageUri = Uri.parse(accountMembers[9]);
186        expungeMessageUri = Uri.parse(accountMembers[10]);
187        undoUri = Uri.parse(accountMembers[11]);
188        settingIntentUri = Uri.parse(accountMembers[12]);
189        settingQueryUri = Uri.parse(accountMembers[13]);
190        helpIntentUri = Uri.parse(accountMembers[14]);
191        syncStatus = Integer.valueOf(accountMembers[15]);
192        composeIntentUri = Uri.parse(accountMembers[16]);
193    }
194
195    public Account(Parcel in) {
196        super(in);
197        providerVersion = in.readInt();
198        uri = in.readParcelable(null);
199        capabilities = in.readInt();
200        folderListUri = in.readParcelable(null);
201        searchUri = in.readParcelable(null);
202        accountFromAddressesUri = in.readParcelable(null);
203        saveDraftUri = in.readParcelable(null);
204        sendMessageUri = in.readParcelable(null);
205        expungeMessageUri = in.readParcelable(null);
206        undoUri = in.readParcelable(null);
207        settingIntentUri = in.readParcelable(null);
208        settingQueryUri = in.readParcelable(null);
209        helpIntentUri = in.readParcelable(null);
210        syncStatus = in.readInt();
211        composeIntentUri = in.readParcelable(null);
212    }
213
214    public Account(Cursor cursor) {
215        super(cursor.getString(UIProvider.ACCOUNT_NAME_COLUMN), "unknown");
216        String fromAddresses = cursor
217                .getString(UIProvider.ACCOUNT_FROM_ADDRESSES_URI_COLUMN);
218        accountFromAddressesUri = !TextUtils.isEmpty(fromAddresses) ? Uri.parse(fromAddresses)
219                : null;
220        capabilities = cursor.getInt(UIProvider.ACCOUNT_CAPABILITIES_COLUMN);
221        providerVersion = cursor.getInt(UIProvider.ACCOUNT_PROVIDER_VERISON_COLUMN);
222        uri = Uri.parse(cursor.getString(UIProvider.ACCOUNT_URI_COLUMN));
223        folderListUri = Uri.parse(cursor.getString(UIProvider.ACCOUNT_FOLDER_LIST_URI_COLUMN));
224        final String search = cursor.getString(UIProvider.ACCOUNT_SEARCH_URI_COLUMN);
225        searchUri = !TextUtils.isEmpty(search) ? Uri.parse(search) : null;
226        saveDraftUri = Uri.parse(cursor.getString(UIProvider.ACCOUNT_SAVE_DRAFT_URI_COLUMN));
227        sendMessageUri = Uri.parse(cursor.getString(UIProvider.ACCOUNT_SEND_MESSAGE_URI_COLUMN));
228        final String expunge = cursor.getString(UIProvider.ACCOUNT_EXPUNGE_MESSAGE_URI_COLUMN);
229        expungeMessageUri = !TextUtils.isEmpty(expunge) ? Uri.parse(expunge) : null;
230        final String undo = cursor.getString(UIProvider.ACCOUNT_UNDO_URI_COLUMN);
231        undoUri = !TextUtils.isEmpty(undo) ? Uri.parse(undo) : null;
232        final String settings = cursor.getString(UIProvider.ACCOUNT_SETTINGS_INTENT_URI_COLUMN);
233        settingIntentUri = !TextUtils.isEmpty(settings) ? Uri.parse(settings) : null;
234        final String settingsQuery = cursor.getString(UIProvider.ACCOUNT_SETTINGS_QUERY_URI_COLUMN);
235        settingQueryUri = !TextUtils.isEmpty(settingsQuery) ? Uri.parse(settingsQuery) : null;
236        final String help = cursor.getString(UIProvider.ACCOUNT_HELP_INTENT_URI_COLUMN);
237        helpIntentUri = !TextUtils.isEmpty(help) ? Uri.parse(help) : null;
238        syncStatus = cursor.getInt(UIProvider.ACCOUNT_SYNC_STATUS_COLUMN);
239        final String compose = cursor.getString(UIProvider.ACCOUNT_COMPOSE_INTENT_URI_COLUMN);
240        composeIntentUri = !TextUtils.isEmpty(compose) ? Uri.parse(compose) : null;
241    }
242
243    /**
244     * Returns an array of all Accounts located at this cursor.
245     * This method does not close the cursor.
246     * @param cursor cursor pointing to the list of accounts
247     * @return the array of all accounts stored at this cursor.
248     */
249    public static Account[] getAllAccounts(Cursor cursor) {
250        final int initialLength = cursor.getCount();
251        if (initialLength <= 0 || !cursor.moveToFirst()) {
252            // Return zero length account array rather than null
253            return new Account[0];
254        }
255
256        Account[] allAccounts = new Account[initialLength];
257        for (int i = 0; i < initialLength; i++) {
258            allAccounts[i] = new Account(cursor);
259            if (!cursor.moveToNext()) {
260                LogUtils.d(LOG_TAG, "Expecting " + initialLength + " accounts. Got: " + i);
261                break;
262            }
263        }
264        return allAccounts;
265    }
266
267    public boolean supportsCapability(int capability) {
268        return (capabilities & capability) != 0;
269    }
270
271    @Override
272    public void writeToParcel(Parcel dest, int flags) {
273        super.writeToParcel(dest, flags);
274        dest.writeInt(providerVersion);
275        dest.writeParcelable(uri, 0);
276        dest.writeInt(capabilities);
277        dest.writeParcelable(folderListUri, 0);
278        dest.writeParcelable(searchUri, 0);
279        dest.writeParcelable(accountFromAddressesUri, 0);
280        dest.writeParcelable(saveDraftUri, 0);
281        dest.writeParcelable(sendMessageUri, 0);
282        dest.writeParcelable(expungeMessageUri, 0);
283        dest.writeParcelable(undoUri, 0);
284        dest.writeParcelable(settingIntentUri, 0);
285        dest.writeParcelable(settingQueryUri, 0);
286        dest.writeParcelable(helpIntentUri, 0);
287        dest.writeInt(syncStatus);
288        dest.writeParcelable(composeIntentUri, 0);
289    }
290
291    /**
292     * Get the settings associated with this account.
293     * TODO: this method is just a stand-in.
294     */
295    public Cursor getSettings() {
296        return null;
297    }
298
299    public Folder getAccountInbox() {
300        // TODO: (mindyp) fill in with call to settings or reading of account settings
301        // to get the default inbox for this account.
302        return null;
303    }
304
305    @SuppressWarnings("hiding")
306    public static final Creator<Account> CREATOR = new Creator<Account>() {
307        @Override
308        public Account createFromParcel(Parcel source) {
309            return new Account(source);
310        }
311
312        @Override
313        public Account[] newArray(int size) {
314            return new Account[size];
315        }
316    };
317}
318