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

Commit dc77bdf2 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Add simple fake for native service manager."

parents fde69639 c9ee3304
Loading
Loading
Loading
Loading
+25 −0
Original line number Diff line number Diff line
cc_defaults {
    name: "fakeservicemanager_defaults",
    srcs: [
        "ServiceManager.cpp",
    ],

    shared_libs: [
        "libbinder",
        "libutils",
    ],
}

cc_library {
    name: "libfakeservicemanager",
    defaults: ["fakeservicemanager_defaults"],
}

cc_test_host {
    name: "fakeservicemanager_test",
    defaults: ["fakeservicemanager_defaults"],
    srcs: [
        "test_sm.cpp",
    ],
    static_libs: ["libgmock"],
}
+64 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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 "ServiceManager.h"

namespace android {

ServiceManager::ServiceManager() {}

sp<IBinder> ServiceManager::getService( const String16& name) const {
    // Servicemanager is single-threaded and cannot block. This method exists for legacy reasons.
    return checkService(name);
}

sp<IBinder> ServiceManager::checkService( const String16& name) const {
    auto it = mNameToService.find(name);
    if (it == mNameToService.end()) {
        return nullptr;
    }
    return it->second;
}

status_t ServiceManager::addService(const String16& name, const sp<IBinder>& service,
                                bool /*allowIsolated*/,
                                int /*dumpsysFlags*/) {
    mNameToService[name] = service;
    return NO_ERROR;
}

Vector<String16> ServiceManager::listServices(int /*dumpsysFlags*/) {
    Vector<String16> services;
    for (auto const& [name, service] : mNameToService) {
        (void) service;
         services.push_back(name);
    }
  return services;
}

IBinder* ServiceManager::onAsBinder() {
    return nullptr;
}

sp<IBinder> ServiceManager::waitForService(const String16& name) {
    return checkService(name);
}

bool ServiceManager::isDeclared(const String16& name) {
    return mNameToService.find(name) != mNameToService.end();
}

}  // namespace android
+74 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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.
 */

#pragma once

#include <binder/IServiceManager.h>

#include <map>

namespace android {

/**
 * A local host simple implementation of IServiceManager, that does not
 * communicate over binder.
*/
class ServiceManager : public IServiceManager {
public:
    ServiceManager();

    /**
     * Equivalent of checkService.
     */
    sp<IBinder> getService( const String16& name) const override;

    /**
     * Retrieve an existing service, non-blocking.
     */
    sp<IBinder> checkService( const String16& name) const override;

    /**
     * Register a service.
     */
    status_t addService(const String16& name, const sp<IBinder>& service,
                        bool allowIsolated = false,
                        int dumpsysFlags = DUMP_FLAG_PRIORITY_DEFAULT) override;

    /**
     * Return list of all existing services.
     */
    Vector<String16> listServices(int dumpsysFlags = 0) override;

    IBinder* onAsBinder() override;

    /**
     * Effectively no-oped in this implementation - equivalent to checkService.
     */
    sp<IBinder> waitForService(const String16& name) override;

    /**
     * Check if a service is declared (e.g. VINTF manifest).
     *
     * If this returns true, waitForService should always be able to return the
     * service.
     */
     bool isDeclared(const String16& name) override;

private:
    std::map<String16, sp<IBinder>> mNameToService;
};

}  // namespace android
+126 −0
Original line number Diff line number Diff line
/*
 * 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 <gtest/gtest.h>
#include <gmock/gmock.h>

#include <binder/Binder.h>
#include <binder/ProcessState.h>
#include <binder/IServiceManager.h>

#include "ServiceManager.h"

using android::sp;
using android::BBinder;
using android::IBinder;
using android::OK;
using android::status_t;
using android::ServiceManager;
using android::String16;
using android::IServiceManager;
using testing::ElementsAre;

static sp<IBinder> getBinder() {
    class LinkableBinder : public BBinder {
        status_t linkToDeath(const sp<DeathRecipient>&, void*, uint32_t) override {
            // let SM linkToDeath
            return OK;
        }
    };

    return new LinkableBinder;
}

TEST(AddService, HappyHappy) {
    auto sm = new ServiceManager();
    EXPECT_EQ(sm->addService(String16("foo"), getBinder(), false /*allowIsolated*/,
        IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT), OK);
}

TEST(AddService, HappyOverExistingService) {
    auto sm = new ServiceManager();
    EXPECT_EQ(sm->addService(String16("foo"), getBinder(), false /*allowIsolated*/,
        IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT), OK);
    EXPECT_EQ(sm->addService(String16("foo"), getBinder(), false /*allowIsolated*/,
        IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT), OK);
}

TEST(GetService, HappyHappy) {
    auto sm = new ServiceManager();
    sp<IBinder> service = getBinder();

    EXPECT_EQ(sm->addService(String16("foo"), service, false /*allowIsolated*/,
        IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT), OK);

    EXPECT_EQ(sm->getService(String16("foo")), service);
}

TEST(GetService, NonExistant) {
    auto sm = new ServiceManager();

    EXPECT_EQ(sm->getService(String16("foo")), nullptr);
}

TEST(ListServices, AllServices) {
    auto sm = new ServiceManager();

    EXPECT_EQ(sm->addService(String16("sd"), getBinder(), false /*allowIsolated*/,
        IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT), OK);
    EXPECT_EQ(sm->addService(String16("sc"), getBinder(), false /*allowIsolated*/,
        IServiceManager::DUMP_FLAG_PRIORITY_NORMAL), OK);
    EXPECT_EQ(sm->addService(String16("sb"), getBinder(), false /*allowIsolated*/,
        IServiceManager::DUMP_FLAG_PRIORITY_HIGH), OK);
    EXPECT_EQ(sm->addService(String16("sa"), getBinder(), false /*allowIsolated*/,
        IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL), OK);

    android::Vector<String16> out = sm->listServices(IServiceManager::DUMP_FLAG_PRIORITY_ALL);

    // all there and in the right order
    EXPECT_THAT(out, ElementsAre(String16("sa"), String16("sb"), String16("sc"),
        String16("sd")));
}

TEST(WaitForService, NonExistant) {
    auto sm = new ServiceManager();

    EXPECT_EQ(sm->waitForService(String16("foo")), nullptr);
}

TEST(WaitForService, HappyHappy) {
    auto sm = new ServiceManager();
    sp<IBinder> service = getBinder();

    EXPECT_EQ(sm->addService(String16("foo"), service, false /*allowIsolated*/,
        IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT), OK);

    EXPECT_EQ(sm->waitForService(String16("foo")), service);
}

TEST(IsDeclared, NonExistant) {
    auto sm = new ServiceManager();

    EXPECT_FALSE(sm->isDeclared(String16("foo")));
}

TEST(IsDeclared, HappyHappy) {
    auto sm = new ServiceManager();
    sp<IBinder> service = getBinder();

    EXPECT_EQ(sm->addService(String16("foo"), service, false /*allowIsolated*/,
        IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT), OK);

    EXPECT_TRUE(sm->isDeclared(String16("foo")));
}