Revert "Define FeatureFlagsService."

Revert submission 23727772-b279054964-flag-api-udc-qpr-dev

Reason for revert: b/290929382

Reverted changes: /q/submissionid:23727772-b279054964-flag-api-udc-qpr-dev

Change-Id: I144a92ee478b76d98dc1a2a47533cb524c5fc056
diff --git a/core/java/Android.bp b/core/java/Android.bp
index 236d0b5..f8f4cc3 100644
--- a/core/java/Android.bp
+++ b/core/java/Android.bp
@@ -34,15 +34,6 @@
 }
 
 filegroup {
-    name: "feature_flags_aidl",
-    srcs: [
-        "android/flags/IFeatureFlags.aidl",
-        "android/flags/IFeatureFlagsCallback.aidl",
-        "android/flags/SyncableFlag.aidl",
-    ],
-}
-
-filegroup {
     name: "ITracingServiceProxy.aidl",
     srcs: ["android/tracing/ITracingServiceProxy.aidl"],
 }
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 2a6d84b..6d82922 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -5298,13 +5298,6 @@
     public static final String APP_PREDICTION_SERVICE = "app_prediction";
 
     /**
-     * Used for reading system-wide, overridable flags.
-     *
-     * @hide
-     */
-    public static final String FEATURE_FLAGS_SERVICE = "feature_flags";
-
-    /**
      * Official published name of the search ui service.
      *
      * <p><b>NOTE: </b> this service is optional; callers of
diff --git a/core/java/android/flags/IFeatureFlags.aidl b/core/java/android/flags/IFeatureFlags.aidl
deleted file mode 100644
index 1eef47f..0000000
--- a/core/java/android/flags/IFeatureFlags.aidl
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2023 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.flags;
-
-import android.flags.IFeatureFlagsCallback;
-import android.flags.SyncableFlag;
-
-/**
- * Binder interface for communicating with {@link com.android.server.flags.FeatureFlagsService}.
- *
- * This interface is used by {@link android.flags.FeatureFlags} and developers should use that to
- * interface with the service. FeatureFlags is the "client" in this documentation.
- *
- * The methods allow client apps to communicate what flags they care about, and receive back
- * current values for those flags. For stable flags, this is the finalized value until the device
- * restarts. For {@link DynamicFlag}s, this is the last known value, though it may change in the
- * future. Clients can listen for changes to flag values so that it can react accordingly.
- * @hide
- */
-interface IFeatureFlags {
-    /**
-     * Synchronize with the {@link com.android.server.flags.FeatureFlagsService} about flags of
-     * interest.
-     *
-     * The client should pass in a list of flags that it is using as {@link SyncableFlag}s, which
-     * includes what it thinks the default values of the flags are.
-     *
-     * The response will contain a list of matching SyncableFlags, whose values are set to what the
-     * value of the flags actually are. The client should update its internal state flag data to
-     * match.
-     *
-     * Generally speaking, if a flag that is passed in is new to the FeatureFlagsService, the
-     * service will cache the passed-in value, and return it back out. If, however, a different
-     * client has synced that flag with the service previously, FeatureFlagsService will return the
-     * existing cached value, which may or may not be what the current client passed in. This allows
-     * FeatureFlagsService to keep clients in agreement with one another.
-     */
-    List<SyncableFlag> syncFlags(in List<SyncableFlag> flagList);
-
-    /**
-     * Pass in an {@link IFeatureFlagsCallback} that will be called whenever a {@link DymamicFlag}
-     * changes.
-     */
-    void registerCallback(IFeatureFlagsCallback callback);
-
-    /**
-     * Remove a {@link IFeatureFlagsCallback} that was previously registered with
-     * {@link #registerCallback}.
-     */
-    void unregisterCallback(IFeatureFlagsCallback callback);
-}
\ No newline at end of file
diff --git a/core/java/android/flags/IFeatureFlagsCallback.aidl b/core/java/android/flags/IFeatureFlagsCallback.aidl
deleted file mode 100644
index f708667..0000000
--- a/core/java/android/flags/IFeatureFlagsCallback.aidl
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2023 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.flags;
-
-import android.flags.SyncableFlag;
-
-/**
- * Callback for {@link IFeatureFlags#registerCallback} to get alerts when a {@link DynamicFlag}
- * changes.
- *
- * DynamicFlags can change at run time. Stable flags will never result in a call to this method.
- *
- * @hide
- */
-oneway interface IFeatureFlagsCallback {
-    void onFlagChange(in SyncableFlag flag);
-}
\ No newline at end of file
diff --git a/core/java/android/flags/SyncableFlag.aidl b/core/java/android/flags/SyncableFlag.aidl
deleted file mode 100644
index 1526ec1..0000000
--- a/core/java/android/flags/SyncableFlag.aidl
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2023 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.flags;
-
-/**
- * A parcelable data class for serializing {@link Flag} across a Binder.
- */
-parcelable SyncableFlag;
\ No newline at end of file
diff --git a/core/java/android/flags/SyncableFlag.java b/core/java/android/flags/SyncableFlag.java
deleted file mode 100644
index 54c4c6d..0000000
--- a/core/java/android/flags/SyncableFlag.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2023 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.flags;
-
-import android.annotation.NonNull;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-/**
- * @hide
- */
-public final class SyncableFlag implements Parcelable {
-    private final String mNamespace;
-    private final String mName;
-    private String mValue;
-    private final boolean mDynamic;
-
-    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
-    public SyncableFlag(
-            @NonNull String namespace,
-            @NonNull String name,
-            @NonNull String value,
-            boolean dynamic) {
-        mNamespace = namespace;
-        mName = name;
-        mValue = value;
-        mDynamic = dynamic;
-    }
-
-    public void setValue(@NonNull String value) {
-        mValue = value;
-    }
-
-    @NonNull
-    public String getNamespace() {
-        return mNamespace;
-    }
-
-    @NonNull
-    public String getName() {
-        return mName;
-    }
-
-    @NonNull
-    public String getValue() {
-        return mValue;
-    }
-
-    @NonNull
-    public boolean isDynamic() {
-        return mDynamic;
-    }
-
-    @NonNull
-    public static final Parcelable.Creator<SyncableFlag> CREATOR = new Parcelable.Creator<>() {
-        public SyncableFlag createFromParcel(Parcel in) {
-            return new SyncableFlag(
-                    in.readString(), in.readString(), in.readString(), in.readBoolean());
-        }
-
-        public SyncableFlag[] newArray(int size) {
-            return new SyncableFlag[size];
-        }
-    };
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(@NonNull Parcel dest, int flags) {
-        dest.writeString(mNamespace);
-        dest.writeString(mName);
-        dest.writeString(mValue);
-        dest.writeBoolean(mDynamic);
-    }
-
-    @Override
-    public String toString() {
-        return getNamespace() + "." + getName() + "[" + getValue() + "]";
-    }
-}
diff --git a/services/Android.bp b/services/Android.bp
index 453f572..b0a0e5e 100644
--- a/services/Android.bp
+++ b/services/Android.bp
@@ -159,7 +159,6 @@
         "services.coverage",
         "services.credentials",
         "services.devicepolicy",
-        "services.flags",
         "services.midi",
         "services.musicsearch",
         "services.net",
