2024年Android最新Android中的Parcel机制,kotlin面试题和答案

最后

希望本文对你有所启发,有任何面试上的建议也欢迎留言分享给大家。

好了,今天的分享就到这里,如果你对在面试中遇到的问题,或者刚毕业及工作几年迷茫不知道该如何准备面试并突破现状提升自己,对于自己的未来还不够了解不知道给如何规划,来看看同行们都是如何突破现状,怎么学习的,来吸收他们的面试以及工作经验完善自己的之后的面试计划及职业规划。

好了~如果你看到了这里,觉得文章写得不错就给个赞呗?如果你觉得那里值得改进的,请给我留言。一定会认真查询,修正不足。谢谢。

为什么某些人会一直比你优秀,是因为他本身就很优秀还一直在持续努力变得更优秀,而你是不是还在满足于现状内心在窃喜!希望读到这的您能点个小赞和关注下我,以后还会更新技术干货,谢谢您的支持!

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  1. private:

  2. Parcel(const Parcel& o);

  3. Parcel&             operator=(const Parcel& o);

  4. status_t            finishWrite(size_t len);

  5. void                releaseObjects();

  6. void                acquireObjects();

  7. status_t            growData(size_t len);

  8. status_t            restartWrite(size_t desired);

  9. status_t            continueWrite(size_t desired);

  10. void                freeDataNoInit();

  11. void                initState();

  12. void                scanForFds() const;

  13. template

  14. status_t            readAligned(T *pArg) const;

  15. template   T readAligned() const;

  16. template

  17. status_t            writeAligned(T val);

  18. status_t            mError;

  19. uint8_t*            mData;

  20. size_t              mDataSize;

  21. size_t              mDataCapacity;

  22. mutable size_t      mDataPos;

  23. size_t*             mObjects;

  24. size_t              mObjectsSize;

  25. size_t              mObjectsCapacity;

  26. mutable size_t      mNextObjectHint;

  27. mutable bool        mFdsKnown;

  28. mutable bool        mHasFds;

  29. release_func        mOwner;

  30. void*               mOwnerCookie;

  31. };

  32. // ---------------------------------------------------------------------------

  33. inline TextOutput& operator<<(TextOutput& to, const Parcel& parcel)

  34. {

  35. parcel.print(to);

  36. return to;

  37. }

  38. // ---------------------------------------------------------------------------

  39. // Generic acquire and release of objects.

  40. void acquire_object(const sp& proc,

  41. const flat_binder_object& obj, const void* who);

  42. void release_object(const sp& proc,

  43. const flat_binder_object& obj, const void* who);

  44. void flatten_binder(const sp& proc,

  45. const sp& binder, flat_binder_object* out);

  46. void flatten_binder(const sp& proc,

  47. const wp& binder, flat_binder_object* out);

  48. status_t unflatten_binder(const sp& proc,

  49. const flat_binder_object& flat, sp* out);

  50. status_t unflatten_binder(const sp& proc,

  51. const flat_binder_object& flat, wp* out);

  52. }; // namespace android

  53. // ---------------------------------------------------------------------------

  54. #endif // ANDROID_PARCEL_H

