Home | History | Annotate | Download | only in native
      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