changes the API setChannelMaxPowers from hide API to system API

This CL changes the hiden API `setChannelMaxPowers` to system API
to allow the privilege app to set the max power of each Thread channel.

Bug: b/346686506
Test: atest CtsThreadNetworkTestCases
Change-Id: I1089a4a315971c3bca8ec688a02143ddec93d039
diff --git a/common/thread_flags.aconfig b/common/thread_flags.aconfig
index 0edb7a8..a3f77a7 100644
--- a/common/thread_flags.aconfig
+++ b/common/thread_flags.aconfig
@@ -15,4 +15,12 @@
     namespace: "thread_network"
     description: "Controls whether the Android Thread configuration is enabled"
     bug: "342519412"
-}
\ No newline at end of file
+}
+
+flag {
+    name: "channel_max_powers_enabled"
+    is_exported: true
+    namespace: "thread_network"
+    description: "Controls whether the Android Thread setting max power of channel feature is enabled"
+    bug: "346686506"
+}
diff --git a/framework-t/api/system-current.txt b/framework-t/api/system-current.txt
index 2354882..9f26bcf 100644
--- a/framework-t/api/system-current.txt
+++ b/framework-t/api/system-current.txt
@@ -516,6 +516,7 @@
     method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_NETWORK_STATE, "android.permission.THREAD_NETWORK_PRIVILEGED"}) public void registerOperationalDatasetCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.thread.ThreadNetworkController.OperationalDatasetCallback);
     method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public void registerStateCallback(@NonNull java.util.concurrent.Executor, @NonNull android.net.thread.ThreadNetworkController.StateCallback);
     method @RequiresPermission("android.permission.THREAD_NETWORK_PRIVILEGED") public void scheduleMigration(@NonNull android.net.thread.PendingOperationalDataset, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.lang.Void,android.net.thread.ThreadNetworkException>);
+    method @FlaggedApi("com.android.net.thread.flags.channel_max_powers_enabled") @RequiresPermission("android.permission.THREAD_NETWORK_PRIVILEGED") public void setChannelMaxPowers(@NonNull @Size(min=1) android.util.SparseIntArray, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.lang.Void,android.net.thread.ThreadNetworkException>);
     method @RequiresPermission("android.permission.THREAD_NETWORK_PRIVILEGED") public void setEnabled(boolean, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.lang.Void,android.net.thread.ThreadNetworkException>);
     method @FlaggedApi("com.android.net.thread.flags.configuration_enabled") @RequiresPermission(android.Manifest.permission.THREAD_NETWORK_PRIVILEGED) public void unregisterConfigurationCallback(@NonNull java.util.function.Consumer<android.net.thread.ThreadConfiguration>);
     method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_NETWORK_STATE, "android.permission.THREAD_NETWORK_PRIVILEGED"}) public void unregisterOperationalDatasetCallback(@NonNull android.net.thread.ThreadNetworkController.OperationalDatasetCallback);
@@ -525,6 +526,7 @@
     field public static final int DEVICE_ROLE_LEADER = 4; // 0x4
     field public static final int DEVICE_ROLE_ROUTER = 3; // 0x3
     field public static final int DEVICE_ROLE_STOPPED = 0; // 0x0
+    field public static final int MAX_POWER_CHANNEL_DISABLED = -2147483648; // 0x80000000
     field public static final int STATE_DISABLED = 0; // 0x0
     field public static final int STATE_DISABLING = 2; // 0x2
     field public static final int STATE_ENABLED = 1; // 0x1
@@ -557,6 +559,7 @@
     field public static final int ERROR_UNAVAILABLE = 4; // 0x4
     field public static final int ERROR_UNKNOWN = 11; // 0xb
     field public static final int ERROR_UNSUPPORTED_CHANNEL = 7; // 0x7
