Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b79bd0bd authored by David Anderson's avatar David Anderson Committed by Android (Google) Code Review
Browse files

Merge "Load /metadata/password_slots/slot_map lazily."

parents 81628828 f55f5d83
Loading
Loading
Loading
Loading
+28 −2
Original line number Original line Diff line number Diff line
@@ -52,10 +52,12 @@ public class PasswordSlotManager {
    // This maps each used password slot to the OS image that created it. Password slots are
    // This maps each used password slot to the OS image that created it. Password slots are
    // integer keys/indices into secure storage. The OS image is recorded as a string. The factory
    // integer keys/indices into secure storage. The OS image is recorded as a string. The factory
    // image is "host" and GSIs are "gsi<N>" where N >= 1.
    // image is "host" and GSIs are "gsi<N>" where N >= 1.
    private final Map<Integer, String> mSlotMap;
    private Map<Integer, String> mSlotMap;

    // Cache the active slots until loadSlotMap() is called.
    private Set<Integer> mActiveSlots;


    public PasswordSlotManager() {
    public PasswordSlotManager() {
        mSlotMap = loadSlotMap();
    }
    }


    @VisibleForTesting
    @VisibleForTesting
@@ -74,6 +76,11 @@ public class PasswordSlotManager {
     * @throws RuntimeException
     * @throws RuntimeException
     */
     */
    public void refreshActiveSlots(Set<Integer> activeSlots) throws RuntimeException {
    public void refreshActiveSlots(Set<Integer> activeSlots) throws RuntimeException {
        if (mSlotMap == null) {
            mActiveSlots = new HashSet<Integer>(activeSlots);
            return;
        }

        // Update which slots are owned by the current image.
        // Update which slots are owned by the current image.
        final HashSet<Integer> slotsToDelete = new HashSet<Integer>();
        final HashSet<Integer> slotsToDelete = new HashSet<Integer>();
        for (Map.Entry<Integer, String> entry : mSlotMap.entrySet()) {
        for (Map.Entry<Integer, String> entry : mSlotMap.entrySet()) {
@@ -100,6 +107,7 @@ public class PasswordSlotManager {
     * @throws RuntimeException
     * @throws RuntimeException
     */
     */
    public void markSlotInUse(int slot) throws RuntimeException {
    public void markSlotInUse(int slot) throws RuntimeException {
        ensureSlotMapLoaded();
        if (mSlotMap.containsKey(slot) && !mSlotMap.get(slot).equals(getMode())) {
        if (mSlotMap.containsKey(slot) && !mSlotMap.get(slot).equals(getMode())) {
            throw new RuntimeException("password slot " + slot + " is not available");
            throw new RuntimeException("password slot " + slot + " is not available");
        }
        }
@@ -113,6 +121,7 @@ public class PasswordSlotManager {
     * @throws RuntimeException
     * @throws RuntimeException
     */
     */
    public void markSlotDeleted(int slot) throws RuntimeException {
    public void markSlotDeleted(int slot) throws RuntimeException {
        ensureSlotMapLoaded();
        if (mSlotMap.containsKey(slot) && mSlotMap.get(slot) != getMode()) {
        if (mSlotMap.containsKey(slot) && mSlotMap.get(slot) != getMode()) {
            throw new RuntimeException("password slot " + slot + " cannot be deleted");
            throw new RuntimeException("password slot " + slot + " cannot be deleted");
        }
        }
@@ -126,6 +135,7 @@ public class PasswordSlotManager {
     * @return Integer set of all used slots.
     * @return Integer set of all used slots.
     */
     */
    public Set<Integer> getUsedSlots() {
    public Set<Integer> getUsedSlots() {
        ensureSlotMapLoaded();
        return Collections.unmodifiableSet(mSlotMap.keySet());
        return Collections.unmodifiableSet(mSlotMap.keySet());
    }
    }


@@ -167,8 +177,21 @@ public class PasswordSlotManager {
        return new HashMap<Integer, String>();
        return new HashMap<Integer, String>();
    }
    }


    private void ensureSlotMapLoaded() {
        if (mSlotMap == null) {
            mSlotMap = loadSlotMap();
            if (mActiveSlots != null) {
                refreshActiveSlots(mActiveSlots);
                mActiveSlots = null;
            }
        }
    }

    @VisibleForTesting
    @VisibleForTesting
    protected void saveSlotMap(OutputStream stream) throws IOException {
    protected void saveSlotMap(OutputStream stream) throws IOException {
        if (mSlotMap == null) {
            return;
        }
        final Properties props = new Properties();
        final Properties props = new Properties();
        for (Map.Entry<Integer, String> entry : mSlotMap.entrySet()) {
        for (Map.Entry<Integer, String> entry : mSlotMap.entrySet()) {
            props.setProperty(entry.getKey().toString(), entry.getValue());
            props.setProperty(entry.getKey().toString(), entry.getValue());
@@ -177,6 +200,9 @@ public class PasswordSlotManager {
    }
    }


    private void saveSlotMap() {
    private void saveSlotMap() {
        if (mSlotMap == null) {
            return;
        }
        if (!getSlotMapFile().getParentFile().exists()) {
        if (!getSlotMapFile().getParentFile().exists()) {
            Slog.w(TAG, "Not saving slot map, " + getSlotMapDir() + " does not exist");
            Slog.w(TAG, "Not saving slot map, " + getSlotMapDir() + " does not exist");
            return;
            return;