1 /*
2  *  Copyright (C) 2008-2009 Marc Blank
3  * Licensed to The Android Open Source Project.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 package com.android.emailcommon.service;
19 
20 import android.content.ContentResolver;
21 import android.net.Uri;
22 import android.os.Bundle;
23 
24 /**
25  * Definitions of service status codes returned to IEmailServiceCallback's status method.
26  *
27  * Now that all sync requests are sent through the system SyncManager, there's no way to specify the
28  * {@link IEmailServiceCallback} to {@link ContentResolver#requestSync} since all we have is a
29  * {@link Bundle}. Instead, the caller requesting the sync specifies values with which to call
30  * {@link ContentResolver#call} in order to receive a callback, and the
31  * {@link android.content.ContentProvider} must handle this call.
32  */
33 public abstract class EmailServiceStatus {
34     public static final int SUCCESS = 0;
35     public static final int IN_PROGRESS = 1;
36     public static final int FAILURE = 2;
37 
38     public static final int MESSAGE_NOT_FOUND = 0x10;
39     public static final int ATTACHMENT_NOT_FOUND = 0x11;
40     public static final int FOLDER_NOT_DELETED = 0x12;
41     public static final int FOLDER_NOT_RENAMED = 0x13;
42     public static final int FOLDER_NOT_CREATED = 0x14;
43     public static final int REMOTE_EXCEPTION = 0x15;
44     public static final int LOGIN_FAILED = 0x16;
45     public static final int SECURITY_FAILURE = 0x17;
46     public static final int ACCOUNT_UNINITIALIZED = 0x18;
47     public static final int ACCESS_DENIED = 0x19;
48 
49     // Maybe we should automatically retry these?
50     public static final int CONNECTION_ERROR = 0x20;
51 
52     // Client certificates used to authenticate cannot be retrieved from the system.
53     public static final int CLIENT_CERTIFICATE_ERROR = 0x21;
54 
55     // Data is invalid on the client side, sync cannot proceed.
56     public static final int HARD_DATA_ERROR = 0x22;
57 
58     // Sync failed due to some type of IO error.
59     public static final int IO_ERROR = 0x23;
60 
61     // The sync call encountered a protocol error.
62     public static final int PROTOCOL_ERROR = 0x24;
63 
64     // The sync call encountered too many redirects.
65     public static final int TOO_MANY_REDIRECTS = 0x25;
66 
67     // The sync call encountered a provisioning error.
68     public static final int PROVISIONING_ERROR = 0x26;
69 
70     // We have encountered some sort of unexpected illegal state.
71     public static final int INTERNAL_ERROR = 0x27;
72 
73     // Keys for the sync extras Bundle that specify the callback.
74     public static final String SYNC_EXTRAS_CALLBACK_URI = "callback_uri";
75     public static final String SYNC_EXTRAS_CALLBACK_METHOD = "callback_method";
76     public static final String SYNC_EXTRAS_CALLBACK_ARG = "callback_arg";
77 
78     // Keys for the status Bundle sent to the callback. These keys are used in every status type.
79     public static final String SYNC_STATUS_TYPE = "type";
80     public static final String SYNC_STATUS_ID = "id";
81     public static final String SYNC_STATUS_CODE = "status_code";
82     public static final String SYNC_RESULT = "result";
83     public static final String SYNC_STATUS_PROGRESS = "progress";
84 
85     // Values for the SYNC_STATUS_TYPE to specify what kind of sync status we're returning.
86     public static final int SYNC_STATUS_TYPE_MAILBOX = 0;
87 
88     /**
89      * Some status updates need to provide values in addition to the core id, code, and progress.
90      * Those updates will provide an appropriate StatusWriter to fill in those extras.
91      */
92     private static interface StatusWriter {
addToStatus(final Bundle statusExtras)93         public void addToStatus(final Bundle statusExtras);
94     }
95 
96     /**
97      * Generic function to check if the callback is necessary and, if so, perform it.
98      * The function is the common parts for the following functions, which are for use by the
99      * {@link android.content.AbstractThreadedSyncAdapter} to communicate the status of a sync
100      * action to the caller.
101      * @param cr A ContentResolver.
102      * @param syncExtras The extras provided to the sync request.
103      * @param statusType The type of sync status update to send.
104      * @param id The id of the thing whose status is being updated (type depends on statusType).
105      * @param statusCode The status code for this sync operation.
106      * @param progress The progress of this sync operation.
107      * @param writer If not null, an object which will write additional status fields.
108      */
syncStatus(final ContentResolver cr, final Bundle syncExtras, final int statusType, final long id, final int statusCode, final int progress, int syncResult, final StatusWriter writer)109     private static void syncStatus(final ContentResolver cr, final Bundle syncExtras,
110             final int statusType, final long id, final int statusCode, final int progress,
111             int syncResult,
112             final StatusWriter writer) {
113         final String callbackUri = syncExtras.getString(SYNC_EXTRAS_CALLBACK_URI);
114         final String callbackMethod = syncExtras.getString(SYNC_EXTRAS_CALLBACK_METHOD);
115         if (callbackUri != null && callbackMethod != null) {
116             final String callbackArg = syncExtras.getString(SYNC_EXTRAS_CALLBACK_ARG, "");
117             final Bundle statusExtras = new Bundle(4);
118             statusExtras.putInt(SYNC_STATUS_TYPE, statusType);
119             statusExtras.putLong(SYNC_STATUS_ID, id);
120             statusExtras.putInt(SYNC_STATUS_CODE, statusCode);
121             if (statusCode != IN_PROGRESS) {
122                 statusExtras.putInt(SYNC_RESULT, syncResult);
123             }
124             statusExtras.putInt(SYNC_STATUS_PROGRESS, progress);
125             if (writer != null) {
126                 writer.addToStatus(statusExtras);
127             }
128             cr.call(Uri.parse(callbackUri), callbackMethod, callbackArg, statusExtras);
129         }
130     }
131 
132     /**
133      * If the sync extras specify a callback, then notify the sync requester of the mailbox's
134      * sync status. This function is for use by the
135      * {@link android.content.AbstractThreadedSyncAdapter}.
136      * @param cr A ContentResolver.
137      * @param syncExtras The extras provided to the sync request.
138      * @param mailboxId The mailbox whose status is changing.
139      * @param statusCode The status code for this sync operation.
140      * @param progress The progress of this sync operation.
141      */
syncMailboxStatus(final ContentResolver cr, final Bundle syncExtras, final long mailboxId, final int statusCode, final int progress, int syncResult)142     public static void syncMailboxStatus(final ContentResolver cr, final Bundle syncExtras,
143             final long mailboxId, final int statusCode, final int progress, int syncResult) {
144         syncStatus(cr, syncExtras, SYNC_STATUS_TYPE_MAILBOX, mailboxId, statusCode, progress,
145                 syncResult, null);
146     }
147 
148 
149 }
150