Failure of Shutdown Alarm Clock after Presetting GMS Package on Android Platform and Its Solution

  • 2021-12-05 07:33:39
  • OfStack

1. Introduction

Shutdown alarm clock is a function supported by default in Android, and it needs to meet 1 certain conditions: automatic startup and ringing after startup. For automatic startup, automatic shutdown can be realized by setting alarm in the application layer, and automatic startup needs the support of the underlying rtc clock; Check the time after starting up, and ring at the point.

2. Principle

The hardware architecture of a smart phone is divided into three parts: RF, BB and AP. The function of the RF part of RF is mainly to receive and transmit RF, so you don't have to pay attention to this. The AP part is the application processor, which is actually the CPU module; The BB part is the baseband module. Usually, when the mobile phone is turned off, the AP module is completely powered off, while the BB is turned off, but in fact, the alarm clock and time part are not powered off. When the set alarm clock reaches the point, the BB module will automatically power up the AP module, so that the system can start up and activate the alarm clock function.

3. Process

After setting an alarm clock with proper time and effective ringing, send the broadcast of setting shutdown alarm clock to PowerOffAlarm and pass in the alarm clock time parameters. After receiving the broadcast, PowerOffAlarm writes the time to rtc according to the preset early startup time and alarm clock time, and writes the time into a file for temporary storage.
After setting the alarm clock, the machine will be turned on according to the time parameters of alrm_time in rtc. After starting up, AlarmManagerService will check the alarm clock and pop up the bell interface after sending a broadcast at the alarm clock time.
After clicking off the alarm clock, it will send a broadcast to cancel the shutdown alarm clock. PowerOffAlarm will compare the incoming time with the temporary time, and if it is the same, it will cancel the shutdown alarm clock.

4. Problems encountered and solutions

4.1 Shutdown alarm clock fails after GMS package is preset

After comparing the platform alarm clock analysis, it is found that Google alarm clock did not send a broadcast to PowerOffAlarm after setting the alarm clock, but Google alarm clock could not be modified.
After analyzing the alarm clock setting steps of the platform, it is found that the method AlarmManager. setAlarmClock () will be called after setting the alarm clock, and then the broadcast of setting the shutdown alarm clock will be sent in updateNextAlarm method of AlarmStateManager.
Google Alarm Clock will also call AlarmManager. setAlarmClock () when setting the alarm clock, so it will send broadcast directly to PowerOffAlarm in this method.


@@ -615,8 +633,34 @@ public class AlarmManager {
  public void setAlarmClock(AlarmClockInfo info, PendingIntent operation) {
   setImpl(RTC_WAKEUP, info.getTriggerTime(), WINDOW_EXACT, 0, 0, operation,
     null, null, null, null, info);
+  setPowerOffAlarm(mContext,info.getTriggerTime());
  }
 
+
+ /*add by hxj at Aug.6,for PowerOffAlarm*/
+ private void setPowerOffAlarm(Context context, long time) {
+  Log.d(TAG, "setPowerOffAlarm: saveAlarmToPreference and sendBroadcast to setPowerOffAlarm,the time is "+time);
+  DEFAULT_ALARM_TIME = time;
+  Intent intent = new Intent(ACTION_SET_POWEROFF_ALARM);
+  intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+  intent.setPackage(POWER_OFF_ALARM_PACKAGE);
+  intent.putExtra(TIME, time);
+  context.sendBroadcast(intent);
+ }
+
+ private void cancelPowerOffAlarm(Context context) {
+  //long time = getAlarmFromPreference(context);
+  Log.d(TAG, "cancelPowerOffAlarm: cancel alarm and cancelPowerOffAlarm(mContext),time is "+DEFAULT_ALARM_TIME );
+  Intent intent = new Intent(ACTION_CANCEL_POWEROFF_ALARM);
+  intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+  intent.putExtra(TIME, DEFAULT_ALARM_TIME);
+  intent.setPackage(POWER_OFF_ALARM_PACKAGE);
+  context.sendBroadcast(intent);
+  DEFAULT_ALARM_TIME = 0L;
+ }
+
+
  /** @hide */
  @SystemApi
  @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS)
@@ -930,6 +974,7 @@ public class AlarmManager {
 
   try {
    mService.remove(operation, null);
+   cancelPowerOffAlarm(mContext);
   } catch (RemoteException ex) {
    throw ex.rethrowFromSystemServer();
   }

4.2 PowerOffAlarm cannot receive broadcast

After analyzing log, it is found that accepting this broadcast requires adding a specific permission in the application, that is, "org. codeaurora. permission. POWER_OFF_ALARM" permission. However, because it is not added in Google Alarm Clock and cannot be modified, this permission is removed from the receiving tube broadcast in PowerOffAlarm.


@@ -29,7 +29,7 @@
   android:defaultToDeviceProtectedStorage="true">
 
   <receiver android:name=".PowerOffAlarmBroadcastReceiver"
-   android:permission="org.codeaurora.permission.POWER_OFF_ALARM"
+
    android:exported="true"
    android:directBootAware="true"
    android:label="PowerOffAlarmBroadcastReceiver">

4.3 The alarm clock expires after startup due to too long startup time

Early boot time platform default to 90,000 milliseconds, the project boot time is longer, so increase boot time, changed to 150,000 milliseconds.


@@ -42,7 +42,7 @@ public class PowerOffAlarmUtils {
 
  private static final int FAILURE = -1;
 
- public static final long MS_IN_ONE_MIN = 90000L;
+ public static final long MS_IN_ONE_MIN = 150000L;
 
  private static final long SEC_TO_MS = 1000L;

In addition, there are other problems that will lead to the failure of the shutdown alarm clock. If you have time, record it again.

Summarize


Related articles: