/*
 * Copyright (C) 2018 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.provider;

import static android.Manifest.permission.READ_DEVICE_CONFIG;
import static android.Manifest.permission.WRITE_DEVICE_CONFIG;

import android.annotation.CallbackExecutor;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.app.ActivityThread;
import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.PackageManager;
import android.database.ContentObserver;
import android.net.Uri;
import android.provider.Settings.ResetMode;
import android.util.ArrayMap;
import android.util.Log;
import android.util.Pair;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.Preconditions;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Executor;

/**
 * Device level configuration parameters which can be tuned by a separate configuration service.
 * Namespaces that end in "_native" such as {@link #NAMESPACE_NETD_NATIVE} are intended to be used
 * by native code and should be pushed to system properties to make them accessible.
 *
 * @hide
 */
@SystemApi
@TestApi
public final class DeviceConfig {
    /**
     * The content:// style URL for the config table.
     *
     * @hide
     */
    public static final Uri CONTENT_URI = Uri.parse("content://" + Settings.AUTHORITY + "/config");

    /**
     * Namespace for activity manager related features. These features will be applied
     * immediately upon change.
     *
     * @hide
     */
    @SystemApi
    public static final String NAMESPACE_ACTIVITY_MANAGER = "activity_manager";

    /**
     * Namespace for all activity manager related features that are used at the native level.
     * These features are applied at reboot.
     *
     * @hide
     */
    @SystemApi
    public static final String NAMESPACE_ACTIVITY_MANAGER_NATIVE_BOOT =
            "activity_manager_native_boot";

    /**
     * Namespace for all app compat related features.  These features will be applied
     * immediately upon change.
     *
     * @hide
     */
    @SystemApi
    public static final String NAMESPACE_APP_COMPAT = "app_compat";

    /**
     * Namespace for AttentionManagerService related features.
     *
     * @hide
     */
    @SystemApi
    public static final String NAMESPACE_ATTENTION_MANAGER_SERVICE = "attention_manager_service";

    /**
     * Namespace for autofill feature that provides suggestions across all apps when
     * the user interacts with input fields.
     *
     * @hide
     */
    @SystemApi
    @TestApi
    public static final String NAMESPACE_AUTOFILL = "autofill";

    /**
     * Namespace for all networking connectivity related features.
     *
     * @hide
     */
    @SystemApi
    public static final String NAMESPACE_CONNECTIVITY = "connectivity";

    /**
     * Namespace for content capture feature used by on-device machine intelligence
     * to provide suggestions in a privacy-safe manner.
     *
     * @hide
     */
    @SystemApi
    @TestApi
    public static final String NAMESPACE_CONTENT_CAPTURE = "content_capture";

    /**
     * Namespace for how dex runs. The feature requires a reboot to reach a clean state.
     *
     * @deprecated No longer used
     * @hide
     */
    @Deprecated
    @SystemApi
    public static final String NAMESPACE_DEX_BOOT = "dex_boot";

    /**
     * Namespace for display manager related features. The names to access the properties in this
     * namespace should be defined in {@link android.hardware.display.DisplayManager}.
     *
     * @hide
     */
    @SystemApi
    public static final String NAMESPACE_DISPLAY_MANAGER = "display_manager";

    /**
     * Namespace for all Game Driver features.
     *
     * @hide
     */
    @SystemApi
    public static final String NAMESPACE_GAME_DRIVER = "game_driver";

    /**
     * Namespace for all input-related features that are used at the native level.
     * These features are applied at reboot.
     *
     * @hide
     */
    @SystemApi
    public static final String NAMESPACE_INPUT_NATIVE_BOOT = "input_native_boot";

    /**
     * Namespace for attention-based features provided by on-device machine intelligence.
     *
     * @hide
     */
    @SystemApi
    public static final String NAMESPACE_INTELLIGENCE_ATTENTION = "intelligence_attention";

    /**
     * Definitions for properties related to Content Suggestions.
     *
     * @hide
     */
    public static final String NAMESPACE_INTELLIGENCE_CONTENT_SUGGESTIONS =
            "intelligence_content_suggestions";

