1bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook/* 2bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Copyright (C) 2008 The Android Open Source Project 3bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 4bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Licensed under the Apache License, Version 2.0 (the "License"); 5bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * you may not use this file except in compliance with the License. 6bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * You may obtain a copy of the License at 7bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 8bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * http://www.apache.org/licenses/LICENSE-2.0 9bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 10bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Unless required by applicable law or agreed to in writing, software 11bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * distributed under the License is distributed on an "AS IS" BASIS, 12bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * See the License for the specific language governing permissions and 14bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * limitations under the License. 15bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 16bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 17bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookpackage com.android.email.activity; 18bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 19bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.app.Activity; 20bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.content.Intent; 21bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.os.Bundle; 22bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.os.Parcelable; 23bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.util.Log; 24bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.view.View; 25bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport android.view.View.OnClickListener; 26bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 27bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport com.android.email.R; 28bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport com.android.email.activity.ShortcutPickerFragment.AccountShortcutPickerFragment; 29bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport com.android.email.activity.ShortcutPickerFragment.MailboxShortcutPickerFragment; 30bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport com.android.email.activity.ShortcutPickerFragment.PickerCallback; 31bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport com.android.emailcommon.Logging; 32bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport com.android.emailcommon.provider.Account; 33bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport com.android.emailcommon.provider.EmailContent.Message; 34bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport com.android.emailcommon.provider.Mailbox; 35bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 36bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook/** 37bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * This class implements a launcher shortcut for directly accessing a single account. 38bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 39bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookpublic class ShortcutPicker extends Activity implements OnClickListener, PickerCallback { 40bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 41bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * If true, creates pre-honeycomb style shortcuts. This allows developers to test launching 42bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * the app from old style shortcuts (which point sat MessageList rather than Welcome) without 43bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * actually carrying over shortcuts from previous versions. 44bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 45bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private final static boolean TEST_CREATE_OLD_STYLE_SHORTCUT = false; // DO NOT SUBMIT WITH TRUE 46bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 47bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook @Override 48bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public void onCreate(Bundle icicle) { 49bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook super.onCreate(icicle); 50bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 51bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // TODO Relax this test slightly in order to re-use this activity for widget creation 52bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (!Intent.ACTION_CREATE_SHORTCUT.equals(getIntent().getAction())) { 53bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // finish() immediately if we aren't supposed to be here 54bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook finish(); 55bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return; 56bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 57bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 58bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // Set handler for the "cancel" button 59bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook setContentView(R.layout.account_shortcut_picker); 60bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook findViewById(R.id.cancel).setOnClickListener(this); 61bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 62bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (getFragmentManager().findFragmentById(R.id.shortcut_list) == null) { 63bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // Load the account picking fragment if we haven't created a fragment yet 64bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // NOTE: do not add to history as this will be the first fragment in the flow 65bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook AccountShortcutPickerFragment fragment = new AccountShortcutPickerFragment(); 66bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook getFragmentManager().beginTransaction().add(R.id.shortcut_list, fragment).commit(); 67bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 68bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 69bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 70bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook @Override 71bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public void onClick(View v) { 72bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook switch (v.getId()) { 73bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook case R.id.cancel: 74bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook finish(); 75bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook break; 76bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 77bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 78bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 79bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook @Override 80bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public Integer buildFilter(Account account) { 81bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (!Account.isNormalAccount(account.mId)) { 82bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // Shortcuts for combined accounts can only be for inboxes. 83bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return MailboxShortcutPickerFragment.FILTER_INBOX_ONLY; 84bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 85bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 86bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook return MailboxShortcutPickerFragment.FILTER_ALLOW_ALL; 87bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 88bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 89bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook @Override 90bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public void onSelected(Account account, long mailboxId) { 91bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook String shortcutName; 92bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (Account.isNormalAccount(account.mId) && 93bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook (Mailbox.getMailboxType(this, mailboxId) != Mailbox.TYPE_INBOX)) { 94bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook shortcutName = Mailbox.getDisplayName(this, mailboxId); 95bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } else { 96bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook shortcutName = account.getDisplayName(); 97bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 98bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook setupShortcut(account, mailboxId, shortcutName); 99bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook finish(); 100bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 101bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 102bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook @Override 103bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook public void onMissingData(boolean missingAccount, boolean missingMailbox) { 104bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // TODO what's the proper handling if the mailbox list is '0'? display toast? 105bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook finish(); 106bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 107bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 108bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook /** 109bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * This function creates a shortcut and returns it to the caller. There are actually two 110bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * intents that you will send back. 111bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 112bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * The first intent serves as a container for the shortcut and is returned to the launcher by 113bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * setResult(). This intent must contain three fields: 114bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 115bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * <ul> 116bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * <li>{@link android.content.Intent#EXTRA_SHORTCUT_INTENT} The shortcut intent.</li> 117bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * <li>{@link android.content.Intent#EXTRA_SHORTCUT_NAME} The text that will be displayed with 118bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * the shortcut.</li> 119bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * <li>{@link android.content.Intent#EXTRA_SHORTCUT_ICON} The shortcut's icon, if provided as a 120bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * bitmap, <i>or</i> {@link android.content.Intent#EXTRA_SHORTCUT_ICON_RESOURCE} if provided as 121bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * a drawable resource.</li> 122bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * </ul> 123bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 124bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * If you use a simple drawable resource, note that you must wrapper it using 125bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * {@link android.content.Intent.ShortcutIconResource}, as shown below. This is required so 126bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * that the launcher can access resources that are stored in your application's .apk file. If 127bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * you return a bitmap, such as a thumbnail, you can simply put the bitmap into the extras 128bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * bundle using {@link android.content.Intent#EXTRA_SHORTCUT_ICON}. 129bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 130bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * The shortcut intent can be any intent that you wish the launcher to send, when the user 131bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * clicks on the shortcut. Typically this will be {@link android.content.Intent#ACTION_VIEW} 132bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * with an appropriate Uri for your content, but any Intent will work here as long as it 133bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * triggers the desired action within your Activity. 134bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */ 135bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook private void setupShortcut(Account account, long mailboxId, String shortcutName) { 136bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook Activity myActivity = this; 137bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // First, set up the shortcut intent. 138bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook final Intent shortcutIntent; 139bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (TEST_CREATE_OLD_STYLE_SHORTCUT) { 140bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook shortcutIntent = MessageList.createFroyoIntent(myActivity, account); 141bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook Log.d(Logging.LOG_TAG, "Created old style intent: " + shortcutIntent); 142bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } else { 143bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // TODO if we add meta-mailboxes/accounts to the database, remove this special case 144bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook if (account.mId == Account.ACCOUNT_ID_COMBINED_VIEW) { 145bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook shortcutIntent = Welcome.createOpenMessageIntent( 146bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook myActivity, account.mId, mailboxId, Message.NO_MESSAGE); 147bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } else { 148bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook String uuid = account.mCompatibilityUuid; 149bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook shortcutIntent = Welcome.createAccountShortcutIntent(myActivity, uuid, mailboxId); 150bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 151bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 152bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 153bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // Then, set up the container intent (the response to the caller) 154bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook Intent intent = new Intent(); 155bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent); 156bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, shortcutName); 157bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook Parcelable iconResource 158bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook = Intent.ShortcutIconResource.fromContext(myActivity, R.mipmap.ic_launcher_email); 159bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, iconResource); 160bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook 161bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook // Now, return the result to the launcher 162bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook myActivity.setResult(Activity.RESULT_OK, intent); 163bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook } 164bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook} 165