1344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com/* 2344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com * Copyright (C) 2012 Google Inc. 3344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com * 4344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com * use this file except in compliance with the License. You may obtain a copy of 6344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com * the License at 7344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com * 8344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com * http://www.apache.org/licenses/LICENSE-2.0 9344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com * 10344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com * Unless required by applicable law or agreed to in writing, software 11344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com * License for the specific language governing permissions and limitations under 14344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com * the License. 15344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com */ 16344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com 17344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.compackage com.googlecode.eyesfree.braille.translate; 18344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com 19344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.comimport android.content.ComponentName; 20344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.comimport android.content.Context; 21344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.comimport android.content.Intent; 22344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.comimport android.content.ServiceConnection; 23344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.comimport android.os.Handler; 24344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.comimport android.os.IBinder; 25344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.comimport android.os.Message; 26344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.comimport android.os.RemoteException; 27344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.comimport android.util.Log; 28344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com 29344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com/** 30344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com * Client-side interface to the central braille translator service. 31344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com * 32344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com * This class can be used to retrieve {@link BrailleTranslator} instances for 33344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com * performing translation between text and braille cells. 34344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com * 35344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com * Typically, an instance of this class is created at application 36344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com * initialization time and destroyed using the {@link destroy()} method when 37344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com * the application is about to be destroyed. It is recommended that the 38344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com * instance is destroyed and recreated if braille translation is not going to 39344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com * be need for a long period of time. 40344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com * 41344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com * Threading:<br> 42344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com * The object must be destroyed on the same thread it was created. 43344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com * Other methods may be called from any thread. 44344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com */ 45344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.compublic class TranslatorManager { 46344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com private static final String LOG_TAG = 47344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com TranslatorManager.class.getSimpleName(); 48344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com private static final String ACTION_TRANSLATOR_SERVICE = 49344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com "com.googlecode.eyesfree.braille.service.ACTION_TRANSLATOR_SERVICE"; 50344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com private static final Intent mServiceIntent = 51344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com new Intent(ACTION_TRANSLATOR_SERVICE); 52344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com /** 53344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com * Delay before the first rebind attempt on bind error or service 54344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com * disconnect. 55344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com */ 56344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com private static final int REBIND_DELAY_MILLIS = 500; 57344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com private static final int MAX_REBIND_ATTEMPTS = 5; 58344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com public static final int ERROR = -1; 59344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com public static final int SUCCESS = 0; 60344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com 61344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com /** 62344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com * A callback interface to get notified when the translation 63344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com * manager is ready to be used, or an error occurred during 64344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com * initialization. 65344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com */ 66344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com public interface OnInitListener { 67344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com /** 68344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com * Called exactly once when it has been determined that the 69344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com * translation service is either ready to be used ({@code SUCCESS}) 70344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com * or the service is not available {@code ERROR}. 71344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com */ 72344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com public void onInit(int status); 73344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com } 74344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com 75344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com private final Context mContext; 76344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com private final TranslatorManagerHandler mHandler = 77344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com new TranslatorManagerHandler(); 78344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com private final ServiceCallback mServiceCallback = new ServiceCallback(); 79344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com 80344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com private OnInitListener mOnInitListener; 81344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com private Connection mConnection; 82344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com private int mNumFailedBinds = 0; 83344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com 84344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com /** 85344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com * Constructs an instance. {@code context} is used to bind to the 86344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com * translator service. The other methods of this class should not be 87344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com * called (they will fail) until {@code onInitListener.onInit()} 88344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com * is called. 89344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com */ 90344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com public TranslatorManager(Context context, OnInitListener onInitListener) { 91344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com mContext = context; 92344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com mOnInitListener = onInitListener; 93344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com doBindService(); 94344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com } 95344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com 96344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com /** 97344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com * Destroys this instance, deallocating any global resources it is using. 98344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com * Any {@link BrailleTranslator} objects that were created using this 99344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com * object are invalid after this call. 100344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com */ 101344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com public void destroy() { 102344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com doUnbindService(); 103344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com mHandler.destroy(); 104344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com } 105344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com 106344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com /** 107344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com * Returns a new {@link BrailleTranslator} for the translation 108344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com * table specified by {@code tableName}. 109344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com */ 110344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com // TODO: Document how to discover valid table names. 111344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com public BrailleTranslator getTranslator(String tableName) { 112344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com ITranslatorService localService = getTranslatorService(); 113344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com if (localService != null) { 114344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com try { 115344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com if (localService.checkTable(tableName)) { 116344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com return new BrailleTranslatorImpl(tableName); 117344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com } 118344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com } catch (RemoteException ex) { 119344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com Log.e(LOG_TAG, "Error in getTranslator", ex); 120344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com } 121344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com } 122344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com return null; 123344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com } 124344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com 125344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com private void doBindService() { 126344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com Connection localConnection = new Connection(); 127344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com if (!mContext.bindService(mServiceIntent, localConnection, 128344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com Context.BIND_AUTO_CREATE)) { 129344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com Log.e(LOG_TAG, "Failed to bind to service"); 130344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com mHandler.scheduleRebind(); 131344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com return; 132344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com } 133344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com mConnection = localConnection; 134344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com Log.i(LOG_TAG, "Bound to translator service"); 135344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com } 136344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com 137344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com private void doUnbindService() { 138344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com if (mConnection != null) { 139344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com mContext.unbindService(mConnection); 140344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com mConnection = null; 141344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com } 142344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com } 143344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com 144344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com private ITranslatorService getTranslatorService() { 145344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com Connection localConnection = mConnection; 146344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com if (localConnection != null) { 147344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com return localConnection.mService; 148344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com } 149344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com return null; 150344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com } 151344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com 152344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com private class Connection implements ServiceConnection { 153344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com // Read in application threads, written in main thread. 154344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com private volatile ITranslatorService mService; 155344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com 156344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com @Override 157344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com public void onServiceConnected(ComponentName className, 158344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com IBinder binder) { 159344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com Log.i(LOG_TAG, "Connected to translation service"); 160344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com ITranslatorService localService = 161344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com ITranslatorService.Stub.asInterface(binder); 162344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com try { 163344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com localService.setCallback(mServiceCallback); 164344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com mService = localService; 165344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com synchronized (mHandler) { 166344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com mNumFailedBinds = 0; 167344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com } 168344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com } catch (RemoteException ex) { 169344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com // Service went away, rely on disconnect handler to 170344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com // schedule a rebind. 171344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com Log.e(LOG_TAG, "Error when setting callback", ex); 172344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com } 173344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com } 174344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com 175344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com @Override 176344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com public void onServiceDisconnected(ComponentName className) { 177344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com Log.e(LOG_TAG, "Disconnected from translator service"); 178344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com mService = null; 179344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com // Retry by rebinding, and finally call the onInit if aplicable. 180344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com mHandler.scheduleRebind(); 181344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com } 182344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com } 183344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com 184344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com private class BrailleTranslatorImpl implements BrailleTranslator { 185344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com private final String mTable; 186344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com 187344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com public BrailleTranslatorImpl(String table) { 188344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com mTable = table; 189344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com } 190344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com 191344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com @Override 192344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com public byte[] translate(String text) { 193344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com ITranslatorService localService = getTranslatorService(); 194344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com if (localService != null) { 195344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com try { 196344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com return localService.translate(text, mTable); 197344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com } catch (RemoteException ex) { 198344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com Log.e(LOG_TAG, "Error in translate", ex); 199344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com } 200344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com } 201344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com return null; 202344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com } 203344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com 204344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com @Override 205344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com public String backTranslate(byte[] cells) { 206344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com ITranslatorService localService = getTranslatorService(); 207344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com if (localService != null) { 208344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com try { 209344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com return localService.backTranslate(cells, mTable); 210344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com } catch (RemoteException ex) { 211344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com Log.e(LOG_TAG, "Error in backTranslate", ex); 212344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com } 213344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com } 214344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com return null; 215344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com } 216344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com } 217344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com 218344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com private class ServiceCallback extends ITranslatorServiceCallback.Stub { 219344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com @Override 220344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com public void onInit(int status) { 221344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com mHandler.onInit(status); 222344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com } 223344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com } 224344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com 225344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com private class TranslatorManagerHandler extends Handler { 226344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com private static final int MSG_ON_INIT = 1; 227344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com private static final int MSG_REBIND_SERVICE = 2; 228344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com 229344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com public void onInit(int status) { 230344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com obtainMessage(MSG_ON_INIT, status, 0).sendToTarget(); 231344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com } 232344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com 233344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com public void destroy() { 234344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com mOnInitListener = null; 235344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com // Cacnel outstanding messages, most importantly 236344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com // scheduled rebinds. 237344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com removeCallbacksAndMessages(null); 238344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com } 239344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com 240344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com public void scheduleRebind() { 241344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com synchronized (this) { 242344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com if (mNumFailedBinds < MAX_REBIND_ATTEMPTS) { 243344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com int delay = REBIND_DELAY_MILLIS << mNumFailedBinds; 244344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com sendEmptyMessageDelayed(MSG_REBIND_SERVICE, delay); 245344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com ++mNumFailedBinds; 246344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com } else { 247344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com onInit(ERROR); 248344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com } 249344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com } 250344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com } 251344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com 252344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com @Override 253344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com public void handleMessage(Message msg) { 254344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com switch (msg.what) { 255344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com case MSG_ON_INIT: 256344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com handleOnInit(msg.arg1); 257344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com break; 258344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com case MSG_REBIND_SERVICE: 259344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com handleRebindService(); 260344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com break; 261344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com } 262344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com } 263344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com 264344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com private void handleOnInit(int status) { 265344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com if (mOnInitListener != null) { 266344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com mOnInitListener.onInit(status); 267344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com mOnInitListener = null; 268344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com } 269344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com } 270344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com 271344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com private void handleRebindService() { 272344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com if (mConnection != null) { 273344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com doUnbindService(); 274344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com } 275344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com doBindService(); 276344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com } 277344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com } 278344caf0bfb20161349dbf2f658a7f096a08ea76plundblad@google.com} 279