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