1 /* 2 * Copyright (C) 2020 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 com.android.server.location.gnss; 18 19 import android.content.Context; 20 import android.location.GnssAntennaInfo; 21 import android.location.IGnssAntennaInfoListener; 22 import android.os.Handler; 23 import android.util.Log; 24 25 import com.android.internal.annotations.VisibleForTesting; 26 import com.android.server.location.CallerIdentity; 27 import com.android.server.location.RemoteListenerHelper; 28 29 import java.util.List; 30 31 /** 32 * An base implementation for GNSS antenna info provider. It abstracts out the responsibility of 33 * handling listeners, while still allowing technology specific implementations to be built. 34 * 35 * @hide 36 */ 37 public abstract class GnssAntennaInfoProvider 38 extends RemoteListenerHelper<Void, IGnssAntennaInfoListener> { 39 private static final String TAG = "GnssAntennaInfoProvider"; 40 private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); 41 42 private final GnssAntennaInfoProviderNative mNative; 43 44 private boolean mIsListeningStarted; 45 GnssAntennaInfoProvider(Context context, Handler handler)46 protected GnssAntennaInfoProvider(Context context, Handler handler) { 47 this(context, handler, new GnssAntennaInfoProviderNative()); 48 } 49 50 @VisibleForTesting GnssAntennaInfoProvider( Context context, Handler handler, GnssAntennaInfoProviderNative aNative)51 public GnssAntennaInfoProvider( 52 Context context, Handler handler, GnssAntennaInfoProviderNative aNative) { 53 super(context, handler, TAG); 54 mNative = aNative; 55 } 56 resumeIfStarted()57 void resumeIfStarted() { 58 if (DEBUG) { 59 Log.d(TAG, "resumeIfStarted"); 60 } 61 if (mIsListeningStarted) { 62 mNative.startAntennaInfoListening(); 63 } 64 } 65 66 67 @Override isAvailableInPlatform()68 public boolean isAvailableInPlatform() { 69 return mNative.isAntennaInfoSupported(); 70 } 71 72 @Override registerWithService()73 protected int registerWithService() { 74 boolean started = mNative.startAntennaInfoListening(); 75 if (started) { 76 mIsListeningStarted = true; 77 return RemoteListenerHelper.RESULT_SUCCESS; 78 } 79 return RemoteListenerHelper.RESULT_INTERNAL_ERROR; 80 } 81 82 @Override unregisterFromService()83 protected void unregisterFromService() { 84 boolean stopped = mNative.stopAntennaInfoListening(); 85 if (stopped) { 86 mIsListeningStarted = false; 87 } 88 } 89 90 /** Handle GNSS capabilities update from the GNSS HAL implementation. */ onCapabilitiesUpdated(boolean isAntennaInfoSupported)91 public void onCapabilitiesUpdated(boolean isAntennaInfoSupported) { 92 setSupported(isAntennaInfoSupported); 93 updateResult(); 94 } 95 96 /** Handle GNSS enabled changes.*/ onGpsEnabledChanged()97 public void onGpsEnabledChanged() { 98 tryUpdateRegistrationWithService(); 99 updateResult(); 100 } 101 102 @Override getHandlerOperation(int result)103 protected ListenerOperation<IGnssAntennaInfoListener> getHandlerOperation(int result) { 104 return (IGnssAntennaInfoListener listener, 105 CallerIdentity callerIdentity) -> { 106 // Do nothing, as GnssAntennaInfo.Callback does not have an onStatusChanged method. 107 }; 108 } 109 110 /** Handle Gnss Antenna Info report. */ onGnssAntennaInfoAvailable(final List<GnssAntennaInfo> gnssAntennaInfos)111 public void onGnssAntennaInfoAvailable(final List<GnssAntennaInfo> gnssAntennaInfos) { 112 foreach((IGnssAntennaInfoListener listener, CallerIdentity callerIdentity) -> { 113 if (!hasPermission(mContext, callerIdentity)) { 114 logPermissionDisabledEventNotReported( 115 TAG, callerIdentity.packageName, "GNSS antenna info"); 116 return; 117 } 118 listener.onGnssAntennaInfoReceived(gnssAntennaInfos); 119 }); 120 } 121 122 /** 123 * Wrapper class for native methods. This is mocked for testing. 124 */ 125 @VisibleForTesting 126 public static class GnssAntennaInfoProviderNative { 127 isAntennaInfoSupported()128 public boolean isAntennaInfoSupported() { 129 return native_is_antenna_info_supported(); 130 } 131 132 /** Start antenna info listening. */ startAntennaInfoListening()133 public boolean startAntennaInfoListening() { 134 return native_start_antenna_info_listening(); 135 } 136 137 /** Stop antenna info listening. */ stopAntennaInfoListening()138 public boolean stopAntennaInfoListening() { 139 return native_stop_antenna_info_listening(); 140 } 141 } 142 native_is_antenna_info_supported()143 private static native boolean native_is_antenna_info_supported(); 144 native_start_antenna_info_listening()145 private static native boolean native_start_antenna_info_listening(); 146 native_stop_antenna_info_listening()147 private static native boolean native_stop_antenna_info_listening(); 148 } 149