Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

535
LINES

< > BotCompany Repo | #1014873 // Boot-up code for JavaX/Android (stage 2, JavaX, before logging changes)

JavaX source code (Android) [tags: use-pretranspiled] - run with: the app

Libraryless. Click here for Pure Java version (5338L/37K/129K).

1  
!7
2  
3  
set flag NoAWT. set flag Android. set flag AndroidOnly.
4  
5  
import java.util.*;
6  
import java.util.zip.*;
7  
import java.util.List;
8  
import java.util.regex.*;
9  
import java.util.concurrent.*;
10  
import java.util.concurrent.atomic.*;
11  
import java.io.*;
12  
import java.net.*;
13  
import java.lang.reflect.*;
14  
import java.lang.ref.*;
15  
import java.lang.management.*;
16  
import java.security.*;
17  
import java.security.spec.*;
18  
import java.math.*;
19  
20  
import android.widget.*;
21  
import android.view.*;
22  
import android.view.View;
23  
import android.view.Menu;
24  
import android.view.MenuItem;
25  
import android.widget.Button;
26  
import android.content.Context;
27  
import android.app.Activity;
28  
import android.view.KeyEvent;
29  
import android.view.inputmethod.*;
30  
import android.content.*;
31  
import android.text.*;
32  
33  
public class main {
34  
  sS awarenessID = #1004078, catEarID = #1014854;
35  
  
36  
  static volatile Class x30;
37  
  static volatile bool x30loading, x30loadingFailed;
38  
39  
  static List<Prog> programsStarted = new ArrayList<Prog>();
40  
  static File defSnip, defargs;
41  
  static volatile Class visibleProgram;
42  
  sbool dontSwitchToRunningProgram;
43  
  static ReliableSingleThread snippetTitleFinder;
44  
45  
  static class Prog {
46  
    String snippetID;
47  
    Thread thread;
48  
  }
49  
50  
  static class Lg {
51  
    static int maxBufferLength = 2048;
52  
    
53  
    Activity context;
54  
    ScrollView sv;
55  
    TextView tv;
56  
    EditText inputView;
57  
    LinearLayout ll;
58  
    StringBuffer buf = new StringBuffer();
59  
    
60  
    Lg(Activity context) {
61  
      this.context = context;
62  
      sv = new ScrollView(context);
63  
      tv = new TextView(context);
64  
      tv.setText(buf.toString());
65  
      sv.addView(tv);
66  
      sv.setLayoutParams(new LinearLayout.LayoutParams(
67  
        LinearLayout.LayoutParams.MATCH_PARENT,
68  
        LinearLayout.LayoutParams.MATCH_PARENT,
69  
        1.0f));
70  
      inputView = new EditText(context);
71  
      inputView.setInputType(InputType.TYPE_CLASS_TEXT); // turn off multiline
72  
      inputView.setOnEditorActionListener(new TextView.OnEditorActionListener() {
73  
        public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
74  
          if ((event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) || (actionId == EditorInfo.IME_ACTION_DONE)) {
75  
            String line = inputView.getText().toString();
76  
            try {
77  
              pout3.write((line + "\n").getBytes("UTF-8"));
78  
              pout3.flush();
79  
            } catch (Exception e) {}
80  
            inputView.selectAll();
81  
          }
82  
          return false;
83  
        }
84  
      });
85  
      ll = new LinearLayout(context);
86  
      ll.setOrientation(ll.VERTICAL);
87  
      ll.addView(sv);
88  
      ll.addView(inputView);
89  
    }
90  
    
91  
    View getView() {
92  
      return ll;
93  
    }
94  
    
95  
    void shortenBuffer() {
96  
      while (buf.length() > maxBufferLength) {
97  
        String s = buf.toString();
98  
        int i = s.indexOf('\n');
99  
        if (i < 0) return;
100  
        buf = new StringBuffer(s.substring(i+1));
101  
      }
102  
    }
103  
    
104  
    // TODO: coalesce
105  
    void print(final String s) {
106  
      androidUI_noWait(r {
107  
        buf.append(s);
108  
        shortenBuffer();
109  
        tv.setText(buf.toString());
110  
        
111  
        sv.post(new Runnable() {
112  
          public void run() {
113  
            // This method works but animates the scrolling 
114  
            // which looks weird on first load
115  
            sv.fullScroll(View.FOCUS_DOWN);
116  
117  
            // This method works even better because there are no animations.
118  
            //sv.scrollTo(0, sv.getBottom());
119  
          }
120  
        });
121  
      });
122  
    }
123  
    
124  
    void println(String s) {
125  
      print(s + "\n");
126  
    }
127  
  }
