• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python
2# Copyright 2013 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# Interactive test script for the Chromoting host native messaging component.
7
8import json
9import readline
10import struct
11import subprocess
12import sys
13
14
15def PrintMenuAndGetBuilder(messages):
16  print
17  for i in range(0, len(messages)):
18    print '%d: %s' % (i + 1, messages[i][0])
19  print 'Q: Quit'
20  while True:
21    choice = raw_input('Enter choice: ')
22    if choice.lower() == 'q':
23      return None
24    choice = int(choice)
25    if choice >= 1 and choice <= len(messages):
26      return messages[choice - 1][1]
27
28
29# Message builder methods.
30def BuildHello():
31  return {'type': 'hello'}
32
33
34def BuildClearAllPairedClients():
35  return {'type': 'clearPairedClients'}
36
37
38def BuildDeletePairedClient():
39  client_id = raw_input('Enter client id: ')
40  return {'type': 'deletePairedClient',
41          'clientId': client_id}
42
43
44def BuildGetHostName():
45  return {'type': 'getHostName'}
46
47
48def BuildGetPinHash():
49  host_id = raw_input('Enter host id: ')
50  pin = raw_input('Enter PIN: ')
51  return {'type': 'getPinHash',
52          'hostId': host_id,
53          'pin': pin}
54
55
56def BuildGenerateKeyPair():
57  return {'type': 'generateKeyPair'}
58
59
60def BuildUpdateDaemonConfig():
61  config_json = raw_input('Enter config JSON: ')
62  return {'type': 'updateDaemonConfig',
63          'config': config_json}
64
65
66def BuildGetDaemonConfig():
67  return {'type': 'getDaemonConfig'}
68
69
70def BuildGetPairedClients():
71  return {'type': 'getPairedClients'}
72
73
74def BuildGetUsageStatsConsent():
75  return {'type': 'getUsageStatsConsent'}
76
77
78def BuildStartDaemon():
79  while True:
80    consent = raw_input('Report usage stats [y/n]? ')
81    if consent.lower() == 'y':
82      consent = True
83    elif consent.lower() == 'n':
84      consent = False
85    else:
86      continue
87    break
88  config_json = raw_input('Enter config JSON: ')
89  return {'type': 'startDaemon',
90          'consent': consent,
91          'config': config_json}
92
93
94def BuildStopDaemon():
95  return {'type': 'stopDaemon'}
96
97
98def BuildGetDaemonState():
99  return {'type': 'getDaemonState'}
100
101
102def main():
103  if len(sys.argv) != 2:
104    print 'Usage: ' + sys.argv[0] + ' <path to native messaging host>'
105    sys.exit(1)
106
107  native_messaging_host = sys.argv[1]
108
109  child = subprocess.Popen(native_messaging_host, stdin=subprocess.PIPE,
110                           stdout=subprocess.PIPE, close_fds=True)
111
112  message_id = 0
113  while True:
114    messages = [
115      ('Hello', BuildHello),
116      ('Clear all paired clients', BuildClearAllPairedClients),
117      ('Delete paired client', BuildDeletePairedClient),
118      ('Get host name', BuildGetHostName),
119      ('Get PIN hash', BuildGetPinHash),
120      ('Generate key pair', BuildGenerateKeyPair),
121      ('Update daemon config', BuildUpdateDaemonConfig),
122      ('Get daemon config', BuildGetDaemonConfig),
123      ('Get paired clients', BuildGetPairedClients),
124      ('Get usage stats consent', BuildGetUsageStatsConsent),
125      ('Start daemon', BuildStartDaemon),
126      ('Stop daemon', BuildStopDaemon),
127      ('Get daemon state', BuildGetDaemonState)
128    ]
129    builder = PrintMenuAndGetBuilder(messages)
130    if not builder:
131      break
132    message_dict = builder()
133    message_dict['id'] = message_id
134    message = json.dumps(message_dict)
135    message_id += 1
136    print 'Message: ' + message
137    child.stdin.write(struct.pack('I', len(message)))
138    child.stdin.write(message)
139    child.stdin.flush()
140
141    reply_length_bytes = child.stdout.read(4)
142    if len(reply_length_bytes) < 4:
143      print 'Invalid message length'
144      break
145    reply_length = struct.unpack('i', reply_length_bytes)[0]
146    reply = child.stdout.read(reply_length).decode('utf-8')
147    print 'Reply: ' + reply
148    if len(reply) != reply_length:
149      print 'Invalid reply length'
150      break
151
152if __name__ == '__main__':
153  main()
154