Home | History | Annotate | Download | only in provider
      1 /*
      2  * Copyright (C) 2012 Google Inc.
      3  * Licensed to 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.email.provider;
     19 
     20 import android.app.Activity;
     21 import android.app.ProgressDialog;
     22 import android.content.ContentUris;
     23 import android.content.ContentValues;
     24 import android.content.Context;
     25 import android.content.Intent;
     26 import android.database.ContentObserver;
     27 import android.net.Uri;
     28 import android.os.Bundle;
     29 import android.os.Handler;
     30 
     31 import com.android.email.R;
     32 import com.android.emailcommon.provider.Account;
     33 import com.android.emailcommon.provider.EmailContent;
     34 import com.android.emailcommon.provider.Mailbox;
     35 import com.android.emailcommon.provider.EmailContent.AccountColumns;
     36 import com.android.emailcommon.provider.EmailContent.MailboxColumns;
     37 import com.android.mail.providers.Folder;
     38 import com.android.mail.utils.LogUtils;
     39 
     40 public class FolderPickerActivity extends Activity implements FolderPickerCallback {
     41     private static final String TAG = "FolderPickerActivity";
     42     public static final String MAILBOX_TYPE_EXTRA = "mailbox_type";
     43 
     44     private long mAccountId;
     45     private int mMailboxType;
     46     private AccountObserver mAccountObserver;
     47     private String mAccountName;
     48     private boolean mInSetup = true;
     49 
     50     @Override
     51     public void onCreate(Bundle bundle) {
     52         super.onCreate(bundle);
     53         Intent i = getIntent();
     54         Uri uri = i.getData();
     55         int headerId;
     56         final com.android.mail.providers.Account uiAccount;
     57         // If we've gotten a Uri, then this is a call from the UI in response to setupIntentUri
     58         // in an account (meaning the account requires setup)
     59         if (uri != null) {
     60             String id = uri.getQueryParameter("account");
     61             if (id == null) {
     62                 LogUtils.w(TAG, "No account # in Uri?");
     63                 finish();
     64                 return;
     65             }
     66             try {
     67                 mAccountId = Long.parseLong(id);
     68             } catch (NumberFormatException e) {
     69                 LogUtils.w(TAG, "Invalid account # in Uri?");
     70                 finish();
     71                 return;
     72             }
     73             // We act a bit differently if we're coming to set up the trash after account creation
     74             mInSetup = !i.hasExtra(MAILBOX_TYPE_EXTRA);
     75             mMailboxType = i.getIntExtra(MAILBOX_TYPE_EXTRA, Mailbox.TYPE_TRASH);
     76             long trashMailboxId = Mailbox.findMailboxOfType(this, mAccountId, Mailbox.TYPE_TRASH);
     77             // If we already have a trash mailbox, we're done (if in setup; a race?)
     78             if (trashMailboxId != Mailbox.NO_MAILBOX && mInSetup) {
     79                 LogUtils.w(TAG, "Trash folder already exists");
     80                 finish();
     81                 return;
     82             }
     83             Account account = Account.restoreAccountWithId(this, mAccountId);
     84             if (account == null) {
     85                 LogUtils.w(TAG, "No account?");
     86                 finish();
     87             } else {
     88                 mAccountName = account.mDisplayName;
     89                 // Two possibilities here; either we have our folder list, or we don't
     90                 if ((account.mFlags & Account.FLAGS_INITIAL_FOLDER_LIST_LOADED) != 0) {
     91                     // If we've got them, just start up the picker dialog
     92                     startPickerForAccount();
     93                 } else {
     94                     // Otherwise, wait for the folders to show up
     95                     waitForFolders();
     96                 }
     97             }
     98         } else {
     99             // In this case, we're coming from Settings
    100             uiAccount = i.getParcelableExtra(EmailProvider.PICKER_UI_ACCOUNT);
    101             mAccountName = uiAccount.name;
    102             mAccountId = Long.parseLong(uiAccount.uri.getLastPathSegment());
    103             mMailboxType = i.getIntExtra(EmailProvider.PICKER_MAILBOX_TYPE, -1);
    104             headerId = i.getIntExtra(EmailProvider.PICKER_HEADER_ID, 0);
    105             if (headerId == 0) {
    106                 finish();
    107                 return;
    108             }
    109             startPicker(uiAccount.folderListUri, headerId);
    110         }
    111     }
    112 
    113     @Override
    114     public void onDestroy() {
    115         super.onDestroy();
    116         // Clean up
    117         if (mAccountObserver != null) {
    118             getContentResolver().unregisterContentObserver(mAccountObserver);
    119             mAccountObserver = null;
    120         }
    121         if (mWaitingForFoldersDialog != null) {
    122             mWaitingForFoldersDialog.dismiss();
    123             mWaitingForFoldersDialog = null;
    124         }
    125     }
    126 
    127     private class AccountObserver extends ContentObserver {
    128         private final Context mContext;
    129 
    130         public AccountObserver(Context context, Handler handler) {
    131             super(handler);
    132             mContext = context;
    133         }
    134 
    135         @Override
    136         public void onChange(boolean selfChange) {
    137             Account account = Account.restoreAccountWithId(mContext, mAccountId);
    138             // All we care about is whether the folder list is now loaded
    139             if ((account.mFlags & Account.FLAGS_INITIAL_FOLDER_LIST_LOADED) != 0 &&
    140                     (mAccountObserver != null)) {
    141                 mContext.getContentResolver().unregisterContentObserver(mAccountObserver);
    142                 mAccountObserver = null;
    143                 // Bring down the ProgressDialog and show the picker
    144                 if (mWaitingForFoldersDialog != null) {
    145                     mWaitingForFoldersDialog.dismiss();
    146                     mWaitingForFoldersDialog = null;
    147                 }
    148                 startPickerForAccount();
    149             }
    150         }
    151     }
    152 
    153     private ProgressDialog mWaitingForFoldersDialog;
    154 
    155     private void waitForFolders() {
    156         /// Show "Waiting for folders..." dialog
    157         mWaitingForFoldersDialog = new ProgressDialog(this);
    158         mWaitingForFoldersDialog.setIndeterminate(true);
    159         mWaitingForFoldersDialog.setMessage(getString(R.string.account_waiting_for_folders_msg));
    160         mWaitingForFoldersDialog.show();
    161 
    162         // Listen for account changes
    163         mAccountObserver = new AccountObserver(this, new Handler());
    164         Uri uri = ContentUris.withAppendedId(Account.CONTENT_URI, mAccountId);
    165         getContentResolver().registerContentObserver(uri, false, mAccountObserver);
    166     }
    167 
    168     private void startPickerForAccount() {
    169         int headerId = R.string.trash_folder_selection_title;
    170         Uri uri = Uri.parse("content://" + EmailContent.AUTHORITY + "/uifullfolders/" + mAccountId);
    171         startPicker(uri, headerId);
    172     }
    173 
    174     private void startPicker(Uri uri, int headerId) {
    175         String header = getString(headerId, mAccountName);
    176         FolderPickerDialog dialog =
    177                 new FolderPickerDialog(this, uri, this, header, !mInSetup);
    178         dialog.show();
    179     }
    180 
    181     @Override
    182     public void select(Folder folder) {
    183         String folderId = folder.folderUri.fullUri.getLastPathSegment();
    184         Long id = Long.parseLong(folderId);
    185         ContentValues values = new ContentValues();
    186 
    187         // If we already have a mailbox of this type, change it back to generic mail type
    188         Mailbox ofType = Mailbox.restoreMailboxOfType(this, mAccountId, mMailboxType);
    189         if (ofType != null) {
    190             values.put(MailboxColumns.TYPE, Mailbox.TYPE_MAIL);
    191             getContentResolver().update(
    192                     ContentUris.withAppendedId(Mailbox.CONTENT_URI, ofType.mId), values,
    193                     null, null);
    194         }
    195 
    196         // Change this mailbox to be of the desired type
    197         Mailbox mailbox = Mailbox.restoreMailboxWithId(this, id);
    198         if (mailbox != null) {
    199             values.put(MailboxColumns.TYPE, mMailboxType);
    200             getContentResolver().update(
    201                     ContentUris.withAppendedId(Mailbox.CONTENT_URI, mailbox.mId), values,
    202                     null, null);
    203             values.clear();
    204             // Touch the account so that UI won't bring up this picker again
    205             Account account = Account.restoreAccountWithId(this, mAccountId);
    206             values.put(AccountColumns.FLAGS, account.mFlags);
    207             getContentResolver().update(
    208                     ContentUris.withAppendedId(Account.CONTENT_URI, account.mId), values,
    209                     null, null);
    210         }
    211         finish();
    212     }
    213 
    214     @Override
    215     public void cancel() {
    216         finish();
    217     }
    218 }
    219