Expose the StackWalker APIs from OpenJDK 17

The new APIs provide a way to
1. Retrive more details of each frame, e.g. StackFrame.getMethodType(),
   getDeclaringClass(), getByteCodeIndex()
2. Filter frames via Option.SHOW_REFLECT_FRAMES
3. Retrieve frames lazily by returning a Stream<StackFrame>

The upstream proposal has more details about the motivation.

Option.SHOW_HIDDEN_FRAMES has the same effect as SHOW_REFLECT_FRAMES,
but is exposed because
1. in favour of portaiblity if 3rd-party library needs to be compiled on
   Android
2. If ART module is updated to support hidden frames, existing app
   can use the option on the existing platform.
3. The existing javadoc has stated that the implementation can choose to
   support hidden frames or not. We don't violate the API contract even
   though the option has no extra effect.
4. The option isn't really hidden from app anyway, because it's exposed via
   Option.values().

All new APIs have the existing CTS test coverage.
See the below test commands

Bug: 191862780
Test: atest CtsLibcoreOjTestCases:test.java.lang
Test: atest CtsLibcoreTestCases:libcore.java.lang.StackWalkerTest
Change-Id: I43fbe4a596d6fa94692de424fb370d52c3722fc2
diff --git a/api/current.txt b/api/current.txt
index f7feb6c..cc458ea 100755
--- a/api/current.txt
+++ b/api/current.txt
@@ -3718,6 +3718,35 @@
     method public boolean isNativeMethod();
   }
 
+  public final class StackWalker {
+    method public void forEach(java.util.function.Consumer<? super java.lang.StackWalker.StackFrame>);
+    method public Class<?> getCallerClass();
+    method public static StackWalker getInstance();
+    method public static StackWalker getInstance(java.lang.StackWalker.Option);
+    method public static StackWalker getInstance(java.util.Set<java.lang.StackWalker.Option>);
+    method public static StackWalker getInstance(java.util.Set<java.lang.StackWalker.Option>, int);
+    method public <T> T walk(java.util.function.Function<? super java.util.stream.Stream<java.lang.StackWalker.StackFrame>,? extends T>);
+  }
+
+  public enum StackWalker.Option {
+    enum_constant public static final java.lang.StackWalker.Option RETAIN_CLASS_REFERENCE;
+    enum_constant public static final java.lang.StackWalker.Option SHOW_HIDDEN_FRAMES;
+    enum_constant public static final java.lang.StackWalker.Option SHOW_REFLECT_FRAMES;
+  }
+
+  public static interface StackWalker.StackFrame {
+    method public int getByteCodeIndex();
+    method public String getClassName();
+    method public Class<?> getDeclaringClass();
+    method public default String getDescriptor();
+    method public String getFileName();
+    method public int getLineNumber();
+    method public String getMethodName();
+    method public default java.lang.invoke.MethodType getMethodType();
+    method public boolean isNativeMethod();
+    method public StackTraceElement toStackTraceElement();
+  }
+
   public final class StrictMath {
     method public static double IEEEremainder(double, double);
     method public static int abs(int);
diff --git a/known_oj_tags.txt b/known_oj_tags.txt
index c92ec3c..91c56b0 100644
--- a/known_oj_tags.txt
+++ b/known_oj_tags.txt
@@ -20,3 +20,4 @@
 @spec
 @revised
 @jls
+@jvms
\ No newline at end of file
diff --git a/lint-baseline.xml b/lint-baseline.xml
index 2496fe9..2b2761d 100644
--- a/lint-baseline.xml
+++ b/lint-baseline.xml
@@ -1494,4 +1494,100 @@
             column="39"/>
     </issue>
 
+    <issue
+            id="NewApi"
+            message="Class requires API level Tiramisu (current min is 31): `java.lang.StackWalker.StackFrame`">
+        <location
+                file="libcore/ojluni/src/main/java/java/lang/LiveStackFrame.java"
+                line="44"/>
+    </issue>
+
+    <issue
+            id="NewApi"
+            message="Class requires API level Tiramisu (current min is 31): `java.lang.StackWalker.Option`">
+        <location
+                file="libcore/ojluni/src/main/java/java/lang/LiveStackFrame.java"
+                line="159"/>
+    </issue>
+
+    <issue
+            id="NewApi"
+            message="Class requires API level Tiramisu (current min is 31): `java.lang.StackWalker.StackFrame`">
+        <location
+                file="libcore/ojluni/src/main/java/java/lang/StackFrameInfo.java"
+                line="31"/>
+    </issue>
+
+    <issue
+            id="NewApi"
+            message="Field requires API level Tiramisu (current min is 31): `java.lang.StackWalker.Option#SHOW_HIDDEN_FRAMES`">
+        <location
+                file="libcore/ojluni/src/main/java/java/lang/StackStreamFactory.java"
+                line="146"/>
+    </issue>
+
+    <issue
+            id="NewApi"
+            message="Field requires API level Tiramisu (current min is 31): `java.lang.StackWalker.Option#SHOW_REFLECT_FRAMES`">
+        <location
+                file="libcore/ojluni/src/main/java/java/lang/StackStreamFactory.java"
+                line="258"/>
+    </issue>
+
+    <issue
+            id="NewApi"
+            message="Field requires API level Tiramisu (current min is 31): `java.lang.StackWalker.Option#SHOW_HIDDEN_FRAMES`">
+        <location
+                file="libcore/ojluni/src/main/java/java/lang/StackStreamFactory.java"
+                line="259"/>
+    </issue>
+
+    <issue
+            id="NewApi"
+            message="Class requires API level Tiramisu (current min is 31): `java.lang.StackWalker`">
+        <location
+                file="libcore/ojluni/src/main/java/java/lang/StackStreamFactory.java"
+                line="1055"/>
+    </issue>
+
+    <issue
+            id="NewApi"
+            message="Class requires API level Tiramisu (current min is 31): `java.lang.StackWalker.Option`">
+        <location
+                file="libcore/ojluni/src/main/java/java/lang/StackWalker.java"
+                line="295"/>
+    </issue>
+
+    <issue
+            id="NewApi"
+            message="Cast from `Option` to `Enum` requires API level 33 (current min is 31)">
+        <location
+                file="libcore/ojluni/src/main/java/java/lang/StackWalker.java"
+                line="340"/>
+    </issue>
+
+    <issue
+            id="NewApi"
+            message="Field requires API level Tiramisu (current min is 31): `java.lang.StackWalker.Option#RETAIN_CLASS_REFERENCE`">
+        <location
+                file="libcore/ojluni/src/main/java/java/lang/StackWalker.java"
+                line="420"/>
+    </issue>
+
+    <issue
+            id="NewApi"
+            message="Field requires API level Tiramisu (current min is 31): `java.lang.StackWalker.Option#RETAIN_CLASS_REFERENCE`">
+        <location
+                file="libcore/ojluni/src/main/java/java/lang/StackWalker.java"
+                line="428"/>
+    </issue>
+
+    <issue
+            id="NewApi"
+            message="Cast from `Option` to `Enum` requires API level 34 (current min is 31)">
+        <location
+                file="libcore/ojluni/src/main/java/java/lang/StackWalker.java"
+                line="340"/>
+    </issue>
+
 </issues>
diff --git a/luni/src/test/java/libcore/java/lang/StackWalkerTest.java b/luni/src/test/java/libcore/java/lang/StackWalkerTest.java
index 97d80d9..d24cbca 100644
--- a/luni/src/test/java/libcore/java/lang/StackWalkerTest.java
+++ b/luni/src/test/java/libcore/java/lang/StackWalkerTest.java
@@ -23,15 +23,19 @@
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.lang.StackWalker.Option;
 import java.lang.StackWalker.StackFrame;
 import java.nio.ByteBuffer;
+import java.util.Arrays;
 import java.util.List;
 import libcore.io.Streams;
 
 import dalvik.system.InMemoryDexClassLoader;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
 @RunWith(JUnit4.class)
 public class StackWalkerTest {
@@ -75,4 +79,34 @@
         }
     }
 
