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.ContentResolver; 20 import android.content.Context; 21 import android.content.Intent; 22 import android.content.pm.ApplicationInfo; 23 import android.content.pm.PackageInfo; 24 import android.content.pm.PackageManager; 25 import android.content.pm.ResolveInfo; 26 import android.os.AsyncTask; 27 import android.provider.Settings; 28 import android.telephony.TelephonyManager; 29 import android.text.TextUtils; 30 import android.util.ArraySet; 31 import android.util.AttributeSet; 32 33 import com.android.settings.AppListPreference; 34 import com.android.settings.R; 35 import com.android.settings.SelfAvailablePreference; 36 import com.android.settings.Utils; 37 38 import java.util.List; 39 import java.util.Objects; 40 import java.util.Set; 41 42 /** 43 * A preference for choosing the default emergency app 44 */ 45 public class DefaultEmergencyPreference extends AppListPreference 46 implements SelfAvailablePreference { 47 48 private static final boolean DEFAULT_EMERGENCY_APP_IS_CONFIGURABLE = false; 49 private final ContentResolver mContentResolver; 50 51 public static final Intent QUERY_INTENT = new Intent( 52 TelephonyManager.ACTION_EMERGENCY_ASSISTANCE); 53 DefaultEmergencyPreference(Context context, AttributeSet attrs)54 public DefaultEmergencyPreference(Context context, AttributeSet attrs) { 55 super(context, attrs); 56 mContentResolver = context.getContentResolver(); 57 load(); 58 } 59 60 @Override getConfirmationMessage(String value)61 protected CharSequence getConfirmationMessage(String value) { 62 return Utils.isPackageDirectBootAware(getContext(), value) ? null 63 : getContext().getText(R.string.direct_boot_unaware_dialog_message); 64 } 65 66 @Override persistString(String value)67 protected boolean persistString(String value) { 68 String previousValue = Settings.Secure.getString(mContentResolver, 69 Settings.Secure.EMERGENCY_ASSISTANCE_APPLICATION); 70 71 if (!TextUtils.isEmpty(value) && !Objects.equals(value, previousValue)) { 72 Settings.Secure.putString(mContentResolver, 73 Settings.Secure.EMERGENCY_ASSISTANCE_APPLICATION, 74 value); 75 } 76 setSummary(getEntry()); 77 return true; 78 } 79 load()80 private void load() { 81 new AsyncTask<Void, Void, Set<String>>() { 82 @Override 83 protected Set<String> doInBackground(Void[] params) { 84 return resolveAssistPackageAndQueryApps(); 85 } 86 87 @Override 88 protected void onPostExecute(Set<String> entries) { 89 String currentPkg = Settings.Secure.getString(mContentResolver, 90 Settings.Secure.EMERGENCY_ASSISTANCE_APPLICATION); 91 setPackageNames(entries.toArray(new String[entries.size()]), currentPkg); 92 } 93 }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); 94 } 95 resolveAssistPackageAndQueryApps()96 private Set<String> resolveAssistPackageAndQueryApps() { 97 Set<String> packages = new ArraySet<>(); 98 99 PackageManager packageManager = getContext().getPackageManager(); 100 List<ResolveInfo> infos = packageManager.queryIntentActivities(QUERY_INTENT, 0); 101 102 PackageInfo bestMatch = null; 103 final int size = infos.size(); 104 for (int i = 0; i < size; i++) { 105 ResolveInfo info = infos.get(i); 106 if (info == null || info.activityInfo == null 107 || packages.contains(info.activityInfo.packageName)) { 108 continue; 109 } 110 111 String packageName = info.activityInfo.packageName; 112 113 packages.add(packageName); 114 115 PackageInfo packageInfo; 116 try { 117 packageInfo = packageManager.getPackageInfo(packageName, 0); 118 } catch (PackageManager.NameNotFoundException e) { 119 continue; 120 } 121 122 // Get earliest installed system app. 123 if (isSystemApp(packageInfo) && (bestMatch == null || 124 bestMatch.firstInstallTime > packageInfo.firstInstallTime)) { 125 bestMatch = packageInfo; 126 } 127 } 128 129 String defaultPackage = Settings.Secure.getString(mContentResolver, 130 Settings.Secure.EMERGENCY_ASSISTANCE_APPLICATION); 131 boolean defaultMissing = TextUtils.isEmpty(defaultPackage) 132 || !packages.contains(defaultPackage); 133 if (bestMatch != null && defaultMissing) { 134 Settings.Secure.putString(mContentResolver, 135 Settings.Secure.EMERGENCY_ASSISTANCE_APPLICATION, 136 bestMatch.packageName); 137 } 138 139 return packages; 140 } 141 isCapable(Context context)142 private static boolean isCapable(Context context) { 143 return TelephonyManager.EMERGENCY_ASSISTANCE_ENABLED 144 && context.getResources().getBoolean( 145 com.android.internal.R.bool.config_voice_capable); 146 } 147 isSystemApp(PackageInfo info)148 private static boolean isSystemApp(PackageInfo info) { 149 return info.applicationInfo != null 150 && (info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 151 } 152 isAvailable(Context context)153 public boolean isAvailable(Context context) { 154 return DEFAULT_EMERGENCY_APP_IS_CONFIGURABLE 155 && isCapable(context) 156 && context.getPackageManager().resolveActivity(QUERY_INTENT, 0) != null; 157 } 158 hasEmergencyPreference(String pkg, Context context)159 public static boolean hasEmergencyPreference(String pkg, Context context) { 160 Intent i = new Intent(QUERY_INTENT); 161 i.setPackage(pkg); 162 final List<ResolveInfo> resolveInfos = 163 context.getPackageManager().queryIntentActivities(i, 0); 164 return resolveInfos != null && resolveInfos.size() != 0; 165 } 166 isEmergencyDefault(String pkg, Context context)167 public static boolean isEmergencyDefault(String pkg, Context context) { 168 String defaultPackage = Settings.Secure.getString(context.getContentResolver(), 169 Settings.Secure.EMERGENCY_ASSISTANCE_APPLICATION); 170 return defaultPackage != null && defaultPackage.equals(pkg); 171 } 172 } 173