Android Open Source - android_device Screen Impl






From Project

Back to project page android_device.

License

The source code is released under:

[Apache License](http://www.apache.org/licenses/): Version 2.0, January 2004 =============== ## TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION ## ### 1. Definitions. ### "License" sha...

If you think the Android project android_device listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 * =================================================================================================
 *                Copyright (C) 2012 - 2014 Martin Albedinsky [Wolf-ITechnologies]
 * =================================================================================================
 *         Licensed under the Apache License, Version 2.0 or later (further "License" only).
 * -------------------------------------------------------------------------------------------------
 * You may use this file only in compliance with the License. More details and copy of this License
 * you may obtain at/*ww  w .j a  va2  s .co m*/
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * You can redistribute, modify or publish any part of the code written within this file but as it
 * is described in the License, the software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES or CONDITIONS OF ANY KIND.
 *
 * See the License for the specific language governing permissions and limitations under the License.
 * =================================================================================================
 */
package com.wit.android.device;

import android.app.Activity;
import android.content.Context;
import android.content.res.Configuration;
import android.os.PowerManager;
import android.provider.Settings.SettingNotFoundException;
import android.provider.Settings.System;
import android.support.annotation.NonNull;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.Window;
import android.view.WindowManager;

/**
 * <h3>Class Overview</h3>
 * Implementation of {@link com.wit.android.device.Screen} wrapper for {@link com.wit.android.device.AndroidDevice AndroidDevice}.
 *
 * @author Martin Albedinsky
 */
final class ScreenImpl implements Screen {

  /**
   * Interface ===================================================================================
   */

  /**
   * Constants ===================================================================================
   */

  /**
   * Log TAG.
   */
  private static final String TAG = "ScreenImpl";

  /**
   * Flag indicating whether the debug output trough log-cat is enabled or not.
   */
  private static final boolean DEBUG_ENABLED = DeviceConfig.LIBRARY_DEBUG_LOG_ENABLED;

  /**
   * Flag indicating whether the output trough log-cat is enabled or not.
   */
  private static final boolean LOG_ENABLED = DeviceConfig.LIBRARY_LOG_ENABLED;

  /**
   * Static members ==============================================================================
   */

  /**
   * Members =====================================================================================
   */

  /**
   * Display metrics.
   */
  private final DisplayMetrics METRICS = new DisplayMetrics();

  /**
   * Application context obtained from the context passed during initialization of this wrapper.
   */
  private final Context mContext;

  /**
   * "Default" width of the current Android device's screen.
   */
  private final int mWidth;

  /**
   * "Default" height of the current Android device's screen.
   */
  private final int mHeight;

  /**
   * Window manager service.
   */
  private final WindowManager mWindowManager;

  /**
   * Default orientation of the current Android device's screen.
   */
  private final ScreenOrientation mDefaultOrientation;

  /**
   * Type of the current Android device's screen.
   */
  private ScreenType mType = ScreenType.UNKNOWN;

  /**
   * Density of the current Android device's screen.
   */
  private ScreenDensity mDensity = ScreenDensity.UNKNOWN;

  /**
   * Raw density of the current Android device's screen.
   */
  private int mRawDensity = -1;

  /**
   * Actual orientation of the current Android device's screen.
   */
  private ScreenOrientation mCurrentOrientation = ScreenOrientation.UNSPECIFIED;

  /**
   * Actual rotation of the current Android device's screen.
   */
  private ScreenRotation mCurrentRotation = ScreenRotation.UNKNOWN;

  /**
   * Actual width of the current Android device's screen. Depends on the actual screen orientation.
   */
  private int mCurrentWidth = 0;

  /**
   * Actual height of the current Android device's screen. Depends on the actual screen orientation.
   */
  private int mCurrentHeight = 0;

  /**
   * Flag indicating whether the current Android device's screen orientation is currently locked or
   * not.
   */
  private boolean mOrientationLocked;

  /**
   * Constructors ================================================================================
   */

  /**
   * Creates a new instance of ScreenImpl wrapper with already prepared screen data to access.
   *
   * @param context Application context or activity context.
   */
  ScreenImpl(Context context) {
    this.mContext = context.getApplicationContext();

    // Initialize window manager.
    this.mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);

    // Initialize data to new ones.
    this.refresh();

    // Initialize screen default orientation.
    this.mDefaultOrientation = this.resolveDefaultOrientation(mCurrentOrientation, mCurrentRotation);

    // Initialize screen density.
    this.mDensity = ScreenDensity.resolve(mRawDensity = METRICS.densityDpi);

    // Initialize screen type.
    this.mType = resolveScreenType(mCurrentOrientation);

    // Resolve actual screen metrics.
    boolean reverse = false;
    switch (mDefaultOrientation) {
      case PORTRAIT:
        reverse = mCurrentOrientation != ScreenOrientation.PORTRAIT && mCurrentOrientation != ScreenOrientation.REVERSE_PORTRAIT;
        break;
      case LANDSCAPE:
        reverse = mCurrentOrientation != ScreenOrientation.LANDSCAPE && mCurrentOrientation != ScreenOrientation.REVERSE_LANDSCAPE;
        break;
    }

    // Initialize display actual width and height.
    this.mCurrentWidth = METRICS.widthPixels;
    this.mCurrentHeight = METRICS.heightPixels;

    this.mWidth = reverse ? mCurrentHeight : mCurrentWidth;
    this.mHeight = reverse ? mCurrentWidth : mCurrentHeight;
  }

  /**
   * Public --------------------------------------------------------------------------------------
   */

  /**
   */
  @Override
  public boolean isOn() {
    final PowerManager power = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
    return power != null && power.isScreenOn();
  }

  /**
   */
  @Override
  public boolean lockOrientation(@NonNull Activity activity) {
    return requestOrientation(ScreenOrientation.CURRENT, activity);
  }

  /**
   */
  @Override
  public void unlockOrientation(@NonNull Activity activity) {
    requestOrientation(ScreenOrientation.USER, activity);
  }

  /**
   */
  @Override
  public boolean requestOrientation(@NonNull ScreenOrientation requestedOrientation, @NonNull Activity activity) {
    if (DEBUG_ENABLED) {
      Log.d(TAG, "requestOrientation(requestedOrientation = " + requestedOrientation + ", " + activity + ")");
    }

    // Request for screen orientation.
    this.requestOrientationInner(
        requestedOrientation != ScreenOrientation.CURRENT ? requestedOrientation : (requestedOrientation = getCurrentOrientation()),
        activity
    );
    return mOrientationLocked = (requestedOrientation != ScreenOrientation.USER);
  }

  /**
   * Getters + Setters ---------------------------------------------------------------------------
   */

  /**
   */
  @Override
  public Display getDisplay() {
    return mWindowManager.getDefaultDisplay();
  }

  /**
   */
  @Override
  public int getWidth() {
    return mWidth;
  }

  /**
   */
  @Override
  public int getHeight() {
    return mHeight;
  }

  /**
   */
  @Override
  public int getCurrentWidth() {
    refresh();
    return mCurrentWidth;
  }

  /**
   */
  @Override
  public int getCurrentHeight() {
    refresh();
    return mCurrentHeight;
  }

  /**
   */
  @NonNull
  @Override
  public DisplayMetrics getMetrics() {
    refresh();
    return METRICS;
  }

  /**
   */
  @NonNull
  @Override
  public ScreenDensity getDensity() {
    return mDensity;
  }

  /**
   */
  @Override
  public int getRawDensity() {
    return mRawDensity;
  }

  /**
   */
  @NonNull
  @Override
  public ScreenType getType() {
    return mType;
  }

  /**
   */
  @NonNull
  @Override
  public ScreenOrientation getCurrentOrientation() {
    refresh();
    return mCurrentOrientation;
  }

  /**
   */
  @NonNull
  @Override
  public ScreenOrientation getDefaultOrientation() {
    return mDefaultOrientation;
  }

  /**
   */
  @NonNull
  @Override
  public ScreenRotation getCurrentRotation() {
    refresh();
    return mCurrentRotation;
  }

  /**
   */
  @Override
  public float getDiagonalDistance(boolean inInches) {
    refresh();
    return inInches ?
        /**
         * Calculation in inches will depends on the exact pixel per inch in each axis (x and y) of the device display.
         */
        (float) Math.sqrt(Math.pow((mWidth / METRICS.xdpi), 2) + Math.pow((mHeight / METRICS.ydpi), 2)) :
        /**
         * Calculation in raw pixels.
         */
        (float) Math.sqrt(Math.pow(mWidth, 2) + Math.pow(mHeight, 2));
  }

  /**
   */
  @Override
  public float getRefreshRate() {
    return getDisplay().getRefreshRate();
  }

  /**
   */
  @Override
  public int getBrightness(@NonNull Activity activity) {
    if (activity != null) {
      final Window window = activity.getWindow();
      if (window != null) {
        // Get the brightness from the current application window settings.
        return Math.round(window.getAttributes().screenBrightness * 100);
      } else {
        if (LOG_ENABLED)
          Log.v(TAG, "Passed activity window is invalid. Can't obtain its brightness.");
      }
    }
    return -100;
  }

  /**
   */
  @Override
  public void setBrightness(int brightness, @NonNull Activity activity) {
    if (brightness < 0 || brightness > 100) {
      throw new IllegalArgumentException("Brightness value(" + brightness + ") out of the range [0, 100].");
    }
    // Create new window parameters.
    final Window window = activity.getWindow();
    WindowManager.LayoutParams layoutParams = window.getAttributes();
    layoutParams.screenBrightness = ((brightness == 0) ? ++brightness : brightness) / 100f;
    // Set new brightness to the current application window.
    window.setAttributes(layoutParams);
  }

  /**
   */
  @Override
  public int getSystemBrightness() {
    float brightness = 0;
    try {
      brightness = System.getInt(mContext.getContentResolver(), System.SCREEN_BRIGHTNESS);
    } catch (SettingNotFoundException e) {
      e.printStackTrace();
    }
    return Math.round(brightness / 255 * 100);
  }

  /**
   */
  @Override
  public boolean isOrientationLocked() {
    return mOrientationLocked;
  }

  /**
   */
  @Override
  public float pixelToDP(int pixel) {
    // From the Android developers documentation:
    // px = dp * (dpi / 160)
    // So modified equation is:
    // dp = px / (dpi / 160)
    return (pixel / (mDensity.value / 160));
  }

  /**
   */
  @Override
  public float dpToPixel(int dp) {
    // From the Android developers documentation:
    // px = dp * (dpi / 160)
    return (dp * (mDensity.value / 160));
  }

  /**
   */
  @Override
  public float getScreenDP() {
    // From the Android developers documentation:
    // The density-independent pixel is equivalent to one physical pixel on
    // a 160 dpi screen, which is the baseline density assumed by the system
    // for a "medium" density screen.
    // px = dp * (dpi / 160)
    // So modified equation is:
    // dp = px / (dpi / 160)
    // and finally to determine for 1 px:
    return (mDensity.value / 160);
  }

  /**
   * Protected -----------------------------------------------------------------------------------
   */

  /**
   * Private -------------------------------------------------------------------------------------
   */

  /**
   * Called to refresh the current data of this screen wrapper instance. This should be called whenever
   * the current data are requested.
   */
  private void refresh() {
    // Reinitialize display metrics to new ones.
    this.initNewMetrics();

    // Refresh when:
    // 1) screen orientation change occurred
    if (mCurrentWidth != METRICS.widthPixels || mCurrentHeight != METRICS.heightPixels) {
      onRefresh();
    }
  }

  /**
   * Invoked to refresh/update the current data. This is invoked only in case, that the current
   * Android device's screen orientation was changed.
   */
  private void onRefresh() {
    // Update orientation to the actual.
    // This call also updates the screen rotation.
    updateOrientation();

    if (DEBUG_ENABLED) {
      Log.d(TAG, "onRefresh() orientation(" + mCurrentOrientation + ")");
      Log.d(TAG, "onRefresh() rotation(" + mCurrentRotation + ")");
      Log.d(TAG, "onRefresh() actualWidth(" + METRICS.widthPixels + ") actualHeight(" + METRICS.heightPixels + ")");
    }

    // Get screen metrics to handle actual ones.
    this.mCurrentWidth = METRICS.widthPixels;
    this.mCurrentHeight = METRICS.heightPixels;
  }

  /**
   * Requests for the given screen <var>orientation</var>.
   *
   * @param orientation Requested orientation.
   * @param activity    The actual (visible) activity context.
   */
  private void requestOrientationInner(ScreenOrientation orientation, Activity activity) {
    // Resolve request.
    switch (orientation) {
      case SQUARE:
      case UNSPECIFIED:
        // In case of SQUARE and UNKNOWN oriented screen we can't do nothing useful :).
        break;
      case CURRENT:
      default:
        // Request for screen orientation.
        activity.setRequestedOrientation(orientation.systemConstant);
        break;
    }
  }

  /**
   * Initializes new display metrics to obtain actual ones.
   */
  private void initNewMetrics() {
    // Initialize new display metrics to get the useful data about device display.
    getDisplay().getMetrics(METRICS);
  }

  /**
   * Resolves the current Android device's screen type.
   *
   * @param orientation Actual screen orientation.
   * @return Resolved type of the screen.
   */
  private ScreenType resolveScreenType(ScreenOrientation orientation) {
    // Get display width and height in dp units depends on actual orientation.
    float defaultWidthDP, defaultHeightDP;
    switch (orientation) {
      case LANDSCAPE:
      case REVERSE_LANDSCAPE:
        defaultWidthDP = pixelToDP(METRICS.heightPixels);
        defaultHeightDP = pixelToDP(METRICS.widthPixels);
        break;
      case PORTRAIT:
      case REVERSE_PORTRAIT:
        defaultWidthDP = pixelToDP(METRICS.widthPixels);
        defaultHeightDP = pixelToDP(METRICS.heightPixels);
        break;
      case SQUARE:
      case UNSPECIFIED:
      default:
        defaultWidthDP = pixelToDP(METRICS.widthPixels);
        defaultHeightDP = pixelToDP(METRICS.heightPixels);
        break;
    }
    if (DEBUG_ENABLED) {
      Log.d(TAG, "resolveScreenType() defaultWidthDP = " + defaultWidthDP + "; defaultHeightDP = " + defaultHeightDP);
    }
    return ScreenType.resolve(defaultWidthDP, defaultHeightDP);
  }

  /**
   * Resolves the current Android device's screen default orientation.
   *
   * @param currentOrientation The current screen orientation.
   * @param currentRotation    The current screen rotation.
   * @return Default screen orientation depends on the given parameters.
   */
  private ScreenOrientation resolveDefaultOrientation(ScreenOrientation currentOrientation, ScreenRotation currentRotation) {
    ScreenOrientation orientation = ScreenOrientation.UNSPECIFIED;
    switch (currentRotation) {
      case ROTATION_0:
      case ROTATION_180:
        switch (currentOrientation) {
          case LANDSCAPE:
          case REVERSE_LANDSCAPE:
            orientation = ScreenOrientation.LANDSCAPE;
            break;
          case PORTRAIT:
          case REVERSE_PORTRAIT:
            orientation = ScreenOrientation.PORTRAIT;
            break;
          default:
        }
        break;
      case ROTATION_90:
      case ROTATION_270:
        switch (currentOrientation) {
          case LANDSCAPE:
          case REVERSE_LANDSCAPE:
            orientation = ScreenOrientation.PORTRAIT;
            break;
          case PORTRAIT:
          case REVERSE_PORTRAIT:
            orientation = ScreenOrientation.LANDSCAPE;
            break;
          default:
        }
        break;
      default:
    }
    return orientation;
  }

  /**
   * Updates the current screen orientation to the actual one. This make difference between phone
   * and tablet screen rotation in degrees so we can find out reversed orientations. Also updates
   * the screen rotation to the actual one.
   *
   * @return Updated screen orientation.
   */
  private ScreenOrientation updateOrientation() {
    // Default initialization.
    ScreenOrientation orientation = ScreenOrientation.UNSPECIFIED;

    // Get actual screen rotation to resolve difference between phone and
    // tablet device.
    final ScreenRotation rotation = updateRotation();

    // Resolve actual screen orientation from configuration.
    switch (mContext.getResources().getConfiguration().orientation) {
      case Configuration.ORIENTATION_LANDSCAPE:
        // Check screen rotation.
        switch (rotation) {
          case ROTATION_0:
            // Tablet in landscape mode.
          case ROTATION_90:
            // Phone in landscape mode.
            orientation = ScreenOrientation.LANDSCAPE;
            break;
          case ROTATION_180:
            // Tablet in reverse landscape mode.
          case ROTATION_270:
            // Phone in reverse landscape mode.
            orientation = ScreenOrientation.REVERSE_LANDSCAPE;
            break;
        }
        break;
      case Configuration.ORIENTATION_PORTRAIT:
        // Check screen rotation.
        switch (rotation) {
          case ROTATION_0:
            // Phone in portrait mode.
          case ROTATION_270:
            // Tablet in portrait mode.
            orientation = ScreenOrientation.PORTRAIT;
            break;
          case ROTATION_90:
            // Tablet in reverse portrait mode.
          case ROTATION_180:
            // Phone in reverse portrait mode.
            orientation = ScreenOrientation.REVERSE_PORTRAIT;
            break;
        }
        break;
      case Configuration.ORIENTATION_UNDEFINED:
      default:
        break;
    }
    return this.mCurrentOrientation = orientation;
  }

  /**
   * Updates the current screen rotation to the actual one.
   *
   * @return Updated screen rotation.
   */
  private ScreenRotation updateRotation() {
    // Resolve by rotation obtained from display.
    return mCurrentRotation = ScreenRotation.resolve(getDisplay().getRotation());
  }

  /**
   * Inner classes ===============================================================================
   */
}




