mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Adds Dark Mode support to new Android embedding (this was accidentally missed previously). (#13215)
This commit is contained in:
parent
98e6d15663
commit
ee91881ccc
@ -4,8 +4,8 @@
|
||||
|
||||
package io.flutter.embedding.android;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Insets;
|
||||
@ -39,6 +39,7 @@ import io.flutter.embedding.engine.FlutterEngine;
|
||||
import io.flutter.embedding.engine.renderer.FlutterRenderer;
|
||||
import io.flutter.embedding.engine.renderer.FlutterUiDisplayListener;
|
||||
import io.flutter.embedding.engine.renderer.RenderSurface;
|
||||
import io.flutter.embedding.engine.systemchannels.SettingsChannel;
|
||||
import io.flutter.plugin.editing.TextInputPlugin;
|
||||
import io.flutter.plugin.platform.PlatformViewsController;
|
||||
import io.flutter.view.AccessibilityBridge;
|
||||
@ -761,10 +762,19 @@ public class FlutterView extends FrameLayout {
|
||||
*
|
||||
* FlutterEngine must be non-null when this method is invoked.
|
||||
*/
|
||||
private void sendUserSettingsToFlutter() {
|
||||
flutterEngine.getSettingsChannel().startMessage()
|
||||
@VisibleForTesting
|
||||
/* package */ void sendUserSettingsToFlutter() {
|
||||
// Lookup the current brightness of the Android OS.
|
||||
boolean isNightModeOn = (getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES;
|
||||
SettingsChannel.PlatformBrightness brightness = isNightModeOn
|
||||
? SettingsChannel.PlatformBrightness.dark
|
||||
: SettingsChannel.PlatformBrightness.light;
|
||||
|
||||
flutterEngine.getSettingsChannel()
|
||||
.startMessage()
|
||||
.setTextScaleFactor(getResources().getConfiguration().fontScale)
|
||||
.setUse24HourFormat(DateFormat.is24HourFormat(getContext()))
|
||||
.setPlatformBrightness(brightness)
|
||||
.send();
|
||||
}
|
||||
|
||||
|
||||
@ -1,12 +1,30 @@
|
||||
package io.flutter.embedding.android;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import static junit.framework.TestCase.assertEquals;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.reset;
|
||||
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 io.flutter.embedding.engine.FlutterJNI;
|
||||
import io.flutter.embedding.engine.dart.DartExecutor;
|
||||
import io.flutter.embedding.engine.loader.FlutterLoader;
|
||||
import io.flutter.embedding.engine.plugins.activity.ActivityControlSurface;
|
||||
import io.flutter.embedding.engine.renderer.FlutterRenderer;
|
||||
import io.flutter.embedding.engine.systemchannels.AccessibilityChannel;
|
||||
import io.flutter.embedding.engine.systemchannels.LifecycleChannel;
|
||||
import io.flutter.embedding.engine.systemchannels.LocalizationChannel;
|
||||
import io.flutter.embedding.engine.systemchannels.NavigationChannel;
|
||||
import io.flutter.embedding.engine.systemchannels.SettingsChannel;
|
||||
import io.flutter.embedding.engine.systemchannels.SystemChannel;
|
||||
import io.flutter.plugin.platform.PlatformViewsController;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@ -14,10 +32,14 @@ import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.mockito.Spy;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import io.flutter.embedding.engine.FlutterEngine;
|
||||
|
||||
@Config(manifest = Config.NONE)
|
||||
@ -44,15 +66,88 @@ public class FlutterViewTest {
|
||||
verify(platformViewsController, times(1)).attachToView(flutterView);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void detachFromFlutterEngine_alertsPlatformViews() {
|
||||
FlutterView flutterView = new FlutterView(RuntimeEnvironment.application);
|
||||
FlutterEngine flutterEngine = spy(new FlutterEngine(RuntimeEnvironment.application, mockFlutterLoader, mockFlutterJni));
|
||||
when(flutterEngine.getPlatformViewsController()).thenReturn(platformViewsController);
|
||||
@Test
|
||||
public void detachFromFlutterEngine_alertsPlatformViews() {
|
||||
FlutterView flutterView = new FlutterView(RuntimeEnvironment.application);
|
||||
FlutterEngine flutterEngine = spy(new FlutterEngine(RuntimeEnvironment.application, mockFlutterLoader, mockFlutterJni));
|
||||
when(flutterEngine.getPlatformViewsController()).thenReturn(platformViewsController);
|
||||
|
||||
flutterView.attachToFlutterEngine(flutterEngine);
|
||||
flutterView.detachFromFlutterEngine();
|
||||
flutterView.attachToFlutterEngine(flutterEngine);
|
||||
flutterView.detachFromFlutterEngine();
|
||||
|
||||
verify(platformViewsController, times(1)).detachFromView();
|
||||
}
|
||||
verify(platformViewsController, times(1)).detachFromView();
|
||||
}
|
||||
|
||||
// TODO(mattcarroll): turn this into an e2e test. GitHub #42990
|
||||
@Test
|
||||
public void itSendsLightPlatformBrightnessToFlutter() {
|
||||
// Setup test.
|
||||
AtomicReference<SettingsChannel.PlatformBrightness> reportedBrightness = new AtomicReference<>();
|
||||
|
||||
// FYI - The default brightness is LIGHT, which is why we don't need to configure it.
|
||||
FlutterView flutterView = new FlutterView(RuntimeEnvironment.application);
|
||||
FlutterEngine flutterEngine = spy(new FlutterEngine(RuntimeEnvironment.application, mockFlutterLoader, mockFlutterJni));
|
||||
|
||||
SettingsChannel fakeSettingsChannel = mock(SettingsChannel.class);
|
||||
SettingsChannel.MessageBuilder fakeMessageBuilder = mock(SettingsChannel.MessageBuilder.class);
|
||||
when(fakeMessageBuilder.setTextScaleFactor(any(Float.class))).thenReturn(fakeMessageBuilder);
|
||||
when(fakeMessageBuilder.setUse24HourFormat(any(Boolean.class))).thenReturn(fakeMessageBuilder);
|
||||
when(fakeMessageBuilder.setPlatformBrightness(any(SettingsChannel.PlatformBrightness.class))).thenAnswer(new Answer<SettingsChannel.MessageBuilder>() {
|
||||
@Override
|
||||
public SettingsChannel.MessageBuilder answer(InvocationOnMock invocation) throws Throwable {
|
||||
reportedBrightness.set((SettingsChannel.PlatformBrightness) invocation.getArguments()[0]);
|
||||
return fakeMessageBuilder;
|
||||
}
|
||||
});
|
||||
when(fakeSettingsChannel.startMessage()).thenReturn(fakeMessageBuilder);
|
||||
when(flutterEngine.getSettingsChannel()).thenReturn(fakeSettingsChannel);
|
||||
|
||||
flutterView.attachToFlutterEngine(flutterEngine);
|
||||
|
||||
// Execute behavior under test.
|
||||
flutterView.sendUserSettingsToFlutter();
|
||||
|
||||
// Verify results.
|
||||
assertEquals(SettingsChannel.PlatformBrightness.light, reportedBrightness.get());
|
||||
}
|
||||
|
||||
// TODO(mattcarroll): turn this into an e2e test. GitHub #42990
|
||||
@Test
|
||||
public void itSendsDarkPlatformBrightnessToFlutter() {
|
||||
// Setup test.
|
||||
AtomicReference<SettingsChannel.PlatformBrightness> reportedBrightness = new AtomicReference<>();
|
||||
|
||||
Context spiedContext = spy(RuntimeEnvironment.application);
|
||||
|
||||
Resources spiedResources = spy(spiedContext.getResources());
|
||||
when(spiedContext.getResources()).thenReturn(spiedResources);
|
||||
|
||||
Configuration spiedConfiguration = spy(spiedResources.getConfiguration());
|
||||
spiedConfiguration.uiMode = (spiedResources.getConfiguration().uiMode | Configuration.UI_MODE_NIGHT_YES) & ~Configuration.UI_MODE_NIGHT_NO;
|
||||
when(spiedResources.getConfiguration()).thenReturn(spiedConfiguration);
|
||||
|
||||
FlutterView flutterView = new FlutterView(spiedContext);
|
||||
FlutterEngine flutterEngine = spy(new FlutterEngine(RuntimeEnvironment.application, mockFlutterLoader, mockFlutterJni));
|
||||
|
||||
SettingsChannel fakeSettingsChannel = mock(SettingsChannel.class);
|
||||
SettingsChannel.MessageBuilder fakeMessageBuilder = mock(SettingsChannel.MessageBuilder.class);
|
||||
when(fakeMessageBuilder.setTextScaleFactor(any(Float.class))).thenReturn(fakeMessageBuilder);
|
||||
when(fakeMessageBuilder.setUse24HourFormat(any(Boolean.class))).thenReturn(fakeMessageBuilder);
|
||||
when(fakeMessageBuilder.setPlatformBrightness(any(SettingsChannel.PlatformBrightness.class))).thenAnswer(new Answer<SettingsChannel.MessageBuilder>() {
|
||||
@Override
|
||||
public SettingsChannel.MessageBuilder answer(InvocationOnMock invocation) throws Throwable {
|
||||
reportedBrightness.set((SettingsChannel.PlatformBrightness) invocation.getArguments()[0]);
|
||||
return fakeMessageBuilder;
|
||||
}
|
||||
});
|
||||
when(fakeSettingsChannel.startMessage()).thenReturn(fakeMessageBuilder);
|
||||
when(flutterEngine.getSettingsChannel()).thenReturn(fakeSettingsChannel);
|
||||
|
||||
// Execute behavior under test.
|
||||
flutterView.attachToFlutterEngine(flutterEngine);
|
||||
flutterView.sendUserSettingsToFlutter();
|
||||
|
||||
// Verify results.
|
||||
assertEquals(SettingsChannel.PlatformBrightness.dark, reportedBrightness.get());
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user