    /**
     * Namespace for all media native related features.
     *
     * @hide
     */
    @SystemApi
    public static final String NAMESPACE_MEDIA_NATIVE = "media_native";

    /**
     * Namespace for all netd related features.
     *
     * @hide
     */
    @SystemApi
    public static final String NAMESPACE_NETD_NATIVE = "netd_native";

    /**
     * Namespace for features related to the Package Manager Service.
     *
     * @hide
     */
    @SystemApi
    public static final String NAMESPACE_PACKAGE_MANAGER_SERVICE = "package_manager_service";

    /**
     * Namespace for Rollback flags that are applied immediately.
     *
     * @hide
     */
    @SystemApi @TestApi
    public static final String NAMESPACE_ROLLBACK = "rollback";

    /**
     * Namespace for Rollback flags that are applied after a reboot.
     *
     * @hide
     */
    @SystemApi @TestApi
    public static final String NAMESPACE_ROLLBACK_BOOT = "rollback_boot";

    /**
     * Namespace for all runtime related features that don't require a reboot to become active.
     * There are no feature flags using NAMESPACE_RUNTIME.
     *
     * @hide
     */
    @SystemApi
    public static final String NAMESPACE_RUNTIME = "runtime";

    /**
     * Namespace for all runtime related features that require system properties for accessing
     * the feature flags from C++ or Java language code. One example is the app image startup
     * cache feature use_app_image_startup_cache.
     *
     * @hide
     */
    @SystemApi
    public static final String NAMESPACE_RUNTIME_NATIVE = "runtime_native";

    /**
     * Namespace for all runtime native boot related features. Boot in this case refers to the
     * fact that the properties only take affect after rebooting the device.
     *
     * @hide
     */
    @SystemApi
    public static final String NAMESPACE_RUNTIME_NATIVE_BOOT = "runtime_native_boot";

    /**
     * Namespace for system scheduler related features. These features will be applied
     * immediately upon change.
     *
     * @hide
     */
    @SystemApi
    public static final String NAMESPACE_SCHEDULER = "scheduler";

    /**
     * Namespace for storage-related features.
     *
     * @deprecated Replace storage namespace with storage_native_boot.
     * @hide
     */
    @Deprecated
    @SystemApi
    public static final String NAMESPACE_STORAGE = "storage";

    /**
     * Namespace for storage-related features, including native and boot.
     *
     * @hide
     */
    @SystemApi
    public static final String NAMESPACE_STORAGE_NATIVE_BOOT = "storage_native_boot";

    /**
     * Namespace for System UI related features.
     *
     * @hide
     */
    @SystemApi
    public static final String NAMESPACE_SYSTEMUI = "systemui";

    /**
     * Telephony related properties.
     *
     * @hide
     */
    @SystemApi
    public static final String NAMESPACE_TELEPHONY = "telephony";

    /**
     * Namespace for TextClassifier related features.
     *
     * @hide
     * @see android.provider.Settings.Global.TEXT_CLASSIFIER_CONSTANTS
     */
    @SystemApi
    public static final String NAMESPACE_TEXTCLASSIFIER = "textclassifier";

    /**
     * Namespace for contacts provider related features.
     *
     * @hide
     */
    public static final String NAMESPACE_CONTACTS_PROVIDER = "contacts_provider";

    /**
     * Namespace for settings ui related features
     *
     * @hide
     */
    public static final String NAMESPACE_SETTINGS_UI = "settings_ui";

    /**
     * Namespace for android related features, i.e. for flags that affect not just a single
     * component, but the entire system.
     *
     * The keys for this namespace are defined in {@link AndroidDeviceConfig}.
     *
     * @hide
     */
    @TestApi
    public static final String NAMESPACE_ANDROID = "android";

    /**
     * Namespace for window manager related features.
     *
     * @hide
     */
    public static final String NAMESPACE_WINDOW_MANAGER = "window_manager";

    /**
     * List of namespaces which can be read without READ_DEVICE_CONFIG permission
     *
     * @hide
     */
    @NonNull
    private static final List<String> PUBLIC_NAMESPACES =
            Arrays.asList(NAMESPACE_TEXTCLASSIFIER, NAMESPACE_RUNTIME);
    /**
     * Privacy related properties definitions.
     *
     * @hide
     */
    @SystemApi
    @TestApi
    public static final String NAMESPACE_PRIVACY = "privacy";

