xref: /aosp_15_r20/external/openscreen/cast/receiver/application_agent.h (revision 3f982cf4871df8771c9d4abe6e9a6f8d829b2736)
1*3f982cf4SFabien Sanglard // Copyright 2020 The Chromium Authors. All rights reserved.
2*3f982cf4SFabien Sanglard // Use of this source code is governed by a BSD-style license that can be
3*3f982cf4SFabien Sanglard // found in the LICENSE file.
4*3f982cf4SFabien Sanglard 
5*3f982cf4SFabien Sanglard #ifndef CAST_RECEIVER_APPLICATION_AGENT_H_
6*3f982cf4SFabien Sanglard #define CAST_RECEIVER_APPLICATION_AGENT_H_
7*3f982cf4SFabien Sanglard 
8*3f982cf4SFabien Sanglard #include <map>
9*3f982cf4SFabien Sanglard #include <memory>
10*3f982cf4SFabien Sanglard #include <string>
11*3f982cf4SFabien Sanglard #include <vector>
12*3f982cf4SFabien Sanglard 
13*3f982cf4SFabien Sanglard #include "cast/common/channel/cast_socket_message_port.h"
14*3f982cf4SFabien Sanglard #include "cast/common/channel/connection_namespace_handler.h"
15*3f982cf4SFabien Sanglard #include "cast/common/channel/virtual_connection_router.h"
16*3f982cf4SFabien Sanglard #include "cast/common/public/cast_socket.h"
17*3f982cf4SFabien Sanglard #include "cast/receiver/channel/device_auth_namespace_handler.h"
18*3f982cf4SFabien Sanglard #include "cast/receiver/public/receiver_socket_factory.h"
19*3f982cf4SFabien Sanglard #include "platform/api/serial_delete_ptr.h"
20*3f982cf4SFabien Sanglard #include "platform/api/task_runner.h"
21*3f982cf4SFabien Sanglard #include "platform/base/error.h"
22*3f982cf4SFabien Sanglard #include "platform/base/ip_address.h"
23*3f982cf4SFabien Sanglard #include "util/json/json_value.h"
24*3f982cf4SFabien Sanglard 
25*3f982cf4SFabien Sanglard namespace openscreen {
26*3f982cf4SFabien Sanglard namespace cast {
27*3f982cf4SFabien Sanglard 
28*3f982cf4SFabien Sanglard class CastSocket;
29*3f982cf4SFabien Sanglard 
30*3f982cf4SFabien Sanglard // A service accepting CastSocket connections, and providing a minimal
31*3f982cf4SFabien Sanglard // implementation of the CastV2 application control protocol to launch receiver
32*3f982cf4SFabien Sanglard // applications and route messages to/from them.
33*3f982cf4SFabien Sanglard //
34*3f982cf4SFabien Sanglard // Workflow: One or more Applications are registered under this ApplicationAgent
35*3f982cf4SFabien Sanglard // (e.g., a "mirroring" app). Later, a ReceiverSocketFactory (external to this
36*3f982cf4SFabien Sanglard // class) will listen and establish CastSocket connections, and then pass
37*3f982cf4SFabien Sanglard // CastSockets to this ApplicationAgent via the OnConnect() method. As each
38*3f982cf4SFabien Sanglard // connection is made, device authentication will take place. Then, Cast V2
39*3f982cf4SFabien Sanglard // application messages asking about application availability are received and
40*3f982cf4SFabien Sanglard // responded to, based on what Applications are registered. Finally, the remote
41*3f982cf4SFabien Sanglard // may request the LAUNCH of an Application (and later a STOP).
42*3f982cf4SFabien Sanglard //
43*3f982cf4SFabien Sanglard // In the meantime, this ApplicationAgent broadcasts RECEIVER_STATUS about what
44*3f982cf4SFabien Sanglard // application is running. In addition, it attempts to launch an "idle screen"
45*3f982cf4SFabien Sanglard // Application whenever no other Application is running. The "idle screen"
46*3f982cf4SFabien Sanglard // Application is usually some kind of screen saver or wallpaper/clock display.
47*3f982cf4SFabien Sanglard // Registering the "idle screen" Application is optional, and if it's not
48*3f982cf4SFabien Sanglard // registered, then nothing will be running during idle periods.
49*3f982cf4SFabien Sanglard class ApplicationAgent final
50*3f982cf4SFabien Sanglard     : public ReceiverSocketFactory::Client,
51*3f982cf4SFabien Sanglard       public CastMessageHandler,
52*3f982cf4SFabien Sanglard       public ConnectionNamespaceHandler::VirtualConnectionPolicy,
53*3f982cf4SFabien Sanglard       public VirtualConnectionRouter::SocketErrorHandler {
54*3f982cf4SFabien Sanglard  public:
55*3f982cf4SFabien Sanglard   class Application {
56*3f982cf4SFabien Sanglard    public:
57*3f982cf4SFabien Sanglard     // Returns the one or more application IDs that are supported. This list
58*3f982cf4SFabien Sanglard     // must not mutate while the Application is registered.
59*3f982cf4SFabien Sanglard     virtual const std::vector<std::string>& GetAppIds() const = 0;
60*3f982cf4SFabien Sanglard 
61*3f982cf4SFabien Sanglard     // Launches the application and returns true if successful. |app_id| is the
62*3f982cf4SFabien Sanglard     // specific ID that was used to launch the app, and |app_params| is a
63*3f982cf4SFabien Sanglard     // pass-through for any arbitrary app-specfic structure (or null if not
64*3f982cf4SFabien Sanglard     // provided). If the Application wishes to send/receive messages, it uses
65*3f982cf4SFabien Sanglard     // the provided |message_port| and must call MessagePort::SetClient() before
66*3f982cf4SFabien Sanglard     // any flow will occur.
67*3f982cf4SFabien Sanglard     virtual bool Launch(const std::string& app_id,
68*3f982cf4SFabien Sanglard                         const Json::Value& app_params,
69*3f982cf4SFabien Sanglard                         MessagePort* message_port) = 0;
70*3f982cf4SFabien Sanglard 
71*3f982cf4SFabien Sanglard     // These reflect the current state of the application, and the data is used
72*3f982cf4SFabien Sanglard     // to populate RECEIVER_STATUS messages.
73*3f982cf4SFabien Sanglard     virtual std::string GetSessionId() = 0;
74*3f982cf4SFabien Sanglard     virtual std::string GetDisplayName() = 0;
75*3f982cf4SFabien Sanglard     virtual std::vector<std::string> GetSupportedNamespaces() = 0;
76*3f982cf4SFabien Sanglard 
77*3f982cf4SFabien Sanglard     // Stops the application, if running.
78*3f982cf4SFabien Sanglard     virtual void Stop() = 0;
79*3f982cf4SFabien Sanglard 
80*3f982cf4SFabien Sanglard    protected:
81*3f982cf4SFabien Sanglard     virtual ~Application();
82*3f982cf4SFabien Sanglard   };
83*3f982cf4SFabien Sanglard 
84*3f982cf4SFabien Sanglard   ApplicationAgent(
85*3f982cf4SFabien Sanglard       TaskRunner* task_runner,
86*3f982cf4SFabien Sanglard       DeviceAuthNamespaceHandler::CredentialsProvider* credentials_provider);
87*3f982cf4SFabien Sanglard 
88*3f982cf4SFabien Sanglard   ~ApplicationAgent() final;
89*3f982cf4SFabien Sanglard 
90*3f982cf4SFabien Sanglard   // Return the interface by which the CastSocket inbound traffic is delivered
91*3f982cf4SFabien Sanglard   // into this agent and any running Applications.
cast_socket_client()92*3f982cf4SFabien Sanglard   CastSocket::Client* cast_socket_client() { return &router_; }
93*3f982cf4SFabien Sanglard 
94*3f982cf4SFabien Sanglard   // Registers an Application for launching by this agent. |app| must outlive
95*3f982cf4SFabien Sanglard   // this ApplicationAgent, or until UnregisterApplication() is called.
96*3f982cf4SFabien Sanglard   void RegisterApplication(Application* app,
97*3f982cf4SFabien Sanglard                            bool auto_launch_for_idle_screen = false);
98*3f982cf4SFabien Sanglard   void UnregisterApplication(Application* app);
99*3f982cf4SFabien Sanglard 
100*3f982cf4SFabien Sanglard   // Stops the given |app| if it is the one currently running. This is used by
101*3f982cf4SFabien Sanglard   // applications that encounter "exit" conditions where they need to STOP
102*3f982cf4SFabien Sanglard   // (e.g., due to timeout of user activity, end of media playback, or fatal
103*3f982cf4SFabien Sanglard   // errors).
104*3f982cf4SFabien Sanglard   void StopApplicationIfRunning(Application* app);
105*3f982cf4SFabien Sanglard 
106*3f982cf4SFabien Sanglard  private:
107*3f982cf4SFabien Sanglard   // ReceiverSocketFactory::Client overrides.
108*3f982cf4SFabien Sanglard   void OnConnected(ReceiverSocketFactory* factory,
109*3f982cf4SFabien Sanglard                    const IPEndpoint& endpoint,
110*3f982cf4SFabien Sanglard                    std::unique_ptr<CastSocket> socket) final;
111*3f982cf4SFabien Sanglard   void OnError(ReceiverSocketFactory* factory, Error error) final;
112*3f982cf4SFabien Sanglard 
113*3f982cf4SFabien Sanglard   // CastMessageHandler overrides.
114*3f982cf4SFabien Sanglard   void OnMessage(VirtualConnectionRouter* router,
115*3f982cf4SFabien Sanglard                  CastSocket* socket,
116*3f982cf4SFabien Sanglard                  ::cast::channel::CastMessage message) final;
117*3f982cf4SFabien Sanglard 
118*3f982cf4SFabien Sanglard   // ConnectionNamespaceHandler::VirtualConnectionPolicy overrides.
119*3f982cf4SFabien Sanglard   bool IsConnectionAllowed(const VirtualConnection& virtual_conn) const final;
120*3f982cf4SFabien Sanglard 
121*3f982cf4SFabien Sanglard   // VirtualConnectionRouter::SocketErrorHandler overrides.
122*3f982cf4SFabien Sanglard   void OnClose(CastSocket* socket) final;
123*3f982cf4SFabien Sanglard   void OnError(CastSocket* socket, Error error) final;
124*3f982cf4SFabien Sanglard 
125*3f982cf4SFabien Sanglard   // OnMessage() delegates to these to take action for each |request|. Each of
126*3f982cf4SFabien Sanglard   // these returns a non-empty response message if a reply should be sent back
127*3f982cf4SFabien Sanglard   // to the requestor.
128*3f982cf4SFabien Sanglard   Json::Value HandlePing();
129*3f982cf4SFabien Sanglard   Json::Value HandleGetAppAvailability(const Json::Value& request);
130*3f982cf4SFabien Sanglard   Json::Value HandleGetStatus(const Json::Value& request);
131*3f982cf4SFabien Sanglard   Json::Value HandleLaunch(const Json::Value& request, CastSocket* socket);
132*3f982cf4SFabien Sanglard   Json::Value HandleStop(const Json::Value& request);
133*3f982cf4SFabien Sanglard   Json::Value HandleInvalidCommand(const Json::Value& request);
134*3f982cf4SFabien Sanglard 
135*3f982cf4SFabien Sanglard   // Stops the currently-running Application and attempts to launch the
136*3f982cf4SFabien Sanglard   // Application referred to by |app_id|. If this fails, the "idle screen"
137*3f982cf4SFabien Sanglard   // Application will be automatically launched as a failure fall-back. |socket|
138*3f982cf4SFabien Sanglard   // is non-null only when the application switch was caused by a remote LAUNCH
139*3f982cf4SFabien Sanglard   // request.
140*3f982cf4SFabien Sanglard   Error SwitchToApplication(std::string app_id,
141*3f982cf4SFabien Sanglard                             const Json::Value& app_params,
142*3f982cf4SFabien Sanglard                             CastSocket* socket);
143*3f982cf4SFabien Sanglard 
144*3f982cf4SFabien Sanglard   // Stops the currently-running Application and launches the "idle screen."
145*3f982cf4SFabien Sanglard   void GoIdle();
146*3f982cf4SFabien Sanglard 
147*3f982cf4SFabien Sanglard   // Populates the given |message| object with the RECEIVER_STATUS fields,
148*3f982cf4SFabien Sanglard   // reflecting the currently-launched app (if any), and a fake volume level
149*3f982cf4SFabien Sanglard   // status.
150*3f982cf4SFabien Sanglard   void PopulateReceiverStatus(Json::Value* message);
151*3f982cf4SFabien Sanglard 
152*3f982cf4SFabien Sanglard   // Broadcasts new RECEIVER_STATUS to all endpoints. This is called after an
153*3f982cf4SFabien Sanglard   // Application LAUNCH or STOP.
154*3f982cf4SFabien Sanglard   void BroadcastReceiverStatus();
155*3f982cf4SFabien Sanglard 
156*3f982cf4SFabien Sanglard   TaskRunner* const task_runner_;
157*3f982cf4SFabien Sanglard   DeviceAuthNamespaceHandler auth_handler_;
158*3f982cf4SFabien Sanglard   VirtualConnectionRouter router_;
159*3f982cf4SFabien Sanglard   ConnectionNamespaceHandler connection_handler_;
160*3f982cf4SFabien Sanglard 
161*3f982cf4SFabien Sanglard   std::map<std::string, Application*> registered_applications_;
162*3f982cf4SFabien Sanglard   Application* idle_screen_app_ = nullptr;
163*3f982cf4SFabien Sanglard 
164*3f982cf4SFabien Sanglard   CastSocketMessagePort message_port_;
165*3f982cf4SFabien Sanglard   Application* launched_app_ = nullptr;
166*3f982cf4SFabien Sanglard   std::string launched_via_app_id_;
167*3f982cf4SFabien Sanglard };
168*3f982cf4SFabien Sanglard 
169*3f982cf4SFabien Sanglard }  // namespace cast
170*3f982cf4SFabien Sanglard }  // namespace openscreen
171*3f982cf4SFabien Sanglard 
172*3f982cf4SFabien Sanglard #endif  // CAST_RECEIVER_APPLICATION_AGENT_H_
173