Upstream version 5.34.92.0
[platform/framework/web/crosswalk.git] / src / xwalk / runtime / android / core / src / org / xwalk / core / extension / api / device_capabilities / DeviceCapabilitiesDisplay.java
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.
4
5 package org.xwalk.core.extension.api.device_capabilities;
6
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;
13
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;
19
20 class DeviceCapabilitiesDisplay {
21     private static final String TAG = "DeviceCapabilitiesDisplay";
22
23     private DeviceCapabilities mDeviceCapabilities;
24     private XWalkDisplayManager mDisplayManager;
25
26     // Holds all available displays connected to the system.
27     private final SparseArray<Display> mDisplayList = new SparseArray<Display>();
28
29     private final XWalkDisplayManager.DisplayListener mDisplayListener =
30             new XWalkDisplayManager.DisplayListener() {
31         @Override
32         public void onDisplayAdded(int displayId) {
33             // Broadcast and add the added display to JavaScript
34             notifyAndSaveConnectedDisplay(mDisplayManager.getDisplay(displayId));
35         }
36
37         @Override
38         public void onDisplayRemoved(int displayId) {
39             Display disp = mDisplayList.get(displayId);
40
41             // Do nothing if the display does not exsit on cache.
42             if (disp == null) {
43                 return;
44             }
45
46             // Broadcast and remove the added display to JavaScript
47             notifyAndRemoveDisconnectedDisplay(disp);
48         }
49
50         @Override
51         public void onDisplayChanged(int displayId) {
52         }
53     };
54
55     public DeviceCapabilitiesDisplay(DeviceCapabilities instance,
56                                      XWalkExtensionContext context) {
57         mDeviceCapabilities = instance;
58         mDisplayManager = XWalkDisplayManager.getInstance(context.getContext());
59
60         // Fetch the original display list
61         initDisplayList();
62     }
63
64     public JSONObject getInfo() {
65         JSONObject out = new JSONObject();
66         JSONArray arr = new JSONArray();
67
68         try {
69             for(int i = 0; i < mDisplayList.size(); i++) {
70                 arr.put(convertDisplayToJSON(mDisplayList.valueAt(i)));
71             }
72             out.put("displays", arr);
73         } catch (JSONException e) {
74             return mDeviceCapabilities.setErrorMessage(e.toString());
75         }
76
77         return out;
78     }
79
80     public JSONObject convertDisplayToJSON(Display disp) {
81         DisplayMetrics displayMetrics = new DisplayMetrics();
82         disp.getRealMetrics(displayMetrics);
83
84         Point realSize = new Point();
85         disp.getRealSize(realSize);
86
87         Point availSize = new Point();
88         disp.getSize(availSize);
89
90         JSONObject out = new JSONObject();
91         try {
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());
104         }
105         return out;
106     }
107
108     private void initDisplayList() {
109         Display[] displays = mDisplayManager.getDisplays();
110
111         for (Display disp : displays) {
112             mDisplayList.put(disp.getDisplayId(), disp);
113         }
114     }
115
116     private void notifyAndSaveConnectedDisplay(Display disp) {
117         if (disp == null) {
118             return;
119         }
120
121         JSONObject out = new JSONObject();
122         try {
123             out.put("reply", "connectDisplay");
124             out.put("eventName", "displayconnect");
125             out.put("data", convertDisplayToJSON(disp));
126
127             mDeviceCapabilities.broadcastMessage(out.toString());
128             mDisplayList.put(disp.getDisplayId(), disp);
129         } catch (JSONException e) {
130             mDeviceCapabilities.printErrorMessage(e);
131         }
132     }
133
134     private void notifyAndRemoveDisconnectedDisplay(Display disp) {
135         JSONObject out = new JSONObject();
136         try {
137             out.put("reply", "disconnectDisplay");
138             out.put("eventName", "displaydisconnect");
139             out.put("data", convertDisplayToJSON(disp));
140
141             mDeviceCapabilities.broadcastMessage(out.toString());
142             mDisplayList.remove(disp.getDisplayId());
143         } catch (JSONException e) {
144             mDeviceCapabilities.printErrorMessage(e);
145         }
146     }
147
148     public void onResume() {
149         Display[] displays = mDisplayManager.getDisplays();
150
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);
158             } else {
159                 mDisplayList.put(disp.getDisplayId(), disp);
160             }
161         }
162
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()) {
168                     found = true;
169                     break;
170                 }
171             }
172
173             if (!found) {
174                 notifyAndRemoveDisconnectedDisplay(mDisplayList.valueAt(i));
175             }
176         }
177
178         // Register the listener to display manager.
179         //
180         // XWalkDisplayManager.registerDisplayListener only works on UI thread,
181         // otherwise coredump.
182         //
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.
186         //
187         // Fortunately, the listneres map in JSAPI will ensurce no noise messages
188         // will exposed out.
189         mDisplayManager.registerDisplayListener(mDisplayListener);
190     }
191
192     public void onPause() {
193         mDisplayManager.unregisterDisplayListener(mDisplayListener);
194     }
195
196     public void onDestroy() {
197     }
198 }