128  
  
129  
  public static String snippetToRun;
130  
  static TextView statusView;
131  
132  
  public static View main(final Context _context) throws Exception {
133  
    final Activity context = _context instanceof Activity ? (Activity) _context : null;
134  
    
135  
    visibleProgram = null;
136  
    
137  
    //System.out.println("676 context: " + _context);
138  
    androidContext = _context;
139  
    
140  
    if (context == null) { // I guess this is for boot time execution
141  
      if (snippetToRun != null) {
142  
        new Thread() {
143  
          public void run() {
144  
            String[] a = { snippetToRun };
145  
            callx30(a);
146  
          }
147  
        }.start();
148  
      }
149  
      return null;
150  
    }
151  
    
152  
    statusView = aTextView();
153  
    preloadx30();
154  
    while (x30 == null && !x30loading && !x30loadingFailed) sleep(10);
155  
156  
    int nInjections = l(injections());
157  
    if (dontSwitchToRunningProgram)
158  
      dontSwitchToRunningProgram = false;
159  
    else if (nInjections > 0) pcall {
160  
      ret getRunningProgramView(nInjections-1);
161  
    }
162  
    
163  
    prepareOptionsMenu();
164  
165  
    defSnip = new File(userHome(), ".javax/defsnip");
166  
    String id = loadTextFile(defSnip.getPath(), "636");
167  
    defargs = new File(userHome(), ".javax/defargs");
168  
    String arg = loadTextFile(defargs.getPath(), "");
169  
170  
    ScrollView sv = new ScrollView(context);
171  
    LinearLayout ll = new LinearLayout(context);
172  
    ll.setOrientation(LinearLayout.VERTICAL);
173  
    
174  
    ll.addView(statusView);
175  
    
176  
    for i to nInjections: {
177  
      final int _i = i;
178  
      ll.addView(aButton("Back to running program " + (i+1), r { showRunningProgram(_i) }));
179  
    }
180  
    for i to nInjections: {
181  
      final int _i = i;
182  
      ll.addView(aButton("Kill running program " + (i+1), r { killRunningProgram(_i) }));
183  
    }
184  
    
185  
    LinearLayout line1 = new LinearLayout(context);
186  
    line1.addView(aTextView("Snippet ID:"));
187  
    
188  
    final EditText tv = new EditText(context);
189  
    // BAD - tv.setInputType(InputType.TYPE_NUMBER_FLAG_DECIMAL);
190  
    tv.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_CLASS_NUMBER);
191  
    tv.setText(id);
192  
    line1.addView(tv);
193  
    
194  
    snippetTitleFinder = new ReliableSingleThread(r {
195  
      S id = aGetText(tv);
196  
      if (isSnippetID(id))
197  
        aSetText(statusView, snippetTitle(id));
198  
    });
199  
    
200  
    aOnChange(tv, snippetTitleFinder);
201  
    
202  
    Button btnRun = new Button(context);
203  
    btnRun.setText("Run");
204  
    line1.addView(btnRun);
205  
    
206  
    ll.addView(line1);
207  
    
208  
    LinearLayout line2 = new LinearLayout(context);
209  
    
210  
    line2.addView(aTextView("Program arguments:"));
211  
    
212  
    final EditText tvArgs = new EditText(context);
213  
    tvArgs.setText(arg);
214  
    line2.addView(tvArgs);
215  
    
216  
    ll.addView(line2);
217  
    
218  
    LinearLayout line3 = new LinearLayout(context);
219  
    
220  
    /*Button btnLeo = new Button(context);
221  
    btnLeo.setText("Sprechen mit Leo");
222  
    line3.addView(btnLeo);*/
223  
    
224  
    line3.addView(aButton("Cat Ear", r {
225  
      main.run(context, catEarID, new String[0]);
226  
    }));
