1 /*
2 * Copyright (C) 2005 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 #define LOG_TAG "PermissionController"
18
19 #include <binder/IPermissionController.h>
20
21 #include <utils/Log.h>
22 #include <binder/Parcel.h>
23 #include <utils/String8.h>
24
25 namespace android {
26
27 // ----------------------------------------------------------------------
28
29 class BpPermissionController : public BpInterface<IPermissionController>
30 {
31 public:
BpPermissionController(const sp<IBinder> & impl)32 explicit BpPermissionController(const sp<IBinder>& impl)
33 : BpInterface<IPermissionController>(impl)
34 {
35 }
36
checkPermission(const String16 & permission,int32_t pid,int32_t uid)37 virtual bool checkPermission(const String16& permission, int32_t pid, int32_t uid)
38 {
39 Parcel data, reply;
40 data.writeInterfaceToken(IPermissionController::getInterfaceDescriptor());
41 data.writeString16(permission);
42 data.writeInt32(pid);
43 data.writeInt32(uid);
44 remote()->transact(CHECK_PERMISSION_TRANSACTION, data, &reply);
45 // fail on exception
46 if (reply.readExceptionCode() != 0) return 0;
47 return reply.readInt32() != 0;
48 }
49
noteOp(const String16 & op,int32_t uid,const String16 & packageName)50 virtual int32_t noteOp(const String16& op, int32_t uid, const String16& packageName)
51 {
52 Parcel data, reply;
53 data.writeInterfaceToken(IPermissionController::getInterfaceDescriptor());
54 data.writeString16(op);
55 data.writeInt32(uid);
56 data.writeString16(packageName);
57 remote()->transact(NOTE_OP_TRANSACTION, data, &reply);
58 // fail on exception
59 if (reply.readExceptionCode() != 0) return 2; // MODE_ERRORED
60 return reply.readInt32();
61 }
62
getPackagesForUid(const uid_t uid,Vector<String16> & packages)63 virtual void getPackagesForUid(const uid_t uid, Vector<String16>& packages)
64 {
65 Parcel data, reply;
66 data.writeInterfaceToken(IPermissionController::getInterfaceDescriptor());
67 data.writeInt32(uid);
68 remote()->transact(GET_PACKAGES_FOR_UID_TRANSACTION, data, &reply);
69 // fail on exception
70 if (reply.readExceptionCode() != 0) {
71 return;
72 }
73 const int32_t size = reply.readInt32();
74 if (size <= 0) {
75 return;
76 }
77 for (int i = 0; i < size; i++) {
78 packages.push(reply.readString16());
79 }
80 }
81
isRuntimePermission(const String16 & permission)82 virtual bool isRuntimePermission(const String16& permission)
83 {
84 Parcel data, reply;
85 data.writeInterfaceToken(IPermissionController::getInterfaceDescriptor());
86 data.writeString16(permission);
87 remote()->transact(IS_RUNTIME_PERMISSION_TRANSACTION, data, &reply);
88 // fail on exception
89 if (reply.readExceptionCode() != 0) return false;
90 return reply.readInt32() != 0;
91 }
92
getPackageUid(const String16 & package,int flags)93 virtual int getPackageUid(const String16& package, int flags)
94 {
95 Parcel data, reply;
96 data.writeInterfaceToken(IPermissionController::getInterfaceDescriptor());
97 data.writeString16(package);
98 data.writeInt32(flags);
99 remote()->transact(GET_PACKAGE_UID_TRANSACTION, data, &reply);
100 // fail on exception
101 if (reply.readExceptionCode() != 0) return false;
102 return reply.readInt32();
103 }
104 };
105
106 IMPLEMENT_META_INTERFACE(PermissionController, "android.os.IPermissionController")
107
108 // ----------------------------------------------------------------------
109
110 // NOLINTNEXTLINE(google-default-arguments)
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)111 status_t BnPermissionController::onTransact(
112 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
113 {
114 switch(code) {
115 case CHECK_PERMISSION_TRANSACTION: {
116 CHECK_INTERFACE(IPermissionController, data, reply);
117 String16 permission = data.readString16();
118 int32_t pid = data.readInt32();
119 int32_t uid = data.readInt32();
120 bool res = checkPermission(permission, pid, uid);
121 reply->writeNoException();
122 reply->writeInt32(res ? 1 : 0);
123 return NO_ERROR;
124 } break;
125
126 case NOTE_OP_TRANSACTION: {
127 CHECK_INTERFACE(IPermissionController, data, reply);
128 String16 op = data.readString16();
129 int32_t uid = data.readInt32();
130 String16 packageName = data.readString16();
131 int32_t res = noteOp(op, uid, packageName);
132 reply->writeNoException();
133 reply->writeInt32(res);
134 return NO_ERROR;
135 } break;
136
137 case GET_PACKAGES_FOR_UID_TRANSACTION: {
138 CHECK_INTERFACE(IPermissionController, data, reply);
139 int32_t uid = data.readInt32();
140 Vector<String16> packages;
141 getPackagesForUid(uid, packages);
142 reply->writeNoException();
143 size_t size = packages.size();
144 reply->writeInt32(size);
145 for (size_t i = 0; i < size; i++) {
146 reply->writeString16(packages[i]);
147 }
148 return NO_ERROR;
149 } break;
150
151 case IS_RUNTIME_PERMISSION_TRANSACTION: {
152 CHECK_INTERFACE(IPermissionController, data, reply);
153 String16 permission = data.readString16();
154 const bool res = isRuntimePermission(permission);
155 reply->writeNoException();
156 reply->writeInt32(res ? 1 : 0);
157 return NO_ERROR;
158 } break;
159
160 case GET_PACKAGE_UID_TRANSACTION: {
161 CHECK_INTERFACE(IPermissionController, data, reply);
162 String16 package = data.readString16();
163 int flags = data.readInt32();
164 const int uid = getPackageUid(package, flags);
165 reply->writeNoException();
166 reply->writeInt32(uid);
167 return NO_ERROR;
168 } break;
169
170 default:
171 return BBinder::onTransact(code, data, reply, flags);
172 }
173 }
174
175 } // namespace android
176