1c066b40160496c1265e21a3b624e267e47807137Pengquan Meng/*
2c066b40160496c1265e21a3b624e267e47807137Pengquan Meng * Copyright (C) 2017 The Android Open Source Project
3c066b40160496c1265e21a3b624e267e47807137Pengquan Meng *
4c066b40160496c1265e21a3b624e267e47807137Pengquan Meng * Licensed under the Apache License, Version 2.0 (the "License");
5c066b40160496c1265e21a3b624e267e47807137Pengquan Meng * you may not use this file except in compliance with the License.
6c066b40160496c1265e21a3b624e267e47807137Pengquan Meng * You may obtain a copy of the License at
7c066b40160496c1265e21a3b624e267e47807137Pengquan Meng *
8c066b40160496c1265e21a3b624e267e47807137Pengquan Meng *      http://www.apache.org/licenses/LICENSE-2.0
9c066b40160496c1265e21a3b624e267e47807137Pengquan Meng *
10c066b40160496c1265e21a3b624e267e47807137Pengquan Meng * Unless required by applicable law or agreed to in writing, software
11c066b40160496c1265e21a3b624e267e47807137Pengquan Meng * distributed under the License is distributed on an "AS IS" BASIS,
12c066b40160496c1265e21a3b624e267e47807137Pengquan Meng * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c066b40160496c1265e21a3b624e267e47807137Pengquan Meng * See the License for the specific language governing permissions and
14c066b40160496c1265e21a3b624e267e47807137Pengquan Meng * limitations under the License.
15c066b40160496c1265e21a3b624e267e47807137Pengquan Meng */
16c066b40160496c1265e21a3b624e267e47807137Pengquan Meng
17c066b40160496c1265e21a3b624e267e47807137Pengquan Mengpackage com.android.internal.telephony;
18c066b40160496c1265e21a3b624e267e47807137Pengquan Meng
19c066b40160496c1265e21a3b624e267e47807137Pengquan Mengimport android.os.AsyncResult;
20c066b40160496c1265e21a3b624e267e47807137Pengquan Mengimport android.os.Message;
21c066b40160496c1265e21a3b624e267e47807137Pengquan Mengimport android.os.SystemClock;
22c066b40160496c1265e21a3b624e267e47807137Pengquan Mengimport android.os.WorkSource;
239e0a2cd0de646f9455c0d6ab34632b89b418235cNarayan Kamathimport android.os.WorkSource.WorkChain;
24c066b40160496c1265e21a3b624e267e47807137Pengquan Mengimport android.telephony.Rlog;
25c066b40160496c1265e21a3b624e267e47807137Pengquan Meng
269e0a2cd0de646f9455c0d6ab34632b89b418235cNarayan Kamathimport java.util.ArrayList;
27c066b40160496c1265e21a3b624e267e47807137Pengquan Mengimport java.util.Random;
28c066b40160496c1265e21a3b624e267e47807137Pengquan Mengimport java.util.concurrent.atomic.AtomicInteger;
29c066b40160496c1265e21a3b624e267e47807137Pengquan Meng
30c066b40160496c1265e21a3b624e267e47807137Pengquan Meng/**
31c066b40160496c1265e21a3b624e267e47807137Pengquan Meng * {@hide}
32c066b40160496c1265e21a3b624e267e47807137Pengquan Meng */
33c066b40160496c1265e21a3b624e267e47807137Pengquan Meng
34c066b40160496c1265e21a3b624e267e47807137Pengquan Mengpublic class RILRequest {
35c066b40160496c1265e21a3b624e267e47807137Pengquan Meng    static final String LOG_TAG = "RilRequest";
36c066b40160496c1265e21a3b624e267e47807137Pengquan Meng
37c066b40160496c1265e21a3b624e267e47807137Pengquan Meng    //***** Class Variables
38c066b40160496c1265e21a3b624e267e47807137Pengquan Meng    static Random sRandom = new Random();
39c066b40160496c1265e21a3b624e267e47807137Pengquan Meng    static AtomicInteger sNextSerial = new AtomicInteger(0);
40c066b40160496c1265e21a3b624e267e47807137Pengquan Meng    private static Object sPoolSync = new Object();
41c066b40160496c1265e21a3b624e267e47807137Pengquan Meng    private static RILRequest sPool = null;
42c066b40160496c1265e21a3b624e267e47807137Pengquan Meng    private static int sPoolSize = 0;
43c066b40160496c1265e21a3b624e267e47807137Pengquan Meng    private static final int MAX_POOL_SIZE = 4;
44c066b40160496c1265e21a3b624e267e47807137Pengquan Meng
45c066b40160496c1265e21a3b624e267e47807137Pengquan Meng    //***** Instance Variables
46c066b40160496c1265e21a3b624e267e47807137Pengquan Meng    int mSerial;
47c066b40160496c1265e21a3b624e267e47807137Pengquan Meng    int mRequest;
48c066b40160496c1265e21a3b624e267e47807137Pengquan Meng    Message mResult;
49c066b40160496c1265e21a3b624e267e47807137Pengquan Meng    RILRequest mNext;
50c066b40160496c1265e21a3b624e267e47807137Pengquan Meng    int mWakeLockType;
51c066b40160496c1265e21a3b624e267e47807137Pengquan Meng    WorkSource mWorkSource;
52c066b40160496c1265e21a3b624e267e47807137Pengquan Meng    String mClientId;
53c066b40160496c1265e21a3b624e267e47807137Pengquan Meng    // time in ms when RIL request was made
54c066b40160496c1265e21a3b624e267e47807137Pengquan Meng    long mStartTimeMs;
55c066b40160496c1265e21a3b624e267e47807137Pengquan Meng
56c066b40160496c1265e21a3b624e267e47807137Pengquan Meng    public int getSerial() {
57c066b40160496c1265e21a3b624e267e47807137Pengquan Meng        return mSerial;
58c066b40160496c1265e21a3b624e267e47807137Pengquan Meng    }
59c066b40160496c1265e21a3b624e267e47807137Pengquan Meng
60c066b40160496c1265e21a3b624e267e47807137Pengquan Meng    public int getRequest() {
61c066b40160496c1265e21a3b624e267e47807137Pengquan Meng        return mRequest;
62c066b40160496c1265e21a3b624e267e47807137Pengquan Meng    }
63c066b40160496c1265e21a3b624e267e47807137Pengquan Meng
64c066b40160496c1265e21a3b624e267e47807137Pengquan Meng    public Message getResult() {
65c066b40160496c1265e21a3b624e267e47807137Pengquan Meng        return mResult;
66c066b40160496c1265e21a3b624e267e47807137Pengquan Meng    }
67c066b40160496c1265e21a3b624e267e47807137Pengquan Meng
68c066b40160496c1265e21a3b624e267e47807137Pengquan Meng    /**
69c066b40160496c1265e21a3b624e267e47807137Pengquan Meng     * Retrieves a new RILRequest instance from the pool.
70c066b40160496c1265e21a3b624e267e47807137Pengquan Meng     *
71c066b40160496c1265e21a3b624e267e47807137Pengquan Meng     * @param request RIL_REQUEST_*
72c066b40160496c1265e21a3b624e267e47807137Pengquan Meng     * @param result sent when operation completes
73c066b40160496c1265e21a3b624e267e47807137Pengquan Meng     * @return a RILRequest instance from the pool.
74c066b40160496c1265e21a3b624e267e47807137Pengquan Meng     */
75c066b40160496c1265e21a3b624e267e47807137Pengquan Meng    private static RILRequest obtain(int request, Message result) {
76c066b40160496c1265e21a3b624e267e47807137Pengquan Meng        RILRequest rr = null;
77c066b40160496c1265e21a3b624e267e47807137Pengquan Meng
78c066b40160496c1265e21a3b624e267e47807137Pengquan Meng        synchronized (sPoolSync) {
79c066b40160496c1265e21a3b624e267e47807137Pengquan Meng            if (sPool != null) {
80c066b40160496c1265e21a3b624e267e47807137Pengquan Meng                rr = sPool;
81c066b40160496c1265e21a3b624e267e47807137Pengquan Meng                sPool = rr.mNext;
82c066b40160496c1265e21a3b624e267e47807137Pengquan Meng                rr.mNext = null;
83c066b40160496c1265e21a3b624e267e47807137Pengquan Meng                sPoolSize--;
84c066b40160496c1265e21a3b624e267e47807137Pengquan Meng            }
85c066b40160496c1265e21a3b624e267e47807137Pengquan Meng        }
86c066b40160496c1265e21a3b624e267e47807137Pengquan Meng
87c066b40160496c1265e21a3b624e267e47807137Pengquan Meng        if (rr == null) {
88c066b40160496c1265e21a3b624e267e47807137Pengquan Meng            rr = new RILRequest();
89c066b40160496c1265e21a3b624e267e47807137Pengquan Meng        }
90c066b40160496c1265e21a3b624e267e47807137Pengquan Meng
91c066b40160496c1265e21a3b624e267e47807137Pengquan Meng        rr.mSerial = sNextSerial.getAndIncrement();
92c066b40160496c1265e21a3b624e267e47807137Pengquan Meng
93c066b40160496c1265e21a3b624e267e47807137Pengquan Meng        rr.mRequest = request;
94c066b40160496c1265e21a3b624e267e47807137Pengquan Meng        rr.mResult = result;
95c066b40160496c1265e21a3b624e267e47807137Pengquan Meng
96c066b40160496c1265e21a3b624e267e47807137Pengquan Meng        rr.mWakeLockType = RIL.INVALID_WAKELOCK;
97c066b40160496c1265e21a3b624e267e47807137Pengquan Meng        rr.mWorkSource = null;
98c066b40160496c1265e21a3b624e267e47807137Pengquan Meng        rr.mStartTimeMs = SystemClock.elapsedRealtime();
99c066b40160496c1265e21a3b624e267e47807137Pengquan Meng        if (result != null && result.getTarget() == null) {
100c066b40160496c1265e21a3b624e267e47807137Pengquan Meng            throw new NullPointerException("Message target must not be null");
101c066b40160496c1265e21a3b624e267e47807137Pengquan Meng        }
102c066b40160496c1265e21a3b624e267e47807137Pengquan Meng
103c066b40160496c1265e21a3b624e267e47807137Pengquan Meng        return rr;
104c066b40160496c1265e21a3b624e267e47807137Pengquan Meng    }
105c066b40160496c1265e21a3b624e267e47807137Pengquan Meng
106c066b40160496c1265e21a3b624e267e47807137Pengquan Meng
107c066b40160496c1265e21a3b624e267e47807137Pengquan Meng    /**
108c066b40160496c1265e21a3b624e267e47807137Pengquan Meng     * Retrieves a new RILRequest instance from the pool and sets the clientId
109c066b40160496c1265e21a3b624e267e47807137Pengquan Meng     *
110c066b40160496c1265e21a3b624e267e47807137Pengquan Meng     * @param request RIL_REQUEST_*
111c066b40160496c1265e21a3b624e267e47807137Pengquan Meng     * @param result sent when operation completes
112c066b40160496c1265e21a3b624e267e47807137Pengquan Meng     * @param workSource WorkSource to track the client
113c066b40160496c1265e21a3b624e267e47807137Pengquan Meng     * @return a RILRequest instance from the pool.
114c066b40160496c1265e21a3b624e267e47807137Pengquan Meng     */
1159e0a2cd0de646f9455c0d6ab34632b89b418235cNarayan Kamath    // @VisibleForTesting
1169e0a2cd0de646f9455c0d6ab34632b89b418235cNarayan Kamath    public static RILRequest obtain(int request, Message result, WorkSource workSource) {
117c066b40160496c1265e21a3b624e267e47807137Pengquan Meng        RILRequest rr = null;
118c066b40160496c1265e21a3b624e267e47807137Pengquan Meng
119c066b40160496c1265e21a3b624e267e47807137Pengquan Meng        rr = obtain(request, result);
120c066b40160496c1265e21a3b624e267e47807137Pengquan Meng        if (workSource != null) {
121c066b40160496c1265e21a3b624e267e47807137Pengquan Meng            rr.mWorkSource = workSource;
1229e0a2cd0de646f9455c0d6ab34632b89b418235cNarayan Kamath            rr.mClientId = rr.getWorkSourceClientId();
123c066b40160496c1265e21a3b624e267e47807137Pengquan Meng        } else {
124c066b40160496c1265e21a3b624e267e47807137Pengquan Meng            Rlog.e(LOG_TAG, "null workSource " + request);
125c066b40160496c1265e21a3b624e267e47807137Pengquan Meng        }
126c066b40160496c1265e21a3b624e267e47807137Pengquan Meng
127c066b40160496c1265e21a3b624e267e47807137Pengquan Meng        return rr;
128c066b40160496c1265e21a3b624e267e47807137Pengquan Meng    }
129c066b40160496c1265e21a3b624e267e47807137Pengquan Meng
130c066b40160496c1265e21a3b624e267e47807137Pengquan Meng    /**
1319e0a2cd0de646f9455c0d6ab34632b89b418235cNarayan Kamath     * Generate a String client ID from the WorkSource.
1329e0a2cd0de646f9455c0d6ab34632b89b418235cNarayan Kamath     */
1339e0a2cd0de646f9455c0d6ab34632b89b418235cNarayan Kamath    // @VisibleForTesting
1349e0a2cd0de646f9455c0d6ab34632b89b418235cNarayan Kamath    public String getWorkSourceClientId() {
1359e0a2cd0de646f9455c0d6ab34632b89b418235cNarayan Kamath        if (mWorkSource == null || mWorkSource.isEmpty()) {
1369e0a2cd0de646f9455c0d6ab34632b89b418235cNarayan Kamath            return null;
1379e0a2cd0de646f9455c0d6ab34632b89b418235cNarayan Kamath        }
1389e0a2cd0de646f9455c0d6ab34632b89b418235cNarayan Kamath
1399e0a2cd0de646f9455c0d6ab34632b89b418235cNarayan Kamath        if (mWorkSource.size() > 0) {
1409e0a2cd0de646f9455c0d6ab34632b89b418235cNarayan Kamath            return mWorkSource.get(0) + ":" + mWorkSource.getName(0);
1419e0a2cd0de646f9455c0d6ab34632b89b418235cNarayan Kamath        }
1429e0a2cd0de646f9455c0d6ab34632b89b418235cNarayan Kamath
1439e0a2cd0de646f9455c0d6ab34632b89b418235cNarayan Kamath        final ArrayList<WorkChain> workChains = mWorkSource.getWorkChains();
1449e0a2cd0de646f9455c0d6ab34632b89b418235cNarayan Kamath        if (workChains != null && !workChains.isEmpty()) {
1459e0a2cd0de646f9455c0d6ab34632b89b418235cNarayan Kamath            final WorkChain workChain = workChains.get(0);
1469e0a2cd0de646f9455c0d6ab34632b89b418235cNarayan Kamath            return workChain.getAttributionUid() + ":" + workChain.getTags()[0];
1479e0a2cd0de646f9455c0d6ab34632b89b418235cNarayan Kamath        }
1489e0a2cd0de646f9455c0d6ab34632b89b418235cNarayan Kamath
1499e0a2cd0de646f9455c0d6ab34632b89b418235cNarayan Kamath        return null;
1509e0a2cd0de646f9455c0d6ab34632b89b418235cNarayan Kamath    }
1519e0a2cd0de646f9455c0d6ab34632b89b418235cNarayan Kamath
1529e0a2cd0de646f9455c0d6ab34632b89b418235cNarayan Kamath    /**
153c066b40160496c1265e21a3b624e267e47807137Pengquan Meng     * Returns a RILRequest instance to the pool.
154c066b40160496c1265e21a3b624e267e47807137Pengquan Meng     *
155c066b40160496c1265e21a3b624e267e47807137Pengquan Meng     * Note: This should only be called once per use.
156c066b40160496c1265e21a3b624e267e47807137Pengquan Meng     */
157c066b40160496c1265e21a3b624e267e47807137Pengquan Meng    void release() {
158c066b40160496c1265e21a3b624e267e47807137Pengquan Meng        synchronized (sPoolSync) {
159c066b40160496c1265e21a3b624e267e47807137Pengquan Meng            if (sPoolSize < MAX_POOL_SIZE) {
160c066b40160496c1265e21a3b624e267e47807137Pengquan Meng                mNext = sPool;
161c066b40160496c1265e21a3b624e267e47807137Pengquan Meng                sPool = this;
162c066b40160496c1265e21a3b624e267e47807137Pengquan Meng                sPoolSize++;
163c066b40160496c1265e21a3b624e267e47807137Pengquan Meng                mResult = null;
164c066b40160496c1265e21a3b624e267e47807137Pengquan Meng                if (mWakeLockType != RIL.INVALID_WAKELOCK) {
165c066b40160496c1265e21a3b624e267e47807137Pengquan Meng                    //This is OK for some wakelock types and not others
166c066b40160496c1265e21a3b624e267e47807137Pengquan Meng                    if (mWakeLockType == RIL.FOR_WAKELOCK) {
167c066b40160496c1265e21a3b624e267e47807137Pengquan Meng                        Rlog.e(LOG_TAG, "RILRequest releasing with held wake lock: "
168c066b40160496c1265e21a3b624e267e47807137Pengquan Meng                                + serialString());
169c066b40160496c1265e21a3b624e267e47807137Pengquan Meng                    }
170c066b40160496c1265e21a3b624e267e47807137Pengquan Meng                }
171c066b40160496c1265e21a3b624e267e47807137Pengquan Meng            }
172c066b40160496c1265e21a3b624e267e47807137Pengquan Meng        }
173c066b40160496c1265e21a3b624e267e47807137Pengquan Meng    }
174c066b40160496c1265e21a3b624e267e47807137Pengquan Meng
175c066b40160496c1265e21a3b624e267e47807137Pengquan Meng    private RILRequest() {
176c066b40160496c1265e21a3b624e267e47807137Pengquan Meng    }
177c066b40160496c1265e21a3b624e267e47807137Pengquan Meng
178c066b40160496c1265e21a3b624e267e47807137Pengquan Meng    static void resetSerial() {
179c066b40160496c1265e21a3b624e267e47807137Pengquan Meng        // use a random so that on recovery we probably don't mix old requests
180c066b40160496c1265e21a3b624e267e47807137Pengquan Meng        // with new.
181c066b40160496c1265e21a3b624e267e47807137Pengquan Meng        sNextSerial.set(sRandom.nextInt());
182c066b40160496c1265e21a3b624e267e47807137Pengquan Meng    }
183c066b40160496c1265e21a3b624e267e47807137Pengquan Meng
184c066b40160496c1265e21a3b624e267e47807137Pengquan Meng    String serialString() {
185c066b40160496c1265e21a3b624e267e47807137Pengquan Meng        //Cheesy way to do %04d
186c066b40160496c1265e21a3b624e267e47807137Pengquan Meng        StringBuilder sb = new StringBuilder(8);
187c066b40160496c1265e21a3b624e267e47807137Pengquan Meng        String sn;
188c066b40160496c1265e21a3b624e267e47807137Pengquan Meng
189c066b40160496c1265e21a3b624e267e47807137Pengquan Meng        long adjustedSerial = (((long) mSerial) - Integer.MIN_VALUE) % 10000;
190c066b40160496c1265e21a3b624e267e47807137Pengquan Meng
191c066b40160496c1265e21a3b624e267e47807137Pengquan Meng        sn = Long.toString(adjustedSerial);
192c066b40160496c1265e21a3b624e267e47807137Pengquan Meng
193c066b40160496c1265e21a3b624e267e47807137Pengquan Meng        //sb.append("J[");
194c066b40160496c1265e21a3b624e267e47807137Pengquan Meng        sb.append('[');
195c066b40160496c1265e21a3b624e267e47807137Pengquan Meng        for (int i = 0, s = sn.length(); i < 4 - s; i++) {
196c066b40160496c1265e21a3b624e267e47807137Pengquan Meng            sb.append('0');
197c066b40160496c1265e21a3b624e267e47807137Pengquan Meng        }
198c066b40160496c1265e21a3b624e267e47807137Pengquan Meng
199c066b40160496c1265e21a3b624e267e47807137Pengquan Meng        sb.append(sn);
200c066b40160496c1265e21a3b624e267e47807137Pengquan Meng        sb.append(']');
201c066b40160496c1265e21a3b624e267e47807137Pengquan Meng        return sb.toString();
202c066b40160496c1265e21a3b624e267e47807137Pengquan Meng    }
203c066b40160496c1265e21a3b624e267e47807137Pengquan Meng
204c066b40160496c1265e21a3b624e267e47807137Pengquan Meng    void onError(int error, Object ret) {
205c066b40160496c1265e21a3b624e267e47807137Pengquan Meng        CommandException ex;
206c066b40160496c1265e21a3b624e267e47807137Pengquan Meng
207c066b40160496c1265e21a3b624e267e47807137Pengquan Meng        ex = CommandException.fromRilErrno(error);
208c066b40160496c1265e21a3b624e267e47807137Pengquan Meng
209c066b40160496c1265e21a3b624e267e47807137Pengquan Meng        if (RIL.RILJ_LOGD) {
210c066b40160496c1265e21a3b624e267e47807137Pengquan Meng            Rlog.d(LOG_TAG, serialString() + "< "
211c066b40160496c1265e21a3b624e267e47807137Pengquan Meng                    + RIL.requestToString(mRequest)
212c066b40160496c1265e21a3b624e267e47807137Pengquan Meng                    + " error: " + ex + " ret=" + RIL.retToString(mRequest, ret));
213c066b40160496c1265e21a3b624e267e47807137Pengquan Meng        }
214c066b40160496c1265e21a3b624e267e47807137Pengquan Meng
215c066b40160496c1265e21a3b624e267e47807137Pengquan Meng        if (mResult != null) {
216c066b40160496c1265e21a3b624e267e47807137Pengquan Meng            AsyncResult.forMessage(mResult, ret, ex);
217c066b40160496c1265e21a3b624e267e47807137Pengquan Meng            mResult.sendToTarget();
218c066b40160496c1265e21a3b624e267e47807137Pengquan Meng        }
219c066b40160496c1265e21a3b624e267e47807137Pengquan Meng    }
220c066b40160496c1265e21a3b624e267e47807137Pengquan Meng}
221