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