1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/*
2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *
4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  Use of this source code is governed by a BSD-style license
5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  that can be found in the LICENSE file in the root of the source
6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  tree. An additional intellectual property rights grant can be found
7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  in the file PATENTS.  All contributing project authors may
8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */
10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
11b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifndef WEBRTC_VOICE_ENGINE_CHANNEL_MANAGER_H
12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#define WEBRTC_VOICE_ENGINE_CHANNEL_MANAGER_H
13b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
14b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org#include <vector>
15b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
16774b3d38a4a0f1a8ec08972a3c543cb5d607ce13henrike@webrtc.org#include "webrtc/base/constructormagic.h"
17b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org#include "webrtc/system_wrappers/interface/atomic32.h"
18b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
19b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org#include "webrtc/system_wrappers/interface/scoped_ptr.h"
20b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org#include "webrtc/typedefs.h"
21b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
22b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.orgnamespace webrtc {
234489c51faaf5b7e9f8845c5fb661f6ae91f7da48minyue@webrtc.org
244489c51faaf5b7e9f8845c5fb661f6ae91f7da48minyue@webrtc.orgclass Config;
254489c51faaf5b7e9f8845c5fb661f6ae91f7da48minyue@webrtc.org
26b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.orgnamespace voe {
27b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
28b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgclass Channel;
29b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
30b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org// Shared-pointer implementation for keeping track of Channels. The underlying
31b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org// shared instance will be dropped when no more ChannelOwners point to it.
32b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org//
33b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org// One common source of ChannelOwner instances are
34b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org// ChannelManager::CreateChannel() and ChannelManager::GetChannel(...).
35b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org// It has a similar use case to shared_ptr in C++11. Should this move to C++11
36b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org// in the future, this class should be replaced by exactly that.
37b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org//
38b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org// To access the underlying Channel, use .channel().
39b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org// IsValid() implements a convenience method as an alternative for checking
40b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org// whether the underlying pointer is NULL or not.
41b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org//
42b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org// Channel channel_owner = channel_manager.GetChannel(channel_id);
43b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org// if (channel_owner.IsValid())
44b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org//   channel_owner.channel()->...;
45b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org//
46b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.orgclass ChannelOwner {
47b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org public:
48b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  explicit ChannelOwner(Channel* channel);
49b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  ChannelOwner(const ChannelOwner& channel_owner);
50b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org
51b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  ~ChannelOwner();
52b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org
53b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  ChannelOwner& operator=(const ChannelOwner& other);
54b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org
55b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  Channel* channel() { return channel_ref_->channel.get(); }
56b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  bool IsValid() { return channel_ref_->channel.get() != NULL; }
57b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org private:
58b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  // Shared instance of a Channel. Copying ChannelOwners increase the reference
59b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  // count and destroying ChannelOwners decrease references. Channels are
60b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  // deleted when no references to them are held.
61b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  struct ChannelRef {
62b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org    ChannelRef(Channel* channel);
63b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org    const scoped_ptr<Channel> channel;
64b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org    Atomic32 ref_count;
65b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  };
66b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org
67b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  ChannelRef* channel_ref_;
68b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org};
69b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
70b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.orgclass ChannelManager {
71b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org public:
724489c51faaf5b7e9f8845c5fb661f6ae91f7da48minyue@webrtc.org  ChannelManager(uint32_t instance_id, const Config& config);
73b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
74b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  // Upon construction of an Iterator it will grab a copy of the channel list of
75b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  // the ChannelManager. The iteration will then occur over this state, not the
76b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  // current one of the ChannelManager. As the Iterator holds its own references
77b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  // to the Channels, they will remain valid even if they are removed from the
78b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  // ChannelManager.
79b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  class Iterator {
80b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org   public:
81b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org    explicit Iterator(ChannelManager* channel_manager);
82b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
83b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org    Channel* GetChannel();
84b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org    bool IsValid();
85b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
86b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org    void Increment();
87b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
88b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org   private:
89b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org    size_t iterator_pos_;
90b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org    std::vector<ChannelOwner> channels_;
91b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
92b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org    DISALLOW_COPY_AND_ASSIGN(Iterator);
93b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  };
94b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
95b43ac9f2c5d33f5613ad2757e1e62a0aa3c2d34fturaj@webrtc.org  // CreateChannel will always return a valid ChannelOwner instance. The channel
96b43ac9f2c5d33f5613ad2757e1e62a0aa3c2d34fturaj@webrtc.org  // is created either based on internal configuration, i.e. |config_|, by
97b43ac9f2c5d33f5613ad2757e1e62a0aa3c2d34fturaj@webrtc.org  // calling CreateChannel(), or using and external configuration
98b43ac9f2c5d33f5613ad2757e1e62a0aa3c2d34fturaj@webrtc.org  // |external_config| if the overloaded method
99b43ac9f2c5d33f5613ad2757e1e62a0aa3c2d34fturaj@webrtc.org  // CreateChannel(const Config& external_config) is called.
100b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  ChannelOwner CreateChannel();
101b43ac9f2c5d33f5613ad2757e1e62a0aa3c2d34fturaj@webrtc.org  ChannelOwner CreateChannel(const Config& external_config);
102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
103b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  // ChannelOwner.channel() will be NULL if channel_id is invalid or no longer
104b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  // exists. This should be checked with ChannelOwner::IsValid().
105b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  ChannelOwner GetChannel(int32_t channel_id);
106b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  void GetAllChannels(std::vector<ChannelOwner>* channels);
107b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
108b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  void DestroyChannel(int32_t channel_id);
109b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  void DestroyAllChannels();
110b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
111b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  size_t NumOfChannels() const;
112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
113b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org private:
114b43ac9f2c5d33f5613ad2757e1e62a0aa3c2d34fturaj@webrtc.org  // Create a channel given a configuration, |config|.
115b43ac9f2c5d33f5613ad2757e1e62a0aa3c2d34fturaj@webrtc.org  ChannelOwner CreateChannelInternal(const Config& config);
116b43ac9f2c5d33f5613ad2757e1e62a0aa3c2d34fturaj@webrtc.org
117b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  uint32_t instance_id_;
118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
119b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  Atomic32 last_channel_id_;
120b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
121b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  scoped_ptr<CriticalSectionWrapper> lock_;
122b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  std::vector<ChannelOwner> channels_;
123b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1244489c51faaf5b7e9f8845c5fb661f6ae91f7da48minyue@webrtc.org  const Config& config_;
1254489c51faaf5b7e9f8845c5fb661f6ae91f7da48minyue@webrtc.org
126b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org  DISALLOW_COPY_AND_ASSIGN(ChannelManager);
127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org};
1283b89e10f31160da35b408fd00cb8f89d2b08862dpbos@webrtc.org}  // namespace voe
1293b89e10f31160da35b408fd00cb8f89d2b08862dpbos@webrtc.org}  // namespace webrtc
130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif  // WEBRTC_VOICE_ENGINE_CHANNEL_MANAGER_H
132