1ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa/* 2ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * Copyright (C) 2014 The Android Open Source Project 3ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 4ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * Licensed under the Apache License, Version 2.0 (the "License"); 5ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * you may not use this file except in compliance with the License. 6ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * You may obtain a copy of the License at 7ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 8ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * http://www.apache.org/licenses/LICENSE-2.0 9ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * 10ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * Unless required by applicable law or agreed to in writing, software 11ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * distributed under the License is distributed on an "AS IS" BASIS, 12ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * See the License for the specific language governing permissions and 14ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * limitations under the License 15ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa */ 16ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 17ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaapackage com.android.server.location; 18ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 19ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaaimport android.annotation.NonNull; 206568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaaimport android.os.Handler; 21ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaaimport android.os.IBinder; 22ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaaimport android.os.IInterface; 23ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaaimport android.os.RemoteException; 24ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaaimport android.util.Log; 25ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 2648f1a647655f3479bc655d2c3c4873c6aa9b712cgomoimport com.android.internal.util.Preconditions; 2748f1a647655f3479bc655d2c3c4873c6aa9b712cgomo 28ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaaimport java.util.HashMap; 2913a60b0d41c740448ea39ca19842c7b193c61efddestradaaimport java.util.Map; 30ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 31ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa/** 32ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa * A helper class, that handles operations in remote listeners, and tracks for remote process death. 33ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa */ 34ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaaabstract class RemoteListenerHelper<TListener extends IInterface> { 3513a60b0d41c740448ea39ca19842c7b193c61efddestradaa 366568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa protected static final int RESULT_SUCCESS = 0; 376568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa protected static final int RESULT_NOT_AVAILABLE = 1; 386568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa protected static final int RESULT_NOT_SUPPORTED = 2; 396568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa protected static final int RESULT_GPS_LOCATION_DISABLED = 3; 406568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa protected static final int RESULT_INTERNAL_ERROR = 4; 4113a60b0d41c740448ea39ca19842c7b193c61efddestradaa protected static final int RESULT_UNKNOWN = 5; 4248f1a647655f3479bc655d2c3c4873c6aa9b712cgomo protected static final int RESULT_NOT_ALLOWED = 6; 436568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa 446568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa private final Handler mHandler; 454b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa private final String mTag; 46ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 4713a60b0d41c740448ea39ca19842c7b193c61efddestradaa private final Map<IBinder, LinkedListener> mListenerMap = new HashMap<>(); 486568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa 499c25085863a2762b06e9e967cffe2d8e78b17526Wyatt Riley private volatile boolean mIsRegistered; // must access only on handler thread, or read-only 509c25085863a2762b06e9e967cffe2d8e78b17526Wyatt Riley 516568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa private boolean mHasIsSupported; 526568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa private boolean mIsSupported; 536568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa 5413a60b0d41c740448ea39ca19842c7b193c61efddestradaa private int mLastReportedResult = RESULT_UNKNOWN; 5513a60b0d41c740448ea39ca19842c7b193c61efddestradaa 566568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa protected RemoteListenerHelper(Handler handler, String name) { 574b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa Preconditions.checkNotNull(name); 586568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa mHandler = handler; 594b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa mTag = name; 604b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa } 614b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa 629c25085863a2762b06e9e967cffe2d8e78b17526Wyatt Riley // read-only access for a dump() thread assured via volatile 639c25085863a2762b06e9e967cffe2d8e78b17526Wyatt Riley public boolean isRegistered() { 649c25085863a2762b06e9e967cffe2d8e78b17526Wyatt Riley return mIsRegistered; 659c25085863a2762b06e9e967cffe2d8e78b17526Wyatt Riley } 669c25085863a2762b06e9e967cffe2d8e78b17526Wyatt Riley 67ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa public boolean addListener(@NonNull TListener listener) { 68ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa Preconditions.checkNotNull(listener, "Attempted to register a 'null' listener."); 69ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa IBinder binder = listener.asBinder(); 70ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa LinkedListener deathListener = new LinkedListener(listener); 71ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa synchronized (mListenerMap) { 72ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa if (mListenerMap.containsKey(binder)) { 73ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa // listener already added 74ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa return true; 75ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 76ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa try { 77ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa binder.linkToDeath(deathListener, 0 /* flags */); 78ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } catch (RemoteException e) { 79ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa // if the remote process registering the listener is already death, just swallow the 806568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa // exception and return 816568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa Log.v(mTag, "Remote listener already died.", e); 82ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa return false; 83ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 84ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa mListenerMap.put(binder, deathListener); 856568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa 866568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa // update statuses we already know about, starting from the ones that will never change 876568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa int result; 886568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa if (!isAvailableInPlatform()) { 896568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa result = RESULT_NOT_AVAILABLE; 906568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa } else if (mHasIsSupported && !mIsSupported) { 916568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa result = RESULT_NOT_SUPPORTED; 926568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa } else if (!isGpsEnabled()) { 936568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa // only attempt to register if GPS is enabled, otherwise we will register once GPS 946568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa // becomes available 95aa420d5e1432d8669ecc10a52246e734b4eea156Wyatt Riley result = RESULT_GPS_LOCATION_DISABLED; 966568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa } else if (mHasIsSupported && mIsSupported) { 97aa420d5e1432d8669ecc10a52246e734b4eea156Wyatt Riley tryRegister(); 98aa420d5e1432d8669ecc10a52246e734b4eea156Wyatt Riley // initially presume success, possible internal error could follow asynchornously 996568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa result = RESULT_SUCCESS; 1006568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa } else { 1016568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa // at this point if the supported flag is not set, the notification will be sent 1026568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa // asynchronously in the future 1036568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa return true; 104ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 1056568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa post(listener, getHandlerOperation(result)); 106ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 107ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa return true; 108ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 109ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 1106568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa public void removeListener(@NonNull TListener listener) { 111ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa Preconditions.checkNotNull(listener, "Attempted to remove a 'null' listener."); 112ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa IBinder binder = listener.asBinder(); 113ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa LinkedListener linkedListener; 114ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa synchronized (mListenerMap) { 115ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa linkedListener = mListenerMap.remove(binder); 1166568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa if (mListenerMap.isEmpty()) { 1176568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa tryUnregister(); 118ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 119ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 120ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa if (linkedListener != null) { 121ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa binder.unlinkToDeath(linkedListener, 0 /* flags */); 122ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 123ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 124ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 1256568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa protected abstract boolean isAvailableInPlatform(); 1266568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa protected abstract boolean isGpsEnabled(); 12748f1a647655f3479bc655d2c3c4873c6aa9b712cgomo // must access only on handler thread 12848f1a647655f3479bc655d2c3c4873c6aa9b712cgomo protected abstract int registerWithService(); 129aa420d5e1432d8669ecc10a52246e734b4eea156Wyatt Riley protected abstract void unregisterFromService(); // must access only on handler thread 1306568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa protected abstract ListenerOperation<TListener> getHandlerOperation(int result); 131ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 132ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa protected interface ListenerOperation<TListener extends IInterface> { 133ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa void execute(TListener listener) throws RemoteException; 134ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 135ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 1366568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa protected void foreach(ListenerOperation<TListener> operation) { 137ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa synchronized (mListenerMap) { 1386568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa foreachUnsafe(operation); 139ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 1406568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa } 141ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 14213a60b0d41c740448ea39ca19842c7b193c61efddestradaa protected void setSupported(boolean value) { 1436568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa synchronized (mListenerMap) { 1446568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa mHasIsSupported = true; 1456568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa mIsSupported = value; 14613a60b0d41c740448ea39ca19842c7b193c61efddestradaa } 14713a60b0d41c740448ea39ca19842c7b193c61efddestradaa } 14813a60b0d41c740448ea39ca19842c7b193c61efddestradaa 149aa420d5e1432d8669ecc10a52246e734b4eea156Wyatt Riley protected void tryUpdateRegistrationWithService() { 15013a60b0d41c740448ea39ca19842c7b193c61efddestradaa synchronized (mListenerMap) { 15113a60b0d41c740448ea39ca19842c7b193c61efddestradaa if (!isGpsEnabled()) { 15213a60b0d41c740448ea39ca19842c7b193c61efddestradaa tryUnregister(); 153aa420d5e1432d8669ecc10a52246e734b4eea156Wyatt Riley return; 15413a60b0d41c740448ea39ca19842c7b193c61efddestradaa } 15513a60b0d41c740448ea39ca19842c7b193c61efddestradaa if (mListenerMap.isEmpty()) { 156aa420d5e1432d8669ecc10a52246e734b4eea156Wyatt Riley return; 15713a60b0d41c740448ea39ca19842c7b193c61efddestradaa } 158aa420d5e1432d8669ecc10a52246e734b4eea156Wyatt Riley tryRegister(); 15913a60b0d41c740448ea39ca19842c7b193c61efddestradaa } 16013a60b0d41c740448ea39ca19842c7b193c61efddestradaa } 16113a60b0d41c740448ea39ca19842c7b193c61efddestradaa 16213a60b0d41c740448ea39ca19842c7b193c61efddestradaa protected void updateResult() { 16313a60b0d41c740448ea39ca19842c7b193c61efddestradaa synchronized (mListenerMap) { 16413a60b0d41c740448ea39ca19842c7b193c61efddestradaa int newResult = calculateCurrentResultUnsafe(); 16513a60b0d41c740448ea39ca19842c7b193c61efddestradaa if (mLastReportedResult == newResult) { 16613a60b0d41c740448ea39ca19842c7b193c61efddestradaa return; 16713a60b0d41c740448ea39ca19842c7b193c61efddestradaa } 16813a60b0d41c740448ea39ca19842c7b193c61efddestradaa foreachUnsafe(getHandlerOperation(newResult)); 16913a60b0d41c740448ea39ca19842c7b193c61efddestradaa mLastReportedResult = newResult; 1706568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa } 1716568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa } 1726568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa 1736568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa private void foreachUnsafe(ListenerOperation<TListener> operation) { 1746568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa for (LinkedListener linkedListener : mListenerMap.values()) { 1756568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa post(linkedListener.getUnderlyingListener(), operation); 1766568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa } 1776568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa } 1786568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa 1796568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa private void post(TListener listener, ListenerOperation<TListener> operation) { 1806568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa if (operation != null) { 1816568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa mHandler.post(new HandlerRunnable(listener, operation)); 1826568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa } 1836568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa } 1846568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa 185aa420d5e1432d8669ecc10a52246e734b4eea156Wyatt Riley private void tryRegister() { 186aa420d5e1432d8669ecc10a52246e734b4eea156Wyatt Riley mHandler.post(new Runnable() { 18748f1a647655f3479bc655d2c3c4873c6aa9b712cgomo int registrationState = RESULT_INTERNAL_ERROR; 188aa420d5e1432d8669ecc10a52246e734b4eea156Wyatt Riley @Override 189aa420d5e1432d8669ecc10a52246e734b4eea156Wyatt Riley public void run() { 190aa420d5e1432d8669ecc10a52246e734b4eea156Wyatt Riley if (!mIsRegistered) { 19148f1a647655f3479bc655d2c3c4873c6aa9b712cgomo registrationState = registerWithService(); 19248f1a647655f3479bc655d2c3c4873c6aa9b712cgomo mIsRegistered = registrationState == RESULT_SUCCESS; 193aa420d5e1432d8669ecc10a52246e734b4eea156Wyatt Riley } 194aa420d5e1432d8669ecc10a52246e734b4eea156Wyatt Riley if (!mIsRegistered) { 195aa420d5e1432d8669ecc10a52246e734b4eea156Wyatt Riley // post back a failure 196aa420d5e1432d8669ecc10a52246e734b4eea156Wyatt Riley mHandler.post(new Runnable() { 197aa420d5e1432d8669ecc10a52246e734b4eea156Wyatt Riley @Override 198aa420d5e1432d8669ecc10a52246e734b4eea156Wyatt Riley public void run() { 199aa420d5e1432d8669ecc10a52246e734b4eea156Wyatt Riley synchronized (mListenerMap) { 20048f1a647655f3479bc655d2c3c4873c6aa9b712cgomo ListenerOperation<TListener> operation = getHandlerOperation(registrationState); 201aa420d5e1432d8669ecc10a52246e734b4eea156Wyatt Riley foreachUnsafe(operation); 202aa420d5e1432d8669ecc10a52246e734b4eea156Wyatt Riley } 203aa420d5e1432d8669ecc10a52246e734b4eea156Wyatt Riley } 204aa420d5e1432d8669ecc10a52246e734b4eea156Wyatt Riley }); 205aa420d5e1432d8669ecc10a52246e734b4eea156Wyatt Riley } 206aa420d5e1432d8669ecc10a52246e734b4eea156Wyatt Riley } 207aa420d5e1432d8669ecc10a52246e734b4eea156Wyatt Riley }); 2086568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa } 2096568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa 2106568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa private void tryUnregister() { 211aa420d5e1432d8669ecc10a52246e734b4eea156Wyatt Riley mHandler.post(new Runnable() { 212aa420d5e1432d8669ecc10a52246e734b4eea156Wyatt Riley @Override 213aa420d5e1432d8669ecc10a52246e734b4eea156Wyatt Riley public void run() { 214aa420d5e1432d8669ecc10a52246e734b4eea156Wyatt Riley if (!mIsRegistered) { 215aa420d5e1432d8669ecc10a52246e734b4eea156Wyatt Riley return; 216aa420d5e1432d8669ecc10a52246e734b4eea156Wyatt Riley } 217aa420d5e1432d8669ecc10a52246e734b4eea156Wyatt Riley unregisterFromService(); 218aa420d5e1432d8669ecc10a52246e734b4eea156Wyatt Riley mIsRegistered = false; 219aa420d5e1432d8669ecc10a52246e734b4eea156Wyatt Riley } 220aa420d5e1432d8669ecc10a52246e734b4eea156Wyatt Riley }); 221ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 222ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 22313a60b0d41c740448ea39ca19842c7b193c61efddestradaa private int calculateCurrentResultUnsafe() { 22413a60b0d41c740448ea39ca19842c7b193c61efddestradaa // update statuses we already know about, starting from the ones that will never change 22513a60b0d41c740448ea39ca19842c7b193c61efddestradaa if (!isAvailableInPlatform()) { 22613a60b0d41c740448ea39ca19842c7b193c61efddestradaa return RESULT_NOT_AVAILABLE; 22713a60b0d41c740448ea39ca19842c7b193c61efddestradaa } 22813a60b0d41c740448ea39ca19842c7b193c61efddestradaa if (!mHasIsSupported || mListenerMap.isEmpty()) { 22913a60b0d41c740448ea39ca19842c7b193c61efddestradaa // we'll update once we have a supported status available 23013a60b0d41c740448ea39ca19842c7b193c61efddestradaa return RESULT_UNKNOWN; 23113a60b0d41c740448ea39ca19842c7b193c61efddestradaa } 23213a60b0d41c740448ea39ca19842c7b193c61efddestradaa if (!mIsSupported) { 23313a60b0d41c740448ea39ca19842c7b193c61efddestradaa return RESULT_NOT_SUPPORTED; 23413a60b0d41c740448ea39ca19842c7b193c61efddestradaa } 23513a60b0d41c740448ea39ca19842c7b193c61efddestradaa if (!isGpsEnabled()) { 23613a60b0d41c740448ea39ca19842c7b193c61efddestradaa return RESULT_GPS_LOCATION_DISABLED; 23713a60b0d41c740448ea39ca19842c7b193c61efddestradaa } 23813a60b0d41c740448ea39ca19842c7b193c61efddestradaa return RESULT_SUCCESS; 23913a60b0d41c740448ea39ca19842c7b193c61efddestradaa } 24013a60b0d41c740448ea39ca19842c7b193c61efddestradaa 241ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa private class LinkedListener implements IBinder.DeathRecipient { 242ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa private final TListener mListener; 243ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 244ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa public LinkedListener(@NonNull TListener listener) { 245ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa mListener = listener; 246ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 247ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 248ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa @NonNull 249ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa public TListener getUnderlyingListener() { 250ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa return mListener; 251ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 252ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa 253ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa @Override 254ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa public void binderDied() { 2554b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa Log.d(mTag, "Remote Listener died: " + mListener); 256ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa removeListener(mListener); 257ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 258ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa } 2596568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa 2606568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa private class HandlerRunnable implements Runnable { 2616568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa private final TListener mListener; 2626568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa private final ListenerOperation<TListener> mOperation; 2636568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa 2646568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa public HandlerRunnable(TListener listener, ListenerOperation<TListener> operation) { 2656568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa mListener = listener; 2666568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa mOperation = operation; 2676568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa } 2686568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa 2696568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa @Override 2706568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa public void run() { 2716568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa try { 2726568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa mOperation.execute(mListener); 2736568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa } catch (RemoteException e) { 2746568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa Log.v(mTag, "Error in monitored listener.", e); 2756568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa } 2766568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa } 2776568d709e78d6ccaf256b7d0e4a19cdfb26deafbdestradaa } 278ea8a8a6076f04360de2d25b3e5853cde8026cd5fdestradaa} 279