package cn.edu.tsinghua.hpc.tmms.syncaction;
import SQLite.StringEncoder;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.provider.Telephony.Mms;
import android.provider.Telephony.Sms;
import android.provider.Telephony.Sms.Inbox;
import android.provider.Telephony.Sms.Sent;
import android.provider.Telephony.Threads;
import android.util.Log;
import cn.edu.tsinghua.hpc.google.tmms.MmsException;
import cn.edu.tsinghua.hpc.google.tmms.pdu.GenericPdu;
import cn.edu.tsinghua.hpc.google.tmms.pdu.PduParser;
import cn.edu.tsinghua.hpc.google.tmms.pdu.PduPersister;
import cn.edu.tsinghua.hpc.google.tmms.util.SqliteWrapper;
import cn.edu.tsinghua.hpc.syncbroker.MessageType;
import cn.edu.tsinghua.hpc.syncbroker.SMSRecord;
import cn.edu.tsinghua.hpc.tmms.service.BootReceiver;
import cn.edu.tsinghua.hpc.tmms.util.TTelephony.TMms;
import cn.edu.tsinghua.hpc.tmms.util.TTelephony.TMmsSms;
import cn.edu.tsinghua.hpc.tmms.util.TTelephony.TSms;
import cn.edu.tsinghua.hpc.tmms.util.TTelephony.TThreads;
public class MmsUtils {
public static void notifySyncService(Context ctx) {
Intent i = new Intent(ctx, BootReceiver.class);
i.setAction(BootReceiver.TSYNC_REQUEST);
ctx.sendBroadcast(i);
}
public static int setGuid(Context ctx, Uri uri, int guid) {
ContentValues values = new ContentValues();
values.put("guid", guid);
return ctx.getContentResolver().update(uri, values, null, null);
}
public static int markMessageOrThread(Context ctx, Uri uri, String syncState) {
ContentValues values = new ContentValues();
values.put("sync_state", syncState);
return ctx.getContentResolver().update(uri, values, null, null);
}
public static int markMessageSyncDirty(Context ctx, Uri uri, int dirty) {
// Mark the sync_dirty bits of the messages true
ContentValues values = new ContentValues();
values.put("sync_dirty", dirty);
return ctx.getContentResolver().update(uri, values, null, null);
}
// sync_state:
// 0 disabled
// 1 enabled
// 2 disable
// 3 enable
// 0 -> 3 (service) -> 1 -> 2 (service) -> 0
// | |
// 0 1
public static int enableMessageOrThreadSync(Context ctx, Uri uri,
boolean sync) {
ContentValues values = new ContentValues();
int state = isMessageSyncableInternal(ctx, uri);
Log.d("MmsUtils", "uri is " + uri.toString() + " state is " + state);
if (sync) {
if (state == SyncState.SYNC_DISABLED) {
values.put("sync_enable", SyncState.SYNC_ENABLE);
} else if (state == SyncState.SYNC_DISABLE) {
values.put("sync_enable", SyncState.SYNC_ENABLED);
} else {
return 0;
}
} else {
if (state == SyncState.SYNC_ENABLED) {
values.put("sync_enable", SyncState.SYNC_DISABLE);
} else if (state == SyncState.SYNC_ENABLE) {
values.put("sync_enable", SyncState.SYNC_DISABLED);
} else {
return 0;
}
}
return ctx.getContentResolver().update(uri, values, null, null);
}
public static int enableMessageOrThreadSyncInternal(Context ctx, Uri uri,
boolean sync) {
ContentValues values = new ContentValues();
if (sync) {
values.put("sync_enable", SyncState.SYNC_ENABLED);
} else {
values.put("sync_enable", SyncState.SYNC_DISABLED);
}
return ctx.getContentResolver().update(uri, values, null, null);
}
public static boolean isMessageSyncable(Context ctx, Uri uri) {
Cursor c = ctx.getContentResolver().query(uri,
new String[] { "sync_enable" }, null, null, null);
if (c != null && c.moveToFirst()) {
int state = c.getInt(c.getColumnIndex("sync_enable"));
return state == SyncState.SYNC_ENABLED
|| state == SyncState.SYNC_DISABLE;
}
return false;
}
public static int isMessageSyncableInternal(Context ctx, Uri uri) {
Cursor c = ctx.getContentResolver().query(uri,
new String[] { "sync_enable" }, null, null, null);
if (c != null && c.moveToFirst()) {
return c.getInt(c.getColumnIndex("sync_enable"));
}
return 0;
}
public static boolean hasThreadLockedMessages(Context ctx, long threadId) {
Uri uri = ContentUris.withAppendedId(TThreads.CONTENT_URI, threadId);
if (threadId == -1) {
uri = TThreads.CONTENT_URI;
}
Cursor c = ctx.getContentResolver().query(uri,
new String[] { "locked" }, "locked=1", null, null);
return c.getCount() != 0;
}
public static boolean isThreadSyncable(Context ctx, long threadId) {
Uri uri = ContentUris.withAppendedId(
Uri.withAppendedPath(TMmsSms.AUTHORITY_URI, "threads"),
//Uri.parse("content://mms-sms/threads/"),
threadId);
return isMessageSyncable(ctx, uri);
}
public static Uri insertOneMessageInto(Context ctx, SMSRecord s,
String syncState) {
Uri resultUri = null;
if (s == null)
return null;
if (s.getMtype() == MessageType.SMS) {
ContentValues values = new ContentValues();
switch (s.getType()) {
case RECEIVE:
values.put(Inbox.ADDRESS, s.getFrom());
values.put(Inbox.BODY, s.getBody());
values.put(Inbox.PROTOCOL, Integer.valueOf(0));
values.put(Inbox.REPLY_PATH_PRESENT, Integer.valueOf(0));
values.put(Inbox.READ, Integer.valueOf(1));
values.put(Inbox.DATE, s.getDate().getTime());
values.put("guid", s.getGuid());
values.put("sync_state", syncState);
resultUri = SqliteWrapper.insert(ctx, ctx.getContentResolver(),
TSms.TInbox.CONTENT_URI, values);
break;
case SEND:
values.put(Sent.ADDRESS, s.getTo());
values.put(Sent.BODY, s.getBody());
values.put(Sent.PROTOCOL, Integer.valueOf(0));
values.put(Sent.REPLY_PATH_PRESENT, Integer.valueOf(0));
values.put(Sent.READ, Integer.valueOf(1));
values.put(Sent.DATE, s.getDate().getTime());
values.put("guid", s.getGuid());
values.put("sync_state", syncState);
resultUri = SqliteWrapper.insert(ctx, ctx.getContentResolver(),
TSms.TSent.CONTENT_URI, values);
break;
default:
break;
}
} else if (s.getMtype() == MessageType.MMS) {
PduPersister p = PduPersister.getPduPersister(ctx);
GenericPdu pdu;
switch (s.getType()) {
case RECEIVE:
pdu = new PduParser(StringEncoder.decode(s.getPdu())).parse();
try {
resultUri = p.persist(pdu, TMms.TInbox.CONTENT_URI);
setGuid(ctx, resultUri, s.getGuid());
markMessageOrThread(ctx, resultUri, syncState);
} catch (MmsException e) {
}
break;
case SEND:
pdu = new PduParser(StringEncoder.decode(s.getPdu())).parse();
try {
resultUri = p.persist(pdu, TMms.TSent.CONTENT_URI);
setGuid(ctx, resultUri, s.getGuid());
markMessageOrThread(ctx, resultUri, syncState);
} catch (MmsException e) {
}
break;
}
}
if (resultUri != null) {
Cursor mCursor = ctx.getContentResolver().query(resultUri,
new String[] { Sms.THREAD_ID, Sms.DATE }, null, null,
Sms.DATE + " DESC");
if (mCursor != null && mCursor.moveToFirst()) {
int thread_id = mCursor.getInt(mCursor
.getColumnIndex(Sms.THREAD_ID));
long lastDate = mCursor.getLong(mCursor
.getColumnIndex(Sms.DATE));
Uri mThread = Uri.withAppendedPath(Uri.withAppendedPath(
TMmsSms.CONTENT_URI, "threads"), String
.valueOf(thread_id));
ContentValues threadValues = new ContentValues();
threadValues.put(Threads.DATE, lastDate);
//add by chenqiang
threadValues.put("sync_state", syncState);
ctx.getContentResolver().update(mThread, threadValues, null,
null);
mCursor.close();
}
}
return resultUri;
}
public static Uri inserRemoteThreadInto(Context ctx, SMSRecord s,
String syncState) {
Uri resultUri = null;
if (s == null)
return null;
if (s.getMtype() == MessageType.SMS) {
ContentValues values = new ContentValues();
switch (s.getType()) {
case RECEIVE:
values.put(Inbox.ADDRESS, s.getFrom());
values.put(Inbox.BODY, s.getBody());
values.put(Inbox.PROTOCOL, Integer.valueOf(0));
values.put(Inbox.REPLY_PATH_PRESENT, Integer.valueOf(0));
values.put(Inbox.READ, Integer.valueOf(1));
values.put(Inbox.DATE, s.getDate().getTime());
values.put("guid", s.getGuid());
values.put("sync_state", syncState);
resultUri = SqliteWrapper.insert(ctx, ctx.getContentResolver(),
TSms.TInbox.CONTENT_URI, values);
break;
case SEND:
values.put(Sent.ADDRESS, s.getTo());
values.put(Sent.BODY, s.getBody());
values.put(Sent.PROTOCOL, Integer.valueOf(0));
values.put(Sent.REPLY_PATH_PRESENT, Integer.valueOf(0));
values.put(Sent.READ, Integer.valueOf(1));
values.put(Sent.DATE, s.getDate().getTime());
values.put("guid", s.getGuid());
values.put("sync_state", syncState);
resultUri = SqliteWrapper.insert(ctx, ctx.getContentResolver(),
TSms.TSent.CONTENT_URI, values);
break;
default:
break;
}
} else if (s.getMtype() == MessageType.MMS) {
PduPersister p = PduPersister.getPduPersister(ctx);
GenericPdu pdu;
switch (s.getType()) {
case RECEIVE:
pdu = new PduParser(StringEncoder.decode(s.getPdu())).parse();
try {
resultUri = p.persist(pdu, TMms.TInbox.CONTENT_URI);
setGuid(ctx, resultUri, s.getGuid());
markMessageOrThread(ctx, resultUri, syncState);
} catch (MmsException e) {
}
break;
case SEND:
pdu = new PduParser(StringEncoder.decode(s.getPdu())).parse();
try {
resultUri = p.persist(pdu, TMms.TSent.CONTENT_URI);
setGuid(ctx, resultUri, s.getGuid());
markMessageOrThread(ctx, resultUri, syncState);
} catch (MmsException e) {
}
break;
}
}
if (resultUri != null) {
Cursor mCursor = ctx.getContentResolver().query(resultUri,
new String[] { Sms.THREAD_ID, Sms.DATE }, null, null,
Sms.DATE + " DESC");
if (mCursor != null && mCursor.moveToFirst()) {
int thread_id = mCursor.getInt(mCursor
.getColumnIndex(Sms.THREAD_ID));
long lastDate = mCursor.getLong(mCursor
.getColumnIndex(Sms.DATE));
Uri mThread = Uri.withAppendedPath(Uri.withAppendedPath(
TMmsSms.CONTENT_URI, "threads"), String
.valueOf(thread_id));
ContentValues threadValues = new ContentValues();
threadValues.put(Threads.DATE, lastDate);
threadValues.put("sync_state", syncState);
ctx.getContentResolver().update(mThread, threadValues, null,
null);
mCursor.close();
}
}
return resultUri;
}
public static Uri tempInsertOneThreadInto(Context ctx, SMSRecord s) {
Uri resultUri = null;
if (s == null)
return null;
if (s.getMtype() == MessageType.SMS) {
ContentValues values = new ContentValues();
switch (s.getType()) {
case RECEIVE:
values.put(Inbox.ADDRESS, s.getFrom());
values.put(Inbox.BODY, s.getBody());
values.put(Inbox.PROTOCOL, Integer.valueOf(0));
values.put(Inbox.REPLY_PATH_PRESENT, Integer.valueOf(0));
values.put(Inbox.READ, Integer.valueOf(1));
values.put(Inbox.DATE, s.getDate().getTime());
values.put("guid", s.getGuid());
values.put("sync_state", SyncState.SYNC_STATE_TMP);
resultUri = SqliteWrapper.insert(ctx, ctx.getContentResolver(),
TSms.TInbox.CONTENT_URI, values);
break;
case SEND:
values.put(Sent.ADDRESS, s.getTo());
values.put(Sent.BODY, s.getBody());
values.put(Sent.PROTOCOL, Integer.valueOf(0));
values.put(Sent.REPLY_PATH_PRESENT, Integer.valueOf(0));
values.put(Sent.READ, Integer.valueOf(1));
values.put(Sent.DATE, s.getDate().getTime());
values.put("guid", s.getGuid());
values.put("sync_state", SyncState.SYNC_STATE_TMP);
resultUri = SqliteWrapper.insert(ctx, ctx.getContentResolver(),
TSms.TSent.CONTENT_URI, values);
break;
default:
break;
}
} else if (s.getMtype() == MessageType.MMS) {
PduPersister p = PduPersister.getPduPersister(ctx);
GenericPdu pdu;
switch (s.getType()) {
case RECEIVE:
pdu = new PduParser(StringEncoder.decode(s.getPdu())).parse();
try {
resultUri = p.persist(pdu, TMms.TInbox.CONTENT_URI);
setGuid(ctx, resultUri, s.getGuid());
markMessageOrThread(ctx, resultUri,
SyncState.SYNC_STATE_TMP);
} catch (MmsException e) {
}
break;
case SEND:
pdu = new PduParser(StringEncoder.decode(s.getPdu())).parse();
try {
resultUri = p.persist(pdu, TMms.TSent.CONTENT_URI);
setGuid(ctx, resultUri, s.getGuid());
markMessageOrThread(ctx, resultUri,
SyncState.SYNC_STATE_TMP);
} catch (MmsException e) {
}
break;
}
}
if (resultUri != null) {
Cursor mCursor = ctx.getContentResolver().query(resultUri,
new String[] { Sms.THREAD_ID, Sms.DATE, Mms.THREAD_ID },
null, null, Sms.DATE + " DESC");
if (mCursor != null && mCursor.moveToFirst()) {
int thread_id = mCursor.getInt(mCursor
.getColumnIndex(Sms.THREAD_ID));
long lastDate = mCursor.getLong(mCursor
.getColumnIndex(Sms.DATE));
Uri mThread = Uri.withAppendedPath(Uri.withAppendedPath(
TMmsSms.CONTENT_URI, "threads"), String
.valueOf(thread_id));
ContentValues threadValues = new ContentValues();
threadValues.put(Threads.DATE, lastDate);
ctx.getContentResolver().update(mThread, threadValues, null,
null);
resultUri = mThread;
mCursor.close();
}
}
return resultUri;
}
}