Bumping manifests a=b2g-bump
[gecko.git] / widget / gonk / GonkPermission.cpp
blob1b8d667d1815c89f2ba2623157c2281bbd3a26ff
1 /*
2 * Copyright (C) 2012 Mozilla Foundation
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include <binder/IPCThreadState.h>
18 #include <binder/ProcessState.h>
19 #include <binder/IServiceManager.h>
20 #include <binder/IPermissionController.h>
21 #include <private/android_filesystem_config.h>
22 #include "GonkPermission.h"
24 #include "mozilla/dom/ContentParent.h"
25 #include "mozilla/dom/TabParent.h"
26 #include "mozilla/SyncRunnable.h"
27 #include "nsIAppsService.h"
28 #include "mozIApplication.h"
29 #include "nsThreadUtils.h"
31 #undef LOG
32 #include <android/log.h>
33 #define ALOGE(args...) __android_log_print(ANDROID_LOG_ERROR, "gonkperm" , ## args)
35 using namespace android;
36 using namespace mozilla;
38 // Checking permissions needs to happen on the main thread, but the
39 // binder callback is called on a special binder thread, so we use
40 // this runnable for that.
41 class GonkPermissionChecker : public nsRunnable {
42 int32_t mPid;
43 bool mCanUseCamera;
45 explicit GonkPermissionChecker(int32_t pid)
46 : mPid(pid)
47 , mCanUseCamera(false)
51 public:
52 static already_AddRefed<GonkPermissionChecker> Inspect(int32_t pid)
54 nsRefPtr<GonkPermissionChecker> that = new GonkPermissionChecker(pid);
55 nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
56 MOZ_ASSERT(mainThread);
57 SyncRunnable::DispatchToThread(mainThread, that);
58 return that.forget();
61 bool CanUseCamera()
63 return mCanUseCamera;
66 NS_IMETHOD Run();
69 NS_IMETHODIMP
70 GonkPermissionChecker::Run()
72 MOZ_ASSERT(NS_IsMainThread());
74 // Find our ContentParent.
75 dom::ContentParent *contentParent = nullptr;
77 nsTArray<dom::ContentParent*> parents;
78 dom::ContentParent::GetAll(parents);
79 for (uint32_t i = 0; i < parents.Length(); ++i) {
80 if (parents[i]->Pid() == mPid) {
81 contentParent = parents[i];
82 break;
86 if (!contentParent) {
87 ALOGE("pid=%d denied: can't find ContentParent", mPid);
88 return NS_OK;
91 // Now iterate its apps...
92 for (uint32_t i = 0; i < contentParent->ManagedPBrowserParent().Length(); i++) {
93 dom::TabParent *tabParent =
94 static_cast<dom::TabParent*>(contentParent->ManagedPBrowserParent()[i]);
95 nsCOMPtr<mozIApplication> mozApp = tabParent->GetOwnOrContainingApp();
96 if (!mozApp) {
97 continue;
100 // ...and check if any of them has camera access.
101 bool appCanUseCamera;
102 nsresult rv = mozApp->HasPermission("camera", &appCanUseCamera);
103 if (NS_SUCCEEDED(rv) && appCanUseCamera) {
104 mCanUseCamera = true;
105 return NS_OK;
108 return NS_OK;
111 bool
112 GonkPermissionService::checkPermission(const String16& permission, int32_t pid,
113 int32_t uid)
115 // root can do anything.
116 if (0 == uid) {
117 return true;
120 String8 perm8(permission);
122 // Some ril implementations need android.permission.MODIFY_AUDIO_SETTINGS
123 if (uid == AID_RADIO &&
124 perm8 == "android.permission.MODIFY_AUDIO_SETTINGS") {
125 return true;
128 // No other permissions apply to non-app processes.
129 if (uid < AID_APP) {
130 ALOGE("%s for pid=%d,uid=%d denied: not an app",
131 String8(permission).string(), pid, uid);
132 return false;
135 // Only these permissions can be granted to apps through this service.
136 if (perm8 != "android.permission.CAMERA" &&
137 perm8 != "android.permission.RECORD_AUDIO") {
138 ALOGE("%s for pid=%d,uid=%d denied: unsupported permission",
139 String8(permission).string(), pid, uid);
140 return false;
143 // Users granted the permission through a prompt dialog.
144 // Before permission managment of gUM is done, app cannot remember the
145 // permission.
146 PermissionGrant permGrant(perm8.string(), pid);
147 if (nsTArray<PermissionGrant>::NoIndex != mGrantArray.IndexOf(permGrant)) {
148 mGrantArray.RemoveElement(permGrant);
149 return true;
152 // Camera/audio record permissions are allowed for apps with the
153 // "camera" permission.
154 nsRefPtr<GonkPermissionChecker> checker =
155 GonkPermissionChecker::Inspect(pid);
156 bool canUseCamera = checker->CanUseCamera();
157 if (!canUseCamera) {
158 ALOGE("%s for pid=%d,uid=%d denied: not granted by user or app manifest",
159 String8(permission).string(), pid, uid);
161 return canUseCamera;
164 static GonkPermissionService* gGonkPermissionService = NULL;
166 /* static */
167 void
168 GonkPermissionService::instantiate()
170 defaultServiceManager()->addService(String16(getServiceName()),
171 GetInstance());
174 /* static */
175 GonkPermissionService*
176 GonkPermissionService::GetInstance()
178 if (!gGonkPermissionService) {
179 gGonkPermissionService = new GonkPermissionService();
181 return gGonkPermissionService;
184 void
185 GonkPermissionService::addGrantInfo(const char* permission, int32_t pid)
187 mGrantArray.AppendElement(PermissionGrant(permission, pid));