    /**
     * Permission related properties definitions.
     *
     * @hide
     */
    @SystemApi
    @TestApi
    public static final String NAMESPACE_PERMISSIONS = "permissions";

    private static final Object sLock = new Object();
    @GuardedBy("sLock")
    private static ArrayMap<OnPropertiesChangedListener, Pair<String, Executor>> sListeners =
            new ArrayMap<>();
    @GuardedBy("sLock")
    private static Map<String, Pair<ContentObserver, Integer>> sNamespaces = new HashMap<>();
    private static final String TAG = "DeviceConfig";

    // Should never be invoked
    private DeviceConfig() {
    }

    /**
     * Look up the value of a property for a particular namespace.
     *
     * @param namespace The namespace containing the property to look up.
     * @param name      The name of the property to look up.
     * @return the corresponding value, or null if not present.
     * @hide
     */
    @SystemApi
    @TestApi
    @RequiresPermission(READ_DEVICE_CONFIG)
    public static String getProperty(@NonNull String namespace, @NonNull String name) {
        // Fetch all properties for the namespace at once and cache them in the local process, so we
        // incur the cost of the IPC less often. Lookups happen much more frequently than updates,
        // and we want to optimize the former.
        return getProperties(namespace, name).getString(name, null);
    }

    /**
     * Look up the values of multiple properties for a particular namespace. The lookup is atomic,
     * such that the values of these properties cannot change between the time when the first is
     * fetched and the time when the last is fetched.
     * <p>
     * Each call to {@link #setProperties(Properties)} is also atomic and ensures that either none
     * or all of the change is picked up here, but never only part of it.
     *
     * @param namespace The namespace containing the properties to look up.
     * @param names     The names of properties to look up, or empty to fetch all properties for the
     *                  given namespace.
     * @return {@link Properties} object containing the requested properties. This reflects the
     *     state of these properties at the time of the lookup, and is not updated to reflect any
     *     future changes. The keyset of this Properties object will contain only the intersection
     *     of properties already set and properties requested via the names parameter. Properties
     *     that are already set but were not requested will not be contained here. Properties that
     *     are not set, but were requested will not be contained here either.
     * @hide
     */
    @SystemApi
    @NonNull
    @RequiresPermission(READ_DEVICE_CONFIG)
    public static Properties getProperties(@NonNull String namespace, @NonNull String ... names) {
        ContentResolver contentResolver = ActivityThread.currentApplication().getContentResolver();
        return new Properties(namespace,
                Settings.Config.getStrings(contentResolver, namespace, Arrays.asList(names)));
    }

    /**
     * Look up the String value of a property for a particular namespace.
     *
     * @param namespace    The namespace containing the property to look up.
     * @param name         The name of the property to look up.
     * @param defaultValue The value to return if the property does not exist or has no non-null
     *                     value.
     * @return the corresponding value, or defaultValue if none exists.
     * @hide
     */
    @SystemApi
    @TestApi
    @RequiresPermission(READ_DEVICE_CONFIG)
    public static String getString(@NonNull String namespace, @NonNull String name,
            @Nullable String defaultValue) {
        String value = getProperty(namespace, name);
        return value != null ? value : defaultValue;
    }

    /**
     * Look up the boolean value of a property for a particular namespace.
     *
     * @param namespace The namespace containing the property to look up.
     * @param name      The name of the property to look up.
     * @param defaultValue The value to return if the property does not exist or has no non-null
     *                     value.
     * @return the corresponding value, or defaultValue if none exists.
     * @hide
     */
    @SystemApi
    @TestApi
    @RequiresPermission(READ_DEVICE_CONFIG)
    public static boolean getBoolean(@NonNull String namespace, @NonNull String name,
            boolean defaultValue) {
        String value = getProperty(namespace, name);
        return value != null ? Boolean.parseBoolean(value) : defaultValue;
    }

