Bug 788829 - Call SetSizeConstraints even if a popup is not open. r=enndeakin
[gecko.git] / dom / camera / DOMCameraManager.cpp
blobeae0d0d43c6aaa94dc4c4b235ff5a1fcdd8fa624
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #include "nsDebug.h"
6 #include "nsPIDOMWindow.h"
7 #include "mozilla/Services.h"
8 #include "nsObserverService.h"
9 #include "nsIPermissionManager.h"
10 #include "DOMCameraControl.h"
11 #include "DOMCameraManager.h"
12 #include "nsDOMClassInfo.h"
13 #include "DictionaryHelpers.h"
14 #include "CameraCommon.h"
16 using namespace mozilla;
17 using namespace dom;
19 DOMCI_DATA(CameraManager, nsIDOMCameraManager)
21 NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMCameraManager)
23 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDOMCameraManager)
24 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mCameraThread)
25 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
27 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDOMCameraManager)
28 NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mCameraThread)
29 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
31 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMCameraManager)
32 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIObserver)
33 NS_INTERFACE_MAP_ENTRY(nsIDOMCameraManager)
34 NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
35 NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CameraManager)
36 NS_INTERFACE_MAP_END
38 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMCameraManager)
39 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMCameraManager)
41 /**
42 * Global camera logging object
44 * Set the NSPR_LOG_MODULES environment variable to enable logging
45 * in a debug build, e.g. NSPR_LOG_MODULES=Camera:5
47 PRLogModuleInfo* gCameraLog = PR_LOG_DEFINE("Camera");
49 /**
50 * nsDOMCameraManager::GetListOfCameras
51 * is implementation-specific, and can be found in (e.g.)
52 * GonkCameraManager.cpp and FallbackCameraManager.cpp.
55 WindowTable nsDOMCameraManager::sActiveWindows;
56 bool nsDOMCameraManager::sActiveWindowsInitialized = false;
58 nsDOMCameraManager::nsDOMCameraManager(uint64_t aWindowId)
59 : mWindowId(aWindowId)
60 , mCameraThread(nullptr)
62 /* member initializers and constructor code */
63 DOM_CAMERA_LOGT("%s:%d : this=%p, windowId=%llx\n", __func__, __LINE__, this, mWindowId);
66 nsDOMCameraManager::~nsDOMCameraManager()
68 /* destructor code */
69 DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
70 nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
71 obs->RemoveObserver(this, "xpcom-shutdown");
74 // static creator
75 already_AddRefed<nsDOMCameraManager>
76 nsDOMCameraManager::CheckPermissionAndCreateInstance(nsPIDOMWindow* aWindow)
78 nsCOMPtr<nsIPermissionManager> permMgr =
79 do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
80 NS_ENSURE_TRUE(permMgr, nullptr);
82 uint32_t permission = nsIPermissionManager::DENY_ACTION;
83 permMgr->TestPermissionFromWindow(aWindow, "camera", &permission);
84 if (permission != nsIPermissionManager::ALLOW_ACTION) {
85 NS_WARNING("No permission to access camera");
86 return nullptr;
89 // Initialize the shared active window tracker
90 if (!sActiveWindowsInitialized) {
91 sActiveWindows.Init();
92 sActiveWindowsInitialized = true;
95 nsRefPtr<nsDOMCameraManager> cameraManager =
96 new nsDOMCameraManager(aWindow->WindowID());
98 nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
99 obs->AddObserver(cameraManager, "xpcom-shutdown", true);
101 return cameraManager.forget();
104 /* [implicit_jscontext] void getCamera ([optional] in jsval aOptions, in nsICameraGetCameraCallback onSuccess, [optional] in nsICameraErrorCallback onError); */
105 NS_IMETHODIMP
106 nsDOMCameraManager::GetCamera(const JS::Value& aOptions, nsICameraGetCameraCallback* onSuccess, nsICameraErrorCallback* onError, JSContext* cx)
108 NS_ENSURE_TRUE(onSuccess, NS_ERROR_INVALID_ARG);
110 uint32_t cameraId = 0; // back (or forward-facing) camera by default
111 CameraSelector selector;
113 nsresult rv = selector.Init(cx, &aOptions);
114 NS_ENSURE_SUCCESS(rv, rv);
116 if (selector.camera.EqualsASCII("front")) {
117 cameraId = 1;
120 // reuse the same camera thread to conserve resources
121 if (!mCameraThread) {
122 rv = NS_NewThread(getter_AddRefs(mCameraThread));
123 NS_ENSURE_SUCCESS(rv, rv);
126 DOM_CAMERA_LOGT("%s:%d\n", __func__, __LINE__);
128 // Creating this object will trigger the onSuccess handler
129 nsCOMPtr<nsDOMCameraControl> cameraControl = new nsDOMCameraControl(cameraId, mCameraThread, onSuccess, onError, mWindowId);
131 Register(cameraControl);
132 return NS_OK;
135 void
136 nsDOMCameraManager::Register(nsDOMCameraControl* aDOMCameraControl)
138 DOM_CAMERA_LOGI(">>> Register( aDOMCameraControl = %p ) mWindowId = 0x%llx\n", aDOMCameraControl, mWindowId);
139 MOZ_ASSERT(NS_IsMainThread());
141 // Put the camera control into the hash table
142 CameraControls* controls = sActiveWindows.Get(mWindowId);
143 if (!controls) {
144 controls = new CameraControls;
145 sActiveWindows.Put(mWindowId, controls);
147 controls->AppendElement(aDOMCameraControl);
150 void
151 nsDOMCameraManager::Shutdown(uint64_t aWindowId)
153 DOM_CAMERA_LOGI(">>> Shutdown( aWindowId = 0x%llx )\n", aWindowId);
154 MOZ_ASSERT(NS_IsMainThread());
156 CameraControls* controls = sActiveWindows.Get(aWindowId);
157 if (!controls) {
158 return;
161 uint32_t length = controls->Length();
162 for (uint32_t i = 0; i < length; i++) {
163 nsRefPtr<nsDOMCameraControl> cameraControl = controls->ElementAt(i);
164 cameraControl->Shutdown();
166 controls->Clear();
168 sActiveWindows.Remove(aWindowId);
171 void
172 nsDOMCameraManager::XpComShutdown()
174 DOM_CAMERA_LOGI(">>> XPCOM Shutdown\n");
175 MOZ_ASSERT(NS_IsMainThread());
177 nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
178 obs->RemoveObserver(this, "xpcom-shutdown");
180 sActiveWindows.Clear();
183 nsresult
184 nsDOMCameraManager::Observe(nsISupports* aSubject, const char* aTopic, const PRUnichar* aData)
186 if (strcmp(aTopic, "xpcom-shutdown") == 0) {
187 XpComShutdown();
189 return NS_OK;
192 void
193 nsDOMCameraManager::OnNavigation(uint64_t aWindowId)
195 DOM_CAMERA_LOGI(">>> OnNavigation event\n");
196 Shutdown(aWindowId);
199 bool
200 nsDOMCameraManager::IsWindowStillActive(uint64_t aWindowId)
202 MOZ_ASSERT(NS_IsMainThread());
204 if (!sActiveWindowsInitialized) {
205 return false;
208 return !!sActiveWindows.Get(aWindowId);