Example #1
0
 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);
  }
Example #4
0
 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);
    }
  }