1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.jdwptunnel.sampleapp.ddms;
18 
19 import android.app.Activity;
20 import android.os.Bundle;
21 import android.os.Debug;
22 import java.lang.reflect.Constructor;
23 import java.lang.reflect.Method;
24 
25 /**
26  * A simple activity which starts a thread that continuously spams DDMS messages.
27  *
28  * <p>This serves as a simple target application/activity get a ddms connection to.
29  */
30 public final class DdmsSampleDeviceActivity extends Activity {
31   @Override
onCreate(Bundle icicle)32   public void onCreate(Bundle icicle) {
33     try {
34       super.onCreate(icicle);
35       setContentView(R.layout.sample_layout);
36       Debug.attachJvmtiAgent(
37           "libDdmsTestAgent.so", null, DdmsSampleDeviceActivity.class.getClassLoader());
38       if (ForceNoHiddenapi() != 0) {
39         throw new Error("Failed to disable hiddenapi!");
40       }
41       Class<?> chunk_klass = Class.forName("org.apache.harmony.dalvik.ddmc.Chunk");
42       Constructor<?> chunk_cons =
43           chunk_klass.getConstructor(
44               Integer.TYPE, new byte[] {}.getClass(), Integer.TYPE, Integer.TYPE);
45       Class<?> server_klass = Class.forName("org.apache.harmony.dalvik.ddmc.DdmServer");
46       Method send_meth = server_klass.getDeclaredMethod("sendChunk", chunk_klass);
47       // Spin spamming DDMS packets so we can try to lose the race.
48       Thread t =
49           new Thread(
50               () -> {
51                 try {
52                   while (true) {
53                     send_meth.invoke(
54                         null,
55                         chunk_cons.newInstance(0xDEADBEEF, new byte[] {0x1, 0x3, 0x3, 0x7}, 0, 4));
56                   }
57                 } catch (Exception e) {
58                   throw new Error("Could not send data!", e);
59                 }
60               });
61       t.setDaemon(true);
62       t.start();
63     } catch (Exception e) {
64       throw new Error("Failed to send ddm notes!", e);
65     }
66   }
67 
68   // Linked by the agent
ForceNoHiddenapi()69   public static native int ForceNoHiddenapi();
70 }
71