1 /* 2 * Copyright (C) 2012 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.os.Binder; 20 import android.os.SystemClock; 21 import android.util.Slog; 22 import android.util.TimeUtils; 23 24 import com.android.internal.app.procstats.AssociationState; 25 import com.android.internal.app.procstats.ProcessStats; 26 27 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; 28 29 /** 30 * Represents a link between a content provider and client. 31 */ 32 public final class ContentProviderConnection extends Binder { 33 public final ContentProviderRecord provider; 34 public final ProcessRecord client; 35 public final String clientPackage; 36 public AssociationState.SourceState association; 37 public final long createTime; 38 public int stableCount; 39 public int unstableCount; 40 // The client of this connection is currently waiting for the provider to appear. 41 // Protected by the provider lock. 42 public boolean waiting; 43 // The provider of this connection is now dead. 44 public boolean dead; 45 46 // For debugging. 47 public int numStableIncs; 48 public int numUnstableIncs; 49 ContentProviderConnection(ContentProviderRecord _provider, ProcessRecord _client, String _clientPackage)50 public ContentProviderConnection(ContentProviderRecord _provider, ProcessRecord _client, 51 String _clientPackage) { 52 provider = _provider; 53 client = _client; 54 clientPackage = _clientPackage; 55 createTime = SystemClock.elapsedRealtime(); 56 } 57 startAssociationIfNeeded()58 public void startAssociationIfNeeded() { 59 // If we don't already have an active association, create one... but only if this 60 // is an association between two different processes. 61 if (ActivityManagerService.TRACK_PROCSTATS_ASSOCIATIONS 62 && association == null && provider.proc != null 63 && (provider.appInfo.uid != client.uid 64 || !provider.info.processName.equals(client.processName))) { 65 ProcessStats.ProcessStateHolder holder = provider.proc.pkgList.get( 66 provider.name.getPackageName()); 67 if (holder == null) { 68 Slog.wtf(TAG_AM, "No package in referenced provider " 69 + provider.name.toShortString() + ": proc=" + provider.proc); 70 } else if (holder.pkg == null) { 71 Slog.wtf(TAG_AM, "Inactive holder in referenced provider " 72 + provider.name.toShortString() + ": proc=" + provider.proc); 73 } else { 74 association = holder.pkg.getAssociationStateLocked(holder.state, 75 provider.name.getClassName()).startSource(client.uid, client.processName, 76 clientPackage); 77 78 } 79 } 80 } 81 trackProcState(int procState, int seq, long now)82 public void trackProcState(int procState, int seq, long now) { 83 if (association != null) { 84 association.trackProcState(procState, seq, now); 85 } 86 } 87 stopAssociation()88 public void stopAssociation() { 89 if (association != null) { 90 association.stop(); 91 association = null; 92 } 93 } 94 toString()95 public String toString() { 96 StringBuilder sb = new StringBuilder(128); 97 sb.append("ContentProviderConnection{"); 98 toShortString(sb); 99 sb.append('}'); 100 return sb.toString(); 101 } 102 toShortString()103 public String toShortString() { 104 StringBuilder sb = new StringBuilder(128); 105 toShortString(sb); 106 return sb.toString(); 107 } 108 toClientString()109 public String toClientString() { 110 StringBuilder sb = new StringBuilder(128); 111 toClientString(sb); 112 return sb.toString(); 113 } 114 toShortString(StringBuilder sb)115 public void toShortString(StringBuilder sb) { 116 sb.append(provider.toShortString()); 117 sb.append("->"); 118 toClientString(sb); 119 } 120 toClientString(StringBuilder sb)121 public void toClientString(StringBuilder sb) { 122 sb.append(client.toShortString()); 123 sb.append(" s"); 124 sb.append(stableCount); 125 sb.append("/"); 126 sb.append(numStableIncs); 127 sb.append(" u"); 128 sb.append(unstableCount); 129 sb.append("/"); 130 sb.append(numUnstableIncs); 131 if (waiting) { 132 sb.append(" WAITING"); 133 } 134 if (dead) { 135 sb.append(" DEAD"); 136 } 137 long nowReal = SystemClock.elapsedRealtime(); 138 sb.append(" "); 139 TimeUtils.formatDuration(nowReal-createTime, sb); 140 } 141 } 142