AndroidHal.cpp (5525B)
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 #include "Hal.h" 7 #include "HalImpl.h" 8 #include "WindowIdentifier.h" 9 #include "AndroidBridge.h" 10 #include "mozilla/dom/network/Constants.h" 11 #include "mozilla/java/GeckoAppShellWrappers.h" 12 #include "mozilla/java/GeckoRuntimeWrappers.h" 13 #include "mozilla/widget/ScreenManager.h" 14 #include "nsPIDOMWindow.h" 15 16 using namespace mozilla::dom; 17 using namespace mozilla::hal; 18 19 namespace mozilla::hal_impl { 20 21 void Vibrate(const nsTArray<uint32_t>& pattern, WindowIdentifier&&) { 22 // Ignore the WindowIdentifier parameter; it's here only because hal::Vibrate, 23 // hal_sandbox::Vibrate, and hal_impl::Vibrate all must have the same 24 // signature. 25 26 // Strangely enough, the Android Java API seems to treat vibrate([0]) as a 27 // nop. But we want to treat vibrate([0]) like CancelVibrate! (Note that we 28 // also need to treat vibrate([]) as a call to CancelVibrate.) 29 bool allZero = true; 30 for (uint32_t i = 0; i < pattern.Length(); i++) { 31 if (pattern[i] != 0) { 32 allZero = false; 33 break; 34 } 35 } 36 37 if (allZero) { 38 hal_impl::CancelVibrate(WindowIdentifier()); 39 return; 40 } 41 42 AndroidBridge* b = AndroidBridge::Bridge(); 43 if (!b) { 44 return; 45 } 46 47 b->Vibrate(pattern); 48 } 49 50 void CancelVibrate(WindowIdentifier&&) { 51 // Ignore WindowIdentifier parameter. 52 53 java::GeckoAppShell::CancelVibrate(); 54 } 55 56 void EnableBatteryNotifications() { 57 java::GeckoAppShell::EnableBatteryNotifications(); 58 } 59 60 void DisableBatteryNotifications() { 61 java::GeckoAppShell::DisableBatteryNotifications(); 62 } 63 64 void GetCurrentBatteryInformation(hal::BatteryInformation* aBatteryInfo) { 65 AndroidBridge::Bridge()->GetCurrentBatteryInformation(aBatteryInfo); 66 } 67 68 void EnableNetworkNotifications() { 69 java::GeckoAppShell::EnableNetworkNotifications(); 70 } 71 72 void DisableNetworkNotifications() { 73 java::GeckoAppShell::DisableNetworkNotifications(); 74 } 75 76 void GetCurrentNetworkInformation(hal::NetworkInformation* aNetworkInfo) { 77 AndroidBridge::Bridge()->GetCurrentNetworkInformation(aNetworkInfo); 78 } 79 80 static bool IsSupportedScreenOrientation(hal::ScreenOrientation aOrientation) { 81 // The Android backend only supports these orientations. 82 static constexpr hal::ScreenOrientation kSupportedOrientations[] = { 83 hal::ScreenOrientation::PortraitPrimary, 84 hal::ScreenOrientation::PortraitSecondary, 85 hal::ScreenOrientation::PortraitPrimary | 86 hal::ScreenOrientation::PortraitSecondary, 87 hal::ScreenOrientation::LandscapePrimary, 88 hal::ScreenOrientation::LandscapeSecondary, 89 hal::ScreenOrientation::LandscapePrimary | 90 hal::ScreenOrientation::LandscapeSecondary, 91 hal::ScreenOrientation::PortraitPrimary | 92 hal::ScreenOrientation::PortraitSecondary | 93 hal::ScreenOrientation::LandscapePrimary | 94 hal::ScreenOrientation::LandscapeSecondary, 95 hal::ScreenOrientation::Default, 96 }; 97 for (auto supportedOrientation : kSupportedOrientations) { 98 if (aOrientation == supportedOrientation) { 99 return true; 100 } 101 } 102 return false; 103 } 104 105 RefPtr<GenericNonExclusivePromise> LockScreenOrientation( 106 const hal::ScreenOrientation& aOrientation) { 107 if (!IsSupportedScreenOrientation(aOrientation)) { 108 NS_WARNING("Unsupported screen orientation type"); 109 return GenericNonExclusivePromise::CreateAndReject( 110 NS_ERROR_DOM_NOT_SUPPORTED_ERR, __func__); 111 } 112 113 java::GeckoRuntime::LocalRef runtime = java::GeckoRuntime::GetInstance(); 114 if (!runtime) { 115 return GenericNonExclusivePromise::CreateAndReject(NS_ERROR_DOM_ABORT_ERR, 116 __func__); 117 } 118 119 hal::ScreenOrientation orientation = [&aOrientation]() { 120 if (aOrientation == hal::ScreenOrientation::Default) { 121 // GeckoView only supports single monitor, so get primary screen data for 122 // natural orientation. 123 RefPtr<widget::Screen> screen = 124 widget::ScreenManager::GetSingleton().GetPrimaryScreen(); 125 return screen->GetDefaultOrientationType(); 126 } 127 return aOrientation; 128 }(); 129 130 auto result = runtime->LockScreenOrientation(uint32_t(orientation)); 131 auto geckoResult = java::GeckoResult::LocalRef(std::move(result)); 132 return GenericNonExclusivePromise::FromGeckoResult(geckoResult) 133 ->Then( 134 GetCurrentSerialEventTarget(), __func__, 135 [](const GenericNonExclusivePromise::ResolveOrRejectValue& aValue) { 136 if (aValue.IsResolve()) { 137 if (aValue.ResolveValue()) { 138 return GenericNonExclusivePromise::CreateAndResolve(true, 139 __func__); 140 } 141 // Delegated orientation controller returns failure for 142 // lock. 143 return GenericNonExclusivePromise::CreateAndReject( 144 NS_ERROR_DOM_ABORT_ERR, __func__); 145 } 146 // Browser side doesn't implement orientation delegate. 147 return GenericNonExclusivePromise::CreateAndReject( 148 NS_ERROR_DOM_NOT_SUPPORTED_ERR, __func__); 149 }); 150 } 151 152 void UnlockScreenOrientation() { 153 java::GeckoRuntime::LocalRef runtime = java::GeckoRuntime::GetInstance(); 154 if (runtime) { 155 runtime->UnlockScreenOrientation(); 156 } 157 } 158 159 } // namespace mozilla::hal_impl