Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor: Port Environment.isExternalStorageManager (Android) #1218

Merged
merged 1 commit into from
Nov 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.baseflow.permissionhandler;

import android.os.Build;
import android.os.Environment;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;

import com.baseflow.instancemanager.InstanceManager;
import com.baseflow.permissionhandler.PermissionHandlerPigeon.EnvironmentHostApi;

import io.flutter.plugin.common.BinaryMessenger;

/**
* Host API implementation for `Environment`.
*
* <p>This class may handle instantiating and adding native object instances that are attached to a
* Dart instance or handle method calls on the associated native class or an instance of the class.
*/
public class EnvironmentHostApiImpl implements EnvironmentHostApi {
// To ease adding additional methods, this value is added prematurely.
@SuppressWarnings({"unused", "FieldCanBeLocal"})
private final BinaryMessenger binaryMessenger;

// To ease adding additional methods, this value is added prematurely.
@SuppressWarnings({"unused", "FieldCanBeLocal"})
private final InstanceManager instanceManager;

/**
* Constructs an {@link EnvironmentHostApiImpl}.
*
* @param binaryMessenger used to communicate with Dart over asynchronous messages
* @param instanceManager maintains instances stored to communicate with attached Dart objects
*/
public EnvironmentHostApiImpl(
@NonNull BinaryMessenger binaryMessenger,
@NonNull InstanceManager instanceManager
) {
this.binaryMessenger = binaryMessenger;
this.instanceManager = instanceManager;
}

@RequiresApi(api = Build.VERSION_CODES.R)
@NonNull
@Override
public Boolean isExternalStorageManager() {
return Environment.isExternalStorageManager();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1516,4 +1516,58 @@ public void dispose(@NonNull String instanceIdArg, @NonNull Reply<Void> callback
channelReply -> callback.reply(null));
}
}
/**
* Host API for `Environment`.
*
* This class may handle instantiating and adding native object instances that
* are attached to a Dart instance or handle method calls on the associated
* native class or an instance of the class.
*
* See https://developer.android.com/reference/android/os/Environment.
*
* Generated interface from Pigeon that represents a handler of messages from Flutter.
*/
public interface EnvironmentHostApi {
/**
* Returns whether the calling app has All Files Access on the primary shared/external storage media.
*
* Declaring the permission [Manifest.permission.manageExternalStorage] is
* not enough to gain the access. To request access, use
* [Settings.actionManageAppAllFilesAccessPermission].
*
* See https://developer.android.com/reference/android/os/Environment#isExternalStorageManager().
*/
@NonNull
Boolean isExternalStorageManager();

/** The codec used by EnvironmentHostApi. */
static @NonNull MessageCodec<Object> getCodec() {
return new StandardMessageCodec();
}
/**Sets up an instance of `EnvironmentHostApi` to handle messages through the `binaryMessenger`. */
static void setup(@NonNull BinaryMessenger binaryMessenger, @Nullable EnvironmentHostApi api) {
{
BasicMessageChannel<Object> channel =
new BasicMessageChannel<>(
binaryMessenger, "dev.flutter.pigeon.permission_handler_android.EnvironmentHostApi.isExternalStorageManager", getCodec());
if (api != null) {
channel.setMessageHandler(
(message, reply) -> {
ArrayList<Object> wrapped = new ArrayList<Object>();
try {
Boolean output = api.isExternalStorageManager();
wrapped.add(0, output);
}
catch (Throwable exception) {
ArrayList<Object> wrappedError = wrapError(exception);
wrapped = wrappedError;
}
reply.reply(wrapped);
});
} else {
channel.setMessageHandler(null);
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import com.baseflow.permissionhandler.PermissionHandlerPigeon.AlarmManagerHostApi;
import com.baseflow.permissionhandler.PermissionHandlerPigeon.BuildVersionHostApi;
import com.baseflow.permissionhandler.PermissionHandlerPigeon.ContextHostApi;
import com.baseflow.permissionhandler.PermissionHandlerPigeon.EnvironmentHostApi;
import com.baseflow.permissionhandler.PermissionHandlerPigeon.IntentHostApi;
import com.baseflow.permissionhandler.PermissionHandlerPigeon.NotificationManagerHostApi;
import com.baseflow.permissionhandler.PermissionHandlerPigeon.PackageManagerHostApi;
Expand Down Expand Up @@ -81,6 +82,9 @@ private void setUp(
final NotificationManagerHostApi notificationManagerHostApi = new NotificationManagerHostApiImpl(binaryMessenger, instanceManager);
NotificationManagerHostApi.setup(binaryMessenger, notificationManagerHostApi);

final EnvironmentHostApi environmentHostApi = new EnvironmentHostApiImpl(binaryMessenger, instanceManager);
EnvironmentHostApi.setup(binaryMessenger, environmentHostApi);

activityFlutterApi = new ActivityFlutterApiImpl(binaryMessenger, instanceManager);
activityHostApi = new ActivityHostApiImpl(
binaryMessenger,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export 'src/android_object_mirrors/activity.dart';
export 'src/android_object_mirrors/alarm_manager.dart';
export 'src/android_object_mirrors/build.dart';
export 'src/android_object_mirrors/context.dart';
export 'src/android_object_mirrors/environment.dart';
export 'src/android_object_mirrors/intent.dart';
export 'src/android_object_mirrors/manifest.dart';
export 'src/android_object_mirrors/notification_manager.dart';
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import '../permission_handler.pigeon.dart';

/// Provides access to environment variables.
///
/// See https://developer.android.com/reference/android/os/Environment.
class Environment {
const Environment._();

static final EnvironmentHostApi _hostApi = EnvironmentHostApi();

/// Returns whether the calling app has All Files Access on the primary shared/external storage media.
///
/// Declaring the permission [Manifest.permission.manageExternalStorage] is
/// not enough to gain the access. To request access, use
/// [Settings.actionManageAppAllFilesAccessPermission].
///
/// See https://developer.android.com/reference/android/os/Environment#isExternalStorageManager().
static Future<bool> isExternalStorageManager() {
return _hostApi.isExternalStorageManager();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -730,3 +730,22 @@ class NotificationManagerFlutterApiImpl extends NotificationManagerFlutterApi {
_instanceManager.remove(instanceId);
}
}

/// Host API implementation of Environment.
class EnvironmentHostApiImpl extends EnvironmentHostApi {
/// Creates a new instance of [EnvironmentHostApiImpl].
EnvironmentHostApiImpl({
this.binaryMessenger,
InstanceManager? instanceManager,
}) : instanceManager = instanceManager ?? JavaObject.globalInstanceManager,
super(binaryMessenger: binaryMessenger);

/// Sends binary data across the Flutter platform barrier.
///
/// If it is null, the default BinaryMessenger will be used which routes to
/// the host platform.
final BinaryMessenger? binaryMessenger;

/// Maintains instances stored to communicate with native language objects.
final InstanceManager instanceManager;
}
52 changes: 52 additions & 0 deletions permission_handler_android/lib/src/permission_handler.pigeon.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1347,3 +1347,55 @@ abstract class NotificationManagerFlutterApi {
}
}
}

/// Host API for `Environment`.
///
/// This class may handle instantiating and adding native object instances that
/// are attached to a Dart instance or handle method calls on the associated
/// native class or an instance of the class.
///
/// See https://developer.android.com/reference/android/os/Environment.
class EnvironmentHostApi {
/// Constructor for [EnvironmentHostApi]. The [binaryMessenger] named argument is
/// available for dependency injection. If it is left null, the default
/// BinaryMessenger will be used which routes to the host platform.
EnvironmentHostApi({BinaryMessenger? binaryMessenger})
: _binaryMessenger = binaryMessenger;
final BinaryMessenger? _binaryMessenger;

static const MessageCodec<Object?> codec = StandardMessageCodec();

/// Returns whether the calling app has All Files Access on the primary shared/external storage media.
///
/// Declaring the permission [Manifest.permission.manageExternalStorage] is
/// not enough to gain the access. To request access, use
/// [Settings.actionManageAppAllFilesAccessPermission].
///
/// See https://developer.android.com/reference/android/os/Environment#isExternalStorageManager().
Future<bool> isExternalStorageManager() async {
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.permission_handler_android.EnvironmentHostApi.isExternalStorageManager',
codec,
binaryMessenger: _binaryMessenger);
final List<Object?>? replyList = await channel.send(null) as List<Object?>?;
if (replyList == null) {
throw PlatformException(
code: 'channel-error',
message: 'Unable to establish connection on channel.',
);
} else if (replyList.length > 1) {
throw PlatformException(
code: replyList[0]! as String,
message: replyList[1] as String?,
details: replyList[2],
);
} else if (replyList[0] == null) {
throw PlatformException(
code: 'null-error',
message: 'Host platform returned null value for non-null return value.',
);
} else {
return (replyList[0] as bool?)!;
}
}
}
19 changes: 19 additions & 0 deletions permission_handler_android/pigeons/android_permission_handler.dart
Original file line number Diff line number Diff line change
Expand Up @@ -449,3 +449,22 @@ abstract class NotificationManagerFlutterApi {
/// Dispose of the Dart instance and remove it from the `InstanceManager`.
void dispose(String instanceId);
}

/// Host API for `Environment`.
///
/// This class may handle instantiating and adding native object instances that
/// are attached to a Dart instance or handle method calls on the associated
/// native class or an instance of the class.
///
/// See https://developer.android.com/reference/android/os/Environment.
@HostApi(dartHostTestHandler: 'EnvironmentTestHostApi')
abstract class EnvironmentHostApi {
/// Returns whether the calling app has All Files Access on the primary shared/external storage media.
///
/// Declaring the permission [Manifest.permission.manageExternalStorage] is
/// not enough to gain the access. To request access, use
/// [Settings.actionManageAppAllFilesAccessPermission].
///
/// See https://developer.android.com/reference/android/os/Environment#isExternalStorageManager().
bool isExternalStorageManager();
}
Original file line number Diff line number Diff line change
Expand Up @@ -909,3 +909,47 @@ abstract class NotificationManagerTestHostApi {
}
}
}

/// Host API for `Environment`.
///
/// This class may handle instantiating and adding native object instances that
/// are attached to a Dart instance or handle method calls on the associated
/// native class or an instance of the class.
///
/// See https://developer.android.com/reference/android/os/Environment.
abstract class EnvironmentTestHostApi {
static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding =>
TestDefaultBinaryMessengerBinding.instance;
static const MessageCodec<Object?> codec = StandardMessageCodec();

/// Returns whether the calling app has All Files Access on the primary shared/external storage media.
///
/// Declaring the permission [Manifest.permission.manageExternalStorage] is
/// not enough to gain the access. To request access, use
/// [Settings.actionManageAppAllFilesAccessPermission].
///
/// See https://developer.android.com/reference/android/os/Environment#isExternalStorageManager().
bool isExternalStorageManager();

static void setup(EnvironmentTestHostApi? api,
{BinaryMessenger? binaryMessenger}) {
{
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.permission_handler_android.EnvironmentHostApi.isExternalStorageManager',
codec,
binaryMessenger: binaryMessenger);
if (api == null) {
_testBinaryMessengerBinding!.defaultBinaryMessenger
.setMockDecodedMessageHandler<Object?>(channel, null);
} else {
_testBinaryMessengerBinding!.defaultBinaryMessenger
.setMockDecodedMessageHandler<Object?>(channel,
(Object? message) async {
// ignore message
final bool output = api.isExternalStorageManager();
return <Object?>[output];
});
}
}
}
}
Loading