1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200
|
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chromeos/ash/components/phonehub/message_receiver_impl.h"
#include <netinet/in.h>
#include <stdint.h>
#include <string>
#include "ash/constants/ash_features.h"
#include "base/logging.h"
#include "chromeos/ash/components/phonehub/proto/phonehub_api.pb.h"
#include "chromeos/ash/components/phonehub/util/histogram_util.h"
namespace ash::phonehub {
namespace {
std::string GetMessageTypeName(proto::MessageType message_type) {
switch (message_type) {
case proto::MessageType::PHONE_STATUS_SNAPSHOT:
return "PHONE_STATUS_SNAPSHOT";
case proto::MessageType::PHONE_STATUS_UPDATE:
return "PHONE_STATUS_UPDATE";
case proto::MessageType::UPDATE_NOTIFICATION_MODE_RESPONSE:
return "UPDATE_NOTIFICATION_MODE_RESPONSE";
case proto::MessageType::RING_DEVICE_RESPONSE:
return "RING_DEVICE_RESPONSE";
case proto::MessageType::UPDATE_BATTERY_MODE_RESPONSE:
return "UPDATE_BATTERY_MODE_RESPONSE";
case proto::MessageType::DISMISS_NOTIFICATION_RESPONSE:
return "DISMISS_NOTIFICATION_RESPONSE";
case proto::MessageType::NOTIFICATION_INLINE_REPLY_RESPONSE:
return "NOTIFICATION_INLINE_REPLY_RESPONSE";
case proto::MessageType::SHOW_NOTIFICATION_ACCESS_SETUP_RESPONSE:
return "SHOW_NOTIFICATION_ACCESS_SETUP_RESPONSE";
case proto::MessageType::FETCH_CAMERA_ROLL_ITEMS_RESPONSE:
return "FETCH_CAMERA_ROLL_ITEMS_RESPONSE";
case proto::MessageType::FETCH_CAMERA_ROLL_ITEM_DATA_RESPONSE:
return "FETCH_CAMERA_ROLL_ITEM_DATA_RESPONSE";
case proto::MessageType::FEATURE_SETUP_RESPONSE:
return "FEATURE_SETUP_RESPONSE";
case proto::MessageType::PING_RESPONSE:
return "PING_RESPONSE";
case proto::MessageType::APP_STREAM_UPDATE:
return "APP_STREAM_UPDATE";
case proto::MessageType::APP_LIST_UPDATE:
return "APP_LIST_UPDATE";
case proto::MessageType::APP_LIST_INCREMENTAL_UPDATE:
return "APP_LIST_INCREMENTAL_UPDATE";
default:
return "UNKOWN_MESSAGE";
}
}
} // namespace
MessageReceiverImpl::MessageReceiverImpl(
secure_channel::ConnectionManager* connection_manager,
PhoneHubStructuredMetricsLogger* phone_hub_structured_metrics_logger)
: connection_manager_(connection_manager),
phone_hub_structured_metrics_logger_(
phone_hub_structured_metrics_logger) {
DCHECK(connection_manager_);
connection_manager_->AddObserver(this);
}
MessageReceiverImpl::~MessageReceiverImpl() {
connection_manager_->RemoveObserver(this);
}
void MessageReceiverImpl::OnMessageReceived(const std::string& payload) {
// The first two bytes of |payload| is reserved for the header
// proto::MessageType.
uint16_t* ptr =
reinterpret_cast<uint16_t*>(const_cast<char*>(payload.data()));
proto::MessageType message_type =
static_cast<proto::MessageType>(ntohs(*ptr));
PA_LOG(INFO) << "MessageReceiver received a "
<< GetMessageTypeName(message_type) << " message.";
util::LogMessageResult(message_type,
util::PhoneHubMessageResult::kResponseReceived);
phone_hub_structured_metrics_logger_->LogPhoneHubMessageEvent(
message_type, PhoneHubMessageDirection::kPhoneToChromebook);
// Decode the proto message if the message is something we want to notify to
// clients.
if (message_type == proto::MessageType::PHONE_STATUS_SNAPSHOT) {
proto::PhoneStatusSnapshot snapshot_proto;
// Serialized proto is after the first two bytes of |payload|.
if (!snapshot_proto.ParseFromString(payload.substr(2))) {
PA_LOG(ERROR) << "OnMessageReceived() could not deserialize the "
<< "PhoneStatusSnapshot proto message.";
return;
}
NotifyPhoneStatusSnapshotReceived(snapshot_proto);
return;
}
if (message_type == proto::MessageType::PHONE_STATUS_UPDATE) {
proto::PhoneStatusUpdate update_proto;
// Serialized proto is after the first two bytes of |payload|.
if (!update_proto.ParseFromString(payload.substr(2))) {
PA_LOG(ERROR) << "OnMessageReceived() could not deserialize the "
<< "PhoneStatusUpdate proto message.";
return;
}
NotifyPhoneStatusUpdateReceived(update_proto);
return;
}
if (message_type == proto::MessageType::FEATURE_SETUP_RESPONSE) {
proto::FeatureSetupResponse response;
// Serialized proto is after the first two bytes of |payload|.
if (!response.ParseFromString(payload.substr(2))) {
PA_LOG(ERROR) << "OnMessageReceived() could not deserialize the "
<< "FeatureSetupResponse proto message.";
return;
}
NotifyFeatureSetupResponseReceived(response);
}
if (features::IsPhoneHubCameraRollEnabled() &&
message_type == proto::MessageType::FETCH_CAMERA_ROLL_ITEMS_RESPONSE) {
proto::FetchCameraRollItemsResponse response;
// Serialized proto is after the first two bytes of |payload|.
if (!response.ParseFromString(payload.substr(2))) {
PA_LOG(ERROR) << "OnMessageReceived() could not deserialize the "
<< "FetchCameraRollItemsResponse proto message.";
return;
}
NotifyFetchCameraRollItemsResponseReceived(response);
return;
}
if (features::IsPhoneHubCameraRollEnabled() &&
message_type ==
proto::MessageType::FETCH_CAMERA_ROLL_ITEM_DATA_RESPONSE) {
proto::FetchCameraRollItemDataResponse response;
// Serialized proto is after the first two bytes of |payload|.
if (!response.ParseFromString(payload.substr(2))) {
PA_LOG(ERROR) << "OnMessageReceived() could not deserialize the "
<< "FetchCameraRollItemDataResponse proto message.";
return;
}
NotifyFetchCameraRollItemDataResponseReceived(response);
return;
}
if (features::IsPhoneHubPingOnBubbleOpenEnabled() &&
message_type == proto::MessageType::PING_RESPONSE) {
// We don't need to send the content of the ping response, we only care
// that we got a response.
NotifyPingResponseReceived();
return;
}
if (features::IsEcheSWAEnabled() &&
message_type == proto::MessageType::APP_STREAM_UPDATE) {
proto::AppStreamUpdate app_stream_update;
// Serialized proto is after the first two bytes of |payload|.
if (!app_stream_update.ParseFromString(payload.substr(2))) {
PA_LOG(ERROR) << "OnMessageReceived() could not deserialize the "
<< "AppStreamUpdate proto message.";
return;
}
NotifyAppStreamUpdateReceived(app_stream_update);
return;
}
if (features::IsEcheSWAEnabled() &&
message_type == proto::MessageType::APP_LIST_UPDATE) {
proto::AppListUpdate app_list_update;
// Serialized proto is after the first two bytes of |payload|.
if (!app_list_update.ParseFromString(payload.substr(2))) {
PA_LOG(ERROR) << "OnMessageReceived() could not deserialize the "
<< "AppListUpdate proto message.";
return;
}
NotifyAppListUpdateReceived(app_list_update);
return;
}
if (features::IsEcheSWAEnabled() &&
message_type == proto::MessageType::APP_LIST_INCREMENTAL_UPDATE) {
proto::AppListIncrementalUpdate app_list_incrementalUpdate;
if (!app_list_incrementalUpdate.ParseFromString(payload.substr(2))) {
PA_LOG(ERROR) << "OnMessageReceived() could not deserialize the "
<< "AppListIncrementalUpdate proto message.";
return;
}
NotifyAppListIncrementalUpdateReceived(app_list_incrementalUpdate);
return;
}
}
} // namespace ash::phonehub
|