void setPara(CharSequence text, int start, int end, TextDirectionHeuristic textDir) {
   this.mText = text;
   this.mTextStart = start;
   int len = end - start;
   this.mLen = len;
   this.mPos = 0;
   if (this.mWidths == null || this.mWidths.length < len) {
     this.mWidths = ArrayUtils.newUnpaddedFloatArray(len);
   }
   if (this.mChars == null || this.mChars.length < len) {
     this.mChars = ArrayUtils.newUnpaddedCharArray(len);
   }
   TextUtils.getChars(text, start, end, this.mChars, 0);
   if (text instanceof Spanned) {
     Spanned spanned = (Spanned) text;
     ReplacementSpan[] spans =
         (ReplacementSpan[]) spanned.getSpans(start, end, ReplacementSpan.class);
     for (int i = 0; i < spans.length; i++) {
       int startInPara = spanned.getSpanStart(spans[i]) - start;
       int endInPara = spanned.getSpanEnd(spans[i]) - start;
       if (startInPara < 0) {
         startInPara = 0;
       }
       if (endInPara > len) {
         endInPara = len;
       }
       for (int j = startInPara; j < endInPara; j++) {
         this.mChars[j] = '\ufffc';
       }
     }
   }
   if ((textDir == TextDirectionHeuristics.LTR
           || textDir == TextDirectionHeuristics.FIRSTSTRONG_LTR
           || textDir == TextDirectionHeuristics.ANYRTL_LTR)
       && TextUtils.doesNotNeedBidi(this.mChars, 0, len)) {
     this.mDir = 1;
     this.mEasy = true;
     return;
   }
   int bidiRequest;
   if (this.mLevels == null || this.mLevels.length < len) {
     this.mLevels = ArrayUtils.newUnpaddedByteArray(len);
   }
   if (textDir == TextDirectionHeuristics.LTR) {
     bidiRequest = 1;
   } else if (textDir == TextDirectionHeuristics.RTL) {
     bidiRequest = -1;
   } else if (textDir == TextDirectionHeuristics.FIRSTSTRONG_LTR) {
     bidiRequest = 2;
   } else if (textDir == TextDirectionHeuristics.FIRSTSTRONG_RTL) {
     bidiRequest = -2;
   } else {
     bidiRequest = textDir.isRtl(this.mChars, 0, len) ? -1 : 1;
   }
   this.mDir = AndroidBidi.bidi(bidiRequest, this.mChars, this.mLevels, len, false);
   this.mEasy = false;
 }
 public void setInfo(String itemKey, boolean isVertical) {
   ButtonInfo item = NavbarEditor.buttonMap.get(itemKey);
   setTag(itemKey);
   final Resources res = getResources();
   setContentDescription(res.getString(item.contentDescription));
   mCode = item.keyCode;
   boolean isSmallButton = ArrayUtils.contains(NavbarEditor.smallButtonIds, getId());
   Drawable keyD;
   if (isSmallButton) {
     keyD = res.getDrawable(item.sideResource);
   } else if (!isVertical) {
     keyD = res.getDrawable(item.portResource);
   } else {
     keyD = res.getDrawable(item.landResource);
   }
   // Reason for setImageDrawable vs setImageResource is because setImageResource calls relayout()
   // w/o
   // any checks. setImageDrawable performs size checks and only calls relayout if necessary. We
   // rely on this
   // because otherwise the setX/setY attributes which are post layout cause it to mess up the
   // layout.
   setImageDrawable(keyD);
   if (itemKey.equals(NavbarEditor.NAVBAR_EMPTY)) {
     if (isSmallButton) {
       setVisibility(NavigationBarView.getEditMode() ? View.VISIBLE : View.INVISIBLE);
     } else {
       setVisibility(NavigationBarView.getEditMode() ? View.VISIBLE : View.GONE);
     }
   } else if (itemKey.equals(NavbarEditor.NAVBAR_CONDITIONAL_MENU)) {
     setVisibility(NavigationBarView.getEditMode() ? View.VISIBLE : View.INVISIBLE);
   } else if (itemKey.equals(NavbarEditor.NAVBAR_HOME)) {
     mSupportsLongpress = false;
   }
 }
