Fixed wakelock not acquired long enough for alert reminder

1. Start queing the alert reminder after tone playing finishes.
2. Fixed that wakelock not acquired long enough for alert reminder
   so the reminder notification and vibration were not consistenly
   played while the device screen is off.
3. Alert reminder vibration now honors the vibration settings.

Test: Manual
bug: 38301329
Merged-In: I6ab7ac120753b7c4d3683cd97ea8e97037a8b797
Change-Id: I6ab7ac120753b7c4d3683cd97ea8e97037a8b797
diff --git a/src/com/android/cellbroadcastreceiver/CellBroadcastAlertAudio.java b/src/com/android/cellbroadcastreceiver/CellBroadcastAlertAudio.java
index 0885218..d3d4266 100644
--- a/src/com/android/cellbroadcastreceiver/CellBroadcastAlertAudio.java
+++ b/src/com/android/cellbroadcastreceiver/CellBroadcastAlertAudio.java
@@ -19,7 +19,6 @@
 import static com.android.cellbroadcastreceiver.CellBroadcastReceiver.DBG;
 import static com.android.cellbroadcastreceiver.CellBroadcastReceiver.VDBG;
 
-import android.app.PendingIntent;
 import android.app.Service;
 import android.content.Context;
 import android.content.Intent;
@@ -111,8 +110,6 @@
     private TelephonyManager mTelephonyManager;
     private int mInitialCallState;
 
-    private PendingIntent mPlayReminderIntent;
-
     public enum ToneType {
         CMAS_DEFAULT,
         ETWS_DEFAULT,
@@ -143,6 +140,8 @@
                         stopSelf();
                         mState = STATE_IDLE;
                     }
+                    // Set alert reminder depending on user preference
+                    CellBroadcastAlertReminder.queueAlertReminder(getApplicationContext(), true);
                     break;
 
                 case ALERT_PAUSE_FINISHED:
@@ -496,11 +495,6 @@
     public void stop() {
         if (DBG) log("stop()");
 
-        if (mPlayReminderIntent != null) {
-            mPlayReminderIntent.cancel();
-            mPlayReminderIntent = null;
-        }
-
         mHandler.removeMessages(ALERT_SOUND_FINISHED);
         mHandler.removeMessages(ALERT_PAUSE_FINISHED);
 
diff --git a/src/com/android/cellbroadcastreceiver/CellBroadcastAlertDialog.java b/src/com/android/cellbroadcastreceiver/CellBroadcastAlertDialog.java
index 052b045..4a0a9dd 100644
--- a/src/com/android/cellbroadcastreceiver/CellBroadcastAlertDialog.java
+++ b/src/com/android/cellbroadcastreceiver/CellBroadcastAlertDialog.java
@@ -374,8 +374,6 @@
         }
 
         ((TextView) findViewById(R.id.dismissButton)).setText(dismissButtonText);
-        // Set alert reminder depending on user preference
-        CellBroadcastAlertReminder.queueAlertReminder(this, true);
     }
 
     /**
diff --git a/src/com/android/cellbroadcastreceiver/CellBroadcastAlertReminder.java b/src/com/android/cellbroadcastreceiver/CellBroadcastAlertReminder.java
index 2b7b3c9..69dc4d2 100644
--- a/src/com/android/cellbroadcastreceiver/CellBroadcastAlertReminder.java
+++ b/src/com/android/cellbroadcastreceiver/CellBroadcastAlertReminder.java
@@ -42,7 +42,10 @@
     private static final String TAG = "CellBroadcastAlertReminder";
 
     /** Action to wake up and play alert reminder sound. */
-    static final String ACTION_PLAY_ALERT_REMINDER = "ACTION_PLAY_ALERT_REMINDER";
+    private static final String ACTION_PLAY_ALERT_REMINDER = "ACTION_PLAY_ALERT_REMINDER";
+
+    /** Extra for alert reminder vibration enabled (from settings). */
+    private static final String ALERT_REMINDER_VIBRATE_EXTRA = "alert_reminder_vibrate_extra";
 
     /**
      * Pending intent for alert reminder. This is static so that we don't have to start the
@@ -69,7 +72,7 @@
         }
 
         log("playing alert reminder");
-        playAlertReminderSound();
+        playAlertReminderSound(intent.getBooleanExtra(ALERT_REMINDER_VIBRATE_EXTRA, true));
 
         if (queueAlertReminder(this, false)) {
             return START_STICKY;
@@ -82,8 +85,11 @@
 
     /**
      * Use the RingtoneManager to play the alert reminder sound.
+     *
+     * @param enableVibration True to enable vibration when the alert reminder tone is playing,
+     *                        otherwise false.
      */
