blob: d3d81b7f3cc7d8bdc88f558cd037ab5b0ef66218 [file] [log] [blame]
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
part of dart.ui;
String _decodeUTF8(ByteData message) {
return message != null ? utf8.decoder.convert(message.buffer.asUint8List()) : null;
}
dynamic _decodeJSON(String message) {
return message != null ? json.decode(message) : null;
}
@pragma('vm:entry-point')
void _updateWindowMetrics(double devicePixelRatio,
double width,
double height,
double paddingTop,
double paddingRight,
double paddingBottom,
double paddingLeft,
double viewInsetTop,
double viewInsetRight,
double viewInsetBottom,
double viewInsetLeft) {
window
.._devicePixelRatio = devicePixelRatio
.._physicalSize = new Size(width, height)
.._padding = new WindowPadding._(
top: paddingTop,
right: paddingRight,
bottom: paddingBottom,
left: paddingLeft)
.._viewInsets = new WindowPadding._(
top: viewInsetTop,
right: viewInsetRight,
bottom: viewInsetBottom,
left: viewInsetLeft);
_invoke(window.onMetricsChanged, window._onMetricsChangedZone);
}
typedef _LocaleClosure = String Function();
String _localeClosure() => window.locale.toString();
@pragma('vm:entry-point')
_LocaleClosure _getLocaleClosure() => _localeClosure;
@pragma('vm:entry-point')
void _updateLocales(List<String> locales) {
const int stringsPerLocale = 4;
final int numLocales = locales.length ~/ stringsPerLocale;
window._locales = new List<Locale>(numLocales);
for (int localeIndex = 0; localeIndex < numLocales; localeIndex++) {
window._locales[localeIndex] = new Locale(locales[localeIndex * stringsPerLocale],
locales[localeIndex * stringsPerLocale + 1]);
}
_invoke(window.onLocaleChanged, window._onLocaleChangedZone);
}
@pragma('vm:entry-point')
void _updateUserSettingsData(String jsonData) {
final Map<String, dynamic> data = json.decode(jsonData);
_updateTextScaleFactor(data['textScaleFactor'].toDouble());
_updateAlwaysUse24HourFormat(data['alwaysUse24HourFormat']);
}
void _updateTextScaleFactor(double textScaleFactor) {
window._textScaleFactor = textScaleFactor;
_invoke(window.onTextScaleFactorChanged, window._onTextScaleFactorChangedZone);
}
void _updateAlwaysUse24HourFormat(bool alwaysUse24HourFormat) {
window._alwaysUse24HourFormat = alwaysUse24HourFormat;
}
@pragma('vm:entry-point')
void _updateSemanticsEnabled(bool enabled) {
window._semanticsEnabled = enabled;
_invoke(window.onSemanticsEnabledChanged, window._onSemanticsEnabledChangedZone);
}
@pragma('vm:entry-point')
void _updateAccessibilityFeatures(int values) {
final AccessibilityFeatures newFeatures = new AccessibilityFeatures._(values);
if (newFeatures == window._accessibilityFeatures)
return;
window._accessibilityFeatures = newFeatures;
_invoke(window.onAccessibilityFeaturesChanged, window._onAccessibilityFlagsChangedZone);
}
@pragma('vm:entry-point')
void _dispatchPlatformMessage(String name, ByteData data, int responseId) {
if (window.onPlatformMessage != null) {
_invoke3<String, ByteData, PlatformMessageResponseCallback>(
window.onPlatformMessage,
window._onPlatformMessageZone,
name,
data,
(ByteData responseData) {
window._respondToPlatformMessage(responseId, responseData);
},
);
} else {
window._respondToPlatformMessage(responseId, null);
}
}
@pragma('vm:entry-point')
void _dispatchPointerDataPacket(ByteData packet) {
if (window.onPointerDataPacket != null)
_invoke1<PointerDataPacket>(window.onPointerDataPacket, window._onPointerDataPacketZone, _unpackPointerDataPacket(packet));
}
@pragma('vm:entry-point')
void _dispatchSemanticsAction(int id, int action, ByteData args) {
_invoke3<int, SemanticsAction, ByteData>(
window.onSemanticsAction,
window._onSemanticsActionZone,
id,
SemanticsAction.values[action],
args,
);
}
@pragma('vm:entry-point')
void _beginFrame(int microseconds) {
_invoke1<Duration>(window.onBeginFrame, window._onBeginFrameZone, new Duration(microseconds: microseconds));
}
@pragma('vm:entry-point')
void _drawFrame() {
_invoke(window.onDrawFrame, window._onDrawFrameZone);
}
/// Invokes [callback] inside the given [zone].
void _invoke(void callback(), Zone zone) {
if (callback == null)
return;
assert(zone != null);
if (identical(zone, Zone.current)) {
callback();
} else {
zone.runGuarded(callback);
}
}
/// Invokes [callback] inside the given [zone] passing it [arg].
void _invoke1<A>(void callback(A a), Zone zone, A arg) {
if (callback == null)
return;
assert(zone != null);
if (identical(zone, Zone.current)) {
callback(arg);
} else {
zone.runUnaryGuarded<A>(callback, arg);
}
}
/// Invokes [callback] inside the given [zone] passing it [arg1] and [arg2].
void _invoke2<A1, A2>(void callback(A1 a1, A2 a2), Zone zone, A1 arg1, A2 arg2) {
if (callback == null)
return;
assert(zone != null);
if (identical(zone, Zone.current)) {
callback(arg1, arg2);
} else {
zone.runBinaryGuarded<A1, A2>(callback, arg1, arg2);
}
}
/// Invokes [callback] inside the given [zone] passing it [arg1], [arg2] and [arg3].
void _invoke3<A1, A2, A3>(void callback(A1 a1, A2 a2, A3 a3), Zone zone, A1 arg1, A2 arg2, A3 arg3) {
if (callback == null)
return;
assert(zone != null);
if (identical(zone, Zone.current)) {
callback(arg1, arg2, arg3);
} else {
zone.runGuarded(() {
callback(arg1, arg2, arg3);
});
}
}
// If this value changes, update the encoding code in the following files:
//
// * pointer_data.cc
// * FlutterView.java
const int _kPointerDataFieldCount = 19;
PointerDataPacket _unpackPointerDataPacket(ByteData packet) {
const int kStride = Int64List.bytesPerElement;
const int kBytesPerPointerData = _kPointerDataFieldCount * kStride;
final int length = packet.lengthInBytes ~/ kBytesPerPointerData;
assert(length * kBytesPerPointerData == packet.lengthInBytes);
final List<PointerData> data = new List<PointerData>(length);
for (int i = 0; i < length; ++i) {
int offset = i * _kPointerDataFieldCount;
data[i] = new PointerData(
timeStamp: new Duration(microseconds: packet.getInt64(kStride * offset++, _kFakeHostEndian)),
change: PointerChange.values[packet.getInt64(kStride * offset++, _kFakeHostEndian)],
kind: PointerDeviceKind.values[packet.getInt64(kStride * offset++, _kFakeHostEndian)],
device: packet.getInt64(kStride * offset++, _kFakeHostEndian),
physicalX: packet.getFloat64(kStride * offset++, _kFakeHostEndian),
physicalY: packet.getFloat64(kStride * offset++, _kFakeHostEndian),
buttons: packet.getInt64(kStride * offset++, _kFakeHostEndian),
obscured: packet.getInt64(kStride * offset++, _kFakeHostEndian) != 0,
pressure: packet.getFloat64(kStride * offset++, _kFakeHostEndian),
pressureMin: packet.getFloat64(kStride * offset++, _kFakeHostEndian),
pressureMax: packet.getFloat64(kStride * offset++, _kFakeHostEndian),
distance: packet.getFloat64(kStride * offset++, _kFakeHostEndian),
distanceMax: packet.getFloat64(kStride * offset++, _kFakeHostEndian),
radiusMajor: packet.getFloat64(kStride * offset++, _kFakeHostEndian),
radiusMinor: packet.getFloat64(kStride * offset++, _kFakeHostEndian),
radiusMin: packet.getFloat64(kStride * offset++, _kFakeHostEndian),
radiusMax: packet.getFloat64(kStride * offset++, _kFakeHostEndian),
orientation: packet.getFloat64(kStride * offset++, _kFakeHostEndian),
tilt: packet.getFloat64(kStride * offset++, _kFakeHostEndian)
);
assert(offset == (i + 1) * _kPointerDataFieldCount);
}
return new PointerDataPacket(data: data);
}