1 /*
2 * Copyright (C) 2016 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 "VehicleMonitor"
18
19 #include <binder/IPCThreadState.h>
20 #include <binder/Status.h>
21 #include <private/android_filesystem_config.h>
22
23 #include <utils/Log.h>
24
25 #include <IVehicleMonitor.h>
26
27 namespace android {
28 enum {
29 SET_APP_PRIORITY = IBinder::FIRST_CALL_TRANSACTION,
30 SET_MONITOR_LISTENER,
31 };
32
33 const char IVehicleMonitor::SERVICE_NAME[] = "com.android.car.vehiclemonitor.IVehicleMonitor";
34
35 // ----------------------------------------------------------------------------
36
37 class BpVehicleMonitor : public BpInterface<IVehicleMonitor> {
38 public:
BpVehicleMonitor(const sp<IBinder> & impl)39 explicit BpVehicleMonitor(const sp<IBinder> & impl)
40 : BpInterface<IVehicleMonitor>(impl) {
41 }
42
setAppPriority(uint32_t pid,uint32_t uid,vehicle_app_priority priority)43 virtual status_t setAppPriority(
44 uint32_t pid, uint32_t uid, vehicle_app_priority priority) {
45 Parcel data, reply;
46 data.writeInterfaceToken(IVehicleMonitor::getInterfaceDescriptor());
47 data.writeInt32(1);
48 data.writeInt32(pid);
49 data.writeInt32(uid);
50 data.writeInt32(priority);
51 status_t status = remote()->transact(SET_APP_PRIORITY, data, &reply);
52 if (status == NO_ERROR) {
53 int32_t exceptionCode = reply.readExceptionCode();
54 if (exceptionCode != NO_ERROR) {
55 if (exceptionCode == binder::Status::EX_SERVICE_SPECIFIC) {
56 return -EAGAIN;
57 } else if (exceptionCode == binder::Status::EX_ILLEGAL_STATE) {
58 return -ESHUTDOWN;
59 }
60 return exceptionCode;
61 }
62 }
63 return status;
64 }
65
setMonitorListener(const sp<IVehicleMonitorListener> & listener)66 virtual status_t setMonitorListener(
67 const sp<IVehicleMonitorListener> &listener) {
68 Parcel data, reply;
69 data.writeInterfaceToken(IVehicleMonitor::getInterfaceDescriptor());
70 data.writeStrongBinder(IInterface::asBinder(listener));
71 status_t status = remote()->transact(SET_MONITOR_LISTENER, data, &reply);
72 return status;
73 }
74 };
75
76 IMPLEMENT_META_INTERFACE(VehicleMonitor, IVehicleMonitor::SERVICE_NAME);
77
78 // ----------------------------------------------------------------------
79
isSystemUser()80 static bool isSystemUser() {
81 uid_t uid = IPCThreadState::self()->getCallingUid();
82 switch (uid) {
83 // This list will be expanded. Only these UIDs are allowed to access vehicle monitor.
84 case AID_ROOT:
85 case AID_SYSTEM: {
86 return true;
87 } break;
88 default: {
89 ALOGE("non-system user tried access, uid %d", uid);
90 } break;
91 }
92 return false;
93 }
94
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)95 status_t BnVehicleMonitor::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
96 uint32_t flags) {
97 if (!isSystemUser()) {
98 return PERMISSION_DENIED;
99 }
100 status_t r;
101 switch (code) {
102 case SET_APP_PRIORITY: {
103 CHECK_INTERFACE(IVehicleMonitor, data, reply);
104 if (data.readInt32() == 0) { // no data
105 ALOGE("null data");
106 return BAD_VALUE;
107 }
108 int32_t pid = data.readInt32();
109 int32_t uid = data.readInt32();
110 int32_t priority = data.readInt32();
111 r = setAppPriority(pid, uid, (vehicle_app_priority) priority);
112 reply->writeNoException();
113 return r;
114 } break;
115 case SET_MONITOR_LISTENER: {
116 CHECK_INTERFACE(IVehicleMonitor, data, reply);
117 sp<IVehicleMonitorListener> listener =
118 interface_cast<IVehicleMonitorListener>(data.readStrongBinder());
119 r = setMonitorListener(listener);
120 reply->writeNoException();
121 return r;
122 } break;
123 default:
124 return BBinder::onTransact(code, data, reply, flags);
125 }
126 }
127
128 }; // namespace android
129