summaryrefslogtreecommitdiffstats
path: root/chrome_frame/cfproxy_private.h
blob: a9cc6dcd35e2c1537ad135b12e7d578b66a3a38c (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
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
// Copyright (c) 2010 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 CHROME_FRAME_CFPROXY_PRIVATE_H_
#define CHROME_FRAME_CFPROXY_PRIVATE_H_
#pragma once

#include <map>
#include <set>
#include <string>
#include <vector>
#include "chrome_frame/cfproxy.h"
#include "base/thread.h"
// Since we can't forward declare IPC::Message::Sender or IPC::Channel::Listener
#include "ipc/ipc_message.h"
#include "ipc/ipc_channel.h"

typedef std::map<int, ChromeProxyDelegate*> TabsMap;

// This is the functions needed by CFProxy implementation.
// Extracted in separate class so we can mock it.
class CFProxyTraits {
 public:
  virtual IPC::Message::Sender* CreateChannel(const std::string& id,
                                              IPC::Channel::Listener* l);
  virtual void CloseChannel(IPC::Message::Sender* s);
  virtual bool LaunchApp(const std::wstring& cmd_line);
};

// Holds a queue of sent synchronous IPC messages. Knows how to dispatch
// the replies.
class SyncMsgSender {
 public:
  explicit SyncMsgSender(TabsMap* tab2delegate);
  void QueueSyncMessage(const IPC::SyncMessage* msg,
                        ChromeProxyDelegate* delegate, SyncMessageContext* ctx);
  bool OnReplyReceived(const IPC::Message* reply_msg);
  void OnChannelClosed();
  void Cancel(ChromeProxyDelegate* delegate);
 private:
  // sync_message_id -> (message_type, delegate, context)
  struct SingleSentMessage {
    SingleSentMessage() : type_(0), ctx_(NULL), delegate_(NULL) {}
    SingleSentMessage(uint32 type,
                      ChromeProxyDelegate* delegate,
                      SyncMessageContext* ctx)
        : type_(type), ctx_(ctx), delegate_(delegate) {}
    ~SingleSentMessage() { delete ctx_; }
    uint32 type_;
    SyncMessageContext* ctx_;
    ChromeProxyDelegate* delegate_;
  };

  SingleSentMessage* RemoveMessage(int id);
  typedef std::map<int, SingleSentMessage*> SentMessages;
  SentMessages messages_;
  Lock messages_lock_;
  TabsMap* tab2delegate_;
};

// Converts method call to an IPC message and then send it over Message::Sender
class Interface2IPCMessage : public ChromeProxy {
 public:
  Interface2IPCMessage() {}

  // General
  virtual void RemoveBrowsingData(int mask);
  virtual void SetProxyConfig(const std::string& json_encoded_proxy_cfg);
  // Tab related.
  virtual void Tab_PostMessage(int tab, const std::string& message,
      const std::string& origin, const std::string& target);
  virtual void Tab_Reload(int tab);
  virtual void Tab_Stop(int tab);
  virtual void Tab_SaveAs(int tab);
  virtual void Tab_Print(int tab);
  virtual void Tab_Cut(int tab);
  virtual void Tab_Copy(int tab);
  virtual void Tab_Paste(int tab);
  virtual void Tab_SelectAll(int tab);
  virtual void Tab_MenuCommand(int tab, int selected_command);
  virtual void Tab_Zoom(int tab, PageZoom::Function zoom_level);
  virtual void Tab_FontSize(int tab, enum AutomationPageFontSize font_size);
  virtual void Tab_SetInitialFocus(int tab, bool reverse,
                                   bool restore_focus_to_view);
  virtual void Tab_SetParentWindow(int tab);
  virtual void Tab_Resize(int tab);
  virtual void Tab_ProcessAccelerator(int tab, const MSG& msg);

  // Misc.
  virtual void Tab_OnHostMoved(int tab);
  virtual void Tab_SetEnableExtensionAutomation(int tab,
      const std::vector<std::string>& functions_enabled);
 protected:
  ~Interface2IPCMessage() {}
 private:
  IPC::Message::Sender* sender_;
};

// Simple class to keep a list of pointers to ChromeProxyDelegate for a
// specific proxy as well as mapping between tab_id -> ChromeProxyDelegate.
class DelegateHolder {
 protected:
  DelegateHolder() {
  }

  void AddDelegate(ChromeProxyDelegate* p);
  void RemoveDelegate(ChromeProxyDelegate* p);
  // Helper
  ChromeProxyDelegate* Tab2Delegate(int tab_handle);
  TabsMap tab2delegate_;
  typedef std::set<ChromeProxyDelegate*> DelegateList;
  DelegateList delegate_list_;
};

// ChromeFrame Automation Proxy implementation.
class CFProxy : public Interface2IPCMessage,
                public IPC::Channel::Listener,
                public DelegateHolder {
 public:
  explicit CFProxy(CFProxyTraits* api);
  ~CFProxy();

 private:
  virtual void Init(const ProxyParams& params);
  virtual int AddDelegate(ChromeProxyDelegate* p);
  virtual int RemoveDelegate(ChromeProxyDelegate* p);

  // Executed in IPC thread.
  void AddDelegateOnIoThread(ChromeProxyDelegate* p);
  void RemoveDelegateOnIoThread(ChromeProxyDelegate* p);
  // Initialization that has to be mede in IPC thread.
  void InitInIoThread(const ProxyParams& params);
  // Cleanup that has to be made in IPC thread.
  void CleanupOnIoThread();
  // IPC connection was not established in timely manner
  void LaunchTimeOut();
  // Close channel, inform delegates.
  void OnPeerLost(ChromeProxyDelegate::DisconnectReason reason);
  // Queues message to be send in IPC thread.
  void SendIpcMessage(IPC::Message* m);
  // Same but in IPC thread.
  void SendIpcMessageOnIoThread(IPC::Message* m);

  //////////////////////////////////////////////////////////////////////////
  // Sync messages.
  virtual void InstallExtension(ChromeProxyDelegate* delegate,
      const FilePath& crx_path, SyncMessageContext* ctx);
  virtual void LoadExtension(ChromeProxyDelegate* delegate,
                             const FilePath& path, SyncMessageContext* ctx);
  virtual void GetEnabledExtensions(ChromeProxyDelegate* delegate,
                                    SyncMessageContext* ctx);
  virtual void Tab_Find(int tab, const string16& search_string,
      FindInPageDirection forward, FindInPageCase match_case, bool find_next);
  virtual void Tab_OverrideEncoding(int tab, const char* encoding);
  virtual void Tab_Navigate(int tab, const GURL& url, const GURL& referrer);
  virtual void CreateTab(ChromeProxyDelegate* delegate,
                         const IPC::ExternalTabSettings& p);
  virtual void ConnectTab(ChromeProxyDelegate* delegate, HWND hwnd,
                          uint64 cookie);
  virtual void BlockTab(uint64 cookie);
  virtual void Tab_RunUnloadHandlers(int tab);

  //////////////////////////////////////////////////////////////////////////
  // IPC::Channel::Listener
  virtual void OnMessageReceived(const IPC::Message& message);
  virtual void OnChannelConnected(int32 peer_pid);
  virtual void OnChannelError();

  bool CalledOnIpcThread() const {
    return PlatformThread::CurrentId() == ipc_thread_.thread_id();
  }

  base::Thread ipc_thread_;
  SyncMsgSender sync_dispatcher_;
  IPC::Message::Sender* ipc_sender_;
  CFProxyTraits* api_;
  int delegate_count_;
  bool is_connected_;
};

DISABLE_RUNNABLE_METHOD_REFCOUNT(CFProxy);

// Support functions.
std::string GenerateChannelId();
int IsTabMessage(const IPC::Message& message);
bool DispatchTabMessageToDelegate(ChromeProxyDelegate* delegate,
                                  const IPC::Message& m);
std::wstring BuildCmdLine(const std::string& channel_id,
                          const FilePath& profile_path,
                          const std::wstring& extra_args);
#endif  // CHROME_FRAME_CFPROXY_PRIVATE_H_