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.app.IServiceConnection; 20 import android.app.PendingIntent; 21 import android.content.Context; 22 import android.util.proto.ProtoOutputStream; 23 import android.util.proto.ProtoUtils; 24 25 import java.io.PrintWriter; 26 27 /** 28 * Description of a single binding to a service. 29 */ 30 final class ConnectionRecord { 31 final AppBindRecord binding; // The application/service binding. 32 final ActivityRecord activity; // If non-null, the owning activity. 33 final IServiceConnection conn; // The client connection. 34 final int flags; // Binding options. 35 final int clientLabel; // String resource labeling this client. 36 final PendingIntent clientIntent; // How to launch the client. 37 String stringName; // Caching of toString. 38 boolean serviceDead; // Well is it? 39 40 // Please keep the following two enum list synced. 41 private static int[] BIND_ORIG_ENUMS = new int[] { 42 Context.BIND_AUTO_CREATE, 43 Context.BIND_DEBUG_UNBIND, 44 Context.BIND_NOT_FOREGROUND, 45 Context.BIND_IMPORTANT_BACKGROUND, 46 Context.BIND_ABOVE_CLIENT, 47 Context.BIND_ALLOW_OOM_MANAGEMENT, 48 Context.BIND_WAIVE_PRIORITY, 49 Context.BIND_IMPORTANT, 50 Context.BIND_ADJUST_WITH_ACTIVITY, 51 Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE, 52 Context.BIND_FOREGROUND_SERVICE, 53 Context.BIND_TREAT_LIKE_ACTIVITY, 54 Context.BIND_VISIBLE, 55 Context.BIND_SHOWING_UI, 56 Context.BIND_NOT_VISIBLE, 57 }; 58 private static int[] BIND_PROTO_ENUMS = new int[] { 59 ConnectionRecordProto.AUTO_CREATE, 60 ConnectionRecordProto.DEBUG_UNBIND, 61 ConnectionRecordProto.NOT_FG, 62 ConnectionRecordProto.IMPORTANT_BG, 63 ConnectionRecordProto.ABOVE_CLIENT, 64 ConnectionRecordProto.ALLOW_OOM_MANAGEMENT, 65 ConnectionRecordProto.WAIVE_PRIORITY, 66 ConnectionRecordProto.IMPORTANT, 67 ConnectionRecordProto.ADJUST_WITH_ACTIVITY, 68 ConnectionRecordProto.FG_SERVICE_WHILE_AWAKE, 69 ConnectionRecordProto.FG_SERVICE, 70 ConnectionRecordProto.TREAT_LIKE_ACTIVITY, 71 ConnectionRecordProto.VISIBLE, 72 ConnectionRecordProto.SHOWING_UI, 73 ConnectionRecordProto.NOT_VISIBLE, 74 }; 75 dump(PrintWriter pw, String prefix)76 void dump(PrintWriter pw, String prefix) { 77 pw.println(prefix + "binding=" + binding); 78 if (activity != null) { 79 pw.println(prefix + "activity=" + activity); 80 } 81 pw.println(prefix + "conn=" + conn.asBinder() 82 + " flags=0x" + Integer.toHexString(flags)); 83 } 84 ConnectionRecord(AppBindRecord _binding, ActivityRecord _activity, IServiceConnection _conn, int _flags, int _clientLabel, PendingIntent _clientIntent)85 ConnectionRecord(AppBindRecord _binding, ActivityRecord _activity, 86 IServiceConnection _conn, int _flags, 87 int _clientLabel, PendingIntent _clientIntent) { 88 binding = _binding; 89 activity = _activity; 90 conn = _conn; 91 flags = _flags; 92 clientLabel = _clientLabel; 93 clientIntent = _clientIntent; 94 } 95 toString()96 public String toString() { 97 if (stringName != null) { 98 return stringName; 99 } 100 StringBuilder sb = new StringBuilder(128); 101 sb.append("ConnectionRecord{"); 102 sb.append(Integer.toHexString(System.identityHashCode(this))); 103 sb.append(" u"); 104 sb.append(binding.client.userId); 105 sb.append(' '); 106 if ((flags&Context.BIND_AUTO_CREATE) != 0) { 107 sb.append("CR "); 108 } 109 if ((flags&Context.BIND_DEBUG_UNBIND) != 0) { 110 sb.append("DBG "); 111 } 112 if ((flags&Context.BIND_NOT_FOREGROUND) != 0) { 113 sb.append("!FG "); 114 } 115 if ((flags&Context.BIND_IMPORTANT_BACKGROUND) != 0) { 116 sb.append("IMPB "); 117 } 118 if ((flags&Context.BIND_ABOVE_CLIENT) != 0) { 119 sb.append("ABCLT "); 120 } 121 if ((flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 122 sb.append("OOM "); 123 } 124 if ((flags&Context.BIND_WAIVE_PRIORITY) != 0) { 125 sb.append("WPRI "); 126 } 127 if ((flags&Context.BIND_IMPORTANT) != 0) { 128 sb.append("IMP "); 129 } 130 if ((flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 131 sb.append("WACT "); 132 } 133 if ((flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE) != 0) { 134 sb.append("FGSA "); 135 } 136 if ((flags&Context.BIND_FOREGROUND_SERVICE) != 0) { 137 sb.append("FGS "); 138 } 139 if ((flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 140 sb.append("LACT "); 141 } 142 if ((flags&Context.BIND_VISIBLE) != 0) { 143 sb.append("VIS "); 144 } 145 if ((flags&Context.BIND_SHOWING_UI) != 0) { 146 sb.append("UI "); 147 } 148 if ((flags&Context.BIND_NOT_VISIBLE) != 0) { 149 sb.append("!VIS "); 150 } 151 if (serviceDead) { 152 sb.append("DEAD "); 153 } 154 sb.append(binding.service.shortName); 155 sb.append(":@"); 156 sb.append(Integer.toHexString(System.identityHashCode(conn.asBinder()))); 157 sb.append('}'); 158 return stringName = sb.toString(); 159 } 160 writeToProto(ProtoOutputStream proto, long fieldId)161 public void writeToProto(ProtoOutputStream proto, long fieldId) { 162 if (binding == null) return; // if binding is null, don't write data, something is wrong. 163 long token = proto.start(fieldId); 164 proto.write(ConnectionRecordProto.HEX_HASH, 165 Integer.toHexString(System.identityHashCode(this))); 166 if (binding.client != null) { 167 proto.write(ConnectionRecordProto.USER_ID, binding.client.userId); 168 } 169 ProtoUtils.writeBitWiseFlagsToProtoEnum(proto, ConnectionRecordProto.FLAGS, 170 flags, BIND_ORIG_ENUMS, BIND_PROTO_ENUMS); 171 if (serviceDead) { 172 proto.write(ConnectionRecordProto.FLAGS, ConnectionRecordProto.DEAD); 173 } 174 if (binding.service != null) { 175 proto.write(ConnectionRecordProto.SERVICE_NAME, binding.service.shortName); 176 } 177 proto.end(token); 178 } 179 } 180