-    private void playAlertReminderSound() {
+    private void playAlertReminderSound(boolean enableVibration) {
         Uri notificationUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
         if (notificationUri == null) {
             loge("Can't get URI for alert reminder sound");
@@ -92,24 +98,31 @@
         Ringtone r = RingtoneManager.getRingtone(this, notificationUri);
         r.setStreamType(AudioManager.STREAM_NOTIFICATION);
 
-        CellBroadcastAlertWakeLock.acquirePartialWakeLock(getApplicationContext());
+        // Acquire the wakelock for 500ms. The wakelock will be released by its
+        // timer.
+        CellBroadcastAlertWakeLock.acquirePartialWakeLock(getApplicationContext(), 500);
         if (r != null) {
             log("playing alert reminder sound");
             r.play();
         } else {
             loge("can't get Ringtone for alert reminder sound");
         }
-        // Vibrate for 500ms.
-        Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
-        vibrator.vibrate(500, new AudioAttributes.Builder()
-                .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
-                .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION).build());
 
-        CellBroadcastAlertWakeLock.releasePartialWakeLock();
+        if (enableVibration) {
+            // Vibrate for 500ms.
+            Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
+            vibrator.vibrate(500, new AudioAttributes.Builder()
+                    .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
+                    .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION).build());
+        }
     }
 
     /**
      * Helper method to start the alert reminder service to queue the alert reminder.
+     *
+     * @param context Context.
+     * @param firstTime True if entering this method for the first time, otherwise false.
+     *
      * @return true if a pending reminder was set; false if there are no more reminders
      */
     static boolean queueAlertReminder(Context context, boolean firstTime) {
@@ -143,6 +156,8 @@
 
         Intent playIntent = new Intent(context, CellBroadcastAlertReminder.class);
         playIntent.setAction(ACTION_PLAY_ALERT_REMINDER);
+        playIntent.putExtra(ALERT_REMINDER_VIBRATE_EXTRA,
+                prefs.getBoolean(CellBroadcastSettings.KEY_ENABLE_ALERT_VIBRATE, true));
         sPlayReminderIntent = PendingIntent.getService(context, 0, playIntent,
                 PendingIntent.FLAG_UPDATE_CURRENT);
 
diff --git a/src/com/android/cellbroadcastreceiver/CellBroadcastAlertWakeLock.java b/src/com/android/cellbroadcastreceiver/CellBroadcastAlertWakeLock.java
index 6f77e15..6bd8de5 100644
--- a/src/com/android/cellbroadcastreceiver/CellBroadcastAlertWakeLock.java
+++ b/src/com/android/cellbroadcastreceiver/CellBroadcastAlertWakeLock.java
@@ -27,22 +27,29 @@
 class CellBroadcastAlertWakeLock {
     private static final String TAG = "CellBroadcastAlertWakeLock";
 
+    private static final long MAX_PARTIAL_WAKELOCK_DURATION = 1000;                  // 1 sec
+    private static final long MAX_SCREEN_BRIGHT_WAKELOCK_DURATION = 1000 * 60 * 5;   // 5 minutes
+
     private static WakeLock sPartialWakeLock;
     private static WakeLock sScreenBrightWakeLock;
 
     private CellBroadcastAlertWakeLock() {}
 
     static void acquirePartialWakeLock(Context context) {
+        // Make sure we don't acquire the partial lock for more than 1 second. This lock
+        // is currently used to make sure the alert reminder tone and vibration could be played
+        // properly in timely manner.
+        acquirePartialWakeLock(context, MAX_PARTIAL_WAKELOCK_DURATION);
+    }
+
+    static void acquirePartialWakeLock(Context context, long timeout) {
         if (sPartialWakeLock == null) {
             PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
             sPartialWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
         }
 
         if (!sPartialWakeLock.isHeld()) {
-            // Make sure we don't acquire the partial lock for more than 1 second. This lock
-            // is currently used to make sure the alert reminder tone and vibration could be played
-            // properly in timely manner.
-            sPartialWakeLock.acquire(1000);
+            sPartialWakeLock.acquire(timeout);
             Log.d(TAG, "acquired partial wakelock");
         }
     }
@@ -55,6 +62,13 @@
     }
 
     static void acquireScreenBrightWakeLock(Context context) {
+        // Make sure we don't acquire the full lock for more than 5 minutes. This lock
+        // is currently used by the main alert tone playing. Normally we hold the lock while
+        // the audio is playing for about 10 ~ 20 seconds.
+        acquireScreenBrightWakeLock(context, MAX_SCREEN_BRIGHT_WAKELOCK_DURATION);
+    }
+
+    static void acquireScreenBrightWakeLock(Context context, long timeout) {
         if (sScreenBrightWakeLock == null) {
             PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
             sScreenBrightWakeLock = pm.newWakeLock(
@@ -62,10 +76,7 @@
         }
 
         if (!sScreenBrightWakeLock.isHeld()) {
-            // Make sure we don't acquire the full lock for more than 5 minutes. This lock
-            // is currently used by the main alert tone playing. Normally we hold the lock while
-            // the audio is playing for about 10 ~ 20 seconds.
-            sScreenBrightWakeLock.acquire(1000 * 60 * 5);
+            sScreenBrightWakeLock.acquire(timeout);
             Log.d(TAG, "acquired screen bright wakelock");
         }
     }