Skip to content

Commit

Permalink
Move attachedActivity logic from mirror to PermissionHandlerAndroid
Browse files Browse the repository at this point in the history
  • Loading branch information
JeroenWeener committed Oct 13, 2023
1 parent 26fd5a8 commit d4b609a
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 35 deletions.
6 changes: 6 additions & 0 deletions permission_handler_android/example/lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import 'dart:async';

import 'package:baseflow_plugin_template/baseflow_plugin_template.dart';
import 'package:flutter/material.dart';
import 'package:permission_handler_android/permission_handler_android.dart';
import 'package:permission_handler_platform_interface/permission_handler_platform_interface.dart';

void main() {
Expand Down Expand Up @@ -132,6 +135,9 @@ class _PermissionState extends State<PermissionWidget> {
Future<void> requestPermission(Permission permission) async {
final status = await _permissionHandler.requestPermissions([permission]);

final a = PermissionHandlerAndroidMirror();
a.register(onAttachedToActivity: (_) => {});

setState(() {
print(status);
_permissionStatus = status[permission] ?? PermissionStatus.denied;
Expand Down
26 changes: 20 additions & 6 deletions permission_handler_android/lib/src/permission_handler_android.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,17 @@ import 'permission_handler_android_mirror.dart';
class PermissionHandlerAndroid extends PermissionHandlerPlatform {
PermissionHandlerAndroidMirror? _mirror;

/// The activity that Flutter is attached to.
///
/// Used for method invocation that require an activity or context.
Activity? _attachedActivity;

/// Allow overriding the attached activity for testing purposes.
@visibleForTesting
set attachedActivity(Activity? activity) {
_attachedActivity = activity;
}

@visibleForTesting
set mirror(PermissionHandlerAndroidMirror mirror) => _mirror = mirror;

Expand All @@ -20,14 +31,19 @@ class PermissionHandlerAndroid extends PermissionHandlerPlatform {
factory PermissionHandlerAndroid() {
final instance = PermissionHandlerAndroid._();
instance._mirror = PermissionHandlerAndroidMirror();
instance._mirror!.init();
instance._mirror!.register(
onAttachedToActivity: (Activity attachedActivity) {
instance._attachedActivity = attachedActivity;
},
);
return instance;
}

/// Registers this class as the default instance of [PermissionHandlerPlatform].
static void registerWith() {
PermissionHandlerPlatform.setInstanceBuilder(
() => PermissionHandlerAndroid());
() => PermissionHandlerAndroid(),
);
}

/// TODO(jweener): implement this method.
Expand All @@ -45,14 +61,12 @@ class PermissionHandlerAndroid extends PermissionHandlerPlatform {

@override
Future<bool> shouldShowRequestPermissionRationale(Permission permission) {
final Activity? attachedActivity = _mirror!.attachedActivity;

if (attachedActivity == null) {
if (_attachedActivity == null) {
throw Exception('There is no attached activity');
}

return ActivityCompat.shouldShowRequestPermissionRationale(
attachedActivity,
_attachedActivity!,
// TODO(jweener): replace with Android manifest name for permission once
// they have been ported over.
'android.permission.READ_CONTACTS',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:flutter/foundation.dart';
import 'package:flutter_instance_manager/flutter_instance_manager.dart';
import 'package:permission_handler_android/src/permission_handler.pigeon.dart';

import 'android_permission_handler_api_impls.dart';
Expand All @@ -11,40 +12,33 @@ import 'android_object_mirrors/activity.dart';
/// void main() {
/// // Initialize Android mirror APIs.
/// final PermissionHandlerAndroidMirror mirror = PermissionHandlerAndroidMirror();
/// mirror.init();
/// final Activity activity = mirror.register((Activity attachedActivity) => this.activity = attachedActivity);
/// }
///
/// void someMethod() {
/// activity.getSystemService(Context.LOCATION_SERVICE);
///
/// ActivityCompat.shouldShowRequestPermissionRationale(
/// mirror.attachedActivity,
/// activity,
/// 'permission_name',
/// );
/// }
/// ```
class PermissionHandlerAndroidMirror {
/// Mirror of the host activity that is needed for some function invocations.
Activity? _attachedActivity;

/// Allow overriding the attached activity for testing purposes.
@visibleForTesting
set attachedActivity(Activity? activity) {
_attachedActivity = activity;
}

/// Get the attached activity.
Activity? get attachedActivity => _attachedActivity;

/// Create a new instance of [PermissionHandlerAndroidMirror].
///
/// After constructing this instance, you must call [init] before using it.
PermissionHandlerAndroidMirror();

/// Initialize the Flutter APIs.
/// Initialize the Flutter APIs and get the activity that Flutter is attached
/// to via `onAttachedToActivity`.
///
/// This method is typically called right after constructing a new instance of
/// [PermissionHandlerAndroidMirror].
void init() {
void register({
required void Function(Activity attachedActivity) onAttachedToActivity,
@visibleForTesting InstanceManager? instanceManager,
}) {
final ActivityFlutterApi activityFlutterApi = ActivityFlutterApiImpl(
onAttachedToActivity: (Activity activity) => _attachedActivity = activity,
onAttachedToActivity: onAttachedToActivity,
instanceManager: instanceManager,
);

ActivityFlutterApi.setup(activityFlutterApi);
}
}
24 changes: 17 additions & 7 deletions permission_handler_android/test/permission_handler_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,8 @@ void main() {
group('PermissionHandlerAndroid', () {
test('shouldShowRequestPermissionRationale', () async {
// > Arrange
final InstanceManager instanceManager = InstanceManager(
onWeakReferenceRemoved: (_) {},
);

// Mock method channel on the native side.
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
.setMockMessageHandler(
'dev.flutter.pigeon.permission_handler_android.ActivityCompatHostApi.shouldShowRequestPermissionRationale',
Expand All @@ -69,18 +68,29 @@ void main() {
return codec.encodeMessage(response);
},
);

final InstanceManager instanceManager = InstanceManager(
onWeakReferenceRemoved: (_) {},
);

ActivityCompat.api =
ActivityCompatHostApiImpl(instanceManager: instanceManager);

final activity = Activity.detached();
instanceManager.addHostCreatedInstance(
activity,
'activity_instance_id',
);
ActivityCompat.api =
ActivityCompatHostApiImpl(instanceManager: instanceManager);

// Arrange permission handler.
final permissionHandler = PermissionHandlerAndroid();
final mirror = PermissionHandlerAndroidMirror();
mirror.init();
mirror.attachedActivity = activity;
mirror.register(
onAttachedToActivity: (Activity activity) {},
instanceManager: instanceManager,
);
permissionHandler.mirror = mirror;
permissionHandler.attachedActivity = activity;

// > Act
final shouldShowRequestPermissionRationale = await permissionHandler
Expand Down

0 comments on commit d4b609a

Please sign in to comment.