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: 39 explicit BpVehicleMonitor(const sp<IBinder> & impl) 40 : BpInterface<IVehicleMonitor>(impl) { 41 } 42 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 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 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 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