ConnectionManager.java
Go to the documentation of this file.
00001 
00002 // *      Copyright (C) 2005-2015 Team XBMC
00003 // *      http://xbmc.org
00004 // *
00005 // *  This Program is free software; you can redistribute it and/or modify
00006 // *  it under the terms of the GNU General Public License as published by
00007 // *  the Free Software Foundation; either version 2, or (at your option)
00008 // *  any later version.
00009 // *
00010 // *  This Program is distributed in the hope that it will be useful,
00011 // *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00013 // *  GNU General Public License for more details.
00014 // *
00015 // *  You should have received a copy of the GNU General Public License
00016 // *  along with XBMC Remote; see the file license.  If not, write to
00017 // *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
00018 // *  http://www.gnu.org/copyleft/gpl.html
00019 // *
00020 // */
00021 //
00022 //package org.xbmc.android.jsonrpc.io;
00023 //
00024 //import java.util.ArrayList;
00025 //import java.util.HashMap;
00026 //import java.util.LinkedList;
00027 //
00028 //import org.codehaus.jackson.JsonNode;
00029 //import org.xbmc.android.jsonrpc.api.AbstractCall;
00030 //import org.xbmc.android.jsonrpc.api.AbstractModel;
00031 //import org.xbmc.android.jsonrpc.config.HostConfig;
00032 //import org.xbmc.android.jsonrpc.notification.AbstractEvent;
00033 //import org.xbmc.android.jsonrpc.notification.PlayerEvent;
00034 //import org.xbmc.android.jsonrpc.notification.PlayerObserver;
00035 //import org.xbmc.android.jsonrpc.notification.SystemEvent;
00036 //import org.xbmc.android.jsonrpc.service.ConnectionService;
00037 //
00039 // * Provides simple access to XBMC's JSON-RPC API.
00040 // * <p/>
00041 // * It is used for two things:
00042 // * <ol><li>Query JSON-API via persistent TCP socket or HTTP.</li>
00043 // *     <li>Subscribe to notification events from XBMC.</li></ol>
00044 // *
00045 // * TCP socket is used by default. If you want to force HTTP request, use
00046 // * {@link #setPreferHTTP()}, which will use HTTP as transport layer and
00047 // * not use the connection service but {@link JsonApiRequest}.
00048 // * <p/>
00049 // * 
00050 // * The TCP connection is managed by {@link ConnectionService}. The manager uses
00051 // * a {@link Messenger} to communicate with the service using a {@link Handler}
00052 // * on both sides (see {@link IncomingHandler}).
00053 // * <p/>
00054 // *
00055 // * <h3>Serialization</h3>
00056 // * Since we're dealing with a service, objects sent to and received by the
00057 // * service must be either native types or {@link Parcelable}. For this reason,
00058 // * our entire JSON-RPC library implements {@link Parcelable}. That includes
00059 // * all classes extending {@link AbstractCall} as well as {@link AbstractModel}.
00060 // * <p/>
00061 // * Once the service receives the API call object, it queries XBMC with the
00062 // * given JSON data and uses the Jackson parser to serialize the response
00063 // * directly into a {@link JsonNode}. Since <tt>JsonNode</tt> is not parcelable,
00064 // * the service directly converts it into our object model using the API call
00065 // * object. The updated API call object is then sent back to
00066 // * <tt>ConnectionManager</tt>.
00067 // *
00068 // * <h3>Synchronization</h3>
00069 // * When syncing the local database we want to avoid the parcelization happening
00070 // * when sending the response back from <tt>ConnectionService</tt> to
00071 // * <tt>ConnectionManager</tt>. Therefore, <tt>call()</tt> can additionally
00072 // * provide a {@link JsonHandler}, which will synchronize the local DB and only
00073 // * respond with a status code instead of the whole response.
00074 // *
00075 // * <h3>Notifications</h3>
00076 // * Every instance of {@link ConnectionManager} appears as a client on the
00077 // * service's side. Upon reception of a notification, the service announces all
00078 // * connected clients. If {@link ConnectionManager} has any registered
00079 // * observers, they will be notified, otherwise the notification is dropped.
00080 // *
00081 // * <h3>Destruction</h3>
00082 // * When an instance of ConnectionManager is not needed anymore, be sure to run
00083 // * {@link #disconnect()} in order to un-bind the service and shut down the TCP
00084 // * connection when it's not needed anymore. Re-using a disconnected instance
00085 // * will re-bind automatically. Note that on error, the service is always
00086 // * disconnected automatically.
00087 // *
00088 // * @author freezy <freezy@xbmc.org>
00089 // */
00090 //public class ConnectionManager {
00091 //
00092 //      private static final String TAG = ConnectionManager.class.getSimpleName();
00093 //
00094 //      private final static String HTTP_PATH = "/jsonrpc";
00095 //
00096 //      /**
00097 //       * Reference to context
00098 //       */
00100 //      /**
00101 //       * True if bound to service, false otherwise.
00102 //       */
00103 //      boolean mIsBound;
00104 //      /**
00105 //       * The reference through which we receive messages from the service
00106 //       */
00108 //      /**
00109 //       * The reference through which we send messages to the service
00110 //       */
00112 //      /**
00113 //       * List of observers listening to notifications.
00114 //       */
00115 //      private final ArrayList<NotificationObserver> mObservers = new ArrayList<NotificationObserver>();
00116 //      /**
00117 //       * List of currently processing API calls with handler. Key is the ID of the API call.
00118 //       */
00119 //      private final HashMap<String, HandlerCallback> mHandlerCallbacks = new HashMap<String, HandlerCallback>();
00120 //      /**
00121 //       * Since we can't return the de-serialized object from the service, put the
00122 //       * response back into the received one and return the received one.
00123 //       */
00124 //      private final HashMap<String, CallRequest<?>> mCallRequests = new HashMap<String, CallRequest<?>>();
00125 //      /**
00126 //       * When posting request data and the service isn't started yet, we need to
00127 //       * reschedule the post until the service is available. This list contains
00128 //       * the requests that are to sent upon service startup.
00129 //       */
00130 //      private final LinkedList<AbstractCall<?>> mPendingCalls = new LinkedList<AbstractCall<?>>();
00131 //      private final HashMap<String, JsonHandler> mPendingHandlers = new HashMap<String, JsonHandler>();
00132 //
00133 //      /**
00134 //       * XBMC host configuration
00135 //       */
00136 //      private final HostConfig mHost;
00137 //      
00138 //      /**
00139 //       * Path where data gets posted.
00140 //       */
00141 //      private String mHttpPath = HTTP_PATH;
00142 //
00143 //      /**
00144 //       * If true and HTTP port is set, use HTTP requests instead of the TCP service.
00145 //       */
00146 //      private boolean mPreferHTTP = false;
00147 //
00148 //      /**
00149 //       * Class constructor.
00150 //       * @param c Needed if the service needs to be started
00151 //       */
00152 //      public ConnectionManager(HostConfig host) {
00154 //              mHost = host;
00155 //      }
00156 //
00157 //      /**
00158 //       * Executes a JSON-RPC request with the full result in the callback.
00159 //       * @param call Call to execute
00160 //       * @param callback
00161 //       * @return
00162 //       */
00163 //      public <T> ConnectionManager call(final AbstractCall<T> call, final ApiCallback<T> callback) {
00164 //
00165 //              if (mPreferHTTP) {
00166 //
00167 //                      // spawn another thread for this
00168 //                      new Thread(new Runnable() {
00169 //                              @Override
00170 //                              public void run() {
00171 //                                      try {
00172 //                                              // synchronously post, retrieve and parse response.
00173 //                                              call.setResponse(JsonApiRequest.execute(getUrl(), mHost.getUsername(), mHost.getPassword(), call.getRequest()));
00174 //                                              callback.onResponse(call);
00175 //                                      } catch (ApiException e) {
00177 //                                      }
00178 //                              }
00179 //                      }).start();
00180 //
00181 //              } else {
00182 //
00183 //                      // start service if not yet started
00184 //                      bindService();
00185 //                      mCallRequests.put(call.getId(), new CallRequest<T>(call, callback));
00186 //                      sendCall(call);
00187 //              }
00188 //              return this;
00189 //      }
00190 //
00191 //      /**
00192 //       * Executes a JSON-RPC request where the handler is executed at the service
00193 //       * and the callback gets a status code only.
00194 //       *
00195 //       * @param call Call to execute
00196 //       * @param handler Handler to treat result
00197 //       * @param callback Callback to handle result, can be null.
00198 //       * @return
00199 //       */
00200 //      public ConnectionManager call(AbstractCall<?> call, JsonHandler handler, HandlerCallback callback) {
00201 //
00202 //              // start service if not yet started
00203 //              bindService();
00204 //              mHandlerCallbacks.put(call.getId(), callback);
00205 //              sendCall(call, handler);
00206 //              return this;
00207 //      }
00208 //
00209 //      /**
00210 //       * Adds a new notification observer.
00211 //       * @param observer New observer
00212 //       * @return Class instance
00213 //       */
00214 //      public ConnectionManager registerObserver(NotificationObserver observer) {
00215 //              // start service if not yet started
00216 //              bindService();
00217 //              mObservers.add(observer);
00218 //              return this;
00219 //      }
00220 //
00221 //      /**
00222 //       * Removes a previously added observer.
00223 //       * @param observer Observer to remove
00224 //       * @return Class instance
00225 //       */
00226 //      public ConnectionManager unregisterObserver(NotificationObserver observer) {
00227 //              final ArrayList<NotificationObserver> observers = mObservers;
00228 //              observers.remove(observer);
00229 //              // stop service if no more observers.
00230 //              if (observers.isEmpty() && mCallRequests.isEmpty() && mHandlerCallbacks.isEmpty()) {
00231 //                      unbindService();
00233 //              } else {
00235 //              }
00236 //              return this;
00237 //      }
00238 //
00239 //      /**
00240 //       * Returns true if HTTP is used instead of a permanent TCP socket.
00241 //       * @return True if HTTP is used, false otherwise.
00242 //       */
00243 //      public boolean prefersHTTP() {
00244 //              return mPreferHTTP;
00245 //      }
00246 //
00247 //      /**
00248 //       * Makes the connection manager use HTTP requests instead of the connection
00249 //       * service, which uses a permanent TCP socket.
00250 //       */
00251 //      public void setPreferHTTP() {
00252 //              mPreferHTTP = true;
00253 //      }
00254 //
00255 //      /**
00256 //       * Binds the connection to the notification service if not yet bound.
00257 //       */
00258 //      private void bindService() {
00259 //              // start service if no observer and no api calls.
00260 //              if (!mIsBound) {
00270 //              }
00271 //      }
00272 //
00273 //      /**
00274 //       * Unbinds the connection from the notification service. This is done by
00275 //       * notifying the service first and then terminating the connection.
00276 //       */
00277 //      private void unbindService() {
00278 //              if (mIsBound) {
00296 //              } else {
00298 //              }
00299 //      }
00300 //
00301 //      /**
00302 //       * Posts a API call to the service.
00303 //       * @param apiCall API call
00304 //       */
00305 //      private void sendCall(AbstractCall<?> apiCall) {
00306 //              if (mService != null) {
00307 //                      try {
00308 //                              final Message msg = Message.obtain(null, ConnectionService.MSG_SEND_APICALL);
00309 //                              final Bundle data = new Bundle();
00310 //                              data.putParcelable(ConnectionService.EXTRA_APICALL, apiCall);
00311 //                              msg.setData(data);
00312 //                              msg.replyTo = mMessenger;
00313 //                              mService.send(msg);
00314 //                              Log.i(TAG, "Posted API call service (with callback).");
00315 //                      } catch (RemoteException e) {
00316 //                              Log.e(TAG, "Error posting message to service: " + e.getMessage(), e);
00317 //                      }
00318 //              } else {
00319 //                      // service not yet started, saving data:
00320 //                      Log.i(TAG, "Saving post data for later.");
00321 //                      mPendingCalls.add(apiCall);
00322 //              }
00323 //      }
00324 //
00325 //      /**
00326 //       * Posts a new handled API call to the service.
00327 //       * @param apiCall API call
00328 //       * @param handler Handler to execute in the service
00329 //       */
00330 //      private void sendCall(AbstractCall<?> apiCall, JsonHandler handler) {
00331 //              if (mService != null) {
00332 //                      try {
00333 //                              final Message msg = Message. obtain(null, ConnectionService.MSG_SEND_HANDLED_APICALL);
00334 //                              final Bundle data = new Bundle();
00335 //                              data.putParcelable(ConnectionService.EXTRA_APICALL, apiCall);
00336 //                              data.putParcelable(ConnectionService.EXTRA_HANDLER, handler);
00337 //                              msg.setData(data);
00338 //                              msg.replyTo = mMessenger;
00339 //                              mService.send(msg);
00340 //                              Log.i(TAG, "Posted handled API call service.");
00341 //                      } catch (RemoteException e) {
00342 //                              Log.e(TAG, "Error posting message to service: " + e.getMessage(), e);
00343 //                      }
00344 //              } else {
00345 //                      // service not yet started, saving data:
00346 //                      Log.i(TAG, "Saving post data for later.");
00347 //                      mPendingCalls.add(apiCall);
00348 //                      mPendingHandlers.put(apiCall.getId(), handler);
00349 //              }
00350 //      }
00351 //
00352 //      /**
00353 //       * Disconnects from the service.
00354 //       *
00355 //       * Run this as soon as there are no immediate calls to the API. Running it
00356 //       * when there are still requests in progress will cut off the callback (so
00357 //       * don't do that). However, notification listener will not be affected. Once
00358 //       * you run {@link #disconnect()}, you still can re-use the same object
00359 //       * later, since it will be reconnect to the service as soon as it's used.
00360 //       */
00361 //      public void disconnect() {
00362 //              if (mObservers.isEmpty()) {
00363 //                      unbindService();
00364 //              }
00365 //      }
00366 //
00367 //      /**
00368 //       * Connection used to communicate with the service.
00369 //       */
00370 //      private final ServiceConnection mConnection = new ServiceConnection() {
00371 //              public void onServiceConnected(ComponentName className, IBinder service) {
00372 //                      mService = new Messenger(service);
00373 //                      Log.i(TAG, "Connected to service.");
00374 //                      try {
00375 //                              final Message msg = Message.obtain(null, ConnectionService.MSG_REGISTER_CLIENT);
00376 //                              msg.replyTo = mMessenger;
00377 //                              mService.send(msg);
00378 //
00379 //                      } catch (RemoteException e) {
00380 //                              Log.e(TAG, "Error registering client: " + e.getMessage(), e);
00381 //                              // In this case the service has crashed before we could even do
00382 //                              // anything with it
00383 //                      }
00384 //                      // now check if there are lost requests:
00385 //                      final LinkedList<AbstractCall<?>> calls = mPendingCalls;
00386 //                      while (!calls.isEmpty()) {
00387 //                              AbstractCall<?> call = calls.poll();
00388 //                              if (mPendingHandlers.containsKey(call.getId())) {
00389 //                                      Log.d(TAG, "Posting pending handled call " + call.getName() + "...");
00390 //                                      final JsonHandler handler = mPendingHandlers.get(call.getId());
00391 //                                      sendCall(call, handler);
00392 //                                      mPendingHandlers.remove(call.getId());
00393 //                              } else {
00394 //                                      Log.d(TAG, "Posting pending call " + call.getName() + " with callback...");
00395 //                                      sendCall(call);
00396 //                              }
00397 //                      }
00398 //              }
00399 //
00400 //              public void onServiceDisconnected(ComponentName className) {
00401 //                      // This is called when the connection with the service has been
00402 //                      // unexpectedly disconnected - process crashed.
00403 //                      mService = null;
00404 //                      Log.i(TAG, "Service disconnected.");
00405 //              }
00406 //      };
00407 //      
00408 //      /**
00409 //       * Returns the path of the HTTP request. Default is {@link ConnectionManager#HTTP_PATH}.
00410 //       * @return HTTP path
00411 //       */
00412 //      public String getHttpPath() {
00413 //              return mHttpPath;
00414 //      }
00415 //
00416 //      /**
00417 //       * Sets the path of the HTTP request. Should start with slash and end without.
00418 //       * @param httpPath
00419 //       */
00420 //      public void setHttpPath(String httpPath) {
00421 //              mHttpPath = httpPath;
00422 //      }
00423 //
00424 //      /**
00425 //       * The handler from the receiving service.
00426 //       * <p>
00427 //       * In here we add the logic of what happens when we get messages from the
00428 //       * notification service.
00429 //       *
00430 //       * @author freezy <freezy@xbmc.org>
00431 //       */
00432 //      private class IncomingHandler extends Handler {
00433 //              @Override
00434 //              public void handleMessage(Message msg) {
00435 //                      Log.i(TAG, "Got message: " + msg.what);
00436 //                      final HashMap<String, CallRequest<?>> callrequests = mCallRequests;
00437 //                      final HashMap<String, HandlerCallback> handlercallbacks = mHandlerCallbacks;
00438 //                      switch (msg.what) {
00439 //
00440 //                              // fully updated API call object
00441 //                              case ConnectionService.MSG_RECEIVE_APICALL: {
00442 //                                      final AbstractCall<?> returnedApiCall = msg.getData().getParcelable(ConnectionService.EXTRA_APICALL);
00443 //                                      if (returnedApiCall != null) {
00444 //                                              if (callrequests.containsKey(returnedApiCall.getId())) {
00445 //                                                      final CallRequest<?> callrequest = callrequests.get(returnedApiCall.getId());
00446 //                                                      callrequest.update(returnedApiCall);
00447 //                                                      callrequest.respond();
00448 //                                                      callrequests.remove(returnedApiCall.getId());
00449 //                                                      Log.d(TAG, "Callback for " + returnedApiCall.getName() + " sent back to caller.");
00450 //                                              } else {
00451 //                                                      Log.w(TAG, "Unknown ID " + returnedApiCall.getId() + " for " + returnedApiCall.getName() + ", dropping.");
00452 //                                              }
00453 //                                      } else {
00454 //                                              Log.e(TAG, "Error retrieving API call object from bundle.");
00455 //                                      }
00456 //                                      break;
00457 //                              }
00458 //
00459 //                              // status code after handled api call
00460 //                              case ConnectionService.MSG_RECEIVE_HANDLED_APICALL: {
00461 //                                      final Bundle b = msg.getData();
00462 //                                      final String id = b.getString(ConnectionService.EXTRA_CALLID);
00463 //                                      if (handlercallbacks.containsKey(id)) {
00464 //                                              if (handlercallbacks.get(id) != null) {
00465 //                                                      handlercallbacks.get(id).onFinish();
00466 //                                                      handlercallbacks.remove(id);
00467 //                                              }
00468 //                                      } else {
00469 //                                              Log.w(TAG, "Unknown ID " + id + " for handled callback, not notifying caller.");
00470 //                                      }
00471 //                                      break;
00472 //                              }
00473 //
00474 //                              // notification
00475 //                              case ConnectionService.MSG_RECEIVE_NOTIFICATION: {
00476 //                                      final Bundle b = msg.getData();
00477 //                                      final AbstractEvent notification = b.getParcelable(ConnectionService.EXTRA_NOTIFICATION);
00478 //                                      final ArrayList<NotificationObserver> observers = mObservers;
00479 //                                      for (NotificationObserver observer : observers) {
00480 //                                              switch (notification.getId()) {
00481 //                                                      case PlayerEvent.Play.ID:
00482 //                                                              observer.getPlayerObserver().onPlay((PlayerEvent.Play)notification);
00483 //                                                              break;
00484 //                                                      case PlayerEvent.Pause.ID:
00485 //                                                              observer.getPlayerObserver().onPause((PlayerEvent.Pause)notification);
00486 //                                                              break;
00487 //                                                      case PlayerEvent.Stop.ID:
00488 //                                                              observer.getPlayerObserver().onStop((PlayerEvent.Stop)notification);
00489 //                                                              break;
00490 //                                                      case PlayerEvent.SpeedChanged.ID:
00491 //                                                              observer.getPlayerObserver().onSpeedChanged((PlayerEvent.SpeedChanged)notification);
00492 //                                                              break;
00493 //                                                      case PlayerEvent.Seek.ID:
00494 //                                                              observer.getPlayerObserver().onSeek((PlayerEvent.Seek)notification);
00495 //                                                              break;
00496 //                                                      case SystemEvent.Quit.ID:
00497 //                                                      case SystemEvent.Restart.ID:
00498 //                                                      case SystemEvent.Wake.ID:
00499 //                                                      case SystemEvent.LowBattery.ID:
00500 //                                                      default:
00501 //                                                              break;
00502 //                                              }
00503 //                                      }
00504 //                                      break;
00505 //                              }
00506 //
00507 //                              // service started connecting to socket
00508 //                              case ConnectionService.MSG_CONNECTING: {
00509 //                                      // we don't care for this right now
00510 //                                      break;
00511 //                              }
00512 //
00513 //                              // service is connected to socket
00514 //                              case ConnectionService.MSG_CONNECTED: {
00515 //                                      final ArrayList<NotificationObserver> observers = mObservers;
00516 //                                      for (NotificationObserver observer : observers) {
00517 //                                              observer.onConnected();
00518 //                                      }
00519 //                                      break;
00520 //                              }
00521 //
00522 //                              // shit happened
00523 //                              case ConnectionService.MSG_ERROR: {
00524 //                                      final Bundle b = msg.getData();
00525 //                                      final int code = b.getInt(ApiException.EXTRA_ERROR_CODE);
00526 //                                      final String message = b.getString(ApiException.EXTRA_ERROR_MESSAGE);
00527 //                                      final String hint = b.getString(ApiException.EXTRA_ERROR_HINT);
00528 //                                      final String id = b.getString(ConnectionService.EXTRA_CALLID);
00529 //
00530 //                                      final HashMap<String, HandlerCallback> handleCallbacks = mHandlerCallbacks;
00531 //                                      final HashMap<String, CallRequest<?>> callRequests = mCallRequests;
00532 //
00533 //                                      if (id != null && handleCallbacks.containsKey(id)) {
00534 //                                              // if ID given and handler call back, announce to handler callback.
00535 //                                              Log.e(TAG, "Error, notifying one handler callback.");
00536 //                                              if (handleCallbacks.get(id) != null) {
00537 //                                                      handleCallbacks.get(id).onError(message, hint);
00538 //                                              }
00539 //                                      } else if (id != null && callRequests.containsKey(id)) {
00540 //                                              // if ID given and api call back, announce error.
00541 //                                              Log.e(TAG, "Error, notifying one API callback.");
00542 //                                              callRequests.get(id).error(code, message, hint);
00543 //                                      } else {
00544 //                                              // otherwise, announce to all clients (callbacks, api callbacks and observers).
00545 //                                              Log.e(TAG, "Error, notifying everybody.");
00546 //                                              for (HandlerCallback handlerCallback : handleCallbacks.values()) {
00547 //                                                      if (handlerCallback != null) {
00548 //                                                              handlerCallback.onError(message, hint);
00549 //                                                      }
00550 //                                              }
00551 //                                              handleCallbacks.clear();
00552 //
00553 //                                              for (CallRequest<?> callreq : callRequests.values()) {
00554 //                                                      callreq.error(code, message, hint);
00555 //                                              }
00556 //                                              callRequests.clear();
00557 //
00558 //                                              final ArrayList<NotificationObserver> observers = mObservers;
00559 //                                              for (NotificationObserver observer : observers) {
00560 //                                                      observer.onError(code, message, hint);
00561 //                                              }
00562 //                                              observers.clear();
00563 //                                              unbindService();
00564 //                                      }
00565 //                                      break;
00566 //                              }
00567 //                              default:
00568 //                                      super.handleMessage(msg);
00569 //                      }
00570 //              }
00571 //      }
00572 //
00573 //
00574 //      /**
00575 //       * Returns the URL of XBMC to connect to.
00576 //       *
00577 //       * The URL already contains the JSON-RPC prefix, e.g.:
00578 //       *              <code>http://192.168.0.100:8080/jsonrpc</code>
00579 //       * @return URL of JSON-RPC via HTTP
00580 //       */
00581 //      private String getUrl() {
00582 //              return "http://" + mHost.getAddress() + ":" + mHost.getHttpPort()+ mHttpPath;
00583 //      }
00584 //
00585 //      /**
00586 //       * A call request bundles an API call and its callback of the same type.
00587 //       *
00588 //       * @author freezy <freezy@xbmc.org>
00589 //       */
00590 //      private static class CallRequest<T> {
00591 //              private final AbstractCall<T> mCall;
00592 //              private final ApiCallback<T> mCallback;
00593 //              public CallRequest(AbstractCall<T> call, ApiCallback<T> callback) {
00594 //                      this.mCall = call;
00595 //                      this.mCallback = callback;
00596 //              }
00597 //              public void update(AbstractCall<?> call) {
00598 //                      mCall.copyResponse(call);
00599 //              }
00600 //              public void respond() {
00601 //                      mCallback.onResponse(mCall);
00602 //              }
00603 //              public void error(int code, String message, String hint) {
00604 //                      mCallback.onError(code, message, hint);
00605 //              }
00606 //      }
00607 //
00608 //      /**
00609 //       * Observer interface that handles arriving notifications.
00610 //       * @author freezy <freezy@xbmc.org>
00611 //       */
00612 //      public static interface NotificationObserver {
00613 //              /**
00614 //               * Handle an arriving notification in here.
00615 //               */
00616 //              public PlayerObserver getPlayerObserver();
00617 //
00618 //              /**
00619 //               * The service is connected to JSON-RPC's TCP socket.
00620 //               * <p/>
00621 //               * If the service was already connected, this will be sent immediately
00622 //               * after registering the client.
00623 //               */
00624 //              public void onConnected();
00625 //
00626 //              /**
00627 //               * An error has occurred which resulted in the termination of the
00628 //               * connection.
00629 //               * @param code Error code, see constants at {@link ApiException}.
00630 //               * @param message Translated error message
00631 //               * @param hint Translated hint what the problem could be
00632 //               */
00633 //              public void onError(int code, String message, String hint);
00634 //      }
00635 //
00636 //      /**
00637 //       * When providing a {@link JsonHandler} to an API call, this interface
00638 //       * will inform the caller when processing has finished.
00639 //       *
00640 //       * @author freezy <freezy@xbmc.org>
00641 //       */
00642 //      public static interface HandlerCallback {
00643 //              /**
00644 //               * Processing has successfully finished.
00645 //               * <p>
00646 //               * Don't forget to run {@link ConnectionManager#disconnect()} in here
00647 //               * if you don't immediately need to run another call.
00648 //               */
00649 //              public void onFinish();
00650 //              /**
00651 //               * Processing has failed.
00652 //               * <p>
00653 //               * Note that the service has been automatically disconnected.
00654 //               * @param message Translated error message
00655 //               * @param hint Translated hint
00656 //               */
00657 //              public void onError(String message, String hint);
00658 //      }
00659 //
00660 //}


smarthome_media_kodi_driver
Author(s): Mickael Gaillard , Erwan Le Huitouze
autogenerated on Thu Jun 6 2019 21:03:49