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 17 package com.android.settings; 18 19 import android.content.ComponentName; 20 import android.content.Context; 21 import android.content.DialogInterface; 22 import android.content.Intent; 23 import android.content.pm.ApplicationInfo; 24 import android.content.pm.PackageManager; 25 import android.graphics.drawable.Drawable; 26 import android.os.Bundle; 27 import android.provider.Telephony.Sms.Intents; 28 import android.telephony.TelephonyManager; 29 import android.text.TextUtils; 30 import android.view.LayoutInflater; 31 import android.view.View; 32 import android.view.ViewGroup; 33 import android.widget.BaseAdapter; 34 import android.widget.ImageView; 35 import android.widget.TextView; 36 37 import com.android.internal.app.AlertActivity; 38 import com.android.internal.app.AlertController; 39 import com.android.internal.telephony.SmsApplication; 40 import com.android.internal.telephony.SmsApplication.SmsApplicationData; 41 42 import java.util.ArrayList; 43 import java.util.List; 44 45 public final class SmsDefaultDialog extends AlertActivity implements 46 DialogInterface.OnClickListener { 47 private SmsApplicationData mNewSmsApplicationData; 48 49 @Override onCreate(Bundle savedInstanceState)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 onClick(DialogInterface dialog, int which)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 buildDialog(String packageName)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.mApplicationName, 113 oldSmsApplicationData.mApplicationName); 114 } else { 115 p.mMessage = getString(R.string.sms_change_default_no_previous_dialog_text, 116 mNewSmsApplicationData.mApplicationName); 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 } 129 setupAlert(); 130 131 return true; 132 } 133 134 /** 135 * The list of SMS apps with label, icon. Current default SMS app is marked as "default". 136 */ 137 private class AppListAdapter extends BaseAdapter { 138 /** 139 * SMS app item in the list 140 */ 141 private class Item { 142 final String label; // app label 143 final Drawable icon; // app icon 144 final String packgeName; // full app package name 145 Item(String label, Drawable icon, String packageName)146 public Item(String label, Drawable icon, String packageName) { 147 this.label = label; 148 this.icon = icon; 149 this.packgeName = packageName; 150 } 151 } 152 153 // The list 154 private final List<Item> mItems; 155 // The index of selected 156 private final int mSelectedIndex; 157 AppListAdapter()158 public AppListAdapter() { 159 mItems = getItems(); 160 int selected = getSelectedIndex(); 161 // Move selected up to the top so it is easy to find 162 if (selected > 0) { 163 Item item = mItems.remove(selected); 164 mItems.add(0, item); 165 selected = 0; 166 } 167 mSelectedIndex = selected; 168 } 169 170 @Override getCount()171 public int getCount() { 172 return mItems != null ? mItems.size() : 0; 173 } 174 175 @Override getItem(int position)176 public Object getItem(int position) { 177 return mItems != null && position < mItems.size() ? mItems.get(position) : null; 178 } 179 180 @Override getItemId(int position)181 public long getItemId(int position) { 182 return position; 183 } 184 185 @Override getView(int position, View convertView, ViewGroup parent)186 public View getView(int position, View convertView, ViewGroup parent) { 187 Item item = ((Item) getItem(position)); 188 LayoutInflater inflater = getLayoutInflater(); 189 View view = inflater.inflate(R.layout.app_preference_item, parent, false); 190 TextView textView = (TextView) view.findViewById(android.R.id.title); 191 textView.setText(item.label); 192 if (position == mSelectedIndex) { 193 view.findViewById(R.id.default_label).setVisibility(View.VISIBLE); 194 } else { 195 view.findViewById(R.id.default_label).setVisibility(View.GONE); 196 } 197 ImageView imageView = (ImageView)view.findViewById(android.R.id.icon); 198 imageView.setImageDrawable(item.icon); 199 return view; 200 } 201 202 /** 203 * Get the selected package name by 204 * 205 * @param position the index of the item in the list 206 * @return the package name of selected item 207 */ getPackageName(int position)208 public String getPackageName(int position) { 209 Item item = (Item) getItem(position); 210 if (item != null) { 211 return item.packgeName; 212 } 213 return null; 214 } 215 216 /** 217 * Check if an item at a position is already selected 218 * 219 * @param position the index of the item in the list 220 * @return true if the item at the position is already selected, false otherwise 221 */ isSelected(int position)222 public boolean isSelected(int position) { 223 return position == mSelectedIndex; 224 } 225 226 // Get the list items by looking for SMS apps getItems()227 private List<Item> getItems() { 228 PackageManager pm = getPackageManager(); 229 List<Item> items = new ArrayList<>(); 230 for (SmsApplication.SmsApplicationData app : 231 SmsApplication.getApplicationCollection(SmsDefaultDialog.this)) { 232 try { 233 String packageName = app.mPackageName; 234 ApplicationInfo appInfo = pm.getApplicationInfo(packageName, 0/*flags*/); 235 if (appInfo != null) { 236 items.add(new Item( 237 appInfo.loadLabel(pm).toString(), 238 appInfo.loadIcon(pm), 239 packageName)); 240 } 241 } catch (PackageManager.NameNotFoundException e) { 242 // Ignore package can't be found 243 } 244 } 245 return items; 246 } 247 248 // Get the selected item index by looking for the current default SMS app getSelectedIndex()249 private int getSelectedIndex() { 250 ComponentName appName = SmsApplication.getDefaultSmsApplication( 251 SmsDefaultDialog.this, true); 252 if (appName != null) { 253 String defaultSmsAppPackageName = appName.getPackageName(); 254 if (!TextUtils.isEmpty(defaultSmsAppPackageName)) { 255 for (int i = 0; i < mItems.size(); i++) { 256 if (TextUtils.equals(mItems.get(i).packgeName, defaultSmsAppPackageName)) { 257 return i; 258 } 259 } 260 } 261 } 262 return -1; 263 } 264 } 265 } 266