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 android.annotation.Nullable; 20 import android.content.IIntentReceiver; 21 import android.content.IntentFilter; 22 import android.os.Binder; 23 import android.os.IBinder; 24 import android.util.PrintWriterPrinter; 25 import android.util.Printer; 26 import android.util.proto.ProtoOutputStream; 27 28 import java.io.PrintWriter; 29 import java.util.ArrayList; 30 31 /** 32 * A receiver object that has registered for one or more broadcasts. 33 * The ArrayList holds BroadcastFilter objects. 34 */ 35 final class ReceiverList extends ArrayList<BroadcastFilter> 36 implements IBinder.DeathRecipient { 37 final ActivityManagerService owner; 38 public final IIntentReceiver receiver; 39 public final @Nullable ProcessRecord app; 40 public final int pid; 41 public final int uid; 42 public final int userId; 43 BroadcastRecord curBroadcast = null; 44 boolean linkedToDeath = false; 45 46 String stringName; 47 ReceiverList(ActivityManagerService _owner, @Nullable ProcessRecord _app, int _pid, int _uid, int _userId, IIntentReceiver _receiver)48 ReceiverList(ActivityManagerService _owner, @Nullable ProcessRecord _app, 49 int _pid, int _uid, int _userId, IIntentReceiver _receiver) { 50 owner = _owner; 51 receiver = _receiver; 52 app = _app; 53 pid = _pid; 54 uid = _uid; 55 userId = _userId; 56 } 57 58 // Want object identity, not the array identity we are inheriting. equals(Object o)59 public boolean equals(Object o) { 60 return this == o; 61 } hashCode()62 public int hashCode() { 63 return System.identityHashCode(this); 64 } 65 binderDied()66 public void binderDied() { 67 linkedToDeath = false; 68 owner.unregisterReceiver(receiver); 69 } 70 containsFilter(IntentFilter filter)71 public boolean containsFilter(IntentFilter filter) { 72 final int N = size(); 73 for (int i = 0; i < N; i++) { 74 final BroadcastFilter f = get(i); 75 if (IntentFilter.filterEquals(f, filter)) { 76 return true; 77 } 78 } 79 return false; 80 } 81 dumpDebug(ProtoOutputStream proto, long fieldId)82 void dumpDebug(ProtoOutputStream proto, long fieldId) { 83 long token = proto.start(fieldId); 84 if (app != null) { 85 app.dumpDebug(proto, ReceiverListProto.APP); 86 proto.write(ReceiverListProto.NUMBER_RECEIVERS, app.mReceivers.numberOfReceivers()); 87 } 88 proto.write(ReceiverListProto.PID, pid); 89 proto.write(ReceiverListProto.UID, uid); 90 proto.write(ReceiverListProto.USER, userId); 91 if (curBroadcast != null) { 92 curBroadcast.dumpDebug(proto, ReceiverListProto.CURRENT); 93 } 94 proto.write(ReceiverListProto.LINKED_TO_DEATH, linkedToDeath); 95 final int N = size(); 96 for (int i=0; i<N; i++) { 97 BroadcastFilter bf = get(i); 98 bf.dumpDebug(proto, ReceiverListProto.FILTERS); 99 } 100 proto.write(ReceiverListProto.HEX_HASH, Integer.toHexString(System.identityHashCode(this))); 101 proto.end(token); 102 } 103 dumpLocal(PrintWriter pw, String prefix)104 void dumpLocal(PrintWriter pw, String prefix) { 105 pw.print(prefix); pw.print("app="); pw.print(app != null ? app.toShortString() : null); 106 pw.print(" pid="); pw.print(pid); pw.print(" uid="); pw.print(uid); 107 pw.print(" user="); pw.print(userId); 108 if (app != null) { 109 pw.print(" #receivers="); pw.print(app.mReceivers.numberOfReceivers()); 110 } 111 pw.println(); 112 if (curBroadcast != null || linkedToDeath) { 113 pw.print(prefix); pw.print("curBroadcast="); pw.print(curBroadcast); 114 pw.print(" linkedToDeath="); pw.println(linkedToDeath); 115 } 116 } 117 dump(PrintWriter pw, String prefix)118 void dump(PrintWriter pw, String prefix) { 119 Printer pr = new PrintWriterPrinter(pw); 120 dumpLocal(pw, prefix); 121 String p2 = prefix + " "; 122 final int N = size(); 123 for (int i=0; i<N; i++) { 124 BroadcastFilter bf = get(i); 125 pw.print(prefix); pw.print("Filter #"); pw.print(i); 126 pw.print(": BroadcastFilter{"); 127 pw.print(Integer.toHexString(System.identityHashCode(bf))); 128 pw.println('}'); 129 bf.dumpInReceiverList(pw, pr, p2); 130 } 131 } 132 toString()133 public String toString() { 134 if (stringName != null) { 135 return stringName; 136 } 137 StringBuilder sb = new StringBuilder(128); 138 sb.append("ReceiverList{"); 139 sb.append(Integer.toHexString(System.identityHashCode(this))); 140 sb.append(' '); 141 sb.append(pid); 142 sb.append(' '); 143 sb.append((app != null ? app.processName : "(unknown name)")); 144 sb.append('/'); 145 sb.append(uid); 146 sb.append("/u"); 147 sb.append(userId); 148 sb.append((receiver.asBinder() instanceof Binder) ? " local:" : " remote:"); 149 sb.append(Integer.toHexString(System.identityHashCode(receiver.asBinder()))); 150 sb.append('}'); 151 return stringName = sb.toString(); 152 } 153 } 154