1 /* 2 * Copyright (C) 2010 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 "IMountService" 18 19 #include <storage/IMountService.h> 20 #include <binder/Parcel.h> 21 22 namespace android { 23 24 enum { 25 TRANSACTION_registerListener = IBinder::FIRST_CALL_TRANSACTION, 26 TRANSACTION_unregisterListener, 27 TRANSACTION_isUsbMassStorageConnected, 28 TRANSACTION_setUsbMassStorageEnabled, 29 TRANSACTION_isUsbMassStorageEnabled, 30 TRANSACTION_mountVolume, 31 TRANSACTION_unmountVolume, 32 TRANSACTION_formatVolume, 33 TRANSACTION_getStorageUsers, 34 TRANSACTION_getVolumeState, 35 TRANSACTION_createSecureContainer, 36 TRANSACTION_finalizeSecureContainer, 37 TRANSACTION_destroySecureContainer, 38 TRANSACTION_mountSecureContainer, 39 TRANSACTION_unmountSecureContainer, 40 TRANSACTION_isSecureContainerMounted, 41 TRANSACTION_renameSecureContainer, 42 TRANSACTION_getSecureContainerPath, 43 TRANSACTION_getSecureContainerList, 44 TRANSACTION_shutdown, 45 TRANSACTION_finishMediaUpdate, 46 TRANSACTION_mountObb, 47 TRANSACTION_unmountObb, 48 TRANSACTION_isObbMounted, 49 TRANSACTION_getMountedObbPath, 50 TRANSACTION_isExternalStorageEmulated, 51 }; 52 53 class BpMountService: public BpInterface<IMountService> 54 { 55 public: BpMountService(const sp<IBinder> & impl)56 explicit BpMountService(const sp<IBinder>& impl) 57 : BpInterface<IMountService>(impl) 58 { 59 } 60 registerListener(const sp<IMountServiceListener> & listener)61 virtual void registerListener(const sp<IMountServiceListener>& listener) 62 { 63 Parcel data, reply; 64 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 65 data.writeStrongBinder(IInterface::asBinder(listener)); 66 if (remote()->transact(TRANSACTION_registerListener, data, &reply) != NO_ERROR) { 67 ALOGD("registerListener could not contact remote\n"); 68 return; 69 } 70 int32_t err = reply.readExceptionCode(); 71 if (err < 0) { 72 ALOGD("registerListener caught exception %d\n", err); 73 return; 74 } 75 } 76 unregisterListener(const sp<IMountServiceListener> & listener)77 virtual void unregisterListener(const sp<IMountServiceListener>& listener) 78 { 79 Parcel data, reply; 80 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 81 data.writeStrongBinder(IInterface::asBinder(listener)); 82 if (remote()->transact(TRANSACTION_unregisterListener, data, &reply) != NO_ERROR) { 83 ALOGD("unregisterListener could not contact remote\n"); 84 return; 85 } 86 int32_t err = reply.readExceptionCode(); 87 if (err < 0) { 88 ALOGD("unregisterListener caught exception %d\n", err); 89 return; 90 } 91 } 92 isUsbMassStorageConnected()93 virtual bool isUsbMassStorageConnected() 94 { 95 Parcel data, reply; 96 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 97 if (remote()->transact(TRANSACTION_isUsbMassStorageConnected, data, &reply) != NO_ERROR) { 98 ALOGD("isUsbMassStorageConnected could not contact remote\n"); 99 return false; 100 } 101 int32_t err = reply.readExceptionCode(); 102 if (err < 0) { 103 ALOGD("isUsbMassStorageConnected caught exception %d\n", err); 104 return false; 105 } 106 return reply.readInt32() != 0; 107 } 108 setUsbMassStorageEnabled(const bool enable)109 virtual void setUsbMassStorageEnabled(const bool enable) 110 { 111 Parcel data, reply; 112 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 113 data.writeInt32(enable != 0); 114 if (remote()->transact(TRANSACTION_setUsbMassStorageEnabled, data, &reply) != NO_ERROR) { 115 ALOGD("setUsbMassStorageEnabled could not contact remote\n"); 116 return; 117 } 118 int32_t err = reply.readExceptionCode(); 119 if (err < 0) { 120 ALOGD("setUsbMassStorageEnabled caught exception %d\n", err); 121 return; 122 } 123 } 124 isUsbMassStorageEnabled()125 virtual bool isUsbMassStorageEnabled() 126 { 127 Parcel data, reply; 128 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 129 if (remote()->transact(TRANSACTION_isUsbMassStorageEnabled, data, &reply) != NO_ERROR) { 130 ALOGD("isUsbMassStorageEnabled could not contact remote\n"); 131 return false; 132 } 133 int32_t err = reply.readExceptionCode(); 134 if (err < 0) { 135 ALOGD("isUsbMassStorageEnabled caught exception %d\n", err); 136 return false; 137 } 138 return reply.readInt32() != 0; 139 } 140 mountVolume(const String16 & mountPoint)141 int32_t mountVolume(const String16& mountPoint) 142 { 143 Parcel data, reply; 144 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 145 data.writeString16(mountPoint); 146 if (remote()->transact(TRANSACTION_mountVolume, data, &reply) != NO_ERROR) { 147 ALOGD("mountVolume could not contact remote\n"); 148 return -1; 149 } 150 int32_t err = reply.readExceptionCode(); 151 if (err < 0) { 152 ALOGD("mountVolume caught exception %d\n", err); 153 return err; 154 } 155 return reply.readInt32(); 156 } 157 unmountVolume(const String16 & mountPoint,const bool force,const bool removeEncryption)158 int32_t unmountVolume(const String16& mountPoint, const bool force, const bool removeEncryption) 159 { 160 Parcel data, reply; 161 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 162 data.writeString16(mountPoint); 163 data.writeInt32(force ? 1 : 0); 164 data.writeInt32(removeEncryption ? 1 : 0); 165 if (remote()->transact(TRANSACTION_unmountVolume, data, &reply) != NO_ERROR) { 166 ALOGD("unmountVolume could not contact remote\n"); 167 return -1; 168 } 169 int32_t err = reply.readExceptionCode(); 170 if (err < 0) { 171 ALOGD("unmountVolume caught exception %d\n", err); 172 return err; 173 } 174 return reply.readInt32(); 175 } 176 formatVolume(const String16 & mountPoint)177 int32_t formatVolume(const String16& mountPoint) 178 { 179 Parcel data, reply; 180 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 181 data.writeString16(mountPoint); 182 if (remote()->transact(TRANSACTION_formatVolume, data, &reply) != NO_ERROR) { 183 ALOGD("formatVolume could not contact remote\n"); 184 return -1; 185 } 186 int32_t err = reply.readExceptionCode(); 187 if (err < 0) { 188 ALOGD("formatVolume caught exception %d\n", err); 189 return err; 190 } 191 return reply.readInt32(); 192 } 193 getStorageUsers(const String16 & mountPoint,int32_t ** users)194 int32_t getStorageUsers(const String16& mountPoint, int32_t** users) 195 { 196 Parcel data, reply; 197 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 198 data.writeString16(mountPoint); 199 if (remote()->transact(TRANSACTION_getStorageUsers, data, &reply) != NO_ERROR) { 200 ALOGD("getStorageUsers could not contact remote\n"); 201 return -1; 202 } 203 int32_t err = reply.readExceptionCode(); 204 if (err < 0) { 205 ALOGD("getStorageUsers caught exception %d\n", err); 206 return err; 207 } 208 int32_t numUsersI = reply.readInt32(); 209 uint32_t numUsers; 210 if (numUsersI < 0) { 211 ALOGW("Number of users is negative: %d\n", numUsersI); 212 numUsers = 0; 213 } else { 214 numUsers = static_cast<uint32_t>(numUsersI); 215 } 216 *users = (int32_t*)malloc(sizeof(int32_t)*numUsers); 217 for (size_t i = 0; i < numUsers; i++) { 218 **users++ = reply.readInt32(); 219 } 220 return static_cast<int32_t>(numUsers); 221 } 222 getVolumeState(const String16 & mountPoint)223 int32_t getVolumeState(const String16& mountPoint) 224 { 225 Parcel data, reply; 226 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 227 data.writeString16(mountPoint); 228 if (remote()->transact(TRANSACTION_getVolumeState, data, &reply) != NO_ERROR) { 229 ALOGD("getVolumeState could not contact remote\n"); 230 return -1; 231 } 232 int32_t err = reply.readExceptionCode(); 233 if (err < 0) { 234 ALOGD("getVolumeState caught exception %d\n", err); 235 return err; 236 } 237 return reply.readInt32(); 238 } 239 createSecureContainer(const String16 & id,const int32_t sizeMb,const String16 & fstype,const String16 & key,const int32_t ownerUid)240 int32_t createSecureContainer(const String16& id, const int32_t sizeMb, const String16& fstype, 241 const String16& key, const int32_t ownerUid) 242 { 243 Parcel data, reply; 244 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 245 data.writeString16(id); 246 data.writeInt32(sizeMb); 247 data.writeString16(fstype); 248 data.writeString16(key); 249 data.writeInt32(ownerUid); 250 if (remote()->transact(TRANSACTION_createSecureContainer, data, &reply) != NO_ERROR) { 251 ALOGD("createSecureContainer could not contact remote\n"); 252 return -1; 253 } 254 int32_t err = reply.readExceptionCode(); 255 if (err < 0) { 256 ALOGD("createSecureContainer caught exception %d\n", err); 257 return err; 258 } 259 return reply.readInt32(); 260 } 261 finalizeSecureContainer(const String16 & id)262 int32_t finalizeSecureContainer(const String16& id) 263 { 264 Parcel data, reply; 265 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 266 data.writeString16(id); 267 if (remote()->transact(TRANSACTION_finalizeSecureContainer, data, &reply) != NO_ERROR) { 268 ALOGD("finalizeSecureContainer couldn't call remote\n"); 269 return -1; 270 } 271 int32_t err = reply.readExceptionCode(); 272 if (err < 0) { 273 ALOGD("finalizeSecureContainer caught exception %d\n", err); 274 return err; 275 } 276 return reply.readInt32(); 277 } 278 destroySecureContainer(const String16 & id)279 int32_t destroySecureContainer(const String16& id) 280 { 281 Parcel data, reply; 282 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 283 data.writeString16(id); 284 if (remote()->transact(TRANSACTION_destroySecureContainer, data, &reply) != NO_ERROR) { 285 ALOGD("destroySecureContainer couldn't call remote"); 286 return -1; 287 } 288 int32_t err = reply.readExceptionCode(); 289 if (err < 0) { 290 ALOGD("destroySecureContainer caught exception %d\n", err); 291 return err; 292 } 293 return reply.readInt32(); 294 } 295 mountSecureContainer(const String16 & id,const String16 & key,const int32_t ownerUid)296 int32_t mountSecureContainer(const String16& id, const String16& key, const int32_t ownerUid) 297 { 298 Parcel data, reply; 299 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 300 data.writeString16(id); 301 data.writeString16(key); 302 data.writeInt32(ownerUid); 303 // Assume read-only 304 data.writeInt32(1); 305 if (remote()->transact(TRANSACTION_mountSecureContainer, data, &reply) != NO_ERROR) { 306 ALOGD("mountSecureContainer couldn't call remote"); 307 return -1; 308 } 309 int32_t err = reply.readExceptionCode(); // What to do... 310 if (err < 0) { 311 ALOGD("mountSecureContainer caught exception %d\n", err); 312 return err; 313 } 314 return reply.readInt32(); 315 } 316 unmountSecureContainer(const String16 & id,const bool force)317 int32_t unmountSecureContainer(const String16& id, const bool force) 318 { 319 Parcel data, reply; 320 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 321 data.writeString16(id); 322 data.writeInt32(force ? 1 : 0); 323 if (remote()->transact(TRANSACTION_getSecureContainerPath, data, &reply) != NO_ERROR) { 324 ALOGD("unmountSecureContainer couldn't call remote"); 325 return -1; 326 } 327 int32_t err = reply.readExceptionCode(); // What to do... 328 if (err < 0) { 329 ALOGD("unmountSecureContainer caught exception %d\n", err); 330 return err; 331 } 332 return reply.readInt32(); 333 } 334 isSecureContainerMounted(const String16 & id)335 bool isSecureContainerMounted(const String16& id) 336 { 337 Parcel data, reply; 338 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 339 data.writeString16(id); 340 if (remote()->transact(TRANSACTION_isSecureContainerMounted, data, &reply) != NO_ERROR) { 341 ALOGD("isSecureContainerMounted couldn't call remote"); 342 return false; 343 } 344 int32_t err = reply.readExceptionCode(); // What to do... 345 if (err < 0) { 346 ALOGD("isSecureContainerMounted caught exception %d\n", err); 347 return false; 348 } 349 return reply.readInt32() != 0; 350 } 351 renameSecureContainer(const String16 & oldId,const String16 & newId)352 int32_t renameSecureContainer(const String16& oldId, const String16& newId) 353 { 354 Parcel data, reply; 355 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 356 data.writeString16(oldId); 357 data.writeString16(newId); 358 if (remote()->transact(TRANSACTION_renameSecureContainer, data, &reply) != NO_ERROR) { 359 ALOGD("renameSecureContainer couldn't call remote"); 360 return -1; 361 } 362 int32_t err = reply.readExceptionCode(); // What to do... 363 if (err < 0) { 364 ALOGD("renameSecureContainer caught exception %d\n", err); 365 return err; 366 } 367 return reply.readInt32(); 368 } 369 getSecureContainerPath(const String16 & id,String16 & path)370 bool getSecureContainerPath(const String16& id, String16& path) 371 { 372 Parcel data, reply; 373 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 374 data.writeString16(id); 375 if (remote()->transact(TRANSACTION_getSecureContainerPath, data, &reply) != NO_ERROR) { 376 ALOGD("getSecureContainerPath couldn't call remote"); 377 return false; 378 } 379 int32_t err = reply.readExceptionCode(); // What to do... 380 if (err < 0) { 381 ALOGD("getSecureContainerPath caught exception %d\n", err); 382 return false; 383 } 384 path = reply.readString16(); 385 return true; 386 } 387 getSecureContainerList(const String16 & id,String16 * & containers)388 int32_t getSecureContainerList(const String16& id, String16*& containers) 389 { 390 Parcel data, reply; 391 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 392 data.writeString16(id); 393 if (remote()->transact(TRANSACTION_getSecureContainerList, data, &reply) != NO_ERROR) { 394 ALOGD("getSecureContainerList couldn't call remote"); 395 return -1; 396 } 397 int32_t err = reply.readExceptionCode(); 398 if (err < 0) { 399 ALOGD("getSecureContainerList caught exception %d\n", err); 400 return err; 401 } 402 const int32_t numStrings = reply.readInt32(); 403 containers = new String16[numStrings]; 404 for (int i = 0; i < numStrings; i++) { 405 containers[i] = reply.readString16(); 406 } 407 return numStrings; 408 } 409 shutdown(const sp<IMountShutdownObserver> & observer)410 void shutdown(const sp<IMountShutdownObserver>& observer) 411 { 412 Parcel data, reply; 413 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 414 data.writeStrongBinder(IInterface::asBinder(observer)); 415 if (remote()->transact(TRANSACTION_shutdown, data, &reply) != NO_ERROR) { 416 ALOGD("shutdown could not contact remote\n"); 417 return; 418 } 419 int32_t err = reply.readExceptionCode(); 420 if (err < 0) { 421 ALOGD("shutdown caught exception %d\n", err); 422 return; 423 } 424 reply.readExceptionCode(); 425 } 426 finishMediaUpdate()427 void finishMediaUpdate() 428 { 429 Parcel data, reply; 430 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 431 if (remote()->transact(TRANSACTION_finishMediaUpdate, data, &reply) != NO_ERROR) { 432 ALOGD("finishMediaUpdate could not contact remote\n"); 433 return; 434 } 435 int32_t err = reply.readExceptionCode(); 436 if (err < 0) { 437 ALOGD("finishMediaUpdate caught exception %d\n", err); 438 return; 439 } 440 reply.readExceptionCode(); 441 } 442 mountObb(const String16 & rawPath,const String16 & canonicalPath,const sp<IObbActionListener> & token,int32_t nonce,const sp<ObbInfo> & obbInfo)443 void mountObb(const String16& rawPath, const String16& canonicalPath, 444 const sp<IObbActionListener>& token, int32_t nonce, const sp<ObbInfo>& obbInfo) 445 { 446 Parcel data, reply; 447 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 448 data.writeString16(rawPath); 449 data.writeString16(canonicalPath); 450 data.writeStrongBinder(IInterface::asBinder(token)); 451 data.writeInt32(nonce); 452 obbInfo->writeToParcel(&data); 453 if (remote()->transact(TRANSACTION_mountObb, data, &reply) != NO_ERROR) { 454 ALOGD("mountObb could not contact remote\n"); 455 return; 456 } 457 int32_t err = reply.readExceptionCode(); 458 if (err < 0) { 459 ALOGD("mountObb caught exception %d\n", err); 460 return; 461 } 462 } 463 unmountObb(const String16 & filename,const bool force,const sp<IObbActionListener> & token,const int32_t nonce)464 void unmountObb(const String16& filename, const bool force, 465 const sp<IObbActionListener>& token, const int32_t nonce) 466 { 467 Parcel data, reply; 468 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 469 data.writeString16(filename); 470 data.writeInt32(force ? 1 : 0); 471 data.writeStrongBinder(IInterface::asBinder(token)); 472 data.writeInt32(nonce); 473 if (remote()->transact(TRANSACTION_unmountObb, data, &reply) != NO_ERROR) { 474 ALOGD("unmountObb could not contact remote\n"); 475 return; 476 } 477 int32_t err = reply.readExceptionCode(); 478 if (err < 0) { 479 ALOGD("unmountObb caught exception %d\n", err); 480 return; 481 } 482 } 483 isObbMounted(const String16 & filename)484 bool isObbMounted(const String16& filename) 485 { 486 Parcel data, reply; 487 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 488 data.writeString16(filename); 489 if (remote()->transact(TRANSACTION_isObbMounted, data, &reply) != NO_ERROR) { 490 ALOGD("isObbMounted could not contact remote\n"); 491 return false; 492 } 493 int32_t err = reply.readExceptionCode(); 494 if (err < 0) { 495 ALOGD("isObbMounted caught exception %d\n", err); 496 return false; 497 } 498 return reply.readInt32() != 0; 499 } 500 getMountedObbPath(const String16 & filename,String16 & path)501 bool getMountedObbPath(const String16& filename, String16& path) 502 { 503 Parcel data, reply; 504 data.writeInterfaceToken(IMountService::getInterfaceDescriptor()); 505 data.writeString16(filename); 506 if (remote()->transact(TRANSACTION_getMountedObbPath, data, &reply) != NO_ERROR) { 507 ALOGD("getMountedObbPath could not contact remote\n"); 508 return false; 509 } 510 int32_t err = reply.readExceptionCode(); 511 if (err < 0) { 512 ALOGD("getMountedObbPath caught exception %d\n", err); 513 return false; 514 } 515 path = reply.readString16(); 516 return true; 517 } 518 }; 519 520 IMPLEMENT_META_INTERFACE(MountService, "android.os.storage.IStorageManager") 521 522 // ---------------------------------------------------------------------- 523 524 } 525