1 // Copyright (c) 2013 Intel Corporation. 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.xwalk.core.extension.api.device_capabilities;
7 import android.content.Context;
8 import android.graphics.Point;
9 import android.util.DisplayMetrics;
10 import android.util.Log;
11 import android.util.SparseArray;
12 import android.view.Display;
14 import org.json.JSONArray;
15 import org.json.JSONException;
16 import org.json.JSONObject;
17 import org.xwalk.core.extension.api.XWalkDisplayManager;
18 import org.xwalk.core.extension.XWalkExtensionContext;
20 class DeviceCapabilitiesDisplay {
21 private static final String TAG = "DeviceCapabilitiesDisplay";
23 private DeviceCapabilities mDeviceCapabilities;
24 private XWalkDisplayManager mDisplayManager;
26 // Holds all available displays connected to the system.
27 private final SparseArray<Display> mDisplayList = new SparseArray<Display>();
29 private final XWalkDisplayManager.DisplayListener mDisplayListener =
30 new XWalkDisplayManager.DisplayListener() {
32 public void onDisplayAdded(int displayId) {
33 // Broadcast and add the added display to JavaScript
34 notifyAndSaveConnectedDisplay(mDisplayManager.getDisplay(displayId));
38 public void onDisplayRemoved(int displayId) {
39 Display disp = mDisplayList.get(displayId);
41 // Do nothing if the display does not exsit on cache.
46 // Broadcast and remove the added display to JavaScript
47 notifyAndRemoveDisconnectedDisplay(disp);
51 public void onDisplayChanged(int displayId) {
55 public DeviceCapabilitiesDisplay(DeviceCapabilities instance,
56 XWalkExtensionContext context) {
57 mDeviceCapabilities = instance;
58 mDisplayManager = XWalkDisplayManager.getInstance(context.getContext());
60 // Fetch the original display list
64 public JSONObject getInfo() {
65 JSONObject out = new JSONObject();
66 JSONArray arr = new JSONArray();
69 for(int i = 0; i < mDisplayList.size(); i++) {
70 arr.put(convertDisplayToJSON(mDisplayList.valueAt(i)));
72 out.put("displays", arr);
73 } catch (JSONException e) {
74 return mDeviceCapabilities.setErrorMessage(e.toString());
80 public JSONObject convertDisplayToJSON(Display disp) {
81 DisplayMetrics displayMetrics = new DisplayMetrics();
82 disp.getRealMetrics(displayMetrics);
84 Point realSize = new Point();
85 disp.getRealSize(realSize);
87 Point availSize = new Point();
88 disp.getSize(availSize);
90 JSONObject out = new JSONObject();
92 out.put("id", disp.getDisplayId());
93 out.put("name", disp.getName());
94 out.put("isPrimary", disp.getDisplayId() == disp.DEFAULT_DISPLAY);
95 out.put("isInternal", disp.getDisplayId() == disp.DEFAULT_DISPLAY);
96 out.put("dpiX", (int) displayMetrics.xdpi);
97 out.put("dpiY", (int) displayMetrics.ydpi);
98 out.put("width", realSize.x);
99 out.put("height", realSize.y);
100 out.put("availWidth", availSize.x);
101 out.put("availHeight", availSize.y);
102 } catch (JSONException e) {
103 return mDeviceCapabilities.setErrorMessage(e.toString());
108 private void initDisplayList() {
109 Display[] displays = mDisplayManager.getDisplays();
111 for (Display disp : displays) {
112 mDisplayList.put(disp.getDisplayId(), disp);
116 private void notifyAndSaveConnectedDisplay(Display disp) {
121 JSONObject out = new JSONObject();
123 out.put("reply", "connectDisplay");
124 out.put("eventName", "displayconnect");
125 out.put("data", convertDisplayToJSON(disp));
127 mDeviceCapabilities.broadcastMessage(out.toString());
128 mDisplayList.put(disp.getDisplayId(), disp);
129 } catch (JSONException e) {
130 mDeviceCapabilities.printErrorMessage(e);
134 private void notifyAndRemoveDisconnectedDisplay(Display disp) {
135 JSONObject out = new JSONObject();
137 out.put("reply", "disconnectDisplay");
138 out.put("eventName", "displaydisconnect");
139 out.put("data", convertDisplayToJSON(disp));
141 mDeviceCapabilities.broadcastMessage(out.toString());
142 mDisplayList.remove(disp.getDisplayId());
143 } catch (JSONException e) {
144 mDeviceCapabilities.printErrorMessage(e);
148 public void onResume() {
149 Display[] displays = mDisplayManager.getDisplays();
151 // Firstly, check whether display in latest list is in cached display list.
152 // If not found, then send out "onconnect" message and insert to cache.
153 // If found, only update the display object without sending message.
154 for (Display disp : displays) {
155 Display foundDisplay = mDisplayList.get(disp.getDisplayId());
156 if (foundDisplay == null) {
157 notifyAndSaveConnectedDisplay(disp);
159 mDisplayList.put(disp.getDisplayId(), disp);
163 // Secondly, remove those displays that only in cache.
164 for(int i = 0; i < mDisplayList.size(); i++) {
165 boolean found = false;
166 for (Display disp : displays) {
167 if (mDisplayList.valueAt(i).getDisplayId() == disp.getDisplayId()) {
174 notifyAndRemoveDisconnectedDisplay(mDisplayList.valueAt(i));
178 // Register the listener to display manager.
180 // XWalkDisplayManager.registerDisplayListener only works on UI thread,
181 // otherwise coredump.
183 // Register the listener here lead to a connect/disconnect event will
184 // unconditionally be posted to JS whatever there is a JS listener
185 // registered or not. It is kind of waste of resource.
187 // Fortunately, the listneres map in JSAPI will ensurce no noise messages
189 mDisplayManager.registerDisplayListener(mDisplayListener);
192 public void onPause() {
193 mDisplayManager.unregisterDisplayListener(mDisplayListener);
196 public void onDestroy() {