Index: ui/display/android/display_android_manager.cc |
diff --git a/ui/display/android/display_android_manager.cc b/ui/display/android/display_android_manager.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..d23fcaefa0f9541e02286a433dadf511311e2d75 |
--- /dev/null |
+++ b/ui/display/android/display_android_manager.cc |
@@ -0,0 +1,177 @@ |
+// Copyright 2012 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "ui/display/android/display_android_manager.h" |
+ |
+#include <jni.h> |
+#include <map> |
+ |
+#include "base/logging.h" |
+#include "jni/DisplayAndroidManager_jni.h" |
+#include "ui/android/window_android.h" |
+#include "ui/display/display.h" |
+#include "ui/display/display_export.h" |
+#include "ui/display/screen.h" |
+ |
+namespace display { |
+ |
+namespace { |
+ |
+// ID of the primary device display, same as Display.DEFAULT_DISPLAY |
+// https://developer.android.com/reference/android/view/Display.html |
+const int kPrimaryDisplayId = 0; |
+} |
+ |
+class DisplayAndroidManager : public Screen { |
+ public: |
+ DisplayAndroidManager() {} |
+ ~DisplayAndroidManager() {} |
+ |
+ // Disallow copy and assign. |
+ DisplayAndroidManager(const DisplayAndroidManager& rhs) = delete; |
+ DisplayAndroidManager& operator=(const DisplayAndroidManager& rhs) = delete; |
+ |
+ // Screen interface. |
+ |
+ gfx::Point GetCursorScreenPoint() { return gfx::Point(); } |
+ |
+ bool IsWindowUnderCursor(gfx::NativeWindow window) { |
+ NOTIMPLEMENTED(); |
+ return false; |
+ } |
+ |
+ gfx::NativeWindow GetWindowAtScreenPoint(const gfx::Point& point) { |
+ NOTIMPLEMENTED(); |
+ return NULL; |
+ } |
+ |
+ int GetNumDisplays() const { |
+ DCHECK_GE(displays_.size(), 1U); |
+ return displays_.size(); |
+ } |
+ |
+ std::vector<Display> GetAllDisplays() const { |
+ DCHECK_GE(displays_.size(), 1U); |
+ |
+ std::vector<Display> result; |
+ for (const auto& display : displays_) |
+ result.push_back(display.second); |
+ |
+ return result; |
+ } |
+ |
+ Display GetDisplayNearestWindow(gfx::NativeView view) const { |
+ DCHECK(view); |
+ ui::WindowAndroid* window = view->GetWindowAndroid(); |
+ |
+ if (window && displays_.count(window->display_id())) |
+ return GetFromMap(window->display_id()); |
+ else |
+ return GetPrimaryDisplay(); |
+ } |
+ |
+ Display GetDisplayNearestPoint(const gfx::Point& point) const { |
+ NOTIMPLEMENTED(); |
+ return Display(); |
+ } |
+ |
+ Display GetDisplayMatching(const gfx::Rect& match_rect) const { |
+ NOTIMPLEMENTED(); |
+ return Display(); |
+ } |
+ |
+ Display GetPrimaryDisplay() const { |
+ // Android documentation for the Display.DEFAULT_DISPLAY says "id of the |
+ // built-in primary display assuming there is one", therefore I assume there |
+ // might be no primary display. We report this case by |
+ // setting no_primary_display_ flag. |
+ if (!displays_.count(kPrimaryDisplayId)) { |
+ CHECK_EQ(no_primary_display_, true); |
+ return Display(); |
+ } |
+ return GetFromMap(kPrimaryDisplayId); |
+ } |
+ |
+ // Native side observers are not implemented for Android. |
+ void AddObserver(DisplayObserver* observer) {} |
+ |
+ void RemoveObserver(DisplayObserver* observer) {} |
+ |
+ // Helper methods that respond to Java calls. |
+ |
+ void UpdateDisplay(int display_id, const Display& display) { |
+ displays_[display_id] = display; |
+ } |
+ |
+ void RemoveDisplay(int display_id) { displays_.erase(display_id); } |
+ |
+ void SetNoPrimaryDisplay() { no_primary_display_ = true; } |
+ |
+ private: |
+ Display GetFromMap(int id) const { |
+ DCHECK_EQ(displays_.count(id), 1U); |
+ return displays_.find(id)->second; |
+ } |
+ |
+ std::map<int, Display> displays_; |
+ bool no_primary_display_ = false; |
+}; |
+ |
+Screen* CreateNativeScreen() { |
+ return new DisplayAndroidManager; |
+} |
+ |
+bool RegisterDisplayAndroidManager(JNIEnv* env) { |
+ return RegisterNativesImpl(env); |
+} |
+ |
+// Called from Java |
+ |
+static void UpdateDisplay(JNIEnv* env, |
mthiesse
2016/10/27 14:30:30
Why is this static? It's only called from a non-st
Tima Vaisburd
2016/10/27 17:56:24
I did this to avoid propagating the native object
mthiesse
2016/10/27 19:51:51
Just my opinion, but I think it would be better to
boliu
2016/10/27 22:17:49
I'm fine with static here. I don't think the assum
Tima Vaisburd
2016/10/31 23:36:15
Kept static.
Tima Vaisburd
2016/11/05 00:13:41
Back to native pointer is PS 13. The native pointe
|
+ const base::android::JavaParamRef<jclass>& jcaller, |
+ jint sdkDisplayId, |
+ jint physicalWidth, |
+ jint physicalHeight, |
+ jint width, |
+ jint height, |
+ jfloat dipScale, |
+ jint rotationDegrees, |
+ jint bitsPerPixel, |
+ jint bitsPerComponent) { |
+ gfx::Rect bounds_in_pixels = gfx::Rect(physicalWidth, physicalHeight); |
+ |
+ // Physical width and height might be not supported. |
+ if (bounds_in_pixels.IsEmpty()) |
+ bounds_in_pixels = gfx::Rect(width, height); |
+ |
+ const gfx::Rect bounds_in_dip = gfx::Rect( |
+ gfx::ScaleToCeiledSize(bounds_in_pixels.size(), 1.0f / dipScale)); |
+ |
+ display::Display display = display::Display(0, bounds_in_dip); |
+ |
+ display.set_device_scale_factor(dipScale); |
+ display.SetRotationAsDegree(rotationDegrees); |
+ display.set_color_depth(bitsPerPixel); |
+ display.set_depth_per_component(bitsPerComponent); |
+ display.set_is_monochrome(bitsPerComponent == 0); |
+ |
+ static_cast<DisplayAndroidManager*>(Screen::GetScreen()) |
+ ->UpdateDisplay(sdkDisplayId, display); |
+} |
+ |
+static void RemoveDisplay(JNIEnv* env, |
+ const base::android::JavaParamRef<jclass>& jcaller, |
+ jint sdkDisplayId) { |
+ static_cast<DisplayAndroidManager*>(Screen::GetScreen()) |
+ ->RemoveDisplay(sdkDisplayId); |
+} |
+ |
+static void SetNoPrimaryDisplay( |
+ JNIEnv* env, |
+ const base::android::JavaParamRef<jclass>& jcaller) { |
+ static_cast<DisplayAndroidManager*>(Screen::GetScreen()) |
+ ->SetNoPrimaryDisplay(); |
+} |
+ |
+} // namespace display |