- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / common / extensions / docs / examples / api / nativeMessaging / host / native-messaging-example-host
1 #!/usr/bin/env python
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
5
6 # A simple native messaging host. Shows a Tkinter dialog with incoming messages
7 # that also allows to send message back to the webapp.
8
9 import struct
10 import sys
11 import threading
12 import Queue
13
14 try:
15   import Tkinter
16   import tkMessageBox
17 except ImportError:
18   Tkinter = None
19
20 # Helper function that sends a message to the webapp.
21 def send_message(message):
22    # Write message size.
23   sys.stdout.write(struct.pack('I', len(message)))
24   # Write the message itself.
25   sys.stdout.write(message)
26   sys.stdout.flush()
27
28 # Thread that reads messages from the webapp.
29 def read_thread_func(queue):
30   message_number = 0
31   while 1:
32     # Read the message type (first 4 bytes).
33     text_length_bytes = sys.stdin.read(4)
34
35     if len(text_length_bytes) == 0:
36       if queue:
37         queue.put(None)
38       sys.exit(0)
39
40     # Read the message length (4 bytes).
41     text_length = struct.unpack('i', text_length_bytes)[0]
42
43     # Read the text (JSON object) of the message.
44     text = sys.stdin.read(text_length).decode('utf-8')
45
46     if queue:
47       queue.put(text)
48     else:
49       # In headless mode just send an echo message back.
50       send_message('{"echo": %s}' % text)
51
52 if Tkinter:
53   class NativeMessagingWindow(Tkinter.Frame):
54     def __init__(self, queue):
55       self.queue = queue
56
57       Tkinter.Frame.__init__(self)
58       self.pack()
59
60       self.text = Tkinter.Text(self)
61       self.text.grid(row=0, column=0, padx=10, pady=10, columnspan=2)
62       self.text.config(state=Tkinter.DISABLED, height=10, width=40)
63
64       self.messageContent = Tkinter.StringVar()
65       self.sendEntry = Tkinter.Entry(self, textvariable=self.messageContent)
66       self.sendEntry.grid(row=1, column=0, padx=10, pady=10)
67
68       self.sendButton = Tkinter.Button(self, text="Send", command=self.onSend)
69       self.sendButton.grid(row=1, column=1, padx=10, pady=10)
70
71       self.after(100, self.processMessages)
72
73     def processMessages(self):
74       while not self.queue.empty():
75         message = self.queue.get_nowait()
76         if message == None:
77           self.quit()
78           return
79         self.log("Received %s" % message)
80
81       self.after(100, self.processMessages)
82
83     def onSend(self):
84       text = '{"text": "' + self.messageContent.get() + '"}'
85       self.log('Sending %s' % text)
86       try:
87         send_message(text)
88       except IOError:
89         tkMessageBox.showinfo('Native Messaging Example',
90                               'Failed to send message.')
91         sys.exit(1)
92
93     def log(self, message):
94       self.text.config(state=Tkinter.NORMAL)
95       self.text.insert(Tkinter.END, message + "\n")
96       self.text.config(state=Tkinter.DISABLED)
97
98
99 def Main():
100   if not Tkinter:
101     send_message('"Tkinter python module wasn\'t found. Running in headless ' +
102                  'mode. Please consider installing Tkinter."')
103     read_thread_func(None)
104     sys.exit(0)
105
106   queue = Queue.Queue()
107
108   main_window = NativeMessagingWindow(queue)
109   main_window.master.title('Native Messaging Example')
110
111   thread = threading.Thread(target=read_thread_func, args=(queue,))
112   thread.daemon = True
113   thread.start()
114
115   main_window.mainloop()
116
117   sys.exit(0)
118
119
120 if __name__ == '__main__':
121   Main()