Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / remoting / android / java / src / org / chromium / chromoting / CapabilityManager.java
blob11057e4ce1e291af4f91a9cb2d45810a742b9275
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.
5 package org.chromium.chromoting;
7 import android.app.Activity;
8 import android.text.TextUtils;
9 import android.util.Log;
11 import java.util.ArrayList;
12 import java.util.Arrays;
13 import java.util.List;
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 communication with
18 * the Chromoting host by dispatching extension messages appropriately.
20 * The CapabilityManager mirrors how the Chromoting host handles extension messages. For each
21 * incoming extension message, runs through a list of HostExtensionSession objects, giving each one
22 * a chance to handle the message.
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 allowing it to support
26 * different capabilities at different stages of the application.
28 public class CapabilityManager {
30 /** Lazily-initialized singleton object that can be used from different Activities. */
31 private static CapabilityManager sInstance;
33 /** Protects access to |sInstance|. */
34 private static final Object sInstanceLock = new Object();
36 /** List of all capabilities that are supported by the application. */
37 private List<String> mLocalCapabilities;
39 /** List of negotiated capabilities received from the host. */
40 private List<String> mNegotiatedCapabilities;
42 /** List of extensions to the client based on capabilities negotiated with the host. */
43 private List<ClientExtension> mClientExtensions;
45 private CapabilityManager() {
46 mLocalCapabilities = new ArrayList<String>();
47 mClientExtensions = new ArrayList<ClientExtension>();
49 mLocalCapabilities.add(Capabilities.CAST_CAPABILITY);
52 /**
53 * Returns the singleton object. Thread-safe.
55 public static CapabilityManager getInstance() {
56 synchronized (sInstanceLock) {
57 if (sInstance == null) {
58 sInstance = new CapabilityManager();
60 return sInstance;
64 /**
65 * Returns a space-separated list (required by host) of the capabilities supported by
66 * this client.
68 public String getLocalCapabilities() {
69 return TextUtils.join(" ", mLocalCapabilities);
72 /**
73 * Returns the ActivityLifecycleListener associated with the specified capability, if
74 * |capability| is enabled and such a listener exists.
76 * Activities that call this method agree to appropriately notify the listener of lifecycle
77 * events., thus supporting |capability|. This allows extensions like the CastExtensionHandler
78 * to hook into an existing activity's lifecycle.
80 public ActivityLifecycleListener onActivityAcceptingListener(
81 Activity activity, String capability) {
83 ActivityLifecycleListener listener;
85 if (isCapabilityEnabled(capability)) {
86 for (ClientExtension ext : mClientExtensions) {
87 if (ext.getCapability().equals(capability)) {
88 listener = ext.onActivityAcceptingListener(activity);
89 if (listener != null) return listener;
94 return new DummyActivityLifecycleListener();
97 /**
98 * Receives the capabilities negotiated between client and host and creates the appropriate
99 * extension handlers.
101 * Currently only the CAST_CAPABILITY exists, so that is the only extension constructed.
103 public void setNegotiatedCapabilities(String capabilities) {
104 mNegotiatedCapabilities = Arrays.asList(capabilities.split(" "));
105 mClientExtensions.clear();
106 if (isCapabilityEnabled(Capabilities.CAST_CAPABILITY)) {
107 mClientExtensions.add(maybeCreateCastExtensionHandler());
112 * Passes the deconstructed extension message to each ClientExtension in turn until the message
113 * is handled or none remain. Returns true if the message was handled.
115 public boolean onExtensionMessage(String type, String data) {
116 if (type == null || type.isEmpty()) {
117 return false;
120 for (ClientExtension ext : mClientExtensions) {
121 if (ext.onExtensionMessage(type, data)) {
122 return true;
125 return false;
129 * Return true if the capability is enabled for this connection with the host.
131 private boolean isCapabilityEnabled(String capability) {
132 return (mNegotiatedCapabilities != null && mNegotiatedCapabilities.contains(capability));
136 * Tries to reflectively instantiate a CastExtensionHandler object.
138 * Note: The ONLY reason this is done is that by default, the regular android application
139 * will be built, without this experimental extension.
141 private ClientExtension maybeCreateCastExtensionHandler() {
142 try {
143 Class<?> cls = Class.forName("org.chromium.chromoting.CastExtensionHandler");
144 return (ClientExtension) cls.newInstance();
145 } catch (ClassNotFoundException e) {
146 Log.w("CapabilityManager", "Failed to create CastExtensionHandler.");
147 return new DummyClientExtension();
148 } catch (InstantiationException e) {
149 Log.w("CapabilityManager", "Failed to create CastExtensionHandler.");
150 return new DummyClientExtension();
151 } catch (IllegalAccessException e) {
152 Log.w("CapabilityManager", "Failed to create CastExtensionHandler.");
153 return new DummyClientExtension();