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