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