1
1
#if __ANDROID__
2
+ #nullable enable
2
3
using System ;
3
4
using Android . App ;
4
5
using Android . Content ;
@@ -11,7 +12,10 @@ namespace Windows.Graphics.Display
11
12
{
12
13
public sealed partial class DisplayInformation
13
14
{
14
- private static DisplayInformation _instance ;
15
+ private static DisplayInformation ? _instance ;
16
+
17
+ private DisplayMetricsCache _cachedDisplayMetrics ;
18
+ private SurfaceOrientation _cachedRotation ;
15
19
16
20
private static DisplayInformation InternalGetForCurrentView ( )
17
21
{
@@ -39,6 +43,11 @@ static partial void SetOrientationPartial(DisplayOrientations orientations)
39
43
}
40
44
}
41
45
46
+ partial void Initialize ( )
47
+ {
48
+ RefreshDisplayMetricsCache ( ) ;
49
+ }
50
+
42
51
public DisplayOrientations CurrentOrientation => GetCurrentOrientation ( ) ;
43
52
44
53
@@ -51,61 +60,21 @@ static partial void SetOrientationPartial(DisplayOrientations orientations)
51
60
52
61
53
62
public uint ScreenHeightInRawPixels
54
- {
55
- get
56
- {
57
- using ( var realDisplayMetrics = CreateRealDisplayMetrics ( ) )
58
- {
59
- return ( uint ) realDisplayMetrics . HeightPixels ;
60
- }
61
- }
62
- }
63
+ => ( uint ) _cachedDisplayMetrics . HeightPixels ;
63
64
64
65
public uint ScreenWidthInRawPixels
65
- {
66
- get
67
- {
68
- using ( var realDisplayMetrics = CreateRealDisplayMetrics ( ) )
69
- {
70
- return ( uint ) realDisplayMetrics . WidthPixels ;
71
- }
72
- }
73
- }
74
-
66
+ => ( uint ) _cachedDisplayMetrics . WidthPixels ;
67
+
75
68
public double RawPixelsPerViewPixel
76
- {
77
- get
78
- {
79
- using ( var realDisplayMetrics = CreateRealDisplayMetrics ( ) )
80
- {
81
- return 1.0f * ( int ) realDisplayMetrics . DensityDpi / ( int ) DisplayMetricsDensity . Default ;
82
- }
83
- }
84
- }
69
+ => 1.0f * ( int ) _cachedDisplayMetrics . DensityDpi / ( int ) DisplayMetricsDensity . Default ;
85
70
86
71
public float LogicalDpi
87
- {
88
- get
89
- {
90
- using ( var realDisplayMetrics = CreateRealDisplayMetrics ( ) )
91
- {
92
- // DisplayMetrics of 1.0 matches 100%, or UWP's default 96.0 DPI.
93
- // https://stuff.mit.edu/afs/sipb/project/android/docs/reference/android/util/DisplayMetrics.html#density
94
- return realDisplayMetrics . Density * BaseDpi ;
95
- }
96
- }
97
- }
72
+ // DisplayMetrics of 1.0 matches 100%, or UWP's default 96.0 DPI.
73
+ // https://stuff.mit.edu/afs/sipb/project/android/docs/reference/android/util/DisplayMetrics.html#density
74
+ => _cachedDisplayMetrics . Density * BaseDpi ;
98
75
99
76
public ResolutionScale ResolutionScale
100
- {
101
- get
102
- {
103
- using ( var realDisplayMetrics = CreateRealDisplayMetrics ( ) )
104
- {
105
- return ( ResolutionScale ) ( int ) ( realDisplayMetrics . Density * 100 ) ;
106
- }
107
- }
108
- }
77
+ => ( ResolutionScale ) ( int ) ( _cachedDisplayMetrics . Density * 100 ) ;
109
78
110
79
/// <summary>
111
80
/// Gets the raw dots per inch (DPI) along the x axis of the display monitor.
@@ -115,15 +84,7 @@ public ResolutionScale ResolutionScale
115
84
/// defaults to 0 if not set
116
85
/// </remarks>
117
86
public float RawDpiX
118
- {
119
- get
120
- {
121
- using ( var realDisplayMetrics = CreateRealDisplayMetrics ( ) )
122
- {
123
- return realDisplayMetrics . Xdpi ;
124
- }
125
- }
126
- }
87
+ => _cachedDisplayMetrics . Xdpi ;
127
88
128
89
/// <summary>
129
90
/// Gets the raw dots per inch (DPI) along the y axis of the display monitor.
@@ -133,15 +94,7 @@ public float RawDpiX
133
94
/// defaults to 0 if not set
134
95
/// </remarks>
135
96
public float RawDpiY
136
- {
137
- get
138
- {
139
- using ( var realDisplayMetrics = CreateRealDisplayMetrics ( ) )
140
- {
141
- return realDisplayMetrics . Ydpi ;
142
- }
143
- }
144
- }
97
+ => _cachedDisplayMetrics . Ydpi ;
145
98
146
99
/// <summary>
147
100
/// Diagonal size of the display in inches.
@@ -154,13 +107,10 @@ public double? DiagonalSizeInInches
154
107
{
155
108
get
156
109
{
157
- using ( var realDisplayMetrics = CreateRealDisplayMetrics ( ) )
158
- {
159
- var x = Math . Pow ( ( uint ) realDisplayMetrics . WidthPixels / realDisplayMetrics . Xdpi , 2 ) ;
160
- var y = Math . Pow ( ( uint ) realDisplayMetrics . HeightPixels / realDisplayMetrics . Ydpi , 2 ) ;
161
- var screenInches = Math . Sqrt ( x + y ) ;
162
- return screenInches ;
163
- }
110
+ var x = Math . Pow ( ( uint ) _cachedDisplayMetrics . WidthPixels / _cachedDisplayMetrics . Xdpi , 2 ) ;
111
+ var y = Math . Pow ( ( uint ) _cachedDisplayMetrics . HeightPixels / _cachedDisplayMetrics . Ydpi , 2 ) ;
112
+ var screenInches = Math . Sqrt ( x + y ) ;
113
+ return screenInches ;
164
114
}
165
115
}
166
116
@@ -175,13 +125,13 @@ private DisplayOrientations GetNativeOrientation()
175
125
{
176
126
using ( var windowManager = CreateWindowManager ( ) )
177
127
{
178
- var orientation = ContextHelper . Current . Resources . Configuration . Orientation ;
128
+ var orientation = ContextHelper . Current . Resources ! . Configuration ! . Orientation ;
179
129
if ( orientation == Android . Content . Res . Orientation . Undefined )
180
130
{
181
131
return DisplayOrientations . None ;
182
132
}
183
133
184
- var rotation = windowManager . DefaultDisplay . Rotation ;
134
+ var rotation = _cachedRotation ;
185
135
bool isLandscape ;
186
136
switch ( rotation )
187
137
{
@@ -208,94 +158,119 @@ private DisplayOrientations GetCurrentOrientation()
208
158
{
209
159
using ( var windowManager = CreateWindowManager ( ) )
210
160
{
211
- var rotation = windowManager . DefaultDisplay . Rotation ;
212
- using ( var displayMetrics = new DisplayMetrics ( ) )
213
- {
214
- #pragma warning disable 618
215
- windowManager . DefaultDisplay . GetMetrics ( displayMetrics ) ;
216
- #pragma warning restore 618
217
-
218
- int width = displayMetrics . WidthPixels ;
219
- int height = displayMetrics . HeightPixels ;
161
+ int width = _cachedDisplayMetrics . WidthPixels ;
162
+ int height = _cachedDisplayMetrics . HeightPixels ;
220
163
221
- if ( width == height )
222
- {
223
- //square device, can't tell orientation
224
- return DisplayOrientations . None ;
225
- }
164
+ if ( width == height )
165
+ {
166
+ //square device, can't tell orientation
167
+ return DisplayOrientations . None ;
168
+ }
226
169
227
- if ( NativeOrientation == DisplayOrientations . Portrait )
228
- {
229
- switch ( rotation )
230
- {
231
- case SurfaceOrientation . Rotation0 :
232
- return DisplayOrientations . Portrait ;
233
- case SurfaceOrientation . Rotation90 :
234
- return DisplayOrientations . Landscape ;
235
- case SurfaceOrientation . Rotation180 :
236
- return DisplayOrientations . PortraitFlipped ;
237
- case SurfaceOrientation . Rotation270 :
238
- return DisplayOrientations . LandscapeFlipped ;
239
- default :
240
- //invalid rotation
241
- return DisplayOrientations . None ;
242
- }
243
- }
244
- else if ( NativeOrientation == DisplayOrientations . Landscape )
170
+ if ( NativeOrientation == DisplayOrientations . Portrait )
171
+ {
172
+ switch ( _cachedRotation )
245
173
{
246
- //device is landscape or square
247
- switch ( rotation )
248
- {
249
- case SurfaceOrientation . Rotation0 :
250
- return DisplayOrientations . Landscape ;
251
- case SurfaceOrientation . Rotation90 :
252
- return DisplayOrientations . Portrait ;
253
- case SurfaceOrientation . Rotation180 :
254
- return DisplayOrientations . LandscapeFlipped ;
255
- case SurfaceOrientation . Rotation270 :
256
- return DisplayOrientations . PortraitFlipped ;
257
- default :
258
- //invalid rotation
259
- return DisplayOrientations . None ;
260
- }
174
+ case SurfaceOrientation . Rotation0 :
175
+ return DisplayOrientations . Portrait ;
176
+ case SurfaceOrientation . Rotation90 :
177
+ return DisplayOrientations . Landscape ;
178
+ case SurfaceOrientation . Rotation180 :
179
+ return DisplayOrientations . PortraitFlipped ;
180
+ case SurfaceOrientation . Rotation270 :
181
+ return DisplayOrientations . LandscapeFlipped ;
182
+ default :
183
+ //invalid rotation
184
+ return DisplayOrientations . None ;
261
185
}
262
- else
186
+ }
187
+ else if ( NativeOrientation == DisplayOrientations . Landscape )
188
+ {
189
+ //device is landscape or square
190
+ switch ( _cachedRotation )
263
191
{
264
- //fallback
265
- return DisplayOrientations . None ;
192
+ case SurfaceOrientation . Rotation0 :
193
+ return DisplayOrientations . Landscape ;
194
+ case SurfaceOrientation . Rotation90 :
195
+ return DisplayOrientations . Portrait ;
196
+ case SurfaceOrientation . Rotation180 :
197
+ return DisplayOrientations . LandscapeFlipped ;
198
+ case SurfaceOrientation . Rotation270 :
199
+ return DisplayOrientations . PortraitFlipped ;
200
+ default :
201
+ //invalid rotation
202
+ return DisplayOrientations . None ;
266
203
}
267
204
}
205
+ else
206
+ {
207
+ //fallback
208
+ return DisplayOrientations . None ;
209
+ }
268
210
}
269
211
}
270
212
271
213
private IWindowManager CreateWindowManager ( )
272
214
{
273
- return ContextHelper . Current . GetSystemService ( Context . WindowService ) . JavaCast < IWindowManager > ( ) ;
274
- }
275
-
276
- private DisplayMetrics CreateRealDisplayMetrics ( )
277
- {
278
- var displayMetrics = new DisplayMetrics ( ) ;
279
- using ( var windowManager = CreateWindowManager ( ) )
215
+ if ( ContextHelper . Current . GetSystemService ( Context . WindowService ) is { } windowService )
280
216
{
281
- windowManager . DefaultDisplay . GetRealMetrics ( displayMetrics ) ;
217
+ return windowService . JavaCast < IWindowManager > ( ) ; ;
282
218
}
283
- return displayMetrics ;
219
+
220
+ throw new InvalidOperationException ( "Failed to get the system Window Service" ) ;
284
221
}
285
222
286
223
partial void StartOrientationChanged ( )
224
+ => _lastKnownOrientation = CurrentOrientation ;
225
+
226
+ partial void StartDpiChanged ( )
227
+ => _lastKnownDpi = LogicalDpi ;
228
+
229
+ internal void HandleConfigurationChange ( )
287
230
{
288
- _lastKnownOrientation = CurrentOrientation ;
231
+ RefreshDisplayMetricsCache ( ) ;
232
+ OnDisplayMetricsChanged ( ) ;
289
233
}
290
234
291
- partial void StartDpiChanged ( )
235
+ private void RefreshDisplayMetricsCache ( )
292
236
{
293
- _lastKnownDpi = LogicalDpi ;
237
+ var displayMetrics = new DisplayMetrics ( ) ;
238
+ using ( var windowManager = CreateWindowManager ( ) )
239
+ {
240
+ if ( windowManager . DefaultDisplay is { } defaultDisplay )
241
+ {
242
+ defaultDisplay . GetRealMetrics ( displayMetrics ) ;
243
+
244
+ _cachedDisplayMetrics = new DisplayMetricsCache ( displayMetrics ) ;
245
+ _cachedRotation = windowManager . DefaultDisplay . Rotation ;
246
+ }
247
+ else
248
+ {
249
+ throw new InvalidOperationException ( "Failed to get the default display information" ) ;
250
+ }
251
+ }
294
252
}
295
253
296
- internal void HandleConfigurationChange ( )
254
+ private class DisplayMetricsCache
297
255
{
298
- OnDisplayMetricsChanged ( ) ;
256
+ public DisplayMetricsCache ( DisplayMetrics displayMetric )
257
+ {
258
+ Density = displayMetric . Density ;
259
+ DensityDpi = displayMetric . DensityDpi ;
260
+ HeightPixels = displayMetric . HeightPixels ;
261
+ ScaledDensity = displayMetric . ScaledDensity ;
262
+ WidthPixels = displayMetric . WidthPixels ;
263
+ Xdpi = displayMetric . Xdpi ;
264
+ Ydpi = displayMetric . Ydpi ;
265
+ }
266
+
267
+ public float Density { get ; }
268
+ public DisplayMetricsDensity DensityDpi { get ; }
269
+ public int HeightPixels { get ; }
270
+ public float ScaledDensity { get ; }
271
+ public int WidthPixels { get ; }
272
+ public float Xdpi { get ; }
273
+ public float Ydpi { get ; }
299
274
}
300
275
}
301
276
}
0 commit comments