summaryrefslogtreecommitdiffstats
path: root/device/bluetooth/dbus/fake_bluetooth_media_client.cc
blob: 246a14097add6c61721cf220ec3ff3f767a302f8 (plain)
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
// Copyright 2014 The Chromium 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 "device/bluetooth/dbus/fake_bluetooth_media_client.h"

#include <string>

#include "base/stl_util.h"
#include "device/bluetooth/dbus/bluez_dbus_manager.h"
#include "device/bluetooth/dbus/fake_bluetooth_adapter_client.h"
#include "device/bluetooth/dbus/fake_bluetooth_media_endpoint_service_provider.h"
#include "device/bluetooth/dbus/fake_bluetooth_media_transport_client.h"

using dbus::ObjectPath;

namespace {

// Except for |kFailedError|, the other error is defined in BlueZ D-Bus Media
// API.
const char kFailedError[] = "org.chromium.Error.Failed";
const char kInvalidArgumentsError[] = "org.chromium.Error.InvalidArguments";

}  // namespace

namespace bluez {

// static
const uint8_t FakeBluetoothMediaClient::kDefaultCodec = 0x00;

FakeBluetoothMediaClient::FakeBluetoothMediaClient()
    : visible_(true),
      object_path_(ObjectPath(FakeBluetoothAdapterClient::kAdapterPath)) {}

FakeBluetoothMediaClient::~FakeBluetoothMediaClient() {}

void FakeBluetoothMediaClient::Init(dbus::Bus* bus) {}

void FakeBluetoothMediaClient::AddObserver(
    BluetoothMediaClient::Observer* observer) {
  DCHECK(observer);
  observers_.AddObserver(observer);
}

void FakeBluetoothMediaClient::RemoveObserver(
    BluetoothMediaClient::Observer* observer) {
  DCHECK(observer);
  observers_.RemoveObserver(observer);
}

void FakeBluetoothMediaClient::RegisterEndpoint(
    const ObjectPath& object_path,
    const ObjectPath& endpoint_path,
    const EndpointProperties& properties,
    const base::Closure& callback,
    const ErrorCallback& error_callback) {
  if (!visible_)
    return;

  VLOG(1) << "RegisterEndpoint: " << endpoint_path.value();

  // The media client and adapter client should have the same object path.
  if (object_path != object_path_ ||
      properties.uuid != BluetoothMediaClient::kBluetoothAudioSinkUUID ||
      properties.codec != kDefaultCodec || properties.capabilities.empty()) {
    error_callback.Run(kInvalidArgumentsError, "");
    return;
  }

  callback.Run();
}

void FakeBluetoothMediaClient::UnregisterEndpoint(
    const ObjectPath& object_path,
    const ObjectPath& endpoint_path,
    const base::Closure& callback,
    const ErrorCallback& error_callback) {
  // TODO(mcchou): Come up with some corresponding actions.
  VLOG(1) << "UnregisterEndpoint: " << endpoint_path.value();

  if (!ContainsKey(endpoints_, endpoint_path)) {
    error_callback.Run(kFailedError, "Unknown media endpoint");
    return;
  }

  SetEndpointRegistered(endpoints_[endpoint_path], false);
  callback.Run();
}

void FakeBluetoothMediaClient::SetVisible(bool visible) {
  visible_ = visible;

  if (visible_)
    return;

  // If the media object becomes invisible, an update chain will unregister all
  // endpoints and set the associated transport objects to be invalid.
  // SetEndpointRegistered will remove the endpoint entry from |endpoints_|.
  while (endpoints_.begin() != endpoints_.end())
    SetEndpointRegistered(endpoints_.begin()->second, false);

  // Notifies observers about the change on |visible_|.
  FOR_EACH_OBSERVER(BluetoothMediaClient::Observer, observers_,
                    MediaRemoved(object_path_));
}

void FakeBluetoothMediaClient::SetEndpointRegistered(
    FakeBluetoothMediaEndpointServiceProvider* endpoint,
    bool registered) {
  if (registered) {
    endpoints_[endpoint->object_path()] = endpoint;
    return;
  }

  if (!IsRegistered(endpoint->object_path()))
    return;

  // Once a media endpoint object becomes invalid, invalidate the associated
  // transport.
  FakeBluetoothMediaTransportClient* transport =
      static_cast<FakeBluetoothMediaTransportClient*>(
          bluez::BluezDBusManager::Get()->GetBluetoothMediaTransportClient());
  transport->SetValid(endpoint, false);

  endpoints_.erase(endpoint->object_path());
  endpoint->Released();
}

bool FakeBluetoothMediaClient::IsRegistered(
    const dbus::ObjectPath& endpoint_path) {
  return ContainsKey(endpoints_, endpoint_path);
}

}  // namespace bluez