alts: add close to TsiHandshaker to avoid resource leak for some impls (#6186)

* alts: add close to TsiHandshaker to avoid resource leak for some implementations

* fix linter error
diff --git a/alts/src/main/java/io/grpc/alts/internal/AltsTsiHandshaker.java b/alts/src/main/java/io/grpc/alts/internal/AltsTsiHandshaker.java
index c8978cf..3cd639a 100644
--- a/alts/src/main/java/io/grpc/alts/internal/AltsTsiHandshaker.java
+++ b/alts/src/main/java/io/grpc/alts/internal/AltsTsiHandshaker.java
@@ -192,4 +192,9 @@
   public TsiFrameProtector createFrameProtector(ByteBufAllocator alloc) {
     return createFrameProtector(AltsTsiFrameProtector.getMaxAllowedFrameBytes(), alloc);
   }
+
+  @Override
+  public void close() {
+    handshaker.close();
+  }
 }
diff --git a/alts/src/main/java/io/grpc/alts/internal/NettyTsiHandshaker.java b/alts/src/main/java/io/grpc/alts/internal/NettyTsiHandshaker.java
index 8d4bbd1..5087123 100644
--- a/alts/src/main/java/io/grpc/alts/internal/NettyTsiHandshaker.java
+++ b/alts/src/main/java/io/grpc/alts/internal/NettyTsiHandshaker.java
@@ -149,4 +149,8 @@
     unwrapper = null;
     return internalHandshaker.createFrameProtector(alloc);
   }
+
+  void close() {
+    internalHandshaker.close();
+  }
 }
diff --git a/alts/src/main/java/io/grpc/alts/internal/TsiHandshakeHandler.java b/alts/src/main/java/io/grpc/alts/internal/TsiHandshakeHandler.java
index 2664ba8..a4123a7 100644
--- a/alts/src/main/java/io/grpc/alts/internal/TsiHandshakeHandler.java
+++ b/alts/src/main/java/io/grpc/alts/internal/TsiHandshakeHandler.java
@@ -185,4 +185,9 @@
       }
     }
   }
+
+  @Override
+  protected void handlerRemoved0(ChannelHandlerContext ctx) throws Exception {
+    handshaker.close();
+  }
 }
\ No newline at end of file
diff --git a/alts/src/main/java/io/grpc/alts/internal/TsiHandshaker.java b/alts/src/main/java/io/grpc/alts/internal/TsiHandshaker.java
index 967582a..35b9457 100644
--- a/alts/src/main/java/io/grpc/alts/internal/TsiHandshaker.java
+++ b/alts/src/main/java/io/grpc/alts/internal/TsiHandshaker.java
@@ -106,4 +106,9 @@
    * @return a new TsiFrameProtector.
    */
   TsiFrameProtector createFrameProtector(ByteBufAllocator alloc);
+
+  /**
+   * Closes resources.
+   */
+  void close();
 }
diff --git a/alts/src/test/java/io/grpc/alts/internal/AltsProtocolNegotiatorTest.java b/alts/src/test/java/io/grpc/alts/internal/AltsProtocolNegotiatorTest.java
index 67c3859..395090d 100644
--- a/alts/src/test/java/io/grpc/alts/internal/AltsProtocolNegotiatorTest.java
+++ b/alts/src/test/java/io/grpc/alts/internal/AltsProtocolNegotiatorTest.java
@@ -479,6 +479,11 @@
       protectors.add(protector);
       return protector;
     }
+
+    @Override
+    public void close() {
+      delegate.close();
+    }
   }
 
   private static class InterceptingProtector implements TsiFrameProtector {
diff --git a/alts/src/test/java/io/grpc/alts/internal/FakeTsiHandshaker.java b/alts/src/test/java/io/grpc/alts/internal/FakeTsiHandshaker.java
index d742607..a04bbfd 100644
--- a/alts/src/test/java/io/grpc/alts/internal/FakeTsiHandshaker.java
+++ b/alts/src/test/java/io/grpc/alts/internal/FakeTsiHandshaker.java
@@ -226,4 +226,9 @@
   public TsiFrameProtector createFrameProtector(ByteBufAllocator alloc) {
     return createFrameProtector(AltsTsiFrameProtector.getMaxAllowedFrameBytes(), alloc);
   }
+
+  @Override
+  public void close() {
+    // No-op
+  }
 }