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 "DropBoxManager" 18 19 #include <android/os/DropBoxManager.h> 20 21 #include <binder/IServiceManager.h> 22 #include <com/android/internal/os/IDropBoxManagerService.h> 23 #include <cutils/log.h> 24 25 #include <sys/types.h> 26 #include <sys/stat.h> 27 #include <fcntl.h> 28 29 namespace android { 30 namespace os { 31 32 using namespace ::com::android::internal::os; 33 34 DropBoxManager::Entry::Entry() 35 :mTag(), 36 mTimeMillis(0), 37 mFlags(IS_EMPTY), 38 mData(), 39 mFd() 40 { 41 mFlags = IS_EMPTY; 42 } 43 44 DropBoxManager::Entry::Entry(const String16& tag, int32_t flags) 45 :mTag(tag), 46 mTimeMillis(0), 47 mFlags(flags), 48 mData(), 49 mFd() 50 { 51 } 52 53 DropBoxManager::Entry::Entry(const String16& tag, int32_t flags, int fd) 54 :mTag(tag), 55 mTimeMillis(0), 56 mFlags(flags), 57 mData(), 58 mFd(fd) 59 { 60 } 61 62 DropBoxManager::Entry::~Entry() 63 { 64 } 65 66 status_t 67 DropBoxManager::Entry::writeToParcel(Parcel* out) const 68 { 69 status_t err; 70 71 err = out->writeString16(mTag); 72 if (err != NO_ERROR) { 73 return err; 74 } 75 76 err = out->writeInt64(mTimeMillis); 77 if (err != NO_ERROR) { 78 return err; 79 } 80 81 if (mFd.get() != -1) { 82 err = out->writeInt32(mFlags & ~HAS_BYTE_ARRAY); // Clear bit just to be safe 83 if (err != NO_ERROR) { 84 return err; 85 } 86 ALOGD("writing fd %d\n", mFd.get()); 87 err = out->writeParcelFileDescriptor(mFd); 88 if (err != NO_ERROR) { 89 return err; 90 } 91 } else { 92 err = out->writeInt32(mFlags | HAS_BYTE_ARRAY); 93 if (err != NO_ERROR) { 94 return err; 95 } 96 err = out->writeByteVector(mData); 97 if (err != NO_ERROR) { 98 return err; 99 } 100 } 101 return NO_ERROR; 102 } 103 104 status_t 105 DropBoxManager::Entry::readFromParcel(const Parcel* in) 106 { 107 status_t err; 108 109 err = in->readString16(&mTag); 110 if (err != NO_ERROR) { 111 return err; 112 } 113 114 err = in->readInt64(&mTimeMillis); 115 if (err != NO_ERROR) { 116 return err; 117 } 118 119 err = in->readInt32(&mFlags); 120 if (err != NO_ERROR) { 121 return err; 122 } 123 124 if ((mFlags & HAS_BYTE_ARRAY) != 0) { 125 err = in->readByteVector(&mData); 126 if (err != NO_ERROR) { 127 return err; 128 } 129 mFlags &= ~HAS_BYTE_ARRAY; 130 } else { 131 int fd; 132 fd = in->readParcelFileDescriptor(); 133 if (fd == -1) { 134 return EBADF; 135 } 136 fd = dup(fd); 137 if (fd == -1) { 138 return errno; 139 } 140 mFd.reset(fd); 141 } 142 143 return NO_ERROR; 144 } 145 146 const vector<uint8_t>& 147 DropBoxManager::Entry::getData() const 148 { 149 return mData; 150 } 151 152 const unique_fd& 153 DropBoxManager::Entry::getFd() const 154 { 155 return mFd; 156 } 157 158 int32_t 159 DropBoxManager::Entry::getFlags() const 160 { 161 return mFlags; 162 } 163 164 int64_t 165 DropBoxManager::Entry::getTimestamp() const 166 { 167 return mTimeMillis; 168 } 169 170 DropBoxManager::DropBoxManager() 171 { 172 } 173 174 DropBoxManager::~DropBoxManager() 175 { 176 } 177 178 Status 179 DropBoxManager::addText(const String16& tag, const string& text) 180 { 181 Entry entry(tag, IS_TEXT); 182 entry.mData.assign(text.c_str(), text.c_str() + text.size()); 183 return add(entry); 184 } 185 186 Status 187 DropBoxManager::addData(const String16& tag, uint8_t const* data, 188 size_t size, int flags) 189 { 190 Entry entry(tag, flags); 191 entry.mData.assign(data, data+size); 192 return add(entry); 193 } 194 195 Status 196 DropBoxManager::addFile(const String16& tag, const string& filename, int flags) 197 { 198 int fd = open(filename.c_str(), O_RDONLY); 199 if (fd == -1) { 200 string message("addFile can't open file: "); 201 message += filename; 202 ALOGW("DropboxManager: %s", message.c_str()); 203 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE, message.c_str()); 204 } 205 return addFile(tag, fd, flags); 206 } 207 208 Status 209 DropBoxManager::addFile(const String16& tag, int fd, int flags) 210 { 211 if (fd == -1) { 212 string message("invalid fd (-1) passed to to addFile"); 213 ALOGW("DropboxManager: %s", message.c_str()); 214 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE, message.c_str()); 215 } 216 Entry entry(tag, flags, fd); 217 return add(entry); 218 } 219 220 Status 221 DropBoxManager::add(const Entry& entry) 222 { 223 sp<IDropBoxManagerService> service = interface_cast<IDropBoxManagerService>( 224 defaultServiceManager()->getService(android::String16("dropbox"))); 225 if (service == NULL) { 226 return Status::fromExceptionCode(Status::EX_NULL_POINTER, "can't find dropbox service"); 227 } 228 ALOGD("About to call service->add()"); 229 Status status = service->add(entry); 230 ALOGD("service->add returned %s", status.toString8().string()); 231 return status; 232 } 233 234 }} // namespace android::os 235