    /**
     * Look up the int value of a property for a particular namespace.
     *
     * @param namespace The namespace containing the property to look up.
     * @param name      The name of the property to look up.
     * @param defaultValue The value to return if the property does not exist, has no non-null
     *                     value, or fails to parse into an int.
     * @return the corresponding value, or defaultValue if either none exists or it does not parse.
     * @hide
     */
    @SystemApi
    @TestApi
    @RequiresPermission(READ_DEVICE_CONFIG)
    public static int getInt(@NonNull String namespace, @NonNull String name, int defaultValue) {
        String value = getProperty(namespace, name);
        if (value == null) {
            return defaultValue;
        }
        try {
            return Integer.parseInt(value);
        } catch (NumberFormatException e) {
            Log.e(TAG, "Parsing integer failed for " + namespace + ":" + name);
            return defaultValue;
        }
    }

    /**
     * Look up the long value of a property for a particular namespace.
     *
     * @param namespace The namespace containing the property to look up.
     * @param name      The name of the property to look up.
     * @param defaultValue The value to return if the property does not exist, has no non-null
     *                     value, or fails to parse into a long.
     * @return the corresponding value, or defaultValue if either none exists or it does not parse.
     * @hide
     */
    @SystemApi
    @TestApi
    @RequiresPermission(READ_DEVICE_CONFIG)
    public static long getLong(@NonNull String namespace, @NonNull String name, long defaultValue) {
        String value = getProperty(namespace, name);
        if (value == null) {
            return defaultValue;
        }
        try {
            return Long.parseLong(value);
        } catch (NumberFormatException e) {
            Log.e(TAG, "Parsing long failed for " + namespace + ":" + name);
            return defaultValue;
        }
    }

    /**
     * Look up the float value of a property for a particular namespace.
     *
     * @param namespace The namespace containing the property to look up.
     * @param name      The name of the property to look up.
     * @param defaultValue The value to return if the property does not exist, has no non-null
     *                     value, or fails to parse into a float.
     * @return the corresponding value, or defaultValue if either none exists or it does not parse.
     * @hide
     */
    @SystemApi
    @TestApi
    @RequiresPermission(READ_DEVICE_CONFIG)
    public static float getFloat(@NonNull String namespace, @NonNull String name,
            float defaultValue) {
        String value = getProperty(namespace, name);
        if (value == null) {
            return defaultValue;
        }
        try {
            return Float.parseFloat(value);
        } catch (NumberFormatException e) {
            Log.e(TAG, "Parsing float failed for " + namespace + ":" + name);
            return defaultValue;
        }
    }

    /**
     * Create a new property with the the provided name and value in the provided namespace, or
     * update the value of such a property if it already exists. The same name can exist in multiple
     * namespaces and might have different values in any or all namespaces.
     * <p>
     * The method takes an argument indicating whether to make the value the default for this
     * property.
     * <p>
     * All properties stored for a particular scope can be reverted to their default values
     * by passing the namespace to {@link #resetToDefaults(int, String)}.
     *
     * @param namespace   The namespace containing the property to create or update.
     * @param name        The name of the property to create or update.
     * @param value       The value to store for the property.
     * @param makeDefault Whether to make the new value the default one.
     * @return True if the value was set, false if the storage implementation throws errors.
     * @hide
     * @see #resetToDefaults(int, String).
     */
    @SystemApi
    @TestApi
    @RequiresPermission(WRITE_DEVICE_CONFIG)
    public static boolean setProperty(@NonNull String namespace, @NonNull String name,
            @Nullable String value, boolean makeDefault) {
        ContentResolver contentResolver = ActivityThread.currentApplication().getContentResolver();
        return Settings.Config.putString(contentResolver, namespace, name, value, makeDefault);
    }

    /**
     * Set all of the properties for a specific namespace. Pre-existing properties will be updated
     * and new properties will be added if necessary. Any pre-existing properties for the specific
     * namespace which are not part of the provided {@link Properties} object will be deleted from
     * the namespace. These changes are all applied atomically, such that no calls to read or reset
     * these properties can happen in the middle of this update.
     * <p>
     * Each call to {@link #getProperties(String, String...)} is also atomic and ensures that either
     * none or all of this update is picked up, but never only part of it.
     *
     * @param properties the complete set of properties to set for a specific namespace.
     * @hide
     */
    @SystemApi
    @RequiresPermission(WRITE_DEVICE_CONFIG)
    public static boolean setProperties(@NonNull Properties properties) {
        ContentResolver contentResolver = ActivityThread.currentApplication().getContentResolver();
        return Settings.Config.setStrings(contentResolver, properties.getNamespace(),
                properties.mMap);
    }

