Nicolas Prevot | 10fa67c | 2014-03-24 13:44:38 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2014 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.internal.app; |
| 18 | |
arangelov | 64439c1e | 2018-07-31 14:18:47 +0100 | [diff] [blame] | 19 | import static android.content.pm.PackageManager.MATCH_DEFAULT_ONLY; |
| 20 | |
| 21 | import android.annotation.Nullable; |
| 22 | import android.annotation.StringRes; |
Nicolas Prevot | 10fa67c | 2014-03-24 13:44:38 +0000 | [diff] [blame] | 23 | import android.app.Activity; |
Wale Ogunwale | 04d9cb5 | 2018-04-30 13:55:07 -0700 | [diff] [blame] | 24 | import android.app.ActivityTaskManager; |
Jeff Sharkey | 9797880 | 2014-10-14 10:48:18 -0700 | [diff] [blame] | 25 | import android.app.ActivityThread; |
Nicolas Prevot | 10fa67c | 2014-03-24 13:44:38 +0000 | [diff] [blame] | 26 | import android.app.AppGlobals; |
Jeff Sharkey | 9797880 | 2014-10-14 10:48:18 -0700 | [diff] [blame] | 27 | import android.app.admin.DevicePolicyManager; |
Artur Satayev | ed5a6ae | 2019-12-10 17:47:54 +0000 | [diff] [blame] | 28 | import android.compat.annotation.UnsupportedAppUsage; |
arangelov | 590fba3 | 2020-02-11 18:05:42 +0000 | [diff] [blame] | 29 | import android.content.ContentResolver; |
Nicolas Prevot | 10fa67c | 2014-03-24 13:44:38 +0000 | [diff] [blame] | 30 | import android.content.Intent; |
arangelov | 64439c1e | 2018-07-31 14:18:47 +0100 | [diff] [blame] | 31 | import android.content.pm.ActivityInfo; |
Nicolas Prevot | 10fa67c | 2014-03-24 13:44:38 +0000 | [diff] [blame] | 32 | import android.content.pm.IPackageManager; |
Tony Mak | 96d78f5 | 2017-05-03 18:53:21 +0100 | [diff] [blame] | 33 | import android.content.pm.PackageManager; |
arangelov | 64439c1e | 2018-07-31 14:18:47 +0100 | [diff] [blame] | 34 | import android.content.pm.ResolveInfo; |
Nicolas Prevot | 10fa67c | 2014-03-24 13:44:38 +0000 | [diff] [blame] | 35 | import android.content.pm.UserInfo; |
Susi Kharraz-Post | 0446fab | 2019-02-21 09:42:31 -0500 | [diff] [blame] | 36 | import android.metrics.LogMaker; |
Jeff Sharkey | 9797880 | 2014-10-14 10:48:18 -0700 | [diff] [blame] | 37 | import android.os.Bundle; |
Robin Lee | 3ea4310 | 2014-07-23 23:41:31 +0100 | [diff] [blame] | 38 | import android.os.RemoteException; |
Nicolas Prevot | 10fa67c | 2014-03-24 13:44:38 +0000 | [diff] [blame] | 39 | import android.os.UserHandle; |
| 40 | import android.os.UserManager; |
Nicolas Prevot | 10fa67c | 2014-03-24 13:44:38 +0000 | [diff] [blame] | 41 | import android.util.Slog; |
Robin Lee | 3ea4310 | 2014-07-23 23:41:31 +0100 | [diff] [blame] | 42 | import android.widget.Toast; |
Alison Cichowlas | 3e34050 | 2018-08-07 17:15:01 -0400 | [diff] [blame] | 43 | |
Tony Mak | 96d78f5 | 2017-05-03 18:53:21 +0100 | [diff] [blame] | 44 | import com.android.internal.annotations.VisibleForTesting; |
Susi Kharraz-Post | 0446fab | 2019-02-21 09:42:31 -0500 | [diff] [blame] | 45 | import com.android.internal.logging.MetricsLogger; |
| 46 | import com.android.internal.logging.nano.MetricsProto.MetricsEvent; |
Alison Cichowlas | 3e34050 | 2018-08-07 17:15:01 -0400 | [diff] [blame] | 47 | |
arangelov | 64439c1e | 2018-07-31 14:18:47 +0100 | [diff] [blame] | 48 | import java.util.Arrays; |
| 49 | import java.util.HashSet; |
Nicolas Prevot | 10fa67c | 2014-03-24 13:44:38 +0000 | [diff] [blame] | 50 | import java.util.List; |
arangelov | 64439c1e | 2018-07-31 14:18:47 +0100 | [diff] [blame] | 51 | import java.util.Set; |
Tony Mak | 96d78f5 | 2017-05-03 18:53:21 +0100 | [diff] [blame] | 52 | |
Jeff Sharkey | 9797880 | 2014-10-14 10:48:18 -0700 | [diff] [blame] | 53 | /** |
| 54 | * This is used in conjunction with |
| 55 | * {@link DevicePolicyManager#addCrossProfileIntentFilter} to enable intents to |
| 56 | * be passed in and out of a managed profile. |
Nicolas Prevot | 10fa67c | 2014-03-24 13:44:38 +0000 | [diff] [blame] | 57 | */ |
Nicolas Prevot | 10fa67c | 2014-03-24 13:44:38 +0000 | [diff] [blame] | 58 | public class IntentForwarderActivity extends Activity { |
Andrei Onea | 1588439 | 2019-03-22 17:28:11 +0000 | [diff] [blame] | 59 | @UnsupportedAppUsage |
Nicolas Prevot | 10fa67c | 2014-03-24 13:44:38 +0000 | [diff] [blame] | 60 | public static String TAG = "IntentForwarderActivity"; |
| 61 | |
Nicolas Prevot | 741abfc | 2015-08-11 12:03:51 +0100 | [diff] [blame] | 62 | public static String FORWARD_INTENT_TO_PARENT |
| 63 | = "com.android.internal.app.ForwardIntentToParent"; |
Nicolas Prevot | 10fa67c | 2014-03-24 13:44:38 +0000 | [diff] [blame] | 64 | |
| 65 | public static String FORWARD_INTENT_TO_MANAGED_PROFILE |
| 66 | = "com.android.internal.app.ForwardIntentToManagedProfile"; |
| 67 | |
arangelov | 3830374 | 2018-08-14 20:14:12 +0100 | [diff] [blame] | 68 | private static final Set<String> ALLOWED_TEXT_MESSAGE_SCHEMES |
arangelov | 64439c1e | 2018-07-31 14:18:47 +0100 | [diff] [blame] | 69 | = new HashSet<>(Arrays.asList("sms", "smsto", "mms", "mmsto")); |
| 70 | |
arangelov | 3830374 | 2018-08-14 20:14:12 +0100 | [diff] [blame] | 71 | private static final String TEL_SCHEME = "tel"; |
| 72 | |
Tony Mak | 96d78f5 | 2017-05-03 18:53:21 +0100 | [diff] [blame] | 73 | private Injector mInjector; |
| 74 | |
Susi Kharraz-Post | 0446fab | 2019-02-21 09:42:31 -0500 | [diff] [blame] | 75 | private MetricsLogger mMetricsLogger; |
| 76 | |
Nicolas Prevot | 10fa67c | 2014-03-24 13:44:38 +0000 | [diff] [blame] | 77 | @Override |
| 78 | protected void onCreate(Bundle savedInstanceState) { |
| 79 | super.onCreate(savedInstanceState); |
Tony Mak | 96d78f5 | 2017-05-03 18:53:21 +0100 | [diff] [blame] | 80 | mInjector = createInjector(); |
Nicolas Prevot | 10fa67c | 2014-03-24 13:44:38 +0000 | [diff] [blame] | 81 | |
Tony Mak | 96d78f5 | 2017-05-03 18:53:21 +0100 | [diff] [blame] | 82 | Intent intentReceived = getIntent(); |
Nicolas Prevot | 10fa67c | 2014-03-24 13:44:38 +0000 | [diff] [blame] | 83 | String className = intentReceived.getComponent().getClassName(); |
Nicolas Prevot | 0e2b73f | 2014-10-27 10:06:11 +0000 | [diff] [blame] | 84 | final int targetUserId; |
Robin Lee | 3ea4310 | 2014-07-23 23:41:31 +0100 | [diff] [blame] | 85 | final int userMessageId; |
Nicolas Prevot | 741abfc | 2015-08-11 12:03:51 +0100 | [diff] [blame] | 86 | if (className.equals(FORWARD_INTENT_TO_PARENT)) { |
Robin Lee | 3ea4310 | 2014-07-23 23:41:31 +0100 | [diff] [blame] | 87 | userMessageId = com.android.internal.R.string.forward_intent_to_owner; |
Nicolas Prevot | 741abfc | 2015-08-11 12:03:51 +0100 | [diff] [blame] | 88 | targetUserId = getProfileParent(); |
Susi Kharraz-Post | 0446fab | 2019-02-21 09:42:31 -0500 | [diff] [blame] | 89 | |
| 90 | getMetricsLogger().write( |
| 91 | new LogMaker(MetricsEvent.ACTION_SWITCH_SHARE_PROFILE) |
| 92 | .setSubtype(MetricsEvent.PARENT_PROFILE)); |
Nicolas Prevot | 10fa67c | 2014-03-24 13:44:38 +0000 | [diff] [blame] | 93 | } else if (className.equals(FORWARD_INTENT_TO_MANAGED_PROFILE)) { |
Robin Lee | 3ea4310 | 2014-07-23 23:41:31 +0100 | [diff] [blame] | 94 | userMessageId = com.android.internal.R.string.forward_intent_to_work; |
Nicolas Prevot | 0e2b73f | 2014-10-27 10:06:11 +0000 | [diff] [blame] | 95 | targetUserId = getManagedProfile(); |
Susi Kharraz-Post | 0446fab | 2019-02-21 09:42:31 -0500 | [diff] [blame] | 96 | |
| 97 | getMetricsLogger().write( |
| 98 | new LogMaker(MetricsEvent.ACTION_SWITCH_SHARE_PROFILE) |
| 99 | .setSubtype(MetricsEvent.MANAGED_PROFILE)); |
Nicolas Prevot | 10fa67c | 2014-03-24 13:44:38 +0000 | [diff] [blame] | 100 | } else { |
| 101 | Slog.wtf(TAG, IntentForwarderActivity.class.getName() + " cannot be called directly"); |
Robin Lee | 3ea4310 | 2014-07-23 23:41:31 +0100 | [diff] [blame] | 102 | userMessageId = -1; |
Nicolas Prevot | 0e2b73f | 2014-10-27 10:06:11 +0000 | [diff] [blame] | 103 | targetUserId = UserHandle.USER_NULL; |
Nicolas Prevot | 10fa67c | 2014-03-24 13:44:38 +0000 | [diff] [blame] | 104 | } |
Nicolas Prevot | 0e2b73f | 2014-10-27 10:06:11 +0000 | [diff] [blame] | 105 | if (targetUserId == UserHandle.USER_NULL) { |
Nicolas Prevot | 741abfc | 2015-08-11 12:03:51 +0100 | [diff] [blame] | 106 | // This covers the case where there is no parent / managed profile. |
Nicolas Prevot | 10fa67c | 2014-03-24 13:44:38 +0000 | [diff] [blame] | 107 | finish(); |
| 108 | return; |
| 109 | } |
Nicolas Prevot | 0e2b73f | 2014-10-27 10:06:11 +0000 | [diff] [blame] | 110 | |
Tony Mak | 96d78f5 | 2017-05-03 18:53:21 +0100 | [diff] [blame] | 111 | final int callingUserId = getUserId(); |
arangelov | 590fba3 | 2020-02-11 18:05:42 +0000 | [diff] [blame] | 112 | final Intent newIntent = canForward(intentReceived, getUserId(), targetUserId, |
| 113 | mInjector.getIPackageManager(), getContentResolver()); |
Tony Mak | 96d78f5 | 2017-05-03 18:53:21 +0100 | [diff] [blame] | 114 | if (newIntent != null) { |
Nicolas Prevot | decd9ea | 2016-02-03 16:18:03 +0000 | [diff] [blame] | 115 | if (Intent.ACTION_CHOOSER.equals(newIntent.getAction())) { |
Tony Mak | 96d78f5 | 2017-05-03 18:53:21 +0100 | [diff] [blame] | 116 | Intent innerIntent = newIntent.getParcelableExtra(Intent.EXTRA_INTENT); |
Nicolas Prevot | decd9ea | 2016-02-03 16:18:03 +0000 | [diff] [blame] | 117 | // At this point, innerIntent is not null. Otherwise, canForward would have returned |
| 118 | // false. |
Nicolas Prevot | 107f7b7 | 2015-07-01 16:31:48 +0100 | [diff] [blame] | 119 | innerIntent.prepareToLeaveUser(callingUserId); |
Matt Pietal | 51ea0d6 | 2019-04-02 10:10:22 -0400 | [diff] [blame] | 120 | innerIntent.fixUris(callingUserId); |
Nicolas Prevot | 0e2b73f | 2014-10-27 10:06:11 +0000 | [diff] [blame] | 121 | } else { |
Nicolas Prevot | 107f7b7 | 2015-07-01 16:31:48 +0100 | [diff] [blame] | 122 | newIntent.prepareToLeaveUser(callingUserId); |
Nicolas Prevot | 0e2b73f | 2014-10-27 10:06:11 +0000 | [diff] [blame] | 123 | } |
Robin Lee | 3ea4310 | 2014-07-23 23:41:31 +0100 | [diff] [blame] | 124 | |
arangelov | 64439c1e | 2018-07-31 14:18:47 +0100 | [diff] [blame] | 125 | final ResolveInfo ri = mInjector.resolveActivityAsUser(newIntent, MATCH_DEFAULT_ONLY, |
| 126 | targetUserId); |
Jeff Sharkey | 9797880 | 2014-10-14 10:48:18 -0700 | [diff] [blame] | 127 | try { |
Alison Cichowlas | 3e34050 | 2018-08-07 17:15:01 -0400 | [diff] [blame] | 128 | startActivityAsCaller(newIntent, null, null, false, targetUserId); |
Jeff Sharkey | 9797880 | 2014-10-14 10:48:18 -0700 | [diff] [blame] | 129 | } catch (RuntimeException e) { |
| 130 | int launchedFromUid = -1; |
| 131 | String launchedFromPackage = "?"; |
| 132 | try { |
Wale Ogunwale | 04d9cb5 | 2018-04-30 13:55:07 -0700 | [diff] [blame] | 133 | launchedFromUid = ActivityTaskManager.getService().getLaunchedFromUid( |
Jeff Sharkey | 9797880 | 2014-10-14 10:48:18 -0700 | [diff] [blame] | 134 | getActivityToken()); |
Wale Ogunwale | 04d9cb5 | 2018-04-30 13:55:07 -0700 | [diff] [blame] | 135 | launchedFromPackage = ActivityTaskManager.getService().getLaunchedFromPackage( |
Jeff Sharkey | 9797880 | 2014-10-14 10:48:18 -0700 | [diff] [blame] | 136 | getActivityToken()); |
| 137 | } catch (RemoteException ignored) { |
| 138 | } |
| 139 | |
| 140 | Slog.wtf(TAG, "Unable to launch as UID " + launchedFromUid + " package " |
| 141 | + launchedFromPackage + ", while running in " |
| 142 | + ActivityThread.currentProcessName(), e); |
| 143 | } |
Robin Lee | 3ea4310 | 2014-07-23 23:41:31 +0100 | [diff] [blame] | 144 | |
arangelov | 64439c1e | 2018-07-31 14:18:47 +0100 | [diff] [blame] | 145 | if (shouldShowDisclosure(ri, intentReceived)) { |
| 146 | mInjector.showToast(userMessageId, Toast.LENGTH_LONG); |
Robin Lee | 3ea4310 | 2014-07-23 23:41:31 +0100 | [diff] [blame] | 147 | } |
Nicolas Prevot | 10fa67c | 2014-03-24 13:44:38 +0000 | [diff] [blame] | 148 | } else { |
Tony Mak | 96d78f5 | 2017-05-03 18:53:21 +0100 | [diff] [blame] | 149 | Slog.wtf(TAG, "the intent: " + intentReceived + " cannot be forwarded from user " |
Nicolas Prevot | 0e2b73f | 2014-10-27 10:06:11 +0000 | [diff] [blame] | 150 | + callingUserId + " to user " + targetUserId); |
Nicolas Prevot | 10fa67c | 2014-03-24 13:44:38 +0000 | [diff] [blame] | 151 | } |
| 152 | finish(); |
| 153 | } |
| 154 | |
arangelov | 64439c1e | 2018-07-31 14:18:47 +0100 | [diff] [blame] | 155 | private boolean shouldShowDisclosure(@Nullable ResolveInfo ri, Intent intent) { |
| 156 | if (ri == null || ri.activityInfo == null) { |
| 157 | return true; |
| 158 | } |
| 159 | if (ri.activityInfo.applicationInfo.isSystemApp() |
| 160 | && (isDialerIntent(intent) || isTextMessageIntent(intent))) { |
| 161 | return false; |
| 162 | } |
| 163 | return !isTargetResolverOrChooserActivity(ri.activityInfo); |
| 164 | } |
| 165 | |
| 166 | private boolean isTextMessageIntent(Intent intent) { |
arangelov | 3830374 | 2018-08-14 20:14:12 +0100 | [diff] [blame] | 167 | return (Intent.ACTION_SENDTO.equals(intent.getAction()) || isViewActionIntent(intent)) |
| 168 | && ALLOWED_TEXT_MESSAGE_SCHEMES.contains(intent.getScheme()); |
arangelov | 64439c1e | 2018-07-31 14:18:47 +0100 | [diff] [blame] | 169 | } |
| 170 | |
| 171 | private boolean isDialerIntent(Intent intent) { |
| 172 | return Intent.ACTION_DIAL.equals(intent.getAction()) |
arangelov | 3830374 | 2018-08-14 20:14:12 +0100 | [diff] [blame] | 173 | || Intent.ACTION_CALL.equals(intent.getAction()) |
| 174 | || Intent.ACTION_CALL_PRIVILEGED.equals(intent.getAction()) |
| 175 | || Intent.ACTION_CALL_EMERGENCY.equals(intent.getAction()) |
| 176 | || (isViewActionIntent(intent) && TEL_SCHEME.equals(intent.getScheme())); |
| 177 | } |
| 178 | |
| 179 | private boolean isViewActionIntent(Intent intent) { |
| 180 | return Intent.ACTION_VIEW.equals(intent.getAction()) |
| 181 | && intent.hasCategory(Intent.CATEGORY_BROWSABLE); |
arangelov | 64439c1e | 2018-07-31 14:18:47 +0100 | [diff] [blame] | 182 | } |
| 183 | |
| 184 | private boolean isTargetResolverOrChooserActivity(ActivityInfo activityInfo) { |
| 185 | if (!"android".equals(activityInfo.packageName)) { |
| 186 | return false; |
| 187 | } |
| 188 | return ResolverActivity.class.getName().equals(activityInfo.name) |
| 189 | || ChooserActivity.class.getName().equals(activityInfo.name); |
| 190 | } |
| 191 | |
Tony Mak | 96d78f5 | 2017-05-03 18:53:21 +0100 | [diff] [blame] | 192 | /** |
| 193 | * Check whether the intent can be forwarded to target user. Return the intent used for |
| 194 | * forwarding if it can be forwarded, {@code null} otherwise. |
| 195 | */ |
arangelov | 590fba3 | 2020-02-11 18:05:42 +0000 | [diff] [blame] | 196 | static Intent canForward(Intent incomingIntent, int sourceUserId, int targetUserId, |
| 197 | IPackageManager packageManager, ContentResolver contentResolver) { |
Tony Mak | 96d78f5 | 2017-05-03 18:53:21 +0100 | [diff] [blame] | 198 | Intent forwardIntent = new Intent(incomingIntent); |
| 199 | forwardIntent.addFlags( |
| 200 | Intent.FLAG_ACTIVITY_FORWARD_RESULT | Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP); |
| 201 | sanitizeIntent(forwardIntent); |
| 202 | |
| 203 | Intent intentToCheck = forwardIntent; |
| 204 | if (Intent.ACTION_CHOOSER.equals(forwardIntent.getAction())) { |
Nicolas Prevot | 0e2b73f | 2014-10-27 10:06:11 +0000 | [diff] [blame] | 205 | // The EXTRA_INITIAL_INTENTS may not be allowed to be forwarded. |
Tony Mak | 96d78f5 | 2017-05-03 18:53:21 +0100 | [diff] [blame] | 206 | if (forwardIntent.hasExtra(Intent.EXTRA_INITIAL_INTENTS)) { |
Nicolas Prevot | 0e2b73f | 2014-10-27 10:06:11 +0000 | [diff] [blame] | 207 | Slog.wtf(TAG, "An chooser intent with extra initial intents cannot be forwarded to" |
| 208 | + " a different user"); |
Tony Mak | 96d78f5 | 2017-05-03 18:53:21 +0100 | [diff] [blame] | 209 | return null; |
Nicolas Prevot | 0e2b73f | 2014-10-27 10:06:11 +0000 | [diff] [blame] | 210 | } |
Tony Mak | 96d78f5 | 2017-05-03 18:53:21 +0100 | [diff] [blame] | 211 | if (forwardIntent.hasExtra(Intent.EXTRA_REPLACEMENT_EXTRAS)) { |
Nicolas Prevot | 0e2b73f | 2014-10-27 10:06:11 +0000 | [diff] [blame] | 212 | Slog.wtf(TAG, "A chooser intent with replacement extras cannot be forwarded to a" |
| 213 | + " different user"); |
Tony Mak | 96d78f5 | 2017-05-03 18:53:21 +0100 | [diff] [blame] | 214 | return null; |
Nicolas Prevot | 0e2b73f | 2014-10-27 10:06:11 +0000 | [diff] [blame] | 215 | } |
Tony Mak | 96d78f5 | 2017-05-03 18:53:21 +0100 | [diff] [blame] | 216 | intentToCheck = forwardIntent.getParcelableExtra(Intent.EXTRA_INTENT); |
| 217 | if (intentToCheck == null) { |
Nicolas Prevot | decd9ea | 2016-02-03 16:18:03 +0000 | [diff] [blame] | 218 | Slog.wtf(TAG, "Cannot forward a chooser intent with no extra " |
| 219 | + Intent.EXTRA_INTENT); |
Tony Mak | 96d78f5 | 2017-05-03 18:53:21 +0100 | [diff] [blame] | 220 | return null; |
Nicolas Prevot | decd9ea | 2016-02-03 16:18:03 +0000 | [diff] [blame] | 221 | } |
Nicolas Prevot | 0e2b73f | 2014-10-27 10:06:11 +0000 | [diff] [blame] | 222 | } |
Tony Mak | 96d78f5 | 2017-05-03 18:53:21 +0100 | [diff] [blame] | 223 | if (forwardIntent.getSelector() != null) { |
| 224 | intentToCheck = forwardIntent.getSelector(); |
Nicolas Prevot | 0e2b73f | 2014-10-27 10:06:11 +0000 | [diff] [blame] | 225 | } |
arangelov | 590fba3 | 2020-02-11 18:05:42 +0000 | [diff] [blame] | 226 | String resolvedType = intentToCheck.resolveTypeIfNeeded(contentResolver); |
Tony Mak | 96d78f5 | 2017-05-03 18:53:21 +0100 | [diff] [blame] | 227 | sanitizeIntent(intentToCheck); |
Nicolas Prevot | 0e2b73f | 2014-10-27 10:06:11 +0000 | [diff] [blame] | 228 | try { |
arangelov | 590fba3 | 2020-02-11 18:05:42 +0000 | [diff] [blame] | 229 | if (packageManager.canForwardTo( |
| 230 | intentToCheck, resolvedType, sourceUserId, targetUserId)) { |
Tony Mak | 96d78f5 | 2017-05-03 18:53:21 +0100 | [diff] [blame] | 231 | return forwardIntent; |
| 232 | } |
Nicolas Prevot | 0e2b73f | 2014-10-27 10:06:11 +0000 | [diff] [blame] | 233 | } catch (RemoteException e) { |
| 234 | Slog.e(TAG, "PackageManagerService is dead?"); |
Nicolas Prevot | 0e2b73f | 2014-10-27 10:06:11 +0000 | [diff] [blame] | 235 | } |
Tony Mak | 96d78f5 | 2017-05-03 18:53:21 +0100 | [diff] [blame] | 236 | return null; |
Nicolas Prevot | 0e2b73f | 2014-10-27 10:06:11 +0000 | [diff] [blame] | 237 | } |
| 238 | |
Nicolas Prevot | 10fa67c | 2014-03-24 13:44:38 +0000 | [diff] [blame] | 239 | /** |
Nicolas Prevot | 0e2b73f | 2014-10-27 10:06:11 +0000 | [diff] [blame] | 240 | * Returns the userId of the managed profile for this device or UserHandle.USER_NULL if there is |
| 241 | * no managed profile. |
Nicolas Prevot | 10fa67c | 2014-03-24 13:44:38 +0000 | [diff] [blame] | 242 | * |
| 243 | * TODO: Remove the assumption that there is only one managed profile |
| 244 | * on the device. |
| 245 | */ |
Nicolas Prevot | 0e2b73f | 2014-10-27 10:06:11 +0000 | [diff] [blame] | 246 | private int getManagedProfile() { |
Tony Mak | 96d78f5 | 2017-05-03 18:53:21 +0100 | [diff] [blame] | 247 | List<UserInfo> relatedUsers = mInjector.getUserManager().getProfiles(UserHandle.myUserId()); |
Nicolas Prevot | 10fa67c | 2014-03-24 13:44:38 +0000 | [diff] [blame] | 248 | for (UserInfo userInfo : relatedUsers) { |
Nicolas Prevot | 0e2b73f | 2014-10-27 10:06:11 +0000 | [diff] [blame] | 249 | if (userInfo.isManagedProfile()) return userInfo.id; |
Nicolas Prevot | 10fa67c | 2014-03-24 13:44:38 +0000 | [diff] [blame] | 250 | } |
| 251 | Slog.wtf(TAG, FORWARD_INTENT_TO_MANAGED_PROFILE |
| 252 | + " has been called, but there is no managed profile"); |
Nicolas Prevot | 0e2b73f | 2014-10-27 10:06:11 +0000 | [diff] [blame] | 253 | return UserHandle.USER_NULL; |
Nicolas Prevot | 10fa67c | 2014-03-24 13:44:38 +0000 | [diff] [blame] | 254 | } |
Nicolas Prevot | 741abfc | 2015-08-11 12:03:51 +0100 | [diff] [blame] | 255 | |
| 256 | /** |
| 257 | * Returns the userId of the profile parent or UserHandle.USER_NULL if there is |
| 258 | * no parent. |
| 259 | */ |
| 260 | private int getProfileParent() { |
Tony Mak | 96d78f5 | 2017-05-03 18:53:21 +0100 | [diff] [blame] | 261 | UserInfo parent = mInjector.getUserManager().getProfileParent(UserHandle.myUserId()); |
Nicolas Prevot | 741abfc | 2015-08-11 12:03:51 +0100 | [diff] [blame] | 262 | if (parent == null) { |
| 263 | Slog.wtf(TAG, FORWARD_INTENT_TO_PARENT |
| 264 | + " has been called, but there is no parent"); |
| 265 | return UserHandle.USER_NULL; |
| 266 | } |
| 267 | return parent.id; |
| 268 | } |
Tony Mak | 96d78f5 | 2017-05-03 18:53:21 +0100 | [diff] [blame] | 269 | |
| 270 | /** |
| 271 | * Sanitize the intent in place. |
| 272 | */ |
arangelov | 590fba3 | 2020-02-11 18:05:42 +0000 | [diff] [blame] | 273 | private static void sanitizeIntent(Intent intent) { |
Tony Mak | 96d78f5 | 2017-05-03 18:53:21 +0100 | [diff] [blame] | 274 | // Apps should not be allowed to target a specific package/ component in the target user. |
| 275 | intent.setPackage(null); |
| 276 | intent.setComponent(null); |
| 277 | } |
| 278 | |
Susi Kharraz-Post | 0446fab | 2019-02-21 09:42:31 -0500 | [diff] [blame] | 279 | protected MetricsLogger getMetricsLogger() { |
| 280 | if (mMetricsLogger == null) { |
| 281 | mMetricsLogger = new MetricsLogger(); |
| 282 | } |
| 283 | return mMetricsLogger; |
| 284 | } |
| 285 | |
Tony Mak | 96d78f5 | 2017-05-03 18:53:21 +0100 | [diff] [blame] | 286 | @VisibleForTesting |
| 287 | protected Injector createInjector() { |
| 288 | return new InjectorImpl(); |
| 289 | } |
| 290 | |
| 291 | private class InjectorImpl implements Injector { |
| 292 | |
| 293 | @Override |
| 294 | public IPackageManager getIPackageManager() { |
| 295 | return AppGlobals.getPackageManager(); |
| 296 | } |
| 297 | |
| 298 | @Override |
| 299 | public UserManager getUserManager() { |
| 300 | return getSystemService(UserManager.class); |
| 301 | } |
| 302 | |
| 303 | @Override |
| 304 | public PackageManager getPackageManager() { |
| 305 | return IntentForwarderActivity.this.getPackageManager(); |
| 306 | } |
arangelov | 64439c1e | 2018-07-31 14:18:47 +0100 | [diff] [blame] | 307 | |
| 308 | @Override |
| 309 | public ResolveInfo resolveActivityAsUser(Intent intent, int flags, int userId) { |
| 310 | return getPackageManager().resolveActivityAsUser(intent, flags, userId); |
| 311 | } |
| 312 | |
| 313 | @Override |
| 314 | public void showToast(int messageId, int duration) { |
| 315 | Toast.makeText(IntentForwarderActivity.this, getString(messageId), duration).show(); |
| 316 | } |
Tony Mak | 96d78f5 | 2017-05-03 18:53:21 +0100 | [diff] [blame] | 317 | } |
| 318 | |
| 319 | public interface Injector { |
| 320 | IPackageManager getIPackageManager(); |
| 321 | |
| 322 | UserManager getUserManager(); |
| 323 | |
| 324 | PackageManager getPackageManager(); |
arangelov | 64439c1e | 2018-07-31 14:18:47 +0100 | [diff] [blame] | 325 | |
| 326 | ResolveInfo resolveActivityAsUser(Intent intent, int flags, int userId); |
| 327 | |
| 328 | void showToast(@StringRes int messageId, int duration); |
Tony Mak | 96d78f5 | 2017-05-03 18:53:21 +0100 | [diff] [blame] | 329 | } |
Nicolas Prevot | 10fa67c | 2014-03-24 13:44:38 +0000 | [diff] [blame] | 330 | } |