void Vibrate(const nsTArray<uint32>& pattern, const WindowIdentifier &id) { AssertMainThread(); // Only active windows may start vibrations. If |id| hasn't gone // through the IPC layer -- that is, if our caller is the outside // world, not hal_proxy -- check whether the window is active. If // |id| has gone through IPC, don't check the window's visibility; // only the window corresponding to the bottommost process has its // visibility state set correctly. if (!id.HasTraveledThroughIPC() && !WindowIsActive(id.GetWindow())) { HAL_LOG(("Vibrate: Window is inactive, dropping vibrate.")); return; } if (InSandbox()) { hal_sandbox::Vibrate(pattern, id); } else { if (!gLastIDToVibrate) InitLastIDToVibrate(); *gLastIDToVibrate = id.AsArray(); HAL_LOG(("Vibrate: Forwarding to hal_impl.")); // hal_impl doesn't need |id|. Send it an empty id, which will // assert if it's used. hal_impl::Vibrate(pattern, WindowIdentifier()); } }
void CancelVibrate(const WindowIdentifier &id) { AssertMainThread(); // Although only active windows may start vibrations, a window may // cancel its own vibration even if it's no longer active. // // After a window is marked as inactive, it sends a CancelVibrate // request. We want this request to cancel a playing vibration // started by that window, so we certainly don't want to reject the // cancellation request because the window is now inactive. // // But it could be the case that, after this window became inactive, // some other window came along and started a vibration. We don't // want this window's cancellation request to cancel that window's // actively-playing vibration! // // To solve this problem, we keep track of the id of the last window // to start a vibration, and only accepts cancellation requests from // the same window. All other cancellation requests are ignored. if (InSandbox()) { hal_sandbox::CancelVibrate(id); } else if (*gLastIDToVibrate == id.AsArray()) { // Don't forward our ID to hal_impl. It doesn't need it, and we // don't want it to be tempted to read it. The empty identifier // will assert if it's used. HAL_LOG(("CancelVibrate: Forwarding to hal_impl.")); hal_impl::CancelVibrate(WindowIdentifier()); } }
void Vibrate(const nsTArray<uint32_t>& pattern, const WindowIdentifier &id) { AssertMainThread(); // Only active windows may start vibrations. If |id| hasn't gone // through the IPC layer -- that is, if our caller is the outside // world, not hal_proxy -- check whether the window is active. If // |id| has gone through IPC, don't check the window's visibility; // only the window corresponding to the bottommost process has its // visibility state set correctly. if (!id.HasTraveledThroughIPC() && !WindowIsActive(id.GetWindow())) { HAL_LOG(("Vibrate: Window is inactive, dropping vibrate.")); return; } if (!InSandbox()) { if (!gLastIDToVibrate) { InitLastIDToVibrate(); } *gLastIDToVibrate = id.AsArray(); } // Don't forward our ID if we are not in the sandbox, because hal_impl // doesn't need it, and we don't want it to be tempted to read it. The // empty identifier will assert if it's used. PROXY_IF_SANDBOXED(Vibrate(pattern, InSandbox() ? id : WindowIdentifier())); }
void Vibrate(const nsTArray<uint32> &pattern, const WindowIdentifier &) { // Ignore the WindowIdentifier parameter; it's here only because hal::Vibrate, // hal_sandbox::Vibrate, and hal_impl::Vibrate all must have the same // signature. // Strangely enough, the Android Java API seems to treat vibrate([0]) as a // nop. But we want to treat vibrate([0]) like CancelVibrate! (Note that we // also need to treat vibrate([]) as a call to CancelVibrate.) bool allZero = true; for (uint32 i = 0; i < pattern.Length(); i++) { if (pattern[i] != 0) { allZero = false; break; } } if (allZero) { hal_impl::CancelVibrate(WindowIdentifier()); return; } AndroidBridge* b = AndroidBridge::Bridge(); if (!b) { return; } b->Vibrate(pattern); }
void Vibrate(const nsTArray<uint32>& pattern, nsIDOMWindow* window) { Vibrate(pattern, WindowIdentifier(window)); }
void CancelVibrate(nsIDOMWindow* window) { CancelVibrate(WindowIdentifier(window)); }