Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 142f343f authored by Sooraj Sasindran's avatar Sooraj Sasindran Committed by Gerrit Code Review
Browse files

Merge changes from topic 'AttributeWakelocksHeldByClients'

* changes:
  Correct the wakelock count while attributing for a request
  Expose api to retrieve wakelock information per client
  Attribute wakelocks held by RIL to clients
parents d4da8408 1d48bb69
Loading
Loading
Loading
Loading
+134 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.internal.telephony;

import android.telephony.ClientRequestStats;
import android.telephony.Rlog;

import com.android.internal.annotations.VisibleForTesting;

import java.util.ArrayList;

public class ClientWakelockAccountant {
    public static final String LOG_TAG = "ClientWakelockAccountant: ";

    @VisibleForTesting
    public ClientRequestStats mRequestStats = new ClientRequestStats();
    @VisibleForTesting
    public ArrayList<RilWakelockInfo> mPendingRilWakelocks = new ArrayList<>();

    @VisibleForTesting
    public ClientWakelockAccountant(String callingPackage) {
        mRequestStats.setCallingPackage(callingPackage);
    }

    @VisibleForTesting
    public void startAttributingWakelock(int request,
            int token, int concurrentRequests, long time) {

        RilWakelockInfo wlInfo = new RilWakelockInfo(request, token, concurrentRequests, time);
        synchronized (mPendingRilWakelocks) {
            mPendingRilWakelocks.add(wlInfo);
        }
    }

    @VisibleForTesting
    public void stopAttributingWakelock(int request, int token, long time) {
        RilWakelockInfo wlInfo = removePendingWakelock(request, token);
        if (wlInfo != null) {
            completeRequest(wlInfo, time);
        }
    }

    @VisibleForTesting
    public void stopAllPendingRequests(long time) {
        synchronized (mPendingRilWakelocks) {
            for (RilWakelockInfo wlInfo : mPendingRilWakelocks) {
                completeRequest(wlInfo, time);
            }
            mPendingRilWakelocks.clear();
        }
    }

    @VisibleForTesting
    public void changeConcurrentRequests(int concurrentRequests, long time) {
        synchronized (mPendingRilWakelocks) {
            for (RilWakelockInfo wlInfo : mPendingRilWakelocks) {
                wlInfo.updateConcurrentRequests(concurrentRequests, time);
            }
        }
    }

    private void completeRequest(RilWakelockInfo wlInfo, long time) {
        wlInfo.setResponseTime(time);
        synchronized (mRequestStats) {
            mRequestStats.addCompletedWakelockTime(wlInfo.getWakelockTimeAttributedToClient());
            mRequestStats.incrementCompletedRequestsCount();
            mRequestStats.updateRequestHistograms(wlInfo.getRilRequestSent(),
                    (int) wlInfo.getWakelockTimeAttributedToClient());
        }
    }

    @VisibleForTesting
    public int getPendingRequestCount() {
        return mPendingRilWakelocks.size();
    }

    @VisibleForTesting
    public synchronized long updatePendingRequestWakelockTime(long uptime) {
        long totalPendingWakelockTime = 0;
        synchronized (mPendingRilWakelocks) {
            for (RilWakelockInfo wlInfo : mPendingRilWakelocks) {
                wlInfo.updateTime(uptime);
                totalPendingWakelockTime += wlInfo.getWakelockTimeAttributedToClient();
            }
        }
        synchronized (mRequestStats) {
            mRequestStats.setPendingRequestsCount(getPendingRequestCount());
            mRequestStats.setPendingRequestsWakelockTime(totalPendingWakelockTime);
        }
        return totalPendingWakelockTime;
    }

    private RilWakelockInfo removePendingWakelock(int request, int token) {
        RilWakelockInfo result = null;
        synchronized (mPendingRilWakelocks) {
            for (RilWakelockInfo wlInfo : mPendingRilWakelocks) {
                if ((wlInfo.getTokenNumber() == token) &&
                    (wlInfo.getRilRequestSent() == request)) {
                    result = wlInfo;
                }
            }
            if( result != null ) {
                mPendingRilWakelocks.remove(result);
            }
        }
        if(result == null) {
            Rlog.w(LOG_TAG, "Looking for Request<" + request + "," + token + "> in "
                + mPendingRilWakelocks);
        }
        return result;
    }

    @Override
    public String toString() {
        return "ClientWakelockAccountant{" +
                "mRequestStats=" + mRequestStats +
                ", mPendingRilWakelocks=" + mPendingRilWakelocks +
                '}';
    }
}
+131 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License
 */

package com.android.internal.telephony;

