@Override public void deleteMessage(int aMessageId, int aRequestId) { class DeleteMessageRunnable implements Runnable { private int mMessageId; private int mRequestId; DeleteMessageRunnable(int aMessageId, int aRequestId) { mMessageId = aMessageId; mRequestId = aRequestId; } @Override public void run() { try { ContentResolver cr = GeckoAppShell.getContext().getContentResolver(); Uri message = ContentUris.withAppendedId(kSmsContentUri, mMessageId); int count = cr.delete(message, null, null); if (count > 1) { throw new TooManyResultsException(); } notifySmsDeleted(count == 1, mRequestId); } catch (TooManyResultsException e) { Log.e("GeckoSmsManager", "Delete more than one message?", e); notifySmsDeleteFailed(kUnknownError, mRequestId); } catch (Exception e) { Log.e("GeckoSmsManager", "Error while trying to delete a message", e); notifySmsDeleteFailed(kUnknownError, mRequestId); } } } if (!SmsIOThread.getInstance().execute(new DeleteMessageRunnable(aMessageId, aRequestId))) { Log.e("GeckoSmsManager", "Failed to add GetMessageRunnable to the SmsIOThread"); notifySmsDeleteFailed(kUnknownError, aRequestId); } }
@Override public void shutdown() { SmsIOThread.getInstance().interrupt(); MessagesListManager.getInstance().clear(); }
@Override public void getNextMessageInList(int aListId, int aRequestId) { class GetNextMessageInListRunnable implements Runnable { private int mListId; private int mRequestId; GetNextMessageInListRunnable(int aListId, int aRequestId) { mListId = aListId; mRequestId = aRequestId; } @Override public void run() { try { Cursor cursor = MessagesListManager.getInstance().get(mListId); if (!cursor.moveToNext()) { MessagesListManager.getInstance().remove(mListId); notifyNoMessageInList(mRequestId); return; } int type = cursor.getInt(cursor.getColumnIndex("type")); int deliveryStatus; String sender = ""; String receiver = ""; if (type == kSmsTypeInbox) { deliveryStatus = kDeliveryStatusSuccess; sender = cursor.getString(cursor.getColumnIndex("address")); } else if (type == kSmsTypeSentbox) { deliveryStatus = getGeckoDeliveryStatus(cursor.getInt(cursor.getColumnIndex("status"))); receiver = cursor.getString(cursor.getColumnIndex("address")); } else { throw new UnexpectedDeliveryStateException(); } int listId = MessagesListManager.getInstance().add(cursor); notifyGotNextMessage( cursor.getInt(cursor.getColumnIndex("_id")), deliveryStatus, receiver, sender, cursor.getString(cursor.getColumnIndex("body")), cursor.getLong(cursor.getColumnIndex("date")), mRequestId); } catch (UnexpectedDeliveryStateException e) { Log.e("GeckoSmsManager", "Unexcepted delivery state type", e); notifyReadingMessageListFailed(kUnknownError, mRequestId); } catch (Exception e) { Log.e("GeckoSmsManager", "Error while trying to get the next message of a list", e); notifyReadingMessageListFailed(kUnknownError, mRequestId); } } } if (!SmsIOThread.getInstance().execute(new GetNextMessageInListRunnable(aListId, aRequestId))) { Log.e("GeckoSmsManager", "Failed to add GetNextMessageInListRunnable to the SmsIOThread"); notifyReadingMessageListFailed(kUnknownError, aRequestId); } }
@Override public void createMessageList( long aStartDate, long aEndDate, String[] aNumbers, int aNumbersCount, int aDeliveryState, boolean aReverse, int aRequestId) { class CreateMessageListRunnable implements Runnable { private long mStartDate; private long mEndDate; private String[] mNumbers; private int mNumbersCount; private int mDeliveryState; private boolean mReverse; private int mRequestId; CreateMessageListRunnable( long aStartDate, long aEndDate, String[] aNumbers, int aNumbersCount, int aDeliveryState, boolean aReverse, int aRequestId) { mStartDate = aStartDate; mEndDate = aEndDate; mNumbers = aNumbers; mNumbersCount = aNumbersCount; mDeliveryState = aDeliveryState; mReverse = aReverse; mRequestId = aRequestId; } @Override public void run() { Cursor cursor = null; boolean closeCursor = true; try { // TODO: should use the |selectionArgs| argument in |ContentResolver.query()|. ArrayList<String> restrictions = new ArrayList<String>(); if (mStartDate != 0) { restrictions.add("date >= " + mStartDate); } if (mEndDate != 0) { restrictions.add("date <= " + mEndDate); } if (mNumbersCount > 0) { String numberRestriction = "address IN ('" + mNumbers[0] + "'"; for (int i = 1; i < mNumbersCount; ++i) { numberRestriction += ", '" + mNumbers[i] + "'"; } numberRestriction += ")"; restrictions.add(numberRestriction); } if (mDeliveryState == kDeliveryStateUnknown) { restrictions.add("type IN ('" + kSmsTypeSentbox + "', '" + kSmsTypeInbox + "')"); } else if (mDeliveryState == kDeliveryStateSent) { restrictions.add("type = " + kSmsTypeSentbox); } else if (mDeliveryState == kDeliveryStateReceived) { restrictions.add("type = " + kSmsTypeInbox); } else { throw new UnexpectedDeliveryStateException(); } String restrictionText = restrictions.size() > 0 ? restrictions.get(0) : ""; for (int i = 1; i < restrictions.size(); ++i) { restrictionText += " AND " + restrictions.get(i); } ContentResolver cr = GeckoAppShell.getContext().getContentResolver(); cursor = cr.query( kSmsContentUri, kRequiredMessageRows, restrictionText, null, mReverse ? "date DESC" : "date ASC"); if (cursor.getCount() == 0) { notifyNoMessageInList(mRequestId); return; } cursor.moveToFirst(); int type = cursor.getInt(cursor.getColumnIndex("type")); int deliveryStatus; String sender = ""; String receiver = ""; if (type == kSmsTypeInbox) { deliveryStatus = kDeliveryStatusSuccess; sender = cursor.getString(cursor.getColumnIndex("address")); } else if (type == kSmsTypeSentbox) { deliveryStatus = getGeckoDeliveryStatus(cursor.getInt(cursor.getColumnIndex("status"))); receiver = cursor.getString(cursor.getColumnIndex("address")); } else { throw new UnexpectedDeliveryStateException(); } int listId = MessagesListManager.getInstance().add(cursor); closeCursor = false; notifyListCreated( listId, cursor.getInt(cursor.getColumnIndex("_id")), deliveryStatus, receiver, sender, cursor.getString(cursor.getColumnIndex("body")), cursor.getLong(cursor.getColumnIndex("date")), mRequestId); } catch (UnexpectedDeliveryStateException e) { Log.e("GeckoSmsManager", "Unexcepted delivery state type", e); notifyReadingMessageListFailed(kUnknownError, mRequestId); } catch (Exception e) { Log.e("GeckoSmsManager", "Error while trying to create a message list cursor", e); notifyReadingMessageListFailed(kUnknownError, mRequestId); } finally { // Close the cursor if MessagesListManager isn't taking care of it. // We could also just check if it is in the MessagesListManager list but // that would be less efficient. if (cursor != null && closeCursor) { cursor.close(); } } } } if (!SmsIOThread.getInstance() .execute( new CreateMessageListRunnable( aStartDate, aEndDate, aNumbers, aNumbersCount, aDeliveryState, aReverse, aRequestId))) { Log.e("GeckoSmsManager", "Failed to add CreateMessageListRunnable to the SmsIOThread"); notifyReadingMessageListFailed(kUnknownError, aRequestId); } }
@Override public void getMessage(int aMessageId, int aRequestId) { class GetMessageRunnable implements Runnable { private int mMessageId; private int mRequestId; GetMessageRunnable(int aMessageId, int aRequestId) { mMessageId = aMessageId; mRequestId = aRequestId; } @Override public void run() { Cursor cursor = null; try { ContentResolver cr = GeckoAppShell.getContext().getContentResolver(); Uri message = ContentUris.withAppendedId(kSmsContentUri, mMessageId); cursor = cr.query(message, kRequiredMessageRows, null, null, null); if (cursor == null || cursor.getCount() == 0) { throw new NotFoundException(); } if (cursor.getCount() != 1) { throw new TooManyResultsException(); } cursor.moveToFirst(); if (cursor.getInt(cursor.getColumnIndex("_id")) != mMessageId) { throw new UnmatchingIdException(); } int type = cursor.getInt(cursor.getColumnIndex("type")); int deliveryStatus; String sender = ""; String receiver = ""; if (type == kSmsTypeInbox) { deliveryStatus = kDeliveryStatusSuccess; sender = cursor.getString(cursor.getColumnIndex("address")); } else if (type == kSmsTypeSentbox) { deliveryStatus = getGeckoDeliveryStatus(cursor.getInt(cursor.getColumnIndex("status"))); receiver = cursor.getString(cursor.getColumnIndex("address")); } else { throw new InvalidTypeException(); } notifyGetSms( cursor.getInt(cursor.getColumnIndex("_id")), deliveryStatus, receiver, sender, cursor.getString(cursor.getColumnIndex("body")), cursor.getLong(cursor.getColumnIndex("date")), mRequestId); } catch (NotFoundException e) { Log.i("GeckoSmsManager", "Message id " + mMessageId + " not found"); notifyGetSmsFailed(kNotFoundError, mRequestId); } catch (UnmatchingIdException e) { Log.e( "GeckoSmsManager", "Requested message id (" + mMessageId + ") is different from the one we got."); notifyGetSmsFailed(kUnknownError, mRequestId); } catch (TooManyResultsException e) { Log.e("GeckoSmsManager", "Get too many results for id " + mMessageId); notifyGetSmsFailed(kUnknownError, mRequestId); } catch (InvalidTypeException e) { Log.i("GeckoSmsManager", "Message has an invalid type, we ignore it."); notifyGetSmsFailed(kNotFoundError, mRequestId); } catch (Exception e) { Log.e("GeckoSmsManager", "Error while trying to get message", e); notifyGetSmsFailed(kUnknownError, mRequestId); } finally { if (cursor != null) { cursor.close(); } } } } if (!SmsIOThread.getInstance().execute(new GetMessageRunnable(aMessageId, aRequestId))) { Log.e("GeckoSmsManager", "Failed to add GetMessageRunnable to the SmsIOThread"); notifyGetSmsFailed(kUnknownError, aRequestId); } }
public GeckoSmsManager() { SmsIOThread.getInstance().start(); }