Beispiel #3
0
  /**
   * Initializes a TextLine and prepares it for use.
   *
   * @param paint the base paint for the line
   * @param text the text, can be Styled
   * @param start the start of the line relative to the text
   * @param limit the limit of the line relative to the text
   * @param dir the paragraph direction of this line
   * @param directions the directions information of this line
   * @param hasTabs true if the line might contain tabs or emoji
   * @param tabStops the tabStops. Can be null.
   */
  void set(
      TextPaint paint,
      CharSequence text,
      int start,
      int limit,
      int dir,
      Directions directions,
      boolean hasTabs,
      TabStops tabStops) {
    mPaint = paint;
    mText = text;
    mStart = start;
    mLen = limit - start;
    mDir = dir;
    mDirections = directions;
    if (mDirections == null) {
      throw new IllegalArgumentException("Directions cannot be null");
    }
    mHasTabs = hasTabs;
    mSpanned = null;

    boolean hasReplacement = false;
    if (text instanceof Spanned) {
      mSpanned = (Spanned) text;
      mReplacementSpanSpanSet.init(mSpanned, start, limit);
      hasReplacement = mReplacementSpanSpanSet.numberOfSpans > 0;
    }

    mCharsValid = hasReplacement || hasTabs || directions != Layout.DIRS_ALL_LEFT_TO_RIGHT;

    if (mCharsValid) {
      if (mChars == null || mChars.length < mLen) {
        mChars = new char[ArrayUtils.idealCharArraySize(mLen)];
      }
      TextUtils.getChars(text, start, limit, mChars, 0);
      if (hasReplacement) {
        // Handle these all at once so we don't have to do it as we go.
        // Replace the first character of each replacement run with the
        // object-replacement character and the remainder with zero width
        // non-break space aka BOM.  Cursor movement code skips these
        // zero-width characters.
        char[] chars = mChars;
        for (int i = start, inext; i < limit; i = inext) {
          inext = mReplacementSpanSpanSet.getNextTransition(i, limit);
          if (mReplacementSpanSpanSet.hasSpansIntersecting(i, inext)) {
            // transition into a span
            chars[i - start] = '\ufffc';
            for (int j = i - start + 1, e = inext - start; j < e; ++j) {
              chars[j] = '\ufeff'; // used as ZWNBS, marks positions to skip
            }
          }
        }
      }
    }
    mTabs = tabStops;
  }
 private static List<VpnProfile> loadVpnProfiles(KeyStore keyStore, int... excludeTypes) {
   final ArrayList<VpnProfile> result = Lists.newArrayList();
   final String[] keys = keyStore.saw(Credentials.VPN);
   if (keys != null) {
     for (String key : keys) {
       final VpnProfile profile = VpnProfile.decode(key, keyStore.get(Credentials.VPN + key));
       if (profile != null && !ArrayUtils.contains(excludeTypes, profile.type)) {
         result.add(profile);
       }
     }
   }
   return result;
 }
  private void updateModeSummary() {
    int mode =
        Settings.System.getIntForUser(
            getContentResolver(),
            Settings.System.DISPLAY_TEMPERATURE_MODE,
            MODE_OFF,
            UserHandle.USER_CURRENT);

    int index = ArrayUtils.indexOf(mModeValues, String.valueOf(mode));
    mLiveDisplay.setSummary(mModeSummaries[index]);

    if (mDisplayTemperature != null) {
      mDisplayTemperature.setEnabled(mode != MODE_OFF);
    }
    if (mOutdoorMode != null) {
      mOutdoorMode.setEnabled(mode != MODE_OFF);
    }
  }
  private void updateHeaderList(List<Header> target) {
    final boolean showDev =
        mDevelopmentPreferences.getBoolean(
            DevelopmentSettings.PREF_SHOW,
            android.os.Build.TYPE.equals("eng") || android.os.Build.TYPE.equals("userdebug"));
    int i = 0;

    mHeaderIndexMap.clear();
    while (i < target.size()) {
      Header header = target.get(i);
      // Ids are integers, so downcasting
      int id = (int) header.id;
      if (id == R.id.operator_settings
          || id == R.id.manufacturer_settings
          || id == R.id.advanced_settings
          || id == R.id.hybrid_settings) {
        Utils.updateHeaderToSpecificActivityFromMetaDataOrRemove(this, target, header);
      } else if (id == R.id.launcher_settings) {
        Intent launcherIntent = new Intent(Intent.ACTION_MAIN);
        launcherIntent.addCategory(Intent.CATEGORY_HOME);
        launcherIntent.addCategory(Intent.CATEGORY_DEFAULT);

        Intent launcherPreferencesIntent = new Intent(Intent.ACTION_MAIN);
        launcherPreferencesIntent.addCategory("com.cyanogenmod.category.LAUNCHER_PREFERENCES");

        ActivityInfo defaultLauncher =
            getPackageManager()
                .resolveActivity(launcherIntent, PackageManager.MATCH_DEFAULT_ONLY)
                .activityInfo;
        launcherPreferencesIntent.setPackage(defaultLauncher.packageName);
        ResolveInfo launcherPreferences =
            getPackageManager().resolveActivity(launcherPreferencesIntent, 0);
        if (launcherPreferences != null) {
          header.intent =
              new Intent()
                  .setClassName(
                      launcherPreferences.activityInfo.packageName,
                      launcherPreferences.activityInfo.name);
        } else {
          target.remove(header);
        }
      } else if (id == R.id.wifi_settings) {
        // Remove WiFi Settings if WiFi service is not available.
        if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI)) {
          target.remove(i);
        }
      } else if (id == R.id.bluetooth_settings) {
        // Remove Bluetooth Settings if Bluetooth service is not available.
        if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)) {
          target.remove(i);
        }
      } else if (id == R.id.data_usage_settings) {
        // Remove data usage when kernel module not enabled
        final INetworkManagementService netManager =
            INetworkManagementService.Stub.asInterface(
                ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE));
        try {
          if (!netManager.isBandwidthControlEnabled()) {
            target.remove(i);
          }
        } catch (RemoteException e) {
          // ignored
        }
      } else if (id == R.id.account_settings) {
        int headerIndex = i + 1;
        i = insertAccountsHeaders(target, headerIndex);
      } else if (id == R.id.user_settings) {
        if (!UserHandle.MU_ENABLED
            || !UserManager.supportsMultipleUsers()
            || Utils.isMonkeyRunning()) {
          target.remove(i);
        }
      }

      if (target.get(i) == header
          && UserHandle.MU_ENABLED
          && UserHandle.myUserId() != 0
          && !ArrayUtils.contains(SETTINGS_FOR_RESTRICTED, id)) {
        target.remove(i);
      }

      // Increment if the current one wasn't removed by the Utils code.
      if (target.get(i) == header) {
        // Hold on to the first header, when we need to reset to the top-level
        if (mFirstHeader == null
            && HeaderAdapter.getHeaderType(header) != HeaderAdapter.HEADER_TYPE_CATEGORY) {
          mFirstHeader = header;
        }
        mHeaderIndexMap.put(id, i);
        i++;
      }
    }
  }
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    final Activity activity = getActivity();
    final ContentResolver resolver = activity.getContentResolver();
    final Resources res = getResources();

    mDefaultDayTemperature =
        res.getInteger(com.android.internal.R.integer.config_dayColorTemperature);
    mDefaultNightTemperature =
        res.getInteger(com.android.internal.R.integer.config_nightColorTemperature);

    mCmHardwareManager = (CmHardwareManager) activity.getSystemService(Context.CMHW_SERVICE);

    addPreferencesFromResource(R.xml.livedisplay);

    PreferenceCategory liveDisplayPrefs =
        (PreferenceCategory) findPreference(KEY_CATEGORY_LIVE_DISPLAY);
    PreferenceCategory calibrationPrefs =
        (PreferenceCategory) findPreference(KEY_CATEGORY_CALIBRATION);

    int displayMode =
        Settings.System.getIntForUser(
            resolver, Settings.System.DISPLAY_TEMPERATURE_MODE, 0, UserHandle.USER_CURRENT);
    mLiveDisplay = (ListPreference) findPreference(KEY_LIVE_DISPLAY);
    mLiveDisplay.setValue(String.valueOf(displayMode));

    mModeEntries = res.getStringArray(com.android.internal.R.array.live_display_entries);
    mModeValues = res.getStringArray(com.android.internal.R.array.live_display_values);
    mModeSummaries = res.getStringArray(com.android.internal.R.array.live_display_summaries);

    // Remove outdoor mode from lists if there is no support
    if (!mCmHardwareManager.isSupported(FEATURE_SUNLIGHT_ENHANCEMENT)) {
      int idx = ArrayUtils.indexOf(mModeValues, String.valueOf(MODE_OUTDOOR));
      String[] entriesTemp = new String[mModeEntries.length - 1];
      String[] valuesTemp = new String[mModeValues.length - 1];
      String[] summariesTemp = new String[mModeSummaries.length - 1];
      int j = 0;
      for (int i = 0; i < mModeEntries.length; i++) {
        if (i == idx) {
          continue;
        }
        entriesTemp[j] = mModeEntries[i];
        valuesTemp[j] = mModeValues[i];
        summariesTemp[j] = mModeSummaries[i];
        j++;
      }
      mModeEntries = entriesTemp;
      mModeValues = valuesTemp;
      mModeSummaries = summariesTemp;
    }

    mLiveDisplay.setEntries(mModeEntries);
    mLiveDisplay.setEntryValues(mModeValues);
    mLiveDisplay.setOnPreferenceChangeListener(this);

    mDisplayTemperature = (DisplayTemperature) findPreference(KEY_LIVE_DISPLAY_TEMPERATURE);

    mLowPower = (SwitchPreference) findPreference(KEY_LIVE_DISPLAY_LOW_POWER);
    if (liveDisplayPrefs != null
        && mLowPower != null
        && !mCmHardwareManager.isSupported(FEATURE_ADAPTIVE_BACKLIGHT)) {
      liveDisplayPrefs.removePreference(mLowPower);
      mLowPower = null;
    }

    mOutdoorMode = (SwitchPreference) findPreference(KEY_LIVE_DISPLAY_AUTO_OUTDOOR_MODE);
    if (liveDisplayPrefs != null
        && mOutdoorMode != null
        && !mCmHardwareManager.isSupported(FEATURE_SUNLIGHT_ENHANCEMENT)) {
      liveDisplayPrefs.removePreference(mOutdoorMode);
      mOutdoorMode = null;
    }

    mColorEnhancement = (SwitchPreference) findPreference(KEY_LIVE_DISPLAY_COLOR_ENHANCE);
    if (liveDisplayPrefs != null
        && mColorEnhancement != null
        && !mCmHardwareManager.isSupported(FEATURE_COLOR_ENHANCEMENT)) {
      liveDisplayPrefs.removePreference(mColorEnhancement);
      mColorEnhancement = null;
    }

    if (calibrationPrefs != null
        && !mCmHardwareManager.isSupported(FEATURE_DISPLAY_GAMMA_CALIBRATION)) {
      Preference gammaPref = findPreference(KEY_DISPLAY_GAMMA);
      if (gammaPref != null) {
        calibrationPrefs.removePreference(gammaPref);
      }
    }

    mScreenColorSettings = (PreferenceScreen) findPreference(KEY_SCREEN_COLOR_SETTINGS);
    if (calibrationPrefs != null) {
      if (!isPostProcessingSupported(getActivity()) && mScreenColorSettings != null) {
        calibrationPrefs.removePreference(mScreenColorSettings);
      } else if ("user".equals(Build.TYPE)) {
        // Remove simple RGB controls if HSIC controls are available
        Preference displayColor = findPreference(KEY_DISPLAY_COLOR);
        if (displayColor != null) {
          calibrationPrefs.removePreference(displayColor);
        }
      }
    }
  }
  @Override
  protected void engineInit(AlgorithmParameterSpec params, SecureRandom random)
      throws InvalidAlgorithmParameterException {
    resetAll();

    boolean success = false;
    try {
      if ((params == null) || (!(params instanceof KeyGenParameterSpec))) {
        throw new InvalidAlgorithmParameterException(
            "Cannot initialize without a " + KeyGenParameterSpec.class.getName() + " parameter");
      }
      KeyGenParameterSpec spec = (KeyGenParameterSpec) params;
      if (spec.getKeystoreAlias() == null) {
        throw new InvalidAlgorithmParameterException("KeyStore entry alias not provided");
      }

      mRng = random;
      mSpec = spec;

      mKeySizeBits = (spec.getKeySize() != -1) ? spec.getKeySize() : mDefaultKeySizeBits;
      if (mKeySizeBits <= 0) {
        throw new InvalidAlgorithmParameterException("Key size must be positive: " + mKeySizeBits);
      } else if ((mKeySizeBits % 8) != 0) {
        throw new InvalidAlgorithmParameterException(
            "Key size in must be a multiple of 8: " + mKeySizeBits);
      }

      try {
        mKeymasterPurposes = KeyProperties.Purpose.allToKeymaster(spec.getPurposes());
        mKeymasterPaddings =
            KeyProperties.EncryptionPadding.allToKeymaster(spec.getEncryptionPaddings());
        mKeymasterBlockModes = KeyProperties.BlockMode.allToKeymaster(spec.getBlockModes());
        if (((spec.getPurposes() & KeyProperties.PURPOSE_ENCRYPT) != 0)
            && (spec.isRandomizedEncryptionRequired())) {
          for (int keymasterBlockMode : mKeymasterBlockModes) {
            if (!KeymasterUtils.isKeymasterBlockModeIndCpaCompatible(keymasterBlockMode)) {
              throw new InvalidAlgorithmParameterException(
                  "Randomized encryption (IND-CPA) required but may be violated"
                      + " by block mode: "
                      + KeyProperties.BlockMode.fromKeymaster(keymasterBlockMode)
                      + ". See "
                      + KeyGenParameterSpec.class.getName()
                      + " documentation.");
            }
          }
        }
        if (spec.isDigestsSpecified()) {
          // Digest(s) explicitly specified in the spec
          mKeymasterDigests = KeyProperties.Digest.allToKeymaster(spec.getDigests());
          if (mKeymasterDigest != -1) {
            // Key algorithm implies a digest -- ensure it's specified in the spec as
            // first digest.
            if (!com.android.internal.util.ArrayUtils.contains(
                mKeymasterDigests, mKeymasterDigest)) {
              throw new InvalidAlgorithmParameterException(
                  "Digests specified in algorithm parameters ("
                      + Arrays.asList(spec.getDigests())
                      + ") must include "
                      + " the digest "
                      + KeyProperties.Digest.fromKeymaster(mKeymasterDigest)
                      + " implied by key algorithm");
            }
            if (mKeymasterDigests[0] != mKeymasterDigest) {
              // The first digest is not the one implied by the key algorithm.
              // Swap the implied digest with the first one.
              for (int i = 0; i < mKeymasterDigests.length; i++) {
                if (mKeymasterDigests[i] == mKeymasterDigest) {
                  mKeymasterDigests[i] = mKeymasterDigests[0];
                  mKeymasterDigests[0] = mKeymasterDigest;
                  break;
                }
              }
            }
          }
        } else {
          // No digest specified in the spec
          if (mKeymasterDigest != -1) {
            // Key algorithm implies a digest -- use that digest
            mKeymasterDigests = new int[] {mKeymasterDigest};
          } else {
            mKeymasterDigests = EmptyArray.INT;
          }
        }
        if (mKeymasterAlgorithm == KeymasterDefs.KM_ALGORITHM_HMAC) {
          if (mKeymasterDigests.length == 0) {
            throw new InvalidAlgorithmParameterException(
                "At least one digest algorithm must be specified");
          }
        }
      } catch (IllegalStateException | IllegalArgumentException e) {
        throw new InvalidAlgorithmParameterException(e);
      }

      success = true;
    } finally {
      if (!success) {
        resetAll();
      }
    }
  }
