@amazon-devices/expo-network 2.0.9000000002 → 3.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,102 +0,0 @@
1
- import ExpoModulesCore
2
- import SystemConfiguration
3
- import Network
4
-
5
- public final class NetworkModule: Module {
6
- private let monitor = NWPathMonitor()
7
- private let monitorQueue = DispatchQueue.global(qos: .default)
8
-
9
- public func definition() -> ModuleDefinition {
10
- Name("ExpoNetwork")
11
-
12
- OnCreate {
13
- monitor.start(queue: monitorQueue)
14
- }
15
-
16
- AsyncFunction("getIpAddressAsync") { () -> String? in
17
- return try getIPAddress()
18
- }
19
-
20
- AsyncFunction("getNetworkStateAsync") {
21
- return getNetworkStateAsync()
22
- }
23
-
24
- OnDestroy {
25
- monitor.cancel()
26
- }
27
- }
28
-
29
- private func getIPAddress() throws -> String {
30
- var address = "0.0.0.0"
31
- var ifaddr: UnsafeMutablePointer<ifaddrs>?
32
-
33
- let error = getifaddrs(&ifaddr)
34
-
35
- guard error == 0 else {
36
- throw IpAddressException(error)
37
- }
38
-
39
- guard let firstAddr = ifaddr else {
40
- return address
41
- }
42
-
43
- for ifptr in sequence(first: firstAddr, next: { $0.pointee.ifa_next }) {
44
- let temp = ifptr.pointee
45
- let family = temp.ifa_addr.pointee.sa_family
46
-
47
- if family == UInt8(AF_INET) {
48
- let name = String(cString: temp.ifa_name)
49
- if name == "en0" || name == "en1" {
50
- var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST))
51
- getnameinfo(
52
- temp.ifa_addr,
53
- socklen_t(temp.ifa_addr.pointee.sa_len),
54
- &hostname,
55
- socklen_t(hostname.count),
56
- nil,
57
- socklen_t(0),
58
- NI_NUMERICHOST)
59
- address = String(cString: hostname)
60
- }
61
- }
62
- }
63
-
64
- freeifaddrs(ifaddr)
65
- return address
66
- }
67
-
68
- private func getNetworkStateAsync() -> [String: Any] {
69
- let path = monitor.currentPath
70
- let isConnected = path.status == .satisfied
71
- var currentNetworkType = NetworkType.unknown
72
-
73
- if !isConnected {
74
- return [
75
- "type": NetworkType.none.description,
76
- "isConnected": isConnected,
77
- "isInternetReachable": isConnected
78
- ]
79
- }
80
-
81
- let connectionType = NWInterface
82
- .InterfaceType
83
- .allCases
84
- .filter { path.usesInterfaceType($0) }
85
- .first
86
-
87
- switch connectionType {
88
- case .wifi:
89
- currentNetworkType = .wifi
90
- case .cellular:
91
- currentNetworkType = .cellular
92
- default:
93
- currentNetworkType = .unknown
94
- }
95
-
96
- return [
97
- "type": currentNetworkType.description,
98
- "isConnected": isConnected,
99
- "isInternetReachable": isConnected
100
- ]
101
- }
102
- }
@@ -1,28 +0,0 @@
1
- import Network
2
-
3
- extension NWInterface.InterfaceType: CaseIterable {
4
- public static var allCases: [NWInterface.InterfaceType] = [
5
- .other,
6
- .wifi,
7
- .cellular,
8
- .loopback,
9
- .wiredEthernet
10
- ]
11
- }
12
-
13
- enum NetworkType: CustomStringConvertible {
14
- case unknown, wifi, none, cellular
15
-
16
- var description: String {
17
- switch self {
18
- case .wifi:
19
- return "WIFI"
20
- case .cellular:
21
- return "CELLULAR"
22
- case .unknown:
23
- return "UNKNOWN"
24
- case .none:
25
- return "NONE"
26
- }
27
- }
28
- }
@@ -1,55 +0,0 @@
1
- /*
2
- * Copyright (c) 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
- *
4
- * PROPRIETARY/CONFIDENTIAL
5
- *
6
- * Use is subject to license terms.
7
- */
8
-
9
- #include "ExpoNetwork.h"
10
-
11
- #include <Kepler/turbomodule/TMLog.h>
12
- #include <fmt/core.h>
13
-
14
- #include "NetworkInterfaces.h"
15
-
16
- ExpoNetwork::ExpoNetwork() : tbm::KeplerTurboModule("ExpoNetwork") {
17
- TMDEBUG(fmt::format("ExpoNetwork constructor {}", name()));
18
- }
19
-
20
- tbm::Promise ExpoNetwork::getIpAddressAsync() {
21
- return tbm::Promise([](std::shared_ptr<tbm::Promise> promise) {
22
- auto interfaces = NetworkInterfaces();
23
- promise->resolve(interfaces.wlanInterfaceAddress());
24
- });
25
- }
26
-
27
- tbm::Promise ExpoNetwork::getNetworkStateAsync() {
28
- return tbm::Promise([](std::shared_ptr<tbm::Promise> promise) {
29
- try {
30
- auto interfaces = NetworkInterfaces();
31
- bool isConnected = interfaces.isNetworkConnected();
32
-
33
- auto networkState = utils::json::JsonContainer::createJsonObject();
34
- networkState.insert("isConnected", isConnected);
35
- networkState.insert("type", isConnected ? 3 : 0);
36
-
37
- promise->resolve(networkState);
38
- } catch (std::exception& e) {
39
- TMDEBUG(fmt::format("Can't get network state: {}", std::string(e.what())));
40
- promise->reject(std::string{"Can't get network state: " + std::string(e.what())});
41
- }
42
- });
43
- }
44
-
45
- tbm::Promise ExpoNetwork::isAirplaneModeEnabledAsync() {
46
- return tbm::Promise([](std::shared_ptr<tbm::Promise> promise) { promise->resolve(false); });
47
- }
48
-
49
- void ExpoNetwork::aggregateMethods(tbm::MethodAggregator<tbm::KeplerTurboModule>& methodAggregator) const noexcept {
50
- TMDEBUG("methodAggregator");
51
-
52
- methodAggregator.addMethod("getNetworkStateAsync", 0, &ExpoNetwork::getNetworkStateAsync);
53
- methodAggregator.addMethod("getIpAddressAsync", 0, &ExpoNetwork::getIpAddressAsync);
54
- methodAggregator.addMethod("isAirplaneModeEnabledAsync", 0, &ExpoNetwork::isAirplaneModeEnabledAsync);
55
- }
@@ -1,28 +0,0 @@
1
- /*
2
- * Copyright (c) 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
- *
4
- * PROPRIETARY/CONFIDENTIAL
5
- *
6
- * Use is subject to license terms.
7
- */
8
-
9
- #include <Kepler/turbomodule/KeplerTurboModule.h>
10
-
11
- #include "expo-export.h"
12
-
13
- namespace tbm = com::amazon::kepler::turbomodule;
14
-
15
- class EXPO_EXPORT ExpoNetwork : public tbm::KeplerTurboModule {
16
- public:
17
- ExpoNetwork();
18
-
19
- void aggregateMethods(tbm::MethodAggregator<tbm::KeplerTurboModule>& methodAggregator) const noexcept override;
20
-
21
- #ifndef UNIT_TEST
22
- protected:
23
- #endif
24
- tbm::Promise getIpAddressAsync();
25
- tbm::Promise getNetworkStateAsync();
26
- tbm::Promise isAirplaneModeEnabledAsync();
27
-
28
- };
@@ -1,23 +0,0 @@
1
- /*
2
- * Copyright (c) 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
- *
4
- * PROPRIETARY/CONFIDENTIAL
5
- *
6
- * Use is subject to license terms.
7
- */
8
-
9
- #include <Kepler/turbomodule/KeplerTurboModuleRegistration.h>
10
- #include <Kepler/turbomodule/TMLog.h>
11
-
12
- #include "ExpoNetwork.h"
13
-
14
- extern "C" {
15
- __attribute__((visibility("default"))) void autoLinkKeplerTurboModulesV1() noexcept {
16
- TMDEBUG("keplerAutoLinkInitV1 for ExpoNetwork");
17
- KEPLER_REGISTER_TURBO_MODULE_WITH_NAME("ExpoNetwork", ExpoNetwork);
18
- }
19
- }
20
-
21
- int main() {
22
- return 0;
23
- }
@@ -1,75 +0,0 @@
1
- /*
2
- * Copyright (c) 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
- *
4
- * PROPRIETARY/CONFIDENTIAL
5
- *
6
- * Use is subject to license terms.
7
- */
8
-
9
- #include "NetworkInterfaces.h"
10
-
11
- #include <Kepler/turbomodule/TMLog.h>
12
- #include <arpa/inet.h>
13
- #include <fmt/core.h>
14
- #include <ifaddrs.h>
15
- #include <linux/if_link.h>
16
- #include <netdb.h>
17
- #include <stdio.h>
18
- #include <stdlib.h>
19
- #include <sys/socket.h>
20
- #include <sys/wait.h>
21
- #include <unistd.h>
22
-
23
- namespace {
24
- const std::string unresolvedAddress = "0.0.0.0";
25
- const std::string wlanInterfaceName = "wlan0";
26
- } // namespace
27
-
28
- NetworkInterfaces::NetworkInterfaces() {
29
- if (getifaddrs(&ifaddr) == -1) {
30
- throw std::runtime_error("network interfaces info failed to fetch.");
31
- }
32
- }
33
-
34
- NetworkInterfaces::~NetworkInterfaces() {
35
- freeifaddrs(ifaddr);
36
- }
37
-
38
- std::string NetworkInterfaces::wlanInterfaceAddress() {
39
- try {
40
- char host[NI_MAXHOST];
41
-
42
- for (auto* ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next) {
43
- if (ifa->ifa_addr == nullptr) {
44
- continue;
45
- }
46
-
47
- auto ifFamily = ifa->ifa_addr->sa_family;
48
- if (ifFamily == AF_INET && std::string(ifa->ifa_name) == wlanInterfaceName) {
49
- auto nameInfo = getnameinfo(
50
- ifa->ifa_addr,
51
- sizeof(struct sockaddr_in),
52
- host,
53
- NI_MAXHOST,
54
- nullptr,
55
- 0,
56
- NI_NUMERICHOST);
57
- if (nameInfo != 0) {
58
- throw std::runtime_error("wlan interface info failed to fetch.");
59
- }
60
-
61
- return std::string(host);
62
- }
63
- }
64
-
65
- TMDEBUG("No wlan interface found.");
66
- } catch (std::exception& e) {
67
- TMDEBUG(fmt::format("Can't get ip address: {}", std::string(e.what())));
68
- }
69
-
70
- return unresolvedAddress;
71
- }
72
-
73
- bool NetworkInterfaces::isNetworkConnected() {
74
- return wlanInterfaceAddress() != unresolvedAddress;
75
- }
@@ -1,20 +0,0 @@
1
- /*
2
- * Copyright (c) 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
- *
4
- * PROPRIETARY/CONFIDENTIAL
5
- *
6
- * Use is subject to license terms.
7
- */
8
-
9
- #include <string>
10
-
11
- class NetworkInterfaces {
12
- public:
13
- NetworkInterfaces();
14
- ~NetworkInterfaces();
15
- std::string wlanInterfaceAddress();
16
- bool isNetworkConnected();
17
-
18
- private:
19
- struct ifaddrs* ifaddr;
20
- };
@@ -1,147 +0,0 @@
1
- /*
2
- * Copyright (c) 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
- *
4
- * PROPRIETARY/CONFIDENTIAL
5
- *
6
- * Use is subject to license terms.
7
- */
8
-
9
- #include <gmock/gmock-actions.h>
10
- #include <gmock/gmock.h>
11
- #include <gtest/gtest.h>
12
-
13
- #include <iostream>
14
-
15
- #include "../ExpoNetwork.h"
16
- #include "JSObjectsConversion.h"
17
- #include "catch.hpp"
18
-
19
- namespace {
20
- bool isValidIPv4Address(const std::string& s) {
21
- std::stringstream ss(s);
22
- std::string segment;
23
- int segmentCount = 0;
24
-
25
- while (std::getline(ss, segment, '.')) {
26
- ++segmentCount;
27
-
28
- if (segment.empty() || segment.length() > 3 || !std::all_of(segment.begin(), segment.end(), ::isdigit) ||
29
- stoi(segment) > 255 || (segment[0] == '0' && segment.length() > 1)) {
30
- return false;
31
- }
32
- }
33
-
34
- return segmentCount == 4;
35
- }
36
-
37
- void handlePromiseRejection(volta::react::NativeJSObject payload) {
38
- std::string rejectionMessage = std::get<std::string>(payload["message"]);
39
- FAIL(rejectionMessage);
40
- }
41
-
42
- enum NetworkState {
43
- NONE = 0,
44
- WIFI = 3,
45
- };
46
- } // namespace
47
-
48
- SCENARIO("Testing Expo Network module") {
49
- GIVEN("Expo Network module") {
50
- ExpoNetwork networkModule;
51
-
52
- // Unable to test due to lack of 'Promise' support
53
- // WHEN("getIpAddressAsync is called") {
54
- // auto promise = networkModule.getIpAddressAsync();
55
-
56
- // promise.promiseOperation_(std::make_shared<volta::react::Promise>(
57
- // volta::react::Callback([](auto args) {
58
- // THEN("Resolved promise contains valid IP") {
59
- // REQUIRE(args.size() == 1);
60
- // REQUIRE(std::holds_alternative<std::string>(args[0]));
61
-
62
- // auto ipAddress = std::get<std::string>(args[0]);
63
-
64
- // REQUIRE(isValidIPv4Address(ipAddress));
65
- // }
66
- // }),
67
- // volta::react::Callback([](auto args) {
68
- // volta::react::NativeJSObject payload = ExpoUtils::convertJsonContainerToNativeJSObject(
69
- // std::get<utils::json::JsonContainer>(args[0]));
70
- // handlePromiseRejection(payload);
71
- // })));
72
- // }
73
-
74
- // Unable to test due to lack of 'Promise' support
75
- // WHEN("getNetworkStateAsync is called") {
76
- // auto promise = networkModule.getNetworkStateAsync();
77
-
78
- // promise.promiseOperation_(std::make_shared<volta::react::Promise>(
79
- // volta::react::Callback([](auto args) {
80
- // THEN("Resolved promise contains valid network state object") {
81
- // REQUIRE(args.size() == 1);
82
- // REQUIRE(std::holds_alternative<utils::json::JsonContainer>(args[0]));
83
-
84
- // volta::react::NativeJSObject networkState =
85
- // ExpoUtils::convertJsonContainerToNativeJSObject(
86
- // std::get<utils::json::JsonContainer>(args[0]));
87
-
88
- // REQUIRE(std::holds_alternative<int32_t>(networkState["type"]));
89
- // REQUIRE(std::holds_alternative<bool>(networkState["isConnected"]));
90
-
91
- // auto type = std::get<int32_t>(networkState["type"]);
92
- // auto isConnected = std::get<bool>(networkState["isConnected"]);
93
-
94
- // if (isConnected) {
95
- // REQUIRE(type == WIFI);
96
- // } else {
97
- // REQUIRE(type == NONE);
98
- // }
99
- // }
100
- // }),
101
- // volta::react::Callback([](auto args) {
102
- // volta::react::NativeJSObject payload = ExpoUtils::convertJsonContainerToNativeJSObject(
103
- // std::get<utils::json::JsonContainer>(args[0]));
104
- // handlePromiseRejection(payload);
105
- // })));
106
- // }
107
-
108
- // Unable to test due to lack of 'Promise' support
109
- // WHEN("isAirplaneModeEnabledAsync is called") {
110
- // auto promise = networkModule.isAirplaneModeEnabledAsync();
111
-
112
- // promise.promiseOperation_(std::make_shared<volta::react::Promise>(
113
- // volta::react::Callback([](auto args) {
114
- // THEN("Resolved promise contains false boolean") {
115
- // REQUIRE(args.size() == 1);
116
- // REQUIRE(std::holds_alternative<bool>(args[0]));
117
-
118
- // auto isAirplaneModeEnabled = std::get<bool>(args[0]);
119
- // REQUIRE_FALSE(isAirplaneModeEnabled);
120
- // }
121
- // }),
122
- // volta::react::Callback([](auto args) {
123
- // volta::react::NativeJSObject payload = ExpoUtils::convertJsonContainerToNativeJSObject(
124
- // std::get<utils::json::JsonContainer>(args[0]));
125
- // handlePromiseRejection(payload);
126
- // })));
127
- // }
128
-
129
- WHEN("aggregateMethods is called") {
130
- std::weak_ptr<facebook::react::Instance> instance;
131
- networkModule.triggerMethodAggregation(*networkModule.jsQueue_, instance);
132
-
133
- THEN("methodContainerMap contains expected methods") {
134
- REQUIRE(networkModule.methodContainerMap_.find("getIpAddressAsync") !=
135
- networkModule.methodContainerMap_.end());
136
- REQUIRE(networkModule.methodContainerMap_.find("getNetworkStateAsync") !=
137
- networkModule.methodContainerMap_.end());
138
- REQUIRE(networkModule.methodContainerMap_.find("isAirplaneModeEnabledAsync") !=
139
- networkModule.methodContainerMap_.end());
140
- }
141
-
142
- THEN("size of methodContainerMap is increased by addListener and removeListeners") {
143
- REQUIRE(networkModule.methodContainerMap_.size() == 5);
144
- }
145
- }
146
- }
147
- }
@@ -1,8 +0,0 @@
1
- {
2
- "versions": {
3
- "2.0.0": "/com.amazon.kepler.expo_network_2@IExpoNetwork_0",
4
- "2.0.9000000000": "/com.amazon.kepler.expo_network_2@IExpoNetwork_0",
5
- "2.0.9000000001": "/com.amazon.kepler.expo_network_2@IExpoNetwork_0",
6
- "2.0.9000000002": "/com.amazon.kepler.expo_network_2@IExpoNetwork_0"
7
- }
8
- }
@@ -1,80 +0,0 @@
1
- import {KeplerTurboModule, TurboModuleRegistry} from '@amazon-devices/keplerscript-turbomodule-api';
2
- import {NetworkState, NetworkStateType} from './Network.types';
3
-
4
- export {NetworkState, NetworkStateType};
5
-
6
- type NativeModuleNetworkState = {
7
- isConnected: boolean; isInternetReachable: boolean; type: number;
8
- };
9
-
10
- interface Spec extends KeplerTurboModule {
11
- getNetworkStateAsync(): Promise<NativeModuleNetworkState>;
12
- getIpAddressAsync(): Promise<string>;
13
- isAirplaneModeEnabledAsync(): Promise<boolean>;
14
- }
15
-
16
- const nativeModule = TurboModuleRegistry.getEnforcing<Spec>('ExpoNetwork') as Spec;
17
-
18
- const networkStateNumberToType = (num: number): NetworkStateType => {
19
- switch (num) {
20
- case 0:
21
- return NetworkStateType.NONE;
22
- case 1:
23
- return NetworkStateType.UNKNOWN;
24
- case 2:
25
- return NetworkStateType.CELLULAR;
26
- case 3:
27
- return NetworkStateType.WIFI;
28
- case 4:
29
- return NetworkStateType.BLUETOOTH;
30
- case 5:
31
- return NetworkStateType.ETHERNET;
32
- case 6:
33
- return NetworkStateType.WIMAX;
34
- case 7:
35
- return NetworkStateType.VPN;
36
- case 8:
37
- return NetworkStateType.OTHER;
38
- default:
39
- return NetworkStateType.UNKNOWN;
40
- }
41
- };
42
-
43
- async function fetchWithTimeout(url: string) {
44
- const controller = new AbortController();
45
- const id = setTimeout(() => controller.abort(), 800);
46
-
47
- const response = await fetch(url, {signal: controller.signal});
48
- clearTimeout(id);
49
-
50
- return response;
51
- }
52
-
53
- const module = {
54
- async getNetworkStateAsync(): Promise<NetworkState> {
55
- const state = await nativeModule.getNetworkStateAsync();
56
-
57
- let dnsResponseReceived = false;
58
- try {
59
- const response = await fetchWithTimeout('https://dns.google/');
60
- dnsResponseReceived = !!response?.ok;
61
- } catch (error) {
62
- dnsResponseReceived = false;
63
- console.error(error)
64
- }
65
-
66
- return {
67
- type: networkStateNumberToType(state.type),
68
- isConnected: state.isConnected,
69
- isInternetReachable: dnsResponseReceived,
70
- };
71
- },
72
- async getIpAddressAsync(): Promise<string> {
73
- return nativeModule.getIpAddressAsync();
74
- },
75
- async isAirplaneModeEnabledAsync(): Promise<boolean> {
76
- return nativeModule.isAirplaneModeEnabledAsync();
77
- },
78
- };
79
-
80
- export default module;
@@ -1,2 +0,0 @@
1
- import { requireNativeModule } from 'expo-modules-core';
2
- export default requireNativeModule('ExpoNetwork');
@@ -1,21 +0,0 @@
1
- import { NetworkState, NetworkStateType } from './Network.types';
2
-
3
- export default {
4
- async getIpAddressAsync(): Promise<string> {
5
- try {
6
- const resp = await fetch('https://api.ipify.org?format=json');
7
- const data = await resp.json();
8
- return data.ip;
9
- } catch (e) {
10
- throw e;
11
- }
12
- },
13
- async getNetworkStateAsync(): Promise<NetworkState> {
14
- const isOnline = typeof navigator !== 'undefined' && navigator.onLine;
15
- return {
16
- type: isOnline ? NetworkStateType.UNKNOWN : NetworkStateType.NONE,
17
- isConnected: isOnline,
18
- isInternetReachable: isOnline,
19
- };
20
- },
21
- };
package/src/Network.ts DELETED
@@ -1,74 +0,0 @@
1
- import { UnavailabilityError } from 'expo-modules-core';
2
-
3
- import ExpoNetwork from './ExpoNetwork';
4
- import { NetworkState, NetworkStateType } from './Network.types';
5
-
6
- export { NetworkState, NetworkStateType };
7
-
8
- // @needsAudit
9
- /**
10
- * Gets the device's current network connection state.
11
- *
12
- * On web, `navigator.connection.type` is not available on browsers. So if there is an active
13
- * network connection, the field `type` returns `NetworkStateType.UNKNOWN`. Otherwise, it returns
14
- * `NetworkStateType.NONE`.
15
- * @return A `Promise` that fulfils with a `NetworkState` object.
16
- *
17
- * @example
18
- * ```ts
19
- * await Network.getNetworkStateAsync();
20
- * // {
21
- * // type: NetworkStateType.CELLULAR,
22
- * // isConnected: true,
23
- * // isInternetReachable: true,
24
- * // }
25
- * ```
26
- */
27
- export async function getNetworkStateAsync(): Promise<NetworkState> {
28
- if (!ExpoNetwork.getNetworkStateAsync) {
29
- throw new UnavailabilityError('expo-network', 'getNetworkStateAsync');
30
- }
31
- return await ExpoNetwork.getNetworkStateAsync();
32
- }
33
-
34
- // @needsAudit
35
- /**
36
- * Gets the device's current IPv4 address. Returns `0.0.0.0` if the IP address could not be retrieved.
37
- *
38
- * On web, this method uses the third-party [`ipify service`](https://www.ipify.org/) to get the
39
- * public IP address of the current device.
40
- * @return A `Promise` that fulfils with a `string` of the current IP address of the device's main
41
- * network interface. Can only be IPv4 address.
42
- *
43
- * @example
44
- * ```ts
45
- * await Network.getIpAddressAsync();
46
- * // "92.168.32.44"
47
- * ```
48
- */
49
- export async function getIpAddressAsync(): Promise<string> {
50
- if (!ExpoNetwork.getIpAddressAsync) {
51
- throw new UnavailabilityError('expo-network', 'getIpAddressAsync');
52
- }
53
- return await ExpoNetwork.getIpAddressAsync();
54
- }
55
-
56
- // @needsAudit
57
- /**
58
- * Tells if the device is in airplane mode.
59
- * @return Returns a `Promise` that fulfils with a `boolean` value for whether the device is in
60
- * airplane mode or not.
61
- * @platform android
62
- *
63
- * @example
64
- * ```ts
65
- * await Network.isAirplaneModeEnabledAsync();
66
- * // false
67
- * ```
68
- */
69
- export async function isAirplaneModeEnabledAsync(): Promise<boolean> {
70
- if (!ExpoNetwork.isAirplaneModeEnabledAsync) {
71
- throw new UnavailabilityError('expo-network', 'isAirplaneModeEnabledAsync');
72
- }
73
- return await ExpoNetwork.isAirplaneModeEnabledAsync();
74
- }