Merge "Handle Exchange meeting invitation responses"
This commit is contained in:
commit
3ef6b0493e
@ -684,6 +684,29 @@ public class Controller {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Respond to a meeting invitation.
|
||||
*
|
||||
* @param messageId the id of the invitation being responded to
|
||||
* @param response the code representing the response to the invitation
|
||||
* @callback the Controller callback by which results will be reported (currently not defined)
|
||||
*/
|
||||
public void sendMeetingResponse(final long messageId, final int response,
|
||||
final Result callback) {
|
||||
// Split here for target type (Service or MessagingController)
|
||||
IEmailService service = getServiceForMessage(messageId);
|
||||
if (service != null) {
|
||||
// Service implementation
|
||||
try {
|
||||
service.sendMeetingResponse(messageId, response);
|
||||
} catch (RemoteException e) {
|
||||
// TODO Change exception handling to be consistent with however this method
|
||||
// is implemented for other protocols
|
||||
Log.e("onDownloadAttachment", "RemoteException", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Request that an attachment be loaded. It will be stored at a location controlled
|
||||
* by the AttachmentProvider.
|
||||
|
@ -31,6 +31,7 @@ import com.android.email.provider.EmailContent.Attachment;
|
||||
import com.android.email.provider.EmailContent.Body;
|
||||
import com.android.email.provider.EmailContent.BodyColumns;
|
||||
import com.android.email.provider.EmailContent.Message;
|
||||
import com.android.exchange.EmailServiceConstants;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
@ -64,7 +65,6 @@ import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.Window;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.webkit.WebView;
|
||||
import android.webkit.WebViewClient;
|
||||
@ -676,6 +676,16 @@ public class MessageView extends Activity implements OnClickListener {
|
||||
return null;
|
||||
}
|
||||
|
||||
// NOTE
|
||||
// This is a placeholder for code used to accept a meeting invitation, and would presumably
|
||||
// be called in response to a button press or menu selection
|
||||
// The appropriate EmailServiceConstant would be changed to implement "decline" and
|
||||
// "tentative" responses
|
||||
private void onAccept() {
|
||||
mController.sendMeetingResponse(mMessageId, EmailServiceConstants.MEETING_REQUEST_ACCEPTED,
|
||||
mControllerCallback);
|
||||
}
|
||||
|
||||
private void onDownloadAttachment(AttachmentInfo attachment) {
|
||||
if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
|
||||
/*
|
||||
|
@ -542,12 +542,18 @@ public abstract class EmailContent {
|
||||
public static final int FLAG_LOADED_DELETED = 3;
|
||||
|
||||
// Bits used in mFlags
|
||||
// These three states are mutually exclusive, and indicate whether the message is an
|
||||
// The following three states are mutually exclusive, and indicate whether the message is an
|
||||
// original, a reply, or a forward
|
||||
public static final int FLAG_TYPE_ORIGINAL = 0;
|
||||
public static final int FLAG_TYPE_REPLY = 1<<0;
|
||||
public static final int FLAG_TYPE_FORWARD = 1<<1;
|
||||
public static final int FLAG_TYPE_MASK = FLAG_TYPE_REPLY | FLAG_TYPE_FORWARD;
|
||||
// The following flags indicate messages that are determined to be meeting related
|
||||
// (e.g. invites)
|
||||
public static final int FLAG_MEETING_INVITE = 1<<2;
|
||||
public static final int FLAG_MEETING_CANCEL_NOTICE = 1<<3;
|
||||
public static final int FLAG_MEETING_MASK =
|
||||
FLAG_MEETING_INVITE | FLAG_MEETING_CANCEL_NOTICE;
|
||||
|
||||
public Message() {
|
||||
mBaseUri = CONTENT_URI;
|
||||
|
@ -287,6 +287,18 @@ public class EmailServiceProxy implements IEmailService {
|
||||
});
|
||||
}
|
||||
|
||||
public void sendMeetingResponse(final long messageId, final int response) throws RemoteException {
|
||||
setTask(new Runnable () {
|
||||
public void run() {
|
||||
try {
|
||||
if (mCallback != null) mService.setCallback(mCallback);
|
||||
mService.sendMeetingResponse(messageId, response);
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void loadMore(long messageId) throws RemoteException {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
@ -76,8 +76,8 @@ public abstract class AbstractSyncService implements Runnable {
|
||||
protected Object mSynchronizer = new Object();
|
||||
|
||||
protected volatile long mRequestTime = 0;
|
||||
protected ArrayList<PartRequest> mPartRequests = new ArrayList<PartRequest>();
|
||||
protected PartRequest mPendingPartRequest = null;
|
||||
protected ArrayList<Request> mRequests = new ArrayList<Request>();
|
||||
protected PartRequest mPendingRequest = null;
|
||||
|
||||
/**
|
||||
* Sent by SyncManager to request that the service stop itself cleanly
|
||||
@ -282,54 +282,23 @@ public abstract class AbstractSyncService implements Runnable {
|
||||
}
|
||||
|
||||
/**
|
||||
* PartRequest handling (common functionality)
|
||||
* Can be overridden if desired, but IMAP/EAS both use the next three methods as-is
|
||||
* Request handling (common functionality)
|
||||
* Can be overridden if desired
|
||||
*/
|
||||
|
||||
public void addPartRequest(PartRequest req) {
|
||||
synchronized (mPartRequests) {
|
||||
mPartRequests.add(req);
|
||||
public void addRequest(Request req) {
|
||||
synchronized (mRequests) {
|
||||
mRequests.add(req);
|
||||
mRequestTime = System.currentTimeMillis();
|
||||
}
|
||||
}
|
||||
|
||||
public void removePartRequest(PartRequest req) {
|
||||
synchronized (mPartRequests) {
|
||||
mPartRequests.remove(req);
|
||||
public void removeRequest(Request req) {
|
||||
synchronized (mRequests) {
|
||||
mRequests.remove(req);
|
||||
}
|
||||
}
|
||||
|
||||
public PartRequest hasPartRequest(long emailId, String part) {
|
||||
synchronized (mPartRequests) {
|
||||
for (PartRequest pr : mPartRequests) {
|
||||
if (pr.emailId == emailId && pr.loc.equals(part))
|
||||
return pr;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// cancelPartRequest is sent in response to user input to stop an attachment load
|
||||
// that is in progress. This will almost certainly require code overriding the base
|
||||
// functionality, as sockets may need to be closed, etc. and this functionality will be
|
||||
// service dependent. This returns the canceled PartRequest or null
|
||||
public PartRequest cancelPartRequest(long emailId, String part) {
|
||||
synchronized (mPartRequests) {
|
||||
PartRequest p = null;
|
||||
for (PartRequest pr : mPartRequests) {
|
||||
if (pr.emailId == emailId && pr.loc.equals(part)) {
|
||||
p = pr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (p != null) {
|
||||
mPartRequests.remove(p);
|
||||
return p;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method wrapping calls to retrieve columns from a single row, via EmailProvider.
|
||||
* The arguments are exactly the same as to contentResolver.query(). Results are returned in
|
||||
|
31
src/com/android/exchange/EasAuthenticationException.java
Normal file
31
src/com/android/exchange/EasAuthenticationException.java
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.exchange;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Use this to be able to distinguish login (authentication) failures from other I/O
|
||||
* exceptions during a sync, as they are handled very differently.
|
||||
*/
|
||||
public class EasAuthenticationException extends IOException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
EasAuthenticationException() {
|
||||
super();
|
||||
}
|
||||
}
|
@ -34,6 +34,7 @@ import com.android.exchange.adapter.AccountSyncAdapter;
|
||||
import com.android.exchange.adapter.ContactsSyncAdapter;
|
||||
import com.android.exchange.adapter.EmailSyncAdapter;
|
||||
import com.android.exchange.adapter.FolderSyncParser;
|
||||
import com.android.exchange.adapter.MeetingResponseParser;
|
||||
import com.android.exchange.adapter.PingParser;
|
||||
import com.android.exchange.adapter.Serializer;
|
||||
import com.android.exchange.adapter.Tags;
|
||||
@ -628,7 +629,7 @@ public class EasSyncService extends AbstractSyncService {
|
||||
* @throws IOException
|
||||
*/
|
||||
protected void getAttachment(PartRequest req) throws IOException {
|
||||
Attachment att = req.att;
|
||||
Attachment att = req.mAttachment;
|
||||
Message msg = Message.restoreMessageWithId(mContext, att.mMessageKey);
|
||||
doProgressCallback(msg.mId, att.mId, 0);
|
||||
|
||||
@ -640,9 +641,9 @@ public class EasSyncService extends AbstractSyncService {
|
||||
HttpEntity e = res.getEntity();
|
||||
int len = (int)e.getContentLength();
|
||||
InputStream is = res.getEntity().getContent();
|
||||
File f = (req.destination != null)
|
||||
? new File(req.destination)
|
||||
: createUniqueFileInternal(req.destination, att.mFileName);
|
||||
File f = (req.mDestination != null)
|
||||
? new File(req.mDestination)
|
||||
: createUniqueFileInternal(req.mDestination, att.mFileName);
|
||||
if (f != null) {
|
||||
// Ensure that the target directory exists
|
||||
File destDir = f.getParentFile();
|
||||
@ -654,7 +655,7 @@ public class EasSyncService extends AbstractSyncService {
|
||||
// len < 0 means "chunked" transfer-encoding
|
||||
if (len != 0) {
|
||||
try {
|
||||
mPendingPartRequest = req;
|
||||
mPendingRequest = req;
|
||||
byte[] bytes = new byte[CHUNK_SIZE];
|
||||
int length = len;
|
||||
// Loop terminates 1) when EOF is reached or 2) if an IOException occurs
|
||||
@ -689,7 +690,7 @@ public class EasSyncService extends AbstractSyncService {
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
mPendingPartRequest = null;
|
||||
mPendingRequest = null;
|
||||
}
|
||||
}
|
||||
os.flush();
|
||||
@ -697,8 +698,8 @@ public class EasSyncService extends AbstractSyncService {
|
||||
|
||||
// EmailProvider will throw an exception if we try to update an unsaved attachment
|
||||
if (att.isSaved()) {
|
||||
String contentUriString = (req.contentUriString != null)
|
||||
? req.contentUriString
|
||||
String contentUriString = (req.mContentUriString != null)
|
||||
? req.mContentUriString
|
||||
: "file://" + f.getAbsolutePath();
|
||||
ContentValues cv = new ContentValues();
|
||||
cv.put(AttachmentColumns.CONTENT_URI, contentUriString);
|
||||
@ -711,6 +712,37 @@ public class EasSyncService extends AbstractSyncService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Responds to a meeting request. The MeetingResponseRequest is basically our
|
||||
* wrapper for the meetingResponse service call
|
||||
* @param req the request (message id and response code)
|
||||
* @throws IOException
|
||||
*/
|
||||
protected void sendMeetingResponse(MeetingResponseRequest req) throws IOException {
|
||||
Message msg = Message.restoreMessageWithId(mContext, req.mMessageId);
|
||||
Serializer s = new Serializer();
|
||||
s.start(Tags.MREQ_MEETING_RESPONSE).start(Tags.MREQ_REQUEST);
|
||||
s.data(Tags.MREQ_USER_RESPONSE, Integer.toString(req.mResponse));
|
||||
s.data(Tags.MREQ_COLLECTION_ID, Long.toString(msg.mMailboxKey));
|
||||
s.data(Tags.MREQ_REQ_ID, msg.mServerId);
|
||||
s.end().end().done();
|
||||
HttpResponse res = sendHttpClientPost("MeetingResponse", s.toByteArray());
|
||||
int status = res.getStatusLine().getStatusCode();
|
||||
if (status == HttpStatus.SC_OK) {
|
||||
HttpEntity e = res.getEntity();
|
||||
int len = (int)e.getContentLength();
|
||||
InputStream is = res.getEntity().getContent();
|
||||
if (len != 0) {
|
||||
new MeetingResponseParser(is, this).parse();
|
||||
}
|
||||
} else if (isAuthError(status)) {
|
||||
throw new EasAuthenticationException();
|
||||
} else {
|
||||
userLog("Meeting response request failed, code: " + status);
|
||||
throw new IOException();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private String makeUriString(String cmd, String extra) throws IOException {
|
||||
// Cache the authentication string and the command string
|
||||
@ -1323,18 +1355,29 @@ public class EasSyncService extends AbstractSyncService {
|
||||
return;
|
||||
}
|
||||
|
||||
// Now, handle various requests
|
||||
while (true) {
|
||||
PartRequest req = null;
|
||||
synchronized (mPartRequests) {
|
||||
if (mPartRequests.isEmpty()) {
|
||||
Request req = null;
|
||||
synchronized (mRequests) {
|
||||
if (mRequests.isEmpty()) {
|
||||
break;
|
||||
} else {
|
||||
req = mPartRequests.get(0);
|
||||
req = mRequests.get(0);
|
||||
}
|
||||
}
|
||||
getAttachment(req);
|
||||
synchronized(mPartRequests) {
|
||||
mPartRequests.remove(req);
|
||||
|
||||
// Our two request types are PartRequest (loading attachment) and
|
||||
// MeetingResponseRequest (respond to a meeting request)
|
||||
if (req instanceof PartRequest) {
|
||||
getAttachment((PartRequest)req);
|
||||
} else if (req instanceof MeetingResponseRequest) {
|
||||
sendMeetingResponse((MeetingResponseRequest)req);
|
||||
}
|
||||
|
||||
// If there's an exception handling the request, we'll throw it
|
||||
// Otherwise, we remove the request
|
||||
synchronized(mRequests) {
|
||||
mRequests.remove(req);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1465,6 +1508,9 @@ public class EasSyncService extends AbstractSyncService {
|
||||
sync(target);
|
||||
} while (mRequestTime != 0);
|
||||
}
|
||||
} catch (EasAuthenticationException e) {
|
||||
userLog("Caught authentication error");
|
||||
mExitStatus = EXIT_LOGIN_FAILURE;
|
||||
} catch (IOException e) {
|
||||
String message = e.getMessage();
|
||||
userLog("Caught IOException: ", (message == null) ? "No message" : message);
|
||||
|
23
src/com/android/exchange/EmailServiceConstants.java
Normal file
23
src/com/android/exchange/EmailServiceConstants.java
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.exchange;
|
||||
|
||||
public class EmailServiceConstants {
|
||||
public static final int MEETING_REQUEST_ACCEPTED = 1;
|
||||
public static final int MEETING_REQUEST_TENTATIVE = 2;
|
||||
public static final int MEETING_REQUEST_DECLINED = 3;
|
||||
}
|
@ -43,4 +43,6 @@ interface IEmailService {
|
||||
void hostChanged(long accountId);
|
||||
|
||||
Bundle autoDiscover(String userName, String password);
|
||||
|
||||
void sendMeetingResponse(long messageId, int response);
|
||||
}
|
29
src/com/android/exchange/MeetingResponseRequest.java
Normal file
29
src/com/android/exchange/MeetingResponseRequest.java
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.exchange;
|
||||
|
||||
/**
|
||||
* MeetingResponseRequest is the EAS wrapper for responding to meeting requests.
|
||||
*/
|
||||
public class MeetingResponseRequest extends Request {
|
||||
public int mResponse;
|
||||
|
||||
MeetingResponseRequest(long messageId, int response) {
|
||||
mMessageId = messageId;
|
||||
mResponse = response;
|
||||
}
|
||||
}
|
@ -24,24 +24,21 @@ import com.android.email.provider.EmailContent.Attachment;
|
||||
* the attachment to be loaded, it also contains the callback to be used for status/progress
|
||||
* updates to the UI.
|
||||
*/
|
||||
public class PartRequest {
|
||||
public long timeStamp;
|
||||
public long emailId;
|
||||
public Attachment att;
|
||||
public String destination;
|
||||
public String contentUriString;
|
||||
public String loc;
|
||||
public class PartRequest extends Request {
|
||||
public Attachment mAttachment;
|
||||
public String mDestination;
|
||||
public String mContentUriString;
|
||||
public String mLocation;
|
||||
|
||||
public PartRequest(Attachment _att) {
|
||||
timeStamp = System.currentTimeMillis();
|
||||
emailId = _att.mMessageKey;
|
||||
att = _att;
|
||||
loc = att.mLocation;
|
||||
mMessageId = _att.mMessageKey;
|
||||
mAttachment = _att;
|
||||
mLocation = mAttachment.mLocation;
|
||||
}
|
||||
|
||||
public PartRequest(Attachment _att, String _destination, String _contentUriString) {
|
||||
this(_att);
|
||||
destination = _destination;
|
||||
contentUriString = _contentUriString;
|
||||
mDestination = _destination;
|
||||
mContentUriString = _contentUriString;
|
||||
}
|
||||
}
|
||||
|
27
src/com/android/exchange/Request.java
Normal file
27
src/com/android/exchange/Request.java
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.exchange;
|
||||
|
||||
/**
|
||||
* Requests for mailbox actions are handled by subclasses of this abstract class.
|
||||
* Two subclasses are now defined: PartRequest (attachment load) and MeetingResponseRequest
|
||||
* (respond to a meeting invitation)
|
||||
*/
|
||||
public abstract class Request {
|
||||
public long mTimeStamp = System.currentTimeMillis();
|
||||
public long mMessageId;
|
||||
}
|
@ -312,7 +312,7 @@ public class SyncManager extends Service implements Runnable {
|
||||
public void loadAttachment(long attachmentId, String destinationFile,
|
||||
String contentUriString) throws RemoteException {
|
||||
Attachment att = Attachment.restoreAttachmentWithId(SyncManager.this, attachmentId);
|
||||
partRequest(new PartRequest(att, destinationFile, contentUriString));
|
||||
sendMessageRequest(new PartRequest(att, destinationFile, contentUriString));
|
||||
}
|
||||
|
||||
public void updateFolderList(long accountId) throws RemoteException {
|
||||
@ -348,8 +348,11 @@ public class SyncManager extends Service implements Runnable {
|
||||
Eas.setUserDebug(on);
|
||||
}
|
||||
|
||||
public void sendMeetingResponse(long messageId, int response) throws RemoteException {
|
||||
sendMessageRequest(new MeetingResponseRequest(messageId, response));
|
||||
}
|
||||
|
||||
public void loadMore(long messageId) throws RemoteException {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
// The following three methods are not implemented in this version
|
||||
@ -1338,7 +1341,7 @@ public class SyncManager extends Service implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
private void startService(Mailbox m, int reason, PartRequest req) {
|
||||
private void startService(Mailbox m, int reason, Request req) {
|
||||
// Don't sync if there's no connectivity
|
||||
if (sConnectivityHold) return;
|
||||
synchronized (sSyncToken) {
|
||||
@ -1351,7 +1354,7 @@ public class SyncManager extends Service implements Runnable {
|
||||
if (!((EasSyncService)service).mIsValid) return;
|
||||
service.mSyncReason = reason;
|
||||
if (req != null) {
|
||||
service.addPartRequest(req);
|
||||
service.addRequest(req);
|
||||
}
|
||||
startService(service, m);
|
||||
}
|
||||
@ -1726,9 +1729,9 @@ public class SyncManager extends Service implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
static public void partRequest(PartRequest req) {
|
||||
static public void sendMessageRequest(Request req) {
|
||||
if (INSTANCE == null) return;
|
||||
Message msg = Message.restoreMessageWithId(INSTANCE, req.emailId);
|
||||
Message msg = Message.restoreMessageWithId(INSTANCE, req.mMessageId);
|
||||
if (msg == null) {
|
||||
return;
|
||||
}
|
||||
@ -1739,33 +1742,7 @@ public class SyncManager extends Service implements Runnable {
|
||||
service = startManualSync(mailboxId, SYNC_SERVICE_PART_REQUEST, req);
|
||||
kick("part request");
|
||||
} else {
|
||||
service.addPartRequest(req);
|
||||
}
|
||||
}
|
||||
|
||||
static public PartRequest hasPartRequest(long emailId, String part) {
|
||||
if (INSTANCE == null) return null;
|
||||
Message msg = Message.restoreMessageWithId(INSTANCE, emailId);
|
||||
if (msg == null) {
|
||||
return null;
|
||||
}
|
||||
long mailboxId = msg.mMailboxKey;
|
||||
AbstractSyncService service = INSTANCE.mServiceMap.get(mailboxId);
|
||||
if (service != null) {
|
||||
return service.hasPartRequest(emailId, part);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static public void cancelPartRequest(long emailId, String part) {
|
||||
Message msg = Message.restoreMessageWithId(INSTANCE, emailId);
|
||||
if (msg == null) {
|
||||
return;
|
||||
}
|
||||
long mailboxId = msg.mMailboxKey;
|
||||
AbstractSyncService service = INSTANCE.mServiceMap.get(mailboxId);
|
||||
if (service != null) {
|
||||
service.cancelPartRequest(emailId, part);
|
||||
service.addRequest(req);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1793,7 +1770,7 @@ public class SyncManager extends Service implements Runnable {
|
||||
return PING_STATUS_OK;
|
||||
}
|
||||
|
||||
static public AbstractSyncService startManualSync(long mailboxId, int reason, PartRequest req) {
|
||||
static public AbstractSyncService startManualSync(long mailboxId, int reason, Request req) {
|
||||
if (INSTANCE == null || INSTANCE.mServiceMap == null) return null;
|
||||
synchronized (sSyncToken) {
|
||||
if (INSTANCE.mServiceMap.get(mailboxId) == null) {
|
||||
@ -1866,7 +1843,7 @@ public class SyncManager extends Service implements Runnable {
|
||||
int exitStatus = svc.mExitStatus;
|
||||
switch (exitStatus) {
|
||||
case AbstractSyncService.EXIT_DONE:
|
||||
if (!svc.mPartRequests.isEmpty()) {
|
||||
if (!svc.mRequests.isEmpty()) {
|
||||
// TODO Handle this case
|
||||
}
|
||||
errorMap.remove(mailboxId);
|
||||
|
@ -166,6 +166,14 @@ public class EmailSyncAdapter extends AbstractSyncAdapter {
|
||||
String text = getValue();
|
||||
msg.mText = text;
|
||||
break;
|
||||
case Tags.EMAIL_MESSAGE_CLASS:
|
||||
String messageClass = getValue();
|
||||
if (messageClass.equals("IPM.Schedule.Meeting.Request")) {
|
||||
msg.mFlags |= Message.FLAG_MEETING_INVITE;
|
||||
} else if (messageClass.equals("IPM.Schedule.Meeting.Canceled")) {
|
||||
msg.mFlags |= Message.FLAG_MEETING_CANCEL_NOTICE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
skipTag();
|
||||
}
|
||||
|
65
src/com/android/exchange/adapter/MeetingResponseParser.java
Normal file
65
src/com/android/exchange/adapter/MeetingResponseParser.java
Normal file
@ -0,0 +1,65 @@
|
||||
/* Copyright (C) 2010 The Android Open Source Project.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.exchange.adapter;
|
||||
|
||||
import com.android.exchange.EasSyncService;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* Parse the result of a MeetingRequest command.
|
||||
*/
|
||||
public class MeetingResponseParser extends Parser {
|
||||
private EasSyncService mService;
|
||||
|
||||
public MeetingResponseParser(InputStream in, EasSyncService service) throws IOException {
|
||||
super(in);
|
||||
mService = service;
|
||||
}
|
||||
|
||||
public void parseResult() throws IOException {
|
||||
while (nextTag(Tags.MREQ_RESULT) != END) {
|
||||
if (tag == Tags.MREQ_STATUS) {
|
||||
int status = getValueInt();
|
||||
if (status != 1) {
|
||||
mService.userLog("Error in meeting response: " + status);
|
||||
}
|
||||
} else if (tag == Tags.MREQ_CAL_ID) {
|
||||
mService.userLog("Meeting response calendar id: " + getValue());
|
||||
} else {
|
||||
skipTag();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean parse() throws IOException {
|
||||
boolean res = false;
|
||||
if (nextTag(START_DOCUMENT) != Tags.MREQ_MEETING_RESPONSE) {
|
||||
throw new IOException();
|
||||
}
|
||||
while (nextTag(START_DOCUMENT) != END_DOCUMENT) {
|
||||
if (tag == Tags.MREQ_RESULT) {
|
||||
parseResult();
|
||||
} else {
|
||||
skipTag();
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
@ -39,6 +39,7 @@ public class Tags {
|
||||
public static final int MOVE = 0x05;
|
||||
public static final int GIE = 0x06;
|
||||
public static final int FOLDER = 0x07;
|
||||
public static final int MREQ = 0x08;
|
||||
public static final int TASK = 0x09;
|
||||
public static final int CONTACTS2 = 0x0C;
|
||||
public static final int PING = 0x0D;
|
||||
@ -218,6 +219,17 @@ public class Tags {
|
||||
public static final int FOLDER_COUNT = FOLDER_PAGE + 0x17;
|
||||
public static final int FOLDER_VERSION = FOLDER_PAGE + 0x18;
|
||||
|
||||
public static final int MREQ_PAGE = MREQ << PAGE_SHIFT;
|
||||
public static final int MREQ_CAL_ID = MREQ_PAGE + 5;
|
||||
public static final int MREQ_COLLECTION_ID = MREQ_PAGE + 6;
|
||||
public static final int MREQ_MEETING_RESPONSE = MREQ_PAGE + 7;
|
||||
public static final int MREQ_REQ_ID = MREQ_PAGE + 8;
|
||||
public static final int MREQ_REQUEST = MREQ_PAGE + 9;
|
||||
public static final int MREQ_RESULT = MREQ_PAGE + 0xA;
|
||||
public static final int MREQ_STATUS = MREQ_PAGE + 0xB;
|
||||
public static final int MREQ_USER_RESPONSE = MREQ_PAGE + 0xC;
|
||||
public static final int MREQ_VERSION = MREQ_PAGE + 0xD;
|
||||
|
||||
public static final int EMAIL_PAGE = EMAIL << PAGE_SHIFT;
|
||||
public static final int EMAIL_ATTACHMENT = EMAIL_PAGE + 5;
|
||||
public static final int EMAIL_ATTACHMENTS = EMAIL_PAGE + 6;
|
||||
@ -441,6 +453,8 @@ public class Tags {
|
||||
},
|
||||
{
|
||||
// 0x08 MeetingResponse
|
||||
"CalId", "CollectionId", "MeetingResponse", "ReqId", "Request",
|
||||
"Result", "Status", "UserResponse", "Version"
|
||||
},
|
||||
{
|
||||
// 0x09 Tasks
|
||||
|
Loading…
Reference in New Issue
Block a user