+    @Test
+    public void testOptionValueOf() {
+        assertSame(Option.RETAIN_CLASS_REFERENCE, Option.valueOf("RETAIN_CLASS_REFERENCE"));
+        assertSame(Option.SHOW_REFLECT_FRAMES, Option.valueOf("SHOW_REFLECT_FRAMES"));
+        assertSame(Option.SHOW_HIDDEN_FRAMES, Option.valueOf("SHOW_HIDDEN_FRAMES"));
+    }
+
+    @Test
+    public void testOptionValues() {
+        Option[] options = Option.values();
+        Option[] expected = new Option[] {
+                Option.RETAIN_CLASS_REFERENCE,
+                Option.SHOW_REFLECT_FRAMES,
+                Option.SHOW_HIDDEN_FRAMES,
+        };
+        for (Option e : expected) {
+            assertHasOption(options, e);
+        }
+        assertEquals(expected.length, options.length);
+    }
+
+    private void assertHasOption(Option[] options, Option expected) {
+        for (Option option : options) {
+            if (option == expected) {
+                return;
+            }
+        }
+        fail("fail to find " + expected + " in " + Arrays.toString(options));
+    }
+
 }
\ No newline at end of file
diff --git a/ojluni/src/main/java/java/lang/StackWalker.java b/ojluni/src/main/java/java/lang/StackWalker.java
index d10994e..056b994 100644
--- a/ojluni/src/main/java/java/lang/StackWalker.java
+++ b/ojluni/src/main/java/java/lang/StackWalker.java
@@ -85,7 +85,6 @@
  * to be thrown.
  *
  * @since 9
- * @hide Hide this API until it's fully implemented.
  */
 public final class StackWalker {
     /**
@@ -170,14 +169,14 @@
             throw new UnsupportedOperationException();
         }
 
-
+        // Android-changed: javadoc should refer to dex bytecodes on Android.
         /**
-         * Returns the index to the code array of the {@code Code} attribute
+         * Returns the index to the {@code insns} array of a {@code code_item}
          * containing the execution point represented by this stack frame.
-         * The code array gives the actual bytes of Java Virtual Machine code
+         * The code array gives the actual bytes of Dalvik bytecode
          * that implement the method.
          *
-         * @return the index to the code array of the {@code Code} attribute
+         * @return the index to the {@code insns} array of the {@code code_item} attribute
          *         containing the execution point represented by this stack frame,
          *         or a negative number if the method is native.
          *
@@ -271,6 +270,7 @@
          * are not filtered or controlled by any stack walking option.
          */
         SHOW_REFLECT_FRAMES,
+        // Android-changed: Add more details about the API usage on Android.
         /**
          * Shows all hidden frames.
          *
@@ -278,6 +278,9 @@
          * specific frames in addition to {@linkplain #SHOW_REFLECT_FRAMES
          * reflection frames}. A {@code StackWalker} with this {@code SHOW_HIDDEN_FRAMES}
          * option will show all hidden frames (including reflection frames).
+         *
+         * @apiNote This option has the same effect as {@link #SHOW_REFLECT_FRAMES} initially,
+         * until the Android Runtime supports other hidden frames.
          */
         SHOW_HIDDEN_FRAMES;
     }