Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b23efff6 authored by Steven Moreland's avatar Steven Moreland Committed by Automerger Merge Worker
Browse files

Merge "servicemanager: vintf declared API" am: 8fd083ca am: a57fdf91 am: 212edd69

Original change: https://android-review.googlesource.com/c/platform/frameworks/native/+/1435031

Change-Id: I38817fafaf14a09b6a4f46b988a31ae98e159ecc
parents 664686b9 212edd69
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -55,6 +55,7 @@ class ServiceManagerMock : public IServiceManager {
    MOCK_METHOD1(listServices, Vector<String16>(int));
    MOCK_METHOD1(listServices, Vector<String16>(int));
    MOCK_METHOD1(waitForService, sp<IBinder>(const String16&));
    MOCK_METHOD1(waitForService, sp<IBinder>(const String16&));
    MOCK_METHOD1(isDeclared, bool(const String16&));
    MOCK_METHOD1(isDeclared, bool(const String16&));
    MOCK_METHOD1(getDeclaredInstances, Vector<String16>(const String16&));
  protected:
  protected:
    MOCK_METHOD0(onAsBinder, IBinder*());
    MOCK_METHOD0(onAsBinder, IBinder*());
};
};
+74 −19
Original line number Original line Diff line number Diff line
@@ -37,22 +37,12 @@ using ::android::internal::Stability;
namespace android {
namespace android {


#ifndef VENDORSERVICEMANAGER
#ifndef VENDORSERVICEMANAGER
static bool isVintfDeclared(const std::string& name) {
    size_t firstSlash = name.find('/');
    size_t lastDot = name.rfind('.', firstSlash);
    if (firstSlash == std::string::npos || lastDot == std::string::npos) {
        LOG(ERROR) << "VINTF HALs require names in the format type/instance (e.g. "
                   << "some.package.foo.IFoo/default) but got: " << name;
        return false;
    }
    const std::string package = name.substr(0, lastDot);
    const std::string iface = name.substr(lastDot+1, firstSlash-lastDot-1);
    const std::string instance = name.substr(firstSlash+1);

struct ManifestWithDescription {
struct ManifestWithDescription {
    std::shared_ptr<const vintf::HalManifest> manifest;
    std::shared_ptr<const vintf::HalManifest> manifest;
    const char* description;
    const char* description;
};
};
// func true -> stop search and forEachManifest will return true
static bool forEachManifest(const std::function<bool(const ManifestWithDescription&)>& func) {
    for (const ManifestWithDescription& mwd : {
    for (const ManifestWithDescription& mwd : {
            ManifestWithDescription{ vintf::VintfObject::GetDeviceHalManifest(), "device" },
            ManifestWithDescription{ vintf::VintfObject::GetDeviceHalManifest(), "device" },
            ManifestWithDescription{ vintf::VintfObject::GetFrameworkHalManifest(), "framework" },
            ManifestWithDescription{ vintf::VintfObject::GetFrameworkHalManifest(), "framework" },
@@ -63,17 +53,58 @@ static bool isVintfDeclared(const std::string& name) {
          // or other bugs (b/151696835)
          // or other bugs (b/151696835)
          continue;
          continue;
        }
        }
        if (func(mwd)) return true;
    }
    return false;
}

static bool isVintfDeclared(const std::string& name) {
    size_t firstSlash = name.find('/');
    size_t lastDot = name.rfind('.', firstSlash);
    if (firstSlash == std::string::npos || lastDot == std::string::npos) {
        LOG(ERROR) << "VINTF HALs require names in the format type/instance (e.g. "
                   << "some.package.foo.IFoo/default) but got: " << name;
        return false;
    }
    const std::string package = name.substr(0, lastDot);
    const std::string iface = name.substr(lastDot+1, firstSlash-lastDot-1);
    const std::string instance = name.substr(firstSlash+1);

    bool found = forEachManifest([&] (const ManifestWithDescription& mwd) {
        if (mwd.manifest->hasAidlInstance(package, iface, instance)) {
        if (mwd.manifest->hasAidlInstance(package, iface, instance)) {
            LOG(INFO) << "Found " << name << " in " << mwd.description << " VINTF manifest.";
            LOG(INFO) << "Found " << name << " in " << mwd.description << " VINTF manifest.";
            return true;
            return true;
        }
        }
    }
        return false;  // continue
    });


    if (!found) {
        // Although it is tested, explicitly rebuilding qualified name, in case it
        // Although it is tested, explicitly rebuilding qualified name, in case it
        // becomes something unexpected.
        // becomes something unexpected.
        LOG(ERROR) << "Could not find " << package << "." << iface << "/" << instance
        LOG(ERROR) << "Could not find " << package << "." << iface << "/" << instance
                   << " in the VINTF manifest.";
                   << " in the VINTF manifest.";
    return false;
    }

    return found;
}

static std::vector<std::string> getVintfInstances(const std::string& interface) {
    size_t lastDot = interface.rfind('.');
    if (lastDot == std::string::npos) {
        LOG(ERROR) << "VINTF interfaces require names in Java package format (e.g. some.package.foo.IFoo) but got: " << interface;
        return {};
    }
    const std::string package = interface.substr(0, lastDot);
    const std::string iface = interface.substr(lastDot+1);

    std::vector<std::string> ret;
    (void)forEachManifest([&](const ManifestWithDescription& mwd) {
        auto instances = mwd.manifest->getAidlInstances(package, iface);
        ret.insert(ret.end(), instances.begin(), instances.end());
        return false;  // continue
    });

    return ret;
}
}


static bool meetsDeclarationRequirements(const sp<IBinder>& binder, const std::string& name) {
static bool meetsDeclarationRequirements(const sp<IBinder>& binder, const std::string& name) {
@@ -331,6 +362,30 @@ Status ServiceManager::isDeclared(const std::string& name, bool* outReturn) {
    return Status::ok();
    return Status::ok();
}
}


binder::Status ServiceManager::getDeclaredInstances(const std::string& interface, std::vector<std::string>* outReturn) {
    auto ctx = mAccess->getCallingContext();

    std::vector<std::string> allInstances;
#ifndef VENDORSERVICEMANAGER
    allInstances = getVintfInstances(interface);
#endif

    outReturn->clear();

    for (const std::string& instance : allInstances) {
        // TODO(b/169275998): allow checking policy only once for the interface
        if (mAccess->canFind(ctx, interface + "/" + instance)) {
            outReturn->push_back(instance);
        }
    }

    if (outReturn->size() == 0 && allInstances.size() != 0) {
        return Status::fromExceptionCode(Status::EX_SECURITY);
    }

    return Status::ok();
}

void ServiceManager::removeRegistrationCallback(const wp<IBinder>& who,
void ServiceManager::removeRegistrationCallback(const wp<IBinder>& who,
                                    ServiceCallbackMap::iterator* it,
                                    ServiceCallbackMap::iterator* it,
                                    bool* found) {
                                    bool* found) {
+1 −0
Original line number Original line Diff line number Diff line
@@ -44,6 +44,7 @@ public:
                                              const sp<IServiceCallback>& callback) override;
                                              const sp<IServiceCallback>& callback) override;


    binder::Status isDeclared(const std::string& name, bool* outReturn) override;
    binder::Status isDeclared(const std::string& name, bool* outReturn) override;
    binder::Status getDeclaredInstances(const std::string& interface, std::vector<std::string>* outReturn) override;
    binder::Status registerClientCallback(const std::string& name, const sp<IBinder>& service,
    binder::Status registerClientCallback(const std::string& name, const sp<IBinder>& service,
                                          const sp<IClientCallback>& cb) override;
                                          const sp<IClientCallback>& cb) override;
    binder::Status tryUnregisterService(const std::string& name, const sp<IBinder>& binder) override;
    binder::Status tryUnregisterService(const std::string& name, const sp<IBinder>& binder) override;
+15 −0
Original line number Original line Diff line number Diff line
@@ -74,6 +74,7 @@ public:
    Vector<String16> listServices(int dumpsysPriority) override;
    Vector<String16> listServices(int dumpsysPriority) override;
    sp<IBinder> waitForService(const String16& name16) override;
    sp<IBinder> waitForService(const String16& name16) override;
    bool isDeclared(const String16& name) override;
    bool isDeclared(const String16& name) override;
    Vector<String16> getDeclaredInstances(const String16& interface) override;


    // for legacy ABI
    // for legacy ABI
    const String16& getInterfaceDescriptor() const override {
    const String16& getInterfaceDescriptor() const override {
@@ -373,4 +374,18 @@ bool ServiceManagerShim::isDeclared(const String16& name) {
    return declared;
    return declared;
}
}


Vector<String16> ServiceManagerShim::getDeclaredInstances(const String16& interface) {
    std::vector<std::string> out;
    if (!mTheRealServiceManager->getDeclaredInstances(String8(interface).c_str(), &out).isOk()) {
        return {};
    }

    Vector<String16> res;
    res.setCapacity(out.size());
    for (const std::string& instance : out) {
        res.push(String16(instance.c_str()));
    }
    return res;
}

} // namespace android
} // namespace android
+8 −0
Original line number Original line Diff line number Diff line
@@ -98,6 +98,14 @@ interface IServiceManager {
     */
     */
    boolean isDeclared(@utf8InCpp String name);
    boolean isDeclared(@utf8InCpp String name);


    /**
     * Returns all declared instances for a particular interface.
     *
     * For instance, if 'android.foo.IFoo/foo' is declared, and 'android.foo.IFoo' is
     * passed here, then ["foo"] would be returned.
     */
    @utf8InCpp String[] getDeclaredInstances(@utf8InCpp String iface);

    /**
    /**
     * Request a callback when the number of clients of the service changes.
     * Request a callback when the number of clients of the service changes.
     * Used by LazyServiceRegistrar to dynamically stop services that have no clients.
     * Used by LazyServiceRegistrar to dynamically stop services that have no clients.
Loading