Accept @Enforce on interface definition

The @Enforce annotation may be used on interfaces in combination with
annotations at the method level. If both are present, both are verified.
For now, this is only implemented for the Java backend.

Move permission-related golden tests to its own directory.

Bug: 197828948
Test: atest --host aidl_unittests
Change-Id: I57fe072c616ddc2652bff911adbda1a79841742a
diff --git a/Android.bp b/Android.bp
index 9fcac01..4a0a933 100644
--- a/Android.bp
+++ b/Android.bp
@@ -287,7 +287,6 @@
         "tests/android/aidl/tests/INamedCallback.aidl",
         "tests/android/aidl/tests/INewName.aidl",
         "tests/android/aidl/tests/IOldName.aidl",
-        "tests/android/aidl/tests/IProtected.aidl",
         "tests/android/aidl/tests/ITestService.aidl",
         "tests/android/aidl/tests/IntEnum.aidl",
         "tests/android/aidl/tests/LongEnum.aidl",
@@ -298,8 +297,9 @@
         "tests/android/aidl/tests/Union.aidl",
         "tests/android/aidl/tests/UnionWithFd.aidl",
         "tests/android/aidl/tests/extension/*.aidl",
-        "tests/android/aidl/tests/unions/*.aidl",
         "tests/android/aidl/tests/nested/*.aidl",
+        "tests/android/aidl/tests/permission/*.aidl",
+        "tests/android/aidl/tests/unions/*.aidl",
     ],
     path: "tests",
 }
diff --git a/aidl_language.cpp b/aidl_language.cpp
index d924433..199689d 100644
--- a/aidl_language.cpp
+++ b/aidl_language.cpp
@@ -181,7 +181,7 @@
        {{"value", kStringArrayType, /* required= */ true}}},
       {AidlAnnotation::Type::ENFORCE,
        "Enforce",
-       CONTEXT_METHOD,
+       CONTEXT_TYPE_INTERFACE | CONTEXT_METHOD,
        {{"condition", kStringType, /* required= */ true}}},
   };
   return kSchemas;
@@ -442,14 +442,13 @@
 }
 
 // Parses the @Enforce annotation expression.
-std::unique_ptr<perm::Expression> AidlAnnotatable::EnforceExpression(
-    const AidlNode& context) const {
+std::unique_ptr<perm::Expression> AidlAnnotatable::EnforceExpression() const {
   auto annot = GetAnnotation(annotations_, AidlAnnotation::Type::ENFORCE);
   if (annot) {
     auto perm_expr = annot->EnforceExpression();
     if (!perm_expr.ok()) {
       // This should have been caught during validation.
-      AIDL_FATAL(context) << "Unable to parse @Enforce annotation: " << perm_expr.error();
+      AIDL_FATAL(this) << "Unable to parse @Enforce annotation: " << perm_expr.error();
     }
     return std::move(perm_expr.value());
   }
diff --git a/aidl_language.h b/aidl_language.h
index d790e05..7e20e03 100644
--- a/aidl_language.h
+++ b/aidl_language.h
@@ -354,7 +354,7 @@
   const AidlAnnotation* RustDerive() const;
   const AidlAnnotation* BackingType() const;
   std::vector<std::string> SuppressWarnings() const;
-  std::unique_ptr<perm::Expression> EnforceExpression(const AidlNode&) const;
+  std::unique_ptr<perm::Expression> EnforceExpression() const;
 
   // ToString is for dumping AIDL.
   // Returns string representation of annotations.
diff --git a/aidl_unittest.cpp b/aidl_unittest.cpp
index fd3c3e3..e8e852d 100644
--- a/aidl_unittest.cpp
+++ b/aidl_unittest.cpp
@@ -3792,6 +3792,29 @@
               HasSubstr("ERROR: a/IFoo.aidl:3.1-38: Unable to parse @Enforce annotation"));
 }
 
+TEST_F(AidlTest, InterfaceEnforceCondition) {
+  io_delegate_.SetFileContents("a/IFoo.aidl", R"(package a;
+    @Enforce(condition="permission = INTERNET")
+    interface IFoo {
+        void Protected();
+    })");
+
+  Options options = Options::From("aidl --lang=java -o out a/IFoo.aidl");
+  EXPECT_TRUE(compile_aidl(options, io_delegate_));
+}
+
+TEST_F(AidlTest, InterfaceAndMethodEnforceCondition) {
+  io_delegate_.SetFileContents("a/IFoo.aidl", R"(package a;
+    @Enforce(condition="permission = INTERNET")
+    interface IFoo {
+        @Enforce(condition="uid = SYSTEM_UID")
+        void Protected();
+    })");
+
+  Options options = Options::From("aidl --lang=java -o out a/IFoo.aidl");
+  EXPECT_TRUE(compile_aidl(options, io_delegate_));
+}
+
 class AidlOutputPathTest : public AidlTest {
  protected:
   void SetUp() override {
diff --git a/generate_java_binder.cpp b/generate_java_binder.cpp
index 9b0fad1..07ac008 100644
--- a/generate_java_binder.cpp
+++ b/generate_java_binder.cpp
@@ -523,19 +523,33 @@
   std::shared_ptr<Expression> result_;
 };
 
-static void GeneratePermissionChecks(const AidlMethod& method,
+static void GeneratePermissionChecks(const AidlInterface& iface, const AidlMethod& method,
                                      std::shared_ptr<StatementBlock> addTo) {
-  auto expr = method.GetType().EnforceExpression(method);
-  if (expr) {
-    auto ifstatement = std::make_shared<IfStatement>();
-    auto permissionExpression = PermissionVisitor::Evaluate(*expr.get());
-    ifstatement->expression = std::make_shared<Comparison>(permissionExpression, "!=", TRUE_VALUE);
-    ifstatement->statements = std::make_shared<StatementBlock>();
-    ifstatement->statements->Add(std::make_shared<LiteralStatement>(android::base::StringPrintf(
-        "throw new SecurityException(\"Access denied, requires: %s\");\n",
-        expr->ToString().c_str())));
-    addTo->Add(ifstatement);
+  std::unique_ptr<perm::Expression> combinedPermExpr;
+  auto ifacePermExpr = iface.EnforceExpression();
+  auto methodPermExpr = method.GetType().EnforceExpression();
+  if (ifacePermExpr) {
+    if (methodPermExpr) {
+      auto andPermExpr = std::make_unique<perm::AndQuantifier>();
+      andPermExpr->Append(std::move(ifacePermExpr));
+      andPermExpr->Append(std::move(methodPermExpr));
+      combinedPermExpr = std::move(andPermExpr);
+    } else {
+      combinedPermExpr = std::move(ifacePermExpr);
+    }
+  } else if (methodPermExpr) {
+    combinedPermExpr = std::move(methodPermExpr);
+  } else {
+    return;
   }
+  auto ifstatement = std::make_shared<IfStatement>();
+  auto combinedExpr = PermissionVisitor::Evaluate(*combinedPermExpr.get());
+  ifstatement->expression = std::make_shared<Comparison>(combinedExpr, "!=", TRUE_VALUE);
+  ifstatement->statements = std::make_shared<StatementBlock>();
+  ifstatement->statements->Add(std::make_shared<LiteralStatement>(
+      android::base::StringPrintf("throw new SecurityException(\"Access denied, requires: %s\");\n",
+                                  combinedPermExpr->ToString().c_str())));
+  addTo->Add(ifstatement);
 }
 
 static void GenerateStubCode(const AidlInterface& iface, const AidlMethod& method, bool oneway,
@@ -565,7 +579,7 @@
             std::make_shared<LiteralExpression>("android.os.Trace.TRACE_TAG_AIDL")}));
   }
 
-  GeneratePermissionChecks(method, statements);
+  GeneratePermissionChecks(iface, method, statements);
 
   auto realCall = std::make_shared<MethodCall>(THIS_VALUE, method.GetName());
 