import android.os.SystemClock;
import android.telephony.ClientRequestStats;
import android.telephony.Rlog;

import com.android.internal.annotations.VisibleForTesting;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class ClientWakelockTracker {
    public static final String LOG_TAG = "ClientWakelockTracker";
    @VisibleForTesting
    public HashMap<String, ClientWakelockAccountant> mClients =
        new HashMap<String, ClientWakelockAccountant>();
    @VisibleForTesting
    public ArrayList<ClientWakelockAccountant> mActiveClients = new ArrayList<>();

    @VisibleForTesting
    public void startTracking(String clientId, int requestId, int token, int numRequestsInQueue) {
        ClientWakelockAccountant client = getClientWakelockAccountant(clientId);
        long uptime = SystemClock.uptimeMillis();
        client.startAttributingWakelock(requestId, token, numRequestsInQueue, uptime);
        updateConcurrentRequests(numRequestsInQueue, uptime);
        synchronized (mActiveClients) {
            if (!mActiveClients.contains(client)) {
                mActiveClients.add(client);
            }
        }
    }

    @VisibleForTesting
    public void stopTracking(String clientId, int requestId, int token, int numRequestsInQueue) {
        ClientWakelockAccountant client = getClientWakelockAccountant(clientId);
        long uptime = SystemClock.uptimeMillis();
        client.stopAttributingWakelock(requestId, token, uptime);
        if(client.getPendingRequestCount() == 0) {
            synchronized (mActiveClients) {
                mActiveClients.remove(client);
            }
        }
        updateConcurrentRequests(numRequestsInQueue, uptime);
    }

    @VisibleForTesting
    public void stopTrackingAll() {
        long uptime = SystemClock.uptimeMillis();
        synchronized (mActiveClients) {
            for (ClientWakelockAccountant client : mActiveClients) {
                client.stopAllPendingRequests(uptime);
            }
            mActiveClients.clear();
        }
    }

    List<ClientRequestStats> getClientRequestStats() {
        List<ClientRequestStats> list;
        long uptime = SystemClock.uptimeMillis();
        synchronized (mClients) {
            list = new ArrayList<>(mClients.size());
            for (String key :  mClients.keySet()) {
                ClientWakelockAccountant client = mClients.get(key);
                client.updatePendingRequestWakelockTime(uptime);
                list.add(new ClientRequestStats(client.mRequestStats));
            }
        }
        return list;
    }

    private ClientWakelockAccountant getClientWakelockAccountant(String clientId) {
        ClientWakelockAccountant client;
        synchronized (mClients) {
            if (mClients.containsKey(clientId)) {
                client = mClients.get(clientId);
            } else {
                client = new ClientWakelockAccountant(clientId);
                mClients.put(clientId, client);
            }
        }
        return client;
    }

    private void updateConcurrentRequests(int numRequestsInQueue, long time) {
        if(numRequestsInQueue != 0) {
            synchronized (mActiveClients) {
                for (ClientWakelockAccountant cI : mActiveClients) {
                    cI.changeConcurrentRequests(numRequestsInQueue, time);
                }
            }
        }
    }

    public boolean isClientActive(String clientId) {
        ClientWakelockAccountant client = getClientWakelockAccountant(clientId);
        synchronized (mActiveClients) {
            if (mActiveClients.contains(client)) {
                return true;
            }
        }

        return false;
    }

    void dumpClientRequestTracker() {
        Rlog.d(RIL.RILJ_LOG_TAG, "-------mClients---------------");
        synchronized (mClients) {
            for (String key : mClients.keySet()) {
                Rlog.d(RIL.RILJ_LOG_TAG, "Client : " + key);
                Rlog.d(RIL.RILJ_LOG_TAG, mClients.get(key).toString());
            }
        }
    }
}
 No newline at end of file
+12 −3
Original line number Diff line number Diff line
@@ -18,7 +18,9 @@ package com.android.internal.telephony;

import android.os.Handler;
import android.os.Message;
import android.os.WorkSource;
import android.service.carrier.CarrierIdentifier;
import android.telephony.ClientRequestStats;