227  
    
228  
    line3.addView(aButton("Start Awareness [" + awarenessID + "]", r {
229  
      saveDef(awarenessID, "");
230  
      main.run(context, awarenessID, new String[0]);
231  
    }));
232  
233  
    ll.addView(line3);
234  
    
235  
    btnRun.setOnClickListener(new View.OnClickListener() {
236  
      public void onClick(View v) {
237  
        hideKeyboard(context);
238  
        String snippetID = tv.getText().toString();
239  
        String text = "Running: " + snippetID;
240  
        Toast.makeText(context, text, 2000).show();
241  
        
242  
        saveDef(snippetID, tvArgs.getText().toString());
243  
        
244  
        // TODO: quoted args
245  
        run(context, snippetID, tvArgs.getText().toString().split(" +"));
246  
      }
247  
    });
248  
249  
    // Show initial status for 1 second, then snippet title
250  
    aLater(1000, snippetTitleFinder);
251  
    
252  
    sv.addView(ll);
253  
    return sv;
254  
  }
255  
  
256  
  static void saveDef(String snippetID, String args) {
257  
    try {
258  
      saveTextFile(defSnip.getPath(), snippetID);
259  
      saveTextFile(defargs.getPath(), args);
260  
    } catch (IOException e) {
261  
    }
262  
  }
263  
  
264  
  static Lg lg;
265  
  
266  
  static int systemInPipeSize = 4*1024; // 4 K
267  
  static PipedInputStream pin3;
268  
  static PipedOutputStream pout3;
269  
  
270  
  public static void run(final Activity context, final String mainSnippet, final String[] args) {
271  
    try {
272  
      pin3 = new PipedInputStream(systemInPipeSize);
273  
      pout3 = new PipedOutputStream(pin3);
274  
    } catch (IOException e) {}
275  
    
276  
    lg = new Lg(context);
277  
    
278  
    OutputStream outputStream = new OutputStream() {
279  
      public void write(int b) {
280  
        try {
281  
          lg.print(new String(new byte[] {(byte) b}, "UTF-8")); // This is crap
282  
        } catch (UnsupportedEncodingException e) {}
283  
      }
284  
      
285  
      @Override
286  
      public void write(byte[] b, int off, int len) {
287  
        try {
288  
          lg.print(new String(b, off, len, "UTF-8")); // This is crap
289  
        } catch (UnsupportedEncodingException e) {}
290  
      }
291  
    };
292  
    
293  
    PrintStream ps = new PrintStream(outputStream, true);
294  
    System.setOut(ps);
295  
    System.setErr(ps);
296  
    System.setIn(pin3);
297  
298  
    Prog prog = new Prog();
299  
    prog.snippetID = mainSnippet;
300  
301  
    prog.thread = new Thread() {
302  
      public void run() {
303  
        try {
304  
          String[] a = new String[args.length+1];
305  
          System.arraycopy(args, 0, a, 1, args.length);
306  
          a[0] = mainSnippet;
307  
          callx30(a);
308  
        } catch (Throwable e) {
309  
          System.out.println("Whoa!");
310  
          e.printStackTrace();
311  
        }
312  
      }
313  
    };
314  
    
315  
    programsStarted.add(prog);
316  
    prog.thread.start();
317  
    
318  
    context.setContentView(lg.getView());
319  
  }
320  
  
321  
  static void setContentViewInUIThread(final View view) {
322  
    androidUI(r {
323  
      androidActivity().setContentView(view);
324  
    });
325  
  }
326  
  
327  
  public static void hideKeyboard(Activity context) {   
328  
    View view = context.getCurrentFocus();
329  
    if (view != null) {
330  
        InputMethodManager inputManager = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
331  
        inputManager.hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
332  
    }
333  
  }
334  
  
335  
  static void onActivityResult(int requestCode, int resultCode, Intent data) {
336  
    /* TODO?
337  
    if (x30.mainClass != null)
338  
      x30.call(x30.mainClass, "onActivityResult", requestCode, resultCode, data);*/
339  
  }
340  
  
341  
  static void onPrepareOptionsPanel(View view, Menu menu) {
342  
    /* TODO
343  
    if (x30.mainClass != null)
344  
      x30.call(x30.mainClass, "onPrepareOptionsPanel", view, menu);*/
345  
  }
