1 /* 2 * Copyright (C) 2016 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.internal.telephony; 18 19 import android.telephony.ClientRequestStats; 20 import android.telephony.Rlog; 21 22 import com.android.internal.annotations.VisibleForTesting; 23 import java.util.ArrayList; 24 25 public class ClientWakelockAccountant { 26 public static final String LOG_TAG = "ClientWakelockAccountant: "; 27 28 @VisibleForTesting 29 public ClientRequestStats mRequestStats = new ClientRequestStats(); 30 @VisibleForTesting 31 public ArrayList<RilWakelockInfo> mPendingRilWakelocks = new ArrayList<>(); 32 33 @VisibleForTesting ClientWakelockAccountant(String callingPackage)34 public ClientWakelockAccountant(String callingPackage) { 35 mRequestStats.setCallingPackage(callingPackage); 36 } 37 38 @VisibleForTesting startAttributingWakelock(int request, int token, int concurrentRequests, long time)39 public void startAttributingWakelock(int request, 40 int token, int concurrentRequests, long time) { 41 42 RilWakelockInfo wlInfo = new RilWakelockInfo(request, token, concurrentRequests, time); 43 synchronized (mPendingRilWakelocks) { 44 mPendingRilWakelocks.add(wlInfo); 45 } 46 } 47 48 @VisibleForTesting stopAttributingWakelock(int request, int token, long time)49 public void stopAttributingWakelock(int request, int token, long time) { 50 RilWakelockInfo wlInfo = removePendingWakelock(request, token); 51 if (wlInfo != null) { 52 completeRequest(wlInfo, time); 53 } 54 } 55 56 @VisibleForTesting stopAllPendingRequests(long time)57 public void stopAllPendingRequests(long time) { 58 synchronized (mPendingRilWakelocks) { 59 for (RilWakelockInfo wlInfo : mPendingRilWakelocks) { 60 completeRequest(wlInfo, time); 61 } 62 mPendingRilWakelocks.clear(); 63 } 64 } 65 66 @VisibleForTesting changeConcurrentRequests(int concurrentRequests, long time)67 public void changeConcurrentRequests(int concurrentRequests, long time) { 68 synchronized (mPendingRilWakelocks) { 69 for (RilWakelockInfo wlInfo : mPendingRilWakelocks) { 70 wlInfo.updateConcurrentRequests(concurrentRequests, time); 71 } 72 } 73 } 74 completeRequest(RilWakelockInfo wlInfo, long time)75 private void completeRequest(RilWakelockInfo wlInfo, long time) { 76 wlInfo.setResponseTime(time); 77 synchronized (mRequestStats) { 78 mRequestStats.addCompletedWakelockTime(wlInfo.getWakelockTimeAttributedToClient()); 79 mRequestStats.incrementCompletedRequestsCount(); 80 mRequestStats.updateRequestHistograms(wlInfo.getRilRequestSent(), 81 (int) wlInfo.getWakelockTimeAttributedToClient()); 82 } 83 } 84 85 @VisibleForTesting getPendingRequestCount()86 public int getPendingRequestCount() { 87 return mPendingRilWakelocks.size(); 88 } 89 90 @VisibleForTesting updatePendingRequestWakelockTime(long uptime)91 public synchronized long updatePendingRequestWakelockTime(long uptime) { 92 long totalPendingWakelockTime = 0; 93 synchronized (mPendingRilWakelocks) { 94 for (RilWakelockInfo wlInfo : mPendingRilWakelocks) { 95 wlInfo.updateTime(uptime); 96 totalPendingWakelockTime += wlInfo.getWakelockTimeAttributedToClient(); 97 } 98 } 99 synchronized (mRequestStats) { 100 mRequestStats.setPendingRequestsCount(getPendingRequestCount()); 101 mRequestStats.setPendingRequestsWakelockTime(totalPendingWakelockTime); 102 } 103 return totalPendingWakelockTime; 104 } 105 removePendingWakelock(int request, int token)106 private RilWakelockInfo removePendingWakelock(int request, int token) { 107 RilWakelockInfo result = null; 108 synchronized (mPendingRilWakelocks) { 109 for (RilWakelockInfo wlInfo : mPendingRilWakelocks) { 110 if ((wlInfo.getTokenNumber() == token) && 111 (wlInfo.getRilRequestSent() == request)) { 112 result = wlInfo; 113 } 114 } 115 if( result != null ) { 116 mPendingRilWakelocks.remove(result); 117 } 118 } 119 if(result == null) { 120 Rlog.w(LOG_TAG, "Looking for Request<" + request + "," + token + "> in " 121 + mPendingRilWakelocks); 122 } 123 return result; 124 } 125 126 @Override toString()127 public String toString() { 128 return "ClientWakelockAccountant{" + 129 "mRequestStats=" + mRequestStats + 130 ", mPendingRilWakelocks=" + mPendingRilWakelocks + 131 '}'; 132 } 133 } 134