[android_alarm_manager] Migrated android_alarm_manager to support null safety #75233 (#3499)

Migrated android_alarm_manager to support null safety.

Fixes flutter/flutter#75233
diff --git a/packages/android_alarm_manager/CHANGELOG.md b/packages/android_alarm_manager/CHANGELOG.md
index df5b7a2..b06f23c 100644
--- a/packages/android_alarm_manager/CHANGELOG.md
+++ b/packages/android_alarm_manager/CHANGELOG.md
@@ -1,3 +1,7 @@
+##  2.0.0-nullsafety
+
+* Migrate to null safety.
+
 ## 0.4.5+20
 
 * Update the example app: remove the deprecated `RaisedButton` and `FlatButton` widgets.
diff --git a/packages/android_alarm_manager/README.md b/packages/android_alarm_manager/README.md
index cf02bf6..5a8a55e 100644
--- a/packages/android_alarm_manager/README.md
+++ b/packages/android_alarm_manager/README.md
@@ -5,13 +5,6 @@
 A Flutter plugin for accessing the Android AlarmManager service, and running
 Dart code in the background when alarms fire.
 
-**Please set your constraint to `android_alarm_manager: '>=0.4.y+x <2.0.0'`**
-
-## Backward compatible 1.0.0 version is coming
-The plugin has reached a stable API, we guarantee that version `1.0.0` will be backward compatible with `0.4.y+z`.
-Please use `android_alarm_manager: '>=0.4.y+x <2.0.0'` as your dependency constraint to allow a smoother ecosystem migration.
-For more details see: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0
-
 ## Getting Started
 
 After importing this plugin to your project as usual, add the following to your
@@ -109,17 +102,12 @@
 **Note:** Not calling `AlarmService.setPluginRegistrant` will result in an exception being
 thrown when an alarm eventually fires.
 
-### Flutter Android Embedding V2 (Flutter Version >= 1.12)
+### Flutter Android Embedding V2
 
 For the Flutter Android Embedding V2, plugins are registered with the background
 isolate via reflection so `AlarmService.setPluginRegistrant` does not need to be
 called.
 