diff --git a/services/flags/Android.bp b/services/flags/Android.bp
deleted file mode 100644
index 29d2b9c..0000000
--- a/services/flags/Android.bp
+++ /dev/null
@@ -1,18 +0,0 @@
-package {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "frameworks_base_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["frameworks_base_license"],
-}
-
-java_library_static {
-    name: "services.flags",
-    defaults: ["platform_service_defaults"],
-    srcs: [
-        "java/**/*.java",
-        ":feature_flags_aidl",
-    ],
-    libs: ["services.core"],
-}
diff --git a/services/flags/OWNERS b/services/flags/OWNERS
deleted file mode 100644
index 3925b5c..0000000
--- a/services/flags/OWNERS
+++ /dev/null
@@ -1,6 +0,0 @@
-# Bug component: 1306523
-
-mankoff@google.com
-
-pixel@google.com
-dsandler@android.com
diff --git a/services/flags/java/com/android/server/flags/DynamicFlagBinderDelegate.java b/services/flags/java/com/android/server/flags/DynamicFlagBinderDelegate.java
deleted file mode 100644
index 322a52bf..0000000
--- a/services/flags/java/com/android/server/flags/DynamicFlagBinderDelegate.java
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * Copyright (C) 2023 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 com.android.server.flags;
-
-import android.annotation.NonNull;
-import android.flags.IFeatureFlagsCallback;
-import android.flags.SyncableFlag;
-import android.os.Build;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.provider.DeviceConfig;
-import android.util.Slog;
-
-import com.android.internal.os.BackgroundThread;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.function.Function;
-
-/**
- * Handles DynamicFlags for {@link FeatureFlagsBinder}.
- *
- * Dynamic flags are simultaneously simpler and more complicated than process stable flags. We can
- * return whatever value is last known for a flag is, without too much worry about the flags
- * changing (they are dynamic after all). However, we have to alert all the relevant clients
- * about those flag changes, and need to be able to restore to a default value if the flag gets
- * reset/erased during runtime.
- */
-class DynamicFlagBinderDelegate {
-
-    private final FlagOverrideStore mFlagStore;
-    private final FlagCache<DynamicFlagData> mDynamicFlags = new FlagCache<>();
-    private final Map<Integer, Set<IFeatureFlagsCallback>> mCallbacks = new HashMap<>();
-    private static final Function<Integer, Set<IFeatureFlagsCallback>> NEW_CALLBACK_SET =
-            k -> new HashSet<>();
-
-    private final DeviceConfig.OnPropertiesChangedListener mDeviceConfigListener =
-            new DeviceConfig.OnPropertiesChangedListener() {
-                @Override
-                public void onPropertiesChanged(@NonNull DeviceConfig.Properties properties) {
-                    String ns = properties.getNamespace();
-                    for (String name : properties.getKeyset()) {
-                        // Don't alert for flags we don't care about.
-                        // Don't alert for flags that have been overridden locally.
-                        if (!mDynamicFlags.contains(ns, name) || mFlagStore.contains(ns, name)) {
-                            continue;
-                        }
-                        mFlagChangeCallback.onFlagChanged(
-                                ns, name, properties.getString(name, null));
-                    }
-                }
-            };
-
-    private final FlagOverrideStore.FlagChangeCallback mFlagChangeCallback =
-            (namespace, name, value) -> {
-                // Don't bother with callbacks for non-dynamic flags.
-                if (!mDynamicFlags.contains(namespace, name)) {
-                    return;
-                }
-
-                // Don't bother with callbacks if nothing changed.
-                // Handling erasure (null) is special, as we may be restoring back to a value
-                // we were already at.
-                DynamicFlagData data = mDynamicFlags.getOrNull(namespace, name);
-                if (data == null) {
-                    return;  // shouldn't happen, but better safe than sorry.
-                }
-                if (value == null) {
-                    if (data.getValue().equals(data.getDefaultValue())) {
-                        return;
-                    }
-                    value = data.getDefaultValue();
-                } else if (data.getValue().equals(value)) {
-                    return;
-                }
-                data.setValue(value);
-
-                final Set<IFeatureFlagsCallback> cbCopy;
-                synchronized (mCallbacks) {
-                    cbCopy = new HashSet<>();
-
-                    for (Integer pid : mCallbacks.keySet()) {
-                        if (data.containsPid(pid)) {
-                            cbCopy.addAll(mCallbacks.get(pid));
-                        }
-                    }
-                }
-                SyncableFlag sFlag = new SyncableFlag(namespace, name, value, true);
-                cbCopy.forEach(cb -> {
-                    try {
-                        cb.onFlagChange(sFlag);
-                    } catch (RemoteException e) {
-                        Slog.w(
-                                FeatureFlagsService.TAG,
-                                "Failed to communicate flag change to client.");
-                    }
-                });
-            };
-
-    DynamicFlagBinderDelegate(FlagOverrideStore flagStore) {
-        mFlagStore = flagStore;
-        mFlagStore.setChangeCallback(mFlagChangeCallback);
-    }
-
-    void syncDynamicFlag(int pid, SyncableFlag sf) {
-        if (!sf.isDynamic()) {
-            return;
-        }
-
-        String ns = sf.getNamespace();
-        String name = sf.getName();
-
-        // Dynamic flags don't need any special threading or synchronization considerations.
-        // We simply give them whatever the current value is.
-        // However, we do need to keep track of dynamic flags, so that we can alert
-        // about changes coming in from adb, DeviceConfig, or other sources.
-        // And also so that we can keep flags relatively consistent across processes.
-
-        // If we already have a value cached, just use that.
-        String value = null;
-        DynamicFlagData data = mDynamicFlags.getOrNull(ns, name);
-        if (data != null) {
-            value = data.getValue();
-        } else {
-            // Put the value in the cache for future reference.
-            data = new DynamicFlagData(ns, name);
-            mDynamicFlags.setIfChanged(ns, name, data);
-        }
-        // If we're not in a release build, flags can be overridden locally on device.
-        if (!Build.IS_USER && value == null) {
-            value = mFlagStore.get(ns, name);
-        }
-        // If we still don't have a value, maybe DeviceConfig does?
-        // Fallback to sf.getValue() here as well.
-        if (value == null) {
-            value = DeviceConfig.getString(ns, name, sf.getValue());
-        }
-        // DeviceConfig listeners are per-namespace.
-        if (!mDynamicFlags.containsNamespace(ns)) {
-            DeviceConfig.addOnPropertiesChangedListener(
-                    ns, BackgroundThread.getExecutor(), mDeviceConfigListener);
-        }
-        data.addClientPid(pid);
-        data.setValue(value);
-        // Store the default value so that if an override gets erased, we can restore
-        // to something.
-        data.setDefaultValue(sf.getValue());
-
-        sf.setValue(value);
-    }
-
-
-    void registerCallback(int pid, IFeatureFlagsCallback callback) {
-        // Always add callback so that we don't end up with a possible race/leak.
-        // We remove the callback directly if we fail to call #linkToDeath.
-        // If we tried to add the callback after we linked, then we could end up in a
-        // scenario where we link, then the binder dies, firing our BinderGriever which tries
-        // to remove the callback (which has not yet been added), then finally we add the
-        // callback, creating a leak.
-        Set<IFeatureFlagsCallback> callbacks;
-        synchronized (mCallbacks) {
-            callbacks = mCallbacks.computeIfAbsent(pid, NEW_CALLBACK_SET);
-            callbacks.add(callback);
-        }
-        try {
-            callback.asBinder().linkToDeath(new BinderGriever(pid), 0);
-        } catch (RemoteException e) {
-            Slog.e(
-                    FeatureFlagsService.TAG,
-                    "Failed to link to binder death. Callback not registered.");
-            synchronized (mCallbacks) {
-                callbacks.remove(callback);
-            }
-        }
-    }
-
-    void unregisterCallback(int pid, IFeatureFlagsCallback callback) {
-        // No need to unlink, since the BinderGriever will essentially be a no-op.
-        // We would have to track our BinderGriever's in a map otherwise.
-        synchronized (mCallbacks) {
-            Set<IFeatureFlagsCallback> callbacks =
-                    mCallbacks.computeIfAbsent(pid, NEW_CALLBACK_SET);
-            callbacks.remove(callback);
-        }
-    }
-
-    private static class DynamicFlagData {
-        private final String mNamespace;
-        private final String mName;
-        private final Set<Integer> mPids = new HashSet<>();
-        private String mValue;
-        private String mDefaultValue;
-
-        private DynamicFlagData(String namespace, String name) {
-            mNamespace = namespace;
-            mName = name;
-        }
-
-        String getValue() {
-            return mValue;
-        }
-
-        void setValue(String value) {
-            mValue = value;
-        }
-
-        String getDefaultValue() {
-            return mDefaultValue;
-        }
-
-        void setDefaultValue(String value) {
-            mDefaultValue = value;
-        }
-
-        void addClientPid(int pid) {
-            mPids.add(pid);
-        }
-
-        boolean containsPid(int pid) {
-            return mPids.contains(pid);
-        }
-
-        @Override
-        public boolean equals(Object other) {
-            if (other == null || !(other instanceof DynamicFlagData)) {
-                return false;
-            }
-
-            DynamicFlagData o = (DynamicFlagData) other;
-
-            return mName.equals(o.mName) && mNamespace.equals(o.mNamespace)
-                    && mValue.equals(o.mValue) && mDefaultValue.equals(o.mDefaultValue);
-        }
-
-        @Override
-        public int hashCode() {
-            return mName.hashCode() + mNamespace.hashCode()
-              + mValue.hashCode() + mDefaultValue.hashCode();
-        }
-    }
-
-
-    private class BinderGriever implements IBinder.DeathRecipient {
-        private final int mPid;
-
-        private BinderGriever(int pid) {
-            mPid = pid;
-        }
-
-        @Override
-        public void binderDied() {
-            synchronized (mCallbacks) {
-                mCallbacks.remove(mPid);
-            }
-        }
-    }
-}
diff --git a/services/flags/java/com/android/server/flags/FeatureFlagsBinder.java b/services/flags/java/com/android/server/flags/FeatureFlagsBinder.java
deleted file mode 100644
index dc97fde..0000000
--- a/services/flags/java/com/android/server/flags/FeatureFlagsBinder.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2023 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 com.android.server.flags;
-
-import android.annotation.NonNull;
-import android.annotation.SystemApi;
-import android.flags.IFeatureFlags;
-import android.flags.IFeatureFlagsCallback;
-import android.flags.SyncableFlag;
-import android.os.Build;
-import android.os.ParcelFileDescriptor;
-
-import java.io.FileOutputStream;
-import java.util.List;
-
-class FeatureFlagsBinder extends IFeatureFlags.Stub {
-    private final FlagOverrideStore mFlagStore;
-    private final FlagsShellCommand mShellCommand;
-    private final FlagCache<String> mFlagCache = new FlagCache<>();
-    private final DynamicFlagBinderDelegate mDynamicFlagDelegate;
-
-    FeatureFlagsBinder(FlagOverrideStore flagStore, FlagsShellCommand shellCommand) {
-        mFlagStore = flagStore;
-        mShellCommand = shellCommand;
-        mDynamicFlagDelegate = new DynamicFlagBinderDelegate(flagStore);
-    }
-
-    @Override
-    public void registerCallback(IFeatureFlagsCallback callback) {
-        mDynamicFlagDelegate.registerCallback(getCallingPid(), callback);
-    }
-
-    @Override
-    public void unregisterCallback(IFeatureFlagsCallback callback) {
-        mDynamicFlagDelegate.unregisterCallback(getCallingPid(), callback);
-    }
-
-    @Override
-    public List<SyncableFlag> syncFlags(List<SyncableFlag> incomingFlags) {
-        int pid = getCallingPid();
-        for (SyncableFlag sf : incomingFlags) {
-            String ns = sf.getNamespace();
-            String name = sf.getName();
-            if (sf.isDynamic()) {
-                mDynamicFlagDelegate.syncDynamicFlag(pid, sf);
-            } else {
-                synchronized (mFlagCache) {
-                    String value = mFlagCache.getOrNull(ns, name);
-                    if (value == null) {
-                        String overrideValue = Build.IS_USER ? null : mFlagStore.get(ns, name);
-                        value = overrideValue != null ? overrideValue : sf.getValue();
-                        mFlagCache.setIfChanged(ns, name, value);
-                    }
-                    sf.setValue(value);
-                }
-            }
-        }
-        return incomingFlags;
-    }
-
-    @SystemApi
-    public int handleShellCommand(
-            @NonNull ParcelFileDescriptor in,
-            @NonNull ParcelFileDescriptor out,
-            @NonNull ParcelFileDescriptor err,
-            @NonNull String[] args) {
-        FileOutputStream fout = new FileOutputStream(out.getFileDescriptor());
-        FileOutputStream ferr = new FileOutputStream(err.getFileDescriptor());
-
-        return mShellCommand.process(args, fout, ferr);
-    }
-}
diff --git a/services/flags/java/com/android/server/flags/FeatureFlagsService.java b/services/flags/java/com/android/server/flags/FeatureFlagsService.java
deleted file mode 100644
index 111fad0..0000000
--- a/services/flags/java/com/android/server/flags/FeatureFlagsService.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2023 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 com.android.server.flags;
-
-import android.content.Context;
-import android.util.Slog;
-
-import com.android.server.SystemService;
-
-/**
- * A service that manages syncing {@link android.flags.FeatureFlags} across processes.
- *
- * This service holds flags stable for at least the lifetime of a process, meaning that if
- * a process comes online with a flag set to true, any other process that connects here and
- * tries to read the same flag will also receive the flag as true. The flag will remain stable
- * until either all of the interested processes have died, or the device restarts.
- *
- * TODO(279054964): Add to dumpsys
- * @hide
- */
-public class FeatureFlagsService extends SystemService {
-
-    static final String TAG = "FeatureFlagsService";
-    private final FlagOverrideStore mFlagStore;
-    private final FlagsShellCommand mShellCommand;
-
-    /**
-     * Initializes the system service.
-     *
-     * @param context The system server context.
-     */
-    public FeatureFlagsService(Context context) {
-        super(context);
-        mFlagStore = new FlagOverrideStore(
-                new GlobalSettingsProxy(context.getContentResolver()));
-        mShellCommand = new FlagsShellCommand(mFlagStore);
-    }
-
-    @Override
-    public void onStart() {
-        Slog.d(TAG, "Started Feature Flag Service");
-        publishBinderService(
-                Context.FEATURE_FLAGS_SERVICE, new FeatureFlagsBinder(mFlagStore, mShellCommand));
-    }
-
-}
diff --git a/services/flags/java/com/android/server/flags/FlagCache.java b/services/flags/java/com/android/server/flags/FlagCache.java
deleted file mode 100644
index cee1578..0000000
--- a/services/flags/java/com/android/server/flags/FlagCache.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2023 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 com.android.server.flags;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.function.Function;
-
-/**
- * Threadsafe cache of values that stores the supplied default on cache miss.
- *
- * @param <V> The type of value to store.
- */
-public class FlagCache<V> {
-    private final Function<String, HashMap<String, V>> mNewHashMap = k -> new HashMap<>();
-
-    // Cache is organized first by namespace, then by name. All values are stored as strings.
-    final Map<String, Map<String, V>> mCache = new HashMap<>();
-
-    FlagCache() {
-    }
-
-    /**
-     * Returns true if the namespace exists in the cache already.
-     */
-    boolean containsNamespace(String namespace) {
-        synchronized (mCache) {
-            return mCache.containsKey(namespace);
-        }
-    }
-
-    /**
-     * Returns true if the value is stored in the cache.
-     */
-    boolean contains(String namespace, String name) {
-        synchronized (mCache) {
-            Map<String, V> nsCache = mCache.get(namespace);
-            return nsCache != null && nsCache.containsKey(name);
-        }
-    }
-
-    /**
-     * Sets the value if it is different from what is currently stored.
-     *
-     * If the value is not set, or the current value is null, it will store the value and
-     * return true.
-     *
-     * @return True if the value was set. False if the value is the same.
-     */
-    boolean setIfChanged(String namespace, String name, V value) {
-        synchronized (mCache) {
-            Map<String, V> nsCache = mCache.computeIfAbsent(namespace, mNewHashMap);
-            V curValue = nsCache.get(name);
-            if (curValue == null || !curValue.equals(value)) {
-                nsCache.put(name, value);
-                return true;
-            }
-            return false;
-        }
-    }
-
-    /**
-     * Gets the current value from the cache, setting it if it is currently absent.
-     *
-     * @return The value that is now in the cache after the call to the method.
-     */
-    V getOrSet(String namespace, String name, V defaultValue) {
-        synchronized (mCache) {
-            Map<String, V> nsCache = mCache.computeIfAbsent(namespace, mNewHashMap);
-            V value = nsCache.putIfAbsent(name, defaultValue);
-            return value == null ? defaultValue : value;
-        }
-    }
-
-    /**
-     * Gets the current value from the cache, returning null if not present.
-     *
-     * @return The value that is now in the cache if there is one.
-     */
-    V getOrNull(String namespace, String name) {
-        synchronized (mCache) {
-            Map<String, V> nsCache = mCache.get(namespace);
-            if (nsCache == null) {
-                return null;
-            }
-            return nsCache.get(name);
-        }
-    }
-}
diff --git a/services/flags/java/com/android/server/flags/FlagOverrideStore.java b/services/flags/java/com/android/server/flags/FlagOverrideStore.java
deleted file mode 100644
index 9866b1c..0000000
--- a/services/flags/java/com/android/server/flags/FlagOverrideStore.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2023 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 com.android.server.flags;
-
-import android.database.Cursor;
-import android.provider.Settings;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Persistent storage for the {@link FeatureFlagsService}.
- *
- * The implementation stores data in Settings.<store> (generally {@link Settings.Global}
- * is expected).
- */
-@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
-public class FlagOverrideStore {
-    private static final String KEYNAME_PREFIX = "flag|";
-    private static final String NAMESPACE_NAME_SEPARATOR = ".";
-
-    private final SettingsProxy mSettingsProxy;
-
-    private FlagChangeCallback mCallback;
-
-    FlagOverrideStore(SettingsProxy settingsProxy) {
-        mSettingsProxy = settingsProxy;
-    }
-
-    void setChangeCallback(FlagChangeCallback callback) {
-        mCallback = callback;
-    }
-
-    /** Returns true if a non-null value is in the store. */
-    boolean contains(String namespace, String name) {
-        return get(namespace, name) != null;
-    }
-
-    /** Put a value in the store. */
-    void set(String namespace, String name, String value) {
-        mSettingsProxy.putString(getPropName(namespace, name), value);
-        mCallback.onFlagChanged(namespace, name, value);
-    }
-
-    /** Read a value out of the store. */
-    @VisibleForTesting
-    public String get(String namespace, String name) {
-        return mSettingsProxy.getString(getPropName(namespace, name));
-    }
-
-    /** Erase a value from the store. */
-    void erase(String namespace, String name) {
-        set(namespace, name, null);
-    }
-
-    Map<String, Map<String, String>> getFlags() {
-        return getFlagsForNamespace(null);
-    }
-
-    Map<String, Map<String, String>> getFlagsForNamespace(String namespace) {
-        Cursor c = mSettingsProxy.getContentResolver().query(
-                Settings.Global.CONTENT_URI,
-                new String[]{Settings.NameValueTable.NAME, Settings.NameValueTable.VALUE},
-                null, // Doesn't support a "LIKE" query
-                null,
-                null
-        );
-
-        if (c == null) {
-            return Map.of();
-        }
-        int keynamePrefixLength = KEYNAME_PREFIX.length();
-        Map<String, Map<String, String>> results = new HashMap<>();
-        while (c.moveToNext()) {
-            String key = c.getString(0);
-            if (!key.startsWith(KEYNAME_PREFIX)
-                    || key.indexOf(NAMESPACE_NAME_SEPARATOR, keynamePrefixLength) < 0) {
-                continue;
-            }
-            String value = c.getString(1);
-            if (value == null || value.isEmpty()) {
-                continue;
-            }
-            String ns = key.substring(keynamePrefixLength, key.indexOf(NAMESPACE_NAME_SEPARATOR));
-            if (namespace != null && !namespace.equals(ns)) {
-                continue;
-            }
-            String name = key.substring(key.indexOf(NAMESPACE_NAME_SEPARATOR) + 1);
-            results.putIfAbsent(ns, new HashMap<>());
-            results.get(ns).put(name, value);
-        }
-        c.close();
-        return results;
-    }
-
-    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
-    static String getPropName(String namespace, String name) {
-        return KEYNAME_PREFIX + namespace + NAMESPACE_NAME_SEPARATOR + name;
-    }
-
-    interface FlagChangeCallback {
-        void onFlagChanged(String namespace, String name, String value);
-    }
-}
diff --git a/services/flags/java/com/android/server/flags/FlagsShellCommand.java b/services/flags/java/com/android/server/flags/FlagsShellCommand.java
deleted file mode 100644
index b7896ee..0000000
--- a/services/flags/java/com/android/server/flags/FlagsShellCommand.java
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Copyright (C) 2023 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 com.android.server.flags;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.FastPrintWriter;
-
-import java.io.OutputStream;
-import java.io.PrintWriter;
-import java.util.Locale;
-import java.util.Map;
-
-/**
- * Process command line input for the flags service.
- */
-@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
-public class FlagsShellCommand {
-    private final FlagOverrideStore mFlagStore;
-
-    FlagsShellCommand(FlagOverrideStore flagStore) {
-        mFlagStore = flagStore;
-    }
-
-    /**
-     * Interpret the command supplied in the constructor.
-     *
-     * @return Zero on success or non-zero on error.
-     */
-    public int process(
-            String[] args,
-            OutputStream out,
-            OutputStream err) {
-        PrintWriter outPw = new FastPrintWriter(out);
-        PrintWriter errPw = new FastPrintWriter(err);
-
-        if (args.length == 0) {
-            return printHelp(outPw);
-        }
-        switch (args[0].toLowerCase(Locale.ROOT)) {
-            case "help":
-                return printHelp(outPw);
-            case "list":
-                return listCmd(args, outPw, errPw);
-            case "set":
-                return setCmd(args, outPw, errPw);
-            case "get":
-                return getCmd(args, outPw, errPw);
-            case "erase":
-                return eraseCmd(args, outPw, errPw);
-            default:
-                return unknownCmd(outPw);
-        }
-    }
-
-    private int printHelp(PrintWriter outPw) {
-        outPw.println("Feature Flags command, allowing listing, setting, getting, and erasing of");
-        outPw.println("local flag overrides on a device.");
-        outPw.println();
-        outPw.println("Commands:");
-        outPw.println("  list [namespace]");
-        outPw.println("    List all flag overrides. Namespace is optional.");
-        outPw.println();
-        outPw.println("  get <namespace> <name>");
-        outPw.println("    Return the string value of a specific flag, or <unset>");
-        outPw.println();
-        outPw.println("  set <namespace> <name> <value>");
-        outPw.println("    Set a specific flag");
-        outPw.println();
-        outPw.println("  erase <namespace> <name>");
-        outPw.println("    Unset a specific flag");
-        outPw.flush();
-        return 0;
-    }
-
-    private int listCmd(String[] args, PrintWriter outPw, PrintWriter errPw) {
-        if (!validateNumArguments(args, 0, 1, args[0], errPw)) {
-            errPw.println("Expected `" + args[0] + " [namespace]`");
-            errPw.flush();
-            return -1;
-        }
-        Map<String, Map<String, String>> overrides;
-        if (args.length == 2) {
-            overrides = mFlagStore.getFlagsForNamespace(args[1]);
-        } else {
-            overrides = mFlagStore.getFlags();
-        }
-        if (overrides.isEmpty()) {
-            outPw.println("No overrides set");
-        } else {
-            int longestNamespaceLen = "namespace".length();
-            int longestFlagLen = "flag".length();
-            int longestValLen = "value".length();
-            for (Map.Entry<String, Map<String, String>> namespace : overrides.entrySet()) {
-                longestNamespaceLen = Math.max(longestNamespaceLen, namespace.getKey().length());
-                for (Map.Entry<String, String> flag : namespace.getValue().entrySet()) {
-                    longestFlagLen = Math.max(longestFlagLen, flag.getKey().length());
-                    longestValLen = Math.max(longestValLen, flag.getValue().length());
-                }
-            }
-            outPw.print(String.format("%-" + longestNamespaceLen + "s", "namespace"));
-            outPw.print(' ');
-            outPw.print(String.format("%-" + longestFlagLen + "s", "flag"));
-            outPw.print(' ');
-            outPw.println("value");
-            for (int i = 0; i < longestNamespaceLen; i++) {
-                outPw.print('=');
-            }
-            outPw.print(' ');
-            for (int i = 0; i < longestFlagLen; i++) {
-                outPw.print('=');
-            }
-            outPw.print(' ');
-            for (int i = 0; i < longestValLen; i++) {
-                outPw.print('=');
-            }
-            outPw.println();
-            for (Map.Entry<String, Map<String, String>> namespace : overrides.entrySet()) {
-                for (Map.Entry<String, String> flag : namespace.getValue().entrySet()) {
-                    outPw.print(
-                            String.format("%-" + longestNamespaceLen + "s", namespace.getKey()));
-                    outPw.print(' ');
-                    outPw.print(String.format("%-" + longestFlagLen + "s", flag.getKey()));
-                    outPw.print(' ');
-                    outPw.println(flag.getValue());
-                }
-            }
-        }
-        outPw.flush();
-        return 0;
-    }
-
-    private int setCmd(String[] args, PrintWriter outPw, PrintWriter errPw) {
-        if (!validateNumArguments(args, 3, args[0], errPw)) {
-            errPw.println("Expected `" + args[0] + " <namespace> <name> <value>`");
-            errPw.flush();
-            return -1;
-        }
-        mFlagStore.set(args[1], args[2], args[3]);
-        outPw.println("Flag " + args[1] + "." + args[2] + " is now " + args[3]);
-        outPw.flush();
-        return 0;
-    }
-
-    private int getCmd(String[] args, PrintWriter outPw, PrintWriter errPw) {
-        if (!validateNumArguments(args, 2, args[0], errPw)) {
-            errPw.println("Expected `" + args[0] + " <namespace> <name>`");
-            errPw.flush();
-            return -1;
-        }
-
-        String value = mFlagStore.get(args[1], args[2]);
-        outPw.print(args[1] + "." + args[2] + " is ");
-        if (value == null || value.isEmpty()) {
-            outPw.println("<unset>");
-        } else {
-            outPw.println("\"" + value.translateEscapes() + "\"");
-        }
-        outPw.flush();
-        return 0;
-    }
-
-    private int eraseCmd(String[] args, PrintWriter outPw, PrintWriter errPw) {
-        if (!validateNumArguments(args, 2, args[0], errPw)) {
-            errPw.println("Expected `" + args[0] + " <namespace> <name>`");
-            errPw.flush();
-            return -1;
-        }
-        mFlagStore.erase(args[1], args[2]);
-        outPw.println("Erased " + args[1] + "." + args[2]);
-        return 0;
-    }
-
-    private int unknownCmd(PrintWriter outPw) {
-        outPw.println("This command is unknown.");
-        printHelp(outPw);
-        outPw.flush();
-        return -1;
-    }
-
-    private boolean validateNumArguments(
-            String[] args, int exactly, String cmdName, PrintWriter errPw) {
-        return validateNumArguments(args, exactly, exactly, cmdName, errPw);
-    }
-
-    private boolean validateNumArguments(
-            String[] args, int min, int max, String cmdName, PrintWriter errPw) {
-        int len = args.length - 1; // Discount the command itself.
-        if (len < min) {
-            errPw.println(
-                    "Less than " + min + " arguments provided for \"" + cmdName + "\" command.");
-            return false;
-        } else if (len > max) {
-            errPw.println(
-                    "More than " + max + " arguments provided for \"" + cmdName + "\" command.");
-            return false;
-        }
-
-        return true;
-    }
-}
diff --git a/services/flags/java/com/android/server/flags/GlobalSettingsProxy.java b/services/flags/java/com/android/server/flags/GlobalSettingsProxy.java
deleted file mode 100644
index acb7bb5..0000000
--- a/services/flags/java/com/android/server/flags/GlobalSettingsProxy.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2023 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 com.android.server.flags;
-
-import android.content.ContentResolver;
-import android.net.Uri;
-import android.provider.Settings;
-
-class GlobalSettingsProxy implements SettingsProxy {
-    private final ContentResolver mContentResolver;
-
-    GlobalSettingsProxy(ContentResolver contentResolver) {
-        mContentResolver = contentResolver;
-    }
-
-    @Override
-    public ContentResolver getContentResolver() {
-        return mContentResolver;
-    }
-
-    @Override
-    public Uri getUriFor(String name) {
-        return Settings.Global.getUriFor(name);
-    }
-
-    @Override
-    public String getStringForUser(String name, int userHandle) {
-        return Settings.Global.getStringForUser(mContentResolver, name, userHandle);
-    }
-
-    @Override
-    public boolean putString(String name, String value, boolean overrideableByRestore) {
-        throw new UnsupportedOperationException(
-                "This method only exists publicly for Settings.System and Settings.Secure");
-    }
-
-    @Override
-    public boolean putStringForUser(String name, String value, int userHandle) {
-        return Settings.Global.putStringForUser(mContentResolver, name, value, userHandle);
-    }
-
-    @Override
-    public boolean putStringForUser(String name, String value, String tag, boolean makeDefault,
-            int userHandle, boolean overrideableByRestore) {
-        return Settings.Global.putStringForUser(
-                mContentResolver, name, value, tag, makeDefault, userHandle,
-                overrideableByRestore);
-    }
-
-    @Override
-    public boolean putString(String name, String value, String tag, boolean makeDefault) {
-        return Settings.Global.putString(mContentResolver, name, value, tag, makeDefault);
-    }
-}
diff --git a/services/flags/java/com/android/server/flags/SettingsProxy.java b/services/flags/java/com/android/server/flags/SettingsProxy.java
deleted file mode 100644
index c6e85d5..0000000
--- a/services/flags/java/com/android/server/flags/SettingsProxy.java
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
- * Copyright (C) 2023 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 com.android.server.flags;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.UserIdInt;
-import android.content.ContentResolver;
-import android.database.ContentObserver;
-import android.net.Uri;
-import android.provider.Settings;
-
-/**
- * Wrapper class meant to enable hermetic testing of {@link Settings}.
- *
- * Implementations of this class are expected to be constructed with a {@link ContentResolver} or,
- * otherwise have access to an implicit one. All the proxy methods in this class exclude
- * {@link ContentResolver} from their signature and rely on an internally defined one instead.
- *
- * Most methods in the {@link Settings} classes have default implementations defined.
- * Implementations of this interfac need only concern themselves with getting and putting Strings.
- * They should also override any methods for a class they are proxying that _are not_ defined, and
- * throw an appropriate {@link UnsupportedOperationException}. For instance, {@link Settings.Global}
- * does not define {@link #putString(String, String, boolean)}, so an implementation of this
- * interface that proxies through to it should throw an exception when that method is called.
- *
- * This class adds in the following helpers as well:
- *  - {@link #getBool(String)}
- *  - {@link #putBool(String, boolean)}
- *  - {@link #registerContentObserver(Uri, ContentObserver)}
- *
- * ... and similar variations for all of those.
- */
-public interface SettingsProxy {
-
-    /**
-     * Returns the {@link ContentResolver} this instance uses.
-     */
-    ContentResolver getContentResolver();
-
-    /**
-     * Construct the content URI for a particular name/value pair,
-     * useful for monitoring changes with a ContentObserver.
-     * @param name to look up in the table
-     * @return the corresponding content URI, or null if not present
-     */
-    Uri getUriFor(String name);
-
-    /**See {@link Settings.Secure#getString(ContentResolver, String)} */
-    String getStringForUser(String name, int userHandle);
-
-    /**See {@link Settings.Secure#putString(ContentResolver, String, String, boolean)} */
-    boolean putString(String name, String value, boolean overrideableByRestore);
-
-    /** See {@link Settings.Secure#putStringForUser(ContentResolver, String, String, int)} */
-    boolean putStringForUser(String name, String value, int userHandle);
-
-    /**
-     * See {@link Settings.Secure#putStringForUser(ContentResolver, String, String, String, boolean,
-     * int, boolean)}
-     */
-    boolean putStringForUser(@NonNull String name, @Nullable String value, @Nullable String tag,
-            boolean makeDefault, @UserIdInt int userHandle, boolean overrideableByRestore);
-
-    /** See {@link Settings.Secure#putString(ContentResolver, String, String, String, boolean)} */
-    boolean putString(@NonNull String name, @Nullable String value, @Nullable String tag,
-            boolean makeDefault);
-
-    /**
-     * Returns the user id for the associated {@link ContentResolver}.
-     */
-    default int getUserId() {
-        return getContentResolver().getUserId();
-    }
-
-    /** See {@link Settings.Secure#getString(ContentResolver, String)} */
-    default String getString(String name) {
-        return getStringForUser(name, getUserId());
-    }
-
-    /** See {@link Settings.Secure#putString(ContentResolver, String, String)} */
-    default boolean putString(String name, String value) {
-        return putStringForUser(name, value, getUserId());
-    }
-    /** See {@link Settings.Secure#getIntForUser(ContentResolver, String, int, int)} */
-    default int getIntForUser(String name, int def, int userHandle) {
-        String v = getStringForUser(name, userHandle);
-        try {
-            return v != null ? Integer.parseInt(v) : def;
-        } catch (NumberFormatException e) {
-            return def;
-        }
-    }
-
-    /** See {@link Settings.Secure#getInt(ContentResolver, String)}  */
-    default int getInt(String name) throws Settings.SettingNotFoundException {
-        return getIntForUser(name, getUserId());
-    }
-
-    /** See {@link Settings.Secure#getIntForUser(ContentResolver, String, int)} */
-    default int getIntForUser(String name, int userHandle)
-            throws Settings.SettingNotFoundException {
-        String v = getStringForUser(name, userHandle);
-        try {
-            return Integer.parseInt(v);
-        } catch (NumberFormatException e) {
-            throw new Settings.SettingNotFoundException(name);
-        }
-    }
-
-    /** See {@link Settings.Secure#putInt(ContentResolver, String, int)} */
-    default boolean putInt(String name, int value) {
-        return putIntForUser(name, value, getUserId());
-    }
-
-    /** See {@link Settings.Secure#putIntForUser(ContentResolver, String, int, int)} */
-    default boolean putIntForUser(String name, int value, int userHandle) {
-        return putStringForUser(name, Integer.toString(value), userHandle);
-    }
-
-    /**
-     * Convenience function for retrieving a single settings value
-     * as a boolean.  Note that internally setting values are always
-     * stored as strings; this function converts the string to a boolean
-     * for you. The default value will be returned if the setting is
-     * not defined or not a boolean.
-     *
-     * @param name The name of the setting to retrieve.
-     * @param def Value to return if the setting is not defined.
-     *
-     * @return The setting's current value, or 'def' if it is not defined
-     * or not a valid boolean.
-     */
-    default boolean getBool(String name, boolean def) {
-        return getBoolForUser(name, def, getUserId());
-    }
-
-    /** See {@link #getBool(String, boolean)}. */
-    default boolean getBoolForUser(String name, boolean def, int userHandle) {
-        return getIntForUser(name, def ? 1 : 0, userHandle) != 0;
-    }
-
-    /**
-     * Convenience function for retrieving a single settings value
-     * as a boolean.  Note that internally setting values are always
-     * stored as strings; this function converts the string to a boolean
-     * for you.
-     * <p>
-     * This version does not take a default value.  If the setting has not
-     * been set, or the string value is not a number,
-     * it throws {@link Settings.SettingNotFoundException}.
-     *
-     * @param name The name of the setting to retrieve.
-     *
-     * @throws Settings.SettingNotFoundException Thrown if a setting by the given
-     * name can't be found or the setting value is not a boolean.
-     *
-     * @return The setting's current value.
-     */
-    default boolean getBool(String name) throws Settings.SettingNotFoundException {
-        return getBoolForUser(name, getUserId());
-    }
-
-    /** See {@link #getBool(String)}. */
-    default boolean getBoolForUser(String name, int userHandle)
-            throws Settings.SettingNotFoundException {
-        return getIntForUser(name, userHandle) != 0;
-    }
-
-    /**
-     * Convenience function for updating a single settings value as a
-     * boolean. This will either create a new entry in the table if the
-     * given name does not exist, or modify the value of the existing row
-     * with that name.  Note that internally setting values are always
-     * stored as strings, so this function converts the given value to a
-     * string before storing it.
-     *
-     * @param name The name of the setting to modify.
-     * @param value The new value for the setting.
-     * @return true if the value was set, false on database errors
-     */
-    default boolean putBool(String name, boolean value) {
-        return putBoolForUser(name, value, getUserId());
-    }
-
-    /** See {@link #putBool(String, boolean)}. */
-    default boolean putBoolForUser(String name, boolean value, int userHandle) {
-        return putIntForUser(name, value ? 1 : 0, userHandle);
-    }
-
-    /** See {@link Settings.Secure#getLong(ContentResolver, String, long)}  */
-    default long getLong(String name, long def) {
-        return getLongForUser(name, def, getUserId());
-    }
-
-    /** See {@link Settings.Secure#getLongForUser(ContentResolver, String, long, int)}  */
-    default long getLongForUser(String name, long def, int userHandle) {
-        String valString = getStringForUser(name, userHandle);
-        long value;
-        try {
-            value = valString != null ? Long.parseLong(valString) : def;
-        } catch (NumberFormatException e) {
-            value = def;
-        }
-        return value;
-    }
-
-    /** See {@link Settings.Secure#getLong(ContentResolver, String)}  */
-    default long getLong(String name) throws Settings.SettingNotFoundException {
-        return getLongForUser(name, getUserId());
-    }
-
-    /** See {@link Settings.Secure#getLongForUser(ContentResolver, String, int)}  */
-    default long getLongForUser(String name, int userHandle)
-            throws Settings.SettingNotFoundException {
-        String valString = getStringForUser(name, userHandle);
-        try {
-            return Long.parseLong(valString);
-        } catch (NumberFormatException e) {
-            throw new Settings.SettingNotFoundException(name);
-        }
-    }
-
-    /** See {@link Settings.Secure#putLong(ContentResolver, String, long)} */
-    default boolean putLong(String name, long value) {
-        return putLongForUser(name, value, getUserId());
-    }
-
-    /** See {@link Settings.Secure#putLongForUser(ContentResolver, String, long, int)}  */
-    default boolean putLongForUser(String name, long value, int userHandle) {
-        return putStringForUser(name, Long.toString(value), userHandle);
-    }
-
-    /** See {@link Settings.Secure#getFloat(ContentResolver, String, float)} */
-    default float getFloat(String name, float def) {
-        return getFloatForUser(name, def, getUserId());
-    }
-
-    /** See {@link Settings.Secure#getFloatForUser(ContentResolver, String, int)} */
-    default float getFloatForUser(String name, float def, int userHandle) {
-        String v = getStringForUser(name, userHandle);
-        try {
-            return v != null ? Float.parseFloat(v) : def;
-        } catch (NumberFormatException e) {
-            return def;
-        }
-    }
-
-
-    /** See {@link Settings.Secure#getFloat(ContentResolver, String)}  */
-    default float getFloat(String name) throws Settings.SettingNotFoundException {
-        return getFloatForUser(name, getUserId());
-    }
-
-    /** See {@link Settings.Secure#getFloatForUser(ContentResolver, String, int)}   */
-    default float getFloatForUser(String name, int userHandle)
-            throws Settings.SettingNotFoundException {
-        String v = getStringForUser(name, userHandle);
-        if (v == null) {
-            throw new Settings.SettingNotFoundException(name);
-        }
-        try {
-            return Float.parseFloat(v);
-        } catch (NumberFormatException e) {
-            throw new Settings.SettingNotFoundException(name);
-        }
-    }
-
-    /** See {@link Settings.Secure#putFloat(ContentResolver, String, float)} */
-    default boolean putFloat(String name, float value) {
-        return putFloatForUser(name, value, getUserId());
-    }
-
-    /** See {@link Settings.Secure#putFloatForUser(ContentResolver, String, float, int)} */
-    default boolean putFloatForUser(String name, float value, int userHandle) {
-        return putStringForUser(name, Float.toString(value), userHandle);
-    }
-
-    /**
-     * Convenience wrapper around
-     * {@link ContentResolver#registerContentObserver(Uri, boolean, ContentObserver)}.'
-     *
-     * Implicitly calls {@link #getUriFor(String)} on the passed in name.
-     */
-    default void registerContentObserver(String name, ContentObserver settingsObserver) {
-        registerContentObserver(getUriFor(name), settingsObserver);
-    }
-
-    /**
-     * Convenience wrapper around
-     * {@link ContentResolver#registerContentObserver(Uri, boolean, ContentObserver)}.'
-     */
-    default void registerContentObserver(Uri uri, ContentObserver settingsObserver) {
-        registerContentObserverForUser(uri, settingsObserver, getUserId());
-    }
-
-    /**
-     * Convenience wrapper around
-     * {@link ContentResolver#registerContentObserver(Uri, boolean, ContentObserver)}.
-     *
-     * Implicitly calls {@link #getUriFor(String)} on the passed in name.
-     */
-    default void registerContentObserver(String name, boolean notifyForDescendants,
-            ContentObserver settingsObserver) {
-        registerContentObserver(getUriFor(name), notifyForDescendants, settingsObserver);
-    }
-
-    /**
-     * Convenience wrapper around
-     * {@link ContentResolver#registerContentObserver(Uri, boolean, ContentObserver)}.'
-     */
-    default void registerContentObserver(Uri uri, boolean notifyForDescendants,
-            ContentObserver settingsObserver) {
-        registerContentObserverForUser(uri, notifyForDescendants, settingsObserver, getUserId());
-    }
-
-    /**
-     * Convenience wrapper around
-     * {@link ContentResolver#registerContentObserver(Uri, boolean, ContentObserver, int)}
-     *
-     * Implicitly calls {@link #getUriFor(String)} on the passed in name.
-     */
-    default void registerContentObserverForUser(
-            String name, ContentObserver settingsObserver, int userHandle) {
-        registerContentObserverForUser(
-                getUriFor(name), settingsObserver, userHandle);
-    }
-
-    /**
-     * Convenience wrapper around
-     * {@link ContentResolver#registerContentObserver(Uri, boolean, ContentObserver, int)}
-     */
-    default void registerContentObserverForUser(
-            Uri uri, ContentObserver settingsObserver, int userHandle) {
-        registerContentObserverForUser(
-                uri, false, settingsObserver, userHandle);
-    }
-
-    /**
-     * Convenience wrapper around
-     * {@link ContentResolver#registerContentObserver(Uri, boolean, ContentObserver, int)}
-     *
-     * Implicitly calls {@link #getUriFor(String)} on the passed in name.
-     */
-    default void registerContentObserverForUser(
-            String name, boolean notifyForDescendants, ContentObserver settingsObserver,
-            int userHandle) {
-        registerContentObserverForUser(
-                getUriFor(name), notifyForDescendants, settingsObserver, userHandle);
-    }
-
-    /**
-     * Convenience wrapper around
-     * {@link ContentResolver#registerContentObserver(Uri, boolean, ContentObserver, int)}
-     */
-    default void registerContentObserverForUser(
-            Uri uri, boolean notifyForDescendants, ContentObserver settingsObserver,
-            int userHandle) {
-        getContentResolver().registerContentObserver(
-                uri, notifyForDescendants, settingsObserver, userHandle);
-    }
-
-    /** See {@link ContentResolver#unregisterContentObserver(ContentObserver)}. */
-    default void unregisterContentObserver(ContentObserver settingsObserver) {
-        getContentResolver().unregisterContentObserver(settingsObserver);
-    }
-}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 7de1279..991248a 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -132,7 +132,6 @@
 import com.android.server.display.color.ColorDisplayService;
 import com.android.server.dreams.DreamManagerService;
 import com.android.server.emergency.EmergencyAffordanceService;
