blob: 52cef1c5bf7670eaa5227e00241a76bfcf8057c3 [file] [log] [blame]
Dianne Hackborn5da5ca52013-02-12 15:12:21 -08001/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
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
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 */
16
17#include <binder/AppOpsManager.h>
Dianne Hackborn913b63d2013-07-17 17:26:15 -070018#include <binder/Binder.h>
Dianne Hackborn5da5ca52013-02-12 15:12:21 -080019#include <binder/IServiceManager.h>
20
21#include <utils/SystemClock.h>
22
23namespace android {
24
Christopher Wiley8ed42702016-02-05 09:08:23 -080025namespace {
26
27#if defined(__BRILLO__)
28// Because Brillo has no application model, security policy is managed
29// statically (at build time) with SELinux controls.
30// As a consequence, it also never runs the AppOpsManager service.
31const int APP_OPS_MANAGER_UNAVAILABLE_MODE = AppOpsManager::MODE_ALLOWED;
32#else
33const int APP_OPS_MANAGER_UNAVAILABLE_MODE = AppOpsManager::MODE_IGNORED;
34#endif // defined(__BRILLO__)
35
36} // namespace
37
Dianne Hackborn5da5ca52013-02-12 15:12:21 -080038static String16 _appops("appops");
Dianne Hackborn913b63d2013-07-17 17:26:15 -070039static pthread_mutex_t gTokenMutex = PTHREAD_MUTEX_INITIALIZER;
40static sp<IBinder> gToken;
41
42static const sp<IBinder>& getToken(const sp<IAppOpsService>& service) {
43 pthread_mutex_lock(&gTokenMutex);
44 if (gToken == NULL) {
45 gToken = service->getToken(new BBinder());
46 }
Zhijun He20d03802013-07-22 17:09:35 -070047 pthread_mutex_unlock(&gTokenMutex);
Dianne Hackborn913b63d2013-07-17 17:26:15 -070048 return gToken;
49}
Dianne Hackborn5da5ca52013-02-12 15:12:21 -080050
51AppOpsManager::AppOpsManager()
52{
53}
54
Christopher Wiley8ed42702016-02-05 09:08:23 -080055#if defined(__BRILLO__)
56// There is no AppOpsService on Brillo
57sp<IAppOpsService> AppOpsManager::getService() { return NULL; }
58#else
Dianne Hackborn5da5ca52013-02-12 15:12:21 -080059sp<IAppOpsService> AppOpsManager::getService()
60{
Christopher Wiley8ed42702016-02-05 09:08:23 -080061
Dianne Hackborn5da5ca52013-02-12 15:12:21 -080062 int64_t startTime = 0;
63 mLock.lock();
64 sp<IAppOpsService> service = mService;
Marco Nelissen2ea926b2014-11-14 08:01:01 -080065 while (service == NULL || !IInterface::asBinder(service)->isBinderAlive()) {
Eino-Ville Talvalae88a85e2013-02-19 12:54:57 -080066 sp<IBinder> binder = defaultServiceManager()->checkService(_appops);
67 if (binder == NULL) {
68 // Wait for the app ops service to come back...
69 if (startTime == 0) {
70 startTime = uptimeMillis();
71 ALOGI("Waiting for app ops service");
72 } else if ((uptimeMillis()-startTime) > 10000) {
73 ALOGW("Waiting too long for app ops service, giving up");
Christopher Wiley6dd45522016-02-05 09:06:30 -080074 service = NULL;
75 break;
Dianne Hackborn5da5ca52013-02-12 15:12:21 -080076 }
Eino-Ville Talvalae88a85e2013-02-19 12:54:57 -080077 sleep(1);
78 } else {
79 service = interface_cast<IAppOpsService>(binder);
80 mService = service;
Dianne Hackborn5da5ca52013-02-12 15:12:21 -080081 }
82 }
83 mLock.unlock();
84 return service;
85}
Christopher Wiley8ed42702016-02-05 09:08:23 -080086#endif // defined(__BRILLO__)
Dianne Hackborn5da5ca52013-02-12 15:12:21 -080087
88int32_t AppOpsManager::checkOp(int32_t op, int32_t uid, const String16& callingPackage)
89{
90 sp<IAppOpsService> service = getService();
Christopher Wiley8ed42702016-02-05 09:08:23 -080091 return service != NULL
92 ? service->checkOperation(op, uid, callingPackage)
93 : APP_OPS_MANAGER_UNAVAILABLE_MODE;
Dianne Hackborn5da5ca52013-02-12 15:12:21 -080094}
95
96int32_t AppOpsManager::noteOp(int32_t op, int32_t uid, const String16& callingPackage) {
97 sp<IAppOpsService> service = getService();
Christopher Wiley8ed42702016-02-05 09:08:23 -080098 return service != NULL
99 ? service->noteOperation(op, uid, callingPackage)
100 : APP_OPS_MANAGER_UNAVAILABLE_MODE;
Dianne Hackborn5da5ca52013-02-12 15:12:21 -0800101}
102
103int32_t AppOpsManager::startOp(int32_t op, int32_t uid, const String16& callingPackage) {
104 sp<IAppOpsService> service = getService();
Christopher Wiley8ed42702016-02-05 09:08:23 -0800105 return service != NULL
106 ? service->startOperation(getToken(service), op, uid, callingPackage)
107 : APP_OPS_MANAGER_UNAVAILABLE_MODE;
Dianne Hackborn5da5ca52013-02-12 15:12:21 -0800108}
109
110void AppOpsManager::finishOp(int32_t op, int32_t uid, const String16& callingPackage) {
111 sp<IAppOpsService> service = getService();
112 if (service != NULL) {
Dianne Hackborn913b63d2013-07-17 17:26:15 -0700113 service->finishOperation(getToken(service), op, uid, callingPackage);
Dianne Hackborn5da5ca52013-02-12 15:12:21 -0800114 }
115}
116
117void AppOpsManager::startWatchingMode(int32_t op, const String16& packageName,
118 const sp<IAppOpsCallback>& callback) {
119 sp<IAppOpsService> service = getService();
120 if (service != NULL) {
121 service->startWatchingMode(op, packageName, callback);
122 }
123}
124
125void AppOpsManager::stopWatchingMode(const sp<IAppOpsCallback>& callback) {
126 sp<IAppOpsService> service = getService();
127 if (service != NULL) {
128 service->stopWatchingMode(callback);
129 }
130}
131
Svetoslavb412f6e2015-04-29 16:50:41 -0700132int32_t AppOpsManager::permissionToOpCode(const String16& permission) {
133 sp<IAppOpsService> service = getService();
134 if (service != NULL) {
135 return service->permissionToOpCode(permission);
136 }
137 return -1;
138}
139
140
Dianne Hackborn5da5ca52013-02-12 15:12:21 -0800141}; // namespace android