156f610dd235b577725198e9341caae92379fdf23Saurabh Shah/* 256f610dd235b577725198e9341caae92379fdf23Saurabh Shah * Copyright (C) 2010 The Android Open Source Project 3d5e3e404e1344eb2148c8df9f3e35d841ddd4285Saurabh Shah * Copyright (C) 2012-2013, The Linux Foundation. All rights reserved. 456f610dd235b577725198e9341caae92379fdf23Saurabh Shah * 556f610dd235b577725198e9341caae92379fdf23Saurabh Shah * Not a Contribution, Apache license notifications and license are 656f610dd235b577725198e9341caae92379fdf23Saurabh Shah * retained for attribution purposes only. 756f610dd235b577725198e9341caae92379fdf23Saurabh Shah 856f610dd235b577725198e9341caae92379fdf23Saurabh Shah * Licensed under the Apache License, Version 2.0 (the "License"); 956f610dd235b577725198e9341caae92379fdf23Saurabh Shah * you may not use this file except in compliance with the License. 1056f610dd235b577725198e9341caae92379fdf23Saurabh Shah * You may obtain a copy of the License at 1156f610dd235b577725198e9341caae92379fdf23Saurabh Shah * 1256f610dd235b577725198e9341caae92379fdf23Saurabh Shah * http://www.apache.org/licenses/LICENSE-2.0 1356f610dd235b577725198e9341caae92379fdf23Saurabh Shah * 1456f610dd235b577725198e9341caae92379fdf23Saurabh Shah * Unless required by applicable law or agreed to in writing, software 1556f610dd235b577725198e9341caae92379fdf23Saurabh Shah * distributed under the License is distributed on an "AS IS" BASIS, 1656f610dd235b577725198e9341caae92379fdf23Saurabh Shah * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1756f610dd235b577725198e9341caae92379fdf23Saurabh Shah * See the License for the specific language governing permissions and 1856f610dd235b577725198e9341caae92379fdf23Saurabh Shah * limitations under the License. 1956f610dd235b577725198e9341caae92379fdf23Saurabh Shah */ 2056f610dd235b577725198e9341caae92379fdf23Saurabh Shah 2156f610dd235b577725198e9341caae92379fdf23Saurabh Shah#include <fcntl.h> 2256f610dd235b577725198e9341caae92379fdf23Saurabh Shah#include <stdint.h> 2356f610dd235b577725198e9341caae92379fdf23Saurabh Shah#include <sys/types.h> 2456f610dd235b577725198e9341caae92379fdf23Saurabh Shah#include <binder/Parcel.h> 2556f610dd235b577725198e9341caae92379fdf23Saurabh Shah#include <binder/IBinder.h> 2656f610dd235b577725198e9341caae92379fdf23Saurabh Shah#include <binder/IInterface.h> 2756f610dd235b577725198e9341caae92379fdf23Saurabh Shah#include <binder/IPCThreadState.h> 2856f610dd235b577725198e9341caae92379fdf23Saurabh Shah#include <utils/Errors.h> 2952fc4cdb4df6fe5ced235cde7f409481c71a2b21Naseer Ahmed#include <private/android_filesystem_config.h> 3056f610dd235b577725198e9341caae92379fdf23Saurabh Shah 3156f610dd235b577725198e9341caae92379fdf23Saurabh Shah#include <IQService.h> 3256f610dd235b577725198e9341caae92379fdf23Saurabh Shah 3356f610dd235b577725198e9341caae92379fdf23Saurabh Shahusing namespace android; 34d5e3e404e1344eb2148c8df9f3e35d841ddd4285Saurabh Shahusing namespace qClient; 3556f610dd235b577725198e9341caae92379fdf23Saurabh Shah 3656f610dd235b577725198e9341caae92379fdf23Saurabh Shah// --------------------------------------------------------------------------- 3756f610dd235b577725198e9341caae92379fdf23Saurabh Shah 3856f610dd235b577725198e9341caae92379fdf23Saurabh Shahnamespace qService { 3956f610dd235b577725198e9341caae92379fdf23Saurabh Shah 4056f610dd235b577725198e9341caae92379fdf23Saurabh Shahclass BpQService : public BpInterface<IQService> 4156f610dd235b577725198e9341caae92379fdf23Saurabh Shah{ 4256f610dd235b577725198e9341caae92379fdf23Saurabh Shahpublic: 4356f610dd235b577725198e9341caae92379fdf23Saurabh Shah BpQService(const sp<IBinder>& impl) 4456f610dd235b577725198e9341caae92379fdf23Saurabh Shah : BpInterface<IQService>(impl) {} 4556f610dd235b577725198e9341caae92379fdf23Saurabh Shah 4656f610dd235b577725198e9341caae92379fdf23Saurabh Shah virtual void securing(uint32_t startEnd) { 4756f610dd235b577725198e9341caae92379fdf23Saurabh Shah Parcel data, reply; 4856f610dd235b577725198e9341caae92379fdf23Saurabh Shah data.writeInterfaceToken(IQService::getInterfaceDescriptor()); 4956f610dd235b577725198e9341caae92379fdf23Saurabh Shah data.writeInt32(startEnd); 5056f610dd235b577725198e9341caae92379fdf23Saurabh Shah remote()->transact(SECURING, data, &reply); 5156f610dd235b577725198e9341caae92379fdf23Saurabh Shah } 5256f610dd235b577725198e9341caae92379fdf23Saurabh Shah 5356f610dd235b577725198e9341caae92379fdf23Saurabh Shah virtual void unsecuring(uint32_t startEnd) { 5456f610dd235b577725198e9341caae92379fdf23Saurabh Shah Parcel data, reply; 5556f610dd235b577725198e9341caae92379fdf23Saurabh Shah data.writeInterfaceToken(IQService::getInterfaceDescriptor()); 5656f610dd235b577725198e9341caae92379fdf23Saurabh Shah data.writeInt32(startEnd); 5756f610dd235b577725198e9341caae92379fdf23Saurabh Shah remote()->transact(UNSECURING, data, &reply); 5856f610dd235b577725198e9341caae92379fdf23Saurabh Shah } 59d5e3e404e1344eb2148c8df9f3e35d841ddd4285Saurabh Shah 60d5e3e404e1344eb2148c8df9f3e35d841ddd4285Saurabh Shah virtual void connect(const sp<IQClient>& client) { 61d5e3e404e1344eb2148c8df9f3e35d841ddd4285Saurabh Shah Parcel data, reply; 62d5e3e404e1344eb2148c8df9f3e35d841ddd4285Saurabh Shah data.writeInterfaceToken(IQService::getInterfaceDescriptor()); 63d5e3e404e1344eb2148c8df9f3e35d841ddd4285Saurabh Shah data.writeStrongBinder(client->asBinder()); 64d5e3e404e1344eb2148c8df9f3e35d841ddd4285Saurabh Shah remote()->transact(CONNECT, data, &reply); 65d5e3e404e1344eb2148c8df9f3e35d841ddd4285Saurabh Shah } 66e1f47e78496b6b9382d8c71c959ae6365c7a05d2Jeykumar Sankaran 67e1f47e78496b6b9382d8c71c959ae6365c7a05d2Jeykumar Sankaran virtual status_t screenRefresh() { 68e1f47e78496b6b9382d8c71c959ae6365c7a05d2Jeykumar Sankaran Parcel data, reply; 69e1f47e78496b6b9382d8c71c959ae6365c7a05d2Jeykumar Sankaran data.writeInterfaceToken(IQService::getInterfaceDescriptor()); 70e1f47e78496b6b9382d8c71c959ae6365c7a05d2Jeykumar Sankaran remote()->transact(SCREEN_REFRESH, data, &reply); 71e1f47e78496b6b9382d8c71c959ae6365c7a05d2Jeykumar Sankaran status_t result = reply.readInt32(); 72e1f47e78496b6b9382d8c71c959ae6365c7a05d2Jeykumar Sankaran return result; 73e1f47e78496b6b9382d8c71c959ae6365c7a05d2Jeykumar Sankaran } 7456f610dd235b577725198e9341caae92379fdf23Saurabh Shah}; 7556f610dd235b577725198e9341caae92379fdf23Saurabh Shah 7656f610dd235b577725198e9341caae92379fdf23Saurabh ShahIMPLEMENT_META_INTERFACE(QService, "android.display.IQService"); 7756f610dd235b577725198e9341caae92379fdf23Saurabh Shah 7856f610dd235b577725198e9341caae92379fdf23Saurabh Shah// ---------------------------------------------------------------------- 7956f610dd235b577725198e9341caae92379fdf23Saurabh Shah 8056f610dd235b577725198e9341caae92379fdf23Saurabh Shahstatic void getProcName(int pid, char *buf, int size); 8156f610dd235b577725198e9341caae92379fdf23Saurabh Shah 8256f610dd235b577725198e9341caae92379fdf23Saurabh Shahstatus_t BnQService::onTransact( 8356f610dd235b577725198e9341caae92379fdf23Saurabh Shah uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 8456f610dd235b577725198e9341caae92379fdf23Saurabh Shah{ 8556f610dd235b577725198e9341caae92379fdf23Saurabh Shah // IPC should be from mediaserver only 8656f610dd235b577725198e9341caae92379fdf23Saurabh Shah IPCThreadState* ipc = IPCThreadState::self(); 8756f610dd235b577725198e9341caae92379fdf23Saurabh Shah const int callerPid = ipc->getCallingPid(); 8852fc4cdb4df6fe5ced235cde7f409481c71a2b21Naseer Ahmed const int callerUid = ipc->getCallingUid(); 8956f610dd235b577725198e9341caae92379fdf23Saurabh Shah const size_t MAX_BUF_SIZE = 1024; 9056f610dd235b577725198e9341caae92379fdf23Saurabh Shah char callingProcName[MAX_BUF_SIZE] = {0}; 9156f610dd235b577725198e9341caae92379fdf23Saurabh Shah 9256f610dd235b577725198e9341caae92379fdf23Saurabh Shah getProcName(callerPid, callingProcName, MAX_BUF_SIZE); 9352fc4cdb4df6fe5ced235cde7f409481c71a2b21Naseer Ahmed 9452fc4cdb4df6fe5ced235cde7f409481c71a2b21Naseer Ahmed const bool permission = (callerUid == AID_MEDIA); 9556f610dd235b577725198e9341caae92379fdf23Saurabh Shah 9656f610dd235b577725198e9341caae92379fdf23Saurabh Shah switch(code) { 9756f610dd235b577725198e9341caae92379fdf23Saurabh Shah case SECURING: { 9852fc4cdb4df6fe5ced235cde7f409481c71a2b21Naseer Ahmed if(!permission) { 99e1f47e78496b6b9382d8c71c959ae6365c7a05d2Jeykumar Sankaran ALOGE("display.qservice SECURING access denied: \ 100e1f47e78496b6b9382d8c71c959ae6365c7a05d2Jeykumar Sankaran pid=%d uid=%d process=%s", 10152fc4cdb4df6fe5ced235cde7f409481c71a2b21Naseer Ahmed callerPid, callerUid, callingProcName); 10252fc4cdb4df6fe5ced235cde7f409481c71a2b21Naseer Ahmed return PERMISSION_DENIED; 10352fc4cdb4df6fe5ced235cde7f409481c71a2b21Naseer Ahmed } 10456f610dd235b577725198e9341caae92379fdf23Saurabh Shah CHECK_INTERFACE(IQService, data, reply); 10556f610dd235b577725198e9341caae92379fdf23Saurabh Shah uint32_t startEnd = data.readInt32(); 10656f610dd235b577725198e9341caae92379fdf23Saurabh Shah securing(startEnd); 10756f610dd235b577725198e9341caae92379fdf23Saurabh Shah return NO_ERROR; 10856f610dd235b577725198e9341caae92379fdf23Saurabh Shah } break; 10956f610dd235b577725198e9341caae92379fdf23Saurabh Shah case UNSECURING: { 11052fc4cdb4df6fe5ced235cde7f409481c71a2b21Naseer Ahmed if(!permission) { 111e1f47e78496b6b9382d8c71c959ae6365c7a05d2Jeykumar Sankaran ALOGE("display.qservice UNSECURING access denied: \ 112e1f47e78496b6b9382d8c71c959ae6365c7a05d2Jeykumar Sankaran pid=%d uid=%d process=%s", 11352fc4cdb4df6fe5ced235cde7f409481c71a2b21Naseer Ahmed callerPid, callerUid, callingProcName); 11452fc4cdb4df6fe5ced235cde7f409481c71a2b21Naseer Ahmed return PERMISSION_DENIED; 11552fc4cdb4df6fe5ced235cde7f409481c71a2b21Naseer Ahmed } 11656f610dd235b577725198e9341caae92379fdf23Saurabh Shah CHECK_INTERFACE(IQService, data, reply); 11756f610dd235b577725198e9341caae92379fdf23Saurabh Shah uint32_t startEnd = data.readInt32(); 11856f610dd235b577725198e9341caae92379fdf23Saurabh Shah unsecuring(startEnd); 11956f610dd235b577725198e9341caae92379fdf23Saurabh Shah return NO_ERROR; 12056f610dd235b577725198e9341caae92379fdf23Saurabh Shah } break; 121d5e3e404e1344eb2148c8df9f3e35d841ddd4285Saurabh Shah case CONNECT: { 122d5e3e404e1344eb2148c8df9f3e35d841ddd4285Saurabh Shah CHECK_INTERFACE(IQService, data, reply); 123d5e3e404e1344eb2148c8df9f3e35d841ddd4285Saurabh Shah if(callerUid != AID_GRAPHICS) { 124e1f47e78496b6b9382d8c71c959ae6365c7a05d2Jeykumar Sankaran ALOGE("display.qservice CONNECT access denied: \ 125e1f47e78496b6b9382d8c71c959ae6365c7a05d2Jeykumar Sankaran pid=%d uid=%d process=%s", 126d5e3e404e1344eb2148c8df9f3e35d841ddd4285Saurabh Shah callerPid, callerUid, callingProcName); 127d5e3e404e1344eb2148c8df9f3e35d841ddd4285Saurabh Shah return PERMISSION_DENIED; 128d5e3e404e1344eb2148c8df9f3e35d841ddd4285Saurabh Shah } 129d5e3e404e1344eb2148c8df9f3e35d841ddd4285Saurabh Shah sp<IQClient> client = 130d5e3e404e1344eb2148c8df9f3e35d841ddd4285Saurabh Shah interface_cast<IQClient>(data.readStrongBinder()); 131d5e3e404e1344eb2148c8df9f3e35d841ddd4285Saurabh Shah connect(client); 132d5e3e404e1344eb2148c8df9f3e35d841ddd4285Saurabh Shah return NO_ERROR; 133d5e3e404e1344eb2148c8df9f3e35d841ddd4285Saurabh Shah } break; 134e1f47e78496b6b9382d8c71c959ae6365c7a05d2Jeykumar Sankaran case SCREEN_REFRESH: { 135e1f47e78496b6b9382d8c71c959ae6365c7a05d2Jeykumar Sankaran CHECK_INTERFACE(IQService, data, reply); 136fc8628e30053b994cf02f4cbb24ca5dcaeb3ee54Ping Li if(callerUid != AID_SYSTEM) { 137e1f47e78496b6b9382d8c71c959ae6365c7a05d2Jeykumar Sankaran ALOGE("display.qservice SCREEN_REFRESH access denied: \ 138e1f47e78496b6b9382d8c71c959ae6365c7a05d2Jeykumar Sankaran pid=%d uid=%d process=%s",callerPid, 139e1f47e78496b6b9382d8c71c959ae6365c7a05d2Jeykumar Sankaran callerUid, callingProcName); 140e1f47e78496b6b9382d8c71c959ae6365c7a05d2Jeykumar Sankaran return PERMISSION_DENIED; 141e1f47e78496b6b9382d8c71c959ae6365c7a05d2Jeykumar Sankaran } 142e1f47e78496b6b9382d8c71c959ae6365c7a05d2Jeykumar Sankaran return screenRefresh(); 143e1f47e78496b6b9382d8c71c959ae6365c7a05d2Jeykumar Sankaran } break; 14456f610dd235b577725198e9341caae92379fdf23Saurabh Shah default: 14556f610dd235b577725198e9341caae92379fdf23Saurabh Shah return BBinder::onTransact(code, data, reply, flags); 14656f610dd235b577725198e9341caae92379fdf23Saurabh Shah } 14756f610dd235b577725198e9341caae92379fdf23Saurabh Shah} 14856f610dd235b577725198e9341caae92379fdf23Saurabh Shah 14956f610dd235b577725198e9341caae92379fdf23Saurabh Shah//Helper 15056f610dd235b577725198e9341caae92379fdf23Saurabh Shahstatic void getProcName(int pid, char *buf, int size) { 15156f610dd235b577725198e9341caae92379fdf23Saurabh Shah int fd = -1; 15256f610dd235b577725198e9341caae92379fdf23Saurabh Shah snprintf(buf, size, "/proc/%d/cmdline", pid); 15356f610dd235b577725198e9341caae92379fdf23Saurabh Shah fd = open(buf, O_RDONLY); 15456f610dd235b577725198e9341caae92379fdf23Saurabh Shah if (fd < 0) { 15556f610dd235b577725198e9341caae92379fdf23Saurabh Shah strcpy(buf, "Unknown"); 15656f610dd235b577725198e9341caae92379fdf23Saurabh Shah } else { 15756f610dd235b577725198e9341caae92379fdf23Saurabh Shah int len = read(fd, buf, size - 1); 15856f610dd235b577725198e9341caae92379fdf23Saurabh Shah buf[len] = 0; 15956f610dd235b577725198e9341caae92379fdf23Saurabh Shah close(fd); 16056f610dd235b577725198e9341caae92379fdf23Saurabh Shah } 16156f610dd235b577725198e9341caae92379fdf23Saurabh Shah} 16256f610dd235b577725198e9341caae92379fdf23Saurabh Shah 16356f610dd235b577725198e9341caae92379fdf23Saurabh Shah}; // namespace qService 164