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 
getReceiverAt(int index)98     ReceiverList getReceiverAt(int index) {
99         return mReceivers.valueAt(index);
100     }
101 
addReceiver(ReceiverList receiver)102     void addReceiver(ReceiverList receiver) {
103         mReceivers.add(receiver);
104     }
105 
removeReceiver(ReceiverList receiver)106     void removeReceiver(ReceiverList receiver) {
107         mReceivers.remove(receiver);
108     }
109 
ProcessReceiverRecord(ProcessRecord app)110     ProcessReceiverRecord(ProcessRecord app) {
111         mApp = app;
112         mService = app.mService;
113     }
114 
115     @GuardedBy("mService")
onCleanupApplicationRecordLocked()116     void onCleanupApplicationRecordLocked() {
117         // Unregister any mReceivers.
118         for (int i = mReceivers.size() - 1; i >= 0; i--) {
119             mService.removeReceiverLocked(mReceivers.valueAt(i));
120         }
121         mReceivers.clear();
122     }
123 
dump(PrintWriter pw, String prefix, long nowUptime)124     void dump(PrintWriter pw, String prefix, long nowUptime) {
125         if (!mCurReceivers.isEmpty()) {
126             pw.print(prefix); pw.println("Current mReceivers:");
127             for (int i = 0, size = mCurReceivers.size(); i < size; i++) {
128                 pw.print(prefix); pw.print("  - "); pw.println(mCurReceivers.valueAt(i));
129             }
130         }
131         if (mReceivers.size() > 0) {
132             pw.print(prefix); pw.println("mReceivers:");
133             for (int i = 0, size = mReceivers.size(); i < size; i++) {
134                 pw.print(prefix); pw.print("  - "); pw.println(mReceivers.valueAt(i));
135             }
136         }
137     }
138 }
139