Home | History | Annotate | Download | only in browser
      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 
     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      */
     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 
     63     public void waitForLoad() {
     64         try {
     65             mLoaded.await();
     66         } catch (InterruptedException e) {}
     67     }
     68 
     69     private class LoadFromDb extends Thread {
     70 
     71         @Override
     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 
    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 
    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 }
    203