/** * Query the DB and return the number of undelivered messages (total for both SMS and MMS) * * @param context The context * @param threadIdResult A container to put the result in, according to the following rules: * threadIdResult[0] contains the thread id of the first message. threadIdResult[1] is nonzero * if the thread ids of all the messages are the same. You can pass in null for * threadIdResult. You can pass in a threadIdResult of size 1 to avoid the comparison of each * thread id. */ private static int getUndeliveredMessageCount(Context context, long[] threadIdResult) { Cursor undeliveredCursor = SqliteWrapper.query( context, context.getContentResolver(), UNDELIVERED_URI, new String[] {Mms.THREAD_ID}, "read=0", null, null); if (undeliveredCursor == null) { return 0; } int count = undeliveredCursor.getCount(); try { if (threadIdResult != null && undeliveredCursor.moveToFirst()) { threadIdResult[0] = undeliveredCursor.getLong(0); if (threadIdResult.length >= 2) { // Test to see if all the undelivered messages belong to the same thread. long firstId = threadIdResult[0]; while (undeliveredCursor.moveToNext()) { if (undeliveredCursor.getLong(0) != firstId) { firstId = 0; break; } } threadIdResult[1] = firstId; // non-zero if all ids are the same } } } finally { undeliveredCursor.close(); } return count; }
private static boolean isDuplicateNotification(Context context, NotificationInd nInd) { final byte[] rawLocation = nInd.getContentLocation(); if (rawLocation != null) { String location = new String(rawLocation); String[] selectionArgs = new String[] {location}; Cursor cursor = null; try { cursor = SqliteWrapper.query( context, context.getContentResolver(), Telephony.Mms.CONTENT_URI, new String[] {Telephony.Mms._ID}, LOCATION_SELECTION, new String[] { Integer.toString(PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND), new String(rawLocation) }, null /*sortOrder*/); if (cursor != null && cursor.getCount() > 0) { // We already received the same notification before. return true; } } catch (SQLiteException e) { Rlog.e(TAG, "failed to query existing notification ind", e); } finally { if (cursor != null) { cursor.close(); } } } return false; }
private static boolean isDuplicateNotification(Context context, NotificationInd nInd) { byte[] rawLocation = nInd.getContentLocation(); if (rawLocation != null) { String location = new String(rawLocation); String selection = Mms.CONTENT_LOCATION + " = ?"; String[] selectionArgs = new String[] {location}; Cursor cursor = SqliteWrapper.query( context, context.getContentResolver(), Mms.CONTENT_URI, new String[] {Mms._ID}, selection, selectionArgs, null); if (cursor != null) { try { if (cursor.getCount() > 0) { cursor.moveToFirst(); Xlog.d(MmsApp.TXN_TAG, "duplicate, location=" + location + ", id=" + cursor.getLong(0)); // We already received the same notification before. return true; } } finally { cursor.close(); } } } return false; }
private static final MmsSmsDeliveryInfo getSmsNewDeliveryInfo(Context context) { ContentResolver resolver = context.getContentResolver(); Cursor cursor = SqliteWrapper.query( context, resolver, Sms.CONTENT_URI, SMS_STATUS_PROJECTION, NEW_DELIVERY_SM_CONSTRAINT, null, Sms.DATE); if (cursor == null) return null; try { if (!cursor.moveToLast()) return null; String address = cursor.getString(COLUMN_SMS_ADDRESS); long timeMillis = 3000; return new MmsSmsDeliveryInfo( String.format(context.getString(R.string.delivery_toast_body), address), timeMillis); } finally { cursor.close(); } }
private static int getDownloadFailedMessageCount(Context context) { // Look for any messages in the MMS Inbox that are of the type // NOTIFICATION_IND (i.e. not already downloaded) and in the // permanent failure state. If there are none, cancel any // failed download notification. Cursor c = SqliteWrapper.query( context, context.getContentResolver(), Mms.Inbox.CONTENT_URI, null, Mms.MESSAGE_TYPE + "=" + String.valueOf(PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND) + " AND " + Mms.STATUS + "=" + String.valueOf(DownloadManager.STATE_PERMANENT_FAILURE), null, null); if (c == null) { return 0; } int count = c.getCount(); c.close(); return count; }
private static final MmsSmsNotificationInfo getSmsNewMessageNotificationInfo( Context context, Set<Long> threads) { ContentResolver resolver = context.getContentResolver(); Cursor cursor = SqliteWrapper.query( context, resolver, Sms.CONTENT_URI, SMS_STATUS_PROJECTION, NEW_INCOMING_SM_CONSTRAINT, null, Sms.DATE + " desc"); if (cursor == null) { return null; } try { if (!cursor.moveToFirst()) { return null; } String address = cursor.getString(COLUMN_SMS_ADDRESS); String body = cursor.getString(COLUMN_SMS_BODY); long threadId = cursor.getLong(COLUMN_THREAD_ID); long timeMillis = cursor.getLong(COLUMN_DATE); if (Log.isLoggable(LogTag.APP, Log.VERBOSE)) { Log.d( TAG, "getSmsNewMessageNotificationInfo: count=" + cursor.getCount() + ", first addr=" + address + ", thread_id=" + threadId); } MmsSmsNotificationInfo info = getNewMessageNotificationInfo( address, body, context, R.drawable.stat_notify_sms, null, threadId, timeMillis, cursor.getCount()); threads.add(threadId); while (cursor.moveToNext()) { threads.add(cursor.getLong(COLUMN_THREAD_ID)); } return info; } finally { cursor.close(); } }
/** * This method is used if this is a "replace short message" SMS. We find any existing message that * matches the incoming message's originating address and protocol identifier. If there is one, we * replace its fields with those of the new message. Otherwise, we store the new message as usual. * * <p>See TS 23.040 9.2.3.9. */ private Uri replaceMessage(Context context, SmsMessage[] msgs, int error) { SmsMessage sms = msgs[0]; ContentValues values = extractContentValues(sms); values.put(Sms.ERROR_CODE, error); int pduCount = msgs.length; if (pduCount == 1) { // There is only one part, so grab the body directly. values.put(Inbox.BODY, replaceFormFeeds(sms.getDisplayMessageBody())); } else { // Build up the body from the parts. StringBuilder body = new StringBuilder(); for (int i = 0; i < pduCount; i++) { sms = msgs[i]; if (sms.mWrappedSmsMessage != null) { body.append(sms.getDisplayMessageBody()); } } values.put(Inbox.BODY, replaceFormFeeds(body.toString())); } ContentResolver resolver = context.getContentResolver(); String originatingAddress = sms.getOriginatingAddress(); int protocolIdentifier = sms.getProtocolIdentifier(); String selection = Sms.ADDRESS + " = ? AND " + Sms.PROTOCOL + " = ?"; String[] selectionArgs = new String[] {originatingAddress, Integer.toString(protocolIdentifier)}; Cursor cursor = SqliteWrapper.query( context, resolver, Inbox.CONTENT_URI, REPLACE_PROJECTION, selection, selectionArgs, null); if (cursor != null) { try { if (cursor.moveToFirst()) { long messageId = cursor.getLong(REPLACE_COLUMN_ID); Uri messageUri = ContentUris.withAppendedId(Sms.CONTENT_URI, messageId); SqliteWrapper.update(context, resolver, messageUri, values, null, null); return messageUri; } } finally { cursor.close(); } } return storeMessage(context, msgs, error); }
/// M:Code analyze 011,add for setting the mms being downloading when shutdown to unrecognized /// after boot complete again,have to manual download @{ public static void setNotificationIndUnstarted(final Context context) { MmsLog.d(MmsApp.TXN_TAG, "setNotificationIndUnstarted"); Cursor cursor = SqliteWrapper.query( context, context.getContentResolver(), Mms.CONTENT_URI, new String[] {Mms._ID, Mms.STATUS}, Mms.MESSAGE_TYPE + "=" + PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND, null, null); if (cursor != null) { try { int count = cursor.getCount(); MmsLog.d(MmsApp.TXN_TAG, "setNotificationIndUnstarted: Message Size=" + count); if (count == 0) { return; } ContentValues values = null; int id = 0; int status = 0; while (cursor.moveToNext()) { id = cursor.getInt(0); status = cursor.getInt(1); MmsLog.d( MmsApp.TXN_TAG, "setNotificationIndUnstarted: MsgId=" + id + "; status=" + status); if (DownloadManager.STATE_DOWNLOADING == (status & ~DownloadManager.DEFERRED_MASK)) { values = new ContentValues(1); values.put(Mms.STATUS, PduHeaders.STATUS_UNRECOGNIZED); SqliteWrapper.update( context, context.getContentResolver(), Mms.CONTENT_URI, values, Mms._ID + "=" + id, null); } } } catch (SQLiteDiskIOException e) { // Ignore MmsLog.e( MmsApp.TXN_TAG, "SQLiteDiskIOException caught while set notification ind unstart", e); } finally { cursor.close(); } } else { MmsLog.d(MmsApp.TXN_TAG, "setNotificationIndUnstarted: no pending messages."); } }
public static void setPendingSmsFailed(final Context context) { Xlog.d(MmsApp.TXN_TAG, "setPendingSmsFailed"); Cursor cursor = SqliteWrapper.query( context, context.getContentResolver(), Sms.CONTENT_URI, new String[] {Sms._ID}, Sms.TYPE + "=" + Sms.MESSAGE_TYPE_OUTBOX + " OR " + Sms.TYPE + "=" + Sms.MESSAGE_TYPE_QUEUED, null, null); if (cursor != null) { try { int count = cursor.getCount(); Xlog.d(MmsApp.TXN_TAG, "setPendingSmsFailed: Message Size=" + count); if (count == 0) { return; } ContentValues values = null; int id = 0; while (cursor.moveToNext()) { id = cursor.getInt(0); Xlog.d(MmsApp.TXN_TAG, "setPendingSmsFailed: MsgId=" + id); values = new ContentValues(1); values.put(Sms.TYPE, Sms.MESSAGE_TYPE_FAILED); SqliteWrapper.update( context, context.getContentResolver(), Sms.CONTENT_URI, values, Sms._ID + "=" + id, null); } } catch (SQLiteDiskIOException e) { Xlog.e(MmsApp.TXN_TAG, "SQLiteDiskIOException caught while set sms failed", e); } finally { cursor.close(); } } else { Xlog.d(MmsApp.TXN_TAG, "setPendingSmsFailed: no pending messages."); } }
private static long findThreadId(Context context, GenericPdu pdu, int type) { String messageId; if (type == MESSAGE_TYPE_DELIVERY_IND) { messageId = new String(((DeliveryInd) pdu).getMessageId()); } else { messageId = new String(((ReadOrigInd) pdu).getMessageId()); } StringBuilder sb = new StringBuilder('('); sb.append(Mms.MESSAGE_ID); sb.append('='); sb.append(DatabaseUtils.sqlEscapeString(messageId)); sb.append(" AND "); sb.append(Mms.MESSAGE_TYPE); sb.append('='); sb.append(PduHeaders.MESSAGE_TYPE_SEND_REQ); // TODO ContentResolver.query() appends closing ')' to the selection argument // sb.append(')'); Cursor cursor = SqliteWrapper.query( context, context.getContentResolver(), Mms.CONTENT_URI, new String[] {Mms.THREAD_ID}, sb.toString(), null, null); if (cursor != null) { try { if ((cursor.getCount() == 1) && cursor.moveToFirst()) { return cursor.getLong(0); } } finally { cursor.close(); } } return -1; }
private static long getDeliveryOrReadReportThreadId(Context context, GenericPdu pdu) { String messageId; if (pdu instanceof DeliveryInd) { messageId = new String(((DeliveryInd) pdu).getMessageId()); } else if (pdu instanceof ReadOrigInd) { messageId = new String(((ReadOrigInd) pdu).getMessageId()); } else { Rlog.e( TAG, "WAP Push data is neither delivery or read report type: " + pdu.getClass().getCanonicalName()); return -1L; } Cursor cursor = null; try { cursor = SqliteWrapper.query( context, context.getContentResolver(), Telephony.Mms.CONTENT_URI, new String[] {Telephony.Mms.THREAD_ID}, THREAD_ID_SELECTION, new String[] { DatabaseUtils.sqlEscapeString(messageId), Integer.toString(PduHeaders.MESSAGE_TYPE_SEND_REQ) }, null /*sortOrder*/); if (cursor != null && cursor.moveToFirst()) { return cursor.getLong(0); } } catch (SQLiteException e) { Rlog.e(TAG, "Failed to query delivery or read report thread id", e); } finally { if (cursor != null) { cursor.close(); } } return -1L; }
private static final MmsSmsNotificationInfo getMmsNewMessageNotificationInfo( Context context, Set<Long> threads) { ContentResolver resolver = context.getContentResolver(); // This query looks like this when logged: // I/Database( 147): elapsedTime4Sql|/data/data/com.android.providers.telephony/databases/ // mmssms.db|0.362 ms|SELECT thread_id, date, _id, sub, sub_cs FROM pdu WHERE ((msg_box=1 // AND seen=0 AND (m_type=130 OR m_type=132))) ORDER BY date desc Cursor cursor = SqliteWrapper.query( context, resolver, Mms.CONTENT_URI, MMS_STATUS_PROJECTION, NEW_INCOMING_MM_CONSTRAINT, null, Mms.DATE + " desc"); if (cursor == null) { return null; } try { if (!cursor.moveToFirst()) { return null; } long msgId = cursor.getLong(COLUMN_MMS_ID); Uri msgUri = Mms.CONTENT_URI.buildUpon().appendPath(Long.toString(msgId)).build(); String address = AddressUtils.getFrom(context, msgUri); String subject = getMmsSubject(cursor.getString(COLUMN_SUBJECT), cursor.getInt(COLUMN_SUBJECT_CS)); long threadId = cursor.getLong(COLUMN_THREAD_ID); long timeMillis = cursor.getLong(COLUMN_DATE) * 1000; if (Log.isLoggable(LogTag.APP, Log.VERBOSE)) { Log.d( TAG, "getMmsNewMessageNotificationInfo: count=" + cursor.getCount() + ", first addr = " + address + ", thread_id=" + threadId); } MmsSmsNotificationInfo info = getNewMessageNotificationInfo( address, subject, context, R.drawable.stat_notify_mms, null, threadId, timeMillis, cursor.getCount()); threads.add(threadId); while (cursor.moveToNext()) { threads.add(cursor.getLong(COLUMN_THREAD_ID)); } return info; } finally { cursor.close(); } }
/** * Constructor that uses the default settings of the MMS Client. * * @param context The context of the MMS Client */ public TransactionSettings(Context context, String apnName) { if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { Log.v(TAG, "TransactionSettings: apnName: " + apnName); } String selection = Telephony.Carriers.CURRENT + " IS NOT NULL"; String[] selectionArgs = null; if (!TextUtils.isEmpty(apnName)) { selection += " AND " + Telephony.Carriers.APN + "=?"; selectionArgs = new String[] {apnName.trim()}; } Cursor cursor = SqliteWrapper.query( context, context.getContentResolver(), Telephony.Carriers.CONTENT_URI, APN_PROJECTION, selection, selectionArgs, null); if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { Log.v( TAG, "TransactionSettings looking for apn: " + selection + " returned: " + (cursor == null ? "null cursor" : (cursor.getCount() + " hits"))); } if (cursor == null) { Log.e(TAG, "Apn is not found in Database!"); return; } boolean sawValidApn = false; try { while (cursor.moveToNext() && TextUtils.isEmpty(mServiceCenter)) { // Read values from APN settings if (isValidApnType(cursor.getString(COLUMN_TYPE), PhoneConstants.APN_TYPE_MMS)) { sawValidApn = true; String mmsc = cursor.getString(COLUMN_MMSC); if (mmsc == null) { continue; } mServiceCenter = NetworkUtils.trimV4AddrZeros(mmsc.trim()); mProxyAddress = NetworkUtils.trimV4AddrZeros(cursor.getString(COLUMN_MMSPROXY)); if (isProxySet()) { String portString = cursor.getString(COLUMN_MMSPORT); try { mProxyPort = Integer.parseInt(portString); } catch (NumberFormatException e) { if (TextUtils.isEmpty(portString)) { Log.w(TAG, "mms port not set!"); } else { Log.e(TAG, "Bad port number format: " + portString, e); } } } } } } finally { cursor.close(); } Log.v(TAG, "APN setting: MMSC: " + mServiceCenter + " looked for: " + selection); if (sawValidApn && TextUtils.isEmpty(mServiceCenter)) { Log.e(TAG, "Invalid APN setting: MMSC is empty"); } }
public static void handleReadReport( final Context context, final Collection<Long> threadIds, final int status, final Runnable callback) { StringBuilder selectionBuilder = new StringBuilder( Mms.MESSAGE_TYPE + " = " + PduHeaders.MESSAGE_TYPE_RETRIEVE_CONF + " AND " + Mms.READ + " = 0" + " AND " + Mms.READ_REPORT + " = " + PduHeaders.VALUE_YES); String[] selectionArgs = null; if (threadIds != null) { String threadIdSelection = null; StringBuilder buf = new StringBuilder(); selectionArgs = new String[threadIds.size()]; int i = 0; for (long threadId : threadIds) { if (i > 0) { buf.append(" OR "); } buf.append(Mms.THREAD_ID).append("=?"); selectionArgs[i++] = Long.toString(threadId); } threadIdSelection = buf.toString(); selectionBuilder.append(" AND (" + threadIdSelection + ")"); } final Cursor c = SqliteWrapper.query( context, context.getContentResolver(), Mms.Inbox.CONTENT_URI, new String[] {Mms._ID, Mms.MESSAGE_ID}, selectionBuilder.toString(), selectionArgs, null); if (c == null) { return; } final Map<String, String> map = new HashMap<String, String>(); try { if (c.getCount() == 0) { if (callback != null) { callback.run(); } return; } while (c.moveToNext()) { Uri uri = ContentUris.withAppendedId(Mms.CONTENT_URI, c.getLong(0)); map.put(c.getString(1), AddressUtils.getFrom(context, uri)); } } finally { c.close(); } OnClickListener positiveListener = new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { for (final Map.Entry<String, String> entry : map.entrySet()) { MmsMessageSender.sendReadRec(context, entry.getValue(), entry.getKey(), status); } if (callback != null) { callback.run(); } dialog.dismiss(); } }; OnClickListener negativeListener = new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { if (callback != null) { callback.run(); } dialog.dismiss(); } }; OnCancelListener cancelListener = new OnCancelListener() { @Override public void onCancel(DialogInterface dialog) { if (callback != null) { callback.run(); } dialog.dismiss(); } }; confirmReadReportDialog(context, positiveListener, negativeListener, cancelListener); }
/** * Load APN settings from system * * @param context * @param apnName the optional APN name to match */ public static ApnSettings load(Context context, String apnName, int subId) throws ApnException { if (Log.isLoggable(TAG, Log.VERBOSE)) { Log.v(TAG, "ApnSettings: apnName " + apnName); } // TODO: CURRENT semantics is currently broken in telephony. Revive this when it is fixed. // String selection = Telephony.Carriers.CURRENT + " IS NOT NULL"; String selection = null; String[] selectionArgs = null; apnName = apnName != null ? apnName.trim() : null; if (!TextUtils.isEmpty(apnName)) { // selection += " AND " + Telephony.Carriers.APN + "=?"; selection = Telephony.Carriers.APN + "=?"; selectionArgs = new String[] {apnName}; } Cursor cursor = null; try { cursor = SqliteWrapper.query( context, context.getContentResolver(), Uri.withAppendedPath(Telephony.Carriers.CONTENT_URI, "/subId/" + subId), APN_PROJECTION, selection, selectionArgs, null /*sortOrder*/); if (cursor != null) { String mmscUrl = null; String proxyAddress = null; int proxyPort = -1; while (cursor.moveToNext()) { // Read values from APN settings if (isValidApnType(cursor.getString(COLUMN_TYPE), PhoneConstants.APN_TYPE_MMS)) { mmscUrl = trimWithNullCheck(cursor.getString(COLUMN_MMSC)); if (TextUtils.isEmpty(mmscUrl)) { continue; } mmscUrl = NetworkUtils.trimV4AddrZeros(mmscUrl); try { new URI(mmscUrl); } catch (URISyntaxException e) { throw new ApnException("Invalid MMSC url " + mmscUrl); } proxyAddress = trimWithNullCheck(cursor.getString(COLUMN_MMSPROXY)); if (!TextUtils.isEmpty(proxyAddress)) { proxyAddress = NetworkUtils.trimV4AddrZeros(proxyAddress); final String portString = trimWithNullCheck(cursor.getString(COLUMN_MMSPORT)); if (portString != null) { try { proxyPort = Integer.parseInt(portString); } catch (NumberFormatException e) { Log.e(TAG, "Invalid port " + portString); throw new ApnException("Invalid port " + portString); } } } return new ApnSettings(mmscUrl, proxyAddress, proxyPort, getDebugText(cursor)); } } } } finally { if (cursor != null) { cursor.close(); } } throw new ApnException("Can not find valid APN"); }
/** Does the actual work of rebuilding the draft cache. */ private synchronized void rebuildCache() { if (Log.isLoggable(LogTag.APP, Log.DEBUG)) { log("rebuildCache"); } HashSet<Long> oldDraftSet = mDraftSet; HashSet<Long> newDraftSet = new HashSet<Long>(oldDraftSet.size()); Cursor cursor = SqliteWrapper.query( mContext, mContext.getContentResolver(), MmsSms.CONTENT_DRAFT_URI, DRAFT_PROJECTION, null, null, null); if (cursor != null) { try { if (cursor.moveToFirst()) { for (; !cursor.isAfterLast(); cursor.moveToNext()) { long threadId = cursor.getLong(COLUMN_DRAFT_THREAD_ID); newDraftSet.add(threadId); if (Log.isLoggable(LogTag.APP, Log.DEBUG)) { log("rebuildCache: add tid=" + threadId); } } } } finally { cursor.close(); } } mDraftSet = newDraftSet; if (Log.isLoggable(LogTag.APP, Log.VERBOSE)) { dump(); } // If nobody's interested in finding out about changes, // just bail out early. if (mChangeListeners.size() < 1) { return; } // Find out which drafts were removed and added and notify // listeners. Set<Long> added = new HashSet<Long>(newDraftSet); added.removeAll(oldDraftSet); Set<Long> removed = new HashSet<Long>(oldDraftSet); removed.removeAll(newDraftSet); for (OnDraftChangedListener l : mChangeListeners) { for (long threadId : added) { l.onDraftChanged(threadId, true); } for (long threadId : removed) { l.onDraftChanged(threadId, false); } } }
@Override protected Void doInBackground(Intent... intents) { Intent intent = intents[0]; Xlog.d( MmsApp.TXN_TAG, "do In Background, slotId=" + intent.getIntExtra(Phone.GEMINI_SIM_ID_KEY, 0)); // Get raw PDU push-data from the message and parse it byte[] pushData = intent.getByteArrayExtra("data"); PduParser parser = new PduParser(pushData); GenericPdu pdu = parser.parse(); if (null == pdu) { Log.e(TAG, "Invalid PUSH data"); return null; } PduPersister p = PduPersister.getPduPersister(mContext); ContentResolver cr = mContext.getContentResolver(); int type = pdu.getMessageType(); long threadId = -1; try { switch (type) { case MESSAGE_TYPE_DELIVERY_IND: Xlog.d(MmsApp.TXN_TAG, "type=MESSAGE_TYPE_DELIVERY_IND"); case MESSAGE_TYPE_READ_ORIG_IND: { if (type == MESSAGE_TYPE_READ_ORIG_IND) { Xlog.d(MmsApp.TXN_TAG, "type=MESSAGE_TYPE_READ_ORIG_IND"); } threadId = findThreadId(mContext, pdu, type); if (threadId == -1) { // The associated SendReq isn't found, therefore skip // processing this PDU. break; } Uri uri = p.persist(pdu, Inbox.CONTENT_URI); // Update thread ID for ReadOrigInd & DeliveryInd. ContentValues values = new ContentValues(1); values.put(Mms.THREAD_ID, threadId); SqliteWrapper.update(mContext, cr, uri, values, null, null); break; } case MESSAGE_TYPE_NOTIFICATION_IND: { Xlog.d(MmsApp.TXN_TAG, "type=MESSAGE_TYPE_NOTIFICATION_IND"); NotificationInd nInd = (NotificationInd) pdu; if (MmsConfig.getTransIdEnabled()) { byte[] contentLocation = nInd.getContentLocation(); if ('=' == contentLocation[contentLocation.length - 1]) { byte[] transactionId = nInd.getTransactionId(); byte[] contentLocationWithId = new byte[contentLocation.length + transactionId.length]; System.arraycopy( contentLocation, 0, contentLocationWithId, 0, contentLocation.length); System.arraycopy( transactionId, 0, contentLocationWithId, contentLocation.length, transactionId.length); nInd.setContentLocation(contentLocationWithId); } } if (!isDuplicateNotification(mContext, nInd)) { Uri uri = p.persist(pdu, Inbox.CONTENT_URI); // add for gemini if (FeatureOption.MTK_GEMINI_SUPPORT) { // update pdu ContentValues values = new ContentValues(2); SIMInfo si = SIMInfo.getSIMInfoBySlot( mContext, intent.getIntExtra(Phone.GEMINI_SIM_ID_KEY, -1)); if (null == si) { Xlog.e( MmsApp.TXN_TAG, "PushReceiver:SIMInfo is null for slot " + intent.getIntExtra(Phone.GEMINI_SIM_ID_KEY, -1)); break; } values.put(Mms.SIM_ID, si.mSimId); values.put(WapPush.SERVICE_ADDR, intent.getStringExtra(WapPush.SERVICE_ADDR)); SqliteWrapper.update(mContext, cr, uri, values, null, null); Xlog.d( MmsApp.TXN_TAG, "save notification slotId=" + intent.getIntExtra(Phone.GEMINI_SIM_ID_KEY, 0) + "\tsimId=" + si.mSimId + "\tsc=" + intent.getStringExtra(WapPush.SERVICE_ADDR) + "\taddr=" + intent.getStringExtra(WapPush.ADDR)); // update pending messages long msgId = 0; Cursor cursor = SqliteWrapper.query( mContext, mContext.getContentResolver(), uri, new String[] {Mms._ID}, null, null, null); if (cursor != null && cursor.getCount() == 1 && cursor.moveToFirst()) { try { msgId = cursor.getLong(0); Xlog.d(MmsApp.TXN_TAG, "msg id = " + msgId); } finally { cursor.close(); } } Uri.Builder uriBuilder = PendingMessages.CONTENT_URI.buildUpon(); uriBuilder.appendQueryParameter("protocol", "mms"); uriBuilder.appendQueryParameter("message", String.valueOf(msgId)); Cursor pendingCs = SqliteWrapper.query( mContext, mContext.getContentResolver(), uriBuilder.build(), null, null, null, null); if (pendingCs != null) { try { if ((pendingCs.getCount() == 1) && pendingCs.moveToFirst()) { ContentValues valuesforPending = new ContentValues(); valuesforPending.put(PendingMessages.SIM_ID, si.mSimId); int columnIndex = pendingCs.getColumnIndexOrThrow(PendingMessages._ID); long id = pendingCs.getLong(columnIndex); SqliteWrapper.update( mContext, mContext.getContentResolver(), PendingMessages.CONTENT_URI, valuesforPending, PendingMessages._ID + "=" + id, null); } else { Xlog.w( MmsApp.TXN_TAG, "can not find message to set pending sim id, msgId=" + msgId); } } finally { pendingCs.close(); } } } else { ContentValues value = new ContentValues(1); value.put(WapPush.SERVICE_ADDR, intent.getStringExtra(WapPush.SERVICE_ADDR)); SqliteWrapper.update(mContext, cr, uri, value, null, null); Xlog.d( MmsApp.TXN_TAG, "save notification," + "\tsc=" + intent.getStringExtra(WapPush.SERVICE_ADDR) + "\taddr=" + intent.getStringExtra(WapPush.ADDR)); } // Start service to finish the notification transaction. Intent svc = new Intent(mContext, TransactionService.class); svc.putExtra(TransactionBundle.URI, uri.toString()); svc.putExtra( TransactionBundle.TRANSACTION_TYPE, Transaction.NOTIFICATION_TRANSACTION); if (FeatureOption.MTK_GEMINI_SUPPORT) { SIMInfo si = SIMInfo.getSIMInfoBySlot( mContext, intent.getIntExtra(Phone.GEMINI_SIM_ID_KEY, -1)); if (null == si) { Xlog.e( MmsApp.TXN_TAG, "PushReceiver: SIMInfo is null for slot " + intent.getIntExtra(Phone.GEMINI_SIM_ID_KEY, -1)); break; } int simId = (int) si.mSimId; svc.putExtra(Phone.GEMINI_SIM_ID_KEY, simId); // svc.putExtra(Phone.GEMINI_SIM_ID_KEY, // intent.getIntExtra(Phone.GEMINI_SIM_ID_KEY, 0)); } mContext.startService(svc); } else if (LOCAL_LOGV) { Log.v( TAG, "Skip downloading duplicate message: " + new String(nInd.getContentLocation())); } break; } default: Log.e(TAG, "Received unrecognized PDU."); } } catch (MmsException e) { Log.e(TAG, "Failed to save the data from PUSH: type=" + type, e); } catch (RuntimeException e) { Log.e(TAG, "Unexpected RuntimeException.", e); } finally { raisePriority(mContext, false); Xlog.d(MmsApp.TXN_TAG, "Normal priority"); } if (LOCAL_LOGV) { Log.v(TAG, "PUSH Intent processed."); } return null; }
private void initModelFromUri(Uri uri) throws MmsException { ContentResolver cr = mContext.getContentResolver(); Cursor c = SqliteWrapper.query(mContext, cr, uri, null, null, null, null); if (c != null) { try { if (c.moveToFirst()) { String path; boolean isFromMms = isMmsUri(uri); // FIXME We suppose that there should be only two sources // of the audio, one is the media store, the other is // our MMS database. if (isFromMms) { path = c.getString(c.getColumnIndexOrThrow(Part._DATA)); mContentType = c.getString(c.getColumnIndexOrThrow(Part.CONTENT_TYPE)); } else { path = c.getString(c.getColumnIndexOrThrow(Audio.Media.DATA)); mContentType = c.getString(c.getColumnIndexOrThrow(Audio.Media.MIME_TYPE)); // Get more extras information which would be useful // to the user. String album = c.getString(c.getColumnIndexOrThrow("album")); if (!TextUtils.isEmpty(album)) { mExtras.put("album", album); } String artist = c.getString(c.getColumnIndexOrThrow("artist")); if (!TextUtils.isEmpty(artist)) { mExtras.put("artist", artist); } } if (FeatureOption.MTK_DRM_APP) { if (MessageUtils.checkUriContainsDrm(mContext, uri)) { path += ".dcf"; } } mSrc = path.substring(path.lastIndexOf('/') + 1).replace(' ', '_'); Log.i(TAG, "path: " + path); Log.i(TAG, "mSrc: " + mSrc); if (TextUtils.isEmpty(mContentType)) { throw new MmsException("Type of media is unknown."); } if (LOCAL_LOGV) { Log.v( TAG, "New AudioModel created:" + " mSrc=" + mSrc + " mContentType=" + mContentType + " mUri=" + uri + " mExtras=" + mExtras); } } else { throw new MmsException("Nothing found: " + uri); } } finally { c.close(); } } else { throw new MmsException("Bad URI: " + uri); } initMediaDuration(); }
public synchronized void sendFirstQueuedMessage() { boolean success = true; // get all the queued messages from the database final Uri uri = Uri.parse("content://sms/queued"); ContentResolver resolver = getContentResolver(); Cursor c = SqliteWrapper.query( this, resolver, uri, SEND_PROJECTION, null, null, "date ASC"); // date ASC so we send out in // same order the user tried // to send messages. if (c != null) { try { if (c.moveToFirst()) { String msgText = c.getString(SEND_COLUMN_BODY); String address = c.getString(SEND_COLUMN_ADDRESS); int threadId = c.getInt(SEND_COLUMN_THREAD_ID); int status = c.getInt(SEND_COLUMN_STATUS); int msgId = c.getInt(SEND_COLUMN_ID); Uri msgUri = ContentUris.withAppendedId(Sms.CONTENT_URI, msgId); SmsMessageSender sender = new SmsSingleRecipientSender( this, address, msgText, threadId, status == Sms.STATUS_PENDING, msgUri); if (LogTag.DEBUG_SEND || LogTag.VERBOSE || Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { Log.v( TAG, "sendFirstQueuedMessage " + msgUri + ", address: " + address + ", threadId: " + threadId); } try { sender.sendMessage(SendingProgressTokenManager.NO_TOKEN); ; mSending = true; } catch (MmsException e) { Log.e(TAG, "sendFirstQueuedMessage: failed to send message " + msgUri + ", caught ", e); mSending = false; messageFailedToSend(msgUri, SmsManager.RESULT_ERROR_GENERIC_FAILURE); success = false; // Sending current message fails. Try to send more pending messages // if there is any. sendBroadcast( new Intent(SmsReceiverService.ACTION_SEND_MESSAGE, null, this, SmsReceiver.class)); } } } finally { c.close(); } } if (success) { // We successfully sent all the messages in the queue. We don't need to // be notified of any service changes any longer. unRegisterForServiceStateChanges(); } }