Home | History | Annotate | Download | only in os
      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