1/*
2 * Copyright (C) 2018 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 <mutex>
18#include <binder/PermissionController.h>
19#include <binder/Binder.h>
20#include <binder/IServiceManager.h>
21
22#include <utils/SystemClock.h>
23
24namespace android {
25
26PermissionController::PermissionController()
27{
28}
29
30sp<IPermissionController> PermissionController::getService()
31{
32    std::lock_guard<Mutex> scoped_lock(mLock);
33    int64_t startTime = 0;
34    sp<IPermissionController> service = mService;
35    while (service == nullptr || !IInterface::asBinder(service)->isBinderAlive()) {
36        sp<IBinder> binder = defaultServiceManager()->checkService(String16("permission"));
37        if (binder == nullptr) {
38            // Wait for the activity service to come back...
39            if (startTime == 0) {
40                startTime = uptimeMillis();
41                ALOGI("Waiting for permission service");
42            } else if ((uptimeMillis() - startTime) > 10000) {
43                ALOGW("Waiting too long for permission service, giving up");
44                service = NULL;
45                break;
46            }
47            sleep(1);
48        } else {
49            service = interface_cast<IPermissionController>(binder);
50            mService = service;
51        }
52    }
53    return service;
54}
55
56bool PermissionController::checkPermission(const String16& permission, int32_t pid, int32_t uid)
57{
58    sp<IPermissionController> service = getService();
59    return service != NULL ? service->checkPermission(permission, pid, uid) : false;
60}
61
62int32_t PermissionController::noteOp(const String16& op, int32_t uid, const String16& packageName)
63{
64    sp<IPermissionController> service = getService();
65    return service != NULL ? service->noteOp(op, uid, packageName) : MODE_ERRORED;
66}
67
68void PermissionController::getPackagesForUid(const uid_t uid, Vector<String16> &packages)
69{
70    sp<IPermissionController> service = getService();
71    if (service != nullptr) {
72        service->getPackagesForUid(uid, packages);
73    }
74}
75
76bool PermissionController::isRuntimePermission(const String16& permission)
77{
78    sp<IPermissionController> service = getService();
79    return service != nullptr ? service->isRuntimePermission(permission) : false;
80}
81
82int PermissionController::getPackageUid(const String16& package, int flags)
83{
84    sp<IPermissionController> service = getService();
85    return service != nullptr ? service->getPackageUid(package, flags) : -1;
86}
87
88}; // namespace android
89