• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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  */
16 #define LOG_TAG "Stability"
17 
18 #include <binder/Stability.h>
19 
20 #include <binder/BpBinder.h>
21 #include <binder/Binder.h>
22 
23 namespace android {
24 namespace internal {
25 
forceDowngradeToStability(const sp<IBinder> & binder,Level level)26 void Stability::forceDowngradeToStability(const sp<IBinder>& binder, Level level) {
27     // Downgrading a remote binder would require also copying the version from
28     // the binder sent here. In practice though, we don't need to downgrade the
29     // stability of a remote binder, since this would as an effect only restrict
30     // what we can do to it.
31     LOG_ALWAYS_FATAL_IF(!binder || !binder->localBinder(), "Can only downgrade local binder");
32 
33     status_t result = setRepr(binder.get(), level, REPR_LOG | REPR_ALLOW_DOWNGRADE);
34     LOG_ALWAYS_FATAL_IF(result != OK, "Should only mark known object.");
35 }
36 
forceDowngradeToLocalStability(const sp<IBinder> & binder)37 void Stability::forceDowngradeToLocalStability(const sp<IBinder>& binder) {
38     forceDowngradeToStability(binder, getLocalLevel());
39 }
40 
forceDowngradeToSystemStability(const sp<IBinder> & binder)41 void Stability::forceDowngradeToSystemStability(const sp<IBinder>& binder) {
42     forceDowngradeToStability(binder, Level::SYSTEM);
43 }
44 
forceDowngradeToVendorStability(const sp<IBinder> & binder)45 void Stability::forceDowngradeToVendorStability(const sp<IBinder>& binder) {
46     forceDowngradeToStability(binder, Level::VENDOR);
47 }
48 
markCompilationUnit(IBinder * binder)49 void Stability::markCompilationUnit(IBinder* binder) {
50     status_t result = setRepr(binder, getLocalLevel(), REPR_LOG);
51     LOG_ALWAYS_FATAL_IF(result != OK, "Should only mark known object.");
52 }
53 
markVintf(IBinder * binder)54 void Stability::markVintf(IBinder* binder) {
55     status_t result = setRepr(binder, Level::VINTF, REPR_LOG);
56     LOG_ALWAYS_FATAL_IF(result != OK, "Should only mark known object.");
57 }
58 
debugToString(const sp<IBinder> & binder)59 std::string Stability::debugToString(const sp<IBinder>& binder) {
60     return levelString(getRepr(binder.get()));
61 }
62 
markVndk(IBinder * binder)63 void Stability::markVndk(IBinder* binder) {
64     status_t result = setRepr(binder, Level::VENDOR, REPR_LOG);
65     LOG_ALWAYS_FATAL_IF(result != OK, "Should only mark known object.");
66 }
67 
requiresVintfDeclaration(const sp<IBinder> & binder)68 bool Stability::requiresVintfDeclaration(const sp<IBinder>& binder) {
69     return check(getRepr(binder.get()), Level::VINTF);
70 }
71 
tryMarkCompilationUnit(IBinder * binder)72 void Stability::tryMarkCompilationUnit(IBinder* binder) {
73     (void)setRepr(binder, getLocalLevel(), REPR_NONE);
74 }
75 
getLocalLevel()76 Stability::Level Stability::getLocalLevel() {
77 #ifdef __ANDROID_APEX__
78 #error APEX can't use libbinder (must use libbinder_ndk)
79 #endif
80 
81 #ifdef __ANDROID_VNDK__
82     return Level::VENDOR;
83 #else
84     // TODO(b/139325195): split up stability levels for system/APEX.
85     return Level::SYSTEM;
86 #endif
87 }
88 
89 status_t Stability::setRepr(IBinder* binder, int32_t setting, uint32_t flags) {
90     bool log = flags & REPR_LOG;
91     bool allowDowngrade = flags & REPR_ALLOW_DOWNGRADE;
92 
93     int16_t current = getRepr(binder);
94 
95     // null binder is always written w/ 'UNDECLARED' stability
96     if (binder == nullptr) {
97         if (setting == UNDECLARED) {
98             return OK;
99         } else {
100             if (log) {
101                 ALOGE("Null binder written with stability %s.", levelString(setting).c_str());
102             }
103             return BAD_TYPE;
104         }
105     }
106 
107     if (!isDeclaredLevel(setting)) {
108         if (log) {
109             ALOGE("Can only set known stability, not %d.", setting);
110         }
111         return BAD_TYPE;
112     }
113     Level levelSetting = static_cast<Level>(setting);
114 
115     if (current == setting) return OK;
116 
117     bool hasAlreadyBeenSet = current != Level::UNDECLARED;
118     bool isAllowedDowngrade = allowDowngrade && check(current, levelSetting);
119     if (hasAlreadyBeenSet && !isAllowedDowngrade) {
120         if (log) {
121             ALOGE("Interface being set with %s but it is already marked as %s",
122                   levelString(setting).c_str(), levelString(current).c_str());
123         }
124         return BAD_TYPE;
125     }
126 
127     if (isAllowedDowngrade) {
128         ALOGI("Interface set with %s downgraded to %s stability", levelString(current).c_str(),
129               levelString(setting).c_str());
130     }
131 
132     BBinder* local = binder->localBinder();
133     if (local != nullptr) {
134         local->mStability = setting;
135     } else {
136         binder->remoteBinder()->mStability = setting;
137     }
138 
139     return OK;
140 }
141 
142 int16_t Stability::getRepr(IBinder* binder) {
143     if (binder == nullptr) {
144         return Level::UNDECLARED;
145     }
146 
147     BBinder* local = binder->localBinder();
148     if (local != nullptr) {
149         return local->mStability;
150     }
151 
152     return binder->remoteBinder()->mStability;
153 }
154 
155 bool Stability::check(int16_t provided, Level required) {
156     bool stable = (provided & required) == required;
157 
158     if (provided != UNDECLARED && !isDeclaredLevel(provided)) {
159         ALOGE("Unknown stability when checking interface stability %d.", provided);
160 
161         stable = false;
162     }
163 
164     return stable;
165 }
166 
167 bool Stability::isDeclaredLevel(int32_t stability) {
168     return stability == VENDOR || stability == SYSTEM || stability == VINTF;
169 }
170 
171 std::string Stability::levelString(int32_t level) {
172     switch (level) {
173         case Level::UNDECLARED: return "undeclared stability";
174         case Level::VENDOR: return "vendor stability";
175         case Level::SYSTEM: return "system stability";
176         case Level::VINTF: return "vintf stability";
177     }
178     return "unknown stability " + std::to_string(level);
179 }
180 
181 }  // namespace internal
182 }  // namespace stability
183