Skip to content
Merged
Show file tree
Hide file tree
Changes from 13 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
4 changes: 4 additions & 0 deletions packages/camera/camera_android/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.10.9+14

* Converts native to dart platform class to Pigeon.

## 0.10.9+13

* Converts `getAvailableCameras` to Pigeon.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
import android.hardware.camera2.CameraMetadata;
import androidx.annotation.NonNull;
import io.flutter.embedding.engine.systemchannels.PlatformChannel;
import io.flutter.plugins.camera.features.autofocus.FocusMode;
import io.flutter.plugins.camera.features.exposurelock.ExposureMode;
import java.util.ArrayList;
import java.util.List;

Expand Down Expand Up @@ -143,4 +145,62 @@ public static List<Messages.PlatformCameraDescription> getAvailableCameras(
}
return cameras;
}

/**
* Converts a DeviceOrientation from the systemchannels package to a PlatformDeviceOrientation
* from Pigeon.
*
* @param orientation A DeviceOrientation.
* @return The corresponding PlatformDeviceOrientation.
*/
@NonNull
public static Messages.PlatformDeviceOrientation orientationToPigeon(
@NonNull PlatformChannel.DeviceOrientation orientation) {
switch (orientation) {
case PORTRAIT_UP:
return Messages.PlatformDeviceOrientation.PORTRAIT_UP;
case PORTRAIT_DOWN:
return Messages.PlatformDeviceOrientation.PORTRAIT_DOWN;
case LANDSCAPE_LEFT:
return Messages.PlatformDeviceOrientation.LANDSCAPE_LEFT;
case LANDSCAPE_RIGHT:
return Messages.PlatformDeviceOrientation.LANDSCAPE_RIGHT;
}
return Messages.PlatformDeviceOrientation.PORTRAIT_UP;
}

/**
* Converts a FocusMode from the autofocus package to a PlatformFocusMode from Pigeon.
*
* @param focusMode A FocusMode.
* @return The corresponding PlatformFocusMode.
*/
@NonNull
public static Messages.PlatformFocusMode focusModeToPigeon(@NonNull FocusMode focusMode) {
switch (focusMode) {
case auto:
return Messages.PlatformFocusMode.AUTO;
case locked:
return Messages.PlatformFocusMode.LOCKED;
}
return Messages.PlatformFocusMode.AUTO;
}