+    field public static final int ERROR_UNSUPPORTED_FEATURE = 13; // 0xd
   }
 
   @FlaggedApi("com.android.net.thread.flags.thread_enabled") public final class ThreadNetworkManager {
diff --git a/thread/framework/java/android/net/thread/ThreadNetworkController.java b/thread/framework/java/android/net/thread/ThreadNetworkController.java
index 551b98f..ecaefd0 100644
--- a/thread/framework/java/android/net/thread/ThreadNetworkController.java
+++ b/thread/framework/java/android/net/thread/ThreadNetworkController.java
@@ -26,6 +26,7 @@
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
 import android.annotation.Size;
+import android.annotation.SuppressLint;
 import android.annotation.SystemApi;
 import android.os.Binder;
 import android.os.OutcomeReceiver;
@@ -102,11 +103,12 @@
     /** Thread standard version 1.3. */
     public static final int THREAD_VERSION_1_3 = 4;
 
-    /** Minimum value of max power in unit of 0.01dBm. @hide */
-    private static final int POWER_LIMITATION_MIN = -32768;
-
-    /** Maximum value of max power in unit of 0.01dBm. @hide */
-    private static final int POWER_LIMITATION_MAX = 32767;
+    /** The value of max power to disable the Thread channel. */
+    // This constant can never change. It has "max" in the name not because it indicates
+    // maximum power, but because it's passed to an API that sets the maximum power to
+    // disabled the Thread channel.
+    @SuppressLint("MinMaxConstant")
+    public static final int MAX_POWER_CHANNEL_DISABLED = Integer.MIN_VALUE;
 
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
@@ -704,6 +706,10 @@
     /**
      * Sets max power of each channel.
      *
+     * <p>This method sets the max power for the given channel. The platform sets the actual
+     * output power to be less than or equal to the {@code channelMaxPowers} and as close as
+     * possible to the {@code channelMaxPowers}.
+     *
      * <p>If not set, the default max power is set by the Thread HAL service or the Thread radio
      * chip firmware.
      *
@@ -712,22 +718,27 @@
      * OutcomeReceiver#onError} will be called with a specific error:
      *
      * <ul>
-     *   <li>{@link ThreadNetworkException#ERROR_UNSUPPORTED_OPERATION} the operation is no
-     *       supported by the platform.
+     *   <li>{@link ThreadNetworkException#ERROR_UNSUPPORTED_FEATURE} the feature is not supported
+     *       by the platform.
      * </ul>
      *
      * @param channelMaxPowers SparseIntArray (key: channel, value: max power) consists of channel
      *     and corresponding max power. Valid channel values should be between {@link
      *     ActiveOperationalDataset#CHANNEL_MIN_24_GHZ} and {@link
-     *     ActiveOperationalDataset#CHANNEL_MAX_24_GHZ}. The unit of the max power is 0.01dBm. Max
-     *     power values should be between INT16_MIN (-32768) and INT16_MAX (32767). If the max power
-     *     is set to INT16_MAX, the corresponding channel is not supported.
+     *     ActiveOperationalDataset#CHANNEL_MAX_24_GHZ}. The unit of the max power is 0.01dBm. For
+     *     example, 1000 means 0.01W and 2000 means 0.1W. If the power value of
+     *     {@code channelMaxPowers} is lower than the minimum output power supported by the
+     *     platform, the output power will be set to the minimum output power supported by the
+     *     platform. If the power value of {@code channelMaxPowers} is higher than the maximum
+     *     output power supported by the platform, the output power will be set to the maximum
+     *     output power supported by the platform. If the power value of {@code channelMaxPowers}
+     *     is set to {@link #MAX_POWER_CHANNEL_DISABLED}, the corresponding channel is disabled.
      * @param executor the executor to execute {@code receiver}.
      * @param receiver the receiver to receive the result of this operation.
      * @throws IllegalArgumentException if the size of {@code channelMaxPowers} is smaller than 1,
      *     or invalid channel or max power is configured.
-     * @hide
      */
+    @FlaggedApi(Flags.FLAG_CHANNEL_MAX_POWERS_ENABLED)
     @RequiresPermission("android.permission.THREAD_NETWORK_PRIVILEGED")
     public final void setChannelMaxPowers(
             @NonNull @Size(min = 1) SparseIntArray channelMaxPowers,
@@ -756,19 +767,6 @@
                                 + ActiveOperationalDataset.CHANNEL_MAX_24_GHZ
                                 + "]");
             }
