blob: b0d5dac600ca11bb5e9f0458fb5d43417321ae8b [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
29public class AutofillHandler {
30
31 private AutoFillProfile mAutoFillProfile;
32 // Default to zero. In the case no profile is set up, the initial
33 // value will come from the AutoFillSettingsFragment when the user
34 // creates a profile. Otherwise, we'll read the ID of the last used
35 // profile from the prefs db.
36 private int mAutoFillActiveProfileId;
37 private static final int NO_AUTOFILL_PROFILE_SET = 0;
38
39 private boolean mLoadFromDbComplete;
40 private Context mContext;
41
42 public AutofillHandler(Context context) {
43 mContext = context;
44 }
45
46 /**
47 * Load settings from the browser app's database. It is performed in
48 * an AsyncTask as it involves plenty of slow disk IO.
49 * NOTE: Strings used for the preferences must match those specified
50 * in the various preference XML files.
51 */
52 public void asyncLoadFromDb() {
53 synchronized (this) {
54 mLoadFromDbComplete = false;
55 }
56 // Run the initial settings load in an AsyncTask as it hits the
57 // disk multiple times through SharedPreferences and SQLite. We
58 // need to be certain though that this has completed before we start
59 // to load pages though, so in the worst case we will block waiting
60 // for it to finish in BrowserActivity.onCreate().
61 new LoadFromDbTask().execute();
62 }
63
64 public void waitForLoad() {
65 synchronized (this) {
66 while (!mLoadFromDbComplete) {
67 try {
68 wait();
69 } catch (InterruptedException e) {}
70 }
71 }
72 }
73
74 private class LoadFromDbTask extends AsyncTask<Void, Void, Void> {
75
76 @Override
77 protected Void doInBackground(Void... unused) {
78 SharedPreferences p =
79 PreferenceManager.getDefaultSharedPreferences(mContext);
80
81 // Read the last active AutoFill profile id.
82 mAutoFillActiveProfileId = p.getInt(
83 PreferenceKeys.PREF_AUTOFILL_ACTIVE_PROFILE_ID,
84 mAutoFillActiveProfileId);
85
86 // Load the autofill profile data from the database. We use a database separate
87 // to the browser preference DB to make it easier to support multiple profiles
88 // and switching between them.
89 AutoFillProfileDatabase autoFillDb = AutoFillProfileDatabase.getInstance(mContext);
90 Cursor c = autoFillDb.getProfile(mAutoFillActiveProfileId);
91
92 if (c.getCount() > 0) {
93 c.moveToFirst();
94
95 String fullName = c.getString(c.getColumnIndex(
96 AutoFillProfileDatabase.Profiles.FULL_NAME));
97 String email = c.getString(c.getColumnIndex(
98 AutoFillProfileDatabase.Profiles.EMAIL_ADDRESS));
99 String company = c.getString(c.getColumnIndex(
100 AutoFillProfileDatabase.Profiles.COMPANY_NAME));
101 String addressLine1 = c.getString(c.getColumnIndex(
102 AutoFillProfileDatabase.Profiles.ADDRESS_LINE_1));
103 String addressLine2 = c.getString(c.getColumnIndex(
104 AutoFillProfileDatabase.Profiles.ADDRESS_LINE_2));
105 String city = c.getString(c.getColumnIndex(
106 AutoFillProfileDatabase.Profiles.CITY));
107 String state = c.getString(c.getColumnIndex(
108 AutoFillProfileDatabase.Profiles.STATE));
109 String zip = c.getString(c.getColumnIndex(
110 AutoFillProfileDatabase.Profiles.ZIP_CODE));
111 String country = c.getString(c.getColumnIndex(
112 AutoFillProfileDatabase.Profiles.COUNTRY));
113 String phone = c.getString(c.getColumnIndex(
114 AutoFillProfileDatabase.Profiles.PHONE_NUMBER));
115 mAutoFillProfile = new AutoFillProfile(mAutoFillActiveProfileId,
116 fullName, email, company, addressLine1, addressLine2, city,
117 state, zip, country, phone);
118 }
119 c.close();
120 autoFillDb.close();
121
122 synchronized (this) {
123 mLoadFromDbComplete = true;
124 notifyAll();
125 }
126 return null;
127 }
128 }
129
130 public void setAutoFillProfile(AutoFillProfile profile, Message msg) {
131 if (profile != null) {
132 setActiveAutoFillProfileId(profile.getUniqueId());
133 // Update the AutoFill DB with the new profile.
134 new SaveProfileToDbTask(msg).execute(profile);
135 } else {
136 // Delete the current profile.
137 if (mAutoFillProfile != null) {
138 new DeleteProfileFromDbTask(msg).execute(mAutoFillProfile.getUniqueId());
139 setActiveAutoFillProfileId(NO_AUTOFILL_PROFILE_SET);
140 }
141 }
142 mAutoFillProfile = profile;
143 }
144
145 public AutoFillProfile getAutoFillProfile() {
146 return mAutoFillProfile;
147 }
148
149 private void setActiveAutoFillProfileId(int activeProfileId) {
150 mAutoFillActiveProfileId = activeProfileId;
151 Editor ed = PreferenceManager.
152 getDefaultSharedPreferences(mContext).edit();
153 ed.putInt(PreferenceKeys.PREF_AUTOFILL_ACTIVE_PROFILE_ID, activeProfileId);
154 ed.apply();
155 }
156
157 private abstract class AutoFillProfileDbTask<T> extends AsyncTask<T, Void, Void> {
158 AutoFillProfileDatabase mAutoFillProfileDb;
159 Message mCompleteMessage;
160
161 public AutoFillProfileDbTask(Message msg) {
162 mCompleteMessage = msg;
163 }
164
165 @Override
166 protected void onPostExecute(Void result) {
167 if (mCompleteMessage != null) {
168 mCompleteMessage.sendToTarget();
169 }
170 mAutoFillProfileDb.close();
171 }
172
173 @Override
174 abstract protected Void doInBackground(T... values);
175 }
176
177
178 private class SaveProfileToDbTask extends AutoFillProfileDbTask<AutoFillProfile> {
179 public SaveProfileToDbTask(Message msg) {
180 super(msg);
181 }
182
183 @Override
184 protected Void doInBackground(AutoFillProfile... values) {
185 mAutoFillProfileDb = AutoFillProfileDatabase.getInstance(mContext);
186 assert mAutoFillActiveProfileId != NO_AUTOFILL_PROFILE_SET;
187 AutoFillProfile newProfile = values[0];
188 mAutoFillProfileDb.addOrUpdateProfile(mAutoFillActiveProfileId, newProfile);
189 return null;
190 }
191 }
192
193 private class DeleteProfileFromDbTask extends AutoFillProfileDbTask<Integer> {
194 public DeleteProfileFromDbTask(Message msg) {
195 super(msg);
196 }
197
198 @Override
199 protected Void doInBackground(Integer... values) {
200 mAutoFillProfileDb = AutoFillProfileDatabase.getInstance(mContext);
201 int id = values[0];
202 assert id > 0;
203 mAutoFillProfileDb.dropProfile(id);
204 return null;
205 }
206 }
207}