blob: d5e90ff72f9076cf9af40f7e1742fe5ec05c48fd [file] [log] [blame]
// Copyright 2015 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "libprotobinder/parcel.h"
#include "libprotobinder/status.h"
#include <base/logging.h>
#include <base/files/file_path.h>
// IDL definition
#include "libprotobinder/binder.pb.h"
namespace protobinder {
const std::map<Status::BinderStatus, std::string> Status::kErrorStrings = {
{Status::OK, "OK"},
{Status::APPLICATION_ERROR, "APPLICATION_ERROR"},
{Status::DEAD_ENDPOINT, "DEAD_ENDPOINT"},
{Status::UNKNOWN_CODE, "UNKNOWN_CODE"},
{Status::DRIVER_ERROR, "DRIVER_ERROR"},
{Status::BAD_PARCEL, "BAD_PARCEL"},
{Status::FAILED_TRANSACTION, "FAILED_TRANSACTION"},
{Status::BAD_PROTO, "BAD_PROTO"},
{Status::ENDPOINT_NOT_SET, "ENDPOINT_NOT_SET"}};
Status::Status(Parcel* parcel) {
std::string reply_string;
parcel->ReadString(&reply_string);
StatusMessage proto;
proto.ParseFromString(reply_string);
CHECK(proto.has_binder_status());
CHECK(proto.has_app_status());
CHECK(proto.has_error_message());
CHECK(proto.has_line());
CHECK(proto.has_file());
binder_status_ = Status::kErrorStrings.count(
static_cast<BinderStatus>(proto.binder_status()))
? static_cast<BinderStatus>(proto.binder_status())
: Status::UNEXPECTED_STATUS;
application_status_ = proto.app_status();
error_message_ = proto.error_message();
line_ = proto.line();
file_ = proto.file();
}
Status::Status(BinderStatus status,
int application_status,
const std::string& error_message,
int line,
const std::string& file)
: binder_status_(status),
application_status_(application_status),
error_message_(error_message),
line_(line) {
file_ = base::FilePath(file).BaseName().value();
}
Status::~Status() {
}
void Status::AddToParcel(Parcel* parcel) const {
// First add Status to a proto.
StatusMessage proto;
proto.set_binder_status(binder_status_);
proto.set_app_status(application_status_);
proto.set_error_message(error_message_);
proto.set_line(line_);
proto.set_file(file_);
// Now add that to the Parcel.
std::string reply_string;
proto.SerializeToString(&reply_string);
parcel->WriteString(reply_string);
}
Status Status::BinderError(const BinderStatus status,
int line,
const std::string& file,
bool log,
logging::LogSeverity level) {
Status status_obj(status, 0, "", line, file);
if (log)
logging::LogMessage(file.c_str(), line, level).stream() << status_obj;
return status_obj;
}
Status Status::AppError(int status,
const std::string& str,
int line,
const std::string& file,
bool log,
logging::LogSeverity level) {
Status status_obj(APPLICATION_ERROR, status, str, line, file);
if (log)
logging::LogMessage(file.c_str(), line, level).stream() << status_obj;
return status_obj;
}
std::ostream& operator<<(std::ostream& os, const Status& status) {
if (status.IsOk()) {
os << "Status: Ok";
} else if (status.IsAppError()) {
os << "Status: Application Error " << status.application_status() << " \""
<< status.error_message() << "\"";
} else {
os << "Status: Binder Error " << status.status() << " ";
auto it = Status::kErrorStrings.find(status.status());
if (it == Status::kErrorStrings.end())
os << "Unknown Binder error";
else
os << it->second;
}
os << " [" << status.file() << ":" << status.line() << "]";
return os;
}
} // namespace protobinder