/** This class contains a metadata of suggestions from the text service */
public final class SuggestionsInfo implements Parcelable {
  private static final String[] EMPTY = ArrayUtils.emptyArray(String.class);

  /**
   * Flag of the attributes of the suggestions that can be obtained by {@link
   * #getSuggestionsAttributes}: this tells that the requested word was found in the dictionary in
   * the text service.
   */
  public static final int RESULT_ATTR_IN_THE_DICTIONARY = 0x0001;
  /**
   * Flag of the attributes of the suggestions that can be obtained by {@link
   * #getSuggestionsAttributes}: this tells that the text service thinks the requested word looks
   * like a typo.
   */
  public static final int RESULT_ATTR_LOOKS_LIKE_TYPO = 0x0002;
  /**
   * Flag of the attributes of the suggestions that can be obtained by {@link
   * #getSuggestionsAttributes}: this tells that the text service thinks the result suggestions
   * include highly recommended ones.
   */
  public static final int RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS = 0x0004;

  private final int mSuggestionsAttributes;
  private final String[] mSuggestions;
  private final boolean mSuggestionsAvailable;
  private int mCookie;
  private int mSequence;

  /**
   * Constructor.
   *
   * @param suggestionsAttributes from the text service
   * @param suggestions from the text service
   */
  public SuggestionsInfo(int suggestionsAttributes, String[] suggestions) {
    this(suggestionsAttributes, suggestions, 0, 0);
  }

