1 /* 2 * Copyright (C) 2015 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.applications; 18 19 import android.content.Context; 20 import android.content.Intent; 21 import android.content.pm.PackageManager; 22 import android.content.pm.ResolveInfo; 23 import android.net.Uri; 24 import android.os.Bundle; 25 import android.os.Handler; 26 import android.os.UserHandle; 27 import android.os.UserManager; 28 import android.preference.Preference; 29 import android.provider.SearchIndexableResource; 30 import android.text.TextUtils; 31 import android.util.Log; 32 33 import com.android.internal.content.PackageMonitor; 34 import com.android.internal.logging.MetricsLogger; 35 import com.android.settings.InstrumentedFragment; 36 import com.android.settings.R; 37 import com.android.settings.SettingsPreferenceFragment; 38 import com.android.settings.search.BaseSearchIndexProvider; 39 import com.android.settings.search.Index; 40 import com.android.settings.search.Indexable; 41 42 import java.util.ArrayList; 43 import java.util.Arrays; 44 import java.util.List; 45 46 public class ManageDefaultApps extends SettingsPreferenceFragment 47 implements Preference.OnPreferenceClickListener, Indexable { 48 49 private static final String TAG = ManageDefaultApps.class.getSimpleName(); 50 51 private static final String KEY_DEFAULT_BROWSER = "default_browser"; 52 private static final String KEY_DEFAULT_PHONE_APP = "default_phone_app"; 53 private static final String KEY_DEFAULT_EMERGENCY_APP = "default_emergency_app"; 54 private static final String KEY_SMS_APPLICATION = "default_sms_app"; 55 56 private DefaultBrowserPreference mDefaultBrowserPreference; 57 private PackageManager mPm; 58 private int myUserId; 59 60 private static final long DELAY_UPDATE_BROWSER_MILLIS = 500; 61 62 private final Handler mHandler = new Handler(); 63 64 private final Runnable mUpdateRunnable = new Runnable() { 65 @Override 66 public void run() { 67 updateDefaultBrowserPreference(); 68 } 69 }; 70 71 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 72 @Override 73 public void onPackageAdded(String packageName, int uid) { 74 sendUpdate(); 75 } 76 77 @Override 78 public void onPackageAppeared(String packageName, int reason) { 79 sendUpdate(); 80 } 81 82 @Override 83 public void onPackageDisappeared(String packageName, int reason) { 84 sendUpdate(); 85 } 86 87 @Override 88 public void onPackageRemoved(String packageName, int uid) { 89 sendUpdate(); 90 } 91 92 private void sendUpdate() { 93 mHandler.postDelayed(mUpdateRunnable, DELAY_UPDATE_BROWSER_MILLIS); 94 } 95 }; 96 updateDefaultBrowserPreference()97 private void updateDefaultBrowserPreference() { 98 mDefaultBrowserPreference.refreshBrowserApps(); 99 100 final PackageManager pm = getPackageManager(); 101 102 String packageName = pm.getDefaultBrowserPackageName(UserHandle.myUserId()); 103 if (!TextUtils.isEmpty(packageName)) { 104 // Check if the default Browser package is still there 105 Intent intent = new Intent(); 106 intent.setPackage(packageName); 107 intent.setAction(Intent.ACTION_VIEW); 108 intent.addCategory(Intent.CATEGORY_BROWSABLE); 109 intent.setData(Uri.parse("http:")); 110 111 ResolveInfo info = mPm.resolveActivityAsUser(intent, 0, myUserId); 112 if (info != null) { 113 mDefaultBrowserPreference.setValue(packageName); 114 CharSequence label = info.loadLabel(pm); 115 mDefaultBrowserPreference.setSummary(label); 116 } else { 117 mDefaultBrowserPreference.setSummary(R.string.default_browser_title_none); 118 } 119 } else { 120 mDefaultBrowserPreference.setSummary(R.string.default_browser_title_none); 121 Log.d(TAG, "Cannot set empty default Browser value!"); 122 } 123 } 124 125 @Override onCreate(Bundle icicle)126 public void onCreate(Bundle icicle) { 127 super.onCreate(icicle); 128 129 addPreferencesFromResource(R.xml.default_apps); 130 131 mPm = getPackageManager(); 132 myUserId = UserHandle.myUserId(); 133 134 mDefaultBrowserPreference = (DefaultBrowserPreference) findPreference(KEY_DEFAULT_BROWSER); 135 mDefaultBrowserPreference.setOnPreferenceChangeListener( 136 new Preference.OnPreferenceChangeListener() { 137 @Override 138 public boolean onPreferenceChange(Preference preference, Object newValue) { 139 if (newValue == null) { 140 return false; 141 } 142 final CharSequence packageName = (CharSequence) newValue; 143 if (TextUtils.isEmpty(packageName)) { 144 return false; 145 } 146 boolean result = mPm.setDefaultBrowserPackageName( 147 packageName.toString(), myUserId); 148 if (result) { 149 mDefaultBrowserPreference.setValue(packageName.toString()); 150 final CharSequence appName = mDefaultBrowserPreference.getEntry(); 151 mDefaultBrowserPreference.setSummary(appName); 152 } 153 return result; 154 } 155 }); 156 final boolean isRestrictedUser = UserManager.get(getActivity()) 157 .getUserInfo(myUserId).isRestricted(); 158 159 // Restricted users cannot currently read/write SMS. 160 // Remove SMS Application if the device does not support SMS 161 if (isRestrictedUser || !DefaultSmsPreference.isAvailable(getActivity())) { 162 removePreference(KEY_SMS_APPLICATION); 163 } 164 165 if (!DefaultPhonePreference.isAvailable(getActivity())) { 166 removePreference(KEY_DEFAULT_PHONE_APP); 167 } 168 169 if (!DefaultEmergencyPreference.isAvailable(getActivity())) { 170 removePreference(KEY_DEFAULT_EMERGENCY_APP); 171 } 172 173 if (DefaultEmergencyPreference.isCapable(getActivity())) { 174 Index.getInstance(getActivity()).updateFromClassNameResource( 175 ManageDefaultApps.class.getName(), true, true); 176 } 177 } 178 179 @Override onResume()180 public void onResume() { 181 super.onResume(); 182 updateDefaultBrowserPreference(); 183 mPackageMonitor.register(getActivity(), getActivity().getMainLooper(), false); 184 } 185 186 @Override onPause()187 public void onPause() { 188 super.onPause(); 189 190 mPackageMonitor.unregister(); 191 } 192 193 @Override getMetricsCategory()194 protected int getMetricsCategory() { 195 return MetricsLogger.APPLICATIONS_DEFAULT_APPS; 196 } 197 198 @Override onPreferenceClick(Preference preference)199 public boolean onPreferenceClick(Preference preference) { 200 return false; 201 } 202 203 public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = 204 new BaseSearchIndexProvider() { 205 @Override 206 public List<SearchIndexableResource> getXmlResourcesToIndex( 207 Context context, boolean enabled) { 208 SearchIndexableResource sir = new SearchIndexableResource(context); 209 sir.xmlResId = R.xml.default_apps; 210 return Arrays.asList(sir); 211 } 212 213 @Override 214 public List<String> getNonIndexableKeys(Context context) { 215 final ArrayList<String> result = new ArrayList<String>(); 216 217 // Remove SMS Application if the device does not support SMS 218 final boolean isRestrictedUser = UserManager.get(context) 219 .getUserInfo(UserHandle.myUserId()).isRestricted(); 220 if (!DefaultSmsPreference.isAvailable(context) || isRestrictedUser) { 221 result.add(KEY_SMS_APPLICATION); 222 } 223 224 if (!DefaultEmergencyPreference.isAvailable(context)) { 225 result.add(KEY_DEFAULT_EMERGENCY_APP); 226 } 227 228 return result; 229 } 230 }; 231 } 232