Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
475f4ab
Replicated existing code and migrated references to new embedding, ad…
matthew-carroll Sep 24, 2019
8cde03b
Introduced CameraPreviewDisplay and CameraImageStream to remove Flutt…
matthew-carroll Sep 24, 2019
2081f42
Introduced a CameraEventListener to completely decouple Camera from E…
matthew-carroll Sep 24, 2019
b78bfcb
Removed all references of Result from Camera by introducing a combina…
matthew-carroll Sep 24, 2019
b45ae68
Refactored Camera such that getFlutterTexture() no longer needs to ex…
matthew-carroll Sep 24, 2019
6780abf
Moved ResolutionPreset to standalone class and made Camera package pr…
matthew-carroll Sep 24, 2019
8b93f68
Re-organized Camera code order to clearly separate preview images, fr…
matthew-carroll Sep 24, 2019
c85fcc2
Removed Activity reference from Camera.
matthew-carroll Sep 24, 2019
e04653b
Refactored CameraPermissions to eliminate Activity, ActivityCompat, C…
matthew-carroll Sep 24, 2019
60c1d20
Refactored CameraPermissions into an Interface and AndroidCameraPermi…
matthew-carroll Sep 25, 2019
13e4303
Separated the CameraPlugin class from the concept of the comms Camera…
matthew-carroll Sep 25, 2019
d5da9ce
Introduced CameraDetails data structure & wrote unit tests for Camera…
matthew-carroll Sep 25, 2019
436d9ca
Added unit tests for CameraPluginProtocol and reached 100% coverage f…
matthew-carroll Sep 25, 2019
3dcc0ab
Moved CameraPreviewDisplay and CameraImageStream implementations into…
matthew-carroll Sep 26, 2019
02ab397
Extracted per-camera channel construction out into CameraPlugin for t…
matthew-carroll Sep 26, 2019
e5408d9
Refactored so that CameraSystem and AndroidCameraSystem could be redu…
matthew-carroll Sep 26, 2019
6ea1b4f
Deleted CameraUtils, and continued to cleanup relationships.
matthew-carroll Sep 26, 2019
4669cb4
Added tests for CameraSystem - at 93% line coverage.
matthew-carroll Sep 26, 2019
410d0ac
Added tests to ensure that CameraPlugin does nothing without an Activ…
matthew-carroll Sep 26, 2019
0bd6522
Added tests for ChannelCameraEventHandler - now at CameraSystem (93%)…
matthew-carroll Sep 26, 2019
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
Prev Previous commit
Next Next commit
Extracted per-camera channel construction out into CameraPlugin for t…
…esting purposes.
  • Loading branch information
matthew-carroll committed Sep 26, 2019
commit 02ab397780d9852e65fa8bfe76aec7ef4704ed6c
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

Expand All @@ -22,6 +21,9 @@
import io.flutter.plugin.common.EventChannel;
import io.flutter.view.TextureRegistry;

/**
* Android implementation of a {@link CameraSystem}.
*/
/* package */ class AndroidCameraSystem implements CameraSystem {
@NonNull
private final FlutterPlugin.FlutterPluginBinding pluginBinding;
Expand All @@ -31,19 +33,23 @@
private final CameraPermissions cameraPermissions;
@NonNull
private final CameraPreviewDisplay cameraPreviewDisplay;
@NonNull
private final CameraPluginProtocol.CameraEventChannelFactory cameraEventChannelFactory;
@Nullable
private Camera camera;

/* package */ AndroidCameraSystem(
@NonNull FlutterPlugin.FlutterPluginBinding pluginBinding,
@NonNull ActivityPluginBinding activityBinding,
@NonNull CameraPermissions cameraPermissions,
@NonNull CameraPreviewDisplay cameraPreviewDisplay
) {
@NonNull CameraPreviewDisplay cameraPreviewDisplay,
@NonNull CameraPluginProtocol.CameraEventChannelFactory cameraEventChannelFactory
) {
this.pluginBinding = pluginBinding;
this.activityBinding = activityBinding;
this.cameraPermissions = cameraPermissions;
this.cameraPreviewDisplay = cameraPreviewDisplay;
this.cameraEventChannelFactory = cameraEventChannelFactory;
}

@Override
Expand Down Expand Up @@ -118,36 +124,19 @@ public void onCameraOpenFailed(@NonNull String message) {
}
});

EventChannel cameraEventChannel = new EventChannel(
pluginBinding.getFlutterEngine().getDartExecutor(),
"flutter.io/cameraPlugin/cameraEvents" + textureEntry.id()
);
final CameraPluginProtocol.ChannelCameraEventHandler eventHandler = new CameraPluginProtocol.ChannelCameraEventHandler();
camera.setCameraEventHandler(eventHandler);

