Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
michael@0 | 1 | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
michael@0 | 2 | /* Copyright 2012 Mozilla Foundation and Mozilla contributors |
michael@0 | 3 | * |
michael@0 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
michael@0 | 5 | * you may not use this file except in compliance with the License. |
michael@0 | 6 | * You may obtain a copy of the License at |
michael@0 | 7 | * |
michael@0 | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
michael@0 | 9 | * |
michael@0 | 10 | * Unless required by applicable law or agreed to in writing, software |
michael@0 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
michael@0 | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
michael@0 | 13 | * See the License for the specific language governing permissions and |
michael@0 | 14 | * limitations under the License. |
michael@0 | 15 | */ |
michael@0 | 16 | |
michael@0 | 17 | #include <android/log.h> |
michael@0 | 18 | #include <fcntl.h> |
michael@0 | 19 | #include <sysutils/NetlinkEvent.h> |
michael@0 | 20 | #include <cutils/properties.h> |
michael@0 | 21 | |
michael@0 | 22 | #include "base/message_loop.h" |
michael@0 | 23 | |
michael@0 | 24 | #include "Hal.h" |
michael@0 | 25 | #include "mozilla/FileUtils.h" |
michael@0 | 26 | #include "mozilla/RefPtr.h" |
michael@0 | 27 | #include "mozilla/Monitor.h" |
michael@0 | 28 | #include "nsPrintfCString.h" |
michael@0 | 29 | #include "nsXULAppAPI.h" |
michael@0 | 30 | #include "nsThreadUtils.h" |
michael@0 | 31 | #include "UeventPoller.h" |
michael@0 | 32 | |
michael@0 | 33 | using namespace mozilla::hal; |
michael@0 | 34 | |
michael@0 | 35 | #define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GonkSwitch" , ## args) |
michael@0 | 36 | |
michael@0 | 37 | #define SWITCH_HEADSET_DEVPATH "/devices/virtual/switch/h2w" |
michael@0 | 38 | #define SWITCH_USB_DEVPATH_GB "/devices/virtual/switch/usb_configuration" |
michael@0 | 39 | #define SWITCH_USB_DEVPATH_ICS "/devices/virtual/android_usb/android0" |
michael@0 | 40 | |
michael@0 | 41 | namespace mozilla { |
michael@0 | 42 | namespace hal_impl { |
michael@0 | 43 | /** |
michael@0 | 44 | * The uevent for a usb on GB insertion looks like: |
michael@0 | 45 | * |
michael@0 | 46 | * change@/devices/virtual/switch/usb_configuration |
michael@0 | 47 | * ACTION=change |
michael@0 | 48 | * DEVPATH=/devices/virtual/switch/usb_configuration |
michael@0 | 49 | * SUBSYSTEM=switch |
michael@0 | 50 | * SWITCH_NAME=usb_configuration |
michael@0 | 51 | * SWITCH_STATE=0 |
michael@0 | 52 | * SEQNUM=5038 |
michael@0 | 53 | */ |
michael@0 | 54 | class SwitchHandler |
michael@0 | 55 | { |
michael@0 | 56 | public: |
michael@0 | 57 | NS_INLINE_DECL_REFCOUNTING(SwitchHandler) |
michael@0 | 58 | |
michael@0 | 59 | SwitchHandler(const char* aDevPath, SwitchDevice aDevice) |
michael@0 | 60 | : mDevPath(aDevPath), |
michael@0 | 61 | mState(SWITCH_STATE_UNKNOWN), |
michael@0 | 62 | mDevice(aDevice) |
michael@0 | 63 | { |
michael@0 | 64 | GetInitialState(); |
michael@0 | 65 | } |
michael@0 | 66 | |
michael@0 | 67 | virtual ~SwitchHandler() |
michael@0 | 68 | { |
michael@0 | 69 | } |
michael@0 | 70 | |
michael@0 | 71 | bool CheckEvent(NetlinkEvent* aEvent) |
michael@0 | 72 | { |
michael@0 | 73 | if (strcmp(GetSubsystem(), aEvent->getSubsystem()) || |
michael@0 | 74 | strcmp(mDevPath, aEvent->findParam("DEVPATH"))) { |
michael@0 | 75 | return false; |
michael@0 | 76 | } |
michael@0 | 77 | |
michael@0 | 78 | mState = ConvertState(GetStateString(aEvent)); |
michael@0 | 79 | return mState != SWITCH_STATE_UNKNOWN; |
michael@0 | 80 | } |
michael@0 | 81 | |
michael@0 | 82 | SwitchState GetState() |
michael@0 | 83 | { |
michael@0 | 84 | return mState; |
michael@0 | 85 | } |
michael@0 | 86 | |
michael@0 | 87 | SwitchDevice GetType() |
michael@0 | 88 | { |
michael@0 | 89 | return mDevice; |
michael@0 | 90 | } |
michael@0 | 91 | protected: |
michael@0 | 92 | virtual const char* GetSubsystem() |
michael@0 | 93 | { |
michael@0 | 94 | return "switch"; |
michael@0 | 95 | } |
michael@0 | 96 | |
michael@0 | 97 | virtual const char* GetStateString(NetlinkEvent* aEvent) |
michael@0 | 98 | { |
michael@0 | 99 | return aEvent->findParam("SWITCH_STATE"); |
michael@0 | 100 | } |
michael@0 | 101 | |
michael@0 | 102 | void GetInitialState() |
michael@0 | 103 | { |
michael@0 | 104 | nsPrintfCString statePath("/sys%s/state", mDevPath); |
michael@0 | 105 | int fd = open(statePath.get(), O_RDONLY); |
michael@0 | 106 | if (fd <= 0) { |
michael@0 | 107 | return; |
michael@0 | 108 | } |
michael@0 | 109 | |
michael@0 | 110 | ScopedClose autoClose(fd); |
michael@0 | 111 | char state[16]; |
michael@0 | 112 | ssize_t bytesRead = read(fd, state, sizeof(state)); |
michael@0 | 113 | if (bytesRead < 0) { |
michael@0 | 114 | LOG("Read data from %s fails", statePath.get()); |
michael@0 | 115 | return; |
michael@0 | 116 | } |
michael@0 | 117 | |
michael@0 | 118 | if (state[bytesRead - 1] == '\n') { |
michael@0 | 119 | bytesRead--; |
michael@0 | 120 | } |
michael@0 | 121 | |
michael@0 | 122 | state[bytesRead] = '\0'; |
michael@0 | 123 | mState = ConvertState(state); |
michael@0 | 124 | } |
michael@0 | 125 | |
michael@0 | 126 | virtual SwitchState ConvertState(const char* aState) |
michael@0 | 127 | { |
michael@0 | 128 | MOZ_ASSERT(aState); |
michael@0 | 129 | return aState[0] == '0' ? SWITCH_STATE_OFF : SWITCH_STATE_ON; |
michael@0 | 130 | } |
michael@0 | 131 | |
michael@0 | 132 | const char* mDevPath; |
michael@0 | 133 | SwitchState mState; |
michael@0 | 134 | SwitchDevice mDevice; |
michael@0 | 135 | }; |
michael@0 | 136 | |
michael@0 | 137 | /** |
michael@0 | 138 | * The uevent delivered for the USB configuration under ICS looks like, |
michael@0 | 139 | * |
michael@0 | 140 | * change@/devices/virtual/android_usb/android0 |
michael@0 | 141 | * ACTION=change |
michael@0 | 142 | * DEVPATH=/devices/virtual/android_usb/android0 |
michael@0 | 143 | * SUBSYSTEM=android_usb |
michael@0 | 144 | * USB_STATE=CONFIGURED |
michael@0 | 145 | * SEQNUM=1802 |
michael@0 | 146 | */ |
michael@0 | 147 | class SwitchHandlerUsbIcs: public SwitchHandler |
michael@0 | 148 | { |
michael@0 | 149 | public: |
michael@0 | 150 | SwitchHandlerUsbIcs(const char* aDevPath) : SwitchHandler(aDevPath, SWITCH_USB) |
michael@0 | 151 | { |
michael@0 | 152 | SwitchHandler::GetInitialState(); |
michael@0 | 153 | } |
michael@0 | 154 | |
michael@0 | 155 | virtual ~SwitchHandlerUsbIcs() { } |
michael@0 | 156 | |
michael@0 | 157 | protected: |
michael@0 | 158 | virtual const char* GetSubsystem() |
michael@0 | 159 | { |
michael@0 | 160 | return "android_usb"; |
michael@0 | 161 | } |
michael@0 | 162 | |
michael@0 | 163 | virtual const char* GetStateString(NetlinkEvent* aEvent) |
michael@0 | 164 | { |
michael@0 | 165 | return aEvent->findParam("USB_STATE"); |
michael@0 | 166 | } |
michael@0 | 167 | |
michael@0 | 168 | SwitchState ConvertState(const char* aState) |
michael@0 | 169 | { |
michael@0 | 170 | MOZ_ASSERT(aState); |
michael@0 | 171 | return strcmp(aState, "CONFIGURED") == 0 ? SWITCH_STATE_ON : SWITCH_STATE_OFF; |
michael@0 | 172 | } |
michael@0 | 173 | }; |
michael@0 | 174 | |
michael@0 | 175 | /** |
michael@0 | 176 | * The uevent delivered for the headset under ICS looks like, |
michael@0 | 177 | * |
michael@0 | 178 | * change@/devices/virtual/switch/h2w |
michael@0 | 179 | * ACTION=change |
michael@0 | 180 | * DEVPATH=/devices/virtual/switch/h2w |
michael@0 | 181 | * SUBSYSTEM=switch |
michael@0 | 182 | * SWITCH_NAME=h2w |
michael@0 | 183 | * SWITCH_STATE=2 // Headset with no mic |
michael@0 | 184 | * SEQNUM=2581 |
michael@0 | 185 | * On Otoro, SWITCH_NAME could be Headset/No Device when plug/unplug. |
michael@0 | 186 | * change@/devices/virtual/switch/h2w |
michael@0 | 187 | * ACTION=change |
michael@0 | 188 | * DEVPATH=/devices/virtual/switch/h2w |
michael@0 | 189 | * SUBSYSTEM=switch |
michael@0 | 190 | * SWITCH_NAME=Headset |
michael@0 | 191 | * SWITCH_STATE=1 // Headset with mic |
michael@0 | 192 | * SEQNUM=1602 |
michael@0 | 193 | */ |
michael@0 | 194 | class SwitchHandlerHeadphone: public SwitchHandler |
michael@0 | 195 | { |
michael@0 | 196 | public: |
michael@0 | 197 | SwitchHandlerHeadphone(const char* aDevPath) : |
michael@0 | 198 | SwitchHandler(aDevPath, SWITCH_HEADPHONES) |
michael@0 | 199 | { |
michael@0 | 200 | SwitchHandler::GetInitialState(); |
michael@0 | 201 | } |
michael@0 | 202 | |
michael@0 | 203 | virtual ~SwitchHandlerHeadphone() { } |
michael@0 | 204 | |
michael@0 | 205 | protected: |
michael@0 | 206 | SwitchState ConvertState(const char* aState) |
michael@0 | 207 | { |
michael@0 | 208 | MOZ_ASSERT(aState); |
michael@0 | 209 | |
michael@0 | 210 | return aState[0] == '0' ? SWITCH_STATE_OFF : |
michael@0 | 211 | (aState[0] == '1' ? SWITCH_STATE_HEADSET : SWITCH_STATE_HEADPHONE); |
michael@0 | 212 | } |
michael@0 | 213 | }; |
michael@0 | 214 | |
michael@0 | 215 | |
michael@0 | 216 | typedef nsTArray<RefPtr<SwitchHandler> > SwitchHandlerArray; |
michael@0 | 217 | |
michael@0 | 218 | class SwitchEventRunnable : public nsRunnable |
michael@0 | 219 | { |
michael@0 | 220 | public: |
michael@0 | 221 | SwitchEventRunnable(SwitchEvent& aEvent) : mEvent(aEvent) |
michael@0 | 222 | { |
michael@0 | 223 | } |
michael@0 | 224 | |
michael@0 | 225 | NS_IMETHOD Run() |
michael@0 | 226 | { |
michael@0 | 227 | NotifySwitchChange(mEvent); |
michael@0 | 228 | return NS_OK; |
michael@0 | 229 | } |
michael@0 | 230 | private: |
michael@0 | 231 | SwitchEvent mEvent; |
michael@0 | 232 | }; |
michael@0 | 233 | |
michael@0 | 234 | class SwitchEventObserver MOZ_FINAL : public IUeventObserver |
michael@0 | 235 | { |
michael@0 | 236 | ~SwitchEventObserver() |
michael@0 | 237 | { |
michael@0 | 238 | mHandler.Clear(); |
michael@0 | 239 | } |
michael@0 | 240 | |
michael@0 | 241 | public: |
michael@0 | 242 | NS_INLINE_DECL_REFCOUNTING(SwitchEventObserver) |
michael@0 | 243 | SwitchEventObserver() : mEnableCount(0) |
michael@0 | 244 | { |
michael@0 | 245 | Init(); |
michael@0 | 246 | } |
michael@0 | 247 | |
michael@0 | 248 | int GetEnableCount() |
michael@0 | 249 | { |
michael@0 | 250 | return mEnableCount; |
michael@0 | 251 | } |
michael@0 | 252 | |
michael@0 | 253 | void EnableSwitch(SwitchDevice aDevice) |
michael@0 | 254 | { |
michael@0 | 255 | mEventInfo[aDevice].mEnabled = true; |
michael@0 | 256 | mEnableCount++; |
michael@0 | 257 | } |
michael@0 | 258 | |
michael@0 | 259 | void DisableSwitch(SwitchDevice aDevice) |
michael@0 | 260 | { |
michael@0 | 261 | mEventInfo[aDevice].mEnabled = false; |
michael@0 | 262 | mEnableCount--; |
michael@0 | 263 | } |
michael@0 | 264 | |
michael@0 | 265 | void Notify(const NetlinkEvent& aEvent) |
michael@0 | 266 | { |
michael@0 | 267 | SwitchState currState; |
michael@0 | 268 | |
michael@0 | 269 | SwitchDevice device = GetEventInfo(aEvent, currState); |
michael@0 | 270 | if (device == SWITCH_DEVICE_UNKNOWN) { |
michael@0 | 271 | return; |
michael@0 | 272 | } |
michael@0 | 273 | |
michael@0 | 274 | EventInfo& info = mEventInfo[device]; |
michael@0 | 275 | if (currState == info.mEvent.status()) { |
michael@0 | 276 | return; |
michael@0 | 277 | } |
michael@0 | 278 | |
michael@0 | 279 | info.mEvent.status() = currState; |
michael@0 | 280 | |
michael@0 | 281 | if (info.mEnabled) { |
michael@0 | 282 | NS_DispatchToMainThread(new SwitchEventRunnable(info.mEvent)); |
michael@0 | 283 | } |
michael@0 | 284 | } |
michael@0 | 285 | |
michael@0 | 286 | void Notify(SwitchDevice aDevice, SwitchState aState) |
michael@0 | 287 | { |
michael@0 | 288 | EventInfo& info = mEventInfo[aDevice]; |
michael@0 | 289 | if (aState == info.mEvent.status()) { |
michael@0 | 290 | return; |
michael@0 | 291 | } |
michael@0 | 292 | |
michael@0 | 293 | info.mEvent.status() = aState; |
michael@0 | 294 | |
michael@0 | 295 | if (info.mEnabled) { |
michael@0 | 296 | NS_DispatchToMainThread(new SwitchEventRunnable(info.mEvent)); |
michael@0 | 297 | } |
michael@0 | 298 | } |
michael@0 | 299 | |
michael@0 | 300 | SwitchState GetCurrentInformation(SwitchDevice aDevice) |
michael@0 | 301 | { |
michael@0 | 302 | return mEventInfo[aDevice].mEvent.status(); |
michael@0 | 303 | } |
michael@0 | 304 | |
michael@0 | 305 | void NotifyAnEvent(SwitchDevice aDevice) |
michael@0 | 306 | { |
michael@0 | 307 | EventInfo& info = mEventInfo[aDevice]; |
michael@0 | 308 | if (info.mEvent.status() != SWITCH_STATE_UNKNOWN) { |
michael@0 | 309 | NS_DispatchToMainThread(new SwitchEventRunnable(info.mEvent)); |
michael@0 | 310 | } |
michael@0 | 311 | } |
michael@0 | 312 | private: |
michael@0 | 313 | class EventInfo |
michael@0 | 314 | { |
michael@0 | 315 | public: |
michael@0 | 316 | EventInfo() : mEnabled(false) |
michael@0 | 317 | { |
michael@0 | 318 | mEvent.status() = SWITCH_STATE_UNKNOWN; |
michael@0 | 319 | mEvent.device() = SWITCH_DEVICE_UNKNOWN; |
michael@0 | 320 | } |
michael@0 | 321 | SwitchEvent mEvent; |
michael@0 | 322 | bool mEnabled; |
michael@0 | 323 | }; |
michael@0 | 324 | |
michael@0 | 325 | EventInfo mEventInfo[NUM_SWITCH_DEVICE]; |
michael@0 | 326 | size_t mEnableCount; |
michael@0 | 327 | SwitchHandlerArray mHandler; |
michael@0 | 328 | |
michael@0 | 329 | void Init() |
michael@0 | 330 | { |
michael@0 | 331 | char value[PROPERTY_VALUE_MAX]; |
michael@0 | 332 | property_get("ro.moz.devinputjack", value, "0"); |
michael@0 | 333 | bool headphonesFromInputDev = !strcmp(value, "1"); |
michael@0 | 334 | |
michael@0 | 335 | if (!headphonesFromInputDev) { |
michael@0 | 336 | mHandler.AppendElement(new SwitchHandlerHeadphone(SWITCH_HEADSET_DEVPATH)); |
michael@0 | 337 | } else { |
michael@0 | 338 | // If headphone status will be notified from input dev then initialize |
michael@0 | 339 | // status to "off" and wait for event notification. |
michael@0 | 340 | mEventInfo[SWITCH_HEADPHONES].mEvent.device() = SWITCH_HEADPHONES; |
michael@0 | 341 | mEventInfo[SWITCH_HEADPHONES].mEvent.status() = SWITCH_STATE_OFF; |
michael@0 | 342 | } |
michael@0 | 343 | mHandler.AppendElement(new SwitchHandler(SWITCH_USB_DEVPATH_GB, SWITCH_USB)); |
michael@0 | 344 | mHandler.AppendElement(new SwitchHandlerUsbIcs(SWITCH_USB_DEVPATH_ICS)); |
michael@0 | 345 | |
michael@0 | 346 | SwitchHandlerArray::index_type handlerIndex; |
michael@0 | 347 | SwitchHandlerArray::size_type numHandlers = mHandler.Length(); |
michael@0 | 348 | |
michael@0 | 349 | for (handlerIndex = 0; handlerIndex < numHandlers; handlerIndex++) { |
michael@0 | 350 | SwitchState state = mHandler[handlerIndex]->GetState(); |
michael@0 | 351 | if (state == SWITCH_STATE_UNKNOWN) { |
michael@0 | 352 | continue; |
michael@0 | 353 | } |
michael@0 | 354 | |
michael@0 | 355 | SwitchDevice device = mHandler[handlerIndex]->GetType(); |
michael@0 | 356 | mEventInfo[device].mEvent.device() = device; |
michael@0 | 357 | mEventInfo[device].mEvent.status() = state; |
michael@0 | 358 | } |
michael@0 | 359 | } |
michael@0 | 360 | |
michael@0 | 361 | SwitchDevice GetEventInfo(const NetlinkEvent& aEvent, SwitchState& aState) |
michael@0 | 362 | { |
michael@0 | 363 | //working around the android code not being const-correct |
michael@0 | 364 | NetlinkEvent *e = const_cast<NetlinkEvent*>(&aEvent); |
michael@0 | 365 | |
michael@0 | 366 | for (size_t i = 0; i < mHandler.Length(); i++) { |
michael@0 | 367 | if (mHandler[i]->CheckEvent(e)) { |
michael@0 | 368 | aState = mHandler[i]->GetState(); |
michael@0 | 369 | return mHandler[i]->GetType(); |
michael@0 | 370 | } |
michael@0 | 371 | } |
michael@0 | 372 | return SWITCH_DEVICE_UNKNOWN; |
michael@0 | 373 | } |
michael@0 | 374 | }; |
michael@0 | 375 | |
michael@0 | 376 | static RefPtr<SwitchEventObserver> sSwitchObserver; |
michael@0 | 377 | |
michael@0 | 378 | static void |
michael@0 | 379 | InitializeResourceIfNeed() |
michael@0 | 380 | { |
michael@0 | 381 | if (!sSwitchObserver) { |
michael@0 | 382 | sSwitchObserver = new SwitchEventObserver(); |
michael@0 | 383 | RegisterUeventListener(sSwitchObserver); |
michael@0 | 384 | } |
michael@0 | 385 | } |
michael@0 | 386 | |
michael@0 | 387 | static void |
michael@0 | 388 | ReleaseResourceIfNeed() |
michael@0 | 389 | { |
michael@0 | 390 | if (sSwitchObserver->GetEnableCount() == 0) { |
michael@0 | 391 | UnregisterUeventListener(sSwitchObserver); |
michael@0 | 392 | sSwitchObserver = nullptr; |
michael@0 | 393 | } |
michael@0 | 394 | } |
michael@0 | 395 | |
michael@0 | 396 | static void |
michael@0 | 397 | EnableSwitchNotificationsIOThread(SwitchDevice aDevice, Monitor *aMonitor) |
michael@0 | 398 | { |
michael@0 | 399 | InitializeResourceIfNeed(); |
michael@0 | 400 | sSwitchObserver->EnableSwitch(aDevice); |
michael@0 | 401 | { |
michael@0 | 402 | MonitorAutoLock lock(*aMonitor); |
michael@0 | 403 | lock.Notify(); |
michael@0 | 404 | } |
michael@0 | 405 | |
michael@0 | 406 | // Notify the latest state if IO thread has the information. |
michael@0 | 407 | if (sSwitchObserver->GetEnableCount() > 1) { |
michael@0 | 408 | sSwitchObserver->NotifyAnEvent(aDevice); |
michael@0 | 409 | } |
michael@0 | 410 | } |
michael@0 | 411 | |
michael@0 | 412 | void |
michael@0 | 413 | EnableSwitchNotifications(SwitchDevice aDevice) |
michael@0 | 414 | { |
michael@0 | 415 | Monitor monitor("EnableSwitch.monitor"); |
michael@0 | 416 | { |
michael@0 | 417 | MonitorAutoLock lock(monitor); |
michael@0 | 418 | XRE_GetIOMessageLoop()->PostTask( |
michael@0 | 419 | FROM_HERE, |
michael@0 | 420 | NewRunnableFunction(EnableSwitchNotificationsIOThread, aDevice, &monitor)); |
michael@0 | 421 | lock.Wait(); |
michael@0 | 422 | } |
michael@0 | 423 | } |
michael@0 | 424 | |
michael@0 | 425 | static void |
michael@0 | 426 | DisableSwitchNotificationsIOThread(SwitchDevice aDevice) |
michael@0 | 427 | { |
michael@0 | 428 | MOZ_ASSERT(sSwitchObserver->GetEnableCount()); |
michael@0 | 429 | sSwitchObserver->DisableSwitch(aDevice); |
michael@0 | 430 | ReleaseResourceIfNeed(); |
michael@0 | 431 | } |
michael@0 | 432 | |
michael@0 | 433 | void |
michael@0 | 434 | DisableSwitchNotifications(SwitchDevice aDevice) |
michael@0 | 435 | { |
michael@0 | 436 | XRE_GetIOMessageLoop()->PostTask( |
michael@0 | 437 | FROM_HERE, |
michael@0 | 438 | NewRunnableFunction(DisableSwitchNotificationsIOThread, aDevice)); |
michael@0 | 439 | } |
michael@0 | 440 | |
michael@0 | 441 | SwitchState |
michael@0 | 442 | GetCurrentSwitchState(SwitchDevice aDevice) |
michael@0 | 443 | { |
michael@0 | 444 | MOZ_ASSERT(sSwitchObserver && sSwitchObserver->GetEnableCount()); |
michael@0 | 445 | return sSwitchObserver->GetCurrentInformation(aDevice); |
michael@0 | 446 | } |
michael@0 | 447 | |
michael@0 | 448 | static void |
michael@0 | 449 | NotifySwitchStateIOThread(SwitchDevice aDevice, SwitchState aState) |
michael@0 | 450 | { |
michael@0 | 451 | sSwitchObserver->Notify(aDevice, aState); |
michael@0 | 452 | } |
michael@0 | 453 | |
michael@0 | 454 | void NotifySwitchStateFromInputDevice(SwitchDevice aDevice, SwitchState aState) |
michael@0 | 455 | { |
michael@0 | 456 | InitializeResourceIfNeed(); |
michael@0 | 457 | XRE_GetIOMessageLoop()->PostTask( |
michael@0 | 458 | FROM_HERE, |
michael@0 | 459 | NewRunnableFunction(NotifySwitchStateIOThread, aDevice, aState)); |
michael@0 | 460 | } |
michael@0 | 461 | } // hal_impl |
michael@0 | 462 | } //mozilla |