Merge "Only update declared methods during class redefinition."
diff --git a/runtime/openjdkjvmti/ti_redefine.cc b/runtime/openjdkjvmti/ti_redefine.cc
index e68a657..533a3c8 100644
--- a/runtime/openjdkjvmti/ti_redefine.cc
+++ b/runtime/openjdkjvmti/ti_redefine.cc
@@ -1368,7 +1368,7 @@
   const art::DexFile::TypeId& declaring_class_id = dex_file_->GetTypeId(class_def.class_idx_);
   const art::DexFile& old_dex_file = mclass->GetDexFile();
   // Update methods.
-  for (art::ArtMethod& method : mclass->GetMethods(image_pointer_size)) {
+  for (art::ArtMethod& method : mclass->GetDeclaredMethods(image_pointer_size)) {
     const art::DexFile::StringId* new_name_id = dex_file_->FindStringId(method.GetName());
     art::dex::TypeIndex method_return_idx =
         dex_file_->GetIndexForTypeId(*dex_file_->FindTypeId(method.GetReturnTypeDescriptor()));
diff --git a/test/1910-transform-with-default/expected.txt b/test/1910-transform-with-default/expected.txt
new file mode 100644
index 0000000..f43ef61
--- /dev/null
+++ b/test/1910-transform-with-default/expected.txt
@@ -0,0 +1,4 @@
+hello
+hello
+Goodbye
+Goodbye
diff --git a/test/1910-transform-with-default/info.txt b/test/1910-transform-with-default/info.txt
new file mode 100644
index 0000000..96ebddd
--- /dev/null
+++ b/test/1910-transform-with-default/info.txt
@@ -0,0 +1,4 @@
+Tests basic functions in the jvmti plugin.
+
+Tests that we we can redefine classes that have default methods inherited from
+interfaces.
diff --git a/test/1910-transform-with-default/run b/test/1910-transform-with-default/run
new file mode 100755
index 0000000..c6e62ae
--- /dev/null
+++ b/test/1910-transform-with-default/run
@@ -0,0 +1,17 @@
+#!/bin/bash
+#
+# Copyright 2016 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.
+
+./default-run "$@" --jvmti
diff --git a/test/1910-transform-with-default/src/Main.java b/test/1910-transform-with-default/src/Main.java
new file mode 100644
index 0000000..fd8b3c7
--- /dev/null
+++ b/test/1910-transform-with-default/src/Main.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+public class Main {
+  public static void main(String[] args) throws Exception {
+    art.Test1910.run();
+  }
+}
diff --git a/test/1910-transform-with-default/src/art/Redefinition.java b/test/1910-transform-with-default/src/art/Redefinition.java
new file mode 100644
index 0000000..56d2938
--- /dev/null
+++ b/test/1910-transform-with-default/src/art/Redefinition.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2017 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 art;
+
+import java.util.ArrayList;
+// Common Redefinition functions. Placed here for use by CTS
+public class Redefinition {
+  public static final class CommonClassDefinition {
+    public final Class<?> target;
+    public final byte[] class_file_bytes;
+    public final byte[] dex_file_bytes;
+
+    public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) {
+      this.target = target;
+      this.class_file_bytes = class_file_bytes;
+      this.dex_file_bytes = dex_file_bytes;
+    }
+  }
+
+  // A set of possible test configurations. Test should set this if they need to.
+  // This must be kept in sync with the defines in ti-agent/common_helper.cc
+  public static enum Config {
+    COMMON_REDEFINE(0),
+    COMMON_RETRANSFORM(1),
+    COMMON_TRANSFORM(2);
+
+    private final int val;
+    private Config(int val) {
+      this.val = val;
+    }
+  }
+
+  public static void setTestConfiguration(Config type) {
+    nativeSetTestConfiguration(type.val);
+  }
+
+  private static native void nativeSetTestConfiguration(int type);
+
+  // Transforms the class
+  public static native void doCommonClassRedefinition(Class<?> target,
+                                                      byte[] classfile,
+                                                      byte[] dexfile);
+
+  public static void doMultiClassRedefinition(CommonClassDefinition... defs) {
+    ArrayList<Class<?>> classes = new ArrayList<>();
+    ArrayList<byte[]> class_files = new ArrayList<>();
+    ArrayList<byte[]> dex_files = new ArrayList<>();
+
+    for (CommonClassDefinition d : defs) {
+      classes.add(d.target);
+      class_files.add(d.class_file_bytes);
+      dex_files.add(d.dex_file_bytes);
+    }
+    doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]),
+                                   class_files.toArray(new byte[0][]),
+                                   dex_files.toArray(new byte[0][]));
+  }
+
+  public static void addMultiTransformationResults(CommonClassDefinition... defs) {
+    for (CommonClassDefinition d : defs) {
+      addCommonTransformationResult(d.target.getCanonicalName(),
+                                    d.class_file_bytes,
+                                    d.dex_file_bytes);
+    }
+  }
+
+  public static native void doCommonMultiClassRedefinition(Class<?>[] targets,
+                                                           byte[][] classfiles,
+                                                           byte[][] dexfiles);
+  public static native void doCommonClassRetransformation(Class<?>... target);
+  public static native void setPopRetransformations(boolean pop);
+  public static native void popTransformationFor(String name);
+  public static native void enableCommonRetransformation(boolean enable);
+  public static native void addCommonTransformationResult(String target_name,
+                                                          byte[] class_bytes,
+                                                          byte[] dex_bytes);
+}
diff --git a/test/1910-transform-with-default/src/art/Test1910.java b/test/1910-transform-with-default/src/art/Test1910.java
new file mode 100644
index 0000000..775fe63
--- /dev/null
+++ b/test/1910-transform-with-default/src/art/Test1910.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2017 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 art;
+
+import java.util.Base64;
+public class Test1910 {
+  static interface TestInterface {
+    public void sayHi();
+    public default void sayHiTwice() {
+      sayHi();
+      sayHi();
+    }
+  }
+
+  static class Transform implements TestInterface {
+    public void sayHi() {
+      System.out.println("hello");
+    }
+  }
+
+  /**
+   * base64 encoded class/dex file for
+   * class Transform implements TestInterface {
+   *   public void sayHi() {
+   *    System.out.println("Goodbye");
+   *   }
+   * }
+   */
+  private static final byte[] CLASS_BYTES = Base64.getDecoder().decode(
+    "yv66vgAAADQAIwoABgAPCQAQABEIABIKABMAFAcAFgcAGQcAGgEABjxpbml0PgEAAygpVgEABENv" +
+    "ZGUBAA9MaW5lTnVtYmVyVGFibGUBAAVzYXlIaQEAClNvdXJjZUZpbGUBAA1UZXN0MTkxMC5qYXZh" +
+    "DAAIAAkHABwMAB0AHgEAB0dvb2RieWUHAB8MACAAIQcAIgEAFmFydC9UZXN0MTkxMCRUcmFuc2Zv" +
+    "cm0BAAlUcmFuc2Zvcm0BAAxJbm5lckNsYXNzZXMBABBqYXZhL2xhbmcvT2JqZWN0AQAaYXJ0L1Rl" +
+    "c3QxOTEwJFRlc3RJbnRlcmZhY2UBAA1UZXN0SW50ZXJmYWNlAQAQamF2YS9sYW5nL1N5c3RlbQEA" +
+    "A291dAEAFUxqYXZhL2lvL1ByaW50U3RyZWFtOwEAE2phdmEvaW8vUHJpbnRTdHJlYW0BAAdwcmlu" +
+    "dGxuAQAVKExqYXZhL2xhbmcvU3RyaW5nOylWAQAMYXJ0L1Rlc3QxOTEwACAABQAGAAEABwAAAAIA" +
+    "AAAIAAkAAQAKAAAAHQABAAEAAAAFKrcAAbEAAAABAAsAAAAGAAEAAAAdAAEADAAJAAEACgAAACUA" +
+    "AgABAAAACbIAAhIDtgAEsQAAAAEACwAAAAoAAgAAAB8ACAAgAAIADQAAAAIADgAYAAAAEgACAAUA" +
+    "FQAXAAgABwAVABsGCA==");
+  private static final byte[] DEX_BYTES = Base64.getDecoder().decode(
+    "ZGV4CjAzNQCimuj5gqsyBEhWaMcfKWwG9eiBycoK3JfcAwAAcAAAAHhWNBIAAAAAAAAAABgDAAAV" +
+    "AAAAcAAAAAoAAADEAAAAAgAAAOwAAAABAAAABAEAAAQAAAAMAQAAAQAAACwBAACQAgAATAEAAK4B" +
+    "AAC2AQAAvwEAAN0BAAD3AQAABwIAACsCAABLAgAAYgIAAHYCAACKAgAAngIAAK0CAAC4AgAAuwIA" +
+    "AL8CAADMAgAA0gIAANcCAADgAgAA5wIAAAIAAAADAAAABAAAAAUAAAAGAAAABwAAAAgAAAAJAAAA" +
+    "CgAAAA0AAAANAAAACQAAAAAAAAAOAAAACQAAAKgBAAAIAAUAEQAAAAEAAAAAAAAAAQAAABMAAAAF" +
+    "AAEAEgAAAAYAAAAAAAAAAQAAAAAAAAAGAAAAoAEAAAsAAACQAQAACAMAAAAAAAACAAAA+QIAAP8C" +
+    "AAABAAEAAQAAAO4CAAAEAAAAcBADAAAADgADAAEAAgAAAPMCAAAIAAAAYgAAABoBAQBuIAIAEAAO" +
+    "AEwBAAAAAAAAAAAAAAAAAAABAAAAAAAAAAEAAAAHAAY8aW5pdD4AB0dvb2RieWUAHExhcnQvVGVz" +
+    "dDE5MTAkVGVzdEludGVyZmFjZTsAGExhcnQvVGVzdDE5MTAkVHJhbnNmb3JtOwAOTGFydC9UZXN0" +
+    "MTkxMDsAIkxkYWx2aWsvYW5ub3RhdGlvbi9FbmNsb3NpbmdDbGFzczsAHkxkYWx2aWsvYW5ub3Rh" +
+    "dGlvbi9Jbm5lckNsYXNzOwAVTGphdmEvaW8vUHJpbnRTdHJlYW07ABJMamF2YS9sYW5nL09iamVj" +
+    "dDsAEkxqYXZhL2xhbmcvU3RyaW5nOwASTGphdmEvbGFuZy9TeXN0ZW07AA1UZXN0MTkxMC5qYXZh" +
+    "AAlUcmFuc2Zvcm0AAVYAAlZMAAthY2Nlc3NGbGFncwAEbmFtZQADb3V0AAdwcmludGxuAAVzYXlI" +
+    "aQAFdmFsdWUAHQAHDgAfAAcOeAACAwEUGAICBAIPBAgQFwwAAAEBAICABNgCAQHwAgAAEAAAAAAA" +
+    "AAABAAAAAAAAAAEAAAAVAAAAcAAAAAIAAAAKAAAAxAAAAAMAAAACAAAA7AAAAAQAAAABAAAABAEA" +
+    "AAUAAAAEAAAADAEAAAYAAAABAAAALAEAAAMQAAABAAAATAEAAAEgAAACAAAAWAEAAAYgAAABAAAA" +
+    "kAEAAAEQAAACAAAAoAEAAAIgAAAVAAAArgEAAAMgAAACAAAA7gIAAAQgAAACAAAA+QIAAAAgAAAB" +
+    "AAAACAMAAAAQAAABAAAAGAMAAA==");
+
+  public static void run() {
+    Redefinition.setTestConfiguration(Redefinition.Config.COMMON_REDEFINE);
+    doTest(new Transform());
+  }
+
+  public static void doTest(TestInterface t) {
+    t.sayHiTwice();
+    Redefinition.doCommonClassRedefinition(Transform.class, CLASS_BYTES, DEX_BYTES);
+    t.sayHiTwice();
+  }
+}
diff --git a/test/921-hello-failure/expected.txt b/test/921-hello-failure/expected.txt
index fdbfbe2..f36d1a3 100644
--- a/test/921-hello-failure/expected.txt
+++ b/test/921-hello-failure/expected.txt
@@ -53,3 +53,6 @@
 hello - Unmodifiable
 Transformation error : java.lang.Exception(Failed to redefine class <[LTransform;> due to JVMTI_ERROR_UNMODIFIABLE_CLASS)
 hello - Unmodifiable
+hello - Undefault
+Transformation error : java.lang.Exception(Failed to redefine class <LTransform5;> due to JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED)
+hello - Undefault
diff --git a/test/921-hello-failure/src/Iface4.java b/test/921-hello-failure/src/Iface4.java
new file mode 100644
index 0000000..66804c2
--- /dev/null
+++ b/test/921-hello-failure/src/Iface4.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+interface Iface4 {
+  default void sayHiTwice(String s) {
+    sayHi(s);
+    sayHi(s);
+  }
+  void sayHi(String s);
+}
diff --git a/test/921-hello-failure/src/Main.java b/test/921-hello-failure/src/Main.java
index cfdcdc2..fb481bd 100644
--- a/test/921-hello-failure/src/Main.java
+++ b/test/921-hello-failure/src/Main.java
@@ -35,6 +35,7 @@
     MissingField.doTest(new Transform4("there"));
     FieldChange.doTest(new Transform4("there again"));
     Unmodifiable.doTest(new Transform[] { new Transform(), });
+    Undefault.doTest(new Transform5());
   }
 
   // TODO Replace this shim with a better re-write of this test.
