File: application_agent.h

package info (click to toggle)
android-platform-tools 35.0.2-1~exp6
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 211,716 kB
  • sloc: cpp: 995,749; java: 290,495; ansic: 145,647; xml: 58,531; python: 39,608; sh: 14,500; javascript: 5,198; asm: 4,866; makefile: 3,115; yacc: 769; awk: 368; ruby: 183; sql: 140; perl: 88; lex: 67
file content (172 lines) | stat: -rw-r--r-- 7,343 bytes parent folder | download | duplicates (6)
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
// Copyright 2020 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.

#ifndef CAST_RECEIVER_APPLICATION_AGENT_H_
#define CAST_RECEIVER_APPLICATION_AGENT_H_

#include <map>
#include <memory>
#include <string>
#include <vector>

#include "cast/common/channel/cast_socket_message_port.h"
#include "cast/common/channel/connection_namespace_handler.h"
#include "cast/common/channel/virtual_connection_router.h"
#include "cast/common/public/cast_socket.h"
#include "cast/receiver/channel/device_auth_namespace_handler.h"
#include "cast/receiver/public/receiver_socket_factory.h"
#include "platform/api/serial_delete_ptr.h"
#include "platform/api/task_runner.h"
#include "platform/base/error.h"
#include "platform/base/ip_address.h"
#include "util/json/json_value.h"

namespace openscreen {
namespace cast {

class CastSocket;

// A service accepting CastSocket connections, and providing a minimal
// implementation of the CastV2 application control protocol to launch receiver
// applications and route messages to/from them.
//
// Workflow: One or more Applications are registered under this ApplicationAgent
// (e.g., a "mirroring" app). Later, a ReceiverSocketFactory (external to this
// class) will listen and establish CastSocket connections, and then pass
// CastSockets to this ApplicationAgent via the OnConnect() method. As each
// connection is made, device authentication will take place. Then, Cast V2
// application messages asking about application availability are received and
// responded to, based on what Applications are registered. Finally, the remote
// may request the LAUNCH of an Application (and later a STOP).
//
// In the meantime, this ApplicationAgent broadcasts RECEIVER_STATUS about what
// application is running. In addition, it attempts to launch an "idle screen"
// Application whenever no other Application is running. The "idle screen"
// Application is usually some kind of screen saver or wallpaper/clock display.
// Registering the "idle screen" Application is optional, and if it's not
// registered, then nothing will be running during idle periods.
class ApplicationAgent final
    : public ReceiverSocketFactory::Client,
      public CastMessageHandler,
      public ConnectionNamespaceHandler::VirtualConnectionPolicy,
      public VirtualConnectionRouter::SocketErrorHandler {
 public:
  class Application {
   public:
    // Returns the one or more application IDs that are supported. This list
    // must not mutate while the Application is registered.
    virtual const std::vector<std::string>& GetAppIds() const = 0;

    // Launches the application and returns true if successful. |app_id| is the
    // specific ID that was used to launch the app, and |app_params| is a
    // pass-through for any arbitrary app-specfic structure (or null if not
    // provided). If the Application wishes to send/receive messages, it uses
    // the provided |message_port| and must call MessagePort::SetClient() before
    // any flow will occur.
    virtual bool Launch(const std::string& app_id,
                        const Json::Value& app_params,
                        MessagePort* message_port) = 0;

    // These reflect the current state of the application, and the data is used
    // to populate RECEIVER_STATUS messages.
    virtual std::string GetSessionId() = 0;
    virtual std::string GetDisplayName() = 0;
    virtual std::vector<std::string> GetSupportedNamespaces() = 0;

    // Stops the application, if running.
    virtual void Stop() = 0;

   protected:
    virtual ~Application();
  };

  ApplicationAgent(
      TaskRunner* task_runner,
      DeviceAuthNamespaceHandler::CredentialsProvider* credentials_provider);

  ~ApplicationAgent() final;

  // Return the interface by which the CastSocket inbound traffic is delivered
  // into this agent and any running Applications.
  CastSocket::Client* cast_socket_client() { return &router_; }

  // Registers an Application for launching by this agent. |app| must outlive
  // this ApplicationAgent, or until UnregisterApplication() is called.
  void RegisterApplication(Application* app,
                           bool auto_launch_for_idle_screen = false);
  void UnregisterApplication(Application* app);

  // Stops the given |app| if it is the one currently running. This is used by
  // applications that encounter "exit" conditions where they need to STOP
  // (e.g., due to timeout of user activity, end of media playback, or fatal
  // errors).
  void StopApplicationIfRunning(Application* app);

 private:
  // ReceiverSocketFactory::Client overrides.
  void OnConnected(ReceiverSocketFactory* factory,
                   const IPEndpoint& endpoint,
                   std::unique_ptr<CastSocket> socket) final;
  void OnError(ReceiverSocketFactory* factory, Error error) final;

  // CastMessageHandler overrides.
  void OnMessage(VirtualConnectionRouter* router,
                 CastSocket* socket,
                 ::cast::channel::CastMessage message) final;

  // ConnectionNamespaceHandler::VirtualConnectionPolicy overrides.
  bool IsConnectionAllowed(const VirtualConnection& virtual_conn) const final;

  // VirtualConnectionRouter::SocketErrorHandler overrides.
  void OnClose(CastSocket* socket) final;
  void OnError(CastSocket* socket, Error error) final;

  // OnMessage() delegates to these to take action for each |request|. Each of
  // these returns a non-empty response message if a reply should be sent back
  // to the requestor.
  Json::Value HandlePing();
  Json::Value HandleGetAppAvailability(const Json::Value& request);
  Json::Value HandleGetStatus(const Json::Value& request);
  Json::Value HandleLaunch(const Json::Value& request, CastSocket* socket);
  Json::Value HandleStop(const Json::Value& request);
  Json::Value HandleInvalidCommand(const Json::Value& request);

  // Stops the currently-running Application and attempts to launch the
  // Application referred to by |app_id|. If this fails, the "idle screen"
  // Application will be automatically launched as a failure fall-back. |socket|
  // is non-null only when the application switch was caused by a remote LAUNCH
  // request.
  Error SwitchToApplication(std::string app_id,
                            const Json::Value& app_params,
                            CastSocket* socket);

  // Stops the currently-running Application and launches the "idle screen."
  void GoIdle();

  // Populates the given |message| object with the RECEIVER_STATUS fields,
  // reflecting the currently-launched app (if any), and a fake volume level
  // status.
  void PopulateReceiverStatus(Json::Value* message);

  // Broadcasts new RECEIVER_STATUS to all endpoints. This is called after an
  // Application LAUNCH or STOP.
  void BroadcastReceiverStatus();

  TaskRunner* const task_runner_;
  DeviceAuthNamespaceHandler auth_handler_;
  VirtualConnectionRouter router_;
  ConnectionNamespaceHandler connection_handler_;

  std::map<std::string, Application*> registered_applications_;
  Application* idle_screen_app_ = nullptr;

  CastSocketMessagePort message_port_;
  Application* launched_app_ = nullptr;
  std::string launched_via_app_id_;
};

}  // namespace cast
}  // namespace openscreen

#endif  // CAST_RECEIVER_APPLICATION_AGENT_H_