예제 #1
0
 public static boolean shouldVibrate(
     String vibroModeKey, SharedPreferences settings, AudioManager audioManager) {
   try {
     int mode = Integer.parseInt(settings.getString(vibroModeKey, "0"));
     switch (mode) {
       case MODE_SYSTEM:
         return audioManager.shouldVibrate(AudioManager.VIBRATE_TYPE_NOTIFICATION);
       case MODE_ALWAYS:
         return true;
       case MODE_NEVER:
         return false;
       case MODE_NORMAL_ONLY:
         return audioManager.getRingerMode() == AudioManager.RINGER_MODE_NORMAL;
       case MODE_SILENT_ONLY:
         switch (audioManager.getRingerMode()) {
           case AudioManager.RINGER_MODE_SILENT:
           case AudioManager.RINGER_MODE_VIBRATE:
             return true;
         }
         return false;
     }
   } catch (Exception ex) {
     Log.w(Settings.class.getSimpleName(), "", ex);
   }
   return false;
 }
예제 #2
0
  boolean shouldVibrate() {
    final AudioManager audioManager =
        (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);

    /// M: MTK_AUDIO_PROFILES @{
    if (PhoneFeatureConstants.FeatureOption.MTK_AUDIO_PROFILES) {
      return audioManager.shouldVibrate(AudioManager.VIBRATE_TYPE_RINGER);
    }
    /// @}
    int ringerMode = audioManager.getRingerMode();
    if (CallFeaturesSetting.getVibrateWhenRinging(mContext)) {
      return ringerMode != AudioManager.RINGER_MODE_SILENT;
    } else {
      return ringerMode == AudioManager.RINGER_MODE_VIBRATE;
    }
  }
  public void enqueueNotificationInternal(
      String pkg,
      int callingUid,
      int callingPid,
      String tag,
      int id,
      int priority,
      Notification notification,
      int[] idOut) {
    checkIncomingCall(pkg);

    // Limit the number of notifications that any given package except the android
    // package can enqueue.  Prevents DOS attacks and deals with leaks.
    if (!"android".equals(pkg)) {
      synchronized (mNotificationList) {
        int count = 0;
        final int N = mNotificationList.size();
        for (int i = 0; i < N; i++) {
          final NotificationRecord r = mNotificationList.get(i);
          if (r.pkg.equals(pkg)) {
            count++;
            if (count >= MAX_PACKAGE_NOTIFICATIONS) {
              Slog.e(
                  TAG,
                  "Package has already posted "
                      + count
                      + " notifications.  Not showing more.  package="
                      + pkg);
              return;
            }
          }
        }
      }
    }

    // This conditional is a dirty hack to limit the logging done on
    //     behalf of the download manager without affecting other apps.
    if (!pkg.equals("com.android.providers.downloads")
        || Log.isLoggable("DownloadManager", Log.VERBOSE)) {
      EventLog.writeEvent(EventLogTags.NOTIFICATION_ENQUEUE, pkg, id, notification.toString());
    }

    if (pkg == null || notification == null) {
      throw new IllegalArgumentException(
          "null not allowed: pkg=" + pkg + " id=" + id + " notification=" + notification);
    }
    if (notification.icon != 0) {
      if (notification.contentView == null) {
        throw new IllegalArgumentException(
            "contentView required: pkg=" + pkg + " id=" + id + " notification=" + notification);
      }
    }

    synchronized (mNotificationList) {
      NotificationRecord r =
          new NotificationRecord(pkg, tag, id, callingUid, callingPid, priority, notification);
      NotificationRecord old = null;

      int index = indexOfNotificationLocked(pkg, tag, id);
      if (index < 0) {
        mNotificationList.add(r);
      } else {
        old = mNotificationList.remove(index);
        mNotificationList.add(index, r);
        // Make sure we don't lose the foreground service state.
        if (old != null) {
          notification.flags |= old.notification.flags & Notification.FLAG_FOREGROUND_SERVICE;
        }
      }

      // Ensure if this is a foreground service that the proper additional
      // flags are set.
      if ((notification.flags & Notification.FLAG_FOREGROUND_SERVICE) != 0) {
        notification.flags |= Notification.FLAG_ONGOING_EVENT | Notification.FLAG_NO_CLEAR;
      }

      if (notification.icon != 0) {
        StatusBarNotification n =
            new StatusBarNotification(pkg, id, tag, r.uid, r.initialPid, notification);
        n.priority = r.priority;

        if (old != null && old.statusBarKey != null) {
          r.statusBarKey = old.statusBarKey;
          long identity = Binder.clearCallingIdentity();
          try {
            mStatusBar.updateNotification(r.statusBarKey, n);
          } finally {
            Binder.restoreCallingIdentity(identity);
          }
        } else {
          long identity = Binder.clearCallingIdentity();
          try {
            r.statusBarKey = mStatusBar.addNotification(n);
            mAttentionLight.pulse();
          } finally {
            Binder.restoreCallingIdentity(identity);
          }
        }
        sendAccessibilityEvent(notification, pkg);
      } else {
        Slog.e(TAG, "Ignoring notification with icon==0: " + notification);
        if (old != null && old.statusBarKey != null) {
          long identity = Binder.clearCallingIdentity();
          try {
            mStatusBar.removeNotification(old.statusBarKey);
          } finally {
            Binder.restoreCallingIdentity(identity);
          }
        }
      }

      // If we're not supposed to beep, vibrate, etc. then don't.
      if (((mDisabledNotifications & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) == 0)
          && (!(old != null && (notification.flags & Notification.FLAG_ONLY_ALERT_ONCE) != 0))
          && mSystemReady) {

        final AudioManager audioManager =
            (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
        // sound
        final boolean useDefaultSound = (notification.defaults & Notification.DEFAULT_SOUND) != 0;
        if (useDefaultSound || notification.sound != null) {
          Uri uri;
          if (useDefaultSound) {
            uri = Settings.System.DEFAULT_NOTIFICATION_URI;
          } else {
            uri = notification.sound;
          }
          boolean looping = (notification.flags & Notification.FLAG_INSISTENT) != 0;
          int audioStreamType;
          if (notification.audioStreamType >= 0) {
            audioStreamType = notification.audioStreamType;
          } else {
            audioStreamType = DEFAULT_STREAM_TYPE;
          }
          mSoundNotification = r;
          // do not play notifications if stream volume is 0
          // (typically because ringer mode is silent).
          if (audioManager.getStreamVolume(audioStreamType) != 0) {
            long identity = Binder.clearCallingIdentity();
            try {
              mSound.play(mContext, uri, looping, audioStreamType);
            } finally {
              Binder.restoreCallingIdentity(identity);
            }
          }
        }

        // vibrate
        final boolean useDefaultVibrate =
            (notification.defaults & Notification.DEFAULT_VIBRATE) != 0;
        if ((useDefaultVibrate || notification.vibrate != null)
            && audioManager.shouldVibrate(AudioManager.VIBRATE_TYPE_NOTIFICATION)) {
          mVibrateNotification = r;

          mVibrator.vibrate(
              useDefaultVibrate ? DEFAULT_VIBRATE_PATTERN : notification.vibrate,
              ((notification.flags & Notification.FLAG_INSISTENT) != 0) ? 0 : -1);
        }
      }

      // this option doesn't shut off the lights

      // light
      // the most recent thing gets the light
      mLights.remove(old);
      if (mLedNotification == old) {
        mLedNotification = null;
      }
      // Slog.i(TAG, "notification.lights="
      //        + ((old.notification.lights.flags & Notification.FLAG_SHOW_LIGHTS) != 0));
      if ((notification.flags & Notification.FLAG_SHOW_LIGHTS) != 0) {
        mLights.add(r);
        updateLightsLocked();
      } else {
        if (old != null && ((old.notification.flags & Notification.FLAG_SHOW_LIGHTS) != 0)) {
          updateLightsLocked();
        }
      }
    }

    idOut[0] = id;
  }
예제 #4
0
 boolean shouldVibrate() {
   AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
   return audioManager.shouldVibrate(AudioManager.VIBRATE_TYPE_RINGER);
 }
예제 #5
0
  @TestTargets({
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        method = "shouldVibrate",
        args = {int.class}),
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        method = "setVibrateSetting",
        args = {int.class, int.class}),
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        method = "getVibrateSetting",
        args = {int.class}),
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        method = "setRingerMode",
        args = {int.class})
  })
  public void testVibrateRinger() throws Exception {
    // VIBRATE_TYPE_RINGER
    mAudioManager.setVibrateSetting(VIBRATE_TYPE_RINGER, VIBRATE_SETTING_ON);
    assertEquals(VIBRATE_SETTING_ON, mAudioManager.getVibrateSetting(VIBRATE_TYPE_RINGER));
    mAudioManager.setRingerMode(RINGER_MODE_NORMAL);
    assertTrue(mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER));

    mAudioManager.setRingerMode(RINGER_MODE_SILENT);
    assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER));

    mAudioManager.setRingerMode(RINGER_MODE_VIBRATE);
    assertEquals(RINGER_MODE_VIBRATE, mAudioManager.getRingerMode());
    assertTrue(mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER));

    // VIBRATE_SETTING_OFF
    mAudioManager.setVibrateSetting(VIBRATE_TYPE_RINGER, VIBRATE_SETTING_OFF);
    assertEquals(VIBRATE_SETTING_OFF, mAudioManager.getVibrateSetting(VIBRATE_TYPE_RINGER));
    mAudioManager.setRingerMode(RINGER_MODE_NORMAL);
    assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER));

    mAudioManager.setRingerMode(RINGER_MODE_SILENT);
    assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER));

    mAudioManager.setRingerMode(RINGER_MODE_VIBRATE);
    assertEquals(RINGER_MODE_VIBRATE, mAudioManager.getRingerMode());
    // Note: as of Froyo, if VIBRATE_TYPE_RINGER is set to OFF, it will
    // not vibrate, even in RINGER_MODE_VIBRATE. This allows users to
    // disable the vibration for incoming calls only.
    assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER));

    // VIBRATE_SETTING_ONLY_SILENT
    mAudioManager.setVibrateSetting(VIBRATE_TYPE_RINGER, VIBRATE_SETTING_ONLY_SILENT);
    assertEquals(VIBRATE_SETTING_ONLY_SILENT, mAudioManager.getVibrateSetting(VIBRATE_TYPE_RINGER));
    mAudioManager.setRingerMode(RINGER_MODE_NORMAL);
    assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER));

    mAudioManager.setRingerMode(RINGER_MODE_SILENT);
    assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER));

    mAudioManager.setRingerMode(RINGER_MODE_VIBRATE);
    assertEquals(RINGER_MODE_VIBRATE, mAudioManager.getRingerMode());
    assertTrue(mAudioManager.shouldVibrate(VIBRATE_TYPE_RINGER));

    // VIBRATE_TYPE_NOTIFICATION
    mAudioManager.setVibrateSetting(VIBRATE_TYPE_RINGER, VIBRATE_SETTING_ON);
    assertEquals(VIBRATE_SETTING_ON, mAudioManager.getVibrateSetting(VIBRATE_TYPE_RINGER));
    mAudioManager.setVibrateSetting(VIBRATE_TYPE_RINGER, VIBRATE_SETTING_OFF);
    assertEquals(VIBRATE_SETTING_OFF, mAudioManager.getVibrateSetting(VIBRATE_TYPE_RINGER));
    mAudioManager.setVibrateSetting(VIBRATE_TYPE_RINGER, VIBRATE_SETTING_ONLY_SILENT);
    assertEquals(VIBRATE_SETTING_ONLY_SILENT, mAudioManager.getVibrateSetting(VIBRATE_TYPE_RINGER));
  }
