diff options
Diffstat (limited to 'src/com/android/swe/browser/AutofillHandler.java')
-rw-r--r-- | src/com/android/swe/browser/AutofillHandler.java | 245 |
1 files changed, 23 insertions, 222 deletions
diff --git a/src/com/android/swe/browser/AutofillHandler.java b/src/com/android/swe/browser/AutofillHandler.java index 5b0320da..15e8a327 100644 --- a/src/com/android/swe/browser/AutofillHandler.java +++ b/src/com/android/swe/browser/AutofillHandler.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package com.android.browser; +package com.android.swe.browser; import android.content.Context; import android.content.SharedPreferences; @@ -27,257 +27,58 @@ import android.os.Message; import android.preference.PreferenceManager; import android.provider.ContactsContract; import android.util.Log; -import android.webkit.WebSettingsClassic.AutoFillProfile; + import java.util.concurrent.CountDownLatch; +import org.codeaurora.swe.AutoFillProfile; + + public class AutofillHandler { - private AutoFillProfile mAutoFillProfile; + protected AutoFillProfile mAutoFillProfile = null; // Default to zero. In the case no profile is set up, the initial // value will come from the AutoFillSettingsFragment when the user // creates a profile. Otherwise, we'll read the ID of the last used // profile from the prefs db. - private int mAutoFillActiveProfileId; + protected String mAutoFillActiveProfileId = ""; private static final int NO_AUTOFILL_PROFILE_SET = 0; - - private CountDownLatch mLoaded = new CountDownLatch(1); private Context mContext; private static final String LOGTAG = "AutofillHandler"; public AutofillHandler(Context context) { mContext = context.getApplicationContext(); - } - - /** - * Load settings from the browser app's database. It is performed in - * an AsyncTask as it involves plenty of slow disk IO. - * NOTE: Strings used for the preferences must match those specified - * in the various preference XML files. - */ - public void asyncLoadFromDb() { - // Run the initial settings load in an AsyncTask as it hits the - // disk multiple times through SharedPreferences and SQLite. We - // need to be certain though that this has completed before we start - // to load pages though, so in the worst case we will block waiting - // for it to finish in BrowserActivity.onCreate(). - new LoadFromDb().start(); - } - - private void waitForLoad() { - try { - mLoaded.await(); - } catch (InterruptedException e) { - Log.w(LOGTAG, "Caught exception while waiting for AutofillProfile to load."); - } - } - - private class LoadFromDb extends Thread { - - @Override - public void run() { - // Note the lack of synchronization over mAutoFillActiveProfileId and - // mAutoFillProfile here. This is because we control all other access - // to these members through the public functions of this class, and they - // all wait for this thread via the mLoaded CountDownLatch. - - SharedPreferences p = PreferenceManager.getDefaultSharedPreferences(mContext); - - // Read the last active AutoFill profile id. - mAutoFillActiveProfileId = p.getInt( + SharedPreferences p = PreferenceManager.getDefaultSharedPreferences(mContext); + mAutoFillActiveProfileId = p.getString( PreferenceKeys.PREF_AUTOFILL_ACTIVE_PROFILE_ID, mAutoFillActiveProfileId); - - // Load the autofill profile data from the database. We use a database separate - // to the browser preference DB to make it easier to support multiple profiles - // and switching between them. Note that this may block startup if this DB lookup - // is extremely slow. We do this to ensure that if there's a profile set, the - // user never sees the "setup Autofill" option. - AutoFillProfileDatabase autoFillDb = AutoFillProfileDatabase.getInstance(mContext); - Cursor c = autoFillDb.getProfile(mAutoFillActiveProfileId); - - if (c.getCount() > 0) { - c.moveToFirst(); - - String fullName = c.getString(c.getColumnIndex( - AutoFillProfileDatabase.Profiles.FULL_NAME)); - String email = c.getString(c.getColumnIndex( - AutoFillProfileDatabase.Profiles.EMAIL_ADDRESS)); - String company = c.getString(c.getColumnIndex( - AutoFillProfileDatabase.Profiles.COMPANY_NAME)); - String addressLine1 = c.getString(c.getColumnIndex( - AutoFillProfileDatabase.Profiles.ADDRESS_LINE_1)); - String addressLine2 = c.getString(c.getColumnIndex( - AutoFillProfileDatabase.Profiles.ADDRESS_LINE_2)); - String city = c.getString(c.getColumnIndex( - AutoFillProfileDatabase.Profiles.CITY)); - String state = c.getString(c.getColumnIndex( - AutoFillProfileDatabase.Profiles.STATE)); - String zip = c.getString(c.getColumnIndex( - AutoFillProfileDatabase.Profiles.ZIP_CODE)); - String country = c.getString(c.getColumnIndex( - AutoFillProfileDatabase.Profiles.COUNTRY)); - String phone = c.getString(c.getColumnIndex( - AutoFillProfileDatabase.Profiles.PHONE_NUMBER)); - mAutoFillProfile = new AutoFillProfile(mAutoFillActiveProfileId, - fullName, email, company, addressLine1, addressLine2, city, - state, zip, country, phone); - } - c.close(); - autoFillDb.close(); - - // At this point we've loaded the profile if there was one, so let any thread - // waiting on initialization continue. - mLoaded.countDown(); - - // Synchronization note: strictly speaking, it's possible that mAutoFillProfile - // may get a value after we check below, but that's OK. This check is only an - // optimisation, and we do a proper synchronized check further down when it comes - // to actually setting the inferred profile. - if (mAutoFillProfile == null) { - // We did not load a profile from disk. Try to infer one from the user's - // "me" contact. - final Uri profileUri = Uri.withAppendedPath(ContactsContract.Profile.CONTENT_URI, - ContactsContract.Contacts.Data.CONTENT_DIRECTORY); - String name = getContactField(profileUri, - ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, - ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE); - // Only attempt to read other data and set a profile if we could successfully - // get a name. - if (name != null) { - String email = getContactField(profileUri, - ContactsContract.CommonDataKinds.Email.ADDRESS, - ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE); - String phone = getContactField(profileUri, - ContactsContract.CommonDataKinds.Phone.NUMBER, - ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE); - String company = getContactField(profileUri, - ContactsContract.CommonDataKinds.Organization.COMPANY, - ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE); - - // Can't easily get structured postal address information (even using - // CommonDataKinds.StructuredPostal) so omit prepopulating that for now. - // When querying structured postal data, it often all comes back as a string - // inside the "street" field. - - synchronized(AutofillHandler.this) { - // Only use this profile if one hasn't been set inbetween the - // inital import and this thread getting to this point. - if (mAutoFillProfile == null) { - setAutoFillProfile(new AutoFillProfile(1, name, email, company, - null, null, null, null, null, null, phone), null); - } - } - } - } - } - - private String getContactField(Uri uri, String field, String itemType) { - String result = null; - - Cursor c = mContext.getContentResolver().query(uri, new String[] { field }, - ContactsContract.Data.MIMETYPE + "=?", new String[] { itemType }, null); - - if (c == null) { - return null; - } - - try { - // Just use the first returned value if we get more than one. - if (c.moveToFirst()) { - result = c.getString(0); - } - } finally { - c.close(); - } - return result; - } } - public synchronized void setAutoFillProfile(AutoFillProfile profile, Message msg) { - waitForLoad(); - int profileId = NO_AUTOFILL_PROFILE_SET; - if (profile != null) { - profileId = profile.getUniqueId(); - // Update the AutoFill DB with the new profile. - new SaveProfileToDbTask(msg).execute(profile); - } else { - // Delete the current profile. - if (mAutoFillProfile != null) { - new DeleteProfileFromDbTask(msg).execute(mAutoFillProfile.getUniqueId()); - } - } - // Make sure we set mAutoFillProfile before calling setActiveAutoFillProfileId - // Calling setActiveAutoFillProfileId will trigger an update of WebViews - // which will expect a new profile to be set + public synchronized void setAutoFillProfile(AutoFillProfile profile) { mAutoFillProfile = profile; - setActiveAutoFillProfileId(profileId); + if (profile == null) + setActiveAutoFillProfileId(""); + else + setActiveAutoFillProfileId(profile.getUniqueId()); } public synchronized AutoFillProfile getAutoFillProfile() { - waitForLoad(); return mAutoFillProfile; } - private synchronized void setActiveAutoFillProfileId(int activeProfileId) { + public synchronized String getAutoFillProfileId() { + return mAutoFillActiveProfileId; + } + + private synchronized void setActiveAutoFillProfileId(String activeProfileId) { + if (mAutoFillActiveProfileId.equals(activeProfileId)) { + return; + } mAutoFillActiveProfileId = activeProfileId; Editor ed = PreferenceManager. getDefaultSharedPreferences(mContext).edit(); - ed.putInt(PreferenceKeys.PREF_AUTOFILL_ACTIVE_PROFILE_ID, activeProfileId); + ed.putString(PreferenceKeys.PREF_AUTOFILL_ACTIVE_PROFILE_ID, activeProfileId); ed.apply(); } - - private abstract class AutoFillProfileDbTask<T> extends AsyncTask<T, Void, Void> { - AutoFillProfileDatabase mAutoFillProfileDb; - Message mCompleteMessage; - - public AutoFillProfileDbTask(Message msg) { - mCompleteMessage = msg; - } - - @Override - protected void onPostExecute(Void result) { - if (mCompleteMessage != null) { - mCompleteMessage.sendToTarget(); - } - mAutoFillProfileDb.close(); - } - - @Override - abstract protected Void doInBackground(T... values); - } - - - private class SaveProfileToDbTask extends AutoFillProfileDbTask<AutoFillProfile> { - public SaveProfileToDbTask(Message msg) { - super(msg); - } - - @Override - protected Void doInBackground(AutoFillProfile... values) { - mAutoFillProfileDb = AutoFillProfileDatabase.getInstance(mContext); - synchronized (AutofillHandler.this) { - assert mAutoFillActiveProfileId != NO_AUTOFILL_PROFILE_SET; - AutoFillProfile newProfile = values[0]; - mAutoFillProfileDb.addOrUpdateProfile(mAutoFillActiveProfileId, newProfile); - } - return null; - } - } - - private class DeleteProfileFromDbTask extends AutoFillProfileDbTask<Integer> { - public DeleteProfileFromDbTask(Message msg) { - super(msg); - } - - @Override - protected Void doInBackground(Integer... values) { - mAutoFillProfileDb = AutoFillProfileDatabase.getInstance(mContext); - int id = values[0]; - assert id > 0; - mAutoFillProfileDb.dropProfile(id); - return null; - } - } } |