OLD | NEW |
(Empty) | |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 package org.chromium.chromoting; |
| 6 |
| 7 import android.app.Activity; |
| 8 import android.text.TextUtils; |
| 9 import android.util.Log; |
| 10 |
| 11 import java.util.ArrayList; |
| 12 import java.util.Arrays; |
| 13 import java.util.List; |
| 14 |
| 15 /** |
| 16 * A manager for the capabilities of the Android client, in charge of creating a
ny required |
| 17 * extension handlers based on capability negotiation. |
| 18 * TODO(aiguha): CapabilityManager currently mimicks the webapp in terms of how
it handles |
| 19 * extension messages. By this, I mean that it itself routes messages to differe
nt handlers based |
| 20 * on the message's type. This is in contrast to the Chromoting host, which, for
each incoming |
| 21 * extension message, runs through a list of HostExtensionSession objects, givin
g each one a chance |
| 22 * to handle the message. |
| 23 */ |
| 24 public class CapabilityManager { |
| 25 |
| 26 /** Singleton object that can be used from different Activities within the a
pplication. */ |
| 27 private static CapabilityManager sInstance; |
| 28 |
| 29 /** The list of all capabilities that are supported by the app. */ |
| 30 private List<String> mLocalCapabilities; |
| 31 |
| 32 /** The list of negotiated capabilities received from the host. */ |
| 33 private List<String> mNegotiatedCapabilities; |
| 34 |
| 35 /** List of extensions to the client based on capabilities negotiated with t
he host. */ |
| 36 private List<ClientExtension> mClientExtensions; |
| 37 |
| 38 private CapabilityManager() { |
| 39 mLocalCapabilities = new ArrayList<String>(); |
| 40 mClientExtensions = new ArrayList<ClientExtension>(); |
| 41 |
| 42 mLocalCapabilities.add(Capabilities.CAST_CAPABILITY); |
| 43 } |
| 44 |
| 45 public static CapabilityManager getInstance() { |
| 46 synchronized (CapabilityManager.class) { |
| 47 if (sInstance == null) { |
| 48 sInstance = new CapabilityManager(); |
| 49 } |
| 50 return sInstance; |
| 51 } |
| 52 } |
| 53 |
| 54 /** Returns a space separated list of the capabilities supported using mLoca
lCapabilities.*/ |
| 55 public String getLocalCapabilities() { |
| 56 return TextUtils.join(" ", mLocalCapabilities); |
| 57 } |
| 58 |
| 59 /** |
| 60 * Returns the ActivityLifecycleListener associated with the specified capab
ility, if capability |
| 61 * is enabled and such a listener exists. Activities that call this method a
gree to support this |
| 62 * capability by appropriately notifying the listener of lifecycle events. T
his allows |
| 63 * extensions like the CastExtensionHandler to hook into an existing activit
y's lifecycle. |
| 64 */ |
| 65 public ActivityLifecycleListener onActivityAcceptingListener( |
| 66 Activity activity, String capability) { |
| 67 |
| 68 ActivityLifecycleListener listener = new DummyActivityLifecycleListener(
); |
| 69 |
| 70 if (isCapabilityEnabled(capability)) { |
| 71 for (ClientExtension ext : mClientExtensions) { |
| 72 if (ext.getCapability().equals(capability)) { |
| 73 listener = ext.onActivityAcceptingListener(activity); |
| 74 if (listener != null) |
| 75 return listener; |
| 76 } |
| 77 } |
| 78 } |
| 79 return listener; |
| 80 } |
| 81 |
| 82 /** |
| 83 * Receives the capabilities negotiated between client and host and creates
the appropriate |
| 84 * extension handlers. |
| 85 */ |
| 86 public void setNegotiatedCapabilities(String capabilities) { |
| 87 mNegotiatedCapabilities = Arrays.asList(capabilities.split(" ")); |
| 88 |
| 89 if (isCapabilityEnabled(Capabilities.CAST_CAPABILITY)) { |
| 90 mClientExtensions.add(tryConstructingCastExtensionHandler()); |
| 91 } |
| 92 } |
| 93 |
| 94 /** |
| 95 * Passes the deconstructed extension message to each ClientExtension in tur
n until the message |
| 96 * is handled or none remain. Returns true if the message was handled. |
| 97 */ |
| 98 public boolean onExtensionMessage(String type, String data) { |
| 99 if (type == null || type.isEmpty()) { |
| 100 return false; |
| 101 } |
| 102 |
| 103 for (ClientExtension ext : mClientExtensions) { |
| 104 if (ext.onExtensionMessage(type, data)) { |
| 105 return true; |
| 106 } |
| 107 } |
| 108 |
| 109 Log.i("CapabilityManager", String.format("Unexpected Message: (%s, %s)",
type, data)); |
| 110 return false; |
| 111 } |
| 112 |
| 113 /** Return true if the capability is enabled for this connection with the ho
st. */ |
| 114 private boolean isCapabilityEnabled(String capability) { |
| 115 return (mNegotiatedCapabilities != null && mNegotiatedCapabilities.conta
ins(capability)); |
| 116 } |
| 117 |
| 118 /** Tries to reflectively instantiate a CastExtensionHandler object. */ |
| 119 private ClientExtension tryConstructingCastExtensionHandler() { |
| 120 try { |
| 121 Class<?> cls = Class.forName("org.chromium.chromoting.CastExtensionH
andler"); |
| 122 return (ClientExtension) cls.newInstance(); |
| 123 } catch (ClassNotFoundException e) { |
| 124 Log.w("CapabilityManager", "Failed to create CastExtensionHandler.")
; |
| 125 return new DummyClientExtension(); |
| 126 } catch (InstantiationException e) { |
| 127 Log.w("CapabilityManager", "Failed to create CastExtensionHandler.")
; |
| 128 return new DummyClientExtension(); |
| 129 } catch (IllegalAccessException e) { |
| 130 Log.w("CapabilityManager", "Failed to create CastExtensionHandler.")
; |
| 131 return new DummyClientExtension(); |
| 132 } |
| 133 } |
| 134 } |
OLD | NEW |