/* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include namespace android { namespace internal { void Stability::markCompilationUnit(IBinder* binder) { status_t result = set(binder, getLocalStability(), true /*log*/); LOG_ALWAYS_FATAL_IF(result != OK, "Should only mark known object."); } void Stability::markVintf(IBinder* binder) { status_t result = set(binder, Level::VINTF, true /*log*/); LOG_ALWAYS_FATAL_IF(result != OK, "Should only mark known object."); } void Stability::debugLogStability(const std::string& tag, const sp& binder) { ALOGE("%s: stability is %s", tag.c_str(), stabilityString(get(binder.get())).c_str()); } void Stability::markVndk(IBinder* binder) { status_t result = set(binder, Level::VENDOR, true /*log*/); LOG_ALWAYS_FATAL_IF(result != OK, "Should only mark known object."); } bool Stability::requiresVintfDeclaration(const sp& binder) { return check(get(binder.get()), Level::VINTF); } void Stability::tryMarkCompilationUnit(IBinder* binder) { (void) set(binder, getLocalStability(), false /*log*/); } Stability::Level Stability::getLocalStability() { #ifdef __ANDROID_VNDK__ #ifdef __ANDROID_APEX__ // TODO(b/142684679) avoid use_vendor on system APEXes #if !defined(__ANDROID_APEX_COM_ANDROID_MEDIA_SWCODEC__) \ && !defined(__ANDROID_APEX_TEST_COM_ANDROID_MEDIA_SWCODEC__) #error VNDK + APEX only defined for com.android.media.swcodec #endif // TODO(b/142684679) avoid use_vendor on system APEXes return Level::SYSTEM; #else return Level::VENDOR; #endif #else // TODO(b/139325195): split up stability levels for system/APEX. return Level::SYSTEM; #endif } status_t Stability::set(IBinder* binder, int32_t stability, bool log) { Level currentStability = get(binder); // null binder is always written w/ 'UNDECLARED' stability if (binder == nullptr) { if (stability == UNDECLARED) { return OK; } else { if (log) { ALOGE("Null binder written with stability %s.", stabilityString(stability).c_str()); } return BAD_TYPE; } } if (!isDeclaredStability(stability)) { if (log) { ALOGE("Can only set known stability, not %d.", stability); } return BAD_TYPE; } if (currentStability != Level::UNDECLARED && currentStability != stability) { if (log) { ALOGE("Interface being set with %s but it is already marked as %s.", stabilityString(stability).c_str(), stabilityString(currentStability).c_str()); } return BAD_TYPE; } if (currentStability == stability) return OK; BBinder* local = binder->localBinder(); if (local != nullptr) { local->mStability = static_cast(stability); } else { binder->remoteBinder()->mStability = static_cast(stability); } return OK; } Stability::Level Stability::get(IBinder* binder) { if (binder == nullptr) return UNDECLARED; BBinder* local = binder->localBinder(); if (local != nullptr) { return static_cast(local->mStability); } return static_cast(binder->remoteBinder()->mStability); } bool Stability::check(int32_t provided, Level required) { bool stable = (provided & required) == required; if (!isDeclaredStability(provided) && provided != UNDECLARED) { ALOGE("Unknown stability when checking interface stability %d.", provided); stable = false; } return stable; } bool Stability::isDeclaredStability(int32_t stability) { return stability == VENDOR || stability == SYSTEM || stability == VINTF; } std::string Stability::stabilityString(int32_t stability) { switch (stability) { case Level::UNDECLARED: return "undeclared stability"; case Level::VENDOR: return "vendor stability"; case Level::SYSTEM: return "system stability"; case Level::VINTF: return "vintf stability"; } return "unknown stability " + std::to_string(stability); } } // namespace internal } // namespace stability