public boolean isBetterThan()

in resources/src/main/java/org/robolectric/res/android/ResTable_config.java [1179:1436]


  public boolean isBetterThan(
      ResTable_config o, ResTable_config requested) {
    if (isTruthy(requested)) {
      if (isTruthy(imsi()) || isTruthy(o.imsi())) {
        if ((mcc != o.mcc) && isTruthy(requested.mcc)) {
          return (isTruthy(mcc));
        }

        if ((mnc != o.mnc) && isTruthy(requested.mnc)) {
          return (isTruthy(mnc));
        }
      }

      if (isLocaleBetterThan(o, requested)) {
        return true;
      }

      if (isTruthy(screenLayout) || isTruthy(o.screenLayout)) {
        if (isTruthy((screenLayout^o.screenLayout) & MASK_LAYOUTDIR)
            && isTruthy(requested.screenLayout & MASK_LAYOUTDIR)) {
          int myLayoutDir = screenLayout & MASK_LAYOUTDIR;
          int oLayoutDir = o.screenLayout & MASK_LAYOUTDIR;
          return (myLayoutDir > oLayoutDir);
        }
      }

      if (isTruthy(smallestScreenWidthDp) || isTruthy(o.smallestScreenWidthDp)) {
        // The configuration closest to the actual size is best.
        // We assume that larger configs have already been filtered
        // out at this point.  That means we just want the largest one.
        if (smallestScreenWidthDp != o.smallestScreenWidthDp) {
          return smallestScreenWidthDp > o.smallestScreenWidthDp;
        }
      }

      if (isTruthy(screenSizeDp()) || isTruthy(o.screenSizeDp())) {
        // "Better" is based on the sum of the difference between both
        // width and height from the requested dimensions.  We are
        // assuming the invalid configs (with smaller dimens) have
        // already been filtered.  Note that if a particular dimension
        // is unspecified, we will end up with a large value (the
        // difference between 0 and the requested dimension), which is
        // good since we will prefer a config that has specified a
        // dimension value.
        int myDelta = 0, otherDelta = 0;
        if (isTruthy(requested.screenWidthDp)) {
          myDelta += requested.screenWidthDp - screenWidthDp;
          otherDelta += requested.screenWidthDp - o.screenWidthDp;
        }
        if (isTruthy(requested.screenHeightDp)) {
          myDelta += requested.screenHeightDp - screenHeightDp;
          otherDelta += requested.screenHeightDp - o.screenHeightDp;
        }

        if (myDelta != otherDelta) {
          return myDelta < otherDelta;
        }
      }

      if (isTruthy(screenLayout) || isTruthy(o.screenLayout)) {
        if (isTruthy((screenLayout^o.screenLayout) & MASK_SCREENSIZE)
            && isTruthy(requested.screenLayout & MASK_SCREENSIZE)) {
          // A little backwards compatibility here: undefined is
          // considered equivalent to normal.  But only if the
          // requested size is at least normal; otherwise, small
          // is better than the default.
          int mySL = (screenLayout & MASK_SCREENSIZE);
          int oSL = (o.screenLayout & MASK_SCREENSIZE);
          int fixedMySL = mySL;
          int fixedOSL = oSL;
          if ((requested.screenLayout & MASK_SCREENSIZE) >= SCREENSIZE_NORMAL) {
            if (fixedMySL == 0) fixedMySL = SCREENSIZE_NORMAL;
            if (fixedOSL == 0) fixedOSL = SCREENSIZE_NORMAL;
          }
          // For screen size, the best match is the one that is
          // closest to the requested screen size, but not over
          // (the not over part is dealt with in match() below).
          if (fixedMySL == fixedOSL) {
            // If the two are the same, but 'this' is actually
            // undefined, then the other is really a better match.
            if (mySL == 0) return false;
            return true;
          }
          if (fixedMySL != fixedOSL) {
            return fixedMySL > fixedOSL;
          }
        }
        if (((screenLayout^o.screenLayout) & MASK_SCREENLONG) != 0
            && isTruthy(requested.screenLayout & MASK_SCREENLONG)) {
          return isTruthy(screenLayout & MASK_SCREENLONG);
        }
      }

      if (isTruthy(screenLayout2) || isTruthy(o.screenLayout2)) {
        if (((screenLayout2^o.screenLayout2) & MASK_SCREENROUND) != 0 &&
            isTruthy(requested.screenLayout2 & MASK_SCREENROUND)) {
          return isTruthy(screenLayout2 & MASK_SCREENROUND);
        }
      }

      if (isTruthy(colorMode) || isTruthy(o.colorMode)) {
        if (((colorMode^o.colorMode) & MASK_WIDE_COLOR_GAMUT) != 0 &&
            isTruthy((requested.colorMode & MASK_WIDE_COLOR_GAMUT))) {
          return isTruthy(colorMode & MASK_WIDE_COLOR_GAMUT);
        }
        if (((colorMode^o.colorMode) & MASK_HDR) != 0 &&
            isTruthy((requested.colorMode & MASK_HDR))) {
          return isTruthy(colorMode & MASK_HDR);
        }
      }

      if ((orientation != o.orientation) && isTruthy(requested.orientation)) {
        return isTruthy(orientation);
      }

      if (isTruthy(uiMode) || isTruthy(o.uiMode)) {
        if (((uiMode^o.uiMode) & MASK_UI_MODE_TYPE) != 0
            && isTruthy(requested.uiMode & MASK_UI_MODE_TYPE)) {
          return isTruthy(uiMode & MASK_UI_MODE_TYPE);
        }
        if (((uiMode^o.uiMode) & MASK_UI_MODE_NIGHT) != 0
            && isTruthy(requested.uiMode & MASK_UI_MODE_NIGHT)) {
          return isTruthy(uiMode & MASK_UI_MODE_NIGHT);
        }
      }

      if (isTruthy(screenType()) || isTruthy(o.screenType())) {
        if (density != o.density) {
          // Use the system default density (DENSITY_MEDIUM, 160dpi) if none specified.
          final int thisDensity = isTruthy(density) ? density : DENSITY_MEDIUM;
          final int otherDensity = isTruthy(o.density) ? o.density : DENSITY_MEDIUM;

          // We always prefer DENSITY_ANY over scaling a density bucket.
          if (thisDensity == DENSITY_ANY) {
            return true;
          } else if (otherDensity == DENSITY_ANY) {
            return false;
          }

          int requestedDensity = requested.density;
          if (requested.density == 0 ||
              requested.density == DENSITY_ANY) {
            requestedDensity = DENSITY_MEDIUM;
          }

          // DENSITY_ANY is now dealt with. We should look to
          // pick a density bucket and potentially scale it.
          // Any density is potentially useful
          // because the system will scale it.  Scaling down
          // is generally better than scaling up.
          int h = thisDensity;
          int l = otherDensity;
          boolean bImBigger = true;
          if (l > h) {
            int t = h;
            h = l;
            l = t;
            bImBigger = false;
          }

          if (requestedDensity >= h) {
            // requested value higher than both l and h, give h
            return bImBigger;
          }
          if (l >= requestedDensity) {
            // requested value lower than both l and h, give l
            return !bImBigger;
          }
          // saying that scaling down is 2x better than up
          if (((2 * l) - requestedDensity) * h > requestedDensity * requestedDensity) {
            return !bImBigger;
          } else {
            return bImBigger;
          }
        }

        if ((touchscreen != o.touchscreen) && isTruthy(requested.touchscreen)) {
          return isTruthy(touchscreen);
        }
      }

      if (isTruthy(input()) || isTruthy(o.input())) {
            final int keysHidden = inputFlags & MASK_KEYSHIDDEN;
            final int oKeysHidden = o.inputFlags & MASK_KEYSHIDDEN;
        if (keysHidden != oKeysHidden) {
                final int reqKeysHidden =
              requested.inputFlags & MASK_KEYSHIDDEN;
          if (isTruthy(reqKeysHidden)) {

            if (keysHidden == 0) return false;
            if (oKeysHidden == 0) return true;
            // For compatibility, we count KEYSHIDDEN_NO as being
            // the same as KEYSHIDDEN_SOFT.  Here we disambiguate
            // these by making an exact match more specific.
            if (reqKeysHidden == keysHidden) return true;
            if (reqKeysHidden == oKeysHidden) return false;
          }
        }

            final int navHidden = inputFlags & MASK_NAVHIDDEN;
            final int oNavHidden = o.inputFlags & MASK_NAVHIDDEN;
        if (navHidden != oNavHidden) {
                final int reqNavHidden =
              requested.inputFlags & MASK_NAVHIDDEN;
          if (isTruthy(reqNavHidden)) {

            if (navHidden == 0) return false;
            if (oNavHidden == 0) return true;
          }
        }

        if ((keyboard != o.keyboard) && isTruthy(requested.keyboard)) {
          return isTruthy(keyboard);
        }

        if ((navigation != o.navigation) && isTruthy(requested.navigation)) {
          return isTruthy(navigation);
        }
      }

      if (isTruthy(screenSize()) || isTruthy(o.screenSize())) {
        // "Better" is based on the sum of the difference between both
        // width and height from the requested dimensions.  We are
        // assuming the invalid configs (with smaller sizes) have
        // already been filtered.  Note that if a particular dimension
        // is unspecified, we will end up with a large value (the
        // difference between 0 and the requested dimension), which is
        // good since we will prefer a config that has specified a
        // size value.
        int myDelta = 0, otherDelta = 0;
        if (isTruthy(requested.screenWidth)) {
          myDelta += requested.screenWidth - screenWidth;
          otherDelta += requested.screenWidth - o.screenWidth;
        }
        if (isTruthy(requested.screenHeight)) {
          myDelta += requested.screenHeight - screenHeight;
          otherDelta += requested.screenHeight - o.screenHeight;
        }
        if (myDelta != otherDelta) {
          return myDelta < otherDelta;
        }
      }

      if (isTruthy(version()) || isTruthy(o.version())) {
        if ((sdkVersion != o.sdkVersion) && isTruthy(requested.sdkVersion)) {
          return (sdkVersion > o.sdkVersion);
        }

        if ((minorVersion != o.minorVersion) &&
            isTruthy(requested.minorVersion)) {
          return isTruthy(minorVersion);
        }
      }

      return false;
    }
    return isMoreSpecificThan(o);
  }