diff --git a/tests/android/aidl/tests/IProtected.aidl b/tests/android/aidl/tests/permission/IProtected.aidl
similarity index 89%
rename from tests/android/aidl/tests/IProtected.aidl
rename to tests/android/aidl/tests/permission/IProtected.aidl
index 14a1b62..2959b13 100644
--- a/tests/android/aidl/tests/IProtected.aidl
+++ b/tests/android/aidl/tests/permission/IProtected.aidl
@@ -1,4 +1,4 @@
-package android.aidl.tests;
+package android.aidl.tests.permission;
 
 interface IProtected {
     @Enforce(condition="permission = READ_PHONE_STATE") void PermissionProtected();
diff --git a/tests/android/aidl/tests/permission/IProtectedInterface.aidl b/tests/android/aidl/tests/permission/IProtectedInterface.aidl
new file mode 100644
index 0000000..8c348f5
--- /dev/null
+++ b/tests/android/aidl/tests/permission/IProtectedInterface.aidl
@@ -0,0 +1,8 @@
+package android.aidl.tests.permission;
+
+@Enforce(condition="permission = ACCESS_FINE_LOCATION")
+interface IProtectedInterface {
+    void Method1();
+
+    @Enforce(condition="permission = INTERNET") void Method2();
+}
diff --git a/tests/golden_output/aidl-test-interface-cpp-source/gen/android/aidl/tests/IProtected.cpp.d b/tests/golden_output/aidl-test-interface-cpp-source/gen/android/aidl/tests/IProtected.cpp.d
deleted file mode 100644
index 867cc9f..0000000
--- a/tests/golden_output/aidl-test-interface-cpp-source/gen/android/aidl/tests/IProtected.cpp.d
+++ /dev/null
@@ -1,2 +0,0 @@
-out/soong/.intermediates/system/tools/aidl/aidl-test-interface-cpp-source/gen/android/aidl/tests/IProtected.cpp : \
-  system/tools/aidl/tests/android/aidl/tests/IProtected.aidl
diff --git a/tests/golden_output/aidl-test-interface-cpp-source/gen/android/aidl/tests/IProtected.cpp b/tests/golden_output/aidl-test-interface-cpp-source/gen/android/aidl/tests/permission/IProtected.cpp
similarity index 92%
rename from tests/golden_output/aidl-test-interface-cpp-source/gen/android/aidl/tests/IProtected.cpp
rename to tests/golden_output/aidl-test-interface-cpp-source/gen/android/aidl/tests/permission/IProtected.cpp
index 86cdc4d..1caaefa 100644
--- a/tests/golden_output/aidl-test-interface-cpp-source/gen/android/aidl/tests/IProtected.cpp
+++ b/tests/golden_output/aidl-test-interface-cpp-source/gen/android/aidl/tests/permission/IProtected.cpp
@@ -1,20 +1,23 @@
-#include <android/aidl/tests/IProtected.h>
-#include <android/aidl/tests/BpProtected.h>
+#include <android/aidl/tests/permission/IProtected.h>
+#include <android/aidl/tests/permission/BpProtected.h>
 namespace android {
 namespace aidl {
 namespace tests {
-DO_NOT_DIRECTLY_USE_ME_IMPLEMENT_META_INTERFACE(Protected, "android.aidl.tests.IProtected")
+namespace permission {
+DO_NOT_DIRECTLY_USE_ME_IMPLEMENT_META_INTERFACE(Protected, "android.aidl.tests.permission.IProtected")
+}  // namespace permission
 }  // namespace tests
 }  // namespace aidl
 }  // namespace android
-#include <android/aidl/tests/BpProtected.h>
-#include <android/aidl/tests/BnProtected.h>
+#include <android/aidl/tests/permission/BpProtected.h>
+#include <android/aidl/tests/permission/BnProtected.h>
 #include <binder/Parcel.h>
 #include <android-base/macros.h>
 
 namespace android {
 namespace aidl {
 namespace tests {
+namespace permission {
 
 BpProtected::BpProtected(const ::android::sp<::android::IBinder>& _aidl_impl)
     : BpInterface<IProtected>(_aidl_impl){
@@ -107,16 +110,18 @@
   return _aidl_status;
 }
 
+}  // namespace permission
 }  // namespace tests
 }  // namespace aidl
 }  // namespace android
-#include <android/aidl/tests/BnProtected.h>
+#include <android/aidl/tests/permission/BnProtected.h>
 #include <binder/Parcel.h>
 #include <binder/Stability.h>
 
 namespace android {
 namespace aidl {
 namespace tests {
+namespace permission {
 
 BnProtected::BnProtected()
 {
@@ -186,6 +191,7 @@
   return _aidl_ret_status;
 }
 
+}  // namespace permission
 }  // namespace tests
 }  // namespace aidl
 }  // namespace android
diff --git a/tests/golden_output/aidl-test-interface-cpp-source/gen/android/aidl/tests/permission/IProtected.cpp.d b/tests/golden_output/aidl-test-interface-cpp-source/gen/android/aidl/tests/permission/IProtected.cpp.d
new file mode 100644
index 0000000..3fb3aee
--- /dev/null
+++ b/tests/golden_output/aidl-test-interface-cpp-source/gen/android/aidl/tests/permission/IProtected.cpp.d
@@ -0,0 +1,2 @@
+out/soong/.intermediates/system/tools/aidl/aidl-test-interface-cpp-source/gen/android/aidl/tests/permission/IProtected.cpp : \
+  system/tools/aidl/tests/android/aidl/tests/permission/IProtected.aidl
diff --git a/tests/golden_output/aidl-test-interface-cpp-source/gen/android/aidl/tests/permission/IProtectedInterface.cpp b/tests/golden_output/aidl-test-interface-cpp-source/gen/android/aidl/tests/permission/IProtectedInterface.cpp
new file mode 100644
index 0000000..86be947
--- /dev/null
+++ b/tests/golden_output/aidl-test-interface-cpp-source/gen/android/aidl/tests/permission/IProtectedInterface.cpp
@@ -0,0 +1,152 @@
+#include <android/aidl/tests/permission/IProtectedInterface.h>
+#include <android/aidl/tests/permission/BpProtectedInterface.h>
+namespace android {
+namespace aidl {
+namespace tests {
+namespace permission {
+DO_NOT_DIRECTLY_USE_ME_IMPLEMENT_META_INTERFACE(ProtectedInterface, "android.aidl.tests.permission.IProtectedInterface")
+}  // namespace permission
+}  // namespace tests
+}  // namespace aidl
+}  // namespace android
+#include <android/aidl/tests/permission/BpProtectedInterface.h>
+#include <android/aidl/tests/permission/BnProtectedInterface.h>
+#include <binder/Parcel.h>
+#include <android-base/macros.h>
+
+namespace android {
+namespace aidl {
+namespace tests {
+namespace permission {
+
+BpProtectedInterface::BpProtectedInterface(const ::android::sp<::android::IBinder>& _aidl_impl)
+    : BpInterface<IProtectedInterface>(_aidl_impl){
+}
+
+::android::binder::Status BpProtectedInterface::Method1() {
+  ::android::Parcel _aidl_data;
+  _aidl_data.markForBinder(remoteStrong());
+  ::android::Parcel _aidl_reply;
+  ::android::status_t _aidl_ret_status = ::android::OK;
+  ::android::binder::Status _aidl_status;
+  _aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor());
+  if (((_aidl_ret_status) != (::android::OK))) {
+    goto _aidl_error;
+  }
+  _aidl_ret_status = remote()->transact(BnProtectedInterface::TRANSACTION_Method1, _aidl_data, &_aidl_reply, 0);
+  if (UNLIKELY(_aidl_ret_status == ::android::UNKNOWN_TRANSACTION && IProtectedInterface::getDefaultImpl())) {
+     return IProtectedInterface::getDefaultImpl()->Method1();
+  }
+  if (((_aidl_ret_status) != (::android::OK))) {
+    goto _aidl_error;
+  }
+  _aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
+  if (((_aidl_ret_status) != (::android::OK))) {
+    goto _aidl_error;
+  }
+  if (!_aidl_status.isOk()) {
+    return _aidl_status;
+  }
+  _aidl_error:
+  _aidl_status.setFromStatusT(_aidl_ret_status);
+  return _aidl_status;
+}
+
+::android::binder::Status BpProtectedInterface::Method2() {
+  ::android::Parcel _aidl_data;
+  _aidl_data.markForBinder(remoteStrong());
+  ::android::Parcel _aidl_reply;
+  ::android::status_t _aidl_ret_status = ::android::OK;
+  ::android::binder::Status _aidl_status;
+  _aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor());
+  if (((_aidl_ret_status) != (::android::OK))) {
+    goto _aidl_error;
+  }
+  _aidl_ret_status = remote()->transact(BnProtectedInterface::TRANSACTION_Method2, _aidl_data, &_aidl_reply, 0);
+  if (UNLIKELY(_aidl_ret_status == ::android::UNKNOWN_TRANSACTION && IProtectedInterface::getDefaultImpl())) {
+     return IProtectedInterface::getDefaultImpl()->Method2();
+  }
+  if (((_aidl_ret_status) != (::android::OK))) {
+    goto _aidl_error;
+  }
+  _aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
+  if (((_aidl_ret_status) != (::android::OK))) {
+    goto _aidl_error;
+  }
+  if (!_aidl_status.isOk()) {
+    return _aidl_status;
+  }
+  _aidl_error:
+  _aidl_status.setFromStatusT(_aidl_ret_status);
+  return _aidl_status;
+}
+
+}  // namespace permission
+}  // namespace tests
+}  // namespace aidl
+}  // namespace android
+#include <android/aidl/tests/permission/BnProtectedInterface.h>
+#include <binder/Parcel.h>
+#include <binder/Stability.h>
+
+namespace android {
+namespace aidl {
+namespace tests {
+namespace permission {
+
+BnProtectedInterface::BnProtectedInterface()
+{
+  ::android::internal::Stability::markCompilationUnit(this);
+}
+
+::android::status_t BnProtectedInterface::onTransact(uint32_t _aidl_code, const ::android::Parcel& _aidl_data, ::android::Parcel* _aidl_reply, uint32_t _aidl_flags) {
+  ::android::status_t _aidl_ret_status = ::android::OK;
+  switch (_aidl_code) {
+  case BnProtectedInterface::TRANSACTION_Method1:
+  {
+    if (!(_aidl_data.checkInterface(this))) {
+      _aidl_ret_status = ::android::BAD_TYPE;
+      break;
+    }
+    ::android::binder::Status _aidl_status(Method1());
+    _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
+    if (((_aidl_ret_status) != (::android::OK))) {
+      break;
+    }
+    if (!_aidl_status.isOk()) {
+      break;
+    }
+  }
+  break;
+  case BnProtectedInterface::TRANSACTION_Method2:
+  {
+    if (!(_aidl_data.checkInterface(this))) {
+      _aidl_ret_status = ::android::BAD_TYPE;
+      break;
+    }
+    ::android::binder::Status _aidl_status(Method2());
+    _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
+    if (((_aidl_ret_status) != (::android::OK))) {
+      break;
+    }
+    if (!_aidl_status.isOk()) {
+      break;
+    }
+  }
+  break;
+  default:
+  {
+    _aidl_ret_status = ::android::BBinder::onTransact(_aidl_code, _aidl_data, _aidl_reply, _aidl_flags);
+  }
+  break;
+  }
+  if (_aidl_ret_status == ::android::UNEXPECTED_NULL) {
+    _aidl_ret_status = ::android::binder::Status::fromExceptionCode(::android::binder::Status::EX_NULL_POINTER).writeToParcel(_aidl_reply);
+  }
+  return _aidl_ret_status;
+}
+
+}  // namespace permission
+}  // namespace tests
+}  // namespace aidl
+}  // namespace android
diff --git a/tests/golden_output/aidl-test-interface-cpp-source/gen/android/aidl/tests/permission/IProtectedInterface.cpp.d b/tests/golden_output/aidl-test-interface-cpp-source/gen/android/aidl/tests/permission/IProtectedInterface.cpp.d
new file mode 100644
index 0000000..1841b65
--- /dev/null
+++ b/tests/golden_output/aidl-test-interface-cpp-source/gen/android/aidl/tests/permission/IProtectedInterface.cpp.d
@@ -0,0 +1,2 @@
+out/soong/.intermediates/system/tools/aidl/aidl-test-interface-cpp-source/gen/android/aidl/tests/permission/IProtectedInterface.cpp : \
+  system/tools/aidl/tests/android/aidl/tests/permission/IProtectedInterface.aidl
diff --git a/tests/golden_output/aidl-test-interface-cpp-source/gen/include/android/aidl/tests/BnProtected.h b/tests/golden_output/aidl-test-interface-cpp-source/gen/include/android/aidl/tests/permission/BnProtected.h
similarity index 92%
rename from tests/golden_output/aidl-test-interface-cpp-source/gen/include/android/aidl/tests/BnProtected.h
rename to tests/golden_output/aidl-test-interface-cpp-source/gen/include/android/aidl/tests/permission/BnProtected.h
index cec78ba..f40e833 100644
--- a/tests/golden_output/aidl-test-interface-cpp-source/gen/include/android/aidl/tests/BnProtected.h
+++ b/tests/golden_output/aidl-test-interface-cpp-source/gen/include/android/aidl/tests/permission/BnProtected.h
@@ -1,11 +1,12 @@
 #pragma once
 
 #include <binder/IInterface.h>