/**
* Converts an ExposureMode from the exposurelock package to a PlatformExposureMode from Pigeon.
*
* @param exposureMode An ExposureMode.
* @return The corresponding PlatformExposureMode.
*/
@NonNull
public static Messages.PlatformExposureMode exposureModeToPigeon(
@NonNull ExposureMode exposureMode) {
switch (exposureMode) {
case auto:
return Messages.PlatformExposureMode.AUTO;
case locked:
return Messages.PlatformExposureMode.LOCKED;
}
return Messages.PlatformExposureMode.AUTO;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,69 +5,36 @@
package io.flutter.plugins.camera;

import android.os.Handler;
import android.text.TextUtils;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import io.flutter.embedding.engine.systemchannels.PlatformChannel;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugins.camera.features.autofocus.FocusMode;
import io.flutter.plugins.camera.features.exposurelock.ExposureMode;
import java.util.HashMap;
import java.util.Map;

/** Utility class that facilitates communication to the Flutter client */
public class DartMessenger {
@NonNull private final Handler handler;
@Nullable MethodChannel cameraChannel;
@Nullable MethodChannel deviceChannel;

/** Specifies the different device related message types. */
enum DeviceEventType {
/** Indicates the device's orientation has changed. */
ORIENTATION_CHANGED("orientation_changed");
final String method;

DeviceEventType(String method) {
this.method = method;
}
}

/** Specifies the different camera related message types. */
enum CameraEventType {
/** Indicates that an error occurred while interacting with the camera. */
ERROR("error"),
/** Indicates that the camera is closing. */
CLOSING("camera_closing"),
/** Indicates that the camera is initialized. */
INITIALIZED("initialized");

final String method;

/**
* Converts the supplied method name to the matching {@link CameraEventType}.
*
* @param method name to be converted into a {@link CameraEventType}.
*/
CameraEventType(String method) {
this.method = method;
}
}
Messages.CameraGlobalEventApi globalEventApi;
Messages.CameraEventApi eventApi;

/**
* Creates a new instance of the {@link DartMessenger} class.
*
* @param messenger is the {@link BinaryMessenger} that is used to communicate with Flutter.
* @param cameraId identifies the camera which is the source of the communication.
* @param handler the handler used to manage the thread's message queue. This should always be a
* handler managing the main thread since communication with Flutter should always happen on
* the main thread. The handler is mainly supplied so it will be easier test this class.
* @param globalEventApi the API used to consume calls to dart that are not tied to a specific
* camera instance.
* @param eventApi the API used to consume calls to dart that are tied to this specific camera.
*/
DartMessenger(BinaryMessenger messenger, long cameraId, @NonNull Handler handler) {
cameraChannel =
new MethodChannel(messenger, "plugins.flutter.io/camera_android/camera" + cameraId);
deviceChannel = new MethodChannel(messenger, "plugins.flutter.io/camera_android/fromPlatform");
DartMessenger(
@NonNull Handler handler,
Messages.CameraGlobalEventApi globalEventApi,
Messages.CameraEventApi eventApi) {
this.handler = handler;
this.globalEventApi = globalEventApi;
this.eventApi = eventApi;
}

/**
Expand All @@ -77,13 +44,17 @@ enum CameraEventType {
*/
public void sendDeviceOrientationChangeEvent(
@NonNull PlatformChannel.DeviceOrientation orientation) {
this.send(
DeviceEventType.ORIENTATION_CHANGED,
new HashMap<String, Object>() {
{
put("orientation", CameraUtils.serializeDeviceOrientation(orientation));
}
});
handler.post(
() ->
globalEventApi.deviceOrientationChanged(
CameraUtils.orientationToPigeon(orientation),
new Messages.VoidResult() {
@Override
public void success() {}

@Override
public void error(@NonNull Throwable error) {}
}));
}

/**
Expand All @@ -109,23 +80,41 @@ void sendCameraInitializedEvent(
assert (focusMode != null);
assert (exposurePointSupported != null);
assert (focusPointSupported != null);
this.send(
CameraEventType.INITIALIZED,
new HashMap<String, Object>() {
{
put("previewWidth", previewWidth.doubleValue());
put("previewHeight", previewHeight.doubleValue());
put("exposureMode", exposureMode.toString());
put("focusMode", focusMode.toString());
put("exposurePointSupported", exposurePointSupported);
put("focusPointSupported", focusPointSupported);
}
});
handler.post(
() ->
eventApi.initialized(
new Messages.PlatformCameraState.Builder()
.setPreviewSize(
new Messages.PlatformSize.Builder()
.setWidth(previewWidth.doubleValue())
.setHeight(previewHeight.doubleValue())
.build())
.setExposurePointSupported(exposurePointSupported)
.setFocusPointSupported(focusPointSupported)
.setExposureMode(CameraUtils.exposureModeToPigeon(exposureMode))
.setFocusMode(CameraUtils.focusModeToPigeon(focusMode))
.build(),
new Messages.VoidResult() {
@Override
public void success() {}

@Override
public void error(@NonNull Throwable error) {}
}));
}

/** Sends a message to the Flutter client informing that the camera is closing. */
void sendCameraClosingEvent() {
send(CameraEventType.CLOSING);
handler.post(
() ->
eventApi.closed(
new Messages.VoidResult() {
@Override
public void success() {}

@Override
public void error(@NonNull Throwable error) {}
}));
}

/**
Expand All @@ -135,43 +124,17 @@ void sendCameraClosingEvent() {
* @param description contains details regarding the error that occurred.
*/
void sendCameraErrorEvent(@Nullable String description) {
this.send(
CameraEventType.ERROR,
new HashMap<String, Object>() {
{
if (!TextUtils.isEmpty(description)) put("description", description);
}
});
}

private void send(CameraEventType eventType) {
send(eventType, new HashMap<>());
}

private void send(CameraEventType eventType, Map<String, Object> args) {
if (cameraChannel == null) {
return;
}

handler.post(
new Runnable() {
@Override
public void run() {
cameraChannel.invokeMethod(eventType.method, args);
}
});
}

private void send(DeviceEventType eventType) {
send(eventType, new HashMap<>());
}

private void send(DeviceEventType eventType, Map<String, Object> args) {
if (deviceChannel == null) {
return;
}

handler.post(() -> deviceChannel.invokeMethod(eventType.method, args));
() ->
eventApi.error(
description,
new Messages.VoidResult() {
@Override
public void success() {}

@Override
public void error(@NonNull Throwable error) {}
}));
}

/**
Expand Down
Loading