[cpp]  view plain copy

  1. /*

  2. * Copyright © 2005 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. #define LOG_TAG “Parcel”

  17. //#define LOG_NDEBUG 0

  18. #include <binder/Parcel.h>

  19. #include <binder/Binder.h>

  20. #include <binder/BpBinder.h>

  21. #include <utils/Debug.h>

  22. #include <binder/ProcessState.h>

  23. #include <utils/Log.h>

  24. #include <utils/String8.h>

  25. #include <utils/String16.h>

  26. #include <utils/TextOutput.h>

  27. #include <utils/misc.h>

  28. #include <utils/Flattenable.h>

  29. #include <private/binder/binder_module.h>

  30. #include <stdio.h>

  31. #include <stdlib.h>

  32. #include <stdint.h>

  33. #ifndef INT32_MAX

  34. #define INT32_MAX ((int32_t)(2147483647))

  35. #endif

  36. #define LOG_REFS(…)

  37. //#define LOG_REFS(…) LOG(LOG_DEBUG, “Parcel”, __VA_ARGS__)

  38. // ---------------------------------------------------------------------------

  39. #define PAD_SIZE(s) (((s)+3)&~3)

  40. // XXX This can be made public if we want to provide

  41. // support for typed data.

  42. struct small_flat_data

  43. {

  44. uint32_t type;

  45. uint32_t data;

  46. };

  47. namespace android {

  48. void acquire_object(const sp& proc,

  49. const flat_binder_object& obj, const void* who)

  50. {

  51. switch (obj.type) {

  52. case BINDER_TYPE_BINDER:

  53. if (obj.binder) {

  54. LOG_REFS(“Parcel %p acquiring reference on local %p”, who, obj.cookie);

  55. static_cast<IBinder*>(obj.cookie)->incStrong(who);

  56. }

  57. return;

  58. case BINDER_TYPE_WEAK_BINDER:

  59. if (obj.binder)

  60. static_castRefBase::weakref\_type\*(obj.binder)->incWeak(who);

  61. return;

  62. case BINDER_TYPE_HANDLE: {

  63. const sp b = proc->getStrongProxyForHandle(obj.handle);

  64. if (b != NULL) {

  65. LOG_REFS(“Parcel %p acquiring reference on remote %p”, who, b.get());

  66. b->incStrong(who);

  67. }

  68. return;

  69. }

  70. case BINDER_TYPE_WEAK_HANDLE: {

  71. const wp b = proc->getWeakProxyForHandle(obj.handle);

  72. if (b != NULL) b.get_refs()->incWeak(who);

  73. return;

  74. }

  75. case BINDER_TYPE_FD: {

  76. // intentionally blank – nothing to do to acquire this, but we do

  77. // recognize it as a legitimate object type.

  78. return;

  79. }

  80. }

  81. LOGD(“Invalid object type 0x%08lx”, obj.type);

  82. }

  83. void release_object(const sp& proc,

  84. const flat_binder_object& obj, const void* who)

  85. {

  86. switch (obj.type) {

  87. case BINDER_TYPE_BINDER:

  88. if (obj.binder) {

  89. LOG_REFS(“Parcel %p releasing reference on local %p”, who, obj.cookie);

  90. static_cast<IBinder*>(obj.cookie)->decStrong(who);

  91. }

  92. return;

  93. case BINDER_TYPE_WEAK_BINDER:

  94. if (obj.binder)

  95. static_castRefBase::weakref\_type\*(obj.binder)->decWeak(who);

  96. return;

  97. case BINDER_TYPE_HANDLE: {

  98. const sp b = proc->getStrongProxyForHandle(obj.handle);

  99. if (b != NULL) {

  100. LOG_REFS(“Parcel %p releasing reference on remote %p”, who, b.get());

  101. b->decStrong(who);

  102. }

  103. return;

  104. }

  105. case BINDER_TYPE_WEAK_HANDLE: {

  106. const wp b = proc->getWeakProxyForHandle(obj.handle);

  107. if (b != NULL) b.get_refs()->decWeak(who);

  108. return;

  109. }

  110. case BINDER_TYPE_FD: {

  111. if (obj.cookie != (void*)0) close(obj.handle);

  112. return;

  113. }

  114. }

  115. LOGE(“Invalid object type 0x%08lx”, obj.type);

  116. }

  117. inline static status_t finish_flatten_binder(

  118. const sp& binder, const flat_binder_object& flat, Parcel* out)

  119. {

  120. return out->writeObject(flat, false);

  121. }

  122. status_t flatten_binder(const sp& proc,

  123. const sp& binder, Parcel* out)

  124. {

  125. flat_binder_object obj;

  126. obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;

  127. if (binder != NULL) {

  128. IBinder *local = binder->localBinder();

  129. if (!local) {

  130. BpBinder *proxy = binder->remoteBinder();

  131. if (proxy == NULL) {

  132. LOGE(“null proxy”);

  133. }

  134. const int32_t handle = proxy ? proxy->handle() : 0;

  135. obj.type = BINDER_TYPE_HANDLE;

  136. obj.handle = handle;

  137. obj.cookie = NULL;

  138. } else {

  139. obj.type = BINDER_TYPE_BINDER;

  140. obj.binder = local->getWeakRefs();

  141. obj.cookie = local;

  142. }

  143. } else {

  144. obj.type = BINDER_TYPE_BINDER;

  145. obj.binder = NULL;

  146. obj.cookie = NULL;

  147. }

  148. return finish_flatten_binder(binder, obj, out);

  149. }

  150. status_t flatten_binder(const sp& proc,

  151. const wp& binder, Parcel* out)

  152. {

  153. flat_binder_object obj;

  154. obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;

  155. if (binder != NULL) {

  156. sp real = binder.promote();

  157. if (real != NULL) {

  158. IBinder *local = real->localBinder();

  159. if (!local) {

  160. BpBinder *proxy = real->remoteBinder();

  161. if (proxy == NULL) {

  162. LOGE(“null proxy”);

  163. }

  164. const int32_t handle = proxy ? proxy->handle() : 0;

  165. obj.type = BINDER_TYPE_WEAK_HANDLE;

  166. obj.handle = handle;

  167. obj.cookie = NULL;

  168. } else {

  169. obj.type = BINDER_TYPE_WEAK_BINDER;

  170. obj.binder = binder.get_refs();

  171. obj.cookie = binder.unsafe_get();

  172. }

  173. return finish_flatten_binder(real, obj, out);

  174. }

  175. // XXX How to deal?  In order to flatten the given binder,

  176. // we need to probe it for information, which requires a primary

  177. // reference…  but we don’t have one.

  178. //

  179. // The OpenBinder implementation uses a dynamic_cast<> here,

  180. // but we can’t do that with the different reference counting

  181. // implementation we are using.

  182. LOGE(“Unable to unflatten Binder weak reference!”);

  183. obj.type = BINDER_TYPE_BINDER;

  184. obj.binder = NULL;

  185. obj.cookie = NULL;

  186. return finish_flatten_binder(NULL, obj, out);

  187. } else {

  188. obj.type = BINDER_TYPE_BINDER;

  189. obj.binder = NULL;

  190. obj.cookie = NULL;

  191. return finish_flatten_binder(NULL, obj, out);

  192. }

  193. }

  194. inline static status_t finish_unflatten_binder(

  195. BpBinder* proxy, const flat_binder_object& flat, const Parcel& in)

  196. {

  197. return NO_ERROR;

  198. }

  199. status_t unflatten_binder(const sp& proc,

  200. const Parcel& in, sp* out)

  201. {

  202. const flat_binder_object* flat = in.readObject(false);

  203. if (flat) {

  204. switch (flat->type) {

  205. case BINDER_TYPE_BINDER:

  206. *out = static_cast<IBinder*>(flat->cookie);

  207. return finish_unflatten_binder(NULL, *flat, in);

  208. case BINDER_TYPE_HANDLE:

  209. *out = proc->getStrongProxyForHandle(flat->handle);

  210. return finish_unflatten_binder(

  211. static_cast<BpBinder*>(out->get()), *flat, in);

  212. }

  213. }

  214. return BAD_TYPE;

  215. }

  216. status_t unflatten_binder(const sp& proc,

  217. const Parcel& in, wp* out)

  218. {

  219. const flat_binder_object* flat = in.readObject(false);

  220. if (flat) {

  221. switch (flat->type) {

  222. case BINDER_TYPE_BINDER:

  223. *out = static_cast<IBinder*>(flat->cookie);

  224. return finish_unflatten_binder(NULL, *flat, in);

  225. case BINDER_TYPE_WEAK_BINDER:

  226. if (flat->binder != NULL) {

  227. out->set_object_and_refs(

  228. static_cast<IBinder*>(flat->cookie),

  229. static_castRefBase::weakref\_type\*(flat->binder));

  230. } else {

  231. *out = NULL;

  232. }

  233. return finish_unflatten_binder(NULL, *flat, in);

  234. case BINDER_TYPE_HANDLE:

  235. case BINDER_TYPE_WEAK_HANDLE:

  236. *out = proc->getWeakProxyForHandle(flat->handle);

  237. return finish_unflatten_binder(

  238. static_cast<BpBinder*>(out->unsafe_get()), *flat, in);

  239. }

  240. }

  241. return BAD_TYPE;

  242. }

  243. // ---------------------------------------------------------------------------

  244. Parcel::Parcel()

  245. {

  246. initState();

  247. }

  248. Parcel::~Parcel()

  249. {

  250. freeDataNoInit();

  251. }

  252. const uint8_t* Parcel::data() const

  253. {

  254. return mData;

  255. }

  256. size_t Parcel::dataSize() const

  257. {

  258. return (mDataSize > mDataPos ? mDataSize : mDataPos);

  259. }

  260. size_t Parcel::dataAvail() const

  261. {

  262. // TODO: decide what to do about the possibility that this can

  263. // report an available-data size that exceeds a Java int’s max

  264. // positive value, causing havoc.  Fortunately this will only

  265. // happen if someone constructs a Parcel containing more than two

  266. // gigabytes of data, which on typical phone hardware is simply

  267. // not possible.

  268. return dataSize() - dataPosition();

  269. }

  270. size_t Parcel::dataPosition() const

  271. {

  272. return mDataPos;

  273. }

  274. size_t Parcel::dataCapacity() const

  275. {

  276. return mDataCapacity;

  277. }

  278. status_t Parcel::setDataSize(size_t size)

  279. {

  280. status_t err;

  281. err = continueWrite(size);

  282. if (err == NO_ERROR) {

  283. mDataSize = size;

  284. LOGV(“setDataSize Setting data size of %p to %d/n”, this, mDataSize);

  285. }

  286. return err;

  287. }

  288. void Parcel::setDataPosition(size_t pos) const

  289. {

  290. mDataPos = pos;

  291. mNextObjectHint = 0;

  292. }

  293. status_t Parcel::setDataCapacity(size_t size)

  294. {

  295. if (size > mDataSize) return continueWrite(size);

  296. return NO_ERROR;

  297. }

  298. status_t Parcel::setData(const uint8_t* buffer, size_t len)

  299. {

  300. status_t err = restartWrite(len);

  301. if (err == NO_ERROR) {

  302. memcpy(const_cast<uint8_t*>(data()), buffer, len);

  303. mDataSize = len;

  304. mFdsKnown = false;

  305. }

  306. return err;

  307. }

  308. status_t Parcel::appendFrom(Parcel *parcel, size_t offset, size_t len)

  309. {

  310. const sp proc(ProcessState::self());

  311. status_t err;

  312. uint8_t *data = parcel->mData;

  313. size_t *objects = parcel->mObjects;

  314. size_t size = parcel->mObjectsSize;

  315. int startPos = mDataPos;

  316. int firstIndex = -1, lastIndex = -2;

  317. if (len == 0) {

  318. return NO_ERROR;

  319. }

  320. // range checks against the source parcel size

  321. if ((offset > parcel->mDataSize)

  322. || (len > parcel->mDataSize)

  323. || (offset + len > parcel->mDataSize)) {

  324. return BAD_VALUE;

  325. }

  326. // Count objects in range

  327. for (int i = 0; i < (int) size; i++) {

  328. size_t off = objects[i];

  329. if ((off >= offset) && (off < offset + len)) {

  330. if (firstIndex == -1) {

  331. firstIndex = i;

  332. }

  333. lastIndex = i;

  334. }

  335. }

  336. int numObjects = lastIndex - firstIndex + 1;

  337. // grow data

  338. err = growData(len);

  339. if (err != NO_ERROR) {

  340. return err;

  341. }

  342. // append data

  343. memcpy(mData + mDataPos, data + offset, len);

  344. mDataPos += len;

  345. mDataSize += len;

  346. if (numObjects > 0) {

  347. // grow objects

  348. if (mObjectsCapacity < mObjectsSize + numObjects) {

  349. int newSize = ((mObjectsSize + numObjects)*3)/2;

  350. size_t *objects =

  351. (size_t*)realloc(mObjects, newSize*sizeof(size_t));

  352. if (objects == (size_t*)0) {

  353. return NO_MEMORY;

  354. }

  355. mObjects = objects;

  356. mObjectsCapacity = newSize;

  357. }

  358. // append and acquire objects

  359. int idx = mObjectsSize;

  360. for (int i = firstIndex; i <= lastIndex; i++) {

  361. size_t off = objects[i] - offset + startPos;

  362. mObjects[idx++] = off;

  363. mObjectsSize++;

  364. flat_binder_object* flat

  365. = reinterpret_cast<flat_binder_object*>(mData + off);

  366. acquire_object(proc, *flat, this);

  367. if (flat->type == BINDER_TYPE_FD) {

  368. // If this is a file descriptor, we need to dup it so the

  369. // new Parcel now owns its own fd, and can declare that we

  370. // officially know we have fds.

  371. flat->handle = dup(flat->handle);

  372. flat->cookie = (void*)1;

  373. mHasFds = mFdsKnown = true;

  374. }

  375. }

  376. }

  377. return NO_ERROR;

  378. }

  379. bool Parcel::hasFileDescriptors() const

  380. {

  381. if (!mFdsKnown) {

  382. scanForFds();

  383. }

  384. return mHasFds;

  385. }

  386. status_t Parcel::writeInterfaceToken(const String16& interface)

  387. {

  388. // currently the interface identification token is just its name as a string

  389. return writeString16(interface);

  390. }

  391. bool Parcel::checkInterface(IBinder* binder) const

  392. {

  393. return enforceInterface(binder->getInterfaceDescriptor());

  394. }

  395. bool Parcel::enforceInterface(const String16& interface) const

  396. {

  397. const String16 str(readString16());

  398. if (str == interface) {

  399. return true;

  400. } else {

  401. LOGW(“**** enforceInterface() expected ‘%s’ but read ‘%s’/n”,

  402. String8(interface).string(), String8(str).string());

  403. return false;

  404. }

  405. }

  406. const size_t* Parcel::objects() const

  407. {

  408. return mObjects;

  409. }

  410. size_t Parcel::objectsCount() const

  411. {

  412. return mObjectsSize;

  413. }

  414. status_t Parcel::errorCheck() const

  415. {

  416. return mError;

  417. }

  418. void Parcel::setError(status_t err)

  419. {

  420. mError = err;

  421. }

  422. status_t Parcel::finishWrite(size_t len)

  423. {

  424. //printf(“Finish write of %d/n”, len);

  425. mDataPos += len;

  426. LOGV(“finishWrite Setting data pos of %p to %d/n”, this, mDataPos);

  427. if (mDataPos > mDataSize) {

  428. mDataSize = mDataPos;

  429. LOGV(“finishWrite Setting data size of %p to %d/n”, this, mDataSize);

  430. }

  431. //printf(“New pos=%d, size=%d/n”, mDataPos, mDataSize);

  432. return NO_ERROR;

  433. }

  434. status_t Parcel::writeUnpadded(const void* data, size_t len)

  435. {

  436. size_t end = mDataPos + len;

  437. if (end < mDataPos) {

  438. // integer overflow

  439. return BAD_VALUE;

  440. }

  441. if (end <= mDataCapacity) {

  442. restart_write:

  443. memcpy(mData+mDataPos, data, len);

  444. return finishWrite(len);

  445. }

  446. status_t err = growData(len);

  447. if (err == NO_ERROR) goto restart_write;

  448. return err;

  449. }

  450. status_t Parcel::write(const void* data, size_t len)

  451. {

  452. void* const d = writeInplace(len);

  453. if (d) {

  454. memcpy(d, data, len);

  455. return NO_ERROR;

  456. }

  457. return mError;

  458. }

  459. void* Parcel::writeInplace(size_t len)

  460. {

  461. const size_t padded = PAD_SIZE(len);

  462. // sanity check for integer overflow

  463. if (mDataPos+padded < mDataPos) {

  464. return NULL;

  465. }

  466. if ((mDataPos+padded) <= mDataCapacity) {

  467. restart_write:

  468. //printf(“Writing %ld bytes, padded to %ld/n”, len, padded);

  469. uint8_t* const data = mData+mDataPos;

  470. // Need to pad at end?

  471. if (padded != len) {

  472. #if BYTE_ORDER == BIG_ENDIAN

  473. static const uint32_t mask[4] = {

  474. 0x00000000, 0xffffff00, 0xffff0000, 0xff000000

  475. };

  476. #endif

  477. #if BYTE_ORDER == LITTLE_ENDIAN

  478. static const uint32_t mask[4] = {

  479. 0x00000000, 0x00ffffff, 0x0000ffff, 0x000000ff

  480. };

  481. #endif

  482. //printf(“Applying pad mask: %p to %p/n”, (void*)mask[padded-len],

  483. //    *reinterpret_cast<void**>(data+padded-4));

  484. *reinterpret_cast<uint32_t*>(data+padded-4) &= mask[padded-len];

  485. }

  486. finishWrite(padded);

  487. return data;

  488. }

  489. status_t err = growData(padded);

  490. if (err == NO_ERROR) goto restart_write;

  491. return NULL;

  492. }

  493. status_t Parcel::writeInt32(int32_t val)

  494. {

  495. return writeAligned(val);

  496. }

  497. status_t Parcel::writeInt64(int64_t val)

  498. {

  499. return writeAligned(val);

  500. }

  501. status_t Parcel::writeFloat(float val)

  502. {

  503. return writeAligned(val);

  504. }

  505. status_t Parcel::writeDouble(double val)

  506. {

  507. return writeAligned(val);

  508. }

  509. status_t Parcel::writeIntPtr(intptr_t val)

  510. {

  511. return writeAligned(val);

  512. }

  513. status_t Parcel::writeCString(const char* str)

  514. {

  515. return write(str, strlen(str)+1);

  516. }

  517. status_t Parcel::writeString8(const String8& str)

  518. {

  519. status_t err = writeInt32(str.bytes());

  520. if (err == NO_ERROR) {

  521. err = write(str.string(), str.bytes()+1);

  522. }

  523. return err;

  524. }

  525. status_t Parcel::writeString16(const String16& str)

  526. {

  527. return writeString16(str.string(), str.size());

  528. }

  529. status_t Parcel::writeString16(const char16_t* str, size_t len)

  530. {

  531. if (str == NULL) return writeInt32(-1);

  532. status_t err = writeInt32(len);

  533. if (err == NO_ERROR) {

  534. len *= sizeof(char16_t);

  535. uint8_t* data = (uint8_t*)writeInplace(len+sizeof(char16_t));

  536. if (data) {

  537. memcpy(data, str, len);

  538. *reinterpret_cast<char16_t*>(data+len) = 0;

  539. return NO_ERROR;

  540. }

  541. err = mError;

  542. }

  543. return err;

  544. }

  545. status_t Parcel::writeStrongBinder(const sp& val)

  546. {

  547. return flatten_binder(ProcessState::self(), val, this);

  548. }

  549. status_t Parcel::writeWeakBinder(const wp& val)

  550. {

  551. return flatten_binder(ProcessState::self(), val, this);

  552. }

  553. status_t Parcel::writeNativeHandle(const native_handle* handle)

  554. {

  555. if (!handle || handle->version != sizeof(native_handle))

  556. return BAD_TYPE;

  557. status_t err;

  558. err = writeInt32(handle->numFds);

  559. if (err != NO_ERROR) return err;

  560. err = writeInt32(handle->numInts);

  561. if (err != NO_ERROR) return err;

  562. for (int i=0 ; err==NO_ERROR && inumFds ; i++)

  563. err = writeDupFileDescriptor(handle->data[i]);

  564. if (err != NO_ERROR) {

  565. LOGD(“write native handle, write dup fd failed”);

  566. return err;

  567. }

  568. err = write(handle->data + handle->numFds, sizeof(int)*handle->numInts);

  569. return err;

  570. }

  571. status_t Parcel::writeFileDescriptor(int fd)

  572. {

  573. flat_binder_object obj;

  574. obj.type = BINDER_TYPE_FD;

  575. obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;

  576. obj.handle = fd;

  577. obj.cookie = (void*)0;

  578. return writeObject(obj, true);

  579. }

  580. status_t Parcel::writeDupFileDescriptor(int fd)

  581. {

  582. flat_binder_object obj;

  583. obj.type = BINDER_TYPE_FD;

  584. obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;

  585. obj.handle = dup(fd);

  586. obj.cookie = (void*)1;

  587. return writeObject(obj, true);

  588. }

  589. status_t Parcel::write(const Flattenable& val)

  590. {

  591. status_t err;

  592. // size if needed

  593. size_t len = val.getFlattenedSize();

  594. size_t fd_count = val.getFdCount();

  595. err = this->writeInt32(len);

  596. if (err) return err;

  597. err = this->writeInt32(fd_count);

  598. if (err) return err;

  599. // payload

  600. void* buf = this->writeInplace(PAD_SIZE(len));

  601. if (buf == NULL)

  602. return BAD_VALUE;

  603. int* fds = NULL;

  604. if (fd_count) {

  605. fds = new int[fd_count];

  606. }

  607. err = val.flatten(buf, len, fds, fd_count);

  608. for (size_t i=0 ; i<fd_count && err==NO_ERROR ; i++) {

  609. err = this->writeDupFileDescriptor( fds[i] );

  610. }

  611. if (fd_count) {

  612. delete [] fds;

  613. }

  614. return err;

  615. }

  616. status_t Parcel::writeObject(const flat_binder_object& val, bool nullMetaData)

  617. {

  618. const bool enoughData = (mDataPos+sizeof(val)) <= mDataCapacity;

  619. const bool enoughObjects = mObjectsSize < mObjectsCapacity;

  620. if (enoughData && enoughObjects) {

  621. restart_write:

  622. *reinterpret_cast<flat_binder_object*>(mData+mDataPos) = val;

  623. // Need to write meta-data?

  624. if (nullMetaData || val.binder != NULL) {

  625. mObjects[mObjectsSize] = mDataPos;

  626. acquire_object(ProcessState::self(), val, this);

  627. mObjectsSize++;

  628. }

  629. // remember if it’s a file descriptor

  630. if (val.type == BINDER_TYPE_FD) {

  631. mHasFds = mFdsKnown = true;

  632. }

  633. return finishWrite(sizeof(flat_binder_object));

  634. }

  635. if (!enoughData) {

  636. const status_t err = growData(sizeof(val));

  637. if (err != NO_ERROR) return err;

  638. }

  639. if (!enoughObjects) {

  640. size_t newSize = ((mObjectsSize+2)*3)/2;

  641. size_t* objects = (size_t*)realloc(mObjects, newSize*sizeof(size_t));

  642. if (objects == NULL) return NO_MEMORY;

  643. mObjects = objects;

  644. mObjectsCapacity = newSize;

  645. }

  646. goto restart_write;

  647. }

  648. void Parcel::remove(size_t start, size_t amt)

  649. {

  650. LOG_ALWAYS_FATAL(“Parcel::remove() not yet implemented!”);

  651. }

  652. status_t Parcel::read(void* outData, size_t len) const

  653. {

  654. if ((mDataPos+PAD_SIZE(len)) >= mDataPos && (mDataPos+PAD_SIZE(len)) <= mDataSize) {

  655. memcpy(outData, mData+mDataPos, len);

  656. mDataPos += PAD_SIZE(len);

  657. LOGV(“read Setting data pos of %p to %d/n”, this, mDataPos);

  658. return NO_ERROR;

  659. }

  660. return NOT_ENOUGH_DATA;

  661. }

  662. const void* Parcel::readInplace(size_t len) const

  663. {

  664. if ((mDataPos+PAD_SIZE(len)) >= mDataPos && (mDataPos+PAD_SIZE(len)) <= mDataSize) {

  665. const void* data = mData+mDataPos;

  666. mDataPos += PAD_SIZE(len);

  667. LOGV(“readInplace Setting data pos of %p to %d/n”, this, mDataPos);

  668. return data;

  669. }

  670. return NULL;

  671. }

  672. template

  673. status_t Parcel::readAligned(T *pArg) const {

  674. COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE(sizeof(T)) == sizeof(T));

  675. if ((mDataPos+sizeof(T)) <= mDataSize) {

  676. const void* data = mData+mDataPos;

  677. mDataPos += sizeof(T);

  678. *pArg =  *reinterpret_cast<const T*>(data);

  679. return NO_ERROR;

  680. } else {

  681. return NOT_ENOUGH_DATA;

  682. }

  683. }

  684. template

  685. T Parcel::readAligned() const {

  686. T result;

  687. if (readAligned(&result) != NO_ERROR) {

  688. result = 0;

  689. }

  690. return result;

  691. }

  692. template

  693. status_t Parcel::writeAligned(T val) {

  694. COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE(sizeof(T)) == sizeof(T));

  695. if ((mDataPos+sizeof(val)) <= mDataCapacity) {

  696. restart_write:

  697. *reinterpret_cast<T*>(mData+mDataPos) = val;

  698. return finishWrite(sizeof(val));

  699. }

  700. status_t err = growData(sizeof(val));

  701. if (err == NO_ERROR) goto restart_write;

  702. return err;

  703. }

  704. status_t Parcel::readInt32(int32_t *pArg) const

  705. {

  706. return readAligned(pArg);

  707. }

  708. int32_t Parcel::readInt32() const

  709. {

  710. return readAligned<int32_t>();

  711. }

  712. status_t Parcel::readInt64(int64_t *pArg) const

  713. {

  714. return readAligned(pArg);

  715. }

  716. int64_t Parcel::readInt64() const

  717. {

  718. return readAligned<int64_t>();

  719. }

  720. status_t Parcel::readFloat(float *pArg) const

  721. {

  722. return readAligned(pArg);

  723. }

  724. float Parcel::readFloat() const

  725. {

  726. return readAligned<float>();

  727. }

  728. status_t Parcel::readDouble(double *pArg) const

  729. {

  730. return readAligned(pArg);

  731. }

  732. double Parcel::readDouble() const

  733. {

  734. return readAligned<double>();

  735. }

  736. status_t Parcel::readIntPtr(intptr_t *pArg) const

  737. {

  738. return readAligned(pArg);

  739. }

  740. intptr_t Parcel::readIntPtr() const

  741. {

  742. return readAligned<intptr_t>();

  743. }

  744. const char* Parcel::readCString() const

  745. {

  746. const size_t avail = mDataSize-mDataPos;

  747. if (avail > 0) {

  748. const char* str = reinterpret_cast<const char*>(mData+mDataPos);

  749. // is the string’s trailing NUL within the parcel’s valid bounds?

  750. const char* eos = reinterpret_cast<const char*>(memchr(str, 0, avail));

  751. if (eos) {

  752. const size_t len = eos - str;

  753. mDataPos += PAD_SIZE(len+1);

  754. LOGV(“readCString Setting data pos of %p to %d/n”, this, mDataPos);

  755. return str;

  756. }

  757. }

  758. return NULL;

  759. }

  760. String8 Parcel::readString8() const

  761. {

  762. int32_t size = readInt32();

  763. // watch for potential int overflow adding 1 for trailing NUL

  764. if (size > 0 && size < INT32_MAX) {

  765. const char* str = (const char*)readInplace(size+1);

  766. if (str) return String8(str, size);

  767. }

  768. return String8();

  769. }

  770. String16 Parcel::readString16() const

  771. {

  772. size_t len;

  773. const char16_t* str = readString16Inplace(&len);

  774. if (str) return String16(str, len);

  775. LOGE(“Reading a NULL string not supported here.”);

  776. return String16();

  777. }

  778. const char16_t* Parcel::readString16Inplace(size_t* outLen) const

  779. {

  780. int32_t size = readInt32();

  781. // watch for potential int overflow from size+1

  782. if (size >= 0 && size < INT32_MAX) {

  783. *outLen = size;

  784. const char16_t* str = (const char16_t*)readInplace((size+1)*sizeof(char16_t));

  785. if (str != NULL) {

  786. return str;

  787. }

  788. }

  789. *outLen = 0;

  790. return NULL;

  791. }

  792. sp Parcel::readStrongBinder() const

  793. {

  794. sp val;

  795. unflatten_binder(ProcessState::self(), *this, &val);

  796. return val;

  797. }

  798. wp Parcel::readWeakBinder() const

  799. {

  800. wp val;

  801. unflatten_binder(ProcessState::self(), *this, &val);

  802. return val;

  803. }

  804. native_handle* Parcel::readNativeHandle() const

  805. {

  806. int numFds, numInts;

  807. status_t err;

  808. err = readInt32(&numFds);

  809. if (err != NO_ERROR) return 0;

  810. err = readInt32(&numInts);

  811. if (err != NO_ERROR) return 0;

  812. native_handle* h = native_handle_create(numFds, numInts);

  813. for (int i=0 ; err==NO_ERROR && i<numFds ; i++) {

  814. h->data[i] = dup(readFileDescriptor());

  815. if (h->data[i] < 0) err = BAD_VALUE;

  816. }

  817. err = read(h->data + numFds, sizeof(int)*numInts);

  818. if (err != NO_ERROR) {

  819. native_handle_close(h);

  820. native_handle_delete(h);

  821. h = 0;

  822. }

  823. return h;

  824. }

  825. int Parcel::readFileDescriptor() const

  826. {

  827. const flat_binder_object* flat = readObject(true);

  828. if (flat) {

  829. switch (flat->type) {

  830. case BINDER_TYPE_FD:

  831. //LOGI(“Returning file descriptor %ld from parcel %p/n”, flat->handle, this);

  832. return flat->handle;

  833. }

  834. }

  835. return BAD_TYPE;

  836. }

  837. status_t Parcel::read(Flattenable& val) const

  838. {

  839. // size

  840. const size_t len = this->readInt32();

  841. const size_t fd_count = this->readInt32();

  842. // payload

  843. void const* buf = this->readInplace(PAD_SIZE(len));

  844. if (buf == NULL)

  845. return BAD_VALUE;

  846. int* fds = NULL;

  847. if (fd_count) {

  848. fds = new int[fd_count];

  849. }

  850. status_t err = NO_ERROR;

  851. for (size_t i=0 ; i<fd_count && err==NO_ERROR ; i++) {

  852. fds[i] = dup(this->readFileDescriptor());

  853. if (fds[i] < 0) err = BAD_VALUE;

  854. }

  855. if (err == NO_ERROR) {

  856. err = val.unflatten(buf, len, fds, fd_count);

  857. }

  858. if (fd_count) {

  859. delete [] fds;

  860. }

  861. return err;

  862. }

  863. const flat_binder_object* Parcel::readObject(bool nullMetaData) const

  864. {

  865. const size_t DPOS = mDataPos;

  866. if ((DPOS+sizeof(flat_binder_object)) <= mDataSize) {

  867. const flat_binder_object* obj

  868. = reinterpret_cast<const flat_binder_object*>(mData+DPOS);

  869. mDataPos = DPOS + sizeof(flat_binder_object);

  870. if (!nullMetaData && (obj->cookie == NULL && obj->binder == NULL)) {

  871. // When transferring a NULL object, we don’t write it into

  872. // the object list, so we don’t want to check for it when

  873. // reading.

  874. LOGV(“readObject Setting data pos of %p to %d/n”, this, mDataPos);

  875. return obj;

  876. }

  877. // Ensure that this object is valid…

  878. size_t* const OBJS = mObjects;

  879. const size_t N = mObjectsSize;

  880. size_t opos = mNextObjectHint;

  881. if (N > 0) {

  882. LOGV(“Parcel %p looking for obj at %d, hint=%d/n”,

  883. this, DPOS, opos);

  884. // Start at the current hint position, looking for an object at

  885. // the current data position.

  886. if (opos < N) {

  887. while (opos < (N-1) && OBJS[opos] < DPOS) {

  888. opos++;

  889. }

  890. } else {

  891. opos = N-1;

  892. }

  893. if (OBJS[opos] == DPOS) {

  894. // Found it!

  895. LOGV(“Parcel found obj %d at index %d with forward search”,

  896. this, DPOS, opos);

  897. mNextObjectHint = opos+1;

  898. LOGV(“readObject Setting data pos of %p to %d/n”, this, mDataPos);

  899. return obj;

  900. }

  901. // Look backwards for it…

  902. while (opos > 0 && OBJS[opos] > DPOS) {

  903. opos–;

  904. }

  905. if (OBJS[opos] == DPOS) {

  906. // Found it!

  907. LOGV(“Parcel found obj %d at index %d with backward search”,

  908. this, DPOS, opos);

  909. mNextObjectHint = opos+1;

  910. LOGV(“readObject Setting data pos of %p to %d/n”, this, mDataPos);

  911. return obj;

  912. }

  913. }

  914. LOGW(“Attempt to read object from Parcel %p at offset %d that is not in the object list”,

  915. this, DPOS);

  916. }

  917. return NULL;

  918. }

  919. void Parcel::closeFileDescriptors()

  920. {

  921. size_t i = mObjectsSize;

  922. if (i > 0) {

  923. //LOGI(“Closing file descriptors for %d objects…”, mObjectsSize);

  924. }

  925. while (i > 0) {

  926. i–;

  927. const flat_binder_object* flat

  928. = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);

  929. if (flat->type == BINDER_TYPE_FD) {

  930. //LOGI(“Closing fd: %ld/n”, flat->handle);

  931. close(flat->handle);

  932. }

  933. }

  934. }

  935. const uint8_t* Parcel::ipcData() const

  936. {

  937. return mData;

  938. }

  939. size_t Parcel::ipcDataSize() const

  940. {

  941. return (mDataSize > mDataPos ? mDataSize : mDataPos);

  942. }

  943. const size_t* Parcel::ipcObjects() const

  944. {

  945. return mObjects;

  946. }

  947. size_t Parcel::ipcObjectsCount() const

  948. {

  949. return mObjectsSize;

  950. }

  951. void Parcel::ipcSetDataReference(const uint8_t* data, size_t dataSize,

  952. const size_t* objects, size_t objectsCount, release_func relFunc, void* relCookie)

  953. {

  954. freeDataNoInit();

  955. mError = NO_ERROR;

  956. mData = const_cast<uint8_t*>(data);

  957. mDataSize = mDataCapacity = dataSize;

  958. //LOGI(“setDataReference Setting data size of %p to %lu (pid=%d)/n”, this, mDataSize, getpid());

  959. mDataPos = 0;

  960. LOGV(“setDataReference Setting data pos of %p to %d/n”, this, mDataPos);

  961. mObjects = const_cast<size_t*>(objects);

  962. mObjectsSize = mObjectsCapacity = objectsCount;

  963. mNextObjectHint = 0;

  964. mOwner = relFunc;

  965. mOwnerCookie = relCookie;

  966. scanForFds();

  967. }

最后

代码真的是重质不重量,质量高的代码,是当前代码界提倡的,当然写出高质量的代码肯定需要一个相当高的专业素养,这需要在日常的代码书写中逐渐去吸收掌握,谁不是每天都在学习呀,目的还不是为了一个,为实现某个功能写出高质量的代码。

所以,长征路还长,大家还是好好地做个务实的程序员吧。

最后,小编这里有一系列Android提升学习资料,有兴趣的小伙伴们可以来看下哦~

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

e;

  1. if (i > 0) {

  2. //LOGI(“Closing file descriptors for %d objects…”, mObjectsSize);

  3. }

  4. while (i > 0) {

  5. i–;

  6. const flat_binder_object* flat

  7. = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);

  8. if (flat->type == BINDER_TYPE_FD) {

  9. //LOGI(“Closing fd: %ld/n”, flat->handle);

  10. close(flat->handle);

  11. }

  12. }

  13. }

  14. const uint8_t* Parcel::ipcData() const

  15. {

  16. return mData;

  17. }

  18. size_t Parcel::ipcDataSize() const

  19. {

  20. return (mDataSize > mDataPos ? mDataSize : mDataPos);

  21. }

  22. const size_t* Parcel::ipcObjects() const

  23. {

  24. return mObjects;

  25. }

  26. size_t Parcel::ipcObjectsCount() const

  27. {

  28. return mObjectsSize;

  29. }

  30. void Parcel::ipcSetDataReference(const uint8_t* data, size_t dataSize,

  31. const size_t* objects, size_t objectsCount, release_func relFunc, void* relCookie)

  32. {

  33. freeDataNoInit();

  34. mError = NO_ERROR;

  35. mData = const_cast<uint8_t*>(data);

  36. mDataSize = mDataCapacity = dataSize;

  37. //LOGI(“setDataReference Setting data size of %p to %lu (pid=%d)/n”, this, mDataSize, getpid());

  38. mDataPos = 0;

  39. LOGV(“setDataReference Setting data pos of %p to %d/n”, this, mDataPos);

  40. mObjects = const_cast<size_t*>(objects);

  41. mObjectsSize = mObjectsCapacity = objectsCount;

  42. mNextObjectHint = 0;

  43. mOwner = relFunc;

  44. mOwnerCookie = relCookie;

  45. scanForFds();

  46. }

最后

代码真的是重质不重量,质量高的代码,是当前代码界提倡的,当然写出高质量的代码肯定需要一个相当高的专业素养,这需要在日常的代码书写中逐渐去吸收掌握,谁不是每天都在学习呀,目的还不是为了一个,为实现某个功能写出高质量的代码。

所以,长征路还长,大家还是好好地做个务实的程序员吧。

最后,小编这里有一系列Android提升学习资料,有兴趣的小伙伴们可以来看下哦~

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 21
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值