14b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa/* 24b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa * Copyright (C) 2014 The Android Open Source Project 34b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa * 44b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa * Licensed under the Apache License, Version 2.0 (the "License"); 54b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa * you may not use this file except in compliance with the License. 64b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa * You may obtain a copy of the License at 74b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa * 84b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa * http://www.apache.org/licenses/LICENSE-2.0 94b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa * 104b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa * Unless required by applicable law or agreed to in writing, software 114b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa * distributed under the License is distributed on an "AS IS" BASIS, 124b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa * See the License for the specific language governing permissions and 144b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa * limitations under the License 154b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa */ 164b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa 174b3e3931270f8e406fc806bc7fa1c2788256687ddestradaapackage android.location; 184b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa 194b3e3931270f8e406fc806bc7fa1c2788256687ddestradaaimport com.android.internal.util.Preconditions; 204b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa 214b3e3931270f8e406fc806bc7fa1c2788256687ddestradaaimport android.annotation.NonNull; 224b3e3931270f8e406fc806bc7fa1c2788256687ddestradaaimport android.os.RemoteException; 234b3e3931270f8e406fc806bc7fa1c2788256687ddestradaaimport android.util.Log; 244b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa 254b3e3931270f8e406fc806bc7fa1c2788256687ddestradaaimport java.util.ArrayList; 264b3e3931270f8e406fc806bc7fa1c2788256687ddestradaaimport java.util.Collection; 274b3e3931270f8e406fc806bc7fa1c2788256687ddestradaaimport java.util.HashSet; 284b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa 294b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa/** 304b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa * A base handler class to manage transport and local listeners. 314b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa * 324b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa * @hide 334b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa */ 344b3e3931270f8e406fc806bc7fa1c2788256687ddestradaaabstract class LocalListenerHelper<TListener> { 354b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa private final HashSet<TListener> mListeners = new HashSet<TListener>(); 364b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa private final String mTag; 374b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa 384b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa protected LocalListenerHelper(String name) { 394b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa Preconditions.checkNotNull(name); 404b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa mTag = name; 414b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa } 424b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa 434b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa public boolean add(@NonNull TListener listener) { 444b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa Preconditions.checkNotNull(listener); 454b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa 464b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa synchronized (mListeners) { 474b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa // we need to register with the service first, because we need to find out if the 484b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa // service will actually support the request before we attempt anything 494b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa if (mListeners.isEmpty()) { 504b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa boolean registeredWithService; 514b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa try { 524b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa registeredWithService = registerWithServer(); 534b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa } catch (RemoteException e) { 544b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa Log.e(mTag, "Error handling first listener.", e); 554b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa return false; 564b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa } 574b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa if (!registeredWithService) { 584b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa Log.e(mTag, "Unable to register listener transport."); 594b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa return false; 604b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa } 614b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa } 624b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa 634b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa if (mListeners.contains(listener)) { 644b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa return true; 654b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa } 664b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa mListeners.add(listener); 674b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa } 684b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa return true; 694b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa } 704b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa 714b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa public void remove(@NonNull TListener listener) { 724b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa Preconditions.checkNotNull(listener); 734b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa 744b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa synchronized (mListeners) { 754b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa boolean removed = mListeners.remove(listener); 764b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa boolean isLastRemoved = removed && mListeners.isEmpty(); 774b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa if (isLastRemoved) { 784b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa try { 794b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa unregisterFromServer(); 804b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa } catch (RemoteException e) { 814b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa 824b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa } 834b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa } 844b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa } 854b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa } 864b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa 874b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa protected abstract boolean registerWithServer() throws RemoteException; 884b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa protected abstract void unregisterFromServer() throws RemoteException; 894b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa 904b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa protected interface ListenerOperation<TListener> { 914b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa void execute(TListener listener) throws RemoteException; 924b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa } 934b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa 944b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa protected void foreach(ListenerOperation operation) { 954b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa Collection<TListener> listeners; 964b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa synchronized (mListeners) { 974b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa listeners = new ArrayList<TListener>(mListeners); 984b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa } 994b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa 1004b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa for (TListener listener : listeners) { 1014b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa try { 1024b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa operation.execute(listener); 1034b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa } catch (RemoteException e) { 1044b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa Log.e(mTag, "Error in monitored listener.", e); 1054b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa // don't return, give a fair chance to all listeners to receive the event 1064b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa } 1074b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa } 1084b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa } 1094b3e3931270f8e406fc806bc7fa1c2788256687ddestradaa} 110