gecko-dev/widget/gonk/GonkPermission.cpp

192 строки
5.3 KiB
C++
Исходник Обычный вид История

/*
* Copyright (C) 2012 Mozilla Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <binder/IPCThreadState.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>
#include <binder/IPermissionController.h>
#include <private/android_filesystem_config.h>
#include "GonkPermission.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/TabParent.h"
#include "mozilla/SyncRunnable.h"
#include "nsIAppsService.h"
#include "mozIApplication.h"
#include "nsThreadUtils.h"
#undef LOG
#include <android/log.h>
#undef ALOGE
#define ALOGE(args...) __android_log_print(ANDROID_LOG_ERROR, "gonkperm" , ## args)
using namespace android;
using namespace mozilla;
// Checking permissions needs to happen on the main thread, but the
// binder callback is called on a special binder thread, so we use
// this runnable for that.
class GonkPermissionChecker : public nsRunnable {
int32_t mPid;
bool mCanUseCamera;
explicit GonkPermissionChecker(int32_t pid)
: mPid(pid)
, mCanUseCamera(false)
{
}
public:
static already_AddRefed<GonkPermissionChecker> Inspect(int32_t pid)
{
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi --HG-- rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
2015-10-18 08:24:48 +03:00
RefPtr<GonkPermissionChecker> that = new GonkPermissionChecker(pid);
nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
MOZ_ASSERT(mainThread);
SyncRunnable::DispatchToThread(mainThread, that);
return that.forget();
}
bool CanUseCamera()
{
return mCanUseCamera;
}
NS_IMETHOD Run();
};
NS_IMETHODIMP
GonkPermissionChecker::Run()
{
MOZ_ASSERT(NS_IsMainThread());
// Find our ContentParent.
dom::ContentParent *contentParent = nullptr;
{
nsTArray<dom::ContentParent*> parents;
dom::ContentParent::GetAll(parents);
for (uint32_t i = 0; i < parents.Length(); ++i) {
if (parents[i]->Pid() == mPid) {
contentParent = parents[i];
break;
}
}
}
if (!contentParent) {
ALOGE("pid=%d denied: can't find ContentParent", mPid);
return NS_OK;
}
// Now iterate its apps...
const ManagedContainer<dom::PBrowserParent>& browsers =
contentParent->ManagedPBrowserParent();
for (auto iter = browsers.ConstIter(); !iter.Done(); iter.Next()) {
dom::TabParent *tabParent =
static_cast<dom::TabParent*>(iter.Get()->GetKey());
nsCOMPtr<mozIApplication> mozApp = tabParent->GetOwnOrContainingApp();
if (!mozApp) {
continue;
}
// ...and check if any of them has camera access.
bool appCanUseCamera;
nsresult rv = mozApp->HasPermission("camera", &appCanUseCamera);
if (NS_SUCCEEDED(rv) && appCanUseCamera) {
mCanUseCamera = true;
return NS_OK;
}
}
return NS_OK;
}
bool
GonkPermissionService::checkPermission(const String16& permission, int32_t pid,
int32_t uid)
{
// root can do anything.
if (0 == uid) {
return true;
}
String8 perm8(permission);
// Some ril implementations need android.permission.MODIFY_AUDIO_SETTINGS
if ((uid == AID_SYSTEM || uid == AID_RADIO || uid == AID_BLUETOOTH) &&
perm8 == "android.permission.MODIFY_AUDIO_SETTINGS") {
return true;
}
// No other permissions apply to non-app processes.
if (uid < AID_APP) {
ALOGE("%s for pid=%d,uid=%d denied: not an app",
String8(permission).string(), pid, uid);
return false;
}
// Only these permissions can be granted to apps through this service.
if (perm8 != "android.permission.CAMERA" &&
perm8 != "android.permission.RECORD_AUDIO") {
ALOGE("%s for pid=%d,uid=%d denied: unsupported permission",
String8(permission).string(), pid, uid);
return false;
}
// Users granted the permission through a prompt dialog.
// Before permission managment of gUM is done, app cannot remember the
// permission.
PermissionGrant permGrant(perm8.string(), pid);
if (nsTArray<PermissionGrant>::NoIndex != mGrantArray.IndexOf(permGrant)) {
mGrantArray.RemoveElement(permGrant);
return true;
}
// Camera/audio record permissions are allowed for apps with the
// "camera" permission.
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi --HG-- rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
2015-10-18 08:24:48 +03:00
RefPtr<GonkPermissionChecker> checker =
GonkPermissionChecker::Inspect(pid);
bool canUseCamera = checker->CanUseCamera();
if (!canUseCamera) {
ALOGE("%s for pid=%d,uid=%d denied: not granted by user or app manifest",
String8(permission).string(), pid, uid);
}
return canUseCamera;
}
static GonkPermissionService* gGonkPermissionService = NULL;
/* static */
void
GonkPermissionService::instantiate()
{
defaultServiceManager()->addService(String16(getServiceName()),
GetInstance());
}
/* static */
GonkPermissionService*
GonkPermissionService::GetInstance()
{
if (!gGonkPermissionService) {
gGonkPermissionService = new GonkPermissionService();
}
return gGonkPermissionService;
}
void
GonkPermissionService::addGrantInfo(const char* permission, int32_t pid)
{
mGrantArray.AppendElement(PermissionGrant(permission, pid));
}