| Ray Essick | 3938dc6 | 2016-11-01 08:56:56 -0700 | [diff] [blame] | 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 "MediaAnalytics" | 
|  | 18 |  | 
|  | 19 | #include <stdint.h> | 
|  | 20 | #include <inttypes.h> | 
|  | 21 | #include <sys/types.h> | 
|  | 22 |  | 
|  | 23 | #include <binder/Parcel.h> | 
|  | 24 | #include <binder/IMemory.h> | 
|  | 25 | #include <binder/IPCThreadState.h> | 
| Ray Essick | 3938dc6 | 2016-11-01 08:56:56 -0700 | [diff] [blame] | 26 |  | 
|  | 27 | #include <utils/Errors.h>  // for status_t | 
|  | 28 | #include <utils/List.h> | 
|  | 29 | #include <utils/Log.h> | 
|  | 30 | #include <utils/String8.h> | 
|  | 31 |  | 
|  | 32 | #include <media/MediaAnalyticsItem.h> | 
|  | 33 | #include <media/IMediaAnalyticsService.h> | 
|  | 34 |  | 
|  | 35 | #define DEBUGGING               0 | 
|  | 36 | #define DEBUGGING_FLOW          0 | 
|  | 37 | #define DEBUGGING_RETURNS       0 | 
|  | 38 |  | 
|  | 39 | namespace android { | 
|  | 40 |  | 
|  | 41 | enum { | 
|  | 42 | GENERATE_UNIQUE_SESSIONID = IBinder::FIRST_CALL_TRANSACTION, | 
|  | 43 | SUBMIT_ITEM, | 
| Ray Essick | 3938dc6 | 2016-11-01 08:56:56 -0700 | [diff] [blame] | 44 | }; | 
|  | 45 |  | 
|  | 46 | class BpMediaAnalyticsService: public BpInterface<IMediaAnalyticsService> | 
|  | 47 | { | 
|  | 48 | public: | 
|  | 49 | explicit BpMediaAnalyticsService(const sp<IBinder>& impl) | 
|  | 50 | : BpInterface<IMediaAnalyticsService>(impl) | 
|  | 51 | { | 
|  | 52 | } | 
|  | 53 |  | 
|  | 54 | virtual MediaAnalyticsItem::SessionID_t generateUniqueSessionID() { | 
|  | 55 | Parcel data, reply; | 
|  | 56 | status_t err; | 
|  | 57 | MediaAnalyticsItem::SessionID_t sessionid = | 
|  | 58 | MediaAnalyticsItem::SessionIDInvalid; | 
|  | 59 |  | 
|  | 60 | data.writeInterfaceToken(IMediaAnalyticsService::getInterfaceDescriptor()); | 
|  | 61 | err = remote()->transact(GENERATE_UNIQUE_SESSIONID, data, &reply); | 
|  | 62 | if (err != NO_ERROR) { | 
|  | 63 | ALOGW("bad response from service"); | 
|  | 64 | return MediaAnalyticsItem::SessionIDInvalid; | 
|  | 65 | } | 
|  | 66 | sessionid = reply.readInt64(); | 
|  | 67 | if (DEBUGGING_RETURNS) { | 
|  | 68 | ALOGD("the caller gets a sessionid of %" PRId64 " back", sessionid); | 
|  | 69 | } | 
|  | 70 | return sessionid; | 
|  | 71 | } | 
|  | 72 |  | 
| Ray Essick | b5fac8e | 2016-12-12 11:33:56 -0800 | [diff] [blame] | 73 | virtual MediaAnalyticsItem::SessionID_t submit(MediaAnalyticsItem *item, bool forcenew) | 
| Ray Essick | 3938dc6 | 2016-11-01 08:56:56 -0700 | [diff] [blame] | 74 | { | 
|  | 75 | // have this record submit itself | 
|  | 76 | // this will be a binder call with appropriate timing | 
|  | 77 | // return value is the uuid that the system generated for it. | 
|  | 78 | // the return value 0 and -1 are reserved. | 
|  | 79 | // -1 to indicate that there was a problem recording... | 
|  | 80 |  | 
|  | 81 | Parcel data, reply; | 
|  | 82 | status_t err; | 
|  | 83 |  | 
|  | 84 | if (item == NULL) { | 
|  | 85 | return MediaAnalyticsItem::SessionIDInvalid; | 
|  | 86 | } | 
|  | 87 |  | 
|  | 88 | data.writeInterfaceToken(IMediaAnalyticsService::getInterfaceDescriptor()); | 
|  | 89 | if(DEBUGGING_FLOW) { | 
|  | 90 | ALOGD("client offers record: %s", item->toString().c_str()); | 
|  | 91 | } | 
|  | 92 | data.writeBool(forcenew); | 
|  | 93 | item->writeToParcel(&data); | 
|  | 94 |  | 
|  | 95 | err = remote()->transact(SUBMIT_ITEM, data, &reply); | 
|  | 96 | if (err != NO_ERROR) { | 
|  | 97 | return MediaAnalyticsItem::SessionIDInvalid; | 
|  | 98 | } | 
|  | 99 |  | 
|  | 100 | // get an answer out of 'reply' | 
|  | 101 | int64_t sessionid = reply.readInt64(); | 
|  | 102 | if (DEBUGGING_RETURNS) { | 
|  | 103 | ALOGD("the caller gets sessionid=%" PRId64 "", sessionid); | 
|  | 104 | } | 
|  | 105 | return sessionid; | 
|  | 106 | } | 
|  | 107 |  | 
| Ray Essick | 3938dc6 | 2016-11-01 08:56:56 -0700 | [diff] [blame] | 108 | }; | 
|  | 109 |  | 
|  | 110 | IMPLEMENT_META_INTERFACE(MediaAnalyticsService, "android.media.IMediaAnalyticsService"); | 
|  | 111 |  | 
|  | 112 | // ---------------------------------------------------------------------- | 
|  | 113 |  | 
|  | 114 | status_t BnMediaAnalyticsService::onTransact( | 
|  | 115 | uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) | 
|  | 116 | { | 
|  | 117 |  | 
|  | 118 |  | 
|  | 119 | // get calling pid/tid | 
|  | 120 | IPCThreadState *ipc = IPCThreadState::self(); | 
|  | 121 | int clientPid = ipc->getCallingPid(); | 
|  | 122 | // permission checking | 
|  | 123 |  | 
|  | 124 | if(DEBUGGING_FLOW) { | 
|  | 125 | ALOGD("running in service, code %d, pid %d; called from pid %d", | 
|  | 126 | code, getpid(), clientPid); | 
|  | 127 | } | 
|  | 128 |  | 
|  | 129 | switch (code) { | 
|  | 130 |  | 
|  | 131 | case GENERATE_UNIQUE_SESSIONID: { | 
|  | 132 | CHECK_INTERFACE(IMediaAnalyticsService, data, reply); | 
|  | 133 |  | 
|  | 134 | MediaAnalyticsItem::SessionID_t sessionid = generateUniqueSessionID(); | 
|  | 135 | reply->writeInt64(sessionid); | 
|  | 136 |  | 
|  | 137 | return NO_ERROR; | 
|  | 138 | } break; | 
|  | 139 |  | 
|  | 140 | case SUBMIT_ITEM: { | 
|  | 141 | CHECK_INTERFACE(IMediaAnalyticsService, data, reply); | 
|  | 142 |  | 
|  | 143 | bool forcenew; | 
| Ray Essick | b5fac8e | 2016-12-12 11:33:56 -0800 | [diff] [blame] | 144 | MediaAnalyticsItem *item = new MediaAnalyticsItem; | 
| Ray Essick | 3938dc6 | 2016-11-01 08:56:56 -0700 | [diff] [blame] | 145 |  | 
|  | 146 | data.readBool(&forcenew); | 
|  | 147 | item->readFromParcel(data); | 
|  | 148 |  | 
|  | 149 | item->setPid(clientPid); | 
|  | 150 |  | 
| Ray Essick | b5fac8e | 2016-12-12 11:33:56 -0800 | [diff] [blame] | 151 | // submit() takes over ownership of 'item' | 
| Ray Essick | 3938dc6 | 2016-11-01 08:56:56 -0700 | [diff] [blame] | 152 | MediaAnalyticsItem::SessionID_t sessionid = submit(item, forcenew); | 
|  | 153 | reply->writeInt64(sessionid); | 
|  | 154 |  | 
|  | 155 | return NO_ERROR; | 
|  | 156 | } break; | 
|  | 157 |  | 
| Ray Essick | 3938dc6 | 2016-11-01 08:56:56 -0700 | [diff] [blame] | 158 | default: | 
|  | 159 | return BBinder::onTransact(code, data, reply, flags); | 
|  | 160 | } | 
|  | 161 | } | 
|  | 162 |  | 
|  | 163 | // ---------------------------------------------------------------------------- | 
|  | 164 |  | 
|  | 165 | } // namespace android |