blob: a98d81d21df5cc76df24012096c3e9665b77777c [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;
20import android.app.role.RoleManagerCallback;
Chihhang Chuangf264cfb2018-06-05 15:29:06 +080021import android.content.ComponentName;
22import android.content.Context;
23import android.content.Intent;
24import android.content.pm.ApplicationInfo;
25import android.content.pm.PackageInfo;
26import android.content.pm.PackageManager;
27import android.content.pm.ResolveInfo;
Hongming Jin862ce042019-02-05 15:42:50 -080028import android.os.AsyncTask;
29import android.os.Binder;
30import android.os.Process;
Chihhang Chuangf264cfb2018-06-05 15:29:06 +080031import android.telephony.TelephonyManager;
32import android.text.TextUtils;
yuanjiahsubc20ba82018-11-26 22:57:18 +080033import android.util.FeatureFlagUtils;
Hongming Jin862ce042019-02-05 15:42:50 -080034import android.util.Log;
35
36import com.android.internal.util.CollectionUtils;
Chihhang Chuangf264cfb2018-06-05 15:29:06 +080037
38import java.util.List;
39
40/**
41 * A helper to query activities of emergency assistance.
42 */
43public class EmergencyAssistanceHelper {
Hongming Jin862ce042019-02-05 15:42:50 -080044 private static final String TAG = EmergencyAssistanceHelper.class.getSimpleName();
Chihhang Chuangf264cfb2018-06-05 15:29:06 +080045 /**
yuanjiahsubc20ba82018-11-26 22:57:18 +080046 * Get intent action of target emergency app.
47 *
48 * @param context The context of the application.
49 * @return A string of intent action to launch target emergency app by feature flag, it will be
50 * used for team food.
51 */
52 public static String getIntentAction(Context context) {
53 if (FeatureFlagUtils.isEnabled(context, FeatureFlagUtils.SAFETY_HUB)) {
54 String action = context.getResources().getString(R.string.config_emergency_app_intent);
55 if (!action.isEmpty()) {
56 return action;
57 }
58 }
59
60 return TelephonyManager.ACTION_EMERGENCY_ASSISTANCE;
61 }
62
63 /**
Chihhang Chuangf264cfb2018-06-05 15:29:06 +080064 * Query activities of emergency assistance.
65 *
66 * @param context The context of the application.
67 * @return A list of {@link ResolveInfo} which is queried from default assistance package,
68 * or null if there is no installed system application of emergency assistance.
69 */
70 public static List<ResolveInfo> resolveAssistPackageAndQueryActivities(Context context) {
Hongming Jin862ce042019-02-05 15:42:50 -080071 final String assistPackage = getDefaultEmergencyPackage(context);
72 List<ResolveInfo> infos = queryAssistActivities(context, assistPackage);
Chihhang Chuangf264cfb2018-06-05 15:29:06 +080073 if (infos == null || infos.isEmpty()) {
74 PackageManager packageManager = context.getPackageManager();
yuanjiahsubc20ba82018-11-26 22:57:18 +080075 Intent queryIntent = new Intent(getIntentAction(context));
Chihhang Chuangf264cfb2018-06-05 15:29:06 +080076 infos = packageManager.queryIntentActivities(queryIntent, 0);
77
78 PackageInfo bestMatch = null;
79 for (int i = 0; i < infos.size(); i++) {
80 if (infos.get(i).activityInfo == null) continue;
81 String packageName = infos.get(i).activityInfo.packageName;
82 PackageInfo packageInfo;
83 try {
84 packageInfo = packageManager.getPackageInfo(packageName, 0);
85 } catch (PackageManager.NameNotFoundException e) {
86 continue;
87 }
88 // Get earliest installed system app.
89 if (isSystemApp(packageInfo) && (bestMatch == null
90 || bestMatch.firstInstallTime > packageInfo.firstInstallTime)) {
91 bestMatch = packageInfo;
92 }
93 }
94
95 if (bestMatch != null) {
Hongming Jin862ce042019-02-05 15:42:50 -080096 setDefaultEmergencyPackageAsync(context, bestMatch.packageName);
97 return queryAssistActivities(context, bestMatch.packageName);
Chihhang Chuangf264cfb2018-06-05 15:29:06 +080098 } else {
99 return null;
100 }
101 } else {
102 return infos;
103 }
104 }
105
106 /**
107 * Compose {@link ComponentName} from {@link ResolveInfo}.
108 */
109 public static ComponentName getComponentName(ResolveInfo resolveInfo) {
110 if (resolveInfo == null || resolveInfo.activityInfo == null) return null;
111 return new ComponentName(resolveInfo.activityInfo.packageName,
112 resolveInfo.activityInfo.name);
113 }
114
Hongming Jin862ce042019-02-05 15:42:50 -0800115 private static List<ResolveInfo> queryAssistActivities(Context context, String assistPackage) {
Chihhang Chuangf264cfb2018-06-05 15:29:06 +0800116 List<ResolveInfo> infos = null;
117
118 if (!TextUtils.isEmpty(assistPackage)) {
yuanjiahsubc20ba82018-11-26 22:57:18 +0800119 Intent queryIntent = new Intent(getIntentAction(context))
Chihhang Chuangf264cfb2018-06-05 15:29:06 +0800120 .setPackage(assistPackage);
121 infos = context.getPackageManager().queryIntentActivities(queryIntent, 0);
122 }
123 return infos;
124 }
125
126 private static boolean isSystemApp(PackageInfo info) {
127 return info.applicationInfo != null
128 && (info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
129 }
Hongming Jin862ce042019-02-05 15:42:50 -0800130
131 private static String getDefaultEmergencyPackage(Context context) {
132 long identity = Binder.clearCallingIdentity();
133 try {
134 return CollectionUtils.firstOrNull(context.getSystemService(RoleManager.class)
135 .getRoleHolders(RoleManager.ROLE_EMERGENCY));
136 } finally {
137 Binder.restoreCallingIdentity(identity);
138 }
139 }
140
141 private static boolean setDefaultEmergencyPackageAsync(Context context, String pkgName) {
142 long identity = Binder.clearCallingIdentity();
143 try {
144 context.getSystemService(RoleManager.class).addRoleHolderAsUser(
145 RoleManager.ROLE_EMERGENCY, pkgName, 0, Process.myUserHandle(),
146 AsyncTask.THREAD_POOL_EXECUTOR, new RoleManagerCallback() {
147 @Override
148 public void onSuccess() {
149 }
150 @Override
151 public void onFailure() {
152 Log.e(TAG, "Failed to set emergency default app.");
153 }
154 });
155 } finally {
156 Binder.restoreCallingIdentity(identity);
157 }
158 return true;
159 }
Chihhang Chuangf264cfb2018-06-05 15:29:06 +0800160}