-
-            if ((maxPower < POWER_LIMITATION_MIN) || (maxPower > POWER_LIMITATION_MAX)) {
-                throw new IllegalArgumentException(
-                        "Channel power ({channel: "
-                                + channel
-                                + ", maxPower: "
-                                + maxPower
-                                + "}) exceeds allowed range ["
-                                + POWER_LIMITATION_MIN
-                                + ", "
-                                + POWER_LIMITATION_MAX
-                                + "]");
-            }
         }
 
         try {
diff --git a/thread/framework/java/android/net/thread/ThreadNetworkException.java b/thread/framework/java/android/net/thread/ThreadNetworkException.java
index b6973f8..1ea2459 100644
--- a/thread/framework/java/android/net/thread/ThreadNetworkException.java
+++ b/thread/framework/java/android/net/thread/ThreadNetworkException.java
@@ -141,16 +141,14 @@
     public static final int ERROR_THREAD_DISABLED = 12;
 
     /**
-     * The operation failed because it is not supported by the platform. For example, some platforms
-     * may not support setting the target power of each channel. The caller should not retry and may
-     * return an error to the user.
-     *
-     * @hide
+     * The operation failed because the feature is not supported by the platform. For example, some
+     * platforms may not support setting the target power of each channel. The caller should not
+     * retry and may return an error to the user.
      */
-    public static final int ERROR_UNSUPPORTED_OPERATION = 13;
+    public static final int ERROR_UNSUPPORTED_FEATURE = 13;
 
     private static final int ERROR_MIN = ERROR_INTERNAL_ERROR;
-    private static final int ERROR_MAX = ERROR_UNSUPPORTED_OPERATION;
+    private static final int ERROR_MAX = ERROR_UNSUPPORTED_FEATURE;
 
     private final int mErrorCode;
 
diff --git a/thread/service/java/com/android/server/thread/ThreadNetworkControllerService.java b/thread/service/java/com/android/server/thread/ThreadNetworkControllerService.java
index b621a6a..452fab9 100644
--- a/thread/service/java/com/android/server/thread/ThreadNetworkControllerService.java
+++ b/thread/service/java/com/android/server/thread/ThreadNetworkControllerService.java
@@ -40,7 +40,7 @@
 import static android.net.thread.ThreadNetworkException.ERROR_THREAD_DISABLED;
 import static android.net.thread.ThreadNetworkException.ERROR_TIMEOUT;
 import static android.net.thread.ThreadNetworkException.ERROR_UNSUPPORTED_CHANNEL;
-import static android.net.thread.ThreadNetworkException.ERROR_UNSUPPORTED_OPERATION;
+import static android.net.thread.ThreadNetworkException.ERROR_UNSUPPORTED_FEATURE;
 import static android.net.thread.ThreadNetworkManager.DISALLOW_THREAD_NETWORK;
 import static android.net.thread.ThreadNetworkManager.PERMISSION_THREAD_NETWORK_PRIVILEGED;
 
@@ -1055,7 +1055,7 @@
             case OT_ERROR_BUSY:
                 return ERROR_BUSY;
             case OT_ERROR_NOT_IMPLEMENTED:
-                return ERROR_UNSUPPORTED_OPERATION;
+                return ERROR_UNSUPPORTED_FEATURE;
             case OT_ERROR_NO_BUFS:
                 return ERROR_RESOURCE_EXHAUSTED;
             case OT_ERROR_PARSE:
diff --git a/thread/tests/cts/Android.bp b/thread/tests/cts/Android.bp
index 6db7c9c..6572755 100644
--- a/thread/tests/cts/Android.bp
+++ b/thread/tests/cts/Android.bp
@@ -40,6 +40,7 @@
     static_libs: [
         "androidx.test.ext.junit",
         "compatibility-device-util-axt",
+        "com.android.net.thread.flags-aconfig-java",
         "ctstestrunner-axt",
         "guava",
         "guava-android-testlib",
diff --git a/thread/tests/cts/src/android/net/thread/cts/ThreadNetworkControllerTest.java b/thread/tests/cts/src/android/net/thread/cts/ThreadNetworkControllerTest.java
index 1a101b6..c048394 100644
--- a/thread/tests/cts/src/android/net/thread/cts/ThreadNetworkControllerTest.java
+++ b/thread/tests/cts/src/android/net/thread/cts/ThreadNetworkControllerTest.java
@@ -35,6 +35,7 @@
 import static android.net.thread.ThreadNetworkException.ERROR_FAILED_PRECONDITION;
 import static android.net.thread.ThreadNetworkException.ERROR_REJECTED_BY_PEER;
 import static android.net.thread.ThreadNetworkException.ERROR_THREAD_DISABLED;
+import static android.net.thread.ThreadNetworkException.ERROR_UNSUPPORTED_FEATURE;
 
 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
 
@@ -70,12 +71,15 @@
 import android.os.Build;
 import android.os.HandlerThread;
 import android.os.OutcomeReceiver;
+import android.platform.test.annotations.RequiresFlagsEnabled;
+import android.util.SparseIntArray;
 
 import androidx.annotation.NonNull;
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.filters.LargeTest;
 
 import com.android.net.module.util.ArrayTrackRecord;
+import com.android.net.thread.flags.Flags;
 import com.android.testutils.FunctionalUtils.ThrowingRunnable;
 
 import org.junit.After;
@@ -116,11 +120,20 @@
     private static final int SET_CONFIGURATION_TIMEOUT_MILLIS = 1_000;
     private static final int SERVICE_DISCOVERY_TIMEOUT_MILLIS = 30_000;
     private static final int SERVICE_LOST_TIMEOUT_MILLIS = 20_000;
+    private static final int VALID_POWER = 32_767;
+    private static final int VALID_CHANNEL = 20;
+    private static final int INVALID_CHANNEL = 10;
     private static final String MESHCOP_SERVICE_TYPE = "_meshcop._udp";
     private static final String THREAD_NETWORK_PRIVILEGED =
             "android.permission.THREAD_NETWORK_PRIVILEGED";
     private static final ThreadConfiguration DEFAULT_CONFIG =
             new ThreadConfiguration.Builder().build();
+    private static final SparseIntArray CHANNEL_MAX_POWERS =
+            new SparseIntArray() {
+                {
+                    put(VALID_CHANNEL, VALID_POWER);
+                }
+            };
 
     @Rule public final ThreadFeatureCheckerRule mThreadRule = new ThreadFeatureCheckerRule();
 
@@ -1460,4 +1473,52 @@
         @Override
         public void onServiceInfoCallbackUnregistered() {}
     }
+
+    @Test
+    @RequiresFlagsEnabled({Flags.FLAG_CHANNEL_MAX_POWERS_ENABLED})
+    public void setChannelMaxPowers_withPrivilegedPermission_success() throws Exception {
+        CompletableFuture<Void> powerFuture = new CompletableFuture<>();
+
+        runAsShell(
+                THREAD_NETWORK_PRIVILEGED,
+                () ->
+                        mController.setChannelMaxPowers(
+                                CHANNEL_MAX_POWERS, mExecutor, newOutcomeReceiver(powerFuture)));
+
+        try {
+            assertThat(powerFuture.get()).isNull();
+        } catch (ExecutionException exception) {
+            ThreadNetworkException thrown = (ThreadNetworkException) exception.getCause();
+            assertThat(thrown.getErrorCode()).isEqualTo(ERROR_UNSUPPORTED_FEATURE);
+        }
+    }
+
+    @Test
+    @RequiresFlagsEnabled({Flags.FLAG_CHANNEL_MAX_POWERS_ENABLED})
+    public void setChannelMaxPowers_withoutPrivilegedPermission_throwsSecurityException()
+            throws Exception {
+        dropAllPermissions();
+
+        assertThrows(
+                SecurityException.class,
+                () -> mController.setChannelMaxPowers(CHANNEL_MAX_POWERS, mExecutor, v -> {}));
+    }
+
+    @Test
+    @RequiresFlagsEnabled({Flags.FLAG_CHANNEL_MAX_POWERS_ENABLED})
+    public void setChannelMaxPowers_invalidChannel_throwsIllegalArgumentException() {
+        final SparseIntArray INVALID_CHANNEL_ARRAY =
+                new SparseIntArray() {
+                    {
+                        put(INVALID_CHANNEL, VALID_POWER);
+                    }
+                };
+
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> mController.setChannelMaxPowers(new SparseIntArray(), mExecutor, v -> {}));
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> mController.setChannelMaxPowers(INVALID_CHANNEL_ARRAY, mExecutor, v -> {}));
+    }
 }
