Adds Dark Mode support to new Android embedding (this was accidentally missed previously). (#13215)

This commit is contained in:
Matt Carroll 2019-10-18 12:46:09 -07:00 committed by GitHub
parent 98e6d15663
commit ee91881ccc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 117 additions and 12 deletions

View File

@ -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();
}

View File

@ -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());
}
}