Home | History | Annotate | Download | only in am
      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 
     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 
     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 
     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 
    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