    /**
     * Reset properties to their default values.
     * <p>
     * The method accepts an optional namespace parameter. If provided, only properties set within
     * that namespace will be reset. Otherwise, all properties will be reset.
     *
     * @param resetMode The reset mode to use.
     * @param namespace Optionally, the specific namespace which resets will be limited to.
     * @hide
     * @see #setProperty(String, String, String, boolean)
     */
    @SystemApi
    @TestApi
    @RequiresPermission(WRITE_DEVICE_CONFIG)
    public static void resetToDefaults(@ResetMode int resetMode, @Nullable String namespace) {
        ContentResolver contentResolver = ActivityThread.currentApplication().getContentResolver();
        Settings.Config.resetToDefaults(contentResolver, resetMode, namespace);
    }

    /**
     * Add a listener for property changes.
     * <p>
     * This listener will be called whenever properties in the specified namespace change. Callbacks
     * will be made on the specified executor. Future calls to this method with the same listener
     * will replace the old namespace and executor. Remove the listener entirely by calling
     * {@link #removeOnPropertiesChangedListener(OnPropertiesChangedListener)}.
     *
     * @param namespace                   The namespace containing properties to monitor.
     * @param executor                    The executor which will be used to run callbacks.
     * @param onPropertiesChangedListener The listener to add.
     * @hide
     * @see #removeOnPropertiesChangedListener(OnPropertiesChangedListener)
     */
    @SystemApi
    @TestApi
    @RequiresPermission(READ_DEVICE_CONFIG)
    public static void addOnPropertiesChangedListener(
            @NonNull String namespace,
            @NonNull @CallbackExecutor Executor executor,
            @NonNull OnPropertiesChangedListener onPropertiesChangedListener) {
        enforceReadPermission(ActivityThread.currentApplication().getApplicationContext(),
                namespace);
        synchronized (sLock) {
            Pair<String, Executor> oldNamespace = sListeners.get(onPropertiesChangedListener);
            if (oldNamespace == null) {
                // Brand new listener, add it to the list.
                sListeners.put(onPropertiesChangedListener, new Pair<>(namespace, executor));
                incrementNamespace(namespace);
            } else if (namespace.equals(oldNamespace.first)) {
                // Listener is already registered for this namespace, update executor just in case.
                sListeners.put(onPropertiesChangedListener, new Pair<>(namespace, executor));
            } else {
                // Update this listener from an old namespace to the new one.
                decrementNamespace(sListeners.get(onPropertiesChangedListener).first);
                sListeners.put(onPropertiesChangedListener, new Pair<>(namespace, executor));
                incrementNamespace(namespace);
            }
        }
    }

    /**
     * Remove a listener for property changes. The listener will receive no further notification of
     * property changes.
     *
     * @param onPropertiesChangedListener The listener to remove.
     * @hide
     * @see #addOnPropertiesChangedListener(String, Executor, OnPropertiesChangedListener)
     */
    @SystemApi
    @TestApi
    public static void removeOnPropertiesChangedListener(
            @NonNull OnPropertiesChangedListener onPropertiesChangedListener) {
        Preconditions.checkNotNull(onPropertiesChangedListener);
        synchronized (sLock) {
            if (sListeners.containsKey(onPropertiesChangedListener)) {
                decrementNamespace(sListeners.get(onPropertiesChangedListener).first);
                sListeners.remove(onPropertiesChangedListener);
            }
        }
    }

    private static Uri createNamespaceUri(@NonNull String namespace) {
        Preconditions.checkNotNull(namespace);
        return CONTENT_URI.buildUpon().appendPath(namespace).build();
    }