-**NOTE: this plugin is not completely compatible with the V2 embedding on
-Flutter versions < 1.12 as the background isolate will not automatically
-register plugins. This can be resolved by running `flutter upgrade` to upgrade
-to the latest Flutter version.**
-
 For help getting started with Flutter, view our online
 [documentation](https://flutter.dev/).
 
diff --git a/packages/android_alarm_manager/example/integration_test/android_alarm_manager_test.dart b/packages/android_alarm_manager/example/integration_test/android_alarm_manager_test.dart
index 4d2e320..4d53a5a 100644
--- a/packages/android_alarm_manager/example/integration_test/android_alarm_manager_test.dart
+++ b/packages/android_alarm_manager/example/integration_test/android_alarm_manager_test.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+// @dart=2.9
+
 import 'dart:async';
 import 'dart:io';
 import 'package:android_alarm_manager_example/main.dart' as app;
diff --git a/packages/android_alarm_manager/example/lib/main.dart b/packages/android_alarm_manager/example/lib/main.dart
index ac27fec..dc3779c 100644
--- a/packages/android_alarm_manager/example/lib/main.dart
+++ b/packages/android_alarm_manager/example/lib/main.dart
@@ -22,7 +22,7 @@
 final ReceivePort port = ReceivePort();
 
 /// Global [SharedPreferences] object.
-SharedPreferences prefs;
+late SharedPreferences prefs;
 
 Future<void> main() async {
   // TODO(bkonyi): uncomment
@@ -54,7 +54,7 @@
 }
 
 class _AlarmHomePage extends StatefulWidget {
-  _AlarmHomePage({Key key, this.title}) : super(key: key);
+  _AlarmHomePage({Key? key, required this.title}) : super(key: key);
   final String title;
 
   @override
@@ -86,7 +86,7 @@
   }
 
   // The background
-  static SendPort uiSendPort;
+  static SendPort? uiSendPort;
 
   // The callback for our alarm
   static Future<void> callback() async {
@@ -94,7 +94,7 @@
 
     // Get the previous cached count and increment it.
     final prefs = await SharedPreferences.getInstance();
-    int currentCount = prefs.getInt(countKey);
+    int currentCount = prefs.getInt(countKey) ?? 0;
     await prefs.setInt(countKey, currentCount + 1);
 
     // This will be null if we're running in the background.
@@ -140,7 +140,7 @@
                 await AndroidAlarmManager.oneShot(
                   const Duration(seconds: 5),
                   // Ensure we have a unique alarm ID.
-                  Random().nextInt(pow(2, 31)),
+                  Random().nextInt(pow(2, 31).toInt()),
                   callback,
                   exact: true,
                   wakeup: true,
diff --git a/packages/android_alarm_manager/example/pubspec.yaml b/packages/android_alarm_manager/example/pubspec.yaml
index 6fce346..029a604 100644
--- a/packages/android_alarm_manager/example/pubspec.yaml
+++ b/packages/android_alarm_manager/example/pubspec.yaml
@@ -11,10 +11,10 @@
     # The example app is bundled with the plugin so we use a path dependency on
     # the parent directory to use the current plugin's version.
     path: ../
-  shared_preferences: ^0.5.6
+  shared_preferences: ^2.0.0-nullsafety
   integration_test:
     path: ../../integration_test
-  path_provider: ^1.3.1
+  path_provider: ^2.0.0-nullsafety
 
 dev_dependencies:
   espresso: ^0.0.1+3
@@ -28,5 +28,5 @@
   uses-material-design: true
 
 environment:
-  sdk: ">=2.1.0 <3.0.0"
+  sdk: '>=2.12.0-0 <3.0.0'
   flutter: ">=1.12.13+hotfix.5"
diff --git a/packages/android_alarm_manager/example/test_driver/integration_test.dart b/packages/android_alarm_manager/example/test_driver/integration_test.dart
index ed54518..4e78d04 100644
--- a/packages/android_alarm_manager/example/test_driver/integration_test.dart
+++ b/packages/android_alarm_manager/example/test_driver/integration_test.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+// @dart=2.9
+
 import 'dart:async';
 import 'dart:convert';
 import 'dart:io';
diff --git a/packages/android_alarm_manager/lib/android_alarm_manager.dart b/packages/android_alarm_manager/lib/android_alarm_manager.dart
index b8afa13..218959b 100644
--- a/packages/android_alarm_manager/lib/android_alarm_manager.dart
+++ b/packages/android_alarm_manager/lib/android_alarm_manager.dart
@@ -31,7 +31,7 @@
 
     // PluginUtilities.getCallbackFromHandle performs a lookup based on the
     // callback handle and returns a tear-off of the original callback.
-    final Function closure = PluginUtilities.getCallbackFromHandle(handle);
+    final Function? closure = PluginUtilities.getCallbackFromHandle(handle);
 
     if (closure == null) {
       print('Fatal: could not find callback');
@@ -56,7 +56,7 @@
 // A lambda that returns the current instant in the form of a [DateTime].
 typedef DateTime _Now();
 // A lambda that gets the handle for the given [callback].
-typedef CallbackHandle _GetCallbackHandle(Function callback);
+typedef CallbackHandle? _GetCallbackHandle(Function callback);
 
 /// A Flutter plugin for registering Dart callbacks with the Android
 /// AlarmManager service.
@@ -77,7 +77,7 @@
   /// the plugin.
   @visibleForTesting
   static void setTestOverides(
-      {_Now now, _GetCallbackHandle getCallbackHandle}) {
+      {_Now? now, _GetCallbackHandle? getCallbackHandle}) {
     _now = (now ?? _now);
     _getCallbackHandle = (getCallbackHandle ?? _getCallbackHandle);
   }
@@ -88,12 +88,12 @@
   /// Returns a [Future] that resolves to `true` on success and `false` on
   /// failure.
   static Future<bool> initialize() async {
-    final CallbackHandle handle =
+    final CallbackHandle? handle =
         _getCallbackHandle(_alarmManagerCallbackDispatcher);
     if (handle == null) {
       return false;
     }
-    final bool r = await _channel.invokeMethod<bool>(
+    final bool? r = await _channel.invokeMethod<bool>(
         'AlarmService.start', <dynamic>[handle.toRawHandle()]);
     return r ?? false;
   }
@@ -207,11 +207,11 @@
     assert(callback is Function() || callback is Function(int));
     assert(id.bitLength < 32);
     final int startMillis = time.millisecondsSinceEpoch;
-    final CallbackHandle handle = _getCallbackHandle(callback);
+    final CallbackHandle? handle = _getCallbackHandle(callback);
     if (handle == null) {
       return false;
     }
-    final bool r =
+    final bool? r =
         await _channel.invokeMethod<bool>('Alarm.oneShotAt', <dynamic>[
       id,
       alarmClock,
@@ -222,7 +222,7 @@
       rescheduleOnReboot,
       handle.toRawHandle(),
     ]);
-    return (r == null) ? false : r;
+    return r ?? false;
   }
 
   /// Schedules a repeating timer to run `callback` with period `duration`.
@@ -262,7 +262,7 @@
     Duration duration,
     int id,
     Function callback, {
-    DateTime startAt,
+    DateTime? startAt,
     bool exact = false,
     bool wakeup = false,
     bool rescheduleOnReboot = false,
@@ -274,11 +274,11 @@
     final int period = duration.inMilliseconds;
     final int first =
         startAt != null ? startAt.millisecondsSinceEpoch : now + period;
-    final CallbackHandle handle = _getCallbackHandle(callback);
+    final CallbackHandle? handle = _getCallbackHandle(callback);
     if (handle == null) {
       return false;
     }
-    final bool r = await _channel.invokeMethod<bool>(
+    final bool? r = await _channel.invokeMethod<bool>(
         'Alarm.periodic', <dynamic>[
       id,
       exact,
@@ -288,7 +288,7 @@
       rescheduleOnReboot,
       handle.toRawHandle()
     ]);
-    return (r == null) ? false : r;
+    return r ?? false;
   }
 
   /// Cancels a timer.
@@ -299,8 +299,8 @@
   /// Returns a [Future] that resolves to `true` on success and `false` on
   /// failure.
   static Future<bool> cancel(int id) async {
-    final bool r =
+    final bool? r =
         await _channel.invokeMethod<bool>('Alarm.cancel', <dynamic>[id]);
-    return (r == null) ? false : r;
+    return r ?? false;
   }
 }
diff --git a/packages/android_alarm_manager/pubspec.yaml b/packages/android_alarm_manager/pubspec.yaml
index d1771c0..ab19372 100644
--- a/packages/android_alarm_manager/pubspec.yaml
+++ b/packages/android_alarm_manager/pubspec.yaml
@@ -1,10 +1,7 @@
 name: android_alarm_manager
 description: Flutter plugin for accessing the Android AlarmManager service, and
   running Dart code in the background when alarms fire.
-# 0.4.y+z is compatible with 1.0.0, if you land a breaking change bump
-# the version to 2.0.0.
-# See more details: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0
-version: 0.4.5+20
+version: 2.0.0-nullsafety
 homepage: https://github.com/flutter/plugins/tree/master/packages/android_alarm_manager
 
 dependencies:
@@ -24,5 +21,5 @@
         pluginClass: AndroidAlarmManagerPlugin
 
 environment:
-  sdk: ">=2.1.0 <3.0.0"
+  sdk: '>=2.12.0-0 <3.0.0'
   flutter: ">=1.12.13+hotfix.5"
diff --git a/script/nnbd_plugins.sh b/script/nnbd_plugins.sh
index 492c8ad..5a54a7f 100644
--- a/script/nnbd_plugins.sh
+++ b/script/nnbd_plugins.sh
@@ -5,6 +5,7 @@
 # null-safe is available on stable.
 
 readonly NNBD_PLUGINS_LIST=(
+  "android_alarm_manager"
   "android_intent"
   "battery"
   "camera"
@@ -36,7 +37,6 @@
 # building the all plugins app. This list should be kept empty.
 
 readonly NON_NNBD_PLUGINS_LIST=(
-  # "android_alarm_manager"
   "camera"
   # "google_maps_flutter"
   # "image_picker"