  /**
   * Constructor.
   *
   * @param suggestionsAttributes from the text service
   * @param suggestions from the text service
   * @param cookie the cookie of the input TextInfo
   * @param sequence the cookie of the input TextInfo
   */
  public SuggestionsInfo(
      int suggestionsAttributes, String[] suggestions, int cookie, int sequence) {
    if (suggestions == null) {
      mSuggestions = EMPTY;
      mSuggestionsAvailable = false;
    } else {
      mSuggestions = suggestions;
      mSuggestionsAvailable = true;
    }
    mSuggestionsAttributes = suggestionsAttributes;
    mCookie = cookie;
    mSequence = sequence;
  }

  public SuggestionsInfo(Parcel source) {
    mSuggestionsAttributes = source.readInt();
    mSuggestions = source.readStringArray();
    mCookie = source.readInt();
    mSequence = source.readInt();
    mSuggestionsAvailable = source.readInt() == 1;
  }

  /**
   * Used to package this object into a {@link Parcel}.
   *
   * @param dest The {@link Parcel} to be written.
   * @param flags The flags used for parceling.
   */
  @Override
  public void writeToParcel(Parcel dest, int flags) {
    dest.writeInt(mSuggestionsAttributes);
    dest.writeStringArray(mSuggestions);
    dest.writeInt(mCookie);
    dest.writeInt(mSequence);
    dest.writeInt(mSuggestionsAvailable ? 1 : 0);
  }

