blob: 339c53833bf9af77c77dab72d39817fe5d69e0dc [file] [log] [blame]
Steven Morelanddea3cf92019-07-16 18:06:55 -07001/*
2 * Copyright (C) 2019 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 */
Steven Moreland89ddfc52020-11-13 02:39:26 +000016#define LOG_TAG "Stability"
17
Steven Morelanddea3cf92019-07-16 18:06:55 -070018#include <binder/Stability.h>
19
Steven Morelanda7fb0182020-02-26 16:02:08 -080020#include <binder/BpBinder.h>
21#include <binder/Binder.h>
22
Steven Morelanddea3cf92019-07-16 18:06:55 -070023namespace android {
24namespace internal {
25
Steven Moreland89ddfc52020-11-13 02:39:26 +000026// the libbinder parcel format is currently unstable
27
28// oldest version which is supported
29constexpr uint8_t kBinderWireFormatOldest = 1;
30// current version
31constexpr uint8_t kBinderWireFormatVersion = 1;
32
33Stability::Category Stability::Category::currentFromLevel(Level level) {
34 return {
35 .version = kBinderWireFormatVersion,
36 .reserved = {0},
37 .level = level,
38 };
39}
40
41std::string Stability::Category::debugString() {
42 return levelString(level) + " wire protocol version "
43 + std::to_string(version);
44}
45
Steven Morelanddea3cf92019-07-16 18:06:55 -070046void Stability::markCompilationUnit(IBinder* binder) {
Steven Moreland89ddfc52020-11-13 02:39:26 +000047 auto stability = Category::currentFromLevel(getLocalLevel());
48 status_t result = setRepr(binder, stability.repr(), true /*log*/);
Steven Morelanddea3cf92019-07-16 18:06:55 -070049 LOG_ALWAYS_FATAL_IF(result != OK, "Should only mark known object.");
50}
51
52void Stability::markVintf(IBinder* binder) {
Steven Moreland89ddfc52020-11-13 02:39:26 +000053 auto stability = Category::currentFromLevel(Level::VINTF);
54 status_t result = setRepr(binder, stability.repr(), true /*log*/);
Steven Morelanddea3cf92019-07-16 18:06:55 -070055 LOG_ALWAYS_FATAL_IF(result != OK, "Should only mark known object.");
56}
57
Steven Moreland64ae9172019-08-02 20:45:15 -070058void Stability::debugLogStability(const std::string& tag, const sp<IBinder>& binder) {
Steven Moreland89ddfc52020-11-13 02:39:26 +000059 auto stability = getCategory(binder.get());
60 ALOGE("%s: stability is %s", tag.c_str(), stability.debugString().c_str());
Steven Moreland64ae9172019-08-02 20:45:15 -070061}
62
Steven Morelandc709dd82019-08-05 20:30:14 -070063void Stability::markVndk(IBinder* binder) {
Steven Moreland89ddfc52020-11-13 02:39:26 +000064 auto stability = Category::currentFromLevel(Level::VENDOR);
65 status_t result = setRepr(binder, stability.repr(), true /*log*/);
Steven Morelandc709dd82019-08-05 20:30:14 -070066 LOG_ALWAYS_FATAL_IF(result != OK, "Should only mark known object.");
67}
68
Steven Moreland86a17f82019-09-10 10:18:00 -070069bool Stability::requiresVintfDeclaration(const sp<IBinder>& binder) {
Steven Moreland89ddfc52020-11-13 02:39:26 +000070 return check(getCategory(binder.get()), Level::VINTF);
Steven Moreland86a17f82019-09-10 10:18:00 -070071}
72
Steven Moreland2a9f32f2019-07-31 17:51:25 -070073void Stability::tryMarkCompilationUnit(IBinder* binder) {
Steven Moreland89ddfc52020-11-13 02:39:26 +000074 auto stability = Category::currentFromLevel(getLocalLevel());
75 (void) setRepr(binder, stability.repr(), false /*log*/);
Steven Moreland2f2c4e02020-07-28 18:11:21 +000076}
77
Steven Moreland89ddfc52020-11-13 02:39:26 +000078Stability::Level Stability::getLocalLevel() {
Steven Moreland2f2c4e02020-07-28 18:11:21 +000079#ifdef __ANDROID_VNDK__
Steven Moreland15b70292021-02-18 19:10:15 +000080 #ifdef __ANDROID_APEX__
81 // TODO(b/142684679) avoid use_vendor on system APEXes
82 #if !defined(__ANDROID_APEX_COM_ANDROID_MEDIA_SWCODEC__) \
83 && !defined(__ANDROID_APEX_TEST_COM_ANDROID_MEDIA_SWCODEC__)
84 #error VNDK + APEX only defined for com.android.media.swcodec
85 #endif
86 // TODO(b/142684679) avoid use_vendor on system APEXes
87 return Level::SYSTEM;
88 #else
89 return Level::VENDOR;
90 #endif
Steven Moreland2f2c4e02020-07-28 18:11:21 +000091#else
92 // TODO(b/139325195): split up stability levels for system/APEX.
93 return Level::SYSTEM;
94#endif
Steven Moreland2a9f32f2019-07-31 17:51:25 -070095}
96
Steven Moreland89ddfc52020-11-13 02:39:26 +000097status_t Stability::setRepr(IBinder* binder, int32_t representation, bool log) {
98 auto current = getCategory(binder);
99 auto setting = Category::fromRepr(representation);
100
101 // If we have ahold of a binder with a newer declared version, then it
102 // should support older versions, and we will simply write our parcels with
103 // the current wire parcel format.
104 if (setting.version < kBinderWireFormatOldest) {
105 // always log, because this shouldn't happen
106 ALOGE("Cannot accept binder with older binder wire protocol version "
107 "%u. Versions less than %u are unsupported.", setting.version,
108 kBinderWireFormatOldest);
109 return BAD_TYPE;
110 }
Steven Morelanddea3cf92019-07-16 18:06:55 -0700111
112 // null binder is always written w/ 'UNDECLARED' stability
113 if (binder == nullptr) {
Steven Moreland89ddfc52020-11-13 02:39:26 +0000114 if (setting.level == UNDECLARED) {
Steven Morelanddea3cf92019-07-16 18:06:55 -0700115 return OK;
116 } else {
Steven Moreland2a9f32f2019-07-31 17:51:25 -0700117 if (log) {
118 ALOGE("Null binder written with stability %s.",
Steven Moreland89ddfc52020-11-13 02:39:26 +0000119 levelString(setting.level).c_str());
Steven Moreland2a9f32f2019-07-31 17:51:25 -0700120 }
Steven Morelanddea3cf92019-07-16 18:06:55 -0700121 return BAD_TYPE;
122 }
123 }
124
Steven Moreland89ddfc52020-11-13 02:39:26 +0000125 if (!isDeclaredLevel(setting.level)) {
Steven Moreland2a9f32f2019-07-31 17:51:25 -0700126 if (log) {
Steven Moreland89ddfc52020-11-13 02:39:26 +0000127 ALOGE("Can only set known stability, not %u.", setting.level);
Steven Morelanddea3cf92019-07-16 18:06:55 -0700128 }
Steven Moreland2a9f32f2019-07-31 17:51:25 -0700129 return BAD_TYPE;
Steven Morelanddea3cf92019-07-16 18:06:55 -0700130 }
131
Steven Moreland89ddfc52020-11-13 02:39:26 +0000132 if (current.repr() != 0 && current != setting) {
Steven Moreland2a9f32f2019-07-31 17:51:25 -0700133 if (log) {
Steven Moreland89ddfc52020-11-13 02:39:26 +0000134 ALOGE("Interface being set with %s but it is already marked as %s",
135 setting.debugString().c_str(),
136 current.debugString().c_str());
Steven Moreland2a9f32f2019-07-31 17:51:25 -0700137 }
Steven Morelanddea3cf92019-07-16 18:06:55 -0700138 return BAD_TYPE;
139 }
140
Steven Moreland89ddfc52020-11-13 02:39:26 +0000141 if (current == setting) return OK;
Steven Morelanddea3cf92019-07-16 18:06:55 -0700142
Steven Morelanda7fb0182020-02-26 16:02:08 -0800143 BBinder* local = binder->localBinder();
144 if (local != nullptr) {
Steven Moreland89ddfc52020-11-13 02:39:26 +0000145 local->mStability = setting.repr();
Steven Morelanda7fb0182020-02-26 16:02:08 -0800146 } else {
Steven Moreland89ddfc52020-11-13 02:39:26 +0000147 binder->remoteBinder()->mStability = setting.repr();
Steven Morelanda7fb0182020-02-26 16:02:08 -0800148 }
Steven Morelanddea3cf92019-07-16 18:06:55 -0700149
150 return OK;
151}
152
Steven Moreland89ddfc52020-11-13 02:39:26 +0000153Stability::Category Stability::getCategory(IBinder* binder) {
154 if (binder == nullptr) {
155 return Category::currentFromLevel(Level::UNDECLARED);
156 }
Steven Morelanddea3cf92019-07-16 18:06:55 -0700157
Steven Morelanda7fb0182020-02-26 16:02:08 -0800158 BBinder* local = binder->localBinder();
159 if (local != nullptr) {
Steven Moreland89ddfc52020-11-13 02:39:26 +0000160 return Category::fromRepr(local->mStability);
Steven Morelanda7fb0182020-02-26 16:02:08 -0800161 }
162
Steven Moreland89ddfc52020-11-13 02:39:26 +0000163 return Category::fromRepr(binder->remoteBinder()->mStability);
Steven Morelanddea3cf92019-07-16 18:06:55 -0700164}
165
Steven Moreland89ddfc52020-11-13 02:39:26 +0000166bool Stability::check(Category provided, Level required) {
167 bool stable = (provided.level & required) == required;
Steven Morelanddea3cf92019-07-16 18:06:55 -0700168
Steven Moreland89ddfc52020-11-13 02:39:26 +0000169 if (provided.level != UNDECLARED && !isDeclaredLevel(provided.level)) {
170 ALOGE("Unknown stability when checking interface stability %d.",
171 provided.level);
Steven Morelanddea3cf92019-07-16 18:06:55 -0700172
173 stable = false;
174 }
175
Steven Morelanddea3cf92019-07-16 18:06:55 -0700176 return stable;
177}
178
Steven Moreland89ddfc52020-11-13 02:39:26 +0000179bool Stability::isDeclaredLevel(Level stability) {
Steven Morelanddea3cf92019-07-16 18:06:55 -0700180 return stability == VENDOR || stability == SYSTEM || stability == VINTF;
181}
182
Steven Moreland89ddfc52020-11-13 02:39:26 +0000183std::string Stability::levelString(Level level) {
184 switch (level) {
Steven Morelanddea3cf92019-07-16 18:06:55 -0700185 case Level::UNDECLARED: return "undeclared stability";
186 case Level::VENDOR: return "vendor stability";
187 case Level::SYSTEM: return "system stability";
188 case Level::VINTF: return "vintf stability";
189 }
Steven Moreland89ddfc52020-11-13 02:39:26 +0000190 return "unknown stability " + std::to_string(level);
Steven Morelanddea3cf92019-07-16 18:06:55 -0700191}
192
193} // namespace internal
Steven Moreland86a17f82019-09-10 10:18:00 -0700194} // namespace stability