EventChannel cameraEventChannel = cameraEventChannelFactory.createCameraEventChannel(textureEntry.id());
cameraEventChannel.setStreamHandler(new EventChannel.StreamHandler() {
@Override
public void onListen(Object o, final EventChannel.EventSink eventSink) {
final Camera.CameraEventHandler cameraEventHandler = new Camera.CameraEventHandler() {
@Override
public void onError(String description) {
Map<String, String> event = new HashMap<>();
event.put("eventType", "error");
event.put("errorDescription", description);
eventSink.success(event);
}

@Override
public void onCameraClosed() {
Map<String, String> event = new HashMap<>();
event.put("eventType", "camera_closing");
eventSink.success(event);
}
};

camera.setCameraEventHandler(cameraEventHandler);
eventHandler.setEventSink(eventSink);
}

@Override
public void onCancel(Object o) {
camera.setCameraEventHandler(null);
eventHandler.setEventSink(null);
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@

import androidx.annotation.NonNull;

/**
* Serializes and sends an {@link Image} to a destination through a stream.
*/
public interface CameraImageStream {
void sendImage(@NonNull Image image);
}
Original file line number Diff line number Diff line change
Expand Up @@ -73,26 +73,32 @@ private void setup() {
"plugins.flutter.io/camera/imageStream"
);
CameraPreviewDisplay cameraImageStream = new CameraPluginProtocol.ChannelCameraPreviewDisplay(imageStreamChannel);
CameraPluginProtocol.CameraEventChannelFactory cameraChannelFactory = new CameraPluginProtocol.CameraEventChannelFactory() {
@NonNull
@Override
public EventChannel createCameraEventChannel(long textureId) {
return new EventChannel(
pluginBinding.getFlutterEngine().getDartExecutor(),
"flutter.io/cameraPlugin/cameraEvents" + textureId
);
}
};
CameraSystem cameraSystem = new AndroidCameraSystem(
pluginBinding,
activityBinding,
cameraPermissions,
cameraImageStream
cameraImageStream,
cameraChannelFactory
);
this.cameraPluginProtocol = new CameraPluginProtocol(cameraSystem);

final MethodChannel channel = new MethodChannel(
final MethodChannel primaryPluginChannel = new MethodChannel(
pluginBinding.getFlutterEngine().getDartExecutor(),
"plugins.flutter.io/camera"
);
channel.setMethodCallHandler(cameraPluginProtocol.getCameraSystemChannelHandler());
primaryPluginChannel.setMethodCallHandler(cameraPluginProtocol.getCameraSystemChannelHandler());
}

// TODO: there are 2+ channels
// 1:EventChannel - plugins.flutter.io/camera/imageStream
// 1:MethodChannel - plugins.flutter.io/camera
// 0+:EventChannel - flutter.io/cameraPlugin/cameraEvents[textureId]

private void teardown() {
// Teardown
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@
import android.media.Image;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;

import io.flutter.plugin.common.EventChannel;
import io.flutter.plugin.common.MethodCall;
Expand Down Expand Up @@ -286,6 +288,11 @@ private void handleException(Exception exception, MethodChannel.Result result) {
}
}

interface CameraEventChannelFactory {
@NonNull
EventChannel createCameraEventChannel(long textureId);
}

/**
* Implementation of a {@link CameraPreviewDisplay} that uses an {@link EventChannel}
* to send camera preview images to Flutter.
Expand Down Expand Up @@ -352,4 +359,45 @@ public void sendImage(@NonNull Image image) {
imageStreamSink.success(imageBuffer);
}
}

/* package */ static class ChannelCameraEventHandler implements Camera.CameraEventHandler {
private final List<Map<String, String>> queuedEvents = new CopyOnWriteArrayList<>();
private EventChannel.EventSink eventSink;

/* package */ ChannelCameraEventHandler() {}

public void setEventSink(@Nullable EventChannel.EventSink eventSink) {
this.eventSink = eventSink;

// Send all queue'd events.
if (!queuedEvents.isEmpty()) {
while (!queuedEvents.isEmpty()) {
eventSink.success(queuedEvents.remove(0));
}
}
}

@Override
public void onError(String description) {
Map<String, String> event = new HashMap<>();
event.put("eventType", "error");
event.put("errorDescription", description);
sendEvent(event);
}

@Override
public void onCameraClosed() {
Map<String, String> event = new HashMap<>();
event.put("eventType", "camera_closing");
sendEvent(event);
}

private void sendEvent(@NonNull Map<String, String> event) {
if (eventSink != null) {
eventSink.success(event);
} else {
queuedEvents.add(event);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@

import androidx.annotation.NonNull;

/**
* Displays a camera preview by streaming {@link Image}s from an Android
* camera by way of a given {@link ImageStreamConnection}.
*/
public interface CameraPreviewDisplay {
void startStreaming(@NonNull final ImageStreamConnection connection);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@

import java.util.List;

/**
* Top-level facade for all Camera plugin behavior.
*/
/* package */ interface CameraSystem {
List<CameraDetails> getAvailableCameras() throws CameraAccessException;

Expand Down