private static void sendDirectAccessibilityEvent(int eventType, JSONObject message) { final AccessibilityEvent accEvent = AccessibilityEvent.obtain(eventType); accEvent.setClassName(GeckoAccessibility.class.getName()); accEvent.setPackageName(GeckoAppShell.getContext().getPackageName()); populateEventFromJSON(accEvent, message); AccessibilityManager accessibilityManager = (AccessibilityManager) GeckoAppShell.getContext().getSystemService(Context.ACCESSIBILITY_SERVICE); try { accessibilityManager.sendAccessibilityEvent(accEvent); } catch (IllegalStateException e) { // Accessibility is off. } }
public int saveSentMessage(String aRecipient, String aBody, long aDate) { try { ContentValues values = new ContentValues(); values.put("address", aRecipient); values.put("body", aBody); values.put("date", aDate); // Always 'PENDING' because we always request status report. values.put("status", kInternalDeliveryStatusPending); ContentResolver cr = GeckoAppShell.getContext().getContentResolver(); Uri uri = cr.insert(kSmsSentContentUri, values); long id = ContentUris.parseId(uri); // The DOM API takes a 32bits unsigned int for the id. It's unlikely that // we happen to need more than that but it doesn't cost to check. if (id > Integer.MAX_VALUE) { throw new IdTooHighException(); } return (int) id; } catch (IdTooHighException e) { Log.e("GeckoSmsManager", "The id we received is higher than the higher allowed value."); return -1; } catch (Exception e) { Log.e("GeckoSmsManager", "Something went wrong when trying to write a sent message", e); return -1; } }
@Override public void start() { IntentFilter smsFilter = new IntentFilter(); smsFilter.addAction(GeckoSmsManager.ACTION_SMS_RECEIVED); smsFilter.addAction(GeckoSmsManager.ACTION_SMS_SENT); smsFilter.addAction(GeckoSmsManager.ACTION_SMS_DELIVERED); GeckoAppShell.getContext().registerReceiver(this, smsFilter); }
private static File getPingFile() { if (GeckoAppShell.getContext() == null) { return null; } GeckoProfile profile = GeckoAppShell.getGeckoInterface().getProfile(); if (profile == null) { return null; } File profDir = profile.getDir(); if (profDir == null) { return null; } File pingDir = new File(profDir, "saved-telemetry-pings"); pingDir.mkdirs(); if (!(pingDir.exists() && pingDir.isDirectory())) { return null; } return new File(pingDir, UUID.randomUUID().toString()); }
@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); } }
@Override public void stop() { GeckoAppShell.getContext().unregisterReceiver(this); }
@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(); } } }
@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(); } } }
@Override public void send(String aNumber, String aMessage, int aRequestId) { int envelopeId = Postman.kUnknownEnvelopeId; try { SmsManager sm = SmsManager.getDefault(); Intent sentIntent = new Intent(ACTION_SMS_SENT); Intent deliveredIntent = new Intent(ACTION_SMS_DELIVERED); Bundle bundle = new Bundle(); bundle.putString("number", aNumber); bundle.putString("message", aMessage); bundle.putInt("requestId", aRequestId); if (aMessage.length() <= kMaxMessageSize) { envelopeId = Postman.getInstance().createEnvelope(1); bundle.putInt("envelopeId", envelopeId); sentIntent.putExtras(bundle); deliveredIntent.putExtras(bundle); /* * There are a few things to know about getBroadcast and pending intents: * - the pending intents are in a shared pool maintained by the system; * - each pending intent is identified by a token; * - when a new pending intent is created, if it has the same token as * another intent in the pool, one of them has to be removed. * * To prevent having a hard time because of this situation, we give a * unique id to all pending intents we are creating. This unique id is * generated by GetPendingIntentUID(). */ PendingIntent sentPendingIntent = PendingIntent.getBroadcast( GeckoAppShell.getContext(), PendingIntentUID.generate(), sentIntent, PendingIntent.FLAG_CANCEL_CURRENT); PendingIntent deliveredPendingIntent = PendingIntent.getBroadcast( GeckoAppShell.getContext(), PendingIntentUID.generate(), deliveredIntent, PendingIntent.FLAG_CANCEL_CURRENT); sm.sendTextMessage(aNumber, "", aMessage, sentPendingIntent, deliveredPendingIntent); } else { ArrayList<String> parts = sm.divideMessage(aMessage); envelopeId = Postman.getInstance().createEnvelope(parts.size()); bundle.putInt("envelopeId", envelopeId); sentIntent.putExtras(bundle); deliveredIntent.putExtras(bundle); ArrayList<PendingIntent> sentPendingIntents = new ArrayList<PendingIntent>(parts.size()); ArrayList<PendingIntent> deliveredPendingIntents = new ArrayList<PendingIntent>(parts.size()); for (int i = 0; i < parts.size(); ++i) { sentPendingIntents.add( PendingIntent.getBroadcast( GeckoAppShell.getContext(), PendingIntentUID.generate(), sentIntent, PendingIntent.FLAG_CANCEL_CURRENT)); deliveredPendingIntents.add( PendingIntent.getBroadcast( GeckoAppShell.getContext(), PendingIntentUID.generate(), deliveredIntent, PendingIntent.FLAG_CANCEL_CURRENT)); } sm.sendMultipartTextMessage( aNumber, "", parts, sentPendingIntents, deliveredPendingIntents); } } catch (Exception e) { Log.e("GeckoSmsManager", "Failed to send an SMS: ", e); if (envelopeId != Postman.kUnknownEnvelopeId) { Postman.getInstance().destroyEnvelope(envelopeId); } notifySmsSendFailed(kUnknownError, aRequestId); } }