Part of #137040 and #80374
The flag `throwOnPluginPubspecError` never actually was enabled during production in #79669, but only in some dart plugin tests. And in the tests the case of the error when enabling the flag was not explicitly tested. The only thing tested was, that it is not thrown when disabled.
As explained [here](https://github.com/flutter/flutter/pull/142035#discussion_r1484237904) the only case, where this error could be thrown is, when a dart implementation and a native inline implementation are provided simultaneously. But throwing an exception there is a wrong behavior, as both can coexist in a plugin package, thus in the pubspec file.
Disabling the flag means, that the error is not thrown and not shown to the user. This is the case in production (contrary to the dart plugin tests), which acts like these plugin cases of implementations are just skipped. And this is what actually should be done.
In conclusion, I think the case of coexisting dart and native implementation in pubspec was just overlooked and therefore this error validation was introduced, which is not necessary or even valid.
For more discussion, see: https://discord.com/channels/608014603317936148/608022056616853515/1200194937791205436
- This is tricky: I already added a test in #142035, which finally complies with the other tests, by removing the flag. So I think it falls in the category of "remove dead code".
- Theoretically this is a breaking change, as removing / altering some tests. But the flag actually was never valid or used, so IDK. But this may not does fall in the category of "contributed tests".
## Description
This PRs changes the default value for the `platform` parameter used to simulate key events.
With this PR, the default value is "web" on web, otherwise it is the operating system name retrieved from `defaultTargetPlatform`.
Previously, for methods in `WidgetController`, it defaulted to âwebâ on web, and âandroidâ everywhere else. And for methods in `KeyEventSimulator` it defaulted to âwebâ on web, and the operating system that the test was running on everywhere else. Because the operating system was based on `Platform.operatingSystem`, it usually differed from the target platform the test was running on.
AFAIK, the `platform` parameter is only meaningful for simulating `RawKeyEvent`. Once `RawKeyboard` will be fully removed, the `platform` parameter wonât be needed.
@gspencergoog In the meantime, do you think it is worth merging this fix?
## Related Issue
Fixes to https://github.com/flutter/flutter/issues/133955
## Tests
Adds one test.
*Replace this paragraph with a description of what this PR is changing or adding, and why. Consider including before/after screenshots.*
*List which issues are fixed by this PR. You must list at least one issue. An issue is not required if the PR fixes something trivial like a typo.*
*If you had to change anything in the [flutter/tests] repo, include a link to the migration guide as per the [breaking change policy].*
## Description
This PRs changes the default value transit mode for key event simulation.
The default transit mode for key event simulation is currently `KeyDataTransitMode.rawKeyData` while on the framework side `KeyDataTransitMode.keyDataThenRawKeyData` is the preferred transit mode.
`KeyDataTransitMode.keyDataThenRawKeyData` is more accurate and can help detect issues.
For instance the following test will fail with `KeyDataTransitMode.rawKeyData` because raw keyboard logic for modifier keys is less accurate:
```dart
testWidgets('Press control left once', (WidgetTester tester) async {
debugKeyEventSimulatorTransitModeOverride = KeyDataTransitMode.keyDataThenRawKeyData;
final List<KeyEvent> events = <KeyEvent>[];
final FocusNode focusNode = FocusNode();
addTearDown(focusNode.dispose);
await tester.pumpWidget(
Focus(
focusNode: focusNode,
autofocus: true,
onKeyEvent: (_, KeyEvent event) {
events.add(event);
return KeyEventResult.handled;
},
child: Container(),
),
);
await simulateKeyDownEvent(LogicalKeyboardKey.controlLeft);
// This will fail when transit mode is KeyDataTransitMode.rawKeyData
// because a down event for controlRight is synthesized.
expect(events.length, 1);
debugKeyEventSimulatorTransitModeOverride = null;
});
```
And the following this test is ok with `KeyDataTransitMode.rawKeyData` but rightly fails with `KeyDataTransitMode.keyDataThenRawKeyData`:
```dart
testWidgets('Simulates consecutive key down events', (WidgetTester tester) async {
debugKeyEventSimulatorTransitModeOverride = KeyDataTransitMode.rawKeyData;
// Simulating several key down events without key up in between is tolerated
// when transit mode is KeyDataTransitMode.rawKeyData, it will trigger an
// assert on KeyDataTransitMode.keyDataThenRawKeyData.
await simulateKeyDownEvent(LogicalKeyboardKey.arrowDown);
await simulateKeyDownEvent(LogicalKeyboardKey.arrowDown);
debugKeyEventSimulatorTransitModeOverride = null;
});
```
## Related Issue
Related to https://github.com/flutter/flutter/issues/143845
## Tests
Adds two tests.
`DevFSBytesContent` (and it's descendant `DevFSStringContent`) have setters that change the underlying content. These are unused outside of tests, so this PR removes them. Amongst other things, this could help me refactor https://github.com/flutter/flutter/pull/144660 into something that has fewer pitfalls.
This is purely a refactoring.
We should always target the newest, and 34 is the newest. This isn't a requirement yet (like it is for 33+) but presumably it will be made required in the nearish future.
I was doing some debugging on a RenderSliver subclass, and found
that SliverConstraints.toString was missing the precedingScrollExtent
field.
Add that, and add both that field and userScrollDirection to the
`==` and hashCode implementations, which had been skipping them,
so that all three methods now handle all the class's fields.
Partial implementation of https://github.com/flutter/flutter/issues/143348
This enables asset transformation during hot reload (except for web, because that has its own implementation of `DevFS` ð). Asset transformers will be reapplied after changing any asset and performing a hot reload during `flutter run`.
Explicitly handle the case where the iOS device is not paired. On `flutter run` show an error and bail instead of trying and failing to launch on the device.
On this PR:
```
$ flutter run -d 00008110-0009588C2651401E
'iPhone' is not paired. Open Xcode and trust this computer when prompted.
$
```
Fixes https://github.com/flutter/flutter/issues/144447
Closes https://github.com/flutter/flutter/pull/144095
Originally, my aim was just to refactor (as per usual), but while messing around with the `TableBorder.symmetric` constructor, I realized that `borderRadius` was missing!
This pull request makes a few class constructors more efficient, and it fixes#144277 by adding the missing parameter.
<br>
This is for https://github.com/flutter/flutter/issues/127803: a text field should unregister from the scribble scope, when it becomes unfocusable.
When a `FocusNode` has listeners and its `_canRequestFocus` flag is set to true, it adds `+1` to `_focusabilityListeningDescendantCount` of all ancestors until it reaches the first ancestor with `descendantsAreFocusable = false`. When the a `FocusNode`'s `descendantsAreFocusable` changes, all listeners that contributed to its `_focusabilityListeningDescendantCount` will be notified.
## Description
This PR simplifies one external link in a commented section of the Android manifest template.
## Related Issue
Fixes https://github.com/flutter/flutter/issues/144249
## Tests
Documentation only PR.
I was talking with @tvolkert about the complex behavior of Shortcuts when a text field is focused. I created [this dartpad](https://dartpad.dev/?id=0b5c08fa85637422baa84927b7f1ee5f) to illustrate the problem, which shows a key being stolen from a text field by Shortcuts, and how to prevent that using DoNothingAndStopPropagationIntent.
This PR adds a section in the docs explaining how all of this works and how to override this "stealing" problem.
This allows relanding https://github.com/flutter/engine/pull/51056. The patch introduced a change where a static member is initialized from `View.generateViewId()` instead of conditionally using that API. Without an implementation for that in android.jar, the test will fail. The test in here currently is using a fake implementation that creates errors seen below.
See https://logs.chromium.org/logs/flutter/buildbucket/cr-buildbucket/8754827734484522225/+/u/run_plugin_test/stdout#L46564_2 for failure. More detailed failure information is available locally in the `build` folder:
```
Mockito cannot mock this class: class io.flutter.embedding.android.FlutterActivity.
If you're not sure why you're getting this error, please open an issue on GitHub.
Java : 17
JVM vendor name : JetBrains s.r.o.
JVM vendor version : 17.0.7+0-17.0.7b1000.6-10550314
JVM name : OpenJDK 64-Bit Server VM
JVM version : 17.0.7+0-17.0.7b1000.6-10550314
JVM info : mixed mode
OS name : Mac OS X
OS version : 14.3.1
You are seeing this disclaimer because Mockito is configured to create inlined mocks.
You can learn about inline mocks and their limitations under item #39 of the Mockito class javadoc.
Underlying exception : org.mockito.exceptions.base.MockitoException: Cannot instrument class io.flutter.embedding.android.FlutterActivity because it or one of its supertypes could not be initialized
at app//dev.flutter.plugins.integration_test.FlutterDeviceScreenshotTest.getFlutterView_returnsFlutterViewForFlutterActivity(FlutterDeviceScreenshotTest.java:32)
at java.base@17.0.7/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base@17.0.7/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at java.base@17.0.7/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.base@17.0.7/java.lang.reflect.Method.invoke(Unknown Source)
at app//org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
at app//org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at app//org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
at app//org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at app//org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at app//org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
at app//org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
at app//org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
at app//org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
at app//org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
at app//org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
at app//org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
at app//org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
at app//org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
at app//org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at app//org.junit.runners.ParentRunner.run(ParentRunner.java:413)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.runTestClass(JUnitTestClassExecutor.java:110)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:58)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:38)
at org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor.processTestClass(AbstractJUnitTestClassProcessor.java:62)
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:51)
at java.base@17.0.7/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base@17.0.7/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at java.base@17.0.7/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.base@17.0.7/java.lang.reflect.Method.invoke(Unknown Source)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
at jdk.proxy1/jdk.proxy1.$Proxy2.processTestClass(Unknown Source)
at org.gradle.api.internal.tasks.testing.worker.TestWorker$2.run(TestWorker.java:176)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60)
at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56)
at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:133)
at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:71)
at app//worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69)
at app//worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74)
Caused by: org.mockito.exceptions.base.MockitoException: Cannot instrument class io.flutter.embedding.android.FlutterActivity because it or one of its supertypes could not be initialized
at app//net.bytebuddy.TypeCache.findOrInsert(TypeCache.java:168)
at app//net.bytebuddy.TypeCache$WithInlineExpunction.findOrInsert(TypeCache.java:399)
at app//net.bytebuddy.TypeCache.findOrInsert(TypeCache.java:190)
at app//net.bytebuddy.TypeCache$WithInlineExpunction.findOrInsert(TypeCache.java:410)
... 44 more
Caused by: java.lang.RuntimeException: Method generateViewId in android.view.View not mocked. See http://g.co/androidstudio/not-mocked for details.
at android.view.View.generateViewId(View.java)
at io.flutter.embedding.android.FlutterActivity.<clinit>(FlutterActivity.java:218)
at java.base/java.lang.Class.forName0(Native Method)
at java.base/java.lang.Class.forName(Unknown Source)
at org.mockito.internal.creation.bytebuddy.InlineBytecodeGenerator.assureInitialization(InlineBytecodeGenerator.java:236)
at org.mockito.internal.creation.bytebuddy.InlineBytecodeGenerator.triggerRetransformation(InlineBytecodeGenerator.java:261)
at org.mockito.internal.creation.bytebuddy.InlineBytecodeGenerator.mockClass(InlineBytecodeGenerator.java:218)
at org.mockito.internal.creation.bytebuddy.TypeCachingBytecodeGenerator.lambda$mockClass$0(TypeCachingBytecodeGenerator.java:47)
at net.bytebuddy.TypeCache.findOrInsert(TypeCache.java:168)
at net.bytebuddy.TypeCache$WithInlineExpunction.findOrInsert(TypeCache.java:399)
at net.bytebuddy.TypeCache.findOrInsert(TypeCache.java:190)
at net.bytebuddy.TypeCache$WithInlineExpunction.findOrInsert(TypeCache.java:410)
at org.mockito.internal.creation.bytebuddy.TypeCachingBytecodeGenerator.mockClass(TypeCachingBytecodeGenerator.java:40)
at org.mockito.internal.creation.bytebuddy.InlineDelegateByteBuddyMockMaker.createMockType(InlineDelegateByteBuddyMockMaker.java:396)
at org.mockito.internal.creation.bytebuddy.InlineDelegateByteBuddyMockMaker.doCreateMock(InlineDelegateByteBuddyMockMaker.java:355)
at org.mockito.internal.creation.bytebuddy.InlineDelegateByteBuddyMockMaker.createMock(InlineDelegateByteBuddyMockMaker.java:334)
at org.mockito.internal.creation.bytebuddy.InlineByteBuddyMockMaker.createMock(InlineByteBuddyMockMaker.java:56)
at org.mockito.internal.util.MockUtil.createMock(MockUtil.java:99)
at org.mockito.internal.MockitoCore.mock(MockitoCore.java:88)
at org.mockito.Mockito.mock(Mockito.java:2087)
at org.mockito.Mockito.mock(Mockito.java:2002)
... 44 more
```