예제 #6
0
  @TestTargets({
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        method = "shouldVibrate",
        args = {int.class}),
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        method = "setVibrateSetting",
        args = {int.class, int.class}),
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        method = "getVibrateSetting",
        args = {int.class}),
    @TestTargetNew(
        level = TestLevel.COMPLETE,
        method = "setRingerMode",
        args = {int.class})
  })
  public void testVibrateNotification() throws Exception {
    // VIBRATE_SETTING_ON
    mAudioManager.setVibrateSetting(VIBRATE_TYPE_NOTIFICATION, VIBRATE_SETTING_ON);
    assertEquals(VIBRATE_SETTING_ON, mAudioManager.getVibrateSetting(VIBRATE_TYPE_NOTIFICATION));
    mAudioManager.setRingerMode(RINGER_MODE_NORMAL);
    assertTrue(mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION));

    mAudioManager.setRingerMode(RINGER_MODE_SILENT);
    assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION));

    mAudioManager.setRingerMode(RINGER_MODE_VIBRATE);
    assertEquals(RINGER_MODE_VIBRATE, mAudioManager.getRingerMode());
    assertTrue(mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION));

    // VIBRATE_SETTING_OFF
    mAudioManager.setVibrateSetting(VIBRATE_TYPE_NOTIFICATION, VIBRATE_SETTING_OFF);
    assertEquals(VIBRATE_SETTING_OFF, mAudioManager.getVibrateSetting(VIBRATE_TYPE_NOTIFICATION));
    mAudioManager.setRingerMode(RINGER_MODE_NORMAL);
    assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION));

    mAudioManager.setRingerMode(RINGER_MODE_SILENT);
    assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION));

    mAudioManager.setRingerMode(RINGER_MODE_VIBRATE);
    assertEquals(RINGER_MODE_VIBRATE, mAudioManager.getRingerMode());
    assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION));

    // VIBRATE_SETTING_ONLY_SILENT
    mAudioManager.setVibrateSetting(VIBRATE_TYPE_NOTIFICATION, VIBRATE_SETTING_ONLY_SILENT);
    assertEquals(
        VIBRATE_SETTING_ONLY_SILENT, mAudioManager.getVibrateSetting(VIBRATE_TYPE_NOTIFICATION));
    mAudioManager.setRingerMode(RINGER_MODE_NORMAL);
    assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION));

    mAudioManager.setRingerMode(RINGER_MODE_SILENT);
    assertFalse(mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION));

    mAudioManager.setRingerMode(RINGER_MODE_VIBRATE);
    assertEquals(RINGER_MODE_VIBRATE, mAudioManager.getRingerMode());
    assertTrue(mAudioManager.shouldVibrate(VIBRATE_TYPE_NOTIFICATION));

    // VIBRATE_TYPE_NOTIFICATION
    mAudioManager.setVibrateSetting(VIBRATE_TYPE_NOTIFICATION, VIBRATE_SETTING_ON);
    assertEquals(VIBRATE_SETTING_ON, mAudioManager.getVibrateSetting(VIBRATE_TYPE_NOTIFICATION));
    mAudioManager.setVibrateSetting(VIBRATE_TYPE_NOTIFICATION, VIBRATE_SETTING_OFF);
    assertEquals(VIBRATE_SETTING_OFF, mAudioManager.getVibrateSetting(VIBRATE_TYPE_NOTIFICATION));
    mAudioManager.setVibrateSetting(VIBRATE_TYPE_NOTIFICATION, VIBRATE_SETTING_ONLY_SILENT);
    assertEquals(
        VIBRATE_SETTING_ONLY_SILENT, mAudioManager.getVibrateSetting(VIBRATE_TYPE_NOTIFICATION));
  }
