blob: b6b237d9521b20432adbe6fbd8c8b4d57c329253 [file] [log] [blame]
John Reck35e9dd62011-04-25 09:01:54 -07001
2/*
3 * Copyright (C) 2011 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18package com.android.browser;
19
20import android.content.Context;
21import android.content.SharedPreferences;
22import android.content.SharedPreferences.Editor;
23import android.database.Cursor;
24import android.os.AsyncTask;
25import android.os.Message;
26import android.preference.PreferenceManager;
27import android.webkit.WebSettings.AutoFillProfile;
28
John Reck7b06c902011-04-26 13:48:09 -070029import java.util.concurrent.CountDownLatch;
30
John Reck35e9dd62011-04-25 09:01:54 -070031public class AutofillHandler {
32
33 private AutoFillProfile mAutoFillProfile;
34 // Default to zero. In the case no profile is set up, the initial
35 // value will come from the AutoFillSettingsFragment when the user
36 // creates a profile. Otherwise, we'll read the ID of the last used
37 // profile from the prefs db.
38 private int mAutoFillActiveProfileId;
39 private static final int NO_AUTOFILL_PROFILE_SET = 0;
40
John Reck7b06c902011-04-26 13:48:09 -070041 private CountDownLatch mLoaded = new CountDownLatch(1);
John Reck35e9dd62011-04-25 09:01:54 -070042 private Context mContext;
43
44 public AutofillHandler(Context context) {
45 mContext = context;
46 }
47
48 /**
49 * Load settings from the browser app's database. It is performed in
50 * an AsyncTask as it involves plenty of slow disk IO.
51 * NOTE: Strings used for the preferences must match those specified
52 * in the various preference XML files.
53 */
54 public void asyncLoadFromDb() {
John Reck35e9dd62011-04-25 09:01:54 -070055 // Run the initial settings load in an AsyncTask as it hits the
56 // disk multiple times through SharedPreferences and SQLite. We
57 // need to be certain though that this has completed before we start
58 // to load pages though, so in the worst case we will block waiting
59 // for it to finish in BrowserActivity.onCreate().
John Reck7b06c902011-04-26 13:48:09 -070060 new LoadFromDb().start();
John Reck35e9dd62011-04-25 09:01:54 -070061 }
62
63 public void waitForLoad() {
John Reck7b06c902011-04-26 13:48:09 -070064 try {
65 mLoaded.await();
66 } catch (InterruptedException e) {}
John Reck35e9dd62011-04-25 09:01:54 -070067 }
68
John Reck7b06c902011-04-26 13:48:09 -070069 private class LoadFromDb extends Thread {
John Reck35e9dd62011-04-25 09:01:54 -070070
71 @Override
John Reck7b06c902011-04-26 13:48:09 -070072 public void run() {
John Reck35e9dd62011-04-25 09:01:54 -070073 SharedPreferences p =
74 PreferenceManager.getDefaultSharedPreferences(mContext);
75
76 // Read the last active AutoFill profile id.
77 mAutoFillActiveProfileId = p.getInt(
78 PreferenceKeys.PREF_AUTOFILL_ACTIVE_PROFILE_ID,
79 mAutoFillActiveProfileId);
80
81 // Load the autofill profile data from the database. We use a database separate
82 // to the browser preference DB to make it easier to support multiple profiles
83 // and switching between them.
84 AutoFillProfileDatabase autoFillDb = AutoFillProfileDatabase.getInstance(mContext);
85 Cursor c = autoFillDb.getProfile(mAutoFillActiveProfileId);
86
87 if (c.getCount() > 0) {
88 c.moveToFirst();
89
90 String fullName = c.getString(c.getColumnIndex(
91 AutoFillProfileDatabase.Profiles.FULL_NAME));
92 String email = c.getString(c.getColumnIndex(
93 AutoFillProfileDatabase.Profiles.EMAIL_ADDRESS));
94 String company = c.getString(c.getColumnIndex(
95 AutoFillProfileDatabase.Profiles.COMPANY_NAME));
96 String addressLine1 = c.getString(c.getColumnIndex(
97 AutoFillProfileDatabase.Profiles.ADDRESS_LINE_1));
98 String addressLine2 = c.getString(c.getColumnIndex(
99 AutoFillProfileDatabase.Profiles.ADDRESS_LINE_2));
100 String city = c.getString(c.getColumnIndex(
101 AutoFillProfileDatabase.Profiles.CITY));
102 String state = c.getString(c.getColumnIndex(
103 AutoFillProfileDatabase.Profiles.STATE));
104 String zip = c.getString(c.getColumnIndex(
105 AutoFillProfileDatabase.Profiles.ZIP_CODE));
106 String country = c.getString(c.getColumnIndex(
107 AutoFillProfileDatabase.Profiles.COUNTRY));
108 String phone = c.getString(c.getColumnIndex(
109 AutoFillProfileDatabase.Profiles.PHONE_NUMBER));
110 mAutoFillProfile = new AutoFillProfile(mAutoFillActiveProfileId,
111 fullName, email, company, addressLine1, addressLine2, city,
112 state, zip, country, phone);
113 }
114 c.close();
115 autoFillDb.close();
116
John Reck7b06c902011-04-26 13:48:09 -0700117 mLoaded.countDown();
John Reck35e9dd62011-04-25 09:01:54 -0700118 }
119 }
120
121 public void setAutoFillProfile(AutoFillProfile profile, Message msg) {
John Reck72d77522011-05-06 10:33:16 -0700122 int profileId = NO_AUTOFILL_PROFILE_SET;
John Reck35e9dd62011-04-25 09:01:54 -0700123 if (profile != null) {
John Reck72d77522011-05-06 10:33:16 -0700124 profileId = profile.getUniqueId();
John Reck35e9dd62011-04-25 09:01:54 -0700125 // Update the AutoFill DB with the new profile.
126 new SaveProfileToDbTask(msg).execute(profile);
127 } else {
128 // Delete the current profile.
129 if (mAutoFillProfile != null) {
130 new DeleteProfileFromDbTask(msg).execute(mAutoFillProfile.getUniqueId());
John Reck35e9dd62011-04-25 09:01:54 -0700131 }
132 }
John Reck72d77522011-05-06 10:33:16 -0700133 // Make sure we set mAutoFillProfile before calling setActiveAutoFillProfileId
134 // Calling setActiveAutoFillProfileId will trigger an update of WebViews
135 // which will expect a new profile to be set
John Reck35e9dd62011-04-25 09:01:54 -0700136 mAutoFillProfile = profile;
John Reck72d77522011-05-06 10:33:16 -0700137 setActiveAutoFillProfileId(profileId);
John Reck35e9dd62011-04-25 09:01:54 -0700138 }
139
140 public AutoFillProfile getAutoFillProfile() {
141 return mAutoFillProfile;
142 }
143
144 private void setActiveAutoFillProfileId(int activeProfileId) {
145 mAutoFillActiveProfileId = activeProfileId;
146 Editor ed = PreferenceManager.
147 getDefaultSharedPreferences(mContext).edit();
148 ed.putInt(PreferenceKeys.PREF_AUTOFILL_ACTIVE_PROFILE_ID, activeProfileId);
149 ed.apply();
150 }
151
152 private abstract class AutoFillProfileDbTask<T> extends AsyncTask<T, Void, Void> {
153 AutoFillProfileDatabase mAutoFillProfileDb;
154 Message mCompleteMessage;
155
156 public AutoFillProfileDbTask(Message msg) {
157 mCompleteMessage = msg;
158 }
159
160 @Override
161 protected void onPostExecute(Void result) {
162 if (mCompleteMessage != null) {
163 mCompleteMessage.sendToTarget();
164 }
165 mAutoFillProfileDb.close();
166 }
167
168 @Override
169 abstract protected Void doInBackground(T... values);
170 }
171
172
173 private class SaveProfileToDbTask extends AutoFillProfileDbTask<AutoFillProfile> {
174 public SaveProfileToDbTask(Message msg) {
175 super(msg);
176 }
177
178 @Override
179 protected Void doInBackground(AutoFillProfile... values) {
180 mAutoFillProfileDb = AutoFillProfileDatabase.getInstance(mContext);
181 assert mAutoFillActiveProfileId != NO_AUTOFILL_PROFILE_SET;
182 AutoFillProfile newProfile = values[0];
183 mAutoFillProfileDb.addOrUpdateProfile(mAutoFillActiveProfileId, newProfile);
184 return null;
185 }
186 }
187
188 private class DeleteProfileFromDbTask extends AutoFillProfileDbTask<Integer> {
189 public DeleteProfileFromDbTask(Message msg) {
190 super(msg);
191 }
192
193 @Override
194 protected Void doInBackground(Integer... values) {
195 mAutoFillProfileDb = AutoFillProfileDatabase.getInstance(mContext);
196 int id = values[0];
197 assert id > 0;
198 mAutoFillProfileDb.dropProfile(id);
199 return null;
200 }
201 }
202}