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

Commit 30925ee9 authored by Jeff Pu's avatar Jeff Pu Committed by Android (Google) Code Review
Browse files

Merge "Close the session if Fingerprint servers die" into udc-dev

parents 9bd4fb37 87e9f2be
Loading
Loading
Loading
Loading
+26 −0
Original line number Diff line number Diff line
@@ -110,6 +110,32 @@ cc_test {
    require_root: true,
}

cc_test {
    name: "android.hardware.biometrics.fingerprint.SessionTest",
    local_include_dirs: ["include"],
    srcs: [
        "tests/SessionTest.cpp",
        "Session.cpp",
        "FakeFingerprintEngine.cpp",
        "FakeLockoutTracker.cpp",
    ],
    shared_libs: [
        "libbase",
        "libbinder_ndk",
        "android.hardware.biometrics.common.thread",
    ],
    static_libs: [
        "libandroid.hardware.biometrics.fingerprint.VirtualProps",
        "android.hardware.biometrics.fingerprint-V3-ndk",
        "android.hardware.biometrics.common-V3-ndk",
        "android.hardware.keymaster-V4-ndk",
        "android.hardware.biometrics.common.util",
    ],
    vendor: true,
    test_suites: ["general-tests"],
    require_root: true,
}

sysprop_library {
    name: "android.hardware.biometrics.fingerprint.VirtualProps",
    srcs: ["fingerprint.sysprop"],
+2 −0
Original line number Diff line number Diff line
@@ -103,6 +103,8 @@ ndk::ScopedAStatus Fingerprint::createSession(int32_t sensorId, int32_t userId,
    mSession = SharedRefBase::make<Session>(sensorId, userId, cb, mEngine.get(), &mWorker);
    *out = mSession;

    mSession->linkToDeath(cb->asBinder().get());

    LOG(INFO) << "createSession: sensorId:" << sensorId << " userId:" << userId;
    return ndk::ScopedAStatus::ok();
}
+15 −0
Original line number Diff line number Diff line
@@ -25,6 +25,14 @@

namespace aidl::android::hardware::biometrics::fingerprint {

void onClientDeath(void* cookie) {
    LOG(INFO) << "FingerprintService has died";
    Session* session = static_cast<Session*>(cookie);
    if (session && !session->isClosed()) {
        session->close();
    }
}

Session::Session(int sensorId, int userId, std::shared_ptr<ISessionCallback> cb,
                 FakeFingerprintEngine* engine, WorkerThread* worker)
    : mSensorId(sensorId),
@@ -39,6 +47,12 @@ Session::Session(int sensorId, int userId, std::shared_ptr<ISessionCallback> cb,
    CHECK(mEngine);
    CHECK(mWorker);
    CHECK(mCb);

    mDeathRecipient = AIBinder_DeathRecipient_new(onClientDeath);
}

binder_status_t Session::linkToDeath(AIBinder* binder) {
    return AIBinder_linkToDeath(binder, mDeathRecipient, this);
}

void Session::scheduleStateOrCrash(SessionState state) {
@@ -228,6 +242,7 @@ ndk::ScopedAStatus Session::close() {
    // Crashing.";
    mCurrentState = SessionState::CLOSED;
    mCb->onSessionClosed();
    AIBinder_DeathRecipient_delete(mDeathRecipient);
    return ndk::ScopedAStatus::ok();
}

+7 −0
Original line number Diff line number Diff line
@@ -42,6 +42,8 @@ enum class SessionState {
    RESETTING_LOCKOUT,
};

void onClientDeath(void* cookie);

class Session : public BnSession {
  public:
    Session(int sensorId, int userId, std::shared_ptr<ISessionCallback> cb,
@@ -101,6 +103,8 @@ class Session : public BnSession {

    ndk::ScopedAStatus setIgnoreDisplayTouches(bool shouldIgnore) override;

    binder_status_t linkToDeath(AIBinder* binder);

    bool isClosed();

  private:
@@ -139,6 +143,9 @@ class Session : public BnSession {
    // modified from both the main and the worker threads.
    std::atomic<SessionState> mScheduledState;
    std::atomic<SessionState> mCurrentState;

    // Binder death handler.
    AIBinder_DeathRecipient* mDeathRecipient;
};

}  // namespace aidl::android::hardware::biometrics::fingerprint
+125 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 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 <android/binder_process.h>
#include <fingerprint.sysprop.h>
#include <gtest/gtest.h>

#include <android-base/logging.h>

#include <aidl/android/hardware/biometrics/fingerprint/BnSessionCallback.h>

#include "Session.h"
#include "thread/WorkerThread.h"
#include "util/Util.h"

using namespace ::android::fingerprint::virt;
using namespace ::aidl::android::hardware::biometrics::fingerprint;

namespace aidl::android::hardware::biometrics::fingerprint {

class TestSessionCallback : public BnSessionCallback {
  public:
    ndk::ScopedAStatus onChallengeGenerated(int64_t /*challenge*/) override {
        return ndk::ScopedAStatus::ok();
    };
    ::ndk::ScopedAStatus onChallengeRevoked(int64_t /*challenge*/) override {
        return ndk::ScopedAStatus::ok();
    };
    ::ndk::ScopedAStatus onError(fingerprint::Error /*error*/, int32_t /*vendorCode*/) override {
        return ndk::ScopedAStatus::ok();
    };
    ::ndk::ScopedAStatus onEnrollmentProgress(int32_t /*enrollmentId*/,
                                              int32_t /*remaining*/) override {
        return ndk::ScopedAStatus::ok();
    };

    ::ndk::ScopedAStatus onAuthenticationSucceeded(int32_t /*enrollmentId*/,
                                                   const keymaster::HardwareAuthToken&) override {
        return ndk::ScopedAStatus::ok();
    };
    ::ndk::ScopedAStatus onAuthenticationFailed() override { return ndk::ScopedAStatus::ok(); };
    ::ndk::ScopedAStatus onInteractionDetected() override { return ndk::ScopedAStatus::ok(); };
    ndk::ScopedAStatus onAcquired(AcquiredInfo /*info*/, int32_t /*vendorCode*/) override {
        return ndk::ScopedAStatus::ok();
    }
    ::ndk::ScopedAStatus onEnrollmentsEnumerated(
            const std::vector<int32_t>& /*enrollmentIds*/) override {
        return ndk::ScopedAStatus::ok();
    };
    ::ndk::ScopedAStatus onEnrollmentsRemoved(
            const std::vector<int32_t>& /*enrollmentIds*/) override {
        return ndk::ScopedAStatus::ok();
    };
    ::ndk::ScopedAStatus onAuthenticatorIdRetrieved(int64_t /*authenticatorId*/) override {
        return ndk::ScopedAStatus::ok();
    };
    ::ndk::ScopedAStatus onAuthenticatorIdInvalidated(int64_t /*authenticatorId*/) override {
        return ndk::ScopedAStatus::ok();
    };
    ::ndk::ScopedAStatus onLockoutPermanent() override { return ndk::ScopedAStatus::ok(); };
    ndk::ScopedAStatus onLockoutTimed(int64_t /* timeout */) override {
        return ndk::ScopedAStatus::ok();
    }
    ndk::ScopedAStatus onLockoutCleared() override { return ndk::ScopedAStatus::ok(); }
    ndk::ScopedAStatus onSessionClosed() override {
        mIsClosed = true;
        return ndk::ScopedAStatus::ok();
    }

    bool mIsClosed = false;
};

class SessionTest : public ::testing::Test {
  public:
    SessionTest() : mWorker(2) {}

  protected:
    void SetUp() override {
        mCb = ndk::SharedRefBase::make<TestSessionCallback>();
        mSession = ndk::SharedRefBase::make<Session>(1, 2, mCb, &mFakeFingerprintEngine, &mWorker);
        ASSERT_TRUE(mSession != nullptr);
        mSession->linkToDeath(mCb->asBinder().get());
    }

    void TearDown() override {}

    std::shared_ptr<Session> mSession;
    std::shared_ptr<TestSessionCallback> mCb;

  private:
    FakeFingerprintEngine mFakeFingerprintEngine;
    WorkerThread mWorker;
};

TEST_F(SessionTest, close) {
    ASSERT_TRUE(!mSession->isClosed());
    ASSERT_TRUE(!mCb->mIsClosed);
    onClientDeath(nullptr);
    ASSERT_TRUE(!mSession->isClosed());
    ASSERT_TRUE(!mCb->mIsClosed);
    onClientDeath(static_cast<void*>(mSession.get()));
    ASSERT_TRUE(mSession->isClosed());
    ASSERT_TRUE(mCb->mIsClosed);
}

}  //  namespace aidl::android::hardware::biometrics::fingerprint

int main(int argc, char** argv) {
    testing::InitGoogleTest(&argc, argv);
    ABinderProcess_startThreadPool();
    return RUN_ALL_TESTS();
}