예제 #7
0
  /**
   * Shows an Astrid notification. Pulls in ring tone and quiet hour settings from preferences. You
   * can make it say anything you like.
   *
   * @param ringTimes number of times to ring (-1 = nonstop)
   */
  public static void showNotification(
      int notificationId, Intent intent, int type, String title, String text, int ringTimes) {
    Context context = ContextManager.getContext();
    if (notificationManager == null) notificationManager = new AndroidNotificationManager(context);

    // quiet hours? unless alarm clock
    boolean quietHours = false;
    int quietHoursStart = Preferences.getIntegerFromString(R.string.p_rmd_quietStart, -1);
    int quietHoursEnd = Preferences.getIntegerFromString(R.string.p_rmd_quietEnd, -1);
    if (quietHoursStart != -1 && quietHoursEnd != -1 && ringTimes >= 0) {
      int hour = new Date().getHours();
      if (quietHoursStart <= quietHoursEnd) {
        if (hour >= quietHoursStart && hour < quietHoursEnd) quietHours = true;
      } else { // wrap across 24/hour boundary
        if (hour >= quietHoursStart || hour < quietHoursEnd) quietHours = true;
      }
    }

    PendingIntent pendingIntent =
        PendingIntent.getActivity(
            context, notificationId, intent, PendingIntent.FLAG_UPDATE_CURRENT);

    // set up properties (name and icon) for the notification
    int icon;
    switch (Preferences.getIntegerFromString(R.string.p_rmd_icon, ICON_SET_ASTRID)) {
      case ICON_SET_PINK:
        icon = R.drawable.notif_pink_alarm;
        break;
      case ICON_SET_BORING:
        icon = R.drawable.notif_boring_alarm;
        break;
      default:
        icon = R.drawable.notif_astrid;
    }

    // create notification object
    Notification notification = new Notification(icon, text, System.currentTimeMillis());
    notification.setLatestEventInfo(context, title, text, pendingIntent);
    notification.flags |= Notification.FLAG_AUTO_CANCEL;
    if (Preferences.getBoolean(R.string.p_rmd_persistent, true)) {
      notification.flags |= Notification.FLAG_NO_CLEAR | Notification.FLAG_SHOW_LIGHTS;
      notification.ledOffMS = 5000;
      notification.ledOnMS = 700;
      notification.ledARGB = Color.YELLOW;
    } else notification.defaults = Notification.DEFAULT_LIGHTS;

    AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);

    // detect call state
    TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
    int callState = tm.getCallState();

    boolean voiceReminder = Preferences.getBoolean(R.string.p_voiceRemindersEnabled, false);

    // if multi-ring is activated, set up the flags for insistent
    // notification, and increase the volume to full volume, so the user
    // will actually pay attention to the alarm
    if (ringTimes != 1 && (type != ReminderService.TYPE_RANDOM)) {
      notification.audioStreamType = AudioManager.STREAM_ALARM;
      audioManager.setStreamVolume(
          AudioManager.STREAM_ALARM, audioManager.getStreamMaxVolume(AudioManager.STREAM_ALARM), 0);

      // insistent rings until notification is disabled
      if (ringTimes < 0) {
        notification.flags |= Notification.FLAG_INSISTENT;
        voiceReminder = false;
      }

    } else {
      notification.audioStreamType = AudioManager.STREAM_NOTIFICATION;
    }

    // quiet hours = no sound
    if (quietHours || callState != TelephonyManager.CALL_STATE_IDLE) {
      notification.sound = null;
      voiceReminder = false;
    } else {
      String notificationPreference = Preferences.getStringValue(R.string.p_rmd_ringtone);
      if (audioManager.getStreamVolume(AudioManager.STREAM_RING) == 0) {
        notification.sound = null;
        voiceReminder = false;
      } else if (notificationPreference != null) {
        if (notificationPreference.length() > 0) {
          Uri notificationSound = Uri.parse(notificationPreference);
          notification.sound = notificationSound;
        } else {
          notification.sound = null;
        }
      } else {
        notification.defaults |= Notification.DEFAULT_SOUND;
      }
    }

    // quiet hours && ! due date or snooze = no vibrate
    if (quietHours && !(type == ReminderService.TYPE_DUE || type == ReminderService.TYPE_SNOOZE)) {
      notification.vibrate = null;
    } else if (callState != TelephonyManager.CALL_STATE_IDLE) {
      notification.vibrate = null;
    } else {
      if (Preferences.getBoolean(R.string.p_rmd_vibrate, true)
          && audioManager.shouldVibrate(AudioManager.VIBRATE_TYPE_NOTIFICATION)) {
        notification.vibrate = new long[] {0, 1000, 500, 1000, 500, 1000};
      } else {
        notification.vibrate = null;
      }
    }

    if (Constants.DEBUG)
      Log.w("Astrid", "Logging notification: " + text); // $NON-NLS-1$ //$NON-NLS-2$

    for (int i = 0; i < Math.max(ringTimes, 1); i++) {
      notificationManager.notify(notificationId, notification);
      AndroidUtilities.sleepDeep(500);
    }

    if (voiceReminder) {
      AndroidUtilities.sleepDeep(2000);
      for (int i = 0; i < 50; i++) {
        AndroidUtilities.sleepDeep(500);
        if (audioManager.getMode() != AudioManager.MODE_RINGTONE) break;
      }
      try {
        VoiceOutputService.getVoiceOutputInstance().queueSpeak(text);
      } catch (VerifyError e) {
        // unavailable
      }
    }
  }