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