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

Commit 719e6b16 authored by Craig Mautner's avatar Craig Mautner
Browse files

Introduce PersistableBundle

The PersistableBundle class is similar to Bundle except that only
objects that have meaning across reboots can be stored and there
is a limited number of types that can be stored. More
specifically Binders, FileDescriptors, Parcelables, Booleans,
Bytes, Shorts, Chars, CharSequences, Floats, and ArrayLists
cannot be stored.

Fixes bug 13736007.

Change-Id: If6595b2e6fd92af6b7f60c4f7140ae867c258794
parent caeaa375
Loading
Loading
Loading
Loading
+56 −1
Original line number Diff line number Diff line
@@ -19254,11 +19254,12 @@ package android.os {
    field public static final int L = 10000; // 0x2710
  }
  public final class Bundle implements java.lang.Cloneable android.os.Parcelable {
  public final class Bundle extends android.os.CommonBundle {
    ctor public Bundle();
    ctor public Bundle(java.lang.ClassLoader);
    ctor public Bundle(int);
    ctor public Bundle(android.os.Bundle);
    ctor public Bundle(android.os.PersistableBundle);
    method public void clear();
    method public java.lang.Object clone();
    method public boolean containsKey(java.lang.String);
@@ -19296,6 +19297,7 @@ package android.os {
    method public T getParcelable(java.lang.String);
    method public android.os.Parcelable[] getParcelableArray(java.lang.String);
    method public java.util.ArrayList<T> getParcelableArrayList(java.lang.String);
    method public android.os.PersistableBundle getPersistableBundle(java.lang.String);
    method public java.io.Serializable getSerializable(java.lang.String);
    method public short getShort(java.lang.String);
    method public short getShort(java.lang.String, short);
@@ -19309,6 +19311,7 @@ package android.os {
    method public boolean isEmpty();
    method public java.util.Set<java.lang.String> keySet();
    method public void putAll(android.os.Bundle);
    method public void putAll(android.os.PersistableBundle);
    method public void putBinder(java.lang.String, android.os.IBinder);
    method public void putBoolean(java.lang.String, boolean);
    method public void putBooleanArray(java.lang.String, boolean[]);
@@ -19332,6 +19335,7 @@ package android.os {
    method public void putParcelable(java.lang.String, android.os.Parcelable);
    method public void putParcelableArray(java.lang.String, android.os.Parcelable[]);
    method public void putParcelableArrayList(java.lang.String, java.util.ArrayList<? extends android.os.Parcelable>);
    method public void putPersistableBundle(java.lang.String, android.os.PersistableBundle);
    method public void putSerializable(java.lang.String, java.io.Serializable);
    method public void putShort(java.lang.String, short);
    method public void putShortArray(java.lang.String, short[]);
@@ -19360,6 +19364,9 @@ package android.os {
    method public abstract void onCancel();
  }
   abstract class CommonBundle implements java.lang.Cloneable android.os.Parcelable {
  }
  public class ConditionVariable {
    ctor public ConditionVariable();
    ctor public ConditionVariable(boolean);
@@ -19786,6 +19793,8 @@ package android.os {
    method public final void readMap(java.util.Map, java.lang.ClassLoader);
    method public final T readParcelable(java.lang.ClassLoader);
    method public final android.os.Parcelable[] readParcelableArray(java.lang.ClassLoader);
    method public final android.os.PersistableBundle readPersistableBundle();
    method public final android.os.PersistableBundle readPersistableBundle(java.lang.ClassLoader);
    method public final java.io.Serializable readSerializable();
    method public final android.util.SparseArray readSparseArray(java.lang.ClassLoader);
    method public final android.util.SparseBooleanArray readSparseBooleanArray();
@@ -19826,6 +19835,7 @@ package android.os {
    method public final void writeNoException();
    method public final void writeParcelable(android.os.Parcelable, int);
    method public final void writeParcelableArray(T[], int);
    method public final void writePersistableBundle(android.os.PersistableBundle);
    method public final void writeSerializable(java.io.Serializable);
    method public final void writeSparseArray(android.util.SparseArray<java.lang.Object>);
    method public final void writeSparseBooleanArray(android.util.SparseBooleanArray);
@@ -19936,6 +19946,51 @@ package android.os {
    field public static final int PATTERN_SIMPLE_GLOB = 2; // 0x2
  }
  public final class PersistableBundle extends android.os.CommonBundle {
    ctor public PersistableBundle();
    ctor public PersistableBundle(java.lang.ClassLoader);
    ctor public PersistableBundle(int);
    ctor public PersistableBundle(android.os.PersistableBundle);
    method public void clear();
    method public java.lang.Object clone();
    method public boolean containsKey(java.lang.String);
    method public int describeContents();
    method public java.lang.Object get(java.lang.String);
    method public java.lang.ClassLoader getClassLoader();
    method public double getDouble(java.lang.String);
    method public double getDouble(java.lang.String, double);
    method public double[] getDoubleArray(java.lang.String);
    method public int getInt(java.lang.String);
    method public int getInt(java.lang.String, int);
    method public int[] getIntArray(java.lang.String);
    method public long getLong(java.lang.String);
    method public long getLong(java.lang.String, long);
    method public long[] getLongArray(java.lang.String);
    method public android.os.PersistableBundle getPersistableBundle(java.lang.String);
    method public java.lang.String getString(java.lang.String);
    method public java.lang.String getString(java.lang.String, java.lang.String);
    method public java.lang.String[] getStringArray(java.lang.String);
    method public boolean isEmpty();
    method public java.util.Set<java.lang.String> keySet();
    method public void putAll(android.os.PersistableBundle);
    method public void putDouble(java.lang.String, double);
    method public void putDoubleArray(java.lang.String, double[]);
    method public void putInt(java.lang.String, int);
    method public void putIntArray(java.lang.String, int[]);
    method public void putLong(java.lang.String, long);
    method public void putLongArray(java.lang.String, long[]);
    method public void putPersistableBundle(java.lang.String, android.os.PersistableBundle);
    method public void putString(java.lang.String, java.lang.String);
    method public void putStringArray(java.lang.String, java.lang.String[]);
    method public void readFromParcel(android.os.Parcel);
    method public void remove(java.lang.String);
    method public void setClassLoader(java.lang.ClassLoader);
    method public int size();
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator CREATOR;
    field public static final android.os.PersistableBundle EMPTY;
  }
  public final class PowerManager {
    method public void goToSleep(long);
    method public boolean isInteractive();
+214 −557

File changed.

Preview size limit exceeded, changes collapsed.

+1384 −0

File added.

Preview size limit exceeded, changes collapsed.

+49 −0
Original line number Diff line number Diff line
@@ -223,6 +223,7 @@ public final class Parcel {
    private static final int VAL_SPARSEBOOLEANARRAY = 22;
    private static final int VAL_BOOLEANARRAY = 23;
    private static final int VAL_CHARSEQUENCEARRAY = 24;
    private static final int VAL_PERSISTABLEBUNDLE = 25;

    // The initial int32 in a Binder call's reply Parcel header:
    private static final int EX_SECURITY = -1;
@@ -637,6 +638,19 @@ public final class Parcel {
        val.writeToParcel(this, 0);
    }

    /**
     * Flatten a PersistableBundle into the parcel at the current dataPosition(),
     * growing dataCapacity() if needed.
     */
    public final void writePersistableBundle(PersistableBundle val) {
        if (val == null) {
            writeInt(-1);
            return;
        }

        val.writeToParcel(this, 0);
    }

    /**
     * Flatten a List into the parcel at the current dataPosition(), growing
     * dataCapacity() if needed.  The List values are written using
@@ -1256,6 +1270,9 @@ public final class Parcel {
        } else if (v instanceof Byte) {
            writeInt(VAL_BYTE);
            writeInt((Byte) v);
        } else if (v instanceof PersistableBundle) {
            writeInt(VAL_PERSISTABLEBUNDLE);
            writePersistableBundle((PersistableBundle) v);
        } else {
            Class<?> clazz = v.getClass();
            if (clazz.isArray() && clazz.getComponentType() == Object.class) {
@@ -1632,6 +1649,35 @@ public final class Parcel {
        return bundle;
    }

    /**
     * Read and return a new Bundle object from the parcel at the current
     * dataPosition().  Returns null if the previously written Bundle object was
     * null.
     */
    public final PersistableBundle readPersistableBundle() {
        return readPersistableBundle(null);
    }

    /**
     * Read and return a new Bundle object from the parcel at the current
     * dataPosition(), using the given class loader to initialize the class
     * loader of the Bundle for later retrieval of Parcelable objects.
     * Returns null if the previously written Bundle object was null.
     */
    public final PersistableBundle readPersistableBundle(ClassLoader loader) {
        int length = readInt();
        if (length < 0) {
            if (Bundle.DEBUG) Log.d(TAG, "null bundle: length=" + length);
            return null;
        }

        final PersistableBundle bundle = new PersistableBundle(this, length);
        if (loader != null) {
            bundle.setClassLoader(loader);
        }
        return bundle;
    }

    /**
     * Read and return a byte[] object from the parcel.
     */
@@ -2082,6 +2128,9 @@ public final class Parcel {
        case VAL_BUNDLE:
            return readBundle(loader); // loading will be deferred

        case VAL_PERSISTABLEBUNDLE:
            return readPersistableBundle(loader);

        default:
            int off = dataPosition() - 4;
            throw new RuntimeException(
+555 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.os;

import android.util.ArrayMap;

import java.util.Set;

/**
 * A mapping from String values to various types that can be saved to persistent and later
 * restored.
 *
 */
public final class PersistableBundle extends CommonBundle {
    public static final PersistableBundle EMPTY;
    static final Parcel EMPTY_PARCEL;

    static {
        EMPTY = new PersistableBundle();
        EMPTY.mMap = ArrayMap.EMPTY;
        EMPTY_PARCEL = CommonBundle.EMPTY_PARCEL;
    }

    /**
     * Constructs a new, empty PersistableBundle.
     */
    public PersistableBundle() {
        super();
    }

    /**
     * Constructs a PersistableBundle whose data is stored as a Parcel.  The data
     * will be unparcelled on first contact, using the assigned ClassLoader.
     *
     * @param parcelledData a Parcel containing a PersistableBundle
     */
    PersistableBundle(Parcel parcelledData) {
        super(parcelledData);
    }

    /* package */ PersistableBundle(Parcel parcelledData, int length) {
        super(parcelledData, length);
    }

    /**
     * Constructs a new, empty PersistableBundle that uses a specific ClassLoader for
     * instantiating Parcelable and Serializable objects.
     *
     * @param loader An explicit ClassLoader to use when instantiating objects
     * inside of the PersistableBundle.
     */
    public PersistableBundle(ClassLoader loader) {
        super(loader);
    }

    /**
     * Constructs a new, empty PersistableBundle sized to hold the given number of
     * elements. The PersistableBundle will grow as needed.
     *
     * @param capacity the initial capacity of the PersistableBundle
     */
    public PersistableBundle(int capacity) {
        super(capacity);
    }

    /**
     * Constructs a PersistableBundle containing a copy of the mappings from the given
     * PersistableBundle.
     *
     * @param b a PersistableBundle to be copied.
     */
    public PersistableBundle(PersistableBundle b) {
        super(b);
    }

    /**
     * Make a PersistableBundle for a single key/value pair.
     *
     * @hide
     */
    public static PersistableBundle forPair(String key, String value) {
        PersistableBundle b = new PersistableBundle(1);
        b.putString(key, value);
        return b;
    }

    /**
     * @hide
     */
    @Override
    public String getPairValue() {
        return super.getPairValue();
    }

    /**
     * Changes the ClassLoader this PersistableBundle uses when instantiating objects.
     *
     * @param loader An explicit ClassLoader to use when instantiating objects
     * inside of the PersistableBundle.
     */
    @Override
    public void setClassLoader(ClassLoader loader) {
        super.setClassLoader(loader);
    }

    /**
     * Return the ClassLoader currently associated with this PersistableBundle.
     */
    @Override
    public ClassLoader getClassLoader() {
        return super.getClassLoader();
    }

    /**
     * Clones the current PersistableBundle. The internal map is cloned, but the keys and
     * values to which it refers are copied by reference.
     */
    @Override
    public Object clone() {
        return new PersistableBundle(this);
    }

    /**
     * @hide
     */
    @Override
    public boolean isParcelled() {
        return super.isParcelled();
    }

    /**
     * Returns the number of mappings contained in this PersistableBundle.
     *
     * @return the number of mappings as an int.
     */
    @Override
    public int size() {
        return super.size();
    }

    /**
     * Returns true if the mapping of this PersistableBundle is empty, false otherwise.
     */
    @Override
    public boolean isEmpty() {
        return super.isEmpty();
    }

    /**
     * Removes all elements from the mapping of this PersistableBundle.
     */
    @Override
    public void clear() {
        super.clear();
    }

    /**
     * Returns true if the given key is contained in the mapping
     * of this PersistableBundle.
     *
     * @param key a String key
     * @return true if the key is part of the mapping, false otherwise
     */
    @Override
    public boolean containsKey(String key) {
        return super.containsKey(key);
    }

    /**
     * Returns the entry with the given key as an object.
     *
     * @param key a String key
     * @return an Object, or null
     */
    @Override
    public Object get(String key) {
        return super.get(key);
    }

    /**
     * Removes any entry with the given key from the mapping of this PersistableBundle.
     *
     * @param key a String key
     */
    @Override
    public void remove(String key) {
        super.remove(key);
    }

    /**
     * Inserts all mappings from the given PersistableBundle into this Bundle.
     *
     * @param bundle a PersistableBundle
     */
    public void putAll(PersistableBundle bundle) {
        super.putAll(bundle);
    }

    /**
     * Returns a Set containing the Strings used as keys in this PersistableBundle.
     *
     * @return a Set of String keys
     */
    @Override
    public Set<String> keySet() {
        return super.keySet();
    }

    /**
     * Inserts an int value into the mapping of this PersistableBundle, replacing
     * any existing value for the given key.
     *
     * @param key a String, or null
     * @param value an int, or null
     */
    @Override
    public void putInt(String key, int value) {
        super.putInt(key, value);
    }

    /**
     * Inserts a long value into the mapping of this PersistableBundle, replacing
     * any existing value for the given key.
     *
     * @param key a String, or null
     * @param value a long
     */
    @Override
    public void putLong(String key, long value) {
        super.putLong(key, value);
    }

    /**
     * Inserts a double value into the mapping of this PersistableBundle, replacing
     * any existing value for the given key.
     *
     * @param key a String, or null
     * @param value a double
     */
    @Override
    public void putDouble(String key, double value) {
        super.putDouble(key, value);
    }

    /**
     * Inserts a String value into the mapping of this PersistableBundle, replacing
     * any existing value for the given key.  Either key or value may be null.
     *
     * @param key a String, or null
     * @param value a String, or null
     */
    @Override
    public void putString(String key, String value) {
        super.putString(key, value);
    }

    /**
     * Inserts an int array value into the mapping of this PersistableBundle, replacing
     * any existing value for the given key.  Either key or value may be null.
     *
     * @param key a String, or null
     * @param value an int array object, or null
     */
    @Override
    public void putIntArray(String key, int[] value) {
        super.putIntArray(key, value);
    }

    /**
     * Inserts a long array value into the mapping of this PersistableBundle, replacing
     * any existing value for the given key.  Either key or value may be null.
     *
     * @param key a String, or null
     * @param value a long array object, or null
     */
    @Override
    public void putLongArray(String key, long[] value) {
        super.putLongArray(key, value);
    }

    /**
     * Inserts a double array value into the mapping of this PersistableBundle, replacing
     * any existing value for the given key.  Either key or value may be null.
     *
     * @param key a String, or null
     * @param value a double array object, or null
     */
    @Override
    public void putDoubleArray(String key, double[] value) {
        super.putDoubleArray(key, value);
    }

    /**
     * Inserts a String array value into the mapping of this PersistableBundle, replacing
     * any existing value for the given key.  Either key or value may be null.
     *
     * @param key a String, or null
     * @param value a String array object, or null
     */
    @Override
    public void putStringArray(String key, String[] value) {
        super.putStringArray(key, value);
    }

    /**
     * Inserts a PersistableBundle value into the mapping of this Bundle, replacing
     * any existing value for the given key.  Either key or value may be null.
     *
     * @param key a String, or null
     * @param value a Bundle object, or null
     */
    public void putPersistableBundle(String key, PersistableBundle value) {
        super.putPersistableBundle(key, value);
    }

    /**
     * Returns the value associated with the given key, or 0 if
     * no mapping of the desired type exists for the given key.
     *
     * @param key a String
     * @return an int value
     */
    @Override
    public int getInt(String key) {
        return super.getInt(key);
    }

    /**
     * Returns the value associated with the given key, or defaultValue if
     * no mapping of the desired type exists for the given key.
     *
     * @param key a String
     * @param defaultValue Value to return if key does not exist
     * @return an int value
     */
    @Override
    public int getInt(String key, int defaultValue) {
        return super.getInt(key, defaultValue);
    }

    /**
     * Returns the value associated with the given key, or 0L if
     * no mapping of the desired type exists for the given key.
     *
     * @param key a String
     * @return a long value
     */
    @Override
    public long getLong(String key) {
        return super.getLong(key);
    }

    /**
     * Returns the value associated with the given key, or defaultValue if
     * no mapping of the desired type exists for the given key.
     *
     * @param key a String
     * @param defaultValue Value to return if key does not exist
     * @return a long value
     */
    @Override
    public long getLong(String key, long defaultValue) {
        return super.getLong(key, defaultValue);
    }

    /**
     * Returns the value associated with the given key, or 0.0 if
     * no mapping of the desired type exists for the given key.
     *
     * @param key a String
     * @return a double value
     */
    @Override
    public double getDouble(String key) {
        return super.getDouble(key);
    }

    /**
     * Returns the value associated with the given key, or defaultValue if
     * no mapping of the desired type exists for the given key.
     *
     * @param key a String
     * @param defaultValue Value to return if key does not exist
     * @return a double value
     */
    @Override
    public double getDouble(String key, double defaultValue) {
        return super.getDouble(key, defaultValue);
    }

    /**
     * Returns the value associated with the given key, or null if
     * no mapping of the desired type exists for the given key or a null
     * value is explicitly associated with the key.
     *
     * @param key a String, or null
     * @return a String value, or null
     */
    @Override
    public String getString(String key) {
        return super.getString(key);
    }

    /**
     * Returns the value associated with the given key, or defaultValue if
     * no mapping of the desired type exists for the given key.
     *
     * @param key a String, or null
     * @param defaultValue Value to return if key does not exist
     * @return the String value associated with the given key, or defaultValue
     *     if no valid String object is currently mapped to that key.
     */
    @Override
    public String getString(String key, String defaultValue) {
        return super.getString(key, defaultValue);
    }

    /**
     * Returns the value associated with the given key, or null if
     * no mapping of the desired type exists for the given key or a null
     * value is explicitly associated with the key.
     *
     * @param key a String, or null
     * @return a Bundle value, or null
     */
    @Override
    public PersistableBundle getPersistableBundle(String key) {
        return super.getPersistableBundle(key);
    }

    /**
     * Returns the value associated with the given key, or null if
     * no mapping of the desired type exists for the given key or a null
     * value is explicitly associated with the key.
     *
     * @param key a String, or null
     * @return an int[] value, or null
     */
    @Override
    public int[] getIntArray(String key) {
        return super.getIntArray(key);
    }

    /**
     * Returns the value associated with the given key, or null if
     * no mapping of the desired type exists for the given key or a null
     * value is explicitly associated with the key.
     *
     * @param key a String, or null
     * @return a long[] value, or null
     */
    @Override
    public long[] getLongArray(String key) {
        return super.getLongArray(key);
    }

    /**
     * Returns the value associated with the given key, or null if
     * no mapping of the desired type exists for the given key or a null
     * value is explicitly associated with the key.
     *
     * @param key a String, or null
     * @return a double[] value, or null
     */
    @Override
    public double[] getDoubleArray(String key) {
        return super.getDoubleArray(key);
    }

    /**
     * Returns the value associated with the given key, or null if
     * no mapping of the desired type exists for the given key or a null
     * value is explicitly associated with the key.
     *
     * @param key a String, or null
     * @return a String[] value, or null
     */
    @Override
    public String[] getStringArray(String key) {
        return super.getStringArray(key);
    }

    public static final Parcelable.Creator<PersistableBundle> CREATOR =
            new Parcelable.Creator<PersistableBundle>() {
                @Override
                public PersistableBundle createFromParcel(Parcel in) {
                    return in.readPersistableBundle();
                }

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

    /**
     * Report the nature of this Parcelable's contents
     */
    @Override
    public int describeContents() {
        return 0;
    }

    /**
     * Writes the PersistableBundle contents to a Parcel, typically in order for
     * it to be passed through an IBinder connection.
     * @param parcel The parcel to copy this bundle to.
     */
    @Override
    public void writeToParcel(Parcel parcel, int flags) {
        final boolean oldAllowFds = parcel.pushAllowFds(false);
        try {
            super.writeToParcelInner(parcel, flags);
        } finally {
            parcel.restoreAllowFds(oldAllowFds);
        }
    }

    /**
     * Reads the Parcel contents into this PersistableBundle, typically in order for
     * it to be passed through an IBinder connection.
     * @param parcel The parcel to overwrite this bundle from.
     */
    public void readFromParcel(Parcel parcel) {
        super.readFromParcelInner(parcel);
    }

    @Override
    synchronized public String toString() {
        if (mParcelledData != null) {
            if (mParcelledData == EMPTY_PARCEL) {
                return "PersistableBundle[EMPTY_PARCEL]";
            } else {
                return "PersistableBundle[mParcelledData.dataSize=" +
                        mParcelledData.dataSize() + "]";
            }
        }
        return "PersistableBundle[" + mMap.toString() + "]";
    }

}