Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

Commit 791fcfb

Browse files
committed
Merge branch 'main' into android-handle-quick-action-without-restart
2 parents 116386b + a0c773b commit 791fcfb

File tree

147 files changed

+2079
-772
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

147 files changed

+2079
-772
lines changed

.ci/flutter_master.version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
02558d69d92384e7ed1b66f50006796342c8945a
1+
39a38b7882fe40436176ebc97e554be11141cc7d

.cirrus.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ task:
113113
# run with --require-excerpts and no exclusions.
114114
- ./script/tool_runner.sh readme-check --require-excerpts --exclude=script/configs/temp_exclude_excerpt.yaml
115115
license_script: dart $PLUGIN_TOOL license-check
116+
dependabot_script: dart $PLUGIN_TOOL dependabot-check
116117
- name: federated_safety
117118
# This check is only meaningful for PRs, as it validates changes
118119
# rather than state.

.github/dependabot.yml

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
11
version: 2
22
updates:
33
- package-ecosystem: "gradle"
4-
directory: "/packages/camera/camera/android"
4+
directory: "/packages/camera/camera_android/android"
5+
commit-message:
6+
prefix: "[camera]"
7+
schedule:
8+
interval: "weekly"
9+
open-pull-requests-limit: 10
10+
11+
- package-ecosystem: "gradle"
12+
directory: "/packages/camera/camera_android/example/android/app"
513
commit-message:
614
prefix: "[camera]"
715
schedule:
@@ -216,6 +224,14 @@ updates:
216224
interval: "weekly"
217225
open-pull-requests-limit: 10
218226

227+
- package-ecosystem: "gradle"
228+
directory: "/packages/shared_preferences/shared_preferences_android/android"
229+
commit-message:
230+
prefix: "[shared_pref]"
231+
schedule:
232+
interval: "weekly"
233+
open-pull-requests-limit: 10
234+
219235
- package-ecosystem: "gradle"
220236
directory: "/packages/shared_preferences/shared_preferences_android/example/android/app"
221237
commit-message:
@@ -248,6 +264,14 @@ updates:
248264
interval: "weekly"
249265
open-pull-requests-limit: 10
250266

267+
- package-ecosystem: "gradle"
268+
directory: "/packages/video_player/video_player/example/android/app"
269+
commit-message:
270+
prefix: "[video_player]"
271+
schedule:
272+
interval: "weekly"
273+
open-pull-requests-limit: 10
274+
251275
- package-ecosystem: "gradle"
252276
directory: "/packages/video_player/video_player_android/android"
253277
commit-message:
@@ -281,13 +305,13 @@ updates:
281305
open-pull-requests-limit: 10
282306

283307
- package-ecosystem: "gradle"
284-
directory: "/packages/webview_flutter/webview_flutter_android/example/android"
308+
directory: "/packages/webview_flutter/webview_flutter_android/example/android/app"
285309
commit-message:
286310
prefix: "[webview]"
287311
schedule:
288312
interval: "weekly"
289313
open-pull-requests-limit: 10
290-
314+
291315
- package-ecosystem: "github-actions"
292316
directory: "/"
293317
commit-message:

packages/camera/camera/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## NEXT
2+
3+
* Ignores unnecessary import warnings in preparation for [upcoming Flutter changes](https://github.com/flutter/flutter/pull/106316).
4+
15
## 0.9.8+1
26

37
* Ignores deprecation warnings for upcoming styleFrom button API changes.

packages/camera/camera/example/android/app/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ flutter {
5757
}
5858

5959
dependencies {
60-
testImplementation 'junit:junit:4.12'
60+
testImplementation 'junit:junit:4.13.2'
6161
androidTestImplementation 'androidx.test:runner:1.2.0'
6262
androidTestImplementation 'androidx.test:rules:1.2.0'
6363
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'

packages/camera/camera/test/camera_value_test.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,13 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5+
// TODO(a14n): remove this import once Flutter 3.1 or later reaches stable (including flutter/flutter#106316)
6+
// ignore: unnecessary_import
57
import 'dart:ui';
68

79
import 'package:camera/camera.dart';
10+
// TODO(a14n): remove this import once Flutter 3.1 or later reaches stable (including flutter/flutter#106316)
11+
// ignore: unnecessary_import
812
import 'package:flutter/cupertino.dart';
913
import 'package:flutter/services.dart';
1014
import 'package:flutter_test/flutter_test.dart';

packages/camera/camera_android/CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
## 0.9.8+3
2+
3+
* Skips duplicate calls to stop background thread and removes unnecessary closings of camera capture sessions on Android.
4+
5+
## 0.9.8+2
6+
7+
* Fixes exception in registerWith caused by the switch to an in-package method channel.
8+
19
## 0.9.8+1
210

311
* Ignores deprecation warnings for upcoming styleFrom button API changes.

packages/camera/camera_android/android/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ android {
6060

6161
dependencies {
6262
compileOnly 'androidx.annotation:annotation:1.1.0'
63-
testImplementation 'junit:junit:4.12'
63+
testImplementation 'junit:junit:4.13.2'
6464
testImplementation 'org.mockito:mockito-inline:4.0.0'
6565
testImplementation 'androidx.test:core:1.3.0'
6666
testImplementation 'org.robolectric:robolectric:4.5'

packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/Camera.java

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,8 @@ class Camera
131131

132132
/** An additional thread for running tasks that shouldn't block the UI. */
133133
private HandlerThread backgroundHandlerThread;
134+
/** True when backgroundHandlerThread is in the process of being stopped. */
135+
private boolean stoppingBackgroundHandlerThread = false;
134136

135137
private CameraDeviceWrapper cameraDevice;
136138
private CameraCaptureSession captureSession;
@@ -382,16 +384,16 @@ public void onError(@NonNull CameraDevice cameraDevice, int errorCode) {
382384
backgroundHandler);
383385
}
384386

385-
private void createCaptureSession(int templateType, Surface... surfaces)
386-
throws CameraAccessException {
387+
@VisibleForTesting
388+
void createCaptureSession(int templateType, Surface... surfaces) throws CameraAccessException {
387389
createCaptureSession(templateType, null, surfaces);
388390
}
389391

390392
private void createCaptureSession(
391393
int templateType, Runnable onSuccessCallback, Surface... surfaces)
392394
throws CameraAccessException {
393395
// Close any existing capture session.
394-
closeCaptureSession();
396+
captureSession = null;
395397

396398
// Create a new capture builder.
397399
previewRequestBuilder = cameraDevice.createCaptureRequest(templateType);
@@ -669,7 +671,11 @@ public void startBackgroundThread() {
669671

670672
/** Stops the background thread and its {@link Handler}. */
671673
public void stopBackgroundThread() {
674+
if (stoppingBackgroundHandlerThread) {
675+
return;
676+
}
672677
if (backgroundHandlerThread != null) {
678+
stoppingBackgroundHandlerThread = true;
673679
backgroundHandlerThread.quitSafely();
674680
try {
675681
backgroundHandlerThread.join();
@@ -679,6 +685,7 @@ public void stopBackgroundThread() {
679685
}
680686
backgroundHandlerThread = null;
681687
backgroundHandler = null;
688+
stoppingBackgroundHandlerThread = false;
682689
}
683690

684691
/** Start capturing a picture, doing autofocus first. */
@@ -1173,12 +1180,19 @@ private void closeCaptureSession() {
11731180

11741181
public void close() {
11751182
Log.i(TAG, "close");
1176-
closeCaptureSession();
11771183

11781184
if (cameraDevice != null) {
11791185
cameraDevice.close();
11801186
cameraDevice = null;
1187+
1188+
// Closing the CameraDevice without closing the CameraCaptureSession is recommended
1189+
// for quickly closing the camera:
1190+
// https://developer.android.com/reference/android/hardware/camera2/CameraCaptureSession#close()
1191+
captureSession = null;
1192+
} else {
1193+
closeCaptureSession();
11811194
}
1195+
11821196
if (pictureImageReader != null) {
11831197
pictureImageReader.close();
11841198
pictureImageReader = null;

packages/camera/camera_android/android/src/test/java/io/flutter/plugins/camera/CameraTest.java

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@
1818
import static org.mockito.Mockito.when;
1919

2020
import android.app.Activity;
21+
import android.graphics.SurfaceTexture;
2122
import android.hardware.camera2.CameraAccessException;
2223
import android.hardware.camera2.CameraCaptureSession;
24+
import android.hardware.camera2.CameraDevice;
2325
import android.hardware.camera2.CameraMetadata;
2426
import android.hardware.camera2.CaptureRequest;
2527
import android.hardware.camera2.params.SessionConfiguration;
@@ -28,13 +30,15 @@
2830
import android.os.Build;
2931
import android.os.Handler;
3032
import android.os.HandlerThread;
33+
import android.util.Size;
3134
import android.view.Surface;
3235
import androidx.annotation.NonNull;
3336
import androidx.annotation.Nullable;
3437
import androidx.lifecycle.LifecycleObserver;
3538
import io.flutter.embedding.engine.systemchannels.PlatformChannel;
3639
import io.flutter.plugin.common.MethodChannel;
3740
import io.flutter.plugins.camera.features.CameraFeatureFactory;
41+
import io.flutter.plugins.camera.features.CameraFeatures;
3842
import io.flutter.plugins.camera.features.Point;
3943
import io.flutter.plugins.camera.features.autofocus.AutoFocusFeature;
4044
import io.flutter.plugins.camera.features.autofocus.FocusMode;
@@ -833,6 +837,28 @@ public void startBackgroundThread_shouldNotStartNewThreadWhenAlreadyCreated() {
833837
verify(mockHandlerThread, times(1)).start();
834838
}
835839

840+
@Test
841+
public void stopBackgroundThread_cancelsDuplicateCalls() throws InterruptedException {
842+
TestUtils.setPrivateField(camera, "stoppingBackgroundHandlerThread", true);
843+
844+
camera.startBackgroundThread();
845+
camera.stopBackgroundThread();
846+
847+
verify(mockHandlerThread, never()).quitSafely();
848+
verify(mockHandlerThread, never()).join();
849+
}
850+
851+
@Test
852+
public void stopBackgroundThread_proceedsWithoutDuplicateCall() throws InterruptedException {
853+
TestUtils.setPrivateField(camera, "stoppingBackgroundHandlerThread", false);
854+
855+
camera.startBackgroundThread();
856+
camera.stopBackgroundThread();
857+
858+
verify(mockHandlerThread).quitSafely();
859+
verify(mockHandlerThread).join();
860+
}
861+
836862
@Test
837863
public void onConverge_shouldTakePictureWithoutAbortingSession() throws CameraAccessException {
838864
ArrayList<CaptureRequest.Builder> mockRequestBuilders = new ArrayList<>();
@@ -856,6 +882,52 @@ public void onConverge_shouldTakePictureWithoutAbortingSession() throws CameraAc
856882
verify(mockCaptureSession, never()).abortCaptures();
857883
}
858884

885+
@Test
886+
public void createCaptureSession_doesNotCloseCaptureSession() throws CameraAccessException {
887+
Surface mockSurface = mock(Surface.class);
888+
SurfaceTexture mockSurfaceTexture = mock(SurfaceTexture.class);
889+
ResolutionFeature mockResolutionFeature = mock(ResolutionFeature.class);
890+
Size mockSize = mock(Size.class);
891+
ArrayList<CaptureRequest.Builder> mockRequestBuilders = new ArrayList<>();
892+
mockRequestBuilders.add(mock(CaptureRequest.Builder.class));
893+
CameraDeviceWrapper fakeCamera = new FakeCameraDeviceWrapper(mockRequestBuilders);
894+
TestUtils.setPrivateField(camera, "cameraDevice", fakeCamera);
895+
896+
TextureRegistry.SurfaceTextureEntry cameraFlutterTexture =
897+
(TextureRegistry.SurfaceTextureEntry) TestUtils.getPrivateField(camera, "flutterTexture");
898+
CameraFeatures cameraFeatures =
899+
(CameraFeatures) TestUtils.getPrivateField(camera, "cameraFeatures");
900+
ResolutionFeature resolutionFeature =
901+
(ResolutionFeature)
902+
TestUtils.getPrivateField(mockCameraFeatureFactory, "mockResolutionFeature");
903+
904+
when(cameraFlutterTexture.surfaceTexture()).thenReturn(mockSurfaceTexture);
905+
when(resolutionFeature.getPreviewSize()).thenReturn(mockSize);
906+
907+
camera.createCaptureSession(CameraDevice.TEMPLATE_PREVIEW, mockSurface);
908+
909+
verify(mockCaptureSession, never()).close();
910+
}
911+
912+
@Test
913+
public void close_doesCloseCaptureSessionWhenCameraDeviceNull() {
914+
camera.close();
915+
916+
verify(mockCaptureSession).close();
917+
}
918+
919+
@Test
920+
public void close_doesNotCloseCaptureSessionWhenCameraDeviceNonNull() {
921+
ArrayList<CaptureRequest.Builder> mockRequestBuilders = new ArrayList<>();
922+
mockRequestBuilders.add(mock(CaptureRequest.Builder.class));
923+
CameraDeviceWrapper fakeCamera = new FakeCameraDeviceWrapper(mockRequestBuilders);
924+
TestUtils.setPrivateField(camera, "cameraDevice", fakeCamera);
925+
926+
camera.close();
927+
928+
verify(mockCaptureSession, never()).close();
929+
}
930+
859931
private static class TestCameraFeatureFactory implements CameraFeatureFactory {
860932
private final AutoFocusFeature mockAutoFocusFeature;
861933
private final ExposureLockFeature mockExposureLockFeature;

0 commit comments

Comments
 (0)