    /**
     * Increment the count used to represent the number of listeners subscribed to the given
     * namespace. If this is the first (i.e. incrementing from 0 to 1) for the given namespace, a
     * ContentObserver is registered.
     *
     * @param namespace The namespace to increment the count for.
     */
    @GuardedBy("sLock")
    private static void incrementNamespace(@NonNull String namespace) {
        Preconditions.checkNotNull(namespace);
        Pair<ContentObserver, Integer> namespaceCount = sNamespaces.get(namespace);
        if (namespaceCount != null) {
            sNamespaces.put(namespace, new Pair<>(namespaceCount.first, namespaceCount.second + 1));
        } else {
            // This is a new namespace, register a ContentObserver for it.
            ContentObserver contentObserver = new ContentObserver(null) {
                @Override
                public void onChange(boolean selfChange, Uri uri) {
                    if (uri != null) {
                        handleChange(uri);
                    }
                }
            };
            ActivityThread.currentApplication().getContentResolver()
                    .registerContentObserver(createNamespaceUri(namespace), true, contentObserver);
            sNamespaces.put(namespace, new Pair<>(contentObserver, 1));
        }
    }

    /**
     * Decrement the count used to represent the number of listeners subscribed to the given
     * namespace. If this is the final decrement call (i.e. decrementing from 1 to 0) for the given
     * namespace, the ContentObserver that had been tracking it will be removed.
     *
     * @param namespace The namespace to decrement the count for.
     */
    @GuardedBy("sLock")
    private static void decrementNamespace(@NonNull String namespace) {
        Preconditions.checkNotNull(namespace);
        Pair<ContentObserver, Integer> namespaceCount = sNamespaces.get(namespace);
        if (namespaceCount == null) {
            // This namespace is not registered and does not need to be decremented
            return;
        } else if (namespaceCount.second > 1) {
            sNamespaces.put(namespace, new Pair<>(namespaceCount.first, namespaceCount.second - 1));
        } else {
            // Decrementing a namespace to zero means we no longer need its ContentObserver.
            ActivityThread.currentApplication().getContentResolver()
                    .unregisterContentObserver(namespaceCount.first);
            sNamespaces.remove(namespace);
        }
    }

    private static void handleChange(@NonNull Uri uri) {
        Preconditions.checkNotNull(uri);
        List<String> pathSegments = uri.getPathSegments();
        // pathSegments(0) is "config"
        final String namespace = pathSegments.get(1);
        Map<String, String> propertyMap = new ArrayMap<>();
        try {
            Properties allProperties = getProperties(namespace);
            for (int i = 2; i < pathSegments.size(); ++i) {
                String key = pathSegments.get(i);
                propertyMap.put(key, allProperties.getString(key, null));
            }
        } catch (SecurityException e) {
            // Silently failing to not crash binder or listener threads.
            Log.e(TAG, "OnPropertyChangedListener update failed: permission violation.");
            return;
        }
        Properties properties = new Properties(namespace, propertyMap);

        synchronized (sLock) {
            for (int i = 0; i < sListeners.size(); i++) {
                if (namespace.equals(sListeners.valueAt(i).first)) {
                    final OnPropertiesChangedListener listener = sListeners.keyAt(i);
                    sListeners.valueAt(i).second.execute(() -> {
                        listener.onPropertiesChanged(properties);
                    });
                }
            }
        }
    }

    /**
     * Enforces READ_DEVICE_CONFIG permission if namespace is not one of public namespaces.
     * @hide
     */
    public static void enforceReadPermission(Context context, String namespace) {
        if (context.checkCallingOrSelfPermission(READ_DEVICE_CONFIG)
                != PackageManager.PERMISSION_GRANTED) {
            if (!PUBLIC_NAMESPACES.contains(namespace)) {
                throw new SecurityException("Permission denial: reading from settings requires:"
                        + READ_DEVICE_CONFIG);
            }
        }
    }

    /**
     * Interface for monitoring changes to properties. Implementations will receive callbacks when
     * properties change, including a {@link Properties} object which contains a single namespace
     * and all of the properties which changed for that namespace. This includes properties which
     * were added, updated, or deleted. This is not necessarily a complete list of all properties
     * belonging to the namespace, as properties which don't change are omitted.
     * <p>
     * Override {@link #onPropertiesChanged(Properties)} to handle callbacks for changes.
     *
     * @hide
     */
    @SystemApi
    @TestApi
    public interface OnPropertiesChangedListener {
        /**
         * Called when one or more properties have changed, providing a Properties object with all
         * of the changed properties. This object will contain only properties which have changed,
         * not the complete set of all properties belonging to the namespace.
         *
         * @param properties Contains the complete collection of properties which have changed for a
         *                   single namespace. This includes only those which were added, updated,
         *                   or deleted.
         */
        void onPropertiesChanged(@NonNull Properties properties);
    }

