• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
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 
18 package com.android.browser;
19 
20 import android.content.Context;
21 import android.content.SharedPreferences;
22 import android.content.SharedPreferences.Editor;
23 import android.database.Cursor;
24 import android.os.AsyncTask;
25 import android.os.Message;
26 import android.preference.PreferenceManager;
27 import android.webkit.WebSettings.AutoFillProfile;
28 
29 import java.util.concurrent.CountDownLatch;
30 
31 public 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 
41     private CountDownLatch mLoaded = new CountDownLatch(1);
42     private Context mContext;
43 
AutofillHandler(Context context)44     public AutofillHandler(Context context) {
45         mContext = context.getApplicationContext();
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      */
asyncLoadFromDb()54     public void asyncLoadFromDb() {
55         // 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().
60          new LoadFromDb().start();
61     }
62 
waitForLoad()63     public void waitForLoad() {
64         try {
65             mLoaded.await();
66         } catch (InterruptedException e) {}
67     }
68 
69     private class LoadFromDb extends Thread {
70 
71         @Override
run()72         public void run() {
73             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 
117             mLoaded.countDown();
118         }
119     }
120 
setAutoFillProfile(AutoFillProfile profile, Message msg)121     public void setAutoFillProfile(AutoFillProfile profile, Message msg) {
122         int profileId = NO_AUTOFILL_PROFILE_SET;
123         if (profile != null) {
124             profileId = profile.getUniqueId();
125             // 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());
131             }
132         }
133         // 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
136         mAutoFillProfile = profile;
137         setActiveAutoFillProfileId(profileId);
138     }
139 
getAutoFillProfile()140     public AutoFillProfile getAutoFillProfile() {
141         return mAutoFillProfile;
142     }
143 
setActiveAutoFillProfileId(int activeProfileId)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 
AutoFillProfileDbTask(Message msg)156         public AutoFillProfileDbTask(Message msg) {
157             mCompleteMessage = msg;
158         }
159 
160         @Override
onPostExecute(Void result)161         protected void onPostExecute(Void result) {
162             if (mCompleteMessage != null) {
163                 mCompleteMessage.sendToTarget();
164             }
165             mAutoFillProfileDb.close();
166         }
167 
168         @Override
doInBackground(T... values)169         abstract protected Void doInBackground(T... values);
170     }
171 
172 
173     private class SaveProfileToDbTask extends AutoFillProfileDbTask<AutoFillProfile> {
SaveProfileToDbTask(Message msg)174         public SaveProfileToDbTask(Message msg) {
175             super(msg);
176         }
177 
178         @Override
doInBackground(AutoFillProfile... values)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> {
DeleteProfileFromDbTask(Message msg)189         public DeleteProfileFromDbTask(Message msg) {
190             super(msg);
191         }
192 
193         @Override
doInBackground(Integer... values)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 }
203