blob: 33788d38e3bd8dfa2ba7f07680f90e29f3edcc2a [file] [log] [blame]
Chihhang Chuangf264cfb2018-06-05 15:29:06 +08001/*
2 * Copyright (C) 2018 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
17package com.android.phone;
18
Hongming Jin862ce042019-02-05 15:42:50 -080019import android.app.role.RoleManager;
Chihhang Chuangf264cfb2018-06-05 15:29:06 +080020import android.content.ComponentName;
21import android.content.Context;
22import android.content.Intent;
23import android.content.pm.ApplicationInfo;
24import android.content.pm.PackageInfo;
25import android.content.pm.PackageManager;
26import android.content.pm.ResolveInfo;
Hongming Jin862ce042019-02-05 15:42:50 -080027import android.os.AsyncTask;
28import android.os.Binder;
29import android.os.Process;
Chihhang Chuangf264cfb2018-06-05 15:29:06 +080030import android.telephony.TelephonyManager;
31import android.text.TextUtils;
Hongming Jin862ce042019-02-05 15:42:50 -080032import android.util.Log;
33
34import com.android.internal.util.CollectionUtils;
Chihhang Chuangf264cfb2018-06-05 15:29:06 +080035
36import java.util.List;
37
38/**
39 * A helper to query activities of emergency assistance.
40 */
41public class EmergencyAssistanceHelper {
Hongming Jin862ce042019-02-05 15:42:50 -080042 private static final String TAG = EmergencyAssistanceHelper.class.getSimpleName();
Chihhang Chuangf264cfb2018-06-05 15:29:06 +080043 /**
yuanjiahsubc20ba82018-11-26 22:57:18 +080044 * Get intent action of target emergency app.
45 *
yuanjiahsucc83a3b2019-05-23 15:29:30 +080046 * @return A string of intent action to launch target emergency app.
yuanjiahsubc20ba82018-11-26 22:57:18 +080047 */
yuanjiahsucc83a3b2019-05-23 15:29:30 +080048 public static String getIntentAction() {
yuanjiahsubc20ba82018-11-26 22:57:18 +080049 return TelephonyManager.ACTION_EMERGENCY_ASSISTANCE;
50 }
51
52 /**
Chihhang Chuangf264cfb2018-06-05 15:29:06 +080053 * Query activities of emergency assistance.
54 *
55 * @param context The context of the application.
56 * @return A list of {@link ResolveInfo} which is queried from default assistance package,
57 * or null if there is no installed system application of emergency assistance.
58 */
59 public static List<ResolveInfo> resolveAssistPackageAndQueryActivities(Context context) {
Hongming Jin862ce042019-02-05 15:42:50 -080060 final String assistPackage = getDefaultEmergencyPackage(context);
61 List<ResolveInfo> infos = queryAssistActivities(context, assistPackage);
Chihhang Chuangf264cfb2018-06-05 15:29:06 +080062 if (infos == null || infos.isEmpty()) {
63 PackageManager packageManager = context.getPackageManager();
yuanjiahsucc83a3b2019-05-23 15:29:30 +080064 Intent queryIntent = new Intent(getIntentAction());
Chihhang Chuangf264cfb2018-06-05 15:29:06 +080065 infos = packageManager.queryIntentActivities(queryIntent, 0);
66
67 PackageInfo bestMatch = null;
68 for (int i = 0; i < infos.size(); i++) {
69 if (infos.get(i).activityInfo == null) continue;
70 String packageName = infos.get(i).activityInfo.packageName;
71 PackageInfo packageInfo;
72 try {
73 packageInfo = packageManager.getPackageInfo(packageName, 0);
74 } catch (PackageManager.NameNotFoundException e) {
75 continue;
76 }
77 // Get earliest installed system app.
78 if (isSystemApp(packageInfo) && (bestMatch == null
79 || bestMatch.firstInstallTime > packageInfo.firstInstallTime)) {
80 bestMatch = packageInfo;
81 }
82 }
83
84 if (bestMatch != null) {
Hongming Jin862ce042019-02-05 15:42:50 -080085 setDefaultEmergencyPackageAsync(context, bestMatch.packageName);
86 return queryAssistActivities(context, bestMatch.packageName);
Chihhang Chuangf264cfb2018-06-05 15:29:06 +080087 } else {
88 return null;
89 }
90 } else {
91 return infos;
92 }
93 }
94
95 /**
96 * Compose {@link ComponentName} from {@link ResolveInfo}.
97 */
98 public static ComponentName getComponentName(ResolveInfo resolveInfo) {
99 if (resolveInfo == null || resolveInfo.activityInfo == null) return null;
100 return new ComponentName(resolveInfo.activityInfo.packageName,
101 resolveInfo.activityInfo.name);
102 }
103
Hongming Jin862ce042019-02-05 15:42:50 -0800104 private static List<ResolveInfo> queryAssistActivities(Context context, String assistPackage) {
Chihhang Chuangf264cfb2018-06-05 15:29:06 +0800105 List<ResolveInfo> infos = null;
106
107 if (!TextUtils.isEmpty(assistPackage)) {
yuanjiahsucc83a3b2019-05-23 15:29:30 +0800108 Intent queryIntent = new Intent(getIntentAction())
Chihhang Chuangf264cfb2018-06-05 15:29:06 +0800109 .setPackage(assistPackage);
110 infos = context.getPackageManager().queryIntentActivities(queryIntent, 0);
111 }
112 return infos;
113 }
114
115 private static boolean isSystemApp(PackageInfo info) {
116 return info.applicationInfo != null
117 && (info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
118 }
Hongming Jin862ce042019-02-05 15:42:50 -0800119
120 private static String getDefaultEmergencyPackage(Context context) {
121 long identity = Binder.clearCallingIdentity();
122 try {
123 return CollectionUtils.firstOrNull(context.getSystemService(RoleManager.class)
124 .getRoleHolders(RoleManager.ROLE_EMERGENCY));
125 } finally {
126 Binder.restoreCallingIdentity(identity);
127 }
128 }
129
130 private static boolean setDefaultEmergencyPackageAsync(Context context, String pkgName) {
131 long identity = Binder.clearCallingIdentity();
132 try {
133 context.getSystemService(RoleManager.class).addRoleHolderAsUser(
134 RoleManager.ROLE_EMERGENCY, pkgName, 0, Process.myUserHandle(),
Hai Zhang651617b2019-03-06 20:40:39 -0800135 AsyncTask.THREAD_POOL_EXECUTOR, successful -> {
136 if (!successful) {
Hongming Jin862ce042019-02-05 15:42:50 -0800137 Log.e(TAG, "Failed to set emergency default app.");
138 }
139 });
140 } finally {
141 Binder.restoreCallingIdentity(identity);
142 }
143 return true;
144 }
Chihhang Chuangf264cfb2018-06-05 15:29:06 +0800145}