1 /*
2  * Copyright (C) 2006 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.server.am;
18 
19 import static android.app.ActivityManager.START_SUCCESS;
20 
21 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
22 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
23 
24 import android.annotation.Nullable;
25 import android.annotation.RequiresPermission;
26 import android.app.ActivityManager;
27 import android.app.ActivityOptions;
28 import android.app.BackgroundStartPrivileges;
29 import android.app.BroadcastOptions;
30 import android.app.IApplicationThread;
31 import android.app.PendingIntent;
32 import android.app.compat.CompatChanges;
33 import android.compat.annotation.ChangeId;
34 import android.compat.annotation.EnabledAfter;
35 import android.compat.annotation.Overridable;
36 import android.content.IIntentReceiver;
37 import android.content.IIntentSender;
38 import android.content.Intent;
39 import android.os.Binder;
40 import android.os.Build;
41 import android.os.Bundle;
42 import android.os.IBinder;
43 import android.os.PowerWhitelistManager;
44 import android.os.PowerWhitelistManager.ReasonCode;
45 import android.os.RemoteCallbackList;
46 import android.os.RemoteException;
47 import android.os.TransactionTooLargeException;
48 import android.os.UserHandle;
49 import android.util.ArrayMap;
50 import android.util.ArraySet;
51 import android.util.Slog;
52 import android.util.TimeUtils;
53 
54 import com.android.internal.os.IResultReceiver;
55 import com.android.internal.util.function.pooled.PooledLambda;
56 import com.android.server.wm.SafeActivityOptions;
57 
58 import java.io.PrintWriter;
59 import java.lang.ref.WeakReference;
60 import java.util.Objects;
61 
62 public final class PendingIntentRecord extends IIntentSender.Stub {
63     private static final String TAG = TAG_WITH_CLASS_NAME ? "PendingIntentRecord" : TAG_AM;
64 
65     /** If enabled BAL are prevented by default in applications targeting U and later. */
66     @ChangeId
67     @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.TIRAMISU)
68     @Overridable
69     private static final long DEFAULT_RESCIND_BAL_PRIVILEGES_FROM_PENDING_INTENT_SENDER = 244637991;
70 
71     public static final int FLAG_ACTIVITY_SENDER = 1 << 0;
72     public static final int FLAG_BROADCAST_SENDER = 1 << 1;
73     public static final int FLAG_SERVICE_SENDER = 1 << 2;
74 
75     final PendingIntentController controller;
76     final Key key;
77     final int uid;
78     public final WeakReference<PendingIntentRecord> ref;
79     boolean sent = false;
80     boolean canceled = false;
81     /**
82      * Map IBinder to duration specified as Pair<Long, Integer>, Long is allowlist duration in
83      * milliseconds, Integer is allowlist type defined at
84      * {@link android.os.PowerExemptionManager.TempAllowListType}
85      */
86     private ArrayMap<IBinder, TempAllowListDuration> mAllowlistDuration;
87     private RemoteCallbackList<IResultReceiver> mCancelCallbacks;
88     private ArraySet<IBinder> mAllowBgActivityStartsForActivitySender = new ArraySet<>();
89     private ArraySet<IBinder> mAllowBgActivityStartsForBroadcastSender = new ArraySet<>();
90     private ArraySet<IBinder> mAllowBgActivityStartsForServiceSender = new ArraySet<>();
91 
92     String stringName;
93     String lastTagPrefix;
94     String lastTag;
95 
96     final static class Key {
97         final int type;
98         final String packageName;
99         final String featureId;
100         final IBinder activity;
101         final String who;
102         final int requestCode;
103         final Intent requestIntent;
104         final String requestResolvedType;
105         final SafeActivityOptions options;
106         Intent[] allIntents;
107         String[] allResolvedTypes;
108         final int flags;
109         final int hashCode;
110         final int userId;
111 
112         private static final int ODD_PRIME_NUMBER = 37;
113 
Key(int _t, String _p, @Nullable String _featureId, IBinder _a, String _w, int _r, Intent[] _i, String[] _it, int _f, SafeActivityOptions _o, int _userId)114         Key(int _t, String _p, @Nullable String _featureId, IBinder _a, String _w,
115                 int _r, Intent[] _i, String[] _it, int _f, SafeActivityOptions _o, int _userId) {
116             type = _t;
117             packageName = _p;
118             featureId = _featureId;
119             activity = _a;
120             who = _w;
121             requestCode = _r;
122             requestIntent = _i != null ? _i[_i.length-1] : null;
123             requestResolvedType = _it != null ? _it[_it.length-1] : null;
124             allIntents = _i;
125             allResolvedTypes = _it;
126             flags = _f;
127             options = _o;
128             userId = _userId;
129 
130             int hash = 23;
131             hash = (ODD_PRIME_NUMBER*hash) + _f;
132             hash = (ODD_PRIME_NUMBER*hash) + _r;
133             hash = (ODD_PRIME_NUMBER*hash) + _userId;
134             if (_w != null) {
135                 hash = (ODD_PRIME_NUMBER*hash) + _w.hashCode();
136             }
137             if (_a != null) {
138                 hash = (ODD_PRIME_NUMBER*hash) + _a.hashCode();
139             }
140             if (requestIntent != null) {
141                 hash = (ODD_PRIME_NUMBER*hash) + requestIntent.filterHashCode();
142             }
143             if (requestResolvedType != null) {
144                 hash = (ODD_PRIME_NUMBER*hash) + requestResolvedType.hashCode();
145             }
146             hash = (ODD_PRIME_NUMBER*hash) + (_p != null ? _p.hashCode() : 0);
147             hash = (ODD_PRIME_NUMBER*hash) + _t;
148             hashCode = hash;
149             //Slog.i(ActivityManagerService.TAG, this + " hashCode=0x"
150             //        + Integer.toHexString(hashCode));
151         }
152 
153         @Override
equals(Object otherObj)154         public boolean equals(Object otherObj) {
155             if (otherObj == null) {
156                 return false;
157             }
158             try {
159                 Key other = (Key)otherObj;
160                 if (type != other.type) {
161                     return false;
162                 }
163                 if (userId != other.userId){
164                     return false;
165                 }
166                 if (!Objects.equals(packageName, other.packageName)) {
167                     return false;
168                 }
169                 if (!Objects.equals(featureId, other.featureId)) {
170                     return false;
171                 }
172                 if (activity != other.activity) {
173                     return false;
174                 }
175                 if (!Objects.equals(who, other.who)) {
176                     return false;
177                 }
178                 if (requestCode != other.requestCode) {
179                     return false;
180                 }
181                 if (requestIntent != other.requestIntent) {
182                     if (requestIntent != null) {
183                         if (!requestIntent.filterEquals(other.requestIntent)) {
184                             return false;
185                         }
186                     } else if (other.requestIntent != null) {
187                         return false;
188                     }
189                 }
190                 if (!Objects.equals(requestResolvedType, other.requestResolvedType)) {
191                     return false;
192                 }
193                 if (flags != other.flags) {
194                     return false;
195                 }
196                 return true;
197             } catch (ClassCastException e) {
198             }
199             return false;
200         }
201 
hashCode()202         public int hashCode() {
203             return hashCode;
204         }
205 
toString()206         public String toString() {
207             return "Key{" + typeName()
208                 + " pkg=" + packageName + (featureId != null ? "/" + featureId : "")
209                 + " intent="
210                 + (requestIntent != null
211                         ? requestIntent.toShortString(false, true, false, false) : "<null>")
212                 + " flags=0x" + Integer.toHexString(flags) + " u=" + userId + "}"
213                 + " requestCode=" + requestCode;
214         }
215 
typeName()216         String typeName() {
217             switch (type) {
218                 case ActivityManager.INTENT_SENDER_ACTIVITY:
219                     return "startActivity";
220                 case ActivityManager.INTENT_SENDER_BROADCAST:
221                     return "broadcastIntent";
222                 case ActivityManager.INTENT_SENDER_SERVICE:
223                     return "startService";
224                 case ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE:
225                     return "startForegroundService";
226                 case ActivityManager.INTENT_SENDER_ACTIVITY_RESULT:
227                     return "activityResult";
228             }
229             return Integer.toString(type);
230         }
231     }
232 
233     static final class TempAllowListDuration {
234         long duration;
235         int type;
236         @ReasonCode int reasonCode;
237         @Nullable String reason;
238 
TempAllowListDuration(long _duration, int _type, @ReasonCode int _reasonCode, String _reason)239         TempAllowListDuration(long _duration, int _type, @ReasonCode int _reasonCode,
240                 String _reason) {
241             duration = _duration;
242             type = _type;
243             reasonCode = _reasonCode;
244             reason = _reason;
245         }
246     }
247 
PendingIntentRecord(PendingIntentController _controller, Key _k, int _u)248     PendingIntentRecord(PendingIntentController _controller, Key _k, int _u) {
249         controller = _controller;
250         key = _k;
251         uid = _u;
252         ref = new WeakReference<>(this);
253     }
254 
setAllowlistDurationLocked(IBinder allowlistToken, long duration, int type, @ReasonCode int reasonCode, @Nullable String reason)255     void setAllowlistDurationLocked(IBinder allowlistToken, long duration, int type,
256             @ReasonCode int reasonCode, @Nullable String reason) {
257         if (duration > 0) {
258             if (mAllowlistDuration == null) {
259                 mAllowlistDuration = new ArrayMap<>();
260             }
261             mAllowlistDuration.put(allowlistToken,
262                     new TempAllowListDuration(duration, type, reasonCode, reason));
263         } else if (mAllowlistDuration != null) {
264             mAllowlistDuration.remove(allowlistToken);
265             if (mAllowlistDuration.size() <= 0) {
266                 mAllowlistDuration = null;
267             }
268         }
269         this.stringName = null;
270     }
271 
setAllowBgActivityStarts(IBinder token, int flags)272     void setAllowBgActivityStarts(IBinder token, int flags) {
273         if (token == null) return;
274         if ((flags & FLAG_ACTIVITY_SENDER) != 0) {
275             mAllowBgActivityStartsForActivitySender.add(token);
276         }
277         if ((flags & FLAG_BROADCAST_SENDER) != 0) {
278             mAllowBgActivityStartsForBroadcastSender.add(token);
279         }
280         if ((flags & FLAG_SERVICE_SENDER) != 0) {
281             mAllowBgActivityStartsForServiceSender.add(token);
282         }
283     }
284 
clearAllowBgActivityStarts(IBinder token)285     void clearAllowBgActivityStarts(IBinder token) {
286         if (token == null) return;
287         mAllowBgActivityStartsForActivitySender.remove(token);
288         mAllowBgActivityStartsForBroadcastSender.remove(token);
289         mAllowBgActivityStartsForServiceSender.remove(token);
290     }
291 
registerCancelListenerLocked(IResultReceiver receiver)292     public void registerCancelListenerLocked(IResultReceiver receiver) {
293         if (mCancelCallbacks == null) {
294             mCancelCallbacks = new RemoteCallbackList<>();
295         }
296         mCancelCallbacks.register(receiver);
297     }
298 
unregisterCancelListenerLocked(IResultReceiver receiver)299     public void unregisterCancelListenerLocked(IResultReceiver receiver) {
300         if (mCancelCallbacks == null) {
301             return; // Already unregistered or detached.
302         }
303         mCancelCallbacks.unregister(receiver);
304         if (mCancelCallbacks.getRegisteredCallbackCount() <= 0) {
305             mCancelCallbacks = null;
306         }
307     }
308 
detachCancelListenersLocked()309     public RemoteCallbackList<IResultReceiver> detachCancelListenersLocked() {
310         RemoteCallbackList<IResultReceiver> listeners = mCancelCallbacks;
311         mCancelCallbacks = null;
312         return listeners;
313     }
314 
send(int code, Intent intent, String resolvedType, IBinder allowlistToken, IIntentReceiver finishedReceiver, String requiredPermission, Bundle options)315     public void send(int code, Intent intent, String resolvedType, IBinder allowlistToken,
316             IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
317         sendInner(null, code, intent, resolvedType, allowlistToken, finishedReceiver,
318                 requiredPermission, null, null, 0, 0, 0, options);
319     }
320 
send(IApplicationThread caller, int code, Intent intent, String resolvedType, IBinder allowlistToken, IIntentReceiver finishedReceiver, String requiredPermission, Bundle options)321     public void send(IApplicationThread caller, int code, Intent intent, String resolvedType,
322             IBinder allowlistToken, IIntentReceiver finishedReceiver, String requiredPermission,
323             Bundle options) {
324         sendInner(caller, code, intent, resolvedType, allowlistToken, finishedReceiver,
325                 requiredPermission, null, null, 0, 0, 0, options);
326     }
327 
sendWithResult(IApplicationThread caller, int code, Intent intent, String resolvedType, IBinder allowlistToken, IIntentReceiver finishedReceiver, String requiredPermission, Bundle options)328     public int sendWithResult(IApplicationThread caller, int code, Intent intent,
329             String resolvedType, IBinder allowlistToken, IIntentReceiver finishedReceiver,
330             String requiredPermission, Bundle options) {
331         return sendInner(caller, code, intent, resolvedType, allowlistToken, finishedReceiver,
332                 requiredPermission, null, null, 0, 0, 0, options);
333     }
334 
335     /**
336      * Return true if the activity options allows PendingIntent to use caller's BAL permission.
337      */
isPendingIntentBalAllowedByPermission( @ullable ActivityOptions activityOptions)338     public static boolean isPendingIntentBalAllowedByPermission(
339             @Nullable ActivityOptions activityOptions) {
340         if (activityOptions == null) {
341             return false;
342         }
343         return activityOptions.isPendingIntentBackgroundActivityLaunchAllowedByPermission();
344     }
345 
346     /**
347      * Return the {@link BackgroundStartPrivileges} the activity options grant the PendingIntent to
348      * use caller's BAL permission.
349      */
getBackgroundStartPrivilegesAllowedByCaller( @ullable ActivityOptions activityOptions, int callingUid, @Nullable String callingPackage)350     public static BackgroundStartPrivileges getBackgroundStartPrivilegesAllowedByCaller(
351             @Nullable ActivityOptions activityOptions, int callingUid,
352             @Nullable String callingPackage) {
353         if (activityOptions == null) {
354             // since the ActivityOptions were not created by the app itself, determine the default
355             // for the app
356             return getDefaultBackgroundStartPrivileges(callingUid, callingPackage);
357         }
358         return getBackgroundStartPrivilegesAllowedByCaller(activityOptions.toBundle(),
359                 callingUid, callingPackage);
360     }
361 
getBackgroundStartPrivilegesAllowedByCaller( @ullable Bundle options, int callingUid, @Nullable String callingPackage)362     private static BackgroundStartPrivileges getBackgroundStartPrivilegesAllowedByCaller(
363             @Nullable Bundle options, int callingUid, @Nullable String callingPackage) {
364         if (options == null || !options.containsKey(
365                         ActivityOptions.KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED)) {
366             return getDefaultBackgroundStartPrivileges(callingUid, callingPackage);
367         }
368         return options.getBoolean(ActivityOptions.KEY_PENDING_INTENT_BACKGROUND_ACTIVITY_ALLOWED)
369                 ? BackgroundStartPrivileges.ALLOW_BAL
370                 : BackgroundStartPrivileges.NONE;
371     }
372 
373     /**
374      * Default {@link BackgroundStartPrivileges} to be used if the intent sender has not made an
375      * explicit choice.
376      *
377      * @hide
378      */
379     @RequiresPermission(
380             allOf = {
381                     android.Manifest.permission.READ_COMPAT_CHANGE_CONFIG,
382                     android.Manifest.permission.LOG_COMPAT_CHANGE
383             })
getDefaultBackgroundStartPrivileges( int callingUid, @Nullable String callingPackage)384     public static BackgroundStartPrivileges getDefaultBackgroundStartPrivileges(
385             int callingUid, @Nullable String callingPackage) {
386         boolean isChangeEnabledForApp = callingPackage != null ? CompatChanges.isChangeEnabled(
387                 DEFAULT_RESCIND_BAL_PRIVILEGES_FROM_PENDING_INTENT_SENDER, callingPackage,
388                 UserHandle.getUserHandleForUid(callingUid)) : CompatChanges.isChangeEnabled(
389                 DEFAULT_RESCIND_BAL_PRIVILEGES_FROM_PENDING_INTENT_SENDER, callingUid);
390         if (isChangeEnabledForApp) {
391             return BackgroundStartPrivileges.ALLOW_FGS;
392         } else {
393             return BackgroundStartPrivileges.ALLOW_BAL;
394         }
395     }
396 
397     @Deprecated
sendInner(int code, Intent intent, String resolvedType, IBinder allowlistToken, IIntentReceiver finishedReceiver, String requiredPermission, IBinder resultTo, String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle options)398     public int sendInner(int code, Intent intent, String resolvedType, IBinder allowlistToken,
399             IIntentReceiver finishedReceiver, String requiredPermission, IBinder resultTo,
400             String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle options) {
401         return sendInner(null, code, intent, resolvedType, allowlistToken, finishedReceiver,
402                 requiredPermission, resultTo, resultWho, requestCode, flagsMask, flagsValues,
403                 options);
404     }
405 
sendInner(IApplicationThread caller, int code, Intent intent, String resolvedType, IBinder allowlistToken, IIntentReceiver finishedReceiver, String requiredPermission, IBinder resultTo, String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle options)406     public int sendInner(IApplicationThread caller, int code, Intent intent,
407             String resolvedType, IBinder allowlistToken, IIntentReceiver finishedReceiver,
408             String requiredPermission, IBinder resultTo, String resultWho, int requestCode,
409             int flagsMask, int flagsValues, Bundle options) {
410         if (intent != null) intent.setDefusable(true);
411         if (options != null) options.setDefusable(true);
412 
413         TempAllowListDuration duration = null;
414         Intent finalIntent = null;
415         Intent[] allIntents = null;
416         String[] allResolvedTypes = null;
417         SafeActivityOptions mergedOptions = null;
418         synchronized (controller.mLock) {
419             if (canceled) {
420                 return ActivityManager.START_CANCELED;
421             }
422 
423             sent = true;
424             if ((key.flags & PendingIntent.FLAG_ONE_SHOT) != 0) {
425                 controller.cancelIntentSender(this, true);
426             }
427 
428             finalIntent = key.requestIntent != null ? new Intent(key.requestIntent) : new Intent();
429 
430             final boolean immutable = (key.flags & PendingIntent.FLAG_IMMUTABLE) != 0;
431             if (!immutable) {
432                 if (intent != null) {
433                     int changes = finalIntent.fillIn(intent, key.flags);
434                     if ((changes & Intent.FILL_IN_DATA) == 0) {
435                         resolvedType = key.requestResolvedType;
436                     }
437                 } else {
438                     resolvedType = key.requestResolvedType;
439                 }
440                 flagsMask &= ~Intent.IMMUTABLE_FLAGS;
441                 flagsValues &= flagsMask;
442                 finalIntent.setFlags((finalIntent.getFlags() & ~flagsMask) | flagsValues);
443             } else {
444                 resolvedType = key.requestResolvedType;
445             }
446 
447             // Apply any launch flags from the ActivityOptions. This is to ensure that the caller
448             // can specify a consistent launch mode even if the PendingIntent is immutable
449             final ActivityOptions opts = ActivityOptions.fromBundle(options);
450             if (opts != null) {
451                 if (opts.getPendingIntentCreatorBackgroundActivityStartMode()
452                         != ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED) {
453                     Slog.wtf(TAG,
454                             "Resetting option "
455                                     + "setPendingIntentCreatorBackgroundActivityStartMode("
456                                     + opts.getPendingIntentCreatorBackgroundActivityStartMode()
457                                     + ") to SYSTEM_DEFINED from the options provided by the "
458                                     + "pending intent sender ("
459                                     + key.packageName
460                                     + ") because this option is meant for the pending intent "
461                                     + "creator");
462                     opts.setPendingIntentCreatorBackgroundActivityStartMode(
463                             ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_SYSTEM_DEFINED);
464                 }
465                 finalIntent.addFlags(opts.getPendingIntentLaunchFlags());
466             }
467 
468             // Extract options before clearing calling identity
469             mergedOptions = key.options;
470             if (mergedOptions == null) {
471                 mergedOptions = new SafeActivityOptions(opts);
472             } else {
473                 mergedOptions.setCallerOptions(opts);
474             }
475 
476             if (mAllowlistDuration != null) {
477                 duration = mAllowlistDuration.get(allowlistToken);
478             }
479 
480             if (key.type == ActivityManager.INTENT_SENDER_ACTIVITY
481                     && key.allIntents != null && key.allIntents.length > 1) {
482                 // Copy all intents and resolved types while we have the controller lock so we can
483                 // use it later when the lock isn't held.
484                 allIntents = new Intent[key.allIntents.length];
485                 allResolvedTypes = new String[key.allIntents.length];
486                 System.arraycopy(key.allIntents, 0, allIntents, 0, key.allIntents.length);
487                 if (key.allResolvedTypes != null) {
488                     System.arraycopy(key.allResolvedTypes, 0, allResolvedTypes, 0,
489                             key.allResolvedTypes.length);
490                 }
491                 allIntents[allIntents.length - 1] = finalIntent;
492                 allResolvedTypes[allResolvedTypes.length - 1] = resolvedType;
493             }
494 
495         }
496         // We don't hold the controller lock beyond this point as we will be calling into AM and WM.
497 
498         final int callingUid = Binder.getCallingUid();
499         final int callingPid = Binder.getCallingPid();
500 
501         // Only system senders can declare a broadcast to be alarm-originated.  We check
502         // this here rather than in the general case handling below to fail before the other
503         // invocation side effects such as allowlisting.
504         if (key.type == ActivityManager.INTENT_SENDER_BROADCAST) {
505             controller.mAmInternal.enforceBroadcastOptionsPermissions(options, callingUid);
506         }
507 
508         final long origId = Binder.clearCallingIdentity();
509 
510         int res = START_SUCCESS;
511         try {
512             if (duration != null) {
513                 StringBuilder tag = new StringBuilder(64);
514                 tag.append("setPendingIntentAllowlistDuration,reason:");
515                 tag.append(duration.reason == null ? "" : duration.reason);
516                 tag.append(",pendingintent:");
517                 UserHandle.formatUid(tag, callingUid);
518                 tag.append(":");
519                 if (finalIntent.getAction() != null) {
520                     tag.append(finalIntent.getAction());
521                 } else if (finalIntent.getComponent() != null) {
522                     finalIntent.getComponent().appendShortString(tag);
523                 } else if (finalIntent.getData() != null) {
524                     tag.append(finalIntent.getData().toSafeString());
525                 }
526                 controller.mAmInternal.tempAllowlistForPendingIntent(callingPid, callingUid,
527                         uid, duration.duration, duration.type, duration.reasonCode, tag.toString());
528             } else if (key.type == ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE
529                     && options != null) {
530                 // If this is a getForegroundService() type pending intent, use its BroadcastOptions
531                 // temp allowlist duration as its pending intent temp allowlist duration.
532                 BroadcastOptions brOptions = new BroadcastOptions(options);
533                 if (brOptions.getTemporaryAppAllowlistDuration() > 0) {
534                     controller.mAmInternal.tempAllowlistForPendingIntent(callingPid, callingUid,
535                             uid, brOptions.getTemporaryAppAllowlistDuration(),
536                             brOptions.getTemporaryAppAllowlistType(),
537                             brOptions.getTemporaryAppAllowlistReasonCode(),
538                             brOptions.getTemporaryAppAllowlistReason());
539                 }
540             }
541 
542             final IApplicationThread finishedReceiverThread = caller;
543             boolean sendFinish = finishedReceiver != null;
544             if ((finishedReceiver != null) && (finishedReceiverThread == null)) {
545                 Slog.w(TAG, "Sending of " + intent + " from " + Binder.getCallingUid()
546                         + " requested resultTo without an IApplicationThread!", new Throwable());
547             }
548 
549             int userId = key.userId;
550             if (userId == UserHandle.USER_CURRENT) {
551                 userId = controller.mUserController.getCurrentOrTargetUserId();
552             }
553 
554             // note: we on purpose don't pass in the information about the PendingIntent's creator,
555             // like pid or ProcessRecord, to the ActivityTaskManagerInternal calls below, because
556             // it's not unusual for the creator's process to not be alive at this time
557             switch (key.type) {
558                 case ActivityManager.INTENT_SENDER_ACTIVITY:
559                     try {
560                         // Note when someone has a pending intent, even from different
561                         // users, then there's no need to ensure the calling user matches
562                         // the target user, so validateIncomingUser is always false below.
563 
564                         if (key.allIntents != null && key.allIntents.length > 1) {
565                             res = controller.mAtmInternal.startActivitiesInPackage(
566                                     uid, callingPid, callingUid, key.packageName, key.featureId,
567                                     allIntents, allResolvedTypes, resultTo, mergedOptions, userId,
568                                     false /* validateIncomingUser */,
569                                     this /* originatingPendingIntent */,
570                                     getBackgroundStartPrivilegesForActivitySender(allowlistToken));
571                         } else {
572                             res = controller.mAtmInternal.startActivityInPackage(uid, callingPid,
573                                     callingUid, key.packageName, key.featureId, finalIntent,
574                                     resolvedType, resultTo, resultWho, requestCode, 0,
575                                     mergedOptions, userId, null, "PendingIntentRecord",
576                                     false /* validateIncomingUser */,
577                                     this /* originatingPendingIntent */,
578                                     getBackgroundStartPrivilegesForActivitySender(allowlistToken));
579                         }
580                     } catch (RuntimeException e) {
581                         Slog.w(TAG, "Unable to send startActivity intent", e);
582                     }
583                     break;
584                 case ActivityManager.INTENT_SENDER_ACTIVITY_RESULT:
585                     controller.mAtmInternal.sendActivityResult(-1, key.activity, key.who,
586                                 key.requestCode, code, finalIntent);
587                     break;
588                 case ActivityManager.INTENT_SENDER_BROADCAST:
589                     try {
590                         final BackgroundStartPrivileges backgroundStartPrivileges =
591                                 getBackgroundStartPrivilegesForActivitySender(
592                                         mAllowBgActivityStartsForBroadcastSender, allowlistToken,
593                                         options, callingUid);
594                         // If a completion callback has been requested, require
595                         // that the broadcast be delivered synchronously
596                         int sent = controller.mAmInternal.broadcastIntentInPackage(key.packageName,
597                                 key.featureId, uid, callingUid, callingPid, finalIntent,
598                                 resolvedType, finishedReceiverThread, finishedReceiver, code, null,
599                                 null, requiredPermission, options, (finishedReceiver != null),
600                                 false, userId, backgroundStartPrivileges,
601                                 null /* broadcastAllowList */);
602                         if (sent == ActivityManager.BROADCAST_SUCCESS) {
603                             sendFinish = false;
604                         }
605                     } catch (RuntimeException e) {
606                         Slog.w(TAG, "Unable to send startActivity intent", e);
607                     }
608                     break;
609                 case ActivityManager.INTENT_SENDER_SERVICE:
610                 case ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE:
611                     try {
612                         final BackgroundStartPrivileges backgroundStartPrivileges =
613                                 getBackgroundStartPrivilegesForActivitySender(
614                                         mAllowBgActivityStartsForServiceSender, allowlistToken,
615                                         options, callingUid);
616                         controller.mAmInternal.startServiceInPackage(uid, finalIntent, resolvedType,
617                                 key.type == ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE,
618                                 key.packageName, key.featureId, userId,
619                                 backgroundStartPrivileges);
620                     } catch (RuntimeException e) {
621                         Slog.w(TAG, "Unable to send startService intent", e);
622                     } catch (TransactionTooLargeException e) {
623                         res = ActivityManager.START_CANCELED;
624                     }
625                     break;
626             }
627 
628             if (sendFinish && res != ActivityManager.START_CANCELED) {
629                 try {
630                     finishedReceiver.performReceive(new Intent(finalIntent), 0,
631                             null, null, false, false, key.userId);
632                 } catch (RemoteException e) {
633                 }
634             }
635         } finally {
636             Binder.restoreCallingIdentity(origId);
637         }
638 
639         return res;
640     }
641 
getBackgroundStartPrivilegesForActivitySender( IBinder allowlistToken)642     private BackgroundStartPrivileges getBackgroundStartPrivilegesForActivitySender(
643             IBinder allowlistToken) {
644         return mAllowBgActivityStartsForActivitySender.contains(allowlistToken)
645                 ? BackgroundStartPrivileges.allowBackgroundActivityStarts(allowlistToken)
646                 : BackgroundStartPrivileges.NONE;
647     }
648 
getBackgroundStartPrivilegesForActivitySender( ArraySet<IBinder> allowedTokenSet, IBinder allowlistToken, Bundle options, int callingUid)649     private BackgroundStartPrivileges getBackgroundStartPrivilegesForActivitySender(
650             ArraySet<IBinder> allowedTokenSet, IBinder allowlistToken,
651             Bundle options, int callingUid) {
652         if (allowedTokenSet.contains(allowlistToken)) {
653             return BackgroundStartPrivileges.allowBackgroundActivityStarts(allowlistToken);
654         }
655         // temporarily allow receivers and services to open activities from background if the
656         // PendingIntent.send() caller was foreground at the time of sendInner() call
657         if (uid != callingUid && controller.mAtmInternal.isUidForeground(callingUid)) {
658             return getBackgroundStartPrivilegesAllowedByCaller(options, callingUid, null);
659         }
660         return BackgroundStartPrivileges.NONE;
661     }
662 
663     @Override
finalize()664     protected void finalize() throws Throwable {
665         try {
666             if (!canceled) {
667                 controller.mH.sendMessage(PooledLambda.obtainMessage(
668                         PendingIntentRecord::completeFinalize, this));
669             }
670         } finally {
671             super.finalize();
672         }
673     }
674 
completeFinalize()675     private void completeFinalize() {
676         synchronized(controller.mLock) {
677             WeakReference<PendingIntentRecord> current = controller.mIntentSenderRecords.get(key);
678             if (current == ref) {
679                 controller.mIntentSenderRecords.remove(key);
680                 controller.decrementUidStatLocked(this);
681             }
682         }
683     }
684 
dump(PrintWriter pw, String prefix)685     public void dump(PrintWriter pw, String prefix) {
686         pw.print(prefix); pw.print("uid="); pw.print(uid);
687                 pw.print(" packageName="); pw.print(key.packageName);
688                 pw.print(" featureId="); pw.print(key.featureId);
689                 pw.print(" type="); pw.print(key.typeName());
690                 pw.print(" flags=0x"); pw.println(Integer.toHexString(key.flags));
691         if (key.activity != null || key.who != null) {
692             pw.print(prefix); pw.print("activity="); pw.print(key.activity);
693                     pw.print(" who="); pw.println(key.who);
694         }
695         if (key.requestCode != 0 || key.requestResolvedType != null) {
696             pw.print(prefix); pw.print("requestCode="); pw.print(key.requestCode);
697                     pw.print(" requestResolvedType="); pw.println(key.requestResolvedType);
698         }
699         if (key.requestIntent != null) {
700             pw.print(prefix); pw.print("requestIntent=");
701                     pw.println(key.requestIntent.toShortString(false, true, true, false));
702         }
703         if (sent || canceled) {
704             pw.print(prefix); pw.print("sent="); pw.print(sent);
705                     pw.print(" canceled="); pw.println(canceled);
706         }
707         if (mAllowlistDuration != null) {
708             pw.print(prefix);
709             pw.print("allowlistDuration=");
710             for (int i = 0; i < mAllowlistDuration.size(); i++) {
711                 if (i != 0) {
712                     pw.print(", ");
713                 }
714                 TempAllowListDuration entry = mAllowlistDuration.valueAt(i);
715                 pw.print(Integer.toHexString(System.identityHashCode(mAllowlistDuration.keyAt(i))));
716                 pw.print(":");
717                 TimeUtils.formatDuration(entry.duration, pw);
718                 pw.print("/");
719                 pw.print(entry.type);
720                 pw.print("/");
721                 pw.print(PowerWhitelistManager.reasonCodeToString(entry.reasonCode));
722                 pw.print("/");
723                 pw.print(entry.reason);
724             }
725             pw.println();
726         }
727         if (mCancelCallbacks != null) {
728             pw.print(prefix); pw.println("mCancelCallbacks:");
729             for (int i = 0; i < mCancelCallbacks.getRegisteredCallbackCount(); i++) {
730                 pw.print(prefix); pw.print("  #"); pw.print(i); pw.print(": ");
731                 pw.println(mCancelCallbacks.getRegisteredCallbackItem(i));
732             }
733         }
734     }
735 
toString()736     public String toString() {
737         if (stringName != null) {
738             return stringName;
739         }
740         StringBuilder sb = new StringBuilder(128);
741         sb.append("PendingIntentRecord{");
742         sb.append(Integer.toHexString(System.identityHashCode(this)));
743         sb.append(' ');
744         sb.append(key.packageName);
745         if (key.featureId != null) {
746             sb.append('/');
747             sb.append(key.featureId);
748         }
749         sb.append(' ');
750         sb.append(key.typeName());
751         if (mAllowlistDuration != null) {
752             sb.append(" (allowlist: ");
753             for (int i = 0; i < mAllowlistDuration.size(); i++) {
754                 if (i != 0) {
755                     sb.append(",");
756                 }
757                 TempAllowListDuration entry = mAllowlistDuration.valueAt(i);
758                 sb.append(Integer.toHexString(System.identityHashCode(
759                         mAllowlistDuration.keyAt(i))));
760                 sb.append(":");
761                 TimeUtils.formatDuration(entry.duration, sb);
762                 sb.append("/");
763                 sb.append(entry.type);
764                 sb.append("/");
765                 sb.append(PowerWhitelistManager.reasonCodeToString(entry.reasonCode));
766                 sb.append("/");
767                 sb.append(entry.reason);
768             }
769             sb.append(")");
770         }
771         sb.append('}');
772         return stringName = sb.toString();
773     }
774 }
775