11b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla/*
21b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla * Copyright (C) 2016 The Android Open Source Project
31b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla *
41b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla * Licensed under the Apache License, Version 2.0 (the "License");
51b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla * you may not use this file except in compliance with the License.
61b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla * You may obtain a copy of the License at
71b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla *
81b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla *      http://www.apache.org/licenses/LICENSE-2.0
91b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla *
101b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla * Unless required by applicable law or agreed to in writing, software
111b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla * distributed under the License is distributed on an "AS IS" BASIS,
121b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla * See the License for the specific language governing permissions and
141b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla * limitations under the License
151b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla */
161b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla
171b90799284785b26b0853ae367cac139ba37e18bNaveen Kallapackage com.android.internal.telephony;
181b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla
191b90799284785b26b0853ae367cac139ba37e18bNaveen Kallaimport android.os.SystemClock;
201b90799284785b26b0853ae367cac139ba37e18bNaveen Kallaimport android.telephony.ClientRequestStats;
211b90799284785b26b0853ae367cac139ba37e18bNaveen Kallaimport android.telephony.Rlog;
221b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla
231b90799284785b26b0853ae367cac139ba37e18bNaveen Kallaimport com.android.internal.annotations.VisibleForTesting;
241b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla
251b90799284785b26b0853ae367cac139ba37e18bNaveen Kallaimport java.util.ArrayList;
261b90799284785b26b0853ae367cac139ba37e18bNaveen Kallaimport java.util.HashMap;
271b90799284785b26b0853ae367cac139ba37e18bNaveen Kallaimport java.util.List;
281b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla
291b90799284785b26b0853ae367cac139ba37e18bNaveen Kallapublic class ClientWakelockTracker {
301b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla    public static final String LOG_TAG = "ClientWakelockTracker";
311b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla    @VisibleForTesting
321b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla    public HashMap<String, ClientWakelockAccountant> mClients =
331b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla        new HashMap<String, ClientWakelockAccountant>();
341b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla    @VisibleForTesting
351b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla    public ArrayList<ClientWakelockAccountant> mActiveClients = new ArrayList<>();
361b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla
371b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla    @VisibleForTesting
381b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla    public void startTracking(String clientId, int requestId, int token, int numRequestsInQueue) {
391b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla        ClientWakelockAccountant client = getClientWakelockAccountant(clientId);
401b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla        long uptime = SystemClock.uptimeMillis();
411b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla        client.startAttributingWakelock(requestId, token, numRequestsInQueue, uptime);
421b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla        updateConcurrentRequests(numRequestsInQueue, uptime);
431b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla        synchronized (mActiveClients) {
441b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla            if (!mActiveClients.contains(client)) {
451b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla                mActiveClients.add(client);
461b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla            }
471b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla        }
481b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla    }
491b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla
501b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla    @VisibleForTesting
511b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla    public void stopTracking(String clientId, int requestId, int token, int numRequestsInQueue) {
521b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla        ClientWakelockAccountant client = getClientWakelockAccountant(clientId);
531b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla        long uptime = SystemClock.uptimeMillis();
541b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla        client.stopAttributingWakelock(requestId, token, uptime);
551b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla        if(client.getPendingRequestCount() == 0) {
561b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla            synchronized (mActiveClients) {
571b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla                mActiveClients.remove(client);
581b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla            }
591b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla        }
601b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla        updateConcurrentRequests(numRequestsInQueue, uptime);
611b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla    }
621b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla
631b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla    @VisibleForTesting
641b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla    public void stopTrackingAll() {
651b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla        long uptime = SystemClock.uptimeMillis();
661b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla        synchronized (mActiveClients) {
671b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla            for (ClientWakelockAccountant client : mActiveClients) {
681b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla                client.stopAllPendingRequests(uptime);
691b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla            }
701b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla            mActiveClients.clear();
711b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla        }
721b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla    }
731b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla
741b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla    List<ClientRequestStats> getClientRequestStats() {
751b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla        List<ClientRequestStats> list;
761b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla        long uptime = SystemClock.uptimeMillis();
771b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla        synchronized (mClients) {
781b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla            list = new ArrayList<>(mClients.size());
791b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla            for (String key :  mClients.keySet()) {
801b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla                ClientWakelockAccountant client = mClients.get(key);
811b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla                client.updatePendingRequestWakelockTime(uptime);
821b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla                list.add(new ClientRequestStats(client.mRequestStats));
831b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla            }
841b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla        }
851b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla        return list;
861b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla    }
871b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla
881b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla    private ClientWakelockAccountant getClientWakelockAccountant(String clientId) {
891b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla        ClientWakelockAccountant client;
901b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla        synchronized (mClients) {
911b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla            if (mClients.containsKey(clientId)) {
921b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla                client = mClients.get(clientId);
931b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla            } else {
941b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla                client = new ClientWakelockAccountant(clientId);
951b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla                mClients.put(clientId, client);
961b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla            }
971b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla        }
981b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla        return client;
991b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla    }
1001b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla
1011b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla    private void updateConcurrentRequests(int numRequestsInQueue, long time) {
1021b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla        if(numRequestsInQueue != 0) {
1031b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla            synchronized (mActiveClients) {
1041b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla                for (ClientWakelockAccountant cI : mActiveClients) {
1051b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla                    cI.changeConcurrentRequests(numRequestsInQueue, time);
1061b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla                }
1071b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla            }
1081b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla        }
1091b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla    }
1101b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla
1118e2a1c76f67ebaeebd8401c4ebf7d0515b522d5eSooraj Sasindran    public boolean isClientActive(String clientId) {
1128e2a1c76f67ebaeebd8401c4ebf7d0515b522d5eSooraj Sasindran        ClientWakelockAccountant client = getClientWakelockAccountant(clientId);
1138e2a1c76f67ebaeebd8401c4ebf7d0515b522d5eSooraj Sasindran        synchronized (mActiveClients) {
1148e2a1c76f67ebaeebd8401c4ebf7d0515b522d5eSooraj Sasindran            if (mActiveClients.contains(client)) {
1158e2a1c76f67ebaeebd8401c4ebf7d0515b522d5eSooraj Sasindran                return true;
1168e2a1c76f67ebaeebd8401c4ebf7d0515b522d5eSooraj Sasindran            }
1178e2a1c76f67ebaeebd8401c4ebf7d0515b522d5eSooraj Sasindran        }
1188e2a1c76f67ebaeebd8401c4ebf7d0515b522d5eSooraj Sasindran
1198e2a1c76f67ebaeebd8401c4ebf7d0515b522d5eSooraj Sasindran        return false;
1208e2a1c76f67ebaeebd8401c4ebf7d0515b522d5eSooraj Sasindran    }
1218e2a1c76f67ebaeebd8401c4ebf7d0515b522d5eSooraj Sasindran
1221b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla    void dumpClientRequestTracker() {
1231b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla        Rlog.d(RIL.RILJ_LOG_TAG, "-------mClients---------------");
1241b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla        synchronized (mClients) {
1251b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla            for (String key : mClients.keySet()) {
1261b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla                Rlog.d(RIL.RILJ_LOG_TAG, "Client : " + key);
1271b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla                Rlog.d(RIL.RILJ_LOG_TAG, mClients.get(key).toString());
1281b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla            }
1291b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla        }
1301b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla    }
1311b90799284785b26b0853ae367cac139ba37e18bNaveen Kalla}