    /**
     * A mapping of properties to values, as well as a single namespace which they all belong to.
     *
     * @hide
     */
    @SystemApi
    @TestApi
    public static class Properties {
        private final String mNamespace;
        private final HashMap<String, String> mMap;

        /**
         * Create a mapping of properties to values and the namespace they belong to.
         *
         * @param namespace The namespace these properties belong to.
         * @param keyValueMap A map between property names and property values.
         * @hide
         */
        public Properties(@NonNull String namespace, @Nullable Map<String, String> keyValueMap) {
            Preconditions.checkNotNull(namespace);
            mNamespace = namespace;
            mMap = new HashMap();
            if (keyValueMap != null) {
                mMap.putAll(keyValueMap);
            }
        }

        /**
         * @return the namespace all properties within this instance belong to.
         */
        @NonNull
        public String getNamespace() {
            return mNamespace;
        }

        /**
         * @return the non-null set of property names.
         */
        @NonNull
        public Set<String> getKeyset() {
            return mMap.keySet();
        }

        /**
         * Look up the String value of a property.
         *
         * @param name         The name of the property to look up.
         * @param defaultValue The value to return if the property has not been defined.
         * @return the corresponding value, or defaultValue if none exists.
         */
        @Nullable
        public String getString(@NonNull String name, @Nullable String defaultValue) {
            Preconditions.checkNotNull(name);
            String value = mMap.get(name);
            return value != null ? value : defaultValue;
        }

        /**
         * Look up the boolean value of a property.
         *
         * @param name         The name of the property to look up.
         * @param defaultValue The value to return if the property has not been defined.
         * @return the corresponding value, or defaultValue if none exists.
         */
        public boolean getBoolean(@NonNull String name, boolean defaultValue) {
            Preconditions.checkNotNull(name);
            String value = mMap.get(name);
            return value != null ? Boolean.parseBoolean(value) : defaultValue;
        }

        /**
         * Look up the int value of a property.
         *
         * @param name         The name of the property to look up.
         * @param defaultValue The value to return if the property has not been defined or fails to
         *                     parse into an int.
         * @return the corresponding value, or defaultValue if no valid int is available.
         */
        public int getInt(@NonNull String name, int defaultValue) {
            Preconditions.checkNotNull(name);
            String value = mMap.get(name);
            if (value == null) {
                return defaultValue;
            }
            try {
                return Integer.parseInt(value);
            } catch (NumberFormatException e) {
                Log.e(TAG, "Parsing int failed for " + name);
                return defaultValue;
            }
        }

        /**
         * Look up the long value of a property.
         *
         * @param name         The name of the property to look up.
         * @param defaultValue The value to return if the property has not been defined. or fails to
         *                     parse into a long.
         * @return the corresponding value, or defaultValue if no valid long is available.
         */
        public long getLong(@NonNull String name, long defaultValue) {
            Preconditions.checkNotNull(name);
            String value = mMap.get(name);
            if (value == null) {
                return defaultValue;
            }
            try {
                return Long.parseLong(value);
            } catch (NumberFormatException e) {
                Log.e(TAG, "Parsing long failed for " + name);
                return defaultValue;
            }
        }

        /**
         * Look up the int value of a property.
         *
         * @param name         The name of the property to look up.
         * @param defaultValue The value to return if the property has not been defined. or fails to
         *                     parse into a float.
         * @return the corresponding value, or defaultValue if no valid float is available.
         */
        public float getFloat(@NonNull String name, float defaultValue) {
            Preconditions.checkNotNull(name);
            String value = mMap.get(name);
            if (value == null) {
                return defaultValue;
            }
            try {
                return Float.parseFloat(value);
            } catch (NumberFormatException e) {
                Log.e(TAG, "Parsing float failed for " + name);
                return defaultValue;
            }
        }
    }
}
