Merge remote-tracking branch 'aosp/upstream-master' am: d7dff33e9c am: 78dac087a2

Original change: https://android-review.googlesource.com/c/platform/external/jarjar/+/2901510

Change-Id: I18474d7cac35343065d789033877a2287fdc6a95
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/src/main/com/tonicsystems/jarjar/ServiceProcessor.java b/src/main/com/tonicsystems/jarjar/ServiceProcessor.java
new file mode 100644
index 0000000..b59460c
--- /dev/null
+++ b/src/main/com/tonicsystems/jarjar/ServiceProcessor.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2024 Google Inc.
+ *
+ * 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 com.tonicsystems.jarjar;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+
+import com.tonicsystems.jarjar.util.EntryStruct;
+import com.tonicsystems.jarjar.util.JarProcessor;
+import java.io.IOException;
+import java.util.stream.Collectors;
+
+class ServiceProcessor implements JarProcessor {
+  private final PackageRemapper pr;
+
+  public ServiceProcessor(PackageRemapper pr) {
+    this.pr = pr;
+  }
+
+  private static final String SERVICES_PREFIX = "META-INF/services/";
+
+  @Override
+  public boolean process(EntryStruct struct) throws IOException {
+    if (struct.name.startsWith(SERVICES_PREFIX)) {
+      String serviceName = struct.name.substring(SERVICES_PREFIX.length());
+      struct.name = SERVICES_PREFIX + mapString(serviceName);
+
+      struct.data =
+          new String(struct.data, UTF_8)
+              .lines()
+              .map(this::mapString)
+              .collect(Collectors.joining("\n", "", "\n"))
+              .getBytes(UTF_8);
+    }
+    return true;
+  }
+
+  private String mapString(String s) {
+    return (String) pr.mapValue(s);
+  }
+}
diff --git a/src/test/com/tonicsystems/jarjar/ServiceProcessorTest.java b/src/test/com/tonicsystems/jarjar/ServiceProcessorTest.java
new file mode 100644
index 0000000..2d6ac69
--- /dev/null
+++ b/src/test/com/tonicsystems/jarjar/ServiceProcessorTest.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2024 Google Inc.
+ *
+ * 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 com.tonicsystems.jarjar;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+
+import com.tonicsystems.jarjar.util.EntryStruct;
+import java.util.Arrays;
+import junit.framework.TestCase;
+
+public class ServiceProcessorTest extends TestCase {
+  public void testProcess() throws Exception {
+    Rule rule = new Rule();
+    rule.setPattern("foo.**");
+    rule.setResult("bar.@1");
+    PackageRemapper remapper = new PackageRemapper(Arrays.asList(rule), false);
+    ServiceProcessor serviceProcessor = new ServiceProcessor(remapper);
+
+    EntryStruct struct = new EntryStruct();
+    struct.name = "META-INF/services/foo.Service";
+    struct.data = "foo.baz.ServiceImplementation\n".getBytes(UTF_8);
+
+    assertTrue(serviceProcessor.process(struct));
+    assertEquals("META-INF/services/bar.Service", struct.name);
+    assertEquals("bar.baz.ServiceImplementation\n", new String(struct.data, UTF_8));
+  }
+
+  public ServiceProcessorTest(String name) {
+    super(name);
+  }
+}