-#include <android/aidl/tests/IProtected.h>
+#include <android/aidl/tests/permission/IProtected.h>
 
 namespace android {
 namespace aidl {
 namespace tests {
+namespace permission {
 class BnProtected : public ::android::BnInterface<IProtected> {
 public:
   static constexpr uint32_t TRANSACTION_PermissionProtected = ::android::IBinder::FIRST_CALL_TRANSACTION + 0;
@@ -31,6 +32,7 @@
 private:
   ::android::sp<IProtected> _aidl_delegate;
 };  // class IProtectedDelegator
+}  // namespace permission
 }  // namespace tests
 }  // namespace aidl
 }  // namespace android
diff --git a/tests/golden_output/aidl-test-interface-cpp-source/gen/include/android/aidl/tests/permission/BnProtectedInterface.h b/tests/golden_output/aidl-test-interface-cpp-source/gen/include/android/aidl/tests/permission/BnProtectedInterface.h
new file mode 100644
index 0000000..7516a17
--- /dev/null
+++ b/tests/golden_output/aidl-test-interface-cpp-source/gen/include/android/aidl/tests/permission/BnProtectedInterface.h
@@ -0,0 +1,34 @@
+#pragma once
+
+#include <binder/IInterface.h>
+#include <android/aidl/tests/permission/IProtectedInterface.h>
+
+namespace android {
+namespace aidl {
+namespace tests {
+namespace permission {
+class BnProtectedInterface : public ::android::BnInterface<IProtectedInterface> {
+public:
+  static constexpr uint32_t TRANSACTION_Method1 = ::android::IBinder::FIRST_CALL_TRANSACTION + 0;
+  static constexpr uint32_t TRANSACTION_Method2 = ::android::IBinder::FIRST_CALL_TRANSACTION + 1;
+  explicit BnProtectedInterface();
+  ::android::status_t onTransact(uint32_t _aidl_code, const ::android::Parcel& _aidl_data, ::android::Parcel* _aidl_reply, uint32_t _aidl_flags) override;
+};  // class BnProtectedInterface
+
+class IProtectedInterfaceDelegator : public BnProtectedInterface {
+public:
+  explicit IProtectedInterfaceDelegator(::android::sp<IProtectedInterface> &impl) : _aidl_delegate(impl) {}
+
+  ::android::binder::Status Method1() override {
+    return _aidl_delegate->Method1();
+  }
+  ::android::binder::Status Method2() override {
+    return _aidl_delegate->Method2();
+  }
+private:
+  ::android::sp<IProtectedInterface> _aidl_delegate;
+};  // class IProtectedInterfaceDelegator
+}  // namespace permission
+}  // namespace tests
+}  // namespace aidl
+}  // namespace android
diff --git a/tests/golden_output/aidl-test-interface-cpp-source/gen/include/android/aidl/tests/BpProtected.h b/tests/golden_output/aidl-test-interface-cpp-source/gen/include/android/aidl/tests/permission/BpProtected.h
similarity index 85%
rename from tests/golden_output/aidl-test-interface-cpp-source/gen/include/android/aidl/tests/BpProtected.h
rename to tests/golden_output/aidl-test-interface-cpp-source/gen/include/android/aidl/tests/permission/BpProtected.h
index dd17bd7..7984942 100644
--- a/tests/golden_output/aidl-test-interface-cpp-source/gen/include/android/aidl/tests/BpProtected.h
+++ b/tests/golden_output/aidl-test-interface-cpp-source/gen/include/android/aidl/tests/permission/BpProtected.h
@@ -3,11 +3,12 @@
 #include <binder/IBinder.h>
 #include <binder/IInterface.h>
 #include <utils/Errors.h>
-#include <android/aidl/tests/IProtected.h>
+#include <android/aidl/tests/permission/IProtected.h>
 
 namespace android {
 namespace aidl {
 namespace tests {
+namespace permission {
 class BpProtected : public ::android::BpInterface<IProtected> {
 public:
   explicit BpProtected(const ::android::sp<::android::IBinder>& _aidl_impl);
@@ -16,6 +17,7 @@
   ::android::binder::Status MultiplePermissions() override;
   ::android::binder::Status MultiplePermissions2() override;
 };  // class BpProtected
+}  // namespace permission
 }  // namespace tests
 }  // namespace aidl
 }  // namespace android
diff --git a/tests/golden_output/aidl-test-interface-cpp-source/gen/include/android/aidl/tests/permission/BpProtectedInterface.h b/tests/golden_output/aidl-test-interface-cpp-source/gen/include/android/aidl/tests/permission/BpProtectedInterface.h
new file mode 100644
index 0000000..c77b59a
--- /dev/null
+++ b/tests/golden_output/aidl-test-interface-cpp-source/gen/include/android/aidl/tests/permission/BpProtectedInterface.h
@@ -0,0 +1,22 @@
+#pragma once
+
+#include <binder/IBinder.h>
+#include <binder/IInterface.h>
+#include <utils/Errors.h>
+#include <android/aidl/tests/permission/IProtectedInterface.h>
+
+namespace android {
+namespace aidl {
+namespace tests {
+namespace permission {
+class BpProtectedInterface : public ::android::BpInterface<IProtectedInterface> {
+public:
+  explicit BpProtectedInterface(const ::android::sp<::android::IBinder>& _aidl_impl);
+  virtual ~BpProtectedInterface() = default;
+  ::android::binder::Status Method1() override;
+  ::android::binder::Status Method2() override;
+};  // class BpProtectedInterface
+}  // namespace permission
+}  // namespace tests
+}  // namespace aidl
+}  // namespace android
diff --git a/tests/golden_output/aidl-test-interface-cpp-source/gen/include/android/aidl/tests/IProtected.h b/tests/golden_output/aidl-test-interface-cpp-source/gen/include/android/aidl/tests/permission/IProtected.h
similarity index 95%
rename from tests/golden_output/aidl-test-interface-cpp-source/gen/include/android/aidl/tests/IProtected.h
rename to tests/golden_output/aidl-test-interface-cpp-source/gen/include/android/aidl/tests/permission/IProtected.h
index 7e3a91e..caaad19 100644
--- a/tests/golden_output/aidl-test-interface-cpp-source/gen/include/android/aidl/tests/IProtected.h
+++ b/tests/golden_output/aidl-test-interface-cpp-source/gen/include/android/aidl/tests/permission/IProtected.h
@@ -8,6 +8,7 @@
 namespace android {
 namespace aidl {
 namespace tests {
+namespace permission {
 class IProtected : public ::android::IInterface {
 public:
   DECLARE_META_INTERFACE(Protected)
@@ -31,6 +32,7 @@
     return ::android::binder::Status::fromStatusT(::android::UNKNOWN_TRANSACTION);
   }
 };  // class IProtectedDefault
+}  // namespace permission
 }  // namespace tests
 }  // namespace aidl
 }  // namespace android