diff --git a/thread/tests/integration/src/android/net/thread/ThreadNetworkControllerTest.java b/thread/tests/integration/src/android/net/thread/ThreadNetworkControllerTest.java
deleted file mode 100644
index ba04348..0000000
--- a/thread/tests/integration/src/android/net/thread/ThreadNetworkControllerTest.java
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright (C) 2024 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.net.thread;
-
-import static android.net.thread.ThreadNetworkException.ERROR_UNSUPPORTED_OPERATION;
-
-import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
-
-import static com.android.testutils.TestPermissionUtil.runAsShell;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.junit.Assert.assertThrows;
-
-import android.content.Context;
-import android.net.thread.utils.ThreadFeatureCheckerRule;
-import android.net.thread.utils.ThreadFeatureCheckerRule.RequiresThreadFeature;
-import android.os.OutcomeReceiver;
-import android.util.SparseIntArray;
-
-import androidx.test.core.app.ApplicationProvider;
-import androidx.test.filters.LargeTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-/** Tests for hide methods of {@link ThreadNetworkController}. */
-@LargeTest
-@RequiresThreadFeature
-@RunWith(AndroidJUnit4.class)
-public class ThreadNetworkControllerTest {
-    private static final int VALID_POWER = 32_767;
-    private static final int INVALID_POWER = 32_768;
-    private static final int VALID_CHANNEL = 20;
-    private static final int INVALID_CHANNEL = 10;
-    private static final String THREAD_NETWORK_PRIVILEGED =
-            "android.permission.THREAD_NETWORK_PRIVILEGED";
-
-    private static final SparseIntArray CHANNEL_MAX_POWERS =
-            new SparseIntArray() {
-                {
-                    put(20, 32767);
-                }
-            };
-
-    @Rule public final ThreadFeatureCheckerRule mThreadRule = new ThreadFeatureCheckerRule();
-
-    private final Context mContext = ApplicationProvider.getApplicationContext();
-    private ExecutorService mExecutor;
-    private ThreadNetworkController mController;
-
-    @Before
-    public void setUp() throws Exception {
-        mController =
-                mContext.getSystemService(ThreadNetworkManager.class)
-                        .getAllThreadNetworkControllers()
-                        .get(0);
-
-        mExecutor = Executors.newSingleThreadExecutor();
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        dropAllPermissions();
-    }
-
-    @Test
-    public void setChannelMaxPowers_withPrivilegedPermission_success() throws Exception {
-        CompletableFuture<Void> powerFuture = new CompletableFuture<>();
-
-        runAsShell(
-                THREAD_NETWORK_PRIVILEGED,
-                () ->
-                        mController.setChannelMaxPowers(
-                                CHANNEL_MAX_POWERS, mExecutor, newOutcomeReceiver(powerFuture)));
-
-        try {
-            assertThat(powerFuture.get()).isNull();
-        } catch (ExecutionException exception) {
-            ThreadNetworkException thrown = (ThreadNetworkException) exception.getCause();
-            assertThat(thrown.getErrorCode()).isEqualTo(ERROR_UNSUPPORTED_OPERATION);
-        }
-    }
-
-    @Test
-    public void setChannelMaxPowers_withoutPrivilegedPermission_throwsSecurityException()
-            throws Exception {
-        dropAllPermissions();
-
-        assertThrows(
-                SecurityException.class,
-                () -> mController.setChannelMaxPowers(CHANNEL_MAX_POWERS, mExecutor, v -> {}));
-    }
-
-    @Test
-    public void setChannelMaxPowers_emptyChannelMaxPower_throwsIllegalArgumentException() {
-        assertThrows(
-                IllegalArgumentException.class,
-                () -> mController.setChannelMaxPowers(new SparseIntArray(), mExecutor, v -> {}));
-    }
-
-    @Test
-    public void setChannelMaxPowers_invalidChannel_throwsIllegalArgumentException() {
-        final SparseIntArray INVALID_CHANNEL_ARRAY =
-                new SparseIntArray() {
-                    {
-                        put(INVALID_CHANNEL, VALID_POWER);
-                    }
-                };
-
-        assertThrows(
-                IllegalArgumentException.class,
-                () -> mController.setChannelMaxPowers(INVALID_CHANNEL_ARRAY, mExecutor, v -> {}));
-    }
-
-    @Test
-    public void setChannelMaxPowers_invalidPower_throwsIllegalArgumentException() {
-        final SparseIntArray INVALID_POWER_ARRAY =
-                new SparseIntArray() {
-                    {
-                        put(VALID_CHANNEL, INVALID_POWER);
-                    }
-                };
-
-        assertThrows(
-                IllegalArgumentException.class,
-                () -> mController.setChannelMaxPowers(INVALID_POWER_ARRAY, mExecutor, v -> {}));
-    }
-
-    private static void dropAllPermissions() {
-        getInstrumentation().getUiAutomation().dropShellPermissionIdentity();
-    }
-
-    private static <V> OutcomeReceiver<V, ThreadNetworkException> newOutcomeReceiver(
-            CompletableFuture<V> future) {
-        return new OutcomeReceiver<V, ThreadNetworkException>() {
-            @Override
-            public void onResult(V result) {
-                future.complete(result);
-            }
-
-            @Override
-            public void onError(ThreadNetworkException e) {
-                future.completeExceptionally(e);
-            }
-        };
-    }
-}
diff --git a/thread/tests/unit/src/android/net/thread/ThreadNetworkControllerTest.java b/thread/tests/unit/src/android/net/thread/ThreadNetworkControllerTest.java
index ac74372..0423578 100644
--- a/thread/tests/unit/src/android/net/thread/ThreadNetworkControllerTest.java
+++ b/thread/tests/unit/src/android/net/thread/ThreadNetworkControllerTest.java
@@ -19,7 +19,7 @@
 import static android.net.thread.ThreadNetworkController.DEVICE_ROLE_CHILD;
 import static android.net.thread.ThreadNetworkException.ERROR_UNAVAILABLE;
 import static android.net.thread.ThreadNetworkException.ERROR_UNSUPPORTED_CHANNEL;
-import static android.net.thread.ThreadNetworkException.ERROR_UNSUPPORTED_OPERATION;
+import static android.net.thread.ThreadNetworkException.ERROR_UNSUPPORTED_FEATURE;
 import static android.os.Process.SYSTEM_UID;
 
 import static com.google.common.io.BaseEncoding.base16;
@@ -394,7 +394,7 @@
         doAnswer(
                         invoke -> {
                             getSetChannelMaxPowersReceiver(invoke)
-                                    .onError(ERROR_UNSUPPORTED_OPERATION, "");
+                                    .onError(ERROR_UNSUPPORTED_FEATURE, "");
                             return null;
                         })
                 .when(mMockService)