  /**
   * Set the cookie and the sequence of SuggestionsInfo which are set to TextInfo from a client
   * application
   *
   * @param cookie the cookie of an input TextInfo
   * @param sequence the cookie of an input TextInfo
   */
  public void setCookieAndSequence(int cookie, int sequence) {
    mCookie = cookie;
    mSequence = sequence;
  }

  /** @return the cookie which may be set by a client application */
  public int getCookie() {
    return mCookie;
  }

  /** @return the sequence which may be set by a client application */
  public int getSequence() {
    return mSequence;
  }

  /**
   * @return the attributes of suggestions. This includes whether the spell checker has the word in
   *     its dictionary or not and whether the spell checker has confident suggestions for the word
   *     or not.
   */
  public int getSuggestionsAttributes() {
    return mSuggestionsAttributes;
  }

  /**
   * @return the count of the suggestions. If there's no suggestions at all, this method returns -1.
   *     Even if this method returns 0, it doesn't necessarily mean that there are no suggestions
   *     for the requested word. For instance, the caller could have been asked to limit the maximum
   *     number of suggestions returned.
   */
  public int getSuggestionsCount() {
    if (!mSuggestionsAvailable) {
      return -1;
    }
    return mSuggestions.length;
  }

  /**
   * @param i the id of suggestions
   * @return the suggestion at the specified id
   */
  public String getSuggestionAt(int i) {
    return mSuggestions[i];
  }

