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