diff options
Diffstat (limited to 'apps/SdkController/src/com/android/tools/sdkcontroller/activities/BaseBindingActivity.java')
-rwxr-xr-x | apps/SdkController/src/com/android/tools/sdkcontroller/activities/BaseBindingActivity.java | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/apps/SdkController/src/com/android/tools/sdkcontroller/activities/BaseBindingActivity.java b/apps/SdkController/src/com/android/tools/sdkcontroller/activities/BaseBindingActivity.java new file mode 100755 index 000000000..ab5306ddc --- /dev/null +++ b/apps/SdkController/src/com/android/tools/sdkcontroller/activities/BaseBindingActivity.java @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.android.tools.sdkcontroller.activities; + +import android.app.Activity; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.ServiceConnection; +import android.os.IBinder; +import android.util.Log; + +import com.android.tools.sdkcontroller.service.ControllerService; +import com.android.tools.sdkcontroller.service.ControllerService.ControllerBinder; +import com.android.tools.sdkcontroller.service.ControllerService.ControllerListener; + +/** + * Base activity class that knows how to bind and unbind from the + * {@link ControllerService}. + */ +public abstract class BaseBindingActivity extends Activity { + + public static String TAG = BaseBindingActivity.class.getSimpleName(); + private static boolean DEBUG = true; + private ServiceConnection mServiceConnection; + private ControllerBinder mServiceBinder; + + /** + * Returns the binder. Activities can use that to query the controller service. + * @return An existing {@link ControllerBinder}. + * The binder is only valid between calls {@link #onServiceConnected()} and + * {@link #onServiceDisconnected()}. Returns null when not valid. + */ + public ControllerBinder getServiceBinder() { + return mServiceBinder; + } + + /** + * Called when the activity resumes. + * This automatically binds to the service, starting it as needed. + * <p/> + * Since on resume we automatically bind to the service, the {@link ServiceConnection} + * will is restored and {@link #onServiceConnected()} is called as necessary. + * Derived classes that need to initialize anything that is related to the service + * (e.g. getting their handler) should thus do so in {@link #onServiceConnected()} and + * <em>not</em> in {@link #onResume()} -- since binding to the service is asynchronous + * there is <em>no</em> guarantee that {@link #getServiceBinder()} returns non-null + * when this call finishes. + */ + @Override + protected void onResume() { + super.onResume(); + bindToService(); + } + + /** + * Called when the activity is paused. + * This automatically unbinds from the service but does not stop it. + */ + @Override + protected void onPause() { + super.onPause(); + unbindFromService(); + } + + // ---------- + + /** + * Called when binding to the service to get the activity's {@link ControllerListener}. + * @return A new non-null {@link ControllerListener}. + */ + protected abstract ControllerListener createControllerListener(); + + /** + * Called by the service once the activity is connected (bound) to it. + * <p/> + * When this is called, {@link #getServiceBinder()} returns a non-null binder that + * can be used by the activity to control the service. + */ + protected abstract void onServiceConnected(); + + /** + * Called by the service when it is forcibly disconnected OR when we know + * we're unbinding the service. + * <p/> + * When this is called, {@link #getServiceBinder()} returns a null binder and + * the activity should stop using that binder and remove any reference to it. + */ + protected abstract void onServiceDisconnected(); + + /** + * Starts the service and binds to it. + */ + protected void bindToService() { + if (mServiceConnection == null) { + final ControllerListener listener = createControllerListener(); + + mServiceConnection = new ServiceConnection() { + /** + * Called when the service is connected. + * Allows us to retrieve the binder to talk to the service. + */ + @Override + public void onServiceConnected(ComponentName name, IBinder service) { + if (DEBUG) Log.d(TAG, "Activity connected to service"); + mServiceBinder = (ControllerBinder) service; + mServiceBinder.addControllerListener(listener); + BaseBindingActivity.this.onServiceConnected(); + } + + /** + * Called when the service got disconnected, e.g. because it crashed. + * This is <em>not</em> called when we unbind from the service. + */ + @Override + public void onServiceDisconnected(ComponentName name) { + if (DEBUG) Log.d(TAG, "Activity disconnected from service"); + mServiceBinder = null; + BaseBindingActivity.this.onServiceDisconnected(); + } + }; + } + + // Start service so that it doesn't stop when we unbind + if (DEBUG) Log.d(TAG, "start requested & bind service"); + Intent service = new Intent(this, ControllerService.class); + startService(service); + bindService(service, + mServiceConnection, + Context.BIND_AUTO_CREATE); + } + + /** + * Unbinds from the service but does not actually stop the service. + * This lets us have it run in the background even if this isn't the active activity. + */ + protected void unbindFromService() { + if (mServiceConnection != null) { + if (DEBUG) Log.d(TAG, "unbind service"); + mServiceConnection.onServiceDisconnected(null /*name*/); + unbindService(mServiceConnection); + mServiceConnection = null; + } + } +}
\ No newline at end of file |