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