  /** Used to make this class parcelable. */
  public static final Creator<SuggestionsInfo> CREATOR =
      new Creator<SuggestionsInfo>() {
        @Override
        public SuggestionsInfo createFromParcel(Parcel source) {
          return new SuggestionsInfo(source);
        }

        @Override
        public SuggestionsInfo[] newArray(int size) {
          return new SuggestionsInfo[size];
        }
      };

  /** Used to make this class parcelable. */
  @Override
  public int describeContents() {
    return 0;
  }
}
 public void dump(Printer pw, String prefix) {
   super.dumpFront(pw, prefix);
   if (className != null) {
     pw.println(prefix + "className=" + className);
   }
   if (permission != null) {
     pw.println(prefix + "permission=" + permission);
   }
   pw.println(prefix + "processName=" + processName);
   pw.println(prefix + "taskAffinity=" + taskAffinity);
   pw.println(
       prefix
           + "uid="
           + uid
           + " flags=0x"
           + Integer.toHexString(flags)
           + " theme=0x"
           + Integer.toHexString(theme));
   pw.println(
       prefix
           + "requiresSmallestWidthDp="
           + requiresSmallestWidthDp
           + " compatibleWidthLimitDp="
           + compatibleWidthLimitDp
           + " largestWidthLimitDp="
           + largestWidthLimitDp);
   pw.println(prefix + "sourceDir=" + sourceDir);
   if (!Objects.equals(sourceDir, publicSourceDir)) {
     pw.println(prefix + "publicSourceDir=" + publicSourceDir);
   }
   if (!ArrayUtils.isEmpty(splitSourceDirs)) {
     pw.println(prefix + "splitSourceDirs=" + Arrays.toString(splitSourceDirs));
   }
   if (!ArrayUtils.isEmpty(splitPublicSourceDirs)
       && !Arrays.equals(splitSourceDirs, splitPublicSourceDirs)) {
     pw.println(prefix + "splitPublicSourceDirs=" + Arrays.toString(splitPublicSourceDirs));
   }
   if (resourceDirs != null) {
     pw.println(prefix + "resourceDirs=" + resourceDirs);
   }
   if (seinfo != null) {
     pw.println(prefix + "seinfo=" + seinfo);
   }
   pw.println(prefix + "dataDir=" + dataDir);
   if (sharedLibraryFiles != null) {
     pw.println(prefix + "sharedLibraryFiles=" + sharedLibraryFiles);
   }
   pw.println(
       prefix
           + "enabled="
           + enabled
           + " targetSdkVersion="
           + targetSdkVersion
           + " versionCode="
           + versionCode);
   if (manageSpaceActivityName != null) {
     pw.println(prefix + "manageSpaceActivityName=" + manageSpaceActivityName);
   }
   if (descriptionRes != 0) {
     pw.println(prefix + "description=0x" + Integer.toHexString(descriptionRes));
   }
   if (uiOptions != 0) {
     pw.println(prefix + "uiOptions=0x" + Integer.toHexString(uiOptions));
   }
   pw.println(prefix + "supportsRtl=" + (hasRtlSupport() ? "true" : "false"));
   super.dumpBack(pw, prefix);
 }
 public void addComponentFilter(ComponentName componentName, Rule rule) {
   Rule[] rules = mRulesByComponent.get(componentName);
   rules = ArrayUtils.appendElement(Rule.class, rules, rule);
   mRulesByComponent.put(componentName, rules);
 }
 public boolean exists(int userId) {
   synchronized (mPackagesLock) {
     return ArrayUtils.contains(mUserIds, userId);
   }
 }
 /**
  * Test if given {@link Signature} sets are exactly equal.
  *
  * @hide
  */
 public static boolean areExactMatch(Signature[] a, Signature[] b) {
   return (a.length == b.length) && ArrayUtils.containsAll(a, b) && ArrayUtils.containsAll(b, a);
 }