1/* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.settings; 18 19import android.content.ComponentName; 20import android.content.Context; 21import android.content.DialogInterface; 22import android.content.Intent; 23import android.content.pm.ApplicationInfo; 24import android.content.pm.PackageManager; 25import android.graphics.drawable.Drawable; 26import android.os.Bundle; 27import android.provider.Telephony.Sms.Intents; 28import android.telephony.TelephonyManager; 29import android.text.TextUtils; 30import android.view.LayoutInflater; 31import android.view.View; 32import android.view.ViewGroup; 33import android.widget.BaseAdapter; 34import android.widget.ImageView; 35import android.widget.TextView; 36 37import com.android.internal.app.AlertActivity; 38import com.android.internal.app.AlertController; 39import com.android.internal.telephony.SmsApplication; 40import com.android.internal.telephony.SmsApplication.SmsApplicationData; 41 42import java.util.ArrayList; 43import java.util.List; 44 45public final class SmsDefaultDialog extends AlertActivity implements 46 DialogInterface.OnClickListener { 47 private SmsApplicationData mNewSmsApplicationData; 48 49 @Override 50 protected void onCreate(Bundle savedInstanceState) { 51 super.onCreate(savedInstanceState); 52 53 Intent intent = getIntent(); 54 String packageName = intent.getStringExtra(Intents.EXTRA_PACKAGE_NAME); 55 56 setResult(RESULT_CANCELED); 57 if (!buildDialog(packageName)) { 58 finish(); 59 } 60 } 61 62 @Override 63 public void onClick(DialogInterface dialog, int which) { 64 switch (which) { 65 case BUTTON_POSITIVE: 66 SmsApplication.setDefaultApplication(mNewSmsApplicationData.mPackageName, this); 67 setResult(RESULT_OK); 68 break; 69 case BUTTON_NEGATIVE: 70 break; 71 default: 72 if (which >= 0) { 73 AppListAdapter adapter = (AppListAdapter) mAlertParams.mAdapter; 74 if (!adapter.isSelected(which)) { 75 String packageName = adapter.getPackageName(which); 76 if (!TextUtils.isEmpty(packageName)) { 77 SmsApplication.setDefaultApplication(packageName, this); 78 setResult(RESULT_OK); 79 } 80 } 81 } 82 break; 83 } 84 } 85 86 private boolean buildDialog(String packageName) { 87 TelephonyManager tm = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE); 88 if (!tm.isSmsCapable()) { 89 // No phone, no SMS 90 return false; 91 } 92 final AlertController.AlertParams p = mAlertParams; 93 p.mTitle = getString(R.string.sms_change_default_dialog_title); 94 mNewSmsApplicationData = SmsApplication.getSmsApplicationData(packageName, this); 95 if (mNewSmsApplicationData != null) { 96 // New default SMS app specified, change to that directly after the confirmation 97 // dialog. 98 SmsApplicationData oldSmsApplicationData = null; 99 ComponentName oldSmsComponent = SmsApplication.getDefaultSmsApplication(this, true); 100 if (oldSmsComponent != null) { 101 oldSmsApplicationData = SmsApplication.getSmsApplicationData( 102 oldSmsComponent.getPackageName(), this); 103 if (oldSmsApplicationData.mPackageName.equals( 104 mNewSmsApplicationData.mPackageName)) { 105 return false; 106 } 107 } 108 109 // Compose dialog; get 110 if (oldSmsApplicationData != null) { 111 p.mMessage = getString(R.string.sms_change_default_dialog_text, 112 mNewSmsApplicationData.getApplicationName(this), 113 oldSmsApplicationData.getApplicationName(this)); 114 } else { 115 p.mMessage = getString(R.string.sms_change_default_no_previous_dialog_text, 116 mNewSmsApplicationData.getApplicationName(this)); 117 } 118 p.mPositiveButtonText = getString(R.string.yes); 119 p.mNegativeButtonText = getString(R.string.no); 120 p.mPositiveButtonListener = this; 121 p.mNegativeButtonListener = this; 122 } else { 123 // No new default SMS app specified, show a list of all SMS apps and let user to pick 124 p.mAdapter = new AppListAdapter(); 125 p.mOnClickListener = this; 126 p.mNegativeButtonText = getString(R.string.cancel); 127 p.mNegativeButtonListener = this; 128 if (p.mAdapter.isEmpty()) { 129 // If there is nothing to choose from, don't build the dialog. 130 return false; 131 } 132 } 133 setupAlert(); 134 135 return true; 136 } 137 138 /** 139 * The list of SMS apps with label, icon. Current default SMS app is marked as "default". 140 */ 141 private class AppListAdapter extends BaseAdapter { 142 /** 143 * SMS app item in the list 144 */ 145 private class Item { 146 final String label; // app label 147 final Drawable icon; // app icon 148 final String packgeName; // full app package name 149 150 public Item(String label, Drawable icon, String packageName) { 151 this.label = label; 152 this.icon = icon; 153 this.packgeName = packageName; 154 } 155 } 156 157 // The list 158 private final List<Item> mItems; 159 // The index of selected 160 private final int mSelectedIndex; 161 162 public AppListAdapter() { 163 mItems = getItems(); 164 int selected = getSelectedIndex(); 165 // Move selected up to the top so it is easy to find 166 if (selected > 0) { 167 Item item = mItems.remove(selected); 168 mItems.add(0, item); 169 selected = 0; 170 } 171 mSelectedIndex = selected; 172 } 173 174 @Override 175 public int getCount() { 176 return mItems != null ? mItems.size() : 0; 177 } 178 179 @Override 180 public Object getItem(int position) { 181 return mItems != null && position < mItems.size() ? mItems.get(position) : null; 182 } 183 184 @Override 185 public long getItemId(int position) { 186 return position; 187 } 188 189 @Override 190 public View getView(int position, View convertView, ViewGroup parent) { 191 Item item = ((Item) getItem(position)); 192 LayoutInflater inflater = getLayoutInflater(); 193 View view = inflater.inflate(R.layout.app_preference_item, parent, false); 194 TextView textView = (TextView) view.findViewById(android.R.id.title); 195 textView.setText(item.label); 196 if (position == mSelectedIndex) { 197 view.findViewById(R.id.default_label).setVisibility(View.VISIBLE); 198 } else { 199 view.findViewById(R.id.default_label).setVisibility(View.GONE); 200 } 201 ImageView imageView = (ImageView)view.findViewById(android.R.id.icon); 202 imageView.setImageDrawable(item.icon); 203 return view; 204 } 205 206 /** 207 * Get the selected package name by 208 * 209 * @param position the index of the item in the list 210 * @return the package name of selected item 211 */ 212 public String getPackageName(int position) { 213 Item item = (Item) getItem(position); 214 if (item != null) { 215 return item.packgeName; 216 } 217 return null; 218 } 219 220 /** 221 * Check if an item at a position is already selected 222 * 223 * @param position the index of the item in the list 224 * @return true if the item at the position is already selected, false otherwise 225 */ 226 public boolean isSelected(int position) { 227 return position == mSelectedIndex; 228 } 229 230 // Get the list items by looking for SMS apps 231 private List<Item> getItems() { 232 PackageManager pm = getPackageManager(); 233 List<Item> items = new ArrayList<>(); 234 for (SmsApplication.SmsApplicationData app : 235 SmsApplication.getApplicationCollection(SmsDefaultDialog.this)) { 236 try { 237 String packageName = app.mPackageName; 238 ApplicationInfo appInfo = pm.getApplicationInfo(packageName, 0/*flags*/); 239 if (appInfo != null) { 240 items.add(new Item( 241 appInfo.loadLabel(pm).toString(), 242 appInfo.loadIcon(pm), 243 packageName)); 244 } 245 } catch (PackageManager.NameNotFoundException e) { 246 // Ignore package can't be found 247 } 248 } 249 return items; 250 } 251 252 // Get the selected item index by looking for the current default SMS app 253 private int getSelectedIndex() { 254 ComponentName appName = SmsApplication.getDefaultSmsApplication( 255 SmsDefaultDialog.this, true); 256 if (appName != null) { 257 String defaultSmsAppPackageName = appName.getPackageName(); 258 if (!TextUtils.isEmpty(defaultSmsAppPackageName)) { 259 for (int i = 0; i < mItems.size(); i++) { 260 if (TextUtils.equals(mItems.get(i).packgeName, defaultSmsAppPackageName)) { 261 return i; 262 } 263 } 264 } 265 } 266 return -1; 267 } 268 } 269} 270