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