Home | History | Annotate | Download | only in embmstestapp
      1 /*
      2  * Copyright (C) 2017 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 android.telephony.cts.embmstestapp;
     18 
     19 import android.app.Service;
     20 import android.content.ComponentName;
     21 import android.content.Intent;
     22 import android.net.Uri;
     23 import android.os.Binder;
     24 import android.os.Handler;
     25 import android.os.HandlerThread;
     26 import android.os.IBinder;
     27 import android.os.RemoteException;
     28 import android.telephony.mbms.GroupCall;
     29 import android.telephony.mbms.MbmsErrors;
     30 import android.telephony.mbms.MbmsGroupCallSessionCallback;
     31 import android.telephony.mbms.GroupCallCallback;
     32 import android.telephony.mbms.vendor.MbmsGroupCallServiceBase;
     33 import android.util.Log;
     34 
     35 import java.util.Arrays;
     36 import java.util.Collections;
     37 import java.util.HashSet;
     38 import java.util.LinkedList;
     39 import java.util.List;
     40 import java.util.Set;
     41 
     42 public class CtsGroupCallService extends MbmsGroupCallServiceBase {
     43     private static final Set<String> ALLOWED_PACKAGES = new HashSet<String>() {{
     44         add("android.telephony.cts");
     45     }};
     46     private static final String TAG = "EmbmsTestGroupCall";
     47 
     48     public static final String METHOD_INITIALIZE = "initialize";
     49     public static final String METHOD_START_GROUP_CALL = "startGroupCall";
     50     public static final String METHOD_UPDATE_GROUP_CALL = "updateGroupCall";
     51     public static final String METHOD_STOP_GROUP_CALL = "stopGroupCall";
     52     public static final String METHOD_CLOSE = "close";
     53 
     54     public static final String CONTROL_INTERFACE_ACTION =
     55             "android.telephony.cts.embmstestapp.ACTION_CONTROL_MIDDLEWARE";
     56     public static final ComponentName CONTROL_INTERFACE_COMPONENT =
     57             ComponentName.unflattenFromString(
     58                     "android.telephony.cts.embmstestapp/.CtsGroupCallService");
     59 
     60     private MbmsGroupCallSessionCallback mAppCallback;
     61     private GroupCallCallback mGroupCallCallback;
     62 
     63     private HandlerThread mHandlerThread;
     64     private Handler mHandler;
     65     private List<List> mReceivedCalls = new LinkedList<>();
     66     private int mErrorCodeOverride = MbmsErrors.SUCCESS;
     67 
     68     @Override
     69     public int initialize(MbmsGroupCallSessionCallback callback, int subId) {
     70         mReceivedCalls.add(Arrays.asList(METHOD_INITIALIZE, subId));
     71         if (mErrorCodeOverride != MbmsErrors.SUCCESS) {
     72             return mErrorCodeOverride;
     73         }
     74 
     75         int packageUid = Binder.getCallingUid();
     76         String[] packageNames = getPackageManager().getPackagesForUid(packageUid);
     77         if (packageNames == null) {
     78             return MbmsErrors.InitializationErrors.ERROR_APP_PERMISSIONS_NOT_GRANTED;
     79         }
     80         boolean isUidAllowed = Arrays.stream(packageNames).anyMatch(ALLOWED_PACKAGES::contains);
     81         if (!isUidAllowed) {
     82             return MbmsErrors.InitializationErrors.ERROR_APP_PERMISSIONS_NOT_GRANTED;
     83         }
     84 
     85         mHandler.post(() -> {
     86             if (mAppCallback == null) {
     87                 mAppCallback = callback;
     88             } else {
     89                 callback.onError(
     90                         MbmsErrors.InitializationErrors.ERROR_DUPLICATE_INITIALIZE, "");
     91                 return;
     92             }
     93             callback.onMiddlewareReady();
     94         });
     95         return MbmsErrors.SUCCESS;
     96     }
     97 
     98     @Override
     99     public int startGroupCall(final int subscriptionId, final long tmgi,
    100             final List<Integer> saiArray, final List<Integer> frequencyArray,
    101             final GroupCallCallback callback) {
    102         mReceivedCalls.add(Arrays.asList(METHOD_START_GROUP_CALL, subscriptionId, tmgi, saiArray,
    103                 frequencyArray));
    104         if (mErrorCodeOverride != MbmsErrors.SUCCESS) {
    105             return mErrorCodeOverride;
    106         }
    107 
    108         mGroupCallCallback = callback;
    109         mHandler.post(() -> callback.onGroupCallStateChanged(GroupCall.STATE_STARTED,
    110                 GroupCall.REASON_BY_USER_REQUEST));
    111         return MbmsErrors.SUCCESS;
    112     }
    113 
    114     @Override
    115     public void updateGroupCall(int subscriptionId, long tmgi,
    116             List<Integer> saiArray, List<Integer> frequencyArray) {
    117         mReceivedCalls.add(Arrays.asList(METHOD_UPDATE_GROUP_CALL,
    118                 subscriptionId, tmgi, saiArray, frequencyArray));
    119     }
    120 
    121     @Override
    122     public void stopGroupCall(int subscriptionId, long tmgi) {
    123         mReceivedCalls.add(Arrays.asList(METHOD_STOP_GROUP_CALL, subscriptionId, tmgi));
    124     }
    125 
    126     @Override
    127     public void dispose(int subscriptionId) {
    128         mReceivedCalls.add(Arrays.asList(METHOD_CLOSE, subscriptionId));
    129     }
    130 
    131     @Override
    132     public void onAppCallbackDied(int uid, int subscriptionId) {
    133         mAppCallback = null;
    134     }
    135 
    136     private final IBinder mControlInterface = new ICtsGroupCallMiddlewareControl.Stub() {
    137         @Override
    138         public void reset() {
    139             mReceivedCalls.clear();
    140             mHandler.removeCallbacksAndMessages(null);
    141             mAppCallback = null;
    142             mErrorCodeOverride = MbmsErrors.SUCCESS;
    143         }
    144 
    145         @Override
    146         public List getGroupCallSessionCalls() {
    147             return mReceivedCalls;
    148         }
    149 
    150         @Override
    151         public void forceErrorCode(int error) {
    152             mErrorCodeOverride = error;
    153         }
    154 
    155         @Override
    156         public void fireErrorOnGroupCall(int errorCode, String message) {
    157             mHandler.post(() -> mGroupCallCallback.onError(errorCode, message));
    158         }
    159 
    160         @Override
    161         public void fireErrorOnSession(int errorCode, String message) {
    162             mHandler.post(() -> mAppCallback.onError(errorCode, message));
    163         }
    164 
    165         @Override
    166         public void fireGroupCallStateChanged(int state, int reason) {
    167             mHandler.post(() -> mGroupCallCallback.onGroupCallStateChanged(state, reason));
    168         }
    169 
    170         @Override
    171         public void fireBroadcastSignalStrengthUpdated(int signalStrength) {
    172             mHandler.post(
    173                     () -> mGroupCallCallback.onBroadcastSignalStrengthUpdated(signalStrength));
    174         }
    175 
    176         @Override
    177         public void fireAvailableSaisUpdated(List currentSais, List availableSais) {
    178             mHandler.post(() -> mAppCallback.onAvailableSaisUpdated(currentSais, availableSais));
    179         }
    180 
    181         @Override
    182         public void fireServiceInterfaceAvailable(String interfaceName, int index) {
    183             mHandler.post(() -> mAppCallback.onServiceInterfaceAvailable(interfaceName, index));
    184         }
    185     };
    186 
    187     @Override
    188     public void onDestroy() {
    189         mHandlerThread.quitSafely();
    190         logd("CtsGroupCallService onDestroy");
    191         super.onDestroy();
    192     }
    193 
    194     @Override
    195     public IBinder onBind(Intent intent) {
    196         logd("CtsGroupCallService onBind");
    197         if (CONTROL_INTERFACE_ACTION.equals(intent.getAction())) {
    198             logd("CtsGroupCallService control interface bind");
    199             return mControlInterface;
    200         }
    201         IBinder binder = super.onBind(intent);
    202 
    203         if (mHandlerThread != null && mHandlerThread.isAlive()) {
    204             return binder;
    205         }
    206 
    207         mHandlerThread = new HandlerThread("CtsGroupCallServiceWorker");
    208         mHandlerThread.start();
    209         mHandler = new Handler(mHandlerThread.getLooper());
    210         return binder;
    211     }
    212 
    213     private static void logd(String s) {
    214         Log.d(TAG, s);
    215     }
    216 
    217     private void checkInitialized() {
    218         if (mAppCallback == null) {
    219             throw new IllegalStateException("Not yet initialized");
    220         }
    221     }
    222 }
    223