import com.android.internal.telephony.cdma.CdmaSmsBroadcastConfigInfo;
import com.android.internal.telephony.dataconnection.DataProfile;
@@ -1387,8 +1389,9 @@ public interface CommandsInterface {
     * Query neighboring cell ids
     *
     * @param response s callback message to cell ids
     * @param workSource calling WorkSource
     */
    void getNeighboringCids(Message response);
    default void getNeighboringCids(Message response, WorkSource workSource){}

    /**
     * Request to enable/disable network state change notifications when
@@ -1730,8 +1733,9 @@ public interface CommandsInterface {
     * AsyncResult.result is a of Collection<CellInfo>
     *
     * @param result is sent back to handler and result.obj is a AsyncResult
     * @param workSource calling WorkSource
     */
    void getCellInfoList(Message result);
    default void getCellInfoList(Message result, WorkSource workSource) {}

    /**
     * Sets the minimum time in milli-seconds between when RIL_UNSOL_CELL_INFO_LIST
@@ -1747,8 +1751,9 @@ public interface CommandsInterface {
     * @param response.obj is AsyncResult ar when sent to associated handler
     *                        ar.exception carries exception on failure or null on success
     *                        otherwise the error.
     * @param workSource calling WorkSource
     */
    void setCellInfoListRate(int rateInMillis, Message response);
    default void setCellInfoListRate(int rateInMillis, Message response, WorkSource workSource){}

    /**
     * Fires when RIL_UNSOL_CELL_INFO_LIST is received from the RIL.
@@ -2055,4 +2060,8 @@ public interface CommandsInterface {
     * @param h handler to be removed
     */
    public void unregisterForPcoData(Handler h);

    default public List<ClientRequestStats> getClientRequestStats() {
        return null;
    }
}
+5 −4
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ import android.os.Registrant;
import android.os.RegistrantList;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.WorkSource;
import android.preference.PreferenceManager;
import android.provider.Settings;
import android.provider.Telephony;
@@ -407,9 +408,9 @@ public class GsmCdmaPhone extends Phone {
    }

    @Override
    public CellLocation getCellLocation() {
    public CellLocation getCellLocation(WorkSource workSource) {
        if (isPhoneTypeGsm()) {
            return mSST.getCellLocation();
            return mSST.getCellLocation(workSource);
        } else {
            CdmaCellLocation loc = (CdmaCellLocation)mSST.mCellLoc;

@@ -1723,9 +1724,9 @@ public class GsmCdmaPhone extends Phone {
    }

    @Override
    public void getNeighboringCids(Message response) {
    public void getNeighboringCids(Message response, WorkSource workSource) {
        if (isPhoneTypeGsm()) {
            mCi.getNeighboringCids(response);
            mCi.getNeighboringCids(response, workSource);
        } else {
            /*
             * This is currently not implemented.  At least as of June
+17 −4
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ import android.os.Message;
import android.os.Registrant;
import android.os.RegistrantList;
import android.os.SystemProperties;
import android.os.WorkSource;
import android.preference.PreferenceManager;
import android.provider.Settings;
import android.service.carrier.CarrierIdentifier;
@@ -41,6 +42,8 @@ import android.telecom.VideoProfile;
import android.telephony.CellIdentityCdma;
import android.telephony.CellInfo;
import android.telephony.CellInfoCdma;
import android.telephony.CellLocation;
import android.telephony.ClientRequestStats;
import android.telephony.PhoneStateListener;
import android.telephony.RadioAccessFamily;
import android.telephony.Rlog;
@@ -1163,6 +1166,10 @@ public abstract class Phone extends Handler implements PhoneInternalInterface {
        mCi.getNetworkSelectionMode(message);
    }

    public List<ClientRequestStats> getClientRequestStats() {
        return mCi.getClientRequestStats();
    }

    /**
     * Manually selects a network. <code>response</code> is
     * dispatched when this is complete.  <code>response.obj</code> will be
@@ -1584,13 +1591,18 @@ public abstract class Phone extends Handler implements PhoneInternalInterface {
    }

    /**
     * @param workSource calling WorkSource
     * @return all available cell information or null if none.
     */
    public List<CellInfo> getAllCellInfo() {
        List<CellInfo> cellInfoList = getServiceStateTracker().getAllCellInfo();
    public List<CellInfo> getAllCellInfo(WorkSource workSource) {
        List<CellInfo> cellInfoList = getServiceStateTracker().getAllCellInfo(workSource);
        return privatizeCellInfoList(cellInfoList);
    }

    public CellLocation getCellLocation() {
        return getCellLocation(null);
    }

    /**
     * Clear CDMA base station lat/long values if location setting is disabled.
     * @param cellInfoList the original cell info list from the RIL
@@ -1633,9 +1645,10 @@ public abstract class Phone extends Handler implements PhoneInternalInterface {
     * A onCellInfoChanged.
     *
     * @param rateInMillis the rate
     * @param workSource calling WorkSource
     */
    public void setCellInfoListRate(int rateInMillis) {
        mCi.setCellInfoListRate(rateInMillis, null);
    public void setCellInfoListRate(int rateInMillis, WorkSource workSource) {
        mCi.setCellInfoListRate(rateInMillis, null, workSource);
    }

    /**
Loading