mobile/android/base/GeckoScreenOrientation.java

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
michael@0 2 * This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
michael@0 4 * You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 package org.mozilla.gecko;
michael@0 7
michael@0 8 import android.content.Context;
michael@0 9 import android.content.pm.ActivityInfo;
michael@0 10 import android.content.res.Configuration;
michael@0 11 import android.util.Log;
michael@0 12 import android.view.Surface;
michael@0 13 import android.app.Activity;
michael@0 14
michael@0 15 import java.util.Arrays;
michael@0 16 import java.util.List;
michael@0 17
michael@0 18 /*
michael@0 19 * Updates, locks and unlocks the screen orientation.
michael@0 20 *
michael@0 21 * Note: Replaces the OnOrientationChangeListener to avoid redundant rotation
michael@0 22 * event handling.
michael@0 23 */
michael@0 24 public class GeckoScreenOrientation {
michael@0 25 private static final String LOGTAG = "GeckoScreenOrientation";
michael@0 26
michael@0 27 // Make sure that any change in dom/base/ScreenOrientation.h happens here too.
michael@0 28 public enum ScreenOrientation {
michael@0 29 NONE(0),
michael@0 30 PORTRAIT_PRIMARY(1 << 0),
michael@0 31 PORTRAIT_SECONDARY(1 << 1),
michael@0 32 LANDSCAPE_PRIMARY(1 << 2),
michael@0 33 LANDSCAPE_SECONDARY(1 << 3),
michael@0 34 DEFAULT(1 << 4);
michael@0 35
michael@0 36 public final short value;
michael@0 37
michael@0 38 private ScreenOrientation(int value) {
michael@0 39 this.value = (short)value;
michael@0 40 }
michael@0 41
michael@0 42 public static ScreenOrientation get(short value) {
michael@0 43 switch (value) {
michael@0 44 case (1 << 0): return PORTRAIT_PRIMARY;
michael@0 45 case (1 << 1): return PORTRAIT_SECONDARY;
michael@0 46 case (1 << 2): return LANDSCAPE_PRIMARY;
michael@0 47 case (1 << 3): return LANDSCAPE_SECONDARY;
michael@0 48 case (1 << 4): return DEFAULT;
michael@0 49 default: return NONE;
michael@0 50 }
michael@0 51 }
michael@0 52 }
michael@0 53
michael@0 54 // Singleton instance.
michael@0 55 private static GeckoScreenOrientation sInstance = null;
michael@0 56 // Default screen orientation, used for initialization and unlocking.
michael@0 57 private static final ScreenOrientation DEFAULT_SCREEN_ORIENTATION = ScreenOrientation.DEFAULT;
michael@0 58 // Default rotation, used when device rotation is unknown.
michael@0 59 private static final int DEFAULT_ROTATION = Surface.ROTATION_0;
michael@0 60 // Default orientation, used if screen orientation is unspecified.
michael@0 61 private ScreenOrientation mDefaultScreenOrientation;
michael@0 62 // Last updated screen orientation.
michael@0 63 private ScreenOrientation mScreenOrientation;
michael@0 64 // Whether the update should notify Gecko about screen orientation changes.
michael@0 65 private boolean mShouldNotify = true;
michael@0 66 // Configuration screen orientation preference path.
michael@0 67 private static final String DEFAULT_SCREEN_ORIENTATION_PREF = "app.orientation.default";
michael@0 68
michael@0 69 public GeckoScreenOrientation() {
michael@0 70 PrefsHelper.getPref(DEFAULT_SCREEN_ORIENTATION_PREF, new PrefsHelper.PrefHandlerBase() {
michael@0 71 @Override public void prefValue(String pref, String value) {
michael@0 72 // Read and update the configuration default preference.
michael@0 73 mDefaultScreenOrientation = screenOrientationFromArrayString(value);
michael@0 74 setRequestedOrientation(mDefaultScreenOrientation);
michael@0 75 }
michael@0 76 });
michael@0 77
michael@0 78 mDefaultScreenOrientation = DEFAULT_SCREEN_ORIENTATION;
michael@0 79 update();
michael@0 80 }
michael@0 81
michael@0 82 public static GeckoScreenOrientation getInstance() {
michael@0 83 if (sInstance == null) {
michael@0 84 sInstance = new GeckoScreenOrientation();
michael@0 85 }
michael@0 86 return sInstance;
michael@0 87 }
michael@0 88
michael@0 89 /*
michael@0 90 * Enable Gecko screen orientation events on update.
michael@0 91 */
michael@0 92 public void enableNotifications() {
michael@0 93 update();
michael@0 94 mShouldNotify = true;
michael@0 95 }
michael@0 96
michael@0 97 /*
michael@0 98 * Disable Gecko screen orientation events on update.
michael@0 99 */
michael@0 100 public void disableNotifications() {
michael@0 101 mShouldNotify = false;
michael@0 102 }
michael@0 103
michael@0 104 /*
michael@0 105 * Update screen orientation.
michael@0 106 * Retrieve orientation and rotation via GeckoAppShell.
michael@0 107 *
michael@0 108 * @return Whether the screen orientation has changed.
michael@0 109 */
michael@0 110 public boolean update() {
michael@0 111 Activity activity = GeckoAppShell.getGeckoInterface().getActivity();
michael@0 112 if (activity == null) {
michael@0 113 return false;
michael@0 114 }
michael@0 115 Configuration config = activity.getResources().getConfiguration();
michael@0 116 return update(config.orientation);
michael@0 117 }
michael@0 118
michael@0 119 /*
michael@0 120 * Update screen orientation given the android orientation.
michael@0 121 * Retrieve rotation via GeckoAppShell.
michael@0 122 *
michael@0 123 * @param aAndroidOrientation
michael@0 124 * Android screen orientation from Configuration.orientation.
michael@0 125 *
michael@0 126 * @return Whether the screen orientation has changed.
michael@0 127 */
michael@0 128 public boolean update(int aAndroidOrientation) {
michael@0 129 return update(getScreenOrientation(aAndroidOrientation, getRotation()));
michael@0 130 }
michael@0 131
michael@0 132 /*
michael@0 133 * Update screen orientation given the screen orientation.
michael@0 134 *
michael@0 135 * @param aScreenOrientation
michael@0 136 * Gecko screen orientation based on android orientation and rotation.
michael@0 137 *
michael@0 138 * @return Whether the screen orientation has changed.
michael@0 139 */
michael@0 140 public boolean update(ScreenOrientation aScreenOrientation) {
michael@0 141 if (mScreenOrientation == aScreenOrientation) {
michael@0 142 return false;
michael@0 143 }
michael@0 144 mScreenOrientation = aScreenOrientation;
michael@0 145 Log.d(LOGTAG, "updating to new orientation " + mScreenOrientation);
michael@0 146 if (mShouldNotify) {
michael@0 147 GeckoAppShell.sendEventToGecko(GeckoEvent.createScreenOrientationEvent(mScreenOrientation.value));
michael@0 148 }
michael@0 149 return true;
michael@0 150 }
michael@0 151
michael@0 152 /*
michael@0 153 * @return The Android orientation (Configuration.orientation).
michael@0 154 */
michael@0 155 public int getAndroidOrientation() {
michael@0 156 return screenOrientationToAndroidOrientation(getScreenOrientation());
michael@0 157 }
michael@0 158
michael@0 159 /*
michael@0 160 * @return The Gecko screen orientation derived from Android orientation and
michael@0 161 * rotation.
michael@0 162 */
michael@0 163 public ScreenOrientation getScreenOrientation() {
michael@0 164 return mScreenOrientation;
michael@0 165 }
michael@0 166
michael@0 167 /*
michael@0 168 * Lock screen orientation given the Android orientation.
michael@0 169 * Retrieve rotation via GeckoAppShell.
michael@0 170 *
michael@0 171 * @param aAndroidOrientation
michael@0 172 * The Android orientation provided by Configuration.orientation.
michael@0 173 */
michael@0 174 public void lock(int aAndroidOrientation) {
michael@0 175 lock(getScreenOrientation(aAndroidOrientation, getRotation()));
michael@0 176 }
michael@0 177
michael@0 178 /*
michael@0 179 * Lock screen orientation given the Gecko screen orientation.
michael@0 180 * Retrieve rotation via GeckoAppShell.
michael@0 181 *
michael@0 182 * @param aScreenOrientation
michael@0 183 * Gecko screen orientation derived from Android orientation and
michael@0 184 * rotation.
michael@0 185 *
michael@0 186 * @return Whether the locking was successful.
michael@0 187 */
michael@0 188 public boolean lock(ScreenOrientation aScreenOrientation) {
michael@0 189 Log.d(LOGTAG, "locking to " + aScreenOrientation);
michael@0 190 update(aScreenOrientation);
michael@0 191 return setRequestedOrientation(aScreenOrientation);
michael@0 192 }
michael@0 193
michael@0 194 /*
michael@0 195 * Unlock and update screen orientation.
michael@0 196 *
michael@0 197 * @return Whether the unlocking was successful.
michael@0 198 */
michael@0 199 public boolean unlock() {
michael@0 200 Log.d(LOGTAG, "unlocking");
michael@0 201 setRequestedOrientation(mDefaultScreenOrientation);
michael@0 202 return update();
michael@0 203 }
michael@0 204
michael@0 205 /*
michael@0 206 * Set the given requested orientation for the current activity.
michael@0 207 * This is essentially an unlock without an update.
michael@0 208 *
michael@0 209 * @param aScreenOrientation
michael@0 210 * Gecko screen orientation.
michael@0 211 *
michael@0 212 * @return Whether the requested orientation was set. This can only fail if
michael@0 213 * the current activity cannot be retrieved vie GeckoAppShell.
michael@0 214 *
michael@0 215 */
michael@0 216 private boolean setRequestedOrientation(ScreenOrientation aScreenOrientation) {
michael@0 217 int activityOrientation = screenOrientationToActivityInfoOrientation(aScreenOrientation);
michael@0 218 Activity activity = GeckoAppShell.getGeckoInterface().getActivity();
michael@0 219 if (activity == null) {
michael@0 220 Log.w(LOGTAG, "setRequestOrientation: failed to get activity");
michael@0 221 }
michael@0 222 if (activity.getRequestedOrientation() == activityOrientation) {
michael@0 223 return false;
michael@0 224 }
michael@0 225 activity.setRequestedOrientation(activityOrientation);
michael@0 226 return true;
michael@0 227 }
michael@0 228
michael@0 229 /*
michael@0 230 * Combine the Android orientation and rotation to the Gecko orientation.
michael@0 231 *
michael@0 232 * @param aAndroidOrientation
michael@0 233 * Android orientation from Configuration.orientation.
michael@0 234 * @param aRotation
michael@0 235 * Device rotation from Display.getRotation().
michael@0 236 *
michael@0 237 * @return Gecko screen orientation.
michael@0 238 */
michael@0 239 private ScreenOrientation getScreenOrientation(int aAndroidOrientation, int aRotation) {
michael@0 240 boolean isPrimary = aRotation == Surface.ROTATION_0 || aRotation == Surface.ROTATION_90;
michael@0 241 if (aAndroidOrientation == Configuration.ORIENTATION_PORTRAIT) {
michael@0 242 if (isPrimary) {
michael@0 243 // Non-rotated portrait device or landscape device rotated
michael@0 244 // to primary portrait mode counter-clockwise.
michael@0 245 return ScreenOrientation.PORTRAIT_PRIMARY;
michael@0 246 }
michael@0 247 return ScreenOrientation.PORTRAIT_SECONDARY;
michael@0 248 }
michael@0 249 if (aAndroidOrientation == Configuration.ORIENTATION_LANDSCAPE) {
michael@0 250 if (isPrimary) {
michael@0 251 // Non-rotated landscape device or portrait device rotated
michael@0 252 // to primary landscape mode counter-clockwise.
michael@0 253 return ScreenOrientation.LANDSCAPE_PRIMARY;
michael@0 254 }
michael@0 255 return ScreenOrientation.LANDSCAPE_SECONDARY;
michael@0 256 }
michael@0 257 return ScreenOrientation.NONE;
michael@0 258 }
michael@0 259
michael@0 260 /*
michael@0 261 * @return Device rotation from Display.getRotation().
michael@0 262 */
michael@0 263 private int getRotation() {
michael@0 264 Activity activity = GeckoAppShell.getGeckoInterface().getActivity();
michael@0 265 if (activity == null) {
michael@0 266 Log.w(LOGTAG, "getRotation: failed to get activity");
michael@0 267 return DEFAULT_ROTATION;
michael@0 268 }
michael@0 269 return activity.getWindowManager().getDefaultDisplay().getRotation();
michael@0 270 }
michael@0 271
michael@0 272 /*
michael@0 273 * Retrieve the screen orientation from an array string.
michael@0 274 *
michael@0 275 * @param aArray
michael@0 276 * String containing comma-delimited strings.
michael@0 277 *
michael@0 278 * @return First parsed Gecko screen orientation.
michael@0 279 */
michael@0 280 public static ScreenOrientation screenOrientationFromArrayString(String aArray) {
michael@0 281 List<String> orientations = Arrays.asList(aArray.split(","));
michael@0 282 if (orientations.size() == 0) {
michael@0 283 // If nothing is listed, return default.
michael@0 284 Log.w(LOGTAG, "screenOrientationFromArrayString: no orientation in string");
michael@0 285 return DEFAULT_SCREEN_ORIENTATION;
michael@0 286 }
michael@0 287
michael@0 288 // We don't support multiple orientations yet. To avoid developer
michael@0 289 // confusion, just take the first one listed.
michael@0 290 return screenOrientationFromString(orientations.get(0));
michael@0 291 }
michael@0 292
michael@0 293 /*
michael@0 294 * Retrieve the scren orientation from a string.
michael@0 295 *
michael@0 296 * @param aStr
michael@0 297 * String hopefully containing a screen orientation name.
michael@0 298 * @return Gecko screen orientation if matched, DEFAULT_SCREEN_ORIENTATION
michael@0 299 * otherwise.
michael@0 300 */
michael@0 301 public static ScreenOrientation screenOrientationFromString(String aStr) {
michael@0 302 if ("portrait".equals(aStr)) {
michael@0 303 return ScreenOrientation.PORTRAIT_PRIMARY;
michael@0 304 }
michael@0 305 else if ("landscape".equals(aStr)) {
michael@0 306 return ScreenOrientation.LANDSCAPE_PRIMARY;
michael@0 307 }
michael@0 308 else if ("portrait-primary".equals(aStr)) {
michael@0 309 return ScreenOrientation.PORTRAIT_PRIMARY;
michael@0 310 }
michael@0 311 else if ("portrait-secondary".equals(aStr)) {
michael@0 312 return ScreenOrientation.PORTRAIT_SECONDARY;
michael@0 313 }
michael@0 314 else if ("landscape-primary".equals(aStr)) {
michael@0 315 return ScreenOrientation.LANDSCAPE_PRIMARY;
michael@0 316 }
michael@0 317 else if ("landscape-secondary".equals(aStr)) {
michael@0 318 return ScreenOrientation.LANDSCAPE_SECONDARY;
michael@0 319 }
michael@0 320 Log.w(LOGTAG, "screenOrientationFromString: unknown orientation string");
michael@0 321 return DEFAULT_SCREEN_ORIENTATION;
michael@0 322 }
michael@0 323
michael@0 324 /*
michael@0 325 * Convert Gecko screen orientation to Android orientation.
michael@0 326 *
michael@0 327 * @param aScreenOrientation
michael@0 328 * Gecko screen orientation.
michael@0 329 * @return Android orientation. This conversion is lossy, the Android
michael@0 330 * orientation does not differentiate between primary and secondary
michael@0 331 * orientations.
michael@0 332 */
michael@0 333 public static int screenOrientationToAndroidOrientation(ScreenOrientation aScreenOrientation) {
michael@0 334 switch (aScreenOrientation) {
michael@0 335 case PORTRAIT_PRIMARY:
michael@0 336 case PORTRAIT_SECONDARY:
michael@0 337 return Configuration.ORIENTATION_PORTRAIT;
michael@0 338 case LANDSCAPE_PRIMARY:
michael@0 339 case LANDSCAPE_SECONDARY:
michael@0 340 return Configuration.ORIENTATION_LANDSCAPE;
michael@0 341 case NONE:
michael@0 342 case DEFAULT:
michael@0 343 default:
michael@0 344 return Configuration.ORIENTATION_UNDEFINED;
michael@0 345 }
michael@0 346 }
michael@0 347
michael@0 348
michael@0 349 /*
michael@0 350 * Convert Gecko screen orientation to Android ActivityInfo orientation.
michael@0 351 * This is yet another orientation used by Android, but it's more detailed
michael@0 352 * than the Android orientation.
michael@0 353 * It is required for screen orientation locking and unlocking.
michael@0 354 *
michael@0 355 * @param aScreenOrientation
michael@0 356 * Gecko screen orientation.
michael@0 357 * @return Android ActivityInfo orientation.
michael@0 358 */
michael@0 359 public static int screenOrientationToActivityInfoOrientation(ScreenOrientation aScreenOrientation) {
michael@0 360 switch (aScreenOrientation) {
michael@0 361 case PORTRAIT_PRIMARY:
michael@0 362 return ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
michael@0 363 case PORTRAIT_SECONDARY:
michael@0 364 return ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
michael@0 365 case LANDSCAPE_PRIMARY:
michael@0 366 return ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
michael@0 367 case LANDSCAPE_SECONDARY:
michael@0 368 return ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
michael@0 369 case DEFAULT:
michael@0 370 case NONE:
michael@0 371 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
michael@0 372 default:
michael@0 373 return ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
michael@0 374 }
michael@0 375 }
michael@0 376 }

mercurial