diff --git a/tests/golden_output/aidl-test-interface-cpp-source/gen/include/android/aidl/tests/permission/IProtectedInterface.h b/tests/golden_output/aidl-test-interface-cpp-source/gen/include/android/aidl/tests/permission/IProtectedInterface.h
new file mode 100644
index 0000000..82aaceb
--- /dev/null
+++ b/tests/golden_output/aidl-test-interface-cpp-source/gen/include/android/aidl/tests/permission/IProtectedInterface.h
@@ -0,0 +1,34 @@
+#pragma once
+
+#include <binder/IBinder.h>
+#include <binder/IInterface.h>
+#include <binder/Status.h>
+#include <utils/StrongPointer.h>
+
+namespace android {
+namespace aidl {
+namespace tests {
+namespace permission {
+class IProtectedInterface : public ::android::IInterface {
+public:
+  DECLARE_META_INTERFACE(ProtectedInterface)
+  virtual ::android::binder::Status Method1() = 0;
+  virtual ::android::binder::Status Method2() = 0;
+};  // class IProtectedInterface
+
+class IProtectedInterfaceDefault : public IProtectedInterface {
+public:
+  ::android::IBinder* onAsBinder() override {
+    return nullptr;
+  }
+  ::android::binder::Status Method1() override {
+    return ::android::binder::Status::fromStatusT(::android::UNKNOWN_TRANSACTION);
+  }
+  ::android::binder::Status Method2() override {
+    return ::android::binder::Status::fromStatusT(::android::UNKNOWN_TRANSACTION);
+  }
+};  // class IProtectedInterfaceDefault
+}  // namespace permission
+}  // namespace tests
+}  // namespace aidl
+}  // namespace android
diff --git a/tests/golden_output/aidl-test-interface-java-source/gen/android/aidl/tests/IProtected.java.d b/tests/golden_output/aidl-test-interface-java-source/gen/android/aidl/tests/IProtected.java.d
deleted file mode 100644
index ac8ddad..0000000
--- a/tests/golden_output/aidl-test-interface-java-source/gen/android/aidl/tests/IProtected.java.d
+++ /dev/null
@@ -1,2 +0,0 @@
-out/soong/.intermediates/system/tools/aidl/aidl-test-interface-java-source/gen/android/aidl/tests/IProtected.java : \
-  system/tools/aidl/tests/android/aidl/tests/IProtected.aidl
diff --git a/tests/golden_output/aidl-test-interface-java-source/gen/android/aidl/tests/IProtected.java b/tests/golden_output/aidl-test-interface-java-source/gen/android/aidl/tests/permission/IProtected.java
similarity index 87%
rename from tests/golden_output/aidl-test-interface-java-source/gen/android/aidl/tests/IProtected.java
rename to tests/golden_output/aidl-test-interface-java-source/gen/android/aidl/tests/permission/IProtected.java
index 8c26f38..bcada36 100644
--- a/tests/golden_output/aidl-test-interface-java-source/gen/android/aidl/tests/IProtected.java
+++ b/tests/golden_output/aidl-test-interface-java-source/gen/android/aidl/tests/permission/IProtected.java
@@ -1,11 +1,11 @@
 /*
  * This file is auto-generated.  DO NOT MODIFY.
  */
-package android.aidl.tests;
+package android.aidl.tests.permission;
 public interface IProtected extends android.os.IInterface
 {
   /** Default implementation for IProtected. */
-  public static class Default implements android.aidl.tests.IProtected
+  public static class Default implements android.aidl.tests.permission.IProtected
   {
     @Override public void PermissionProtected() throws android.os.RemoteException
     {
@@ -22,7 +22,7 @@
     }
   }
   /** Local-side IPC implementation stub class. */
-  public static abstract class Stub extends android.os.Binder implements android.aidl.tests.IProtected
+  public static abstract class Stub extends android.os.Binder implements android.aidl.tests.permission.IProtected
   {
     /** Construct the stub at attach it to the interface. */
     public Stub()
@@ -30,19 +30,19 @@
       this.attachInterface(this, DESCRIPTOR);
     }
     /**
-     * Cast an IBinder object into an android.aidl.tests.IProtected interface,
+     * Cast an IBinder object into an android.aidl.tests.permission.IProtected interface,
      * generating a proxy if needed.
      */
-    public static android.aidl.tests.IProtected asInterface(android.os.IBinder obj)
+    public static android.aidl.tests.permission.IProtected asInterface(android.os.IBinder obj)
     {
       if ((obj==null)) {
         return null;
       }
       android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
-      if (((iin!=null)&&(iin instanceof android.aidl.tests.IProtected))) {
-        return ((android.aidl.tests.IProtected)iin);
+      if (((iin!=null)&&(iin instanceof android.aidl.tests.permission.IProtected))) {
+        return ((android.aidl.tests.permission.IProtected)iin);
       }
-      return new android.aidl.tests.IProtected.Stub.Proxy(obj);
+      return new android.aidl.tests.permission.IProtected.Stub.Proxy(obj);
     }
     @Override public android.os.IBinder asBinder()
     {
@@ -98,7 +98,7 @@
       }
       return true;
     }
-    private static class Proxy implements android.aidl.tests.IProtected
+    private static class Proxy implements android.aidl.tests.permission.IProtected
     {
       private android.os.IBinder mRemote;
       Proxy(android.os.IBinder remote)
@@ -173,12 +173,12 @@
           _data.recycle();
         }
       }
-      public static android.aidl.tests.IProtected sDefaultImpl;
+      public static android.aidl.tests.permission.IProtected sDefaultImpl;
     }
     static final int TRANSACTION_PermissionProtected = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
     static final int TRANSACTION_MultiplePermissions = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
     static final int TRANSACTION_MultiplePermissions2 = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);
-    public static boolean setDefaultImpl(android.aidl.tests.IProtected impl) {
+    public static boolean setDefaultImpl(android.aidl.tests.permission.IProtected impl) {
       // Only one user of this interface can use this function
       // at a time. This is a heuristic to detect if two different
       // users in the same process use this function.
@@ -191,11 +191,11 @@
       }
       return false;
     }
-    public static android.aidl.tests.IProtected getDefaultImpl() {
+    public static android.aidl.tests.permission.IProtected getDefaultImpl() {
       return Stub.Proxy.sDefaultImpl;
     }
   }
-  public static final java.lang.String DESCRIPTOR = "android$aidl$tests$IProtected".replace('$', '.');
+  public static final java.lang.String DESCRIPTOR = "android$aidl$tests$permission$IProtected".replace('$', '.');
   public void PermissionProtected() throws android.os.RemoteException;
   public void MultiplePermissions() throws android.os.RemoteException;
   public void MultiplePermissions2() throws android.os.RemoteException;