346  
  
347  
  static boolean onOptionsItemSelected(MenuItem item) {
348  
    /* TODO
349  
    if (x30.mainClass != null)
350  
      return (boolean) x30.call(x30.mainClass, "onOptionsItemSelected", item);*/
351  
    S s = str(item.getTitle());
352  
    print("Item title: " + quote(s));
353  
    if (eq(s, "Settings"))
354  
      showStartScreen();
355  
    else if (eqic(s, "Show Console")) {
356  
      visibleProgram = null;
357  
      androidActivity().setContentView(lg.getView());
358  
    }
359  
    callOpt(visibleProgram, 'onMenuCommand, s);
360  
    true;
361  
  }
362  
  
363  
  static void callx30(S[] args) {
364  
    while (x30 == null)
365  
      if (x30loadingFailed) fail("x30 load failed");
366  
      else sleep(10); // guess it's loading
367  
    print("Calling x30 " + join(" ", args));
368  
    pcall {
369  
      set(x30, "androidContext", androidContext);
370  
      ((ThreadLocal) get(x30, 'onProgramLoad)).set(voidfunc(O paa) {
371  
        visibleProgram = (Class) getOpt(paa, 'mainClass);
372  
        //print("Have visible program: " + visibleProgram);
373  
      });
374  
      callMain(x30, args);
375  
      L injections = injections();
376  
      //visibleProgram = (Class) getOpt(last(injections), 'mainClass); // TODO: imprecise if main program tempers with injections
377  
      //print("Have " + l(injections) + " injections, visibleProgram=" + visibleProgram);
378  
      //print("x30 done");
379  
    }
380  
  }
381  
  
382  
  svoid preloadx30() { thread { getx30(); } }
383  
  
384  
  static void getx30() {
385  
    try {
386  
      S status = "";
387  
      if (x30 != null) status = "Have x30.";
388  
      else {
389  
        O dataStore = null;
390  
        pcall {
391  
          dataStore = Class.forName("de.tinybrain.javax_allperms.DataStore");
392  
        }
393  
        if (dataStore != null) {
394  
          x30 = (Class) call(dataStore, "get", "x30");
395  
          if (x30 != null) status = "Have x30 from data store.";
396  
        }
397  
        if (x30 == null) {
398  
          x30loading = true;
399  
          status("Loading x30");
400  
          Class x30 = loadx30("#1004182");
401  
          callOpt(dataStore, "put", "x30", x30);
402  
          setOpt(x30, "bootUpClass", main.class);
403  
          main.x30 = x30;
404  
          status = "x30 loaded.";
405  
        }
406  
      }
407  
      L injections = injections();
408  
      if (nempty(injections))
409  
        status += " " + n2(injections, "injection");
410  
      status(status);
411  
    } catch e {
412  
      printStackTrace(e);
413  
      x30loadingFailed = true;
414  
    } finally {
415  
      x30loading = false;
416  
    }
417  
  }
418  
  
419  
  static L injections() {
420  
    ret (L) callOpt(x30, 'getInjections);
421  
  }
422  
  
423  
  svoid killRunningProgram(int i) {
424  
    try {
425  
      O paa = get(injections(), i);
426  
      if (paa == null) ret;
427  
      call(x30, 'removeInjection, paa);
428  
      showStartScreen();
429  
    } catch e {
430  
      printStackTrace(e);
431  
      status(str(e));
432  
    }
433  
  }
434  
  
435  
  svoid showStartScreen() {
436  
    androidUI(r {
437  
      dontSwitchToRunningProgram = true;
438  
      androidActivity().setContentView(main(androidContext()));
439  
    });
440  
  }
441  
  
442  
  svoid showRunningProgram(int i) {
443  
    View v = getRunningProgramView(i);
444  
    if (v != null)
445  
      setContentViewInUIThread(v);
446  
  }
447  
  
448  
  static View getRunningProgramView(int i) {
449  
    O paa = get(injections(), i);
450  
    if (paa == null) ret null with status("No running program to show");
451  
    Class mainClass = cast getOpt(paa, 'mainClass);
452  
    View view = cast getOpt(mainClass, 'androidShow_view);
453  
    if (view == null)
454  
      //ret null with status("Program has no view to show");
455  
      view = lg.getView(); // show log instead
456  
    print("Switched to program " + get(paa, 'progID));
457  
    visibleProgram = mainClass;
458  
    ViewGroup group = (ViewGroup) view.getParent();
459  
    if (group != null)
460  
      group.removeView(view);
461  
    ret view;
462  
  }
463  
  
464  
  svoid status(S s) {
465  
    aSetText(statusView, s);
466  
    print(s);
467  
  }
468  
  
469  
  static Class<?> loadx30(String programID) ctex {
470  
    System.out.println("Program ID: " + programID);
471  
    S url = "http://tinybrain.de:8080/dexcompile.php?id=" + parseSnippetID(programID);
472  
    byte[] dexData = loadBinaryPage(url);
473  
    if (!isDex(dexData))
474  
      throw new RuntimeException("Dex generation error");
475  
    System.out.println("Dex loaded: " + dexData.length + "b");
476  
477  
    File dexDir = makeAndroidTempDir();
478  
    File dexFile = new File(dexDir, System.currentTimeMillis() + ".dex");
479  
    File dexOutputDir = makeAndroidTempDir();
480  
481  
    System.out.println("Saving dex to: " + dexDir.getAbsolutePath());
482  
    try {
483  
      saveBinaryFile(dexFile.getPath(), dexData);
484  
    } catch (Throwable e) {
485  
      System.out.println("Whoa!");
486  
      throw new RuntimeException(e);
487  
    }
488  
489  
    System.out.println("Getting parent class loader.");
490  
    ClassLoader parentClassLoader =
491  
      main.class.getClassLoader().getParent();
492  
493  
    //System.out.println("Making DexClassLoader.");
494  
    //DexClassLoader classLoader = new DexClassLoader(dexFile.getAbsolutePath(), dexOutputDir.getAbsolutePath(), null,
495  
    //  parentClassLoader);
496  
    Class dcl = Class.forName("dalvik.system.DexClassLoader");
497  
    Object classLoader = dcl.getConstructors()[0].newInstance(dexFile.getAbsolutePath(), dexOutputDir.getAbsolutePath(), null,
498  
      parentClassLoader);
499  
500  
    System.out.println("Loading main class.");
501  
    Class<?> theClass = (Class<?>) call(classLoader, "loadClass", "x30");
502  
503  
    System.out.println("Main class loaded.");
504  
    try {
505  
      set(theClass, "androidContext", androidContext);
506  
    } catch (Throwable e) {}
507  
508  
    setVars(theClass, programID);
509  
    hotwire_copyOver(theClass);
510  
    return theClass;
511  
  }
512  
  
513  
  static void setVars(Class<?> theClass, String programID) {
514  
    try {
515  
      set(theClass, "programID", programID);
516  
    } catch (Throwable e) {}
517  
518  
    try {
519  
      set(theClass, "__javax", x30);
520  
    } catch (Throwable e) {}
521  
  }
522  
  
523  
  static String getConsoleOutput() {
524  
    ret lg.buf.toString();
525  
  }
526  
  
527  
  svoid prepareOptionsMenu {
528  
    pcall {
529  
      Menu menu = cast getOpt(androidActivity(), 'optionsMenu);
530  
      if (menu == null) ret;
531  
      if (menu.size() < 2)
532  
        menu.add("Show Console");
533  
    }
534  
  }
535  
}

Author comment

Began life as a copy of #676

download  show line numbers  debug dex  old transpilations   

Travelled to 13 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt

No comments. add comment

Snippet ID: #1014873
Snippet name: Boot-up code for JavaX/Android (stage 2, JavaX, before logging changes)
Eternal ID of this version: #1014873/3
Text MD5: d095c96ea1f225c27fecc6882f154e07
Transpilation MD5: 82a8e459d7faee2ba46c937756307a87
Author: stefan
Category: javax
Type: JavaX source code (Android)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2019-05-20 13:59:59
Source code size: 16236 bytes / 535 lines
Pitched / IR pitched: No / No
Views / Downloads: 377 / 3059
Version history: 2 change(s)
Referenced in: [show references]