• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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