USB 摄像头+远程遥控+中英的适配+topic的集成和状态的使用到相应页面

This commit is contained in:
2026-10-20 17:03:37 +08:00
parent 178cd2533c
commit 582242e9aa
144 changed files with 15759 additions and 406 deletions

View File

@@ -0,0 +1,21 @@
// Copyright 2013 The Flutter Authors
// 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;
/*
* Annotation to aid repository tooling in determining if a test is
* a native java unit test or a java class with a dart integration.
*
* See: https://github.com/flutter/flutter/blob/master/docs/ecosystem/testing/Plugin-Tests.md#enabling-android-ui-tests
* for more information.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface DartIntegrationTest {}

View File

@@ -0,0 +1,19 @@
// Copyright 2013 The Flutter Authors
// 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);
}

View File

@@ -0,0 +1,73 @@
// Copyright 2013 The Flutter Authors
// 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 static androidx.test.espresso.flutter.EspressoFlutter.WidgetInteraction;
import static androidx.test.espresso.flutter.EspressoFlutter.onFlutterWidget;
import static androidx.test.espresso.flutter.action.FlutterActions.click;
import static androidx.test.espresso.flutter.assertion.FlutterAssertions.matches;
import static androidx.test.espresso.flutter.matcher.FlutterMatchers.isExisting;
import static androidx.test.espresso.flutter.matcher.FlutterMatchers.withText;
import static androidx.test.espresso.flutter.matcher.FlutterMatchers.withValueKey;
import androidx.test.ext.junit.rules.ActivityScenarioRule;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class VideoPlayerUITest {
@Rule
public ActivityScenarioRule<DriverExtensionActivity> activityRule =
new ActivityScenarioRule<>(DriverExtensionActivity.class);
@Test
@Ignore("Doesn't run in Firebase Test Lab: https://github.com/flutter/flutter/issues/94748")
public void playVideo() {
WidgetInteraction remoteTab = onFlutterWidget(withText("Remote"));
remoteTab.check(matches(isExisting()));
for (String tabName : new String[] {"Platform view", "Texture view"}) {
WidgetInteraction viewTypeTab = onFlutterWidget(withText(tabName));
viewTypeTab.check(matches(isExisting()));
viewTypeTab.perform(click());
WidgetInteraction playButton = onFlutterWidget(withValueKey("Play"));
playButton.check(matches(isExisting()));
playButton.perform(click());
WidgetInteraction playbackSpeed1x = onFlutterWidget(withText("1.0x"));
playbackSpeed1x.check(matches(isExisting()));
playbackSpeed1x.perform(click());
WidgetInteraction playbackSpeed5xButton = onFlutterWidget(withText("5.0x"));
playbackSpeed5xButton.check(matches(isExisting()));
playbackSpeed5xButton.perform(click());
WidgetInteraction playbackSpeed5x = onFlutterWidget(withText("5.0x"));
playbackSpeed5x.check(matches(isExisting()));
}
for (String[] tabData :
new String[][] {{"Asset", "With assets mp4"}, {"Remote", "With remote mp4"}}) {
String tabName = tabData[0];
String videoDescription = tabData[1];
WidgetInteraction tab = onFlutterWidget(withText(tabName));
WidgetInteraction tabDescription = onFlutterWidget(withText(videoDescription));
tab.check(matches(isExisting()));
// TODO(FirentisTFW): Assert that testDescription is not visible before we tap on tab.
// This should be done once the Espresso API allows us to perform such an assertion. See
// https://github.com/flutter/flutter/issues/160599
tab.perform(click());
tab.check(matches(isExisting()));
tabDescription.check(matches(isExisting()));
}
}
}

View File

@@ -0,0 +1,10 @@
// Copyright 2013 The Flutter Authors
// 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 io.flutter.embedding.android.FlutterActivity;
/** Test Activity that sets the name of the Dart method entrypoint in the manifest. */
public class DriverExtensionActivity extends FlutterActivity {}

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@android:color/white" />
<!-- You can insert your own image assets here -->
<!-- <item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" />
</item> -->
</layer-list>

Binary file not shown.

After

Width:  |  Height:  |  Size: 544 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 442 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 721 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
</resources>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">www.sample-videos.com</domain>
<domain includeSubdomains="true">184.72.239.149</domain>
<!-- Needed for Espresso integration test -->
<domain includeSubdomains="true">127.0.0.1</domain>
</domain-config>
</network-security-config>

View File

@@ -0,0 +1,56 @@
// Copyright 2013 The Flutter Authors
// 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 static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.platform.PlatformViewRegistry;
import io.flutter.plugins.videoplayer.VideoPlayerPlugin;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
@RunWith(RobolectricTestRunner.class)
@Config(manifest = Config.NONE)
public class FlutterActivityTest {
AutoCloseable mockCloseable;
@Mock FlutterPlugin.FlutterPluginBinding flutterPluginBinding;
@Before
public void before() {
mockCloseable = MockitoAnnotations.openMocks(this);
}
@After
public void tearDown() throws Exception {
mockCloseable.close();
}
@Test
public void disposeAllPlayers() {
when(flutterPluginBinding.getApplicationContext()).thenReturn(mock(Context.class));
when(flutterPluginBinding.getBinaryMessenger()).thenReturn(mock(BinaryMessenger.class));
when(flutterPluginBinding.getPlatformViewRegistry())
.thenReturn(mock(PlatformViewRegistry.class));
VideoPlayerPlugin videoPlayerPlugin = spy(new VideoPlayerPlugin());
videoPlayerPlugin.onAttachedToEngine(flutterPluginBinding);
videoPlayerPlugin.onDetachedFromEngine(flutterPluginBinding);
verify(videoPlayerPlugin, times(1)).onDestroy();
}
}