diff --git a/test/921-hello-failure/src/Transform5.java b/test/921-hello-failure/src/Transform5.java
new file mode 100644
index 0000000..cf7b20a
--- /dev/null
+++ b/test/921-hello-failure/src/Transform5.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+class Transform5 implements Iface4 {
+  public void sayHi(String name) {
+    System.out.println("hello - " + name);
+  }
+}
diff --git a/test/921-hello-failure/src/Undefault.java b/test/921-hello-failure/src/Undefault.java
new file mode 100644
index 0000000..8303a84
--- /dev/null
+++ b/test/921-hello-failure/src/Undefault.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+import java.util.Base64;
+
+class Undefault {
+  // The following is a base64 encoding of the following class.
+  // class Transform5 implements Iface4 {
+  //   public void sayHiTwice(String s) {
+  //     throw new Error("Should not be called");
+  //   }
+  //   public void sayHi(String name) {
+  //     throw new Error("Should not be called!");
+  //   }
+  // }
+  private static final byte[] CLASS_BYTES = Base64.getDecoder().decode(
+    "yv66vgAAADQAGgoABwASBwATCAAUCgACABUIABYHABcHABgHABkBAAY8aW5pdD4BAAMoKVYBAARD" +
+    "b2RlAQAPTGluZU51bWJlclRhYmxlAQAKc2F5SGlUd2ljZQEAFShMamF2YS9sYW5nL1N0cmluZzsp" +
+    "VgEABXNheUhpAQAKU291cmNlRmlsZQEAD1RyYW5zZm9ybTUuamF2YQwACQAKAQAPamF2YS9sYW5n" +
+    "L0Vycm9yAQAUU2hvdWxkIG5vdCBiZSBjYWxsZWQMAAkADgEAFVNob3VsZCBub3QgYmUgY2FsbGVk" +
+    "IQEAClRyYW5zZm9ybTUBABBqYXZhL2xhbmcvT2JqZWN0AQAGSWZhY2U0ACAABgAHAAEACAAAAAMA" +
+    "AAAJAAoAAQALAAAAHQABAAEAAAAFKrcAAbEAAAABAAwAAAAGAAEAAAABAAEADQAOAAEACwAAACIA" +
+    "AwACAAAACrsAAlkSA7cABL8AAAABAAwAAAAGAAEAAAADAAEADwAOAAEACwAAACIAAwACAAAACrsA" +
+    "AlkSBbcABL8AAAABAAwAAAAGAAEAAAAGAAEAEAAAAAIAEQ==");
+  private static final byte[] DEX_BYTES = Base64.getDecoder().decode(
+    "ZGV4CjAzNQD5XbJiwMAcY0cucJ5gcVhFu7tMG0dZX8PsAgAAcAAAAHhWNBIAAAAAAAAAAFgCAAAN" +
+    "AAAAcAAAAAYAAACkAAAAAgAAALwAAAAAAAAAAAAAAAUAAADUAAAAAQAAAPwAAADQAQAAHAEAAIIB" +
+    "AACKAQAAlAEAAKIBAAC1AQAAyQEAAN0BAADzAQAACgIAABsCAAAeAgAAIgIAACkCAAABAAAAAgAA" +
+    "AAMAAAAEAAAABQAAAAkAAAAJAAAABQAAAAAAAAAKAAAABQAAAHwBAAABAAAAAAAAAAEAAQALAAAA" +
+    "AQABAAwAAAACAAEAAAAAAAMAAAAAAAAAAQAAAAAAAAADAAAAdAEAAAgAAAAAAAAARgIAAAAAAAAB" +
+    "AAEAAQAAADUCAAAEAAAAcBAEAAAADgAEAAIAAgAAADoCAAAIAAAAIgACABoBBwBwIAMAEAAnAAQA" +
+    "AgACAAAAQAIAAAgAAAAiAAIAGgEGAHAgAwAQACcAAQAAAAAAAAABAAAABAAGPGluaXQ+AAhMSWZh" +
+    "Y2U0OwAMTFRyYW5zZm9ybTU7ABFMamF2YS9sYW5nL0Vycm9yOwASTGphdmEvbGFuZy9PYmplY3Q7" +
+    "ABJMamF2YS9sYW5nL1N0cmluZzsAFFNob3VsZCBub3QgYmUgY2FsbGVkABVTaG91bGQgbm90IGJl" +
+    "IGNhbGxlZCEAD1RyYW5zZm9ybTUuamF2YQABVgACVkwABXNheUhpAApzYXlIaVR3aWNlAAEABw4A" +
+    "BgEABw4AAwEABw4AAAABAgCAgAScAgEBtAIBAdQCDAAAAAAAAAABAAAAAAAAAAEAAAANAAAAcAAA" +
+    "AAIAAAAGAAAApAAAAAMAAAACAAAAvAAAAAUAAAAFAAAA1AAAAAYAAAABAAAA/AAAAAEgAAADAAAA" +
+    "HAEAAAEQAAACAAAAdAEAAAIgAAANAAAAggEAAAMgAAADAAAANQIAAAAgAAABAAAARgIAAAAQAAAB" +
+    "AAAAWAIAAA==");
+
+  public static void doTest(Transform5 t) {
+    t.sayHi("Undefault");
+    try {
+      Main.doCommonClassRedefinition(Transform5.class, CLASS_BYTES, DEX_BYTES);
+    } catch (Exception e) {
+      System.out.println(
+          "Transformation error : " + e.getClass().getName() + "(" + e.getMessage() + ")");
+    }
+    t.sayHi("Undefault");
+  }
+}