Use std::optional instead of std::unique_ptr

Since Android R, Parcel provides read/write methods for "@nullable"
values using std::optional.

Bug: 149784838
Test: m
Change-Id: I343841e690ed2d00548bb2ad623e07fa26823214
This commit is contained in:
Jooyung Han 2020-11-18 12:17:50 +09:00
parent a58771971b
commit 1eec75aaa7
8 changed files with 35 additions and 32 deletions

View file

@ -26,8 +26,8 @@ namespace keymaster {
KeyAttestationApplicationId::KeyAttestationApplicationId() = default;
KeyAttestationApplicationId::KeyAttestationApplicationId(
std::unique_ptr<KeyAttestationPackageInfo> package) :
packageInfos_(new std::vector<std::unique_ptr<KeyAttestationPackageInfo>>()) {
std::optional<KeyAttestationPackageInfo> package)
: packageInfos_(new std::vector<std::optional<KeyAttestationPackageInfo>>()) {
packageInfos_->push_back(std::move(package));
}
@ -39,10 +39,13 @@ status_t KeyAttestationApplicationId::writeToParcel(Parcel* parcel) const {
}
status_t KeyAttestationApplicationId::readFromParcel(const Parcel* parcel) {
std::unique_ptr<std::vector<std::unique_ptr<KeyAttestationPackageInfo>>> temp_vector;
std::optional<std::vector<std::optional<KeyAttestationPackageInfo>>> temp_vector;
auto rc = parcel->readParcelableVector(&temp_vector);
if (rc != NO_ERROR) return rc;
packageInfos_.reset(temp_vector.release());
packageInfos_.reset();
if (temp_vector) {
packageInfos_ = std::make_shared<PackageInfoVector>(std::move(*temp_vector));
}
return NO_ERROR;
}

View file

@ -28,7 +28,7 @@ KeyAttestationPackageInfo::KeyAttestationPackageInfo() = default;
KeyAttestationPackageInfo::KeyAttestationPackageInfo(const String16& packageName,
int64_t versionCode,
SharedSignaturesVector signatures)
: packageName_(new String16(packageName)), versionCode_(versionCode), signatures_(signatures) {}
: packageName_(packageName), versionCode_(versionCode), signatures_(signatures) {}
status_t KeyAttestationPackageInfo::writeToParcel(Parcel* parcel) const {
auto rc = parcel->writeString16(packageName_);
@ -44,10 +44,13 @@ status_t KeyAttestationPackageInfo::readFromParcel(const Parcel* parcel) {
rc = parcel->readInt64(&versionCode_);
if (rc != NO_ERROR) return rc;
std::unique_ptr<SignaturesVector> temp_vector;
std::optional<SignaturesVector> temp_vector;
rc = parcel->readParcelableVector(&temp_vector);
if (rc != NO_ERROR) return rc;
signatures_.reset(temp_vector.release());
signatures_.reset();
if (temp_vector) {
signatures_ = std::make_shared<SignaturesVector>(std::move(*temp_vector));
}
return NO_ERROR;
}

View file

@ -16,6 +16,7 @@
#define KEYSTORE_INCLUDE_KEYSTORE_KEYATTESTATIONAPPLICATIONID_H_
#include <memory>
#include <optional>
#include <vector>
#include <binder/Parcelable.h>
@ -30,10 +31,10 @@ class KeyAttestationApplicationId : public Parcelable {
public:
typedef SharedNullableIterator<const KeyAttestationPackageInfo, std::vector>
ConstKeyAttestationPackageInfoIterator;
typedef std::vector<std::unique_ptr<KeyAttestationPackageInfo>> PackageInfoVector;
typedef std::vector<std::optional<KeyAttestationPackageInfo>> PackageInfoVector;
KeyAttestationApplicationId();
// Following c'tors are for initializing instances containing test data.
explicit KeyAttestationApplicationId(std::unique_ptr<KeyAttestationPackageInfo> package);
explicit KeyAttestationApplicationId(std::optional<KeyAttestationPackageInfo> package);
explicit KeyAttestationApplicationId(PackageInfoVector packages);
status_t writeToParcel(Parcel*) const override;
@ -47,7 +48,7 @@ class KeyAttestationApplicationId : public Parcelable {
}
private:
std::shared_ptr<std::vector<std::unique_ptr<KeyAttestationPackageInfo>>> packageInfos_;
std::shared_ptr<PackageInfoVector> packageInfos_;
};
} // namespace keymaster

View file

@ -18,6 +18,7 @@
#include <stdint.h>
#include <memory>
#include <optional>
#include <vector>
#include <binder/Parcelable.h>
@ -33,8 +34,7 @@ class KeyAttestationPackageInfo : public Parcelable {
public:
typedef SharedNullableIterator<const content::pm::Signature, std::vector>
ConstSignatureIterator;
typedef std::vector<std::unique_ptr<content::pm::Signature>>
SignaturesVector;
typedef std::vector<std::optional<content::pm::Signature>> SignaturesVector;
typedef std::shared_ptr<SignaturesVector> SharedSignaturesVector;
KeyAttestationPackageInfo(const String16& packageName, int64_t versionCode,
@ -44,14 +44,14 @@ class KeyAttestationPackageInfo : public Parcelable {
status_t writeToParcel(Parcel*) const override;
status_t readFromParcel(const Parcel* parcel) override;
const std::unique_ptr<String16>& package_name() const { return packageName_; }
const std::optional<String16>& package_name() const { return packageName_; }
int64_t version_code() const { return versionCode_; }
ConstSignatureIterator sigs_begin() const { return ConstSignatureIterator(signatures_); }
ConstSignatureIterator sigs_end() const { return ConstSignatureIterator(); }
private:
std::unique_ptr<String16> packageName_;
std::optional<String16> packageName_;
int64_t versionCode_;
SharedSignaturesVector signatures_;
};

View file

@ -31,29 +31,24 @@ struct KeystoreResponse : public ::android::Parcelable {
public:
KeystoreResponse() = default;
explicit KeystoreResponse(const int response_code, const String16& error_msg)
: response_code_(response_code), error_msg_(std::make_unique<String16>(error_msg)) {}
: response_code_(response_code), error_msg_(error_msg) {}
explicit KeystoreResponse(const int response_code)
: response_code_(response_code), error_msg_() {}
// NOLINTNEXTLINE(google-explicit-constructor)
KeystoreResponse(const ::keystore::KeyStoreServiceReturnCode& rc)
: response_code_(rc.getErrorCode()), error_msg_() {}
KeystoreResponse(const KeystoreResponse& other)
: response_code_(other.response_code_), error_msg_() {
if (other.error_msg_) {
error_msg_ = std::make_unique<String16>(*other.error_msg_);
}
}
KeystoreResponse(const KeystoreResponse& other) = default;
KeystoreResponse(KeystoreResponse&& other) = default;
status_t readFromParcel(const Parcel* in) override;
status_t writeToParcel(Parcel* out) const override;
int response_code() const { return response_code_; }
const String16* error_msg() const { return error_msg_.get(); }
const std::optional<String16>& error_msg() const { return error_msg_; }
private:
int response_code_;
std::unique_ptr<String16> error_msg_;
std::optional<String16> error_msg_;
};
} // namespace keystore

View file

@ -5,6 +5,7 @@
#include <iterator>
#include <memory>
#include <optional>
#include <vector>
namespace android {
@ -12,7 +13,7 @@ namespace security {
/*
* This iterator abstracts from a collection of the form
* std::shared_ptr<COLLECTION_TYPE<std::unique_ptr<T>>>
* std::shared_ptr<COLLECTION_TYPE<std::optional<T>>>
* such that it is defined both for nulled outer pointer and
* nulled entries. If shared_ptr(nullptr) is passed in, the iterator behaves
* like the end iterator yielding an empty collection. Nulled
@ -25,7 +26,7 @@ namespace security {
template <typename T, template <typename...> class Coll = std::vector>
class SharedNullableIterator {
public:
typedef Coll<std::unique_ptr<typename std::remove_const<T>::type>> CollectionType;
typedef Coll<std::optional<typename std::remove_const<T>::type>> CollectionType;
typedef std::shared_ptr<CollectionType> CollectionPtr;
SharedNullableIterator() {}

View file

@ -271,7 +271,7 @@ StatusOr<std::vector<uint8_t>> gather_attestation_application_id(uid_t uid) {
if (uid == AID_SYSTEM) {
/* Use a fixed ID for system callers */
auto pinfo = std::make_unique<KeyAttestationPackageInfo>(
auto pinfo = std::make_optional<KeyAttestationPackageInfo>(
String16(kAttestationSystemPackageName), 1 /* version code */,
std::make_shared<KeyAttestationPackageInfo::SignaturesVector>());
key_attestation_id = KeyAttestationApplicationId(std::move(pinfo));
@ -284,7 +284,7 @@ StatusOr<std::vector<uint8_t>> gather_attestation_application_id(uid_t uid) {
if (!status.isOk()) {
ALOGW("package manager request for key attestation ID failed with: %s %d",
status.exceptionMessage().string(), status.exceptionCode());
auto pinfo = std::make_unique<KeyAttestationPackageInfo>(
auto pinfo = std::make_optional<KeyAttestationPackageInfo>(
String16(kUnknownPackageName), 1 /* version code */,
std::make_shared<KeyAttestationPackageInfo::SignaturesVector>());
key_attestation_id = KeyAttestationApplicationId(std::move(pinfo));

View file

@ -75,15 +75,15 @@ constexpr const size_t kTooManySignatures = 35;
using ::android::content::pm::Signature;
using ::android::security::build_attestation_application_id;
std::unique_ptr<KeyAttestationPackageInfo>
std::optional<KeyAttestationPackageInfo>
make_package_info_with_signatures(const char* package_name,
KeyAttestationPackageInfo::SignaturesVector signatures) {
return std::make_unique<KeyAttestationPackageInfo>(
return std::make_optional<KeyAttestationPackageInfo>(
String16(package_name), 1 /* version code */,
std::make_shared<KeyAttestationPackageInfo::SignaturesVector>(std::move(signatures)));
}
std::unique_ptr<KeyAttestationPackageInfo> make_package_info(const char* package_name) {
std::optional<KeyAttestationPackageInfo> make_package_info(const char* package_name) {
return make_package_info_with_signatures(package_name,
KeyAttestationPackageInfo::SignaturesVector());
}
@ -111,7 +111,7 @@ TEST(AaidTruncationTest, tooManySignaturesTest) {
KeyAttestationPackageInfo::SignaturesVector signatures;
// Add 35 signatures which will surely exceed the 1K limit.
for (size_t i = 0; i < kTooManySignatures; ++i) {
signatures.push_back(std::make_unique<Signature>(dummy_sig_data));
signatures.push_back(std::make_optional<Signature>(dummy_sig_data));
}
KeyAttestationApplicationId app_id(
@ -131,7 +131,7 @@ TEST(AaidTruncationTest, combinedPackagesAndSignaturesTest) {
KeyAttestationPackageInfo::SignaturesVector signatures;
// Add a few signatures for each package
for (int j = 0; j < 3; ++j) {
signatures.push_back(std::make_unique<Signature>(dummy_sig_data));
signatures.push_back(std::make_optional<Signature>(dummy_sig_data));
}
packages.push_back(
make_package_info_with_signatures(kReasonablePackageName, std::move(signatures)));