Skip to content

Commit

Permalink
Enable Android integration tests in remaining plugins (flutter#4514)
Browse files Browse the repository at this point in the history
  • Loading branch information
Emmanuel Garcia authored and amantoux committed Dec 11, 2021
1 parent 415a779 commit 430e655
Show file tree
Hide file tree
Showing 29 changed files with 165 additions and 70 deletions.
5 changes: 5 additions & 0 deletions packages/camera/camera/CHANGELOG.md
@@ -1,3 +1,8 @@
## 0.9.4+5

* Fixes bug where calling a method after the camera was closed resulted in a Java `IllegalStateException` exception.
* Fixes integration tests.

## 0.9.4+4

* Change Android compileSdkVersion to 31.
Expand Down
Expand Up @@ -281,8 +281,10 @@ public void onOpened(@NonNull CameraDevice device) {
public void onClosed(@NonNull CameraDevice camera) {
Log.i(TAG, "open | onClosed");

// Prevents calls to methods that would otherwise result in IllegalStateException exceptions.
cameraDevice = null;
closeCaptureSession();
dartMessenger.sendCameraClosingEvent();
super.onClosed(camera);
}

@Override
Expand Down Expand Up @@ -364,10 +366,13 @@ private void createCaptureSession(
// Prepare the callback.
CameraCaptureSession.StateCallback callback =
new CameraCaptureSession.StateCallback() {
boolean captureSessionClosed = false;

@Override
public void onConfigured(@NonNull CameraCaptureSession session) {
Log.i(TAG, "CameraCaptureSession onConfigured");
// Camera was already closed.
if (cameraDevice == null) {
if (cameraDevice == null || captureSessionClosed) {
dartMessenger.sendCameraErrorEvent("The camera was closed during configuration.");
return;
}
Expand All @@ -382,8 +387,15 @@ public void onConfigured(@NonNull CameraCaptureSession session) {

@Override
public void onConfigureFailed(@NonNull CameraCaptureSession cameraCaptureSession) {
Log.i(TAG, "CameraCaptureSession onConfigureFailed");
dartMessenger.sendCameraErrorEvent("Failed to configure camera session.");
}

@Override
public void onClosed(@NonNull CameraCaptureSession session) {
Log.i(TAG, "CameraCaptureSession onClosed");
captureSessionClosed = true;
}
};

// Start the session.
Expand Down Expand Up @@ -427,10 +439,12 @@ private void createCaptureSession(
// Send a repeating request to refresh capture session.
private void refreshPreviewCaptureSession(
@Nullable Runnable onSuccessCallback, @NonNull ErrorCallback onErrorCallback) {
Log.i(TAG, "refreshPreviewCaptureSession");

if (captureSession == null) {
Log.i(
TAG,
"[refreshPreviewCaptureSession] captureSession not yet initialized, "
"refreshPreviewCaptureSession: captureSession not yet initialized, "
+ "skipping preview capture session refresh.");
return;
}
Expand All @@ -445,6 +459,8 @@ private void refreshPreviewCaptureSession(
onSuccessCallback.run();
}

} catch (IllegalStateException e) {
onErrorCallback.onError("cameraAccess", "Camera is closed: " + e.getMessage());
} catch (CameraAccessException e) {
onErrorCallback.onError("cameraAccess", e.getMessage());
}
Expand Down
94 changes: 51 additions & 43 deletions packages/camera/camera/example/integration_test/camera_test.dart
Expand Up @@ -71,28 +71,32 @@ void main() {
expectedSize, Size(image.height.toDouble(), image.width.toDouble()));
}

testWidgets('Capture specific image resolutions',
(WidgetTester tester) async {
final List<CameraDescription> cameras = await availableCameras();
if (cameras.isEmpty) {
return;
}
for (CameraDescription cameraDescription in cameras) {
bool previousPresetExactlySupported = true;
for (MapEntry<ResolutionPreset, Size> preset
in presetExpectedSizes.entries) {
final CameraController controller =
CameraController(cameraDescription, preset.key);
await controller.initialize();
final bool presetExactlySupported =
await testCaptureImageResolution(controller, preset.key);
assert(!(!previousPresetExactlySupported && presetExactlySupported),
'The camera took higher resolution pictures at a lower resolution.');
previousPresetExactlySupported = presetExactlySupported;
await controller.dispose();
testWidgets(
'Capture specific image resolutions',
(WidgetTester tester) async {
final List<CameraDescription> cameras = await availableCameras();
if (cameras.isEmpty) {
return;
}
}
}, skip: !Platform.isAndroid);
for (CameraDescription cameraDescription in cameras) {
bool previousPresetExactlySupported = true;
for (MapEntry<ResolutionPreset, Size> preset
in presetExpectedSizes.entries) {
final CameraController controller =
CameraController(cameraDescription, preset.key);
await controller.initialize();
final bool presetExactlySupported =
await testCaptureImageResolution(controller, preset.key);
assert(!(!previousPresetExactlySupported && presetExactlySupported),
'The camera took higher resolution pictures at a lower resolution.');
previousPresetExactlySupported = presetExactlySupported;
await controller.dispose();
}
}
},
// TODO(egarciad): Fix https://github.com/flutter/flutter/issues/93686.
skip: true,
);

// This tests that the capture is no bigger than the preset, since we have
// automatic code to fall back to smaller sizes when we need to. Returns
Expand Down Expand Up @@ -121,29 +125,33 @@ void main() {
expectedSize, Size(video.height, video.width));
}

testWidgets('Capture specific video resolutions',
(WidgetTester tester) async {
final List<CameraDescription> cameras = await availableCameras();
if (cameras.isEmpty) {
return;
}
for (CameraDescription cameraDescription in cameras) {
bool previousPresetExactlySupported = true;
for (MapEntry<ResolutionPreset, Size> preset
in presetExpectedSizes.entries) {
final CameraController controller =
CameraController(cameraDescription, preset.key);
await controller.initialize();
await controller.prepareForVideoRecording();
final bool presetExactlySupported =
await testCaptureVideoResolution(controller, preset.key);
assert(!(!previousPresetExactlySupported && presetExactlySupported),
'The camera took higher resolution pictures at a lower resolution.');
previousPresetExactlySupported = presetExactlySupported;
await controller.dispose();
testWidgets(
'Capture specific video resolutions',
(WidgetTester tester) async {
final List<CameraDescription> cameras = await availableCameras();
if (cameras.isEmpty) {
return;
}
}
}, skip: !Platform.isAndroid);
for (CameraDescription cameraDescription in cameras) {
bool previousPresetExactlySupported = true;
for (MapEntry<ResolutionPreset, Size> preset
in presetExpectedSizes.entries) {
final CameraController controller =
CameraController(cameraDescription, preset.key);
await controller.initialize();
await controller.prepareForVideoRecording();
final bool presetExactlySupported =
await testCaptureVideoResolution(controller, preset.key);
assert(!(!previousPresetExactlySupported && presetExactlySupported),
'The camera took higher resolution pictures at a lower resolution.');
previousPresetExactlySupported = presetExactlySupported;
await controller.dispose();
}
}
},
// TODO(egarciad): Fix https://github.com/flutter/flutter/issues/93686.
skip: true,
);

testWidgets('Pause and resume video recording', (WidgetTester tester) async {
final List<CameraDescription> cameras = await availableCameras();
Expand Down
2 changes: 1 addition & 1 deletion packages/camera/camera/pubspec.yaml
Expand Up @@ -4,7 +4,7 @@ description: A Flutter plugin for controlling the camera. Supports previewing
Dart.
repository: https://github.com/flutter/plugins/tree/master/packages/camera/camera
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22
version: 0.9.4+4
version: 0.9.4+5

environment:
sdk: ">=2.14.0 <3.0.0"
Expand Down
1 change: 1 addition & 0 deletions packages/in_app_purchase/in_app_purchase/CHANGELOG.md
@@ -1,5 +1,6 @@
## NEXT

* Fixes integration tests.
* Updates example app Android compileSdkVersion to 31.

* **BREAKING CHANGES**:
Expand Down

This file was deleted.

Expand Up @@ -2,14 +2,21 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:io';

import 'package:flutter_test/flutter_test.dart';
import 'package:in_app_purchase/in_app_purchase.dart';
import 'package:in_app_purchase_android/in_app_purchase_android.dart';
import 'package:integration_test/integration_test.dart';

void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();

testWidgets('Can create InAppPurchase instance', (WidgetTester tester) async {
if (Platform.isAndroid) {
// https://github.com/flutter/flutter/issues/93837
InAppPurchaseAndroidPlatformAddition.enablePendingPurchases();
}
final InAppPurchase iapInstance = InAppPurchase.instance;
expect(iapInstance, isNotNull);
});
Expand Down
@@ -0,0 +1,19 @@
// 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.

package io.flutter.plugins.sharedpreferencesexample;

import androidx.test.rule.ActivityTestRule;
import dev.flutter.plugins.integration_test.FlutterTestRunner;
import io.flutter.embedding.android.FlutterActivity;
import io.flutter.plugins.DartIntegrationTest;
import org.junit.Rule;
import org.junit.runner.RunWith;

@DartIntegrationTest
@RunWith(FlutterTestRunner.class)
public class FlutterActivityTest {
@Rule
public ActivityTestRule<FlutterActivity> rule = new ActivityTestRule<>(FlutterActivity.class);
}

This file was deleted.

Expand Up @@ -6,7 +6,7 @@ buildscript {
}

dependencies {
classpath 'com.android.tools.build:gradle:4.1.0'
classpath 'com.android.tools.build:gradle:7.0.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
Expand Down
Expand Up @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-all.zip
4 changes: 3 additions & 1 deletion packages/url_launcher/url_launcher/CHANGELOG.md
@@ -1,5 +1,7 @@
## NEXT
## 6.0.14

* Updates readme to indicate that sending SMS messages on Android 11 requires to add a query to AndroidManifest.xml.
* Fixes integration tests.
* Updates example app Android compileSdkVersion to 31.

## 6.0.13
Expand Down
7 changes: 6 additions & 1 deletion packages/url_launcher/url_launcher/README.md
Expand Up @@ -72,7 +72,12 @@ for examples of other queries.
<action android:name="android.intent.action.DIAL" />
<data android:scheme="tel" />
</intent>
<!-- If your app emails -->
<!-- If your sends SMS messages -->
<intent>
<action android:name="android.intent.action.SENDTO" />
<data android:scheme="smsto" />
</intent>
<!-- If your app sends emails -->
<intent>
<action android:name="android.intent.action.SEND" />
<data android:mimeType="*/*" />
Expand Down
Expand Up @@ -12,11 +12,14 @@
import android.net.Uri;
import android.os.Bundle;
import android.provider.Browser;
import android.util.Log;
import androidx.annotation.Nullable;

/** Launches components for URLs. */
class UrlLauncher {
private static final String TAG = "UrlLauncher";
private final Context applicationContext;

@Nullable private Activity activity;

/**
Expand All @@ -40,9 +43,14 @@ boolean canLaunch(String url) {
ComponentName componentName =
launchIntent.resolveActivity(applicationContext.getPackageManager());

return componentName != null
&& !"{com.android.fallback/com.android.fallback.Fallback}"
.equals(componentName.toShortString());
if (componentName == null) {
Log.i(TAG, "component name for " + url + " is null");
return false;
} else {
Log.i(TAG, "component name for " + url + " is " + componentName.toShortString());
return !"{com.android.fallback/com.android.fallback.Fallback}"
.equals(componentName.toShortString());
}
}

/**
Expand Down
Expand Up @@ -17,6 +17,10 @@
<action android:name="android.intent.action.DIAL" />
<data android:scheme="tel" />
</intent>
<intent>
<action android:name="android.intent.action.SENDTO" />
<data android:scheme="smsto" />
</intent>
</queries>

<application
Expand Down
Expand Up @@ -17,6 +17,7 @@ void main() {

// Generally all devices should have some default browser.
expect(await canLaunch('http://flutter.dev'), true);
expect(await canLaunch('https://www.google.com/404'), true);

// SMS handling is available by default on most platforms.
if (kIsWeb || !(Platform.isLinux || Platform.isWindows)) {
Expand Down
2 changes: 1 addition & 1 deletion packages/url_launcher/url_launcher/pubspec.yaml
Expand Up @@ -3,7 +3,7 @@ description: Flutter plugin for launching a URL. Supports
web, phone, SMS, and email schemes.
repository: https://github.com/flutter/plugins/tree/master/packages/url_launcher/url_launcher
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+url_launcher%22
version: 6.0.13
version: 6.0.14

environment:
sdk: ">=2.14.0 <3.0.0"
Expand Down
1 change: 1 addition & 0 deletions packages/video_player/video_player/CHANGELOG.md
@@ -1,5 +1,6 @@
## NEXT

* Fixes integration tests.
* Updates example app Android compileSdkVersion to 31.

## 2.2.7
Expand Down
@@ -0,0 +1,14 @@
// 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.

package io.flutter.plugins;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface DartIntegrationTest {}
@@ -0,0 +1,19 @@
// 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.

package io.flutter.plugins.videoplayerexample;

import androidx.test.rule.ActivityTestRule;
import dev.flutter.plugins.integration_test.FlutterTestRunner;
import io.flutter.embedding.android.FlutterActivity;
import io.flutter.plugins.DartIntegrationTest;
import org.junit.Rule;
import org.junit.runner.RunWith;

@DartIntegrationTest
@RunWith(FlutterTestRunner.class)
public class FlutterActivityTest {
@Rule
public ActivityTestRule<FlutterActivity> rule = new ActivityTestRule<>(FlutterActivity.class);
}

0 comments on commit 430e655

Please sign in to comment.