Java Source Code List

com.wit.android.device.AndroidDevice.java
com.wit.android.device.BatteryImpl.java
com.wit.android.device.Battery.java
com.wit.android.device.ConnectionImpl.java
com.wit.android.device.Connection.java
com.wit.android.device.DeviceConfig.java
com.wit.android.device.ScreenImpl.java
com.wit.android.device.Screen.java
com.wit.android.device.StorageAction.java
com.wit.android.device.StorageImpl.java
com.wit.android.device.Storage.java
com.wit.android.device.examples.HomeActivity.java
com.wit.android.device.examples.adapter.BatteryInfoAdapter.java
com.wit.android.device.examples.adapter.ConnectionInfoAdapter.java
com.wit.android.device.examples.adapter.FilesAdapter.java
com.wit.android.device.examples.adapter.OrientationsAdapter.java
com.wit.android.device.examples.adapter.SimpleInfoAdapter.java
com.wit.android.device.examples.adapter.StorageAdapter.java
com.wit.android.device.examples.dialog.NewFileDialog.java
com.wit.android.device.examples.fragment.BaseDeviceFragment.java
com.wit.android.device.examples.fragment.BatteryInfoFragment.java
com.wit.android.device.examples.fragment.ConnectionInfoFragment.java
com.wit.android.device.examples.fragment.DeviceInfoFragment.java
com.wit.android.device.examples.fragment.FragmentsFactory.java
com.wit.android.device.examples.fragment.ScreenInfoFragment.java
com.wit.android.device.examples.fragment.ScreenInterfaceFragment.java
com.wit.android.device.examples.fragment.StorageFilesFragment.java
com.wit.android.device.examples.fragment.StorageInfoFragment.java
com.wit.android.device.examples.fragment.StorageInterfaceFragment.java
com.wit.android.device.examples.model.BatteryInfo.java
com.wit.android.device.examples.model.ConnectionInfo.java
com.wit.android.device.examples.model.SimpleInfo.java
com.wit.android.device.examples.model.StorageItem.java
com.wit.android.device.examples.module.StorageAssistant.java
com.wit.android.device.receiver.BatteryHealthReceiver.java
com.wit.android.device.receiver.BatteryPluggedStateReceiver.java
com.wit.android.device.receiver.BatteryStatusReceiver.java
com.wit.android.device.receiver.BroadcastProcessor.java
com.wit.android.device.receiver.ConnectionStateReceiver.java
com.wit.android.device.util.ConnectionUtils.java
com.wit.android.device.util.ScreenUtils.java
com.wit.android.device.util.StorageEditor.java
com.wit.android.device.util.StorageUtils.java