1 /*
2  * Copyright (C) 2020 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 android.util.ArraySet;
20 
21 import com.android.internal.annotations.GuardedBy;
22 
23 import java.io.PrintWriter;
24 
25 /**
26  * The state info of all broadcast receivers in the process.
27  */
28 final class ProcessReceiverRecord {
29     final ProcessRecord mApp;
30     private final ActivityManagerService mService;
31 
32     /**
33      * mReceivers currently running in the app.
34      */
35     private final ArraySet<BroadcastRecord> mCurReceivers = new ArraySet<BroadcastRecord>();
36 
37     private int mCurReceiversSize;
38 
39     /**
40      * All IIntentReceivers that are registered from this process.
41      */
42     private final ArraySet<ReceiverList> mReceivers = new ArraySet<>();
43 
numberOfCurReceivers()44     int numberOfCurReceivers() {
45         return mCurReceiversSize;
46     }
47 
incrementCurReceivers()48     void incrementCurReceivers() {
49         mCurReceiversSize++;
50     }
51 
decrementCurReceivers()52     void decrementCurReceivers() {
53         mCurReceiversSize--;
54     }
55 
56     /**
57      * @deprecated we're moving towards tracking only a reference count to
58      *             improve performance.
59      */
60     @Deprecated
getCurReceiverAt(int index)61     BroadcastRecord getCurReceiverAt(int index) {
62         return mCurReceivers.valueAt(index);
63     }
64 
65     /**
66      * @deprecated we're moving towards tracking only a reference count to
67      *             improve performance.
68      */
69     @Deprecated
hasCurReceiver(BroadcastRecord receiver)70     boolean hasCurReceiver(BroadcastRecord receiver) {
71         return mCurReceivers.contains(receiver);
72     }
73 
74     /**
75      * @deprecated we're moving towards tracking only a reference count to
76      *             improve performance.
77      */
78     @Deprecated
addCurReceiver(BroadcastRecord receiver)79     void addCurReceiver(BroadcastRecord receiver) {
80         mCurReceivers.add(receiver);
81         mCurReceiversSize = mCurReceivers.size();
82     }
83 
84     /**
85      * @deprecated we're moving towards tracking only a reference count to
86      *             improve performance.
87      */
88     @Deprecated
removeCurReceiver(BroadcastRecord receiver)89     void removeCurReceiver(BroadcastRecord receiver) {
90         mCurReceivers.remove(receiver);
91         mCurReceiversSize = mCurReceivers.size();
92     }
93 
numberOfReceivers()94     int numberOfReceivers() {
95         return mReceivers.size();
96     }
97 
addReceiver(ReceiverList receiver)98     void addReceiver(ReceiverList receiver) {
99         mReceivers.add(receiver);
100     }
101 
removeReceiver(ReceiverList receiver)102     void removeReceiver(ReceiverList receiver) {
103         mReceivers.remove(receiver);
104     }
105 
ProcessReceiverRecord(ProcessRecord app)106     ProcessReceiverRecord(ProcessRecord app) {
107         mApp = app;
108         mService = app.mService;
109     }
110 
111     @GuardedBy("mService")
onCleanupApplicationRecordLocked()112     void onCleanupApplicationRecordLocked() {
113         // Unregister any mReceivers.
114         for (int i = mReceivers.size() - 1; i >= 0; i--) {
115             mService.removeReceiverLocked(mReceivers.valueAt(i));
116         }
117         mReceivers.clear();
118     }
119 
dump(PrintWriter pw, String prefix, long nowUptime)120     void dump(PrintWriter pw, String prefix, long nowUptime) {
121         if (!mCurReceivers.isEmpty()) {
122             pw.print(prefix); pw.println("Current mReceivers:");
123             for (int i = 0, size = mCurReceivers.size(); i < size; i++) {
124                 pw.print(prefix); pw.print("  - "); pw.println(mCurReceivers.valueAt(i));
125             }
126         }
127         if (mReceivers.size() > 0) {
128             pw.print(prefix); pw.println("mReceivers:");
129             for (int i = 0, size = mReceivers.size(); i < size; i++) {
130                 pw.print(prefix); pw.print("  - "); pw.println(mReceivers.valueAt(i));
131             }
132         }
133     }
134 }
135