-import com.android.server.flags.FeatureFlagsService;
 import com.android.server.gpu.GpuService;
 import com.android.server.grammaticalinflection.GrammaticalInflectionService;
 import com.android.server.graphics.fonts.FontManagerService;
@@ -1112,12 +1111,6 @@
         mSystemServiceManager.startService(DeviceIdentifiersPolicyService.class);
         t.traceEnd();
 
-        // Starts a service for reading runtime flag overrides, and keeping processes
-        // in sync with one another.
-        t.traceBegin("StartFeatureFlagsService");
-        mSystemServiceManager.startService(FeatureFlagsService.class);
-        t.traceEnd();
-
         // Uri Grants Manager.
         t.traceBegin("UriGrantsManagerService");
         mSystemServiceManager.startService(UriGrantsManagerService.Lifecycle.class);
diff --git a/services/tests/servicestests/Android.bp b/services/tests/servicestests/Android.bp
index 0530f89..ee3a773 100644
--- a/services/tests/servicestests/Android.bp
+++ b/services/tests/servicestests/Android.bp
@@ -34,7 +34,6 @@
         "services.core",
         "services.credentials",
         "services.devicepolicy",
-        "services.flags",
         "services.net",
         "services.people",
         "services.usage",
diff --git a/services/tests/servicestests/src/com/android/server/flags/FeatureFlagsServiceTest.java b/services/tests/servicestests/src/com/android/server/flags/FeatureFlagsServiceTest.java
deleted file mode 100644
index 8455b88..0000000
--- a/services/tests/servicestests/src/com/android/server/flags/FeatureFlagsServiceTest.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright (C) 2023 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 com.android.server.flags;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.flags.IFeatureFlagsCallback;
-import android.flags.SyncableFlag;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.platform.test.annotations.Presubmit;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnit;
-import org.mockito.junit.MockitoRule;
-
-import java.util.List;
-
-@Presubmit
-@SmallTest
-public class FeatureFlagsServiceTest {
-    private static final String NS = "ns";
-    private static final String NAME = "name";
-    private static final String PROP_NAME = FlagOverrideStore.getPropName(NS, NAME);
-
-    @Rule
-    public final MockitoRule mockito = MockitoJUnit.rule();
-
-    @Mock
-    private FlagOverrideStore mFlagStore;
-    @Mock
-    private FlagsShellCommand mFlagCommand;
-    @Mock
-    private IFeatureFlagsCallback mIFeatureFlagsCallback;
-    @Mock
-    private IBinder mIFeatureFlagsCallbackAsBinder;
-
-    private FeatureFlagsBinder mFeatureFlagsService;
-
-    @Before
-    public void setup() {
-        when(mIFeatureFlagsCallback.asBinder()).thenReturn(mIFeatureFlagsCallbackAsBinder);
-        mFeatureFlagsService = new FeatureFlagsBinder(mFlagStore, mFlagCommand);
-    }
-
-    @Test
-    public void testRegisterCallback() {
-        mFeatureFlagsService.registerCallback(mIFeatureFlagsCallback);
-        try {
-            verify(mIFeatureFlagsCallbackAsBinder).linkToDeath(any(), eq(0));
-        } catch (RemoteException e) {
-            fail("Our mock threw a Remote Exception?");
-        }
-    }
-
-    @Test
-    public void testSyncFlags_noOverrides() {
-        List<SyncableFlag> inputFlags = List.of(
-                new SyncableFlag(NS, "a", "false", false),
-                new SyncableFlag(NS, "b", "true", false),
-                new SyncableFlag(NS, "c", "false", false)
-        );
-
-        List<SyncableFlag> outputFlags = mFeatureFlagsService.syncFlags(inputFlags);
-
-        assertThat(inputFlags.size()).isEqualTo(outputFlags.size());
-
-        for (SyncableFlag inpF: inputFlags) {
-            boolean found = false;
-            for (SyncableFlag outF : outputFlags) {
-                if (compareSyncableFlagsNames(inpF, outF)) {
-                    found = true;
-                    break;
-                }
-            }
-            assertWithMessage("Failed to find input flag " + inpF + " in the output")
-                    .that(found).isTrue();
-        }
-    }
-
-    @Test
-    public void testSyncFlags_withSomeOverrides() {
-        List<SyncableFlag> inputFlags = List.of(
-                new SyncableFlag(NS, "a", "false", false),
-                new SyncableFlag(NS, "b", "true", false),
-                new SyncableFlag(NS, "c", "false", false)
-        );
-
-        assertThat(mFlagStore).isNotNull();
-        when(mFlagStore.get(NS, "c")).thenReturn("true");
-        List<SyncableFlag> outputFlags = mFeatureFlagsService.syncFlags(inputFlags);
-
-        assertThat(inputFlags.size()).isEqualTo(outputFlags.size());
-
-        for (SyncableFlag inpF: inputFlags) {
-            boolean found = false;
-            for (SyncableFlag outF : outputFlags) {
-                if (compareSyncableFlagsNames(inpF, outF)) {
-                    found = true;
-
-                    // Once we've found "c", do an extra check
-                    if (outF.getName().equals("c")) {
-                        assertWithMessage("Flag " + outF + "was not returned with an override")
-                                .that(outF.getValue()).isEqualTo("true");
-                    }
-                    break;
-                }
-            }
-            assertWithMessage("Failed to find input flag " + inpF + " in the output")
-                    .that(found).isTrue();
-        }
-    }
-
-
-    @Test
-    public void testSyncFlags_twoCallsWithDifferentDefaults() {
-        List<SyncableFlag> inputFlagsFirst = List.of(
-                new SyncableFlag(NS, "a", "false", false)
-        );
-        List<SyncableFlag> inputFlagsSecond = List.of(
-                new SyncableFlag(NS, "a", "true", false),
-                new SyncableFlag(NS, "b", "false", false)
-        );
-
-        List<SyncableFlag> outputFlagsFirst = mFeatureFlagsService.syncFlags(inputFlagsFirst);
-        List<SyncableFlag> outputFlagsSecond = mFeatureFlagsService.syncFlags(inputFlagsSecond);
-
-        assertThat(inputFlagsFirst.size()).isEqualTo(outputFlagsFirst.size());
-        assertThat(inputFlagsSecond.size()).isEqualTo(outputFlagsSecond.size());
-
-        // This test only cares that the "a" flag passed in the second time came out with the
-        // same value that was passed in the first time.
-
-        boolean found = false;
-        for (SyncableFlag second : outputFlagsSecond) {
-            if (compareSyncableFlagsNames(second, inputFlagsFirst.get(0))) {
-                found = true;
-                assertThat(second.getValue()).isEqualTo(inputFlagsFirst.get(0).getValue());
-                break;
-            }
-        }
-
-        assertWithMessage(
-                "Failed to find flag " + inputFlagsFirst.get(0) + " in the second calls output")
-                .that(found).isTrue();
-    }
-
-    private static boolean compareSyncableFlagsNames(SyncableFlag a, SyncableFlag b) {
-        return a.getNamespace().equals(b.getNamespace())
-                && a.getName().equals(b.getName())
-                && a.isDynamic() == b.isDynamic();
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/flags/FlagCacheTest.java b/services/tests/servicestests/src/com/android/server/flags/FlagCacheTest.java
deleted file mode 100644
index c2cf540..0000000
--- a/services/tests/servicestests/src/com/android/server/flags/FlagCacheTest.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2023 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 com.android.server.flags;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-@RunWith(JUnit4.class)
-public class FlagCacheTest {
-    private static final String NS = "ns";
-    private static final String NAME = "name";
-
-    FlagCache mFlagCache = new FlagCache();
-
-    @Test
-    public void testGetOrNull_unset() {
-        assertThat(mFlagCache.getOrNull(NS, NAME)).isNull();
-    }
-
-    @Test
-    public void testGetOrSet_unset() {
-        assertThat(mFlagCache.getOrSet(NS, NAME, "value")).isEqualTo("value");
-    }
-
-    @Test
-    public void testGetOrSet_alreadySet() {
-        mFlagCache.setIfChanged(NS, NAME, "value");
-        assertThat(mFlagCache.getOrSet(NS, NAME, "newvalue")).isEqualTo("value");
-    }
-
-    @Test
-    public void testSetIfChanged_unset() {
-        assertThat(mFlagCache.setIfChanged(NS, NAME, "value")).isTrue();
-    }
-
-    @Test
-    public void testSetIfChanged_noChange() {
-        mFlagCache.setIfChanged(NS, NAME, "value");
-        assertThat(mFlagCache.setIfChanged(NS, NAME, "value")).isFalse();
-    }
-
-    @Test
-    public void testSetIfChanged_changing() {
-        mFlagCache.setIfChanged(NS, NAME, "value");
-        assertThat(mFlagCache.setIfChanged(NS, NAME, "newvalue")).isTrue();
-    }
-
-    @Test
-    public void testContainsNamespace_unset() {
-        assertThat(mFlagCache.containsNamespace(NS)).isFalse();
-    }
-
-    @Test
-    public void testContainsNamespace_set() {
-        mFlagCache.setIfChanged(NS, NAME, "value");
-        assertThat(mFlagCache.containsNamespace(NS)).isTrue();
-    }
-
-    @Test
-    public void testContains_unset() {
-        assertThat(mFlagCache.contains(NS, NAME)).isFalse();
-    }
-
-    @Test
-    public void testContains_set() {
-        mFlagCache.setIfChanged(NS, NAME, "value");
-        assertThat(mFlagCache.contains(NS, NAME)).isTrue();
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/flags/FlagOverrideStoreTest.java b/services/tests/servicestests/src/com/android/server/flags/FlagOverrideStoreTest.java
deleted file mode 100644
index 6cc3acf..0000000
--- a/services/tests/servicestests/src/com/android/server/flags/FlagOverrideStoreTest.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2023 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 com.android.server.flags;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.platform.test.annotations.Presubmit;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnit;
-import org.mockito.junit.MockitoRule;
-
-@Presubmit
-@SmallTest
-public class FlagOverrideStoreTest {
-    private static final String NS = "ns";
-    private static final String NAME = "name";
-    private static final String PROP_NAME = FlagOverrideStore.getPropName(NS, NAME);
-
-    @Rule
-    public final MockitoRule mockito = MockitoJUnit.rule();
-
-    @Mock
-    private SettingsProxy mSettingsProxy;
-    @Mock
-    private FlagOverrideStore.FlagChangeCallback mCallback;
-
-    private FlagOverrideStore mFlagStore;
-
-    @Before
-    public void setup() {
-        mFlagStore = new FlagOverrideStore(mSettingsProxy);
-        mFlagStore.setChangeCallback(mCallback);
-    }
-
-    @Test
-    public void testSet_unset() {
-        mFlagStore.set(NS, NAME, "value");
-        verify(mSettingsProxy).putString(PROP_NAME, "value");
-    }
-
-    @Test
-    public void testSet_setTwice() {
-        mFlagStore.set(NS, NAME, "value");
-        mFlagStore.set(NS, NAME, "newvalue");
-        verify(mSettingsProxy).putString(PROP_NAME, "value");
-        verify(mSettingsProxy).putString(PROP_NAME, "newvalue");
-    }
-
-    @Test
-    public void testGet_unset() {
-        assertThat(mFlagStore.get(NS, NAME)).isNull();
-    }
-
-    @Test
-    public void testGet_set() {
-        when(mSettingsProxy.getString(PROP_NAME)).thenReturn("value");
-        assertThat(mFlagStore.get(NS, NAME)).isEqualTo("value");
-    }
-
-    @Test
-    public void testErase() {
-        mFlagStore.erase(NS, NAME);
-        verify(mSettingsProxy).putString(PROP_NAME, null);
-    }
-
-    @Test
-    public void testContains_unset() {
-        assertThat(mFlagStore.contains(NS, NAME)).isFalse();
-    }
-
-    @Test
-    public void testContains_set() {
-        when(mSettingsProxy.getString(PROP_NAME)).thenReturn("value");
-        assertThat(mFlagStore.contains(NS, NAME)).isTrue();
-    }
-
-    @Test
-    public void testCallback_onSet() {
-        mFlagStore.set(NS, NAME, "value");
-        verify(mCallback).onFlagChanged(NS, NAME, "value");
-    }
-
-    @Test
-    public void testCallback_onErase() {
-        mFlagStore.erase(NS, NAME);
-        verify(mCallback).onFlagChanged(NS, NAME, null);
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/flags/OWNERS b/services/tests/servicestests/src/com/android/server/flags/OWNERS
deleted file mode 100644
index 7ed369e..0000000
--- a/services/tests/servicestests/src/com/android/server/flags/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-include /services/flags/OWNERS