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. Based on the negotiated
set of |
| 17 * capabilities, it creates the associated ClientExtensions, and enables their c
ommunication with |
| 18 * the Chromoting host by dispatching extension messages appropriately. |
| 19 * |
| 20 * The CapabilityManager mirrors how the Chromoting host handles extension messa
ges. For each |
| 21 * incoming extension message, runs through a list of HostExtensionSession objec
ts, giving each one |
| 22 * a chance to handle the message. |
| 23 * |
| 24 * The CapabilityManager is a singleton class so we can manage client extensions
on an application |
| 25 * level. The singleton object may be used from multiple Activities, thus allowi
ng it to support |
| 26 * different capabilities at different stages of the application. |
| 27 */ |
| 28 public class CapabilityManager { |
| 29 |
| 30 /** Lazily-initialized singleton object that can be used from different Acti
vities. */ |
| 31 private static CapabilityManager sInstance; |
| 32 |
| 33 /** Protects access to |sInstance|. */ |
| 34 private static final Object sInstanceLock = new Object(); |
| 35 |
| 36 /** List of all capabilities that are supported by the application. */ |
| 37 private List<String> mLocalCapabilities; |
| 38 |
| 39 /** List of negotiated capabilities received from the host. */ |
| 40 private List<String> mNegotiatedCapabilities; |
| 41 |
| 42 /** List of extensions to the client based on capabilities negotiated with t
he host. */ |
| 43 private List<ClientExtension> mClientExtensions; |
| 44 |
| 45 private CapabilityManager() { |
| 46 mLocalCapabilities = new ArrayList<String>(); |
| 47 mClientExtensions = new ArrayList<ClientExtension>(); |
| 48 |
| 49 mLocalCapabilities.add(Capabilities.CAST_CAPABILITY); |
| 50 } |
| 51 |
| 52 /** |
| 53 * Returns the singleton object. Thread-safe. |
| 54 */ |
| 55 public static CapabilityManager getInstance() { |
| 56 synchronized (sInstanceLock) { |
| 57 if (sInstance == null) { |
| 58 sInstance = new CapabilityManager(); |
| 59 } |
| 60 return sInstance; |
| 61 } |
| 62 } |
| 63 |
| 64 /** |
| 65 * Returns a space-separated list (required by host) of the capabilities sup
ported by |
| 66 * this client. |
| 67 */ |
| 68 public String getLocalCapabilities() { |
| 69 return TextUtils.join(" ", mLocalCapabilities); |
| 70 } |
| 71 |
| 72 /** |
| 73 * Returns the ActivityLifecycleListener associated with the specified capab
ility, if |
| 74 * |capability| is enabled and such a listener exists. |
| 75 * |
| 76 * Activities that call this method agree to appropriately notify the listen
er of lifecycle |
| 77 * events., thus supporting |capability|. This allows extensions like the Ca
stExtensionHandler |
| 78 * to hook into an existing activity's lifecycle. |
| 79 */ |
| 80 public ActivityLifecycleListener onActivityAcceptingListener( |
| 81 Activity activity, String capability) { |
| 82 |
| 83 ActivityLifecycleListener listener; |
| 84 |
| 85 if (isCapabilityEnabled(capability)) { |
| 86 for (ClientExtension ext : mClientExtensions) { |
| 87 if (ext.getCapability().equals(capability)) { |
| 88 listener = ext.onActivityAcceptingListener(activity); |
| 89 if (listener != null) |
| 90 return listener; |
| 91 } |
| 92 } |
| 93 } |
| 94 |
| 95 return new DummyActivityLifecycleListener(); |
| 96 } |
| 97 |
| 98 /** |
| 99 * Receives the capabilities negotiated between client and host and creates
the appropriate |
| 100 * extension handlers. |
| 101 * |
| 102 * Currently only the CAST_CAPABILITY exists, so that is the only extension
constructed. |
| 103 */ |
| 104 public void setNegotiatedCapabilities(String capabilities) { |
| 105 mNegotiatedCapabilities = Arrays.asList(capabilities.split(" ")); |
| 106 mClientExtensions.clear(); |
| 107 if (isCapabilityEnabled(Capabilities.CAST_CAPABILITY)) { |
| 108 mClientExtensions.add(maybeCreateCastExtensionHandler()); |
| 109 } |
| 110 } |
| 111 |
| 112 /** |
| 113 * Passes the deconstructed extension message to each ClientExtension in tur
n until the message |
| 114 * is handled or none remain. Returns true if the message was handled. |
| 115 */ |
| 116 public boolean onExtensionMessage(String type, String data) { |
| 117 if (type == null || type.isEmpty()) { |
| 118 return false; |
| 119 } |
| 120 |
| 121 for (ClientExtension ext : mClientExtensions) { |
| 122 if (ext.onExtensionMessage(type, data)) { |
| 123 return true; |
| 124 } |
| 125 } |
| 126 return false; |
| 127 } |
| 128 |
| 129 /** |
| 130 * Return true if the capability is enabled for this connection with the hos
t. |
| 131 */ |
| 132 private boolean isCapabilityEnabled(String capability) { |
| 133 return (mNegotiatedCapabilities != null && mNegotiatedCapabilities.conta
ins(capability)); |
| 134 } |
| 135 |
| 136 /** |
| 137 * Tries to reflectively instantiate a CastExtensionHandler object. |
| 138 * |
| 139 * Note: The ONLY reason this is done is that by default, the regular androi
d application |
| 140 * will be built, without this experimental extension. |
| 141 */ |
| 142 private ClientExtension maybeCreateCastExtensionHandler() { |
| 143 try { |
| 144 Class<?> cls = Class.forName("org.chromium.chromoting.CastExtensionH
andler"); |
| 145 return (ClientExtension) cls.newInstance(); |
| 146 } catch (ClassNotFoundException e) { |
| 147 Log.w("CapabilityManager", "Failed to create CastExtensionHandler.")
; |
| 148 return new DummyClientExtension(); |
| 149 } catch (InstantiationException e) { |
| 150 Log.w("CapabilityManager", "Failed to create CastExtensionHandler.")
; |
| 151 return new DummyClientExtension(); |
| 152 } catch (IllegalAccessException e) { |
| 153 Log.w("CapabilityManager", "Failed to create CastExtensionHandler.")
; |
| 154 return new DummyClientExtension(); |
| 155 } |
| 156 } |
| 157 } |
OLD | NEW |