diff --git a/tests/golden_output/aidl-test-interface-java-source/gen/android/aidl/tests/permission/IProtected.java.d b/tests/golden_output/aidl-test-interface-java-source/gen/android/aidl/tests/permission/IProtected.java.d
new file mode 100644
index 0000000..9eb7054
--- /dev/null
+++ b/tests/golden_output/aidl-test-interface-java-source/gen/android/aidl/tests/permission/IProtected.java.d
@@ -0,0 +1,2 @@
+out/soong/.intermediates/system/tools/aidl/aidl-test-interface-java-source/gen/android/aidl/tests/permission/IProtected.java : \
+  system/tools/aidl/tests/android/aidl/tests/permission/IProtected.aidl
diff --git a/tests/golden_output/aidl-test-interface-java-source/gen/android/aidl/tests/permission/IProtectedInterface.java b/tests/golden_output/aidl-test-interface-java-source/gen/android/aidl/tests/permission/IProtectedInterface.java
new file mode 100644
index 0000000..bca9289
--- /dev/null
+++ b/tests/golden_output/aidl-test-interface-java-source/gen/android/aidl/tests/permission/IProtectedInterface.java
@@ -0,0 +1,168 @@
+/*
+ * This file is auto-generated.  DO NOT MODIFY.
+ */
+package android.aidl.tests.permission;
+public interface IProtectedInterface extends android.os.IInterface
+{
+  /** Default implementation for IProtectedInterface. */
+  public static class Default implements android.aidl.tests.permission.IProtectedInterface
+  {
+    @Override public void Method1() throws android.os.RemoteException
+    {
+    }
+    @Override public void Method2() throws android.os.RemoteException
+    {
+    }
+    @Override
+    public android.os.IBinder asBinder() {
+      return null;
+    }
+  }
+  /** Local-side IPC implementation stub class. */
+  public static abstract class Stub extends android.os.Binder implements android.aidl.tests.permission.IProtectedInterface
+  {
+    /** Construct the stub at attach it to the interface. */
+    public Stub()
+    {
+      this.attachInterface(this, DESCRIPTOR);
+    }
+    /**
+     * Cast an IBinder object into an android.aidl.tests.permission.IProtectedInterface interface,
+     * generating a proxy if needed.
+     */
+    public static android.aidl.tests.permission.IProtectedInterface asInterface(android.os.IBinder obj)
+    {
+      if ((obj==null)) {
+        return null;
+      }
+      android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
+      if (((iin!=null)&&(iin instanceof android.aidl.tests.permission.IProtectedInterface))) {
+        return ((android.aidl.tests.permission.IProtectedInterface)iin);
+      }
+      return new android.aidl.tests.permission.IProtectedInterface.Stub.Proxy(obj);
+    }
+    @Override public android.os.IBinder asBinder()
+    {
+      return this;
+    }
+    @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
+    {
+      java.lang.String descriptor = DESCRIPTOR;
+      if (code >= android.os.IBinder.FIRST_CALL_TRANSACTION && code <= android.os.IBinder.LAST_CALL_TRANSACTION) {
+        data.enforceInterface(descriptor);
+      }
+      switch (code)
+      {
+        case INTERFACE_TRANSACTION:
+        {
+          reply.writeString(descriptor);
+          return true;
+        }
+      }
+      switch (code)
+      {
+        case TRANSACTION_Method1:
+        {
+          if (((android.permission.PermissionManager.checkPermission(android.Manifest.permission.ACCESS_FINE_LOCATION, this.getCallingPid(), this.getCallingUid())==android.content.pm.PackageManager.PERMISSION_GRANTED)!=true)) {
+            throw new SecurityException("Access denied, requires: permission = ACCESS_FINE_LOCATION");
+          }
+          this.Method1();
+          reply.writeNoException();
+          break;
+        }
+        case TRANSACTION_Method2:
+        {
+          if ((((android.permission.PermissionManager.checkPermission(android.Manifest.permission.ACCESS_FINE_LOCATION, this.getCallingPid(), this.getCallingUid())==android.content.pm.PackageManager.PERMISSION_GRANTED)&&(android.permission.PermissionManager.checkPermission(android.Manifest.permission.INTERNET, this.getCallingPid(), this.getCallingUid())==android.content.pm.PackageManager.PERMISSION_GRANTED))!=true)) {
+            throw new SecurityException("Access denied, requires: permission = ACCESS_FINE_LOCATION && permission = INTERNET");
+          }
+          this.Method2();
+          reply.writeNoException();
+          break;
+        }
+        default:
+        {
+          return super.onTransact(code, data, reply, flags);
+        }
+      }
+      return true;
+    }
+    private static class Proxy implements android.aidl.tests.permission.IProtectedInterface
+    {
+      private android.os.IBinder mRemote;
+      Proxy(android.os.IBinder remote)
+      {
+        mRemote = remote;
+      }
+      @Override public android.os.IBinder asBinder()
+      {
+        return mRemote;
+      }
+      public java.lang.String getInterfaceDescriptor()
+      {
+        return DESCRIPTOR;
+      }
+      @Override public void Method1() throws android.os.RemoteException
+      {
+        android.os.Parcel _data = android.os.Parcel.obtain(asBinder());
+        android.os.Parcel _reply = android.os.Parcel.obtain();
+        try {
+          _data.writeInterfaceToken(DESCRIPTOR);
+          boolean _status = mRemote.transact(Stub.TRANSACTION_Method1, _data, _reply, 0);
+          if (!_status) {
+            if (getDefaultImpl() != null) {
+              getDefaultImpl().Method1();
+              return;
+            }
+          }
+          _reply.readException();
+        }
+        finally {
+          _reply.recycle();
+          _data.recycle();
+        }
+      }
+      @Override public void Method2() throws android.os.RemoteException
+      {
+        android.os.Parcel _data = android.os.Parcel.obtain(asBinder());
+        android.os.Parcel _reply = android.os.Parcel.obtain();
+        try {
+          _data.writeInterfaceToken(DESCRIPTOR);
+          boolean _status = mRemote.transact(Stub.TRANSACTION_Method2, _data, _reply, 0);
+          if (!_status) {
+            if (getDefaultImpl() != null) {
+              getDefaultImpl().Method2();
+              return;
+            }
+          }
+          _reply.readException();
+        }
+        finally {
+          _reply.recycle();
+          _data.recycle();
+        }
+      }
+      public static android.aidl.tests.permission.IProtectedInterface sDefaultImpl;
+    }
+    static final int TRANSACTION_Method1 = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
+    static final int TRANSACTION_Method2 = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
+    public static boolean setDefaultImpl(android.aidl.tests.permission.IProtectedInterface impl) {
+      // Only one user of this interface can use this function
+      // at a time. This is a heuristic to detect if two different
+      // users in the same process use this function.
+      if (Stub.Proxy.sDefaultImpl != null) {
+        throw new IllegalStateException("setDefaultImpl() called twice");
+      }
+      if (impl != null) {
+        Stub.Proxy.sDefaultImpl = impl;
+        return true;
+      }
+      return false;
+    }
+    public static android.aidl.tests.permission.IProtectedInterface getDefaultImpl() {
+      return Stub.Proxy.sDefaultImpl;
+    }
+  }
+  public static final java.lang.String DESCRIPTOR = "android$aidl$tests$permission$IProtectedInterface".replace('$', '.');
+  public void Method1() throws android.os.RemoteException;
+  public void Method2() throws android.os.RemoteException;
+}
diff --git a/tests/golden_output/aidl-test-interface-java-source/gen/android/aidl/tests/permission/IProtectedInterface.java.d b/tests/golden_output/aidl-test-interface-java-source/gen/android/aidl/tests/permission/IProtectedInterface.java.d
new file mode 100644
index 0000000..4f04f76
--- /dev/null
+++ b/tests/golden_output/aidl-test-interface-java-source/gen/android/aidl/tests/permission/IProtectedInterface.java.d
@@ -0,0 +1,2 @@
+out/soong/.intermediates/system/tools/aidl/aidl-test-interface-java-source/gen/android/aidl/tests/permission/IProtectedInterface.java : \
+  system/tools/aidl/tests/android/aidl/tests/permission/IProtectedInterface.aidl
diff --git a/tests/golden_output/aidl-test-interface-ndk-source/gen/android/aidl/tests/IProtected.cpp.d b/tests/golden_output/aidl-test-interface-ndk-source/gen/android/aidl/tests/IProtected.cpp.d
deleted file mode 100644
index e7cff00..0000000
--- a/tests/golden_output/aidl-test-interface-ndk-source/gen/android/aidl/tests/IProtected.cpp.d
+++ /dev/null
@@ -1,2 +0,0 @@
-out/soong/.intermediates/system/tools/aidl/aidl-test-interface-ndk-source/gen/android/aidl/tests/IProtected.cpp : \
-  system/tools/aidl/tests/android/aidl/tests/IProtected.aidl
diff --git a/tests/golden_output/aidl-test-interface-ndk-source/gen/android/aidl/tests/IProtected.cpp b/tests/golden_output/aidl-test-interface-ndk-source/gen/android/aidl/tests/permission/IProtected.cpp
similarity index 96%
rename from tests/golden_output/aidl-test-interface-ndk-source/gen/android/aidl/tests/IProtected.cpp
rename to tests/golden_output/aidl-test-interface-ndk-source/gen/android/aidl/tests/permission/IProtected.cpp
index b57c273..38b9d36 100644
--- a/tests/golden_output/aidl-test-interface-ndk-source/gen/android/aidl/tests/IProtected.cpp
+++ b/tests/golden_output/aidl-test-interface-ndk-source/gen/android/aidl/tests/permission/IProtected.cpp
@@ -1,12 +1,13 @@
 #include <android/binder_parcel_utils.h>
-#include <aidl/android/aidl/tests/BpProtected.h>
-#include <aidl/android/aidl/tests/BnProtected.h>
-#include <aidl/android/aidl/tests/IProtected.h>
+#include <aidl/android/aidl/tests/permission/BpProtected.h>
+#include <aidl/android/aidl/tests/permission/BnProtected.h>
+#include <aidl/android/aidl/tests/permission/IProtected.h>
 
 namespace aidl {
 namespace android {
 namespace aidl {
 namespace tests {
+namespace permission {
 static binder_status_t _aidl_onTransact(AIBinder* _aidl_binder, transaction_code_t _aidl_code, const AParcel* _aidl_in, AParcel* _aidl_out) {
   (void)_aidl_in;
   (void)_aidl_out;
@@ -165,7 +166,7 @@
   return ::ndk::SpAIBinder(binder);
 }
 // Source for IProtected
-const char* IProtected::descriptor = "android.aidl.tests.IProtected";
+const char* IProtected::descriptor = "android.aidl.tests.permission.IProtected";
 IProtected::IProtected() {}
 IProtected::~IProtected() {}
 
@@ -225,6 +226,7 @@
 bool IProtectedDefault::isRemote() {
   return false;
 }
+}  // namespace permission
 }  // namespace tests
 }  // namespace aidl
 }  // namespace android
diff --git a/tests/golden_output/aidl-test-interface-ndk-source/gen/android/aidl/tests/permission/IProtected.cpp.d b/tests/golden_output/aidl-test-interface-ndk-source/gen/android/aidl/tests/permission/IProtected.cpp.d
new file mode 100644
index 0000000..7db52de
--- /dev/null
+++ b/tests/golden_output/aidl-test-interface-ndk-source/gen/android/aidl/tests/permission/IProtected.cpp.d
@@ -0,0 +1,2 @@
+out/soong/.intermediates/system/tools/aidl/aidl-test-interface-ndk-source/gen/android/aidl/tests/permission/IProtected.cpp : \
+  system/tools/aidl/tests/android/aidl/tests/permission/IProtected.aidl
diff --git a/tests/golden_output/aidl-test-interface-ndk-source/gen/android/aidl/tests/permission/IProtectedInterface.cpp b/tests/golden_output/aidl-test-interface-ndk-source/gen/android/aidl/tests/permission/IProtectedInterface.cpp
new file mode 100644
index 0000000..0d4d19f
--- /dev/null
+++ b/tests/golden_output/aidl-test-interface-ndk-source/gen/android/aidl/tests/permission/IProtectedInterface.cpp
@@ -0,0 +1,184 @@
+#include <android/binder_parcel_utils.h>
+#include <aidl/android/aidl/tests/permission/BpProtectedInterface.h>
+#include <aidl/android/aidl/tests/permission/BnProtectedInterface.h>
+#include <aidl/android/aidl/tests/permission/IProtectedInterface.h>
+
+namespace aidl {
+namespace android {
+namespace aidl {
+namespace tests {
+namespace permission {
+static binder_status_t _aidl_onTransact(AIBinder* _aidl_binder, transaction_code_t _aidl_code, const AParcel* _aidl_in, AParcel* _aidl_out) {
+  (void)_aidl_in;
+  (void)_aidl_out;
+  binder_status_t _aidl_ret_status = STATUS_UNKNOWN_TRANSACTION;
+  std::shared_ptr<BnProtectedInterface> _aidl_impl = std::static_pointer_cast<BnProtectedInterface>(::ndk::ICInterface::asInterface(_aidl_binder));
+  switch (_aidl_code) {
+    case (FIRST_CALL_TRANSACTION + 0 /*Method1*/): {
+
+      ::ndk::ScopedAStatus _aidl_status = _aidl_impl->Method1();
+      _aidl_ret_status = AParcel_writeStatusHeader(_aidl_out, _aidl_status.get());
+      if (_aidl_ret_status != STATUS_OK) break;
+
+      if (!AStatus_isOk(_aidl_status.get())) break;
+
+      break;
+    }
+    case (FIRST_CALL_TRANSACTION + 1 /*Method2*/): {
+
+      ::ndk::ScopedAStatus _aidl_status = _aidl_impl->Method2();
+      _aidl_ret_status = AParcel_writeStatusHeader(_aidl_out, _aidl_status.get());
+      if (_aidl_ret_status != STATUS_OK) break;
+
+      if (!AStatus_isOk(_aidl_status.get())) break;
+
+      break;
+    }
+  }
+  return _aidl_ret_status;
+}
+
+static AIBinder_Class* _g_aidl_clazz = ::ndk::ICInterface::defineClass(IProtectedInterface::descriptor, _aidl_onTransact);
+
+BpProtectedInterface::BpProtectedInterface(const ::ndk::SpAIBinder& binder) : BpCInterface(binder) {}
+BpProtectedInterface::~BpProtectedInterface() {}
+
+::ndk::ScopedAStatus BpProtectedInterface::Method1() {
+  binder_status_t _aidl_ret_status = STATUS_OK;
+  ::ndk::ScopedAStatus _aidl_status;
+  ::ndk::ScopedAParcel _aidl_in;
+  ::ndk::ScopedAParcel _aidl_out;
+
+  _aidl_ret_status = AIBinder_prepareTransaction(asBinder().get(), _aidl_in.getR());
+  if (_aidl_ret_status != STATUS_OK) goto _aidl_error;
+
+  _aidl_ret_status = AIBinder_transact(
+    asBinder().get(),
+    (FIRST_CALL_TRANSACTION + 0 /*Method1*/),
+    _aidl_in.getR(),
+    _aidl_out.getR(),
+    0
+    #ifdef BINDER_STABILITY_SUPPORT
+    | FLAG_PRIVATE_LOCAL
+    #endif  // BINDER_STABILITY_SUPPORT
+    );
+  if (_aidl_ret_status == STATUS_UNKNOWN_TRANSACTION && IProtectedInterface::getDefaultImpl()) {
+    _aidl_status = IProtectedInterface::getDefaultImpl()->Method1();
+    goto _aidl_status_return;
+  }
+  if (_aidl_ret_status != STATUS_OK) goto _aidl_error;
+
+  _aidl_ret_status = AParcel_readStatusHeader(_aidl_out.get(), _aidl_status.getR());
+  if (_aidl_ret_status != STATUS_OK) goto _aidl_error;
+
+  if (!AStatus_isOk(_aidl_status.get())) goto _aidl_status_return;
+  _aidl_error:
+  _aidl_status.set(AStatus_fromStatus(_aidl_ret_status));
+  _aidl_status_return:
+  return _aidl_status;
+}
+::ndk::ScopedAStatus BpProtectedInterface::Method2() {
+  binder_status_t _aidl_ret_status = STATUS_OK;
+  ::ndk::ScopedAStatus _aidl_status;
+  ::ndk::ScopedAParcel _aidl_in;
+  ::ndk::ScopedAParcel _aidl_out;
+
+  _aidl_ret_status = AIBinder_prepareTransaction(asBinder().get(), _aidl_in.getR());
+  if (_aidl_ret_status != STATUS_OK) goto _aidl_error;
+
+  _aidl_ret_status = AIBinder_transact(
+    asBinder().get(),
+    (FIRST_CALL_TRANSACTION + 1 /*Method2*/),
+    _aidl_in.getR(),
+    _aidl_out.getR(),
+    0
+    #ifdef BINDER_STABILITY_SUPPORT
+    | FLAG_PRIVATE_LOCAL
+    #endif  // BINDER_STABILITY_SUPPORT
+    );
+  if (_aidl_ret_status == STATUS_UNKNOWN_TRANSACTION && IProtectedInterface::getDefaultImpl()) {
+    _aidl_status = IProtectedInterface::getDefaultImpl()->Method2();
+    goto _aidl_status_return;
+  }
+  if (_aidl_ret_status != STATUS_OK) goto _aidl_error;
+
+  _aidl_ret_status = AParcel_readStatusHeader(_aidl_out.get(), _aidl_status.getR());
+  if (_aidl_ret_status != STATUS_OK) goto _aidl_error;
+
+  if (!AStatus_isOk(_aidl_status.get())) goto _aidl_status_return;
+  _aidl_error:
+  _aidl_status.set(AStatus_fromStatus(_aidl_ret_status));
+  _aidl_status_return:
+  return _aidl_status;
+}
+// Source for BnProtectedInterface
+BnProtectedInterface::BnProtectedInterface() {}
+BnProtectedInterface::~BnProtectedInterface() {}
+::ndk::SpAIBinder BnProtectedInterface::createBinder() {
+  AIBinder* binder = AIBinder_new(_g_aidl_clazz, static_cast<void*>(this));
+  #ifdef BINDER_STABILITY_SUPPORT
+  AIBinder_markCompilationUnitStability(binder);
+  #endif  // BINDER_STABILITY_SUPPORT
+  return ::ndk::SpAIBinder(binder);
+}
+// Source for IProtectedInterface
+const char* IProtectedInterface::descriptor = "android.aidl.tests.permission.IProtectedInterface";
+IProtectedInterface::IProtectedInterface() {}
+IProtectedInterface::~IProtectedInterface() {}
+
+
+std::shared_ptr<IProtectedInterface> IProtectedInterface::fromBinder(const ::ndk::SpAIBinder& binder) {
+  if (!AIBinder_associateClass(binder.get(), _g_aidl_clazz)) { return nullptr; }
+  std::shared_ptr<::ndk::ICInterface> interface = ::ndk::ICInterface::asInterface(binder.get());
+  if (interface) {
+    return std::static_pointer_cast<IProtectedInterface>(interface);
+  }
+  return ::ndk::SharedRefBase::make<BpProtectedInterface>(binder);
+}
+
+binder_status_t IProtectedInterface::writeToParcel(AParcel* parcel, const std::shared_ptr<IProtectedInterface>& instance) {
+  return AParcel_writeStrongBinder(parcel, instance ? instance->asBinder().get() : nullptr);
+}
+binder_status_t IProtectedInterface::readFromParcel(const AParcel* parcel, std::shared_ptr<IProtectedInterface>* instance) {
+  ::ndk::SpAIBinder binder;
+  binder_status_t status = AParcel_readStrongBinder(parcel, binder.getR());
+  if (status != STATUS_OK) return status;
+  *instance = IProtectedInterface::fromBinder(binder);
+  return STATUS_OK;
+}
+bool IProtectedInterface::setDefaultImpl(const std::shared_ptr<IProtectedInterface>& impl) {
+  // Only one user of this interface can use this function
+  // at a time. This is a heuristic to detect if two different
+  // users in the same process use this function.
+  assert(!IProtectedInterface::default_impl);
+  if (impl) {
+    IProtectedInterface::default_impl = impl;
+    return true;
+  }
+  return false;
+}
+const std::shared_ptr<IProtectedInterface>& IProtectedInterface::getDefaultImpl() {
+  return IProtectedInterface::default_impl;
+}
+std::shared_ptr<IProtectedInterface> IProtectedInterface::default_impl = nullptr;
+::ndk::ScopedAStatus IProtectedInterfaceDefault::Method1() {
+  ::ndk::ScopedAStatus _aidl_status;
+  _aidl_status.set(AStatus_fromStatus(STATUS_UNKNOWN_TRANSACTION));
+  return _aidl_status;
+}
+::ndk::ScopedAStatus IProtectedInterfaceDefault::Method2() {
+  ::ndk::ScopedAStatus _aidl_status;
+  _aidl_status.set(AStatus_fromStatus(STATUS_UNKNOWN_TRANSACTION));
+  return _aidl_status;
+}
+::ndk::SpAIBinder IProtectedInterfaceDefault::asBinder() {
+  return ::ndk::SpAIBinder();
+}
+bool IProtectedInterfaceDefault::isRemote() {
+  return false;
+}
+}  // namespace permission
+}  // namespace tests
+}  // namespace aidl
+}  // namespace android
+}  // namespace aidl
diff --git a/tests/golden_output/aidl-test-interface-ndk-source/gen/android/aidl/tests/permission/IProtectedInterface.cpp.d b/tests/golden_output/aidl-test-interface-ndk-source/gen/android/aidl/tests/permission/IProtectedInterface.cpp.d
new file mode 100644
index 0000000..0dbab58
--- /dev/null
+++ b/tests/golden_output/aidl-test-interface-ndk-source/gen/android/aidl/tests/permission/IProtectedInterface.cpp.d
@@ -0,0 +1,2 @@
+out/soong/.intermediates/system/tools/aidl/aidl-test-interface-ndk-source/gen/android/aidl/tests/permission/IProtectedInterface.cpp : \
+  system/tools/aidl/tests/android/aidl/tests/permission/IProtectedInterface.aidl
diff --git a/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/BnProtected.h b/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/permission/BnProtected.h
similarity index 78%
rename from tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/BnProtected.h
rename to tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/permission/BnProtected.h
index 9f968af..150c5b8 100644
--- a/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/BnProtected.h
+++ b/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/permission/BnProtected.h
@@ -1,6 +1,6 @@
 #pragma once
 
-#include "aidl/android/aidl/tests/IProtected.h"
+#include "aidl/android/aidl/tests/permission/IProtected.h"
 
 #include <android/binder_ibinder.h>
 
@@ -8,6 +8,7 @@
 namespace android {
 namespace aidl {
 namespace tests {
+namespace permission {
 class BnProtected : public ::ndk::BnCInterface<IProtected> {
 public:
   BnProtected();
@@ -16,6 +17,7 @@
   ::ndk::SpAIBinder createBinder() override;
 private:
 };
+}  // namespace permission
 }  // namespace tests
 }  // namespace aidl
 }  // namespace android
diff --git a/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/permission/BnProtectedInterface.h b/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/permission/BnProtectedInterface.h
new file mode 100644
index 0000000..ac2a46c
--- /dev/null
+++ b/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/permission/BnProtectedInterface.h
@@ -0,0 +1,24 @@
+#pragma once
+
+#include "aidl/android/aidl/tests/permission/IProtectedInterface.h"
+
+#include <android/binder_ibinder.h>
+
+namespace aidl {
+namespace android {
+namespace aidl {
+namespace tests {
+namespace permission {
+class BnProtectedInterface : public ::ndk::BnCInterface<IProtectedInterface> {
+public:
+  BnProtectedInterface();
+  virtual ~BnProtectedInterface();
+protected:
+  ::ndk::SpAIBinder createBinder() override;
+private:
+};
+}  // namespace permission
+}  // namespace tests
+}  // namespace aidl
+}  // namespace android
+}  // namespace aidl
diff --git a/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/BpProtected.h b/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/permission/BpProtected.h
similarity index 82%
rename from tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/BpProtected.h
rename to tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/permission/BpProtected.h
index aa75c4e..be3444b 100644
--- a/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/BpProtected.h
+++ b/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/permission/BpProtected.h
@@ -1,6 +1,6 @@
 #pragma once
 
-#include "aidl/android/aidl/tests/IProtected.h"
+#include "aidl/android/aidl/tests/permission/IProtected.h"
 
 #include <android/binder_ibinder.h>
 
@@ -8,6 +8,7 @@
 namespace android {
 namespace aidl {
 namespace tests {
+namespace permission {
 class BpProtected : public ::ndk::BpCInterface<IProtected> {
 public:
   explicit BpProtected(const ::ndk::SpAIBinder& binder);
@@ -17,6 +18,7 @@
   ::ndk::ScopedAStatus MultiplePermissions() override;
   ::ndk::ScopedAStatus MultiplePermissions2() override;
 };
+}  // namespace permission
 }  // namespace tests
 }  // namespace aidl
 }  // namespace android
diff --git a/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/permission/BpProtectedInterface.h b/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/permission/BpProtectedInterface.h
new file mode 100644
index 0000000..7878862
--- /dev/null
+++ b/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/permission/BpProtectedInterface.h
@@ -0,0 +1,24 @@
+#pragma once
+
+#include "aidl/android/aidl/tests/permission/IProtectedInterface.h"
+
+#include <android/binder_ibinder.h>
+
+namespace aidl {
+namespace android {
+namespace aidl {
+namespace tests {
+namespace permission {
+class BpProtectedInterface : public ::ndk::BpCInterface<IProtectedInterface> {
+public:
+  explicit BpProtectedInterface(const ::ndk::SpAIBinder& binder);
+  virtual ~BpProtectedInterface();
+
+  ::ndk::ScopedAStatus Method1() override;
+  ::ndk::ScopedAStatus Method2() override;
+};
+}  // namespace permission
+}  // namespace tests
+}  // namespace aidl
+}  // namespace android
+}  // namespace aidl
diff --git a/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/IProtected.h b/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/permission/IProtected.h
similarity index 96%
rename from tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/IProtected.h
rename to tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/permission/IProtected.h
index 33be7b3..26bb785 100644
--- a/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/IProtected.h
+++ b/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/permission/IProtected.h
@@ -14,6 +14,7 @@
 namespace android {
 namespace aidl {
 namespace tests {
+namespace permission {
 class IProtected : public ::ndk::ICInterface {
 public:
   static const char* descriptor;
@@ -43,6 +44,7 @@
   ::ndk::SpAIBinder asBinder() override;
   bool isRemote() override;
 };
+}  // namespace permission
 }  // namespace tests
 }  // namespace aidl
 }  // namespace android
diff --git a/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/permission/IProtectedInterface.h b/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/permission/IProtectedInterface.h
new file mode 100644
index 0000000..2afb203
--- /dev/null
+++ b/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/permission/IProtectedInterface.h
@@ -0,0 +1,48 @@
+#pragma once
+
+#include <cstdint>
+#include <memory>
+#include <optional>
+#include <string>
+#include <vector>
+#include <android/binder_interface_utils.h>
+#ifdef BINDER_STABILITY_SUPPORT
+#include <android/binder_stability.h>
+#endif  // BINDER_STABILITY_SUPPORT
+
+namespace aidl {
+namespace android {
+namespace aidl {
+namespace tests {
+namespace permission {
+class IProtectedInterface : public ::ndk::ICInterface {
+public:
+  static const char* descriptor;
+  IProtectedInterface();
+  virtual ~IProtectedInterface();
+
+  static constexpr uint32_t TRANSACTION_Method1 = FIRST_CALL_TRANSACTION + 0;
+  static constexpr uint32_t TRANSACTION_Method2 = FIRST_CALL_TRANSACTION + 1;
+
+  static std::shared_ptr<IProtectedInterface> fromBinder(const ::ndk::SpAIBinder& binder);
+  static binder_status_t writeToParcel(AParcel* parcel, const std::shared_ptr<IProtectedInterface>& instance);
+  static binder_status_t readFromParcel(const AParcel* parcel, std::shared_ptr<IProtectedInterface>* instance);
+  static bool setDefaultImpl(const std::shared_ptr<IProtectedInterface>& impl);
+  static const std::shared_ptr<IProtectedInterface>& getDefaultImpl();
+  virtual ::ndk::ScopedAStatus Method1() = 0;
+  virtual ::ndk::ScopedAStatus Method2() = 0;
+private:
+  static std::shared_ptr<IProtectedInterface> default_impl;
+};
+class IProtectedInterfaceDefault : public IProtectedInterface {
+public:
+  ::ndk::ScopedAStatus Method1() override;
+  ::ndk::ScopedAStatus Method2() override;
+  ::ndk::SpAIBinder asBinder() override;
+  bool isRemote() override;
+};
+}  // namespace permission
+}  // namespace tests
+}  // namespace aidl
+}  // namespace android
+}  // namespace aidl
diff --git a/tests/golden_output/aidl-test-interface-rust-source/gen/android/aidl/tests/IProtected.rs.d b/tests/golden_output/aidl-test-interface-rust-source/gen/android/aidl/tests/IProtected.rs.d
deleted file mode 100644
index 0a72a08..0000000
--- a/tests/golden_output/aidl-test-interface-rust-source/gen/android/aidl/tests/IProtected.rs.d
+++ /dev/null
@@ -1,2 +0,0 @@
-out/soong/.intermediates/system/tools/aidl/aidl-test-interface-rust-source/gen/android/aidl/tests/IProtected.rs : \
-  system/tools/aidl/tests/android/aidl/tests/IProtected.aidl
diff --git a/tests/golden_output/aidl-test-interface-rust-source/gen/android/aidl/tests/IProtected.rs b/tests/golden_output/aidl-test-interface-rust-source/gen/android/aidl/tests/permission/IProtected.rs
similarity index 96%
rename from tests/golden_output/aidl-test-interface-rust-source/gen/android/aidl/tests/IProtected.rs
rename to tests/golden_output/aidl-test-interface-rust-source/gen/android/aidl/tests/permission/IProtected.rs
index 2a3a63d..e8ef428 100644
--- a/tests/golden_output/aidl-test-interface-rust-source/gen/android/aidl/tests/IProtected.rs
+++ b/tests/golden_output/aidl-test-interface-rust-source/gen/android/aidl/tests/permission/IProtected.rs
@@ -4,14 +4,14 @@
 #[allow(unused_imports)] use binder::IBinderInternal;
 use binder::declare_binder_interface;
 declare_binder_interface! {
-  IProtected["android.aidl.tests.IProtected"] {
+  IProtected["android.aidl.tests.permission.IProtected"] {
     native: BnProtected(on_transact),
     proxy: BpProtected {
     },
   }
 }
 pub trait IProtected: binder::Interface + Send {
-  fn get_descriptor() -> &'static str where Self: Sized { "android.aidl.tests.IProtected" }
+  fn get_descriptor() -> &'static str where Self: Sized { "android.aidl.tests.permission.IProtected" }
   fn PermissionProtected(&self) -> binder::public_api::Result<()>;
   fn MultiplePermissions(&self) -> binder::public_api::Result<()>;
   fn MultiplePermissions2(&self) -> binder::public_api::Result<()>;
@@ -128,5 +128,5 @@
   }
 }
 pub(crate) mod mangled {
- pub use super::IProtected as _7_android_4_aidl_5_tests_10_IProtected;
+ pub use super::IProtected as _7_android_4_aidl_5_tests_10_permission_10_IProtected;
 }
diff --git a/tests/golden_output/aidl-test-interface-rust-source/gen/android/aidl/tests/permission/IProtected.rs.d b/tests/golden_output/aidl-test-interface-rust-source/gen/android/aidl/tests/permission/IProtected.rs.d
new file mode 100644
index 0000000..72476b7
--- /dev/null
+++ b/tests/golden_output/aidl-test-interface-rust-source/gen/android/aidl/tests/permission/IProtected.rs.d
@@ -0,0 +1,2 @@
+out/soong/.intermediates/system/tools/aidl/aidl-test-interface-rust-source/gen/android/aidl/tests/permission/IProtected.rs : \
+  system/tools/aidl/tests/android/aidl/tests/permission/IProtected.aidl
diff --git a/tests/golden_output/aidl-test-interface-rust-source/gen/android/aidl/tests/permission/IProtectedInterface.rs b/tests/golden_output/aidl-test-interface-rust-source/gen/android/aidl/tests/permission/IProtectedInterface.rs
new file mode 100644
index 0000000..6ac11f7
--- /dev/null
+++ b/tests/golden_output/aidl-test-interface-rust-source/gen/android/aidl/tests/permission/IProtectedInterface.rs
@@ -0,0 +1,102 @@
+#![forbid(unsafe_code)]
+#![allow(non_upper_case_globals)]
+#![allow(non_snake_case)]
+#[allow(unused_imports)] use binder::IBinderInternal;
+use binder::declare_binder_interface;
+declare_binder_interface! {
+  IProtectedInterface["android.aidl.tests.permission.IProtectedInterface"] {
+    native: BnProtectedInterface(on_transact),
+    proxy: BpProtectedInterface {
+    },
+  }
+}
+pub trait IProtectedInterface: binder::Interface + Send {
+  fn get_descriptor() -> &'static str where Self: Sized { "android.aidl.tests.permission.IProtectedInterface" }
+  fn Method1(&self) -> binder::public_api::Result<()>;
+  fn Method2(&self) -> binder::public_api::Result<()>;
+  fn getDefaultImpl() -> IProtectedInterfaceDefaultRef where Self: Sized {
+    DEFAULT_IMPL.lock().unwrap().clone()
+  }
+  fn setDefaultImpl(d: IProtectedInterfaceDefaultRef) -> IProtectedInterfaceDefaultRef where Self: Sized {
+    std::mem::replace(&mut *DEFAULT_IMPL.lock().unwrap(), d)
+  }
+}
+pub trait IProtectedInterfaceDefault: Send + Sync {
+  fn Method1(&self) -> binder::public_api::Result<()> {
+    Err(binder::StatusCode::UNKNOWN_TRANSACTION.into())
+  }
+  fn Method2(&self) -> binder::public_api::Result<()> {
+    Err(binder::StatusCode::UNKNOWN_TRANSACTION.into())
+  }
+}
+pub mod transactions {
+  pub const Method1: binder::TransactionCode = binder::FIRST_CALL_TRANSACTION + 0;
+  pub const Method2: binder::TransactionCode = binder::FIRST_CALL_TRANSACTION + 1;
+}
+pub type IProtectedInterfaceDefaultRef = Option<std::sync::Arc<dyn IProtectedInterfaceDefault>>;
+use lazy_static::lazy_static;
+lazy_static! {
+  static ref DEFAULT_IMPL: std::sync::Mutex<IProtectedInterfaceDefaultRef> = std::sync::Mutex::new(None);
+}
+impl IProtectedInterface for BpProtectedInterface {
+  fn Method1(&self) -> binder::public_api::Result<()> {
+    let _aidl_reply = self.binder.transact(transactions::Method1, binder::FLAG_PRIVATE_LOCAL, |_aidl_data| {
+      Ok(())
+    });
+    if let Err(binder::StatusCode::UNKNOWN_TRANSACTION) = _aidl_reply {
+      if let Some(_aidl_default_impl) = <Self as IProtectedInterface>::getDefaultImpl() {
+        return _aidl_default_impl.Method1();
+      }
+    }
+    let _aidl_reply = _aidl_reply?;
+    let _aidl_status: binder::Status = _aidl_reply.read()?;
+    if !_aidl_status.is_ok() { return Err(_aidl_status); }
+    Ok(())
+  }
+  fn Method2(&self) -> binder::public_api::Result<()> {
+    let _aidl_reply = self.binder.transact(transactions::Method2, binder::FLAG_PRIVATE_LOCAL, |_aidl_data| {
+      Ok(())
+    });
+    if let Err(binder::StatusCode::UNKNOWN_TRANSACTION) = _aidl_reply {
+      if let Some(_aidl_default_impl) = <Self as IProtectedInterface>::getDefaultImpl() {
+        return _aidl_default_impl.Method2();
+      }
+    }
+    let _aidl_reply = _aidl_reply?;
+    let _aidl_status: binder::Status = _aidl_reply.read()?;
+    if !_aidl_status.is_ok() { return Err(_aidl_status); }
+    Ok(())
+  }
+}
+impl IProtectedInterface for binder::Binder<BnProtectedInterface> {
+  fn Method1(&self) -> binder::public_api::Result<()> { self.0.Method1() }
+  fn Method2(&self) -> binder::public_api::Result<()> { self.0.Method2() }
+}
+fn on_transact(_aidl_service: &dyn IProtectedInterface, _aidl_code: binder::TransactionCode, _aidl_data: &binder::parcel::Parcel, _aidl_reply: &mut binder::parcel::Parcel) -> binder::Result<()> {
+  match _aidl_code {
+    transactions::Method1 => {
+      let _aidl_return = _aidl_service.Method1();
+      match &_aidl_return {
+        Ok(_aidl_return) => {
+          _aidl_reply.write(&binder::Status::from(binder::StatusCode::OK))?;
+        }
+        Err(_aidl_status) => _aidl_reply.write(_aidl_status)?
+      }
+      Ok(())
+    }
+    transactions::Method2 => {
+      let _aidl_return = _aidl_service.Method2();
+      match &_aidl_return {
+        Ok(_aidl_return) => {
+          _aidl_reply.write(&binder::Status::from(binder::StatusCode::OK))?;
+        }
+        Err(_aidl_status) => _aidl_reply.write(_aidl_status)?
+      }
+      Ok(())
+    }
+    _ => Err(binder::StatusCode::UNKNOWN_TRANSACTION)
+  }
+}
+pub(crate) mod mangled {
+ pub use super::IProtectedInterface as _7_android_4_aidl_5_tests_10_permission_19_IProtectedInterface;
+}
diff --git a/tests/golden_output/aidl-test-interface-rust-source/gen/android/aidl/tests/permission/IProtectedInterface.rs.d b/tests/golden_output/aidl-test-interface-rust-source/gen/android/aidl/tests/permission/IProtectedInterface.rs.d
new file mode 100644
index 0000000..318359f
--- /dev/null
+++ b/tests/golden_output/aidl-test-interface-rust-source/gen/android/aidl/tests/permission/IProtectedInterface.rs.d
@@ -0,0 +1,2 @@
+out/soong/.intermediates/system/tools/aidl/aidl-test-interface-rust-source/gen/android/aidl/tests/permission/IProtectedInterface.rs : \
+  system/tools/aidl/tests/android/aidl/tests/permission/IProtectedInterface.aidl