Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.
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
Expand Up @@ -5,8 +5,8 @@
package io.flutter.plugins.camera;

import android.os.Handler;
import android.os.Looper;
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;
Expand All @@ -17,6 +17,7 @@
import java.util.Map;

class DartMessenger {
@NonNull private final Handler handler;
@Nullable private MethodChannel cameraChannel;
@Nullable private MethodChannel deviceChannel;

Expand All @@ -41,9 +42,10 @@ enum CameraEventType {
}
}

DartMessenger(BinaryMessenger messenger, long cameraId) {
DartMessenger(BinaryMessenger messenger, long cameraId, @NonNull Handler handler) {
cameraChannel = new MethodChannel(messenger, "flutter.io/cameraPlugin/camera" + cameraId);
deviceChannel = new MethodChannel(messenger, "flutter.io/cameraPlugin/device");
this.handler = handler;
}

void sendDeviceOrientationChangeEvent(PlatformChannel.DeviceOrientation orientation) {
Expand Down Expand Up @@ -106,14 +108,14 @@ void send(CameraEventType eventType, Map<String, Object> args) {
if (cameraChannel == null) {
return;
}
new Handler(Looper.getMainLooper())
.post(
new Runnable() {
@Override
public void run() {
cameraChannel.invokeMethod(eventType.method, args);
}
});

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

void send(DeviceEventType eventType) {
Expand All @@ -124,13 +126,13 @@ void send(DeviceEventType eventType, Map<String, Object> args) {
if (deviceChannel == null) {
return;
}
new Handler(Looper.getMainLooper())
.post(
new Runnable() {
@Override
public void run() {
deviceChannel.invokeMethod(eventType.method, args);
}
});

handler.post(
new Runnable() {
@Override
public void run() {
deviceChannel.invokeMethod(eventType.method, args);
}
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

import android.app.Activity;
import android.hardware.camera2.CameraAccessException;
import android.os.Handler;
import android.os.Looper;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import io.flutter.embedding.engine.systemchannels.PlatformChannel;
Expand Down Expand Up @@ -353,7 +355,9 @@ private void instantiateCamera(MethodCall call, Result result) throws CameraAcce
boolean enableAudio = call.argument("enableAudio");
TextureRegistry.SurfaceTextureEntry flutterSurfaceTexture =
textureRegistry.createSurfaceTexture();
DartMessenger dartMessenger = new DartMessenger(messenger, flutterSurfaceTexture.id());
DartMessenger dartMessenger =
new DartMessenger(
messenger, flutterSurfaceTexture.id(), new Handler(Looper.getMainLooper()));
camera =
new Camera(
activity,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@

import static junit.framework.TestCase.assertNull;
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;

import android.os.Handler;
import androidx.annotation.NonNull;
import io.flutter.embedding.engine.systemchannels.PlatformChannel;
import io.flutter.plugin.common.BinaryMessenger;
Expand All @@ -19,6 +23,8 @@
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;

public class DartMessengerTest {
/** A {@link BinaryMessenger} implementation that does nothing but save its messages. */
Expand All @@ -43,20 +49,24 @@ List<ByteBuffer> getMessages() {
}
}

private Handler mockHandler;
private DartMessenger dartMessenger;
private FakeBinaryMessenger fakeBinaryMessenger;

@Before
public void setUp() {
mockHandler = mock(Handler.class);
fakeBinaryMessenger = new FakeBinaryMessenger();
dartMessenger = new DartMessenger(fakeBinaryMessenger, 0);
dartMessenger = new DartMessenger(fakeBinaryMessenger, 0, mockHandler);
}

@Test
public void sendCameraErrorEvent_includesErrorDescriptions() {
dartMessenger.sendCameraErrorEvent("error description");
doAnswer(createPostHandlerAnswer()).when(mockHandler).post(any(Runnable.class));

dartMessenger.sendCameraErrorEvent("error description");
List<ByteBuffer> sentMessages = fakeBinaryMessenger.getMessages();

assertEquals(1, sentMessages.size());
MethodCall call = decodeSentMessage(sentMessages.get(0));
assertEquals("error", call.method);
Expand All @@ -65,6 +75,7 @@ public void sendCameraErrorEvent_includesErrorDescriptions() {

@Test
public void sendCameraInitializedEvent_includesPreviewSize() {
doAnswer(createPostHandlerAnswer()).when(mockHandler).post(any(Runnable.class));
dartMessenger.sendCameraInitializedEvent(0, 0, ExposureMode.auto, FocusMode.auto, true, true);

List<ByteBuffer> sentMessages = fakeBinaryMessenger.getMessages();
Expand All @@ -81,6 +92,7 @@ public void sendCameraInitializedEvent_includesPreviewSize() {

@Test
public void sendCameraClosingEvent() {
doAnswer(createPostHandlerAnswer()).when(mockHandler).post(any(Runnable.class));
dartMessenger.sendCameraClosingEvent();

List<ByteBuffer> sentMessages = fakeBinaryMessenger.getMessages();
Expand All @@ -92,6 +104,7 @@ public void sendCameraClosingEvent() {

@Test
public void sendDeviceOrientationChangedEvent() {
doAnswer(createPostHandlerAnswer()).when(mockHandler).post(any(Runnable.class));
dartMessenger.sendDeviceOrientationChangeEvent(PlatformChannel.DeviceOrientation.PORTRAIT_UP);

List<ByteBuffer> sentMessages = fakeBinaryMessenger.getMessages();
Expand All @@ -101,6 +114,19 @@ public void sendDeviceOrientationChangedEvent() {
assertEquals(call.argument("orientation"), "portraitUp");
}

private static Answer<Boolean> createPostHandlerAnswer() {
return new Answer<Boolean>() {
@Override
public Boolean answer(InvocationOnMock invocation) throws Throwable {
Runnable runnable = invocation.getArgument(0, Runnable.class);
if (runnable != null) {
runnable.run();
}
return true;
}
};
}

private MethodCall decodeSentMessage(ByteBuffer sentMessage) {
sentMessage.position(0);

Expand Down
9 changes: 6 additions & 3 deletions script/tool/lib/src/java_test_command.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,12 @@ class JavaTestCommand extends PluginCommand {
final Stream<Directory> examplesWithTests = getExamples().where(
(Directory d) =>
isFlutterPackage(d, fileSystem) &&
fileSystem
.directory(p.join(d.path, 'android', 'app', 'src', 'test'))
.existsSync());
(fileSystem
.directory(p.join(d.path, 'android', 'app', 'src', 'test'))
.existsSync() ||
fileSystem
.directory(p.join(d.path, '..', 'android', 'src', 'test'))
.existsSync()));

final List<String> failingPackages = <String>[];
final List<String> missingFlutterBuild = <String>[];
Expand Down
86 changes: 86 additions & 0 deletions script/tool/test/java_test_command_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:args/command_runner.dart';
import 'package:file/file.dart';
import 'package:flutter_plugin_tools/src/java_test_command.dart';
import 'package:path/path.dart' as p;
import 'package:test/test.dart';

import 'util.dart';

void main() {
group('$JavaTestCommand', () {
CommandRunner<JavaTestCommand> runner;
final RecordingProcessRunner processRunner = RecordingProcessRunner();

setUp(() {
initializeFakePackages();
final JavaTestCommand command = JavaTestCommand(
mockPackagesDir, mockFileSystem,
processRunner: processRunner);

runner =
CommandRunner<Null>('java_test_test', 'Test for $JavaTestCommand');
runner.addCommand(command);
});

tearDown(() {
cleanupPackages();
processRunner.recordedCalls.clear();
});

test('Should run Java tests in Android implementation folder', () async {
final Directory plugin = createFakePlugin(
'plugin1',
isAndroidPlugin: true,
isFlutter: true,
withSingleExample: true,
withExtraFiles: <List<String>>[
<String>['example/android', 'gradlew'],
<String>['android/src/test', 'example_test.java'],
],
);

await runner.run(<String>['java-test']);

expect(
processRunner.recordedCalls,
orderedEquals(<ProcessCall>[
ProcessCall(
p.join(plugin.path, 'example/android/gradlew'),
<String>['testDebugUnitTest', '--info'],
p.join(plugin.path, 'example/android'),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't this be android/

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No this would be the working directory and it needs to point to the example/android location. From there it will look up the tests in android (through the compiled version of the example app).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, my mistake.

),
]),
);
});

test('Should run Java tests in example folder', () async {
final Directory plugin = createFakePlugin(
'plugin1',
isAndroidPlugin: true,
isFlutter: true,
withSingleExample: true,
withExtraFiles: <List<String>>[
<String>['example/android', 'gradlew'],
<String>['example/android/app/src/test', 'example_test.java'],
],
);

await runner.run(<String>['java-test']);

expect(
processRunner.recordedCalls,
orderedEquals(<ProcessCall>[
ProcessCall(
p.join(plugin.path, 'example/android/gradlew'),
<String>['testDebugUnitTest', '--info'],
p.join(plugin.path, 'example/android'),
),
]),
);
});
});
}