1b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet#!/usr/bin/env python
2b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet#
3b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet# Copyright (C) 2008 The Android Open Source Project
4b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet#
5b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet# Licensed under the Apache License, Version 2.0 (the "License");
6b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet# you may not use this file except in compliance with the License.
7b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet# You may obtain a copy of the License at
8b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet#
9b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet#      http://www.apache.org/licenses/LICENSE-2.0
10b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet#
11b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet# Unless required by applicable law or agreed to in writing, software
12b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet# distributed under the License is distributed on an "AS IS" BASIS,
13b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet# See the License for the specific language governing permissions and
15b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet# limitations under the License.
16b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet
17b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet"""
18b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier DucrohetA faux Setup Wizard.  Stuffs one or two usernames + passwords into the
19b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohetdatabase on the device.
20b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet"""
21b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet
22b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohetimport sys
23b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohetif sys.hexversion < 0x02040000:
24b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet  print "This script requires python 2.4 or higher."
25b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet  sys.exit(1)
26b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet
27b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohetimport getpass
28b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohetimport subprocess
29b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohetimport time
30b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohetimport sha
31b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet
32b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier DucrohetDB = "/data/data/com.google.android.googleapps/databases/accounts.db"
33b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet
34b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohetdef RunCmd(args):
35b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet  proc = subprocess.Popen(args, stdout=subprocess.PIPE)
36b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet  out = proc.stdout.read()
37b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet  if proc.wait():
38b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet    print
39b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet    print "failed: %s" % " ".join(args)
40b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet    return None
41b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet  return out
42b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet
43b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohetdef GetProp(adb_flags, name):
44b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet  args = ("adb",) + adb_flags + ("shell", "su", "root",
45b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet                                 "/system/bin/getprop", name)
46b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet  return RunCmd(args)
47b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet
48b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohetdef SetProp(adb_flags, name, value):
49b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet  args = ("adb",) + adb_flags + ("shell", "su", "root",
50b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet                                 "/system/bin/setprop", name, value)
51b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet  return RunCmd(args)
52b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet
53b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohetdef DbExists(adb_flags):
54b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet  args = ("adb",) + adb_flags + ("shell", "su", "root",
55b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet                                 "/system/bin/ls", DB)
56b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet  result = RunCmd(args)
57b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet  if result is None: return None
58b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet  return "No such file" not in result
59b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet
60b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohetdef main(argv):
61b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet  if len(argv) == 1:
62b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet    print ("usage: %s [adb flags] "
63b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet           "[<dasher address[:password]>] "
64b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet           "[<gmail address[:password]>]") % (argv[0],)
65b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet    sys.exit(2)
66b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet
67b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet  argv = argv[1:]
68b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet
69b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet  gmail = None
70b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet  dasher = None
71b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet  while argv and "@" in argv[-1]:
72b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet    addr = argv.pop()
73b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet    if "@gmail.com" in addr or "@googlemail.com" in addr:
74b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet      gmail = addr
75b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet    else:
76b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet      dasher = addr
77b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet
78b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet  adb_flags = tuple(argv)
79b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet
80b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet  while True:
81b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet    db = DbExists(adb_flags)
82b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet    if db is None:
83b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet      print "failed to contact device; will retry in 3 seconds"
84b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet      time.sleep(3)
85b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet      continue
86b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet
87b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet    if db:
88b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet      print
89b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet      print "GoogleLoginService has already started on this device;"
90b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet      print "it's too late to use this script to add accounts."
91b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet      print
92b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet      print "This script only works on a freshly-wiped device (or "
93b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet      print "emulator) while booting for the first time."
94b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet      print
95b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet      break
96b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet
97b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet    hosted_account = GetProp(adb_flags, "ro.config.hosted_account").strip()
98b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet    google_account = GetProp(adb_flags, "ro.config.google_account").strip()
99b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet
100b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet    if dasher and hosted_account:
101b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet      print
102b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet      print "A dasher account is already configured on this device;"
103b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet      print "can't add", hosted_account
104b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet      print
105b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet      dasher = None
106b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet
107b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet    if gmail and google_account:
108b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet      print
109b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet      print "A google account is already configured on this device;"
110b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet      print "can't add", google_account
111b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet      print
112b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet      gmail = None
113b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet
114b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet    if not gmail and not dasher: break
115b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet
116b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet    if dasher:
117b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet      SetProp(adb_flags, "ro.config.hosted_account", dasher)
118b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet      print "set hosted_account to", dasher
119b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet    if gmail:
120b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet      SetProp(adb_flags, "ro.config.google_account", gmail)
121b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet      print "set google_account to", gmail
122b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet
123b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet    break
124b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet
125b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet
126b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet
127b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet
128b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet
129b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet
130b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohetif __name__ == "__main__":
131b958224f51c06e6b778a00ccee3366c8e26a8f0aXavier Ducrohet  main(sys.argv)
132