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