1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * Copyright (C) 2012-2013, The Linux Foundation. All rights reserved. 4 * 5 * Not a Contribution, Apache license notifications and license are 6 * retained for attribution purposes only. 7 8 * Licensed under the Apache License, Version 2.0 (the "License"); 9 * you may not use this file except in compliance with the License. 10 * You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 */ 20 21 #include <fcntl.h> 22 #include <stdint.h> 23 #include <sys/types.h> 24 #include <binder/Parcel.h> 25 #include <binder/IBinder.h> 26 #include <binder/IInterface.h> 27 #include <binder/IPCThreadState.h> 28 #include <utils/Errors.h> 29 #include <private/android_filesystem_config.h> 30 31 #include <IQService.h> 32 33 using namespace android; 34 using namespace qClient; 35 36 // --------------------------------------------------------------------------- 37 38 namespace qService { 39 40 class BpQService : public BpInterface<IQService> 41 { 42 public: 43 BpQService(const sp<IBinder>& impl) 44 : BpInterface<IQService>(impl) {} 45 46 virtual void securing(uint32_t startEnd) { 47 Parcel data, reply; 48 data.writeInterfaceToken(IQService::getInterfaceDescriptor()); 49 data.writeInt32(startEnd); 50 remote()->transact(SECURING, data, &reply); 51 } 52 53 virtual void unsecuring(uint32_t startEnd) { 54 Parcel data, reply; 55 data.writeInterfaceToken(IQService::getInterfaceDescriptor()); 56 data.writeInt32(startEnd); 57 remote()->transact(UNSECURING, data, &reply); 58 } 59 60 virtual void connect(const sp<IQClient>& client) { 61 Parcel data, reply; 62 data.writeInterfaceToken(IQService::getInterfaceDescriptor()); 63 data.writeStrongBinder(client->asBinder()); 64 remote()->transact(CONNECT, data, &reply); 65 } 66 67 virtual status_t screenRefresh() { 68 Parcel data, reply; 69 data.writeInterfaceToken(IQService::getInterfaceDescriptor()); 70 remote()->transact(SCREEN_REFRESH, data, &reply); 71 status_t result = reply.readInt32(); 72 return result; 73 } 74 }; 75 76 IMPLEMENT_META_INTERFACE(QService, "android.display.IQService"); 77 78 // ---------------------------------------------------------------------- 79 80 static void getProcName(int pid, char *buf, int size); 81 82 status_t BnQService::onTransact( 83 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 84 { 85 // IPC should be from mediaserver only 86 IPCThreadState* ipc = IPCThreadState::self(); 87 const int callerPid = ipc->getCallingPid(); 88 const int callerUid = ipc->getCallingUid(); 89 const size_t MAX_BUF_SIZE = 1024; 90 char callingProcName[MAX_BUF_SIZE] = {0}; 91 92 getProcName(callerPid, callingProcName, MAX_BUF_SIZE); 93 94 const bool permission = (callerUid == AID_MEDIA); 95 96 switch(code) { 97 case SECURING: { 98 if(!permission) { 99 ALOGE("display.qservice SECURING access denied: \ 100 pid=%d uid=%d process=%s", 101 callerPid, callerUid, callingProcName); 102 return PERMISSION_DENIED; 103 } 104 CHECK_INTERFACE(IQService, data, reply); 105 uint32_t startEnd = data.readInt32(); 106 securing(startEnd); 107 return NO_ERROR; 108 } break; 109 case UNSECURING: { 110 if(!permission) { 111 ALOGE("display.qservice UNSECURING access denied: \ 112 pid=%d uid=%d process=%s", 113 callerPid, callerUid, callingProcName); 114 return PERMISSION_DENIED; 115 } 116 CHECK_INTERFACE(IQService, data, reply); 117 uint32_t startEnd = data.readInt32(); 118 unsecuring(startEnd); 119 return NO_ERROR; 120 } break; 121 case CONNECT: { 122 CHECK_INTERFACE(IQService, data, reply); 123 if(callerUid != AID_GRAPHICS) { 124 ALOGE("display.qservice CONNECT access denied: \ 125 pid=%d uid=%d process=%s", 126 callerPid, callerUid, callingProcName); 127 return PERMISSION_DENIED; 128 } 129 sp<IQClient> client = 130 interface_cast<IQClient>(data.readStrongBinder()); 131 connect(client); 132 return NO_ERROR; 133 } break; 134 case SCREEN_REFRESH: { 135 CHECK_INTERFACE(IQService, data, reply); 136 if(callerUid != AID_SYSTEM) { 137 ALOGE("display.qservice SCREEN_REFRESH access denied: \ 138 pid=%d uid=%d process=%s",callerPid, 139 callerUid, callingProcName); 140 return PERMISSION_DENIED; 141 } 142 return screenRefresh(); 143 } break; 144 default: 145 return BBinder::onTransact(code, data, reply, flags); 146 } 147 } 148 149 //Helper 150 static void getProcName(int pid, char *buf, int size) { 151 int fd = -1; 152 snprintf(buf, size, "/proc/%d/cmdline", pid); 153 fd = open(buf, O_RDONLY); 154 if (fd < 0) { 155 strcpy(buf, "Unknown"); 156 } else { 157 int len = read(fd, buf, size - 1); 158 buf[len] = 0; 159 close(fd); 160 } 161 } 162 163 }; // namespace qService 164