ref: 0818148b0432a1b11d2feb72cca47156a603e884
dir: /gui-android/java/org/echoline/drawterm/MainActivity.java/
package org.echoline.drawterm; import android.content.Context; import android.content.SharedPreferences; import android.content.pm.ActivityInfo; import android.content.res.Resources; import android.graphics.Point; import android.os.Bundle; import android.os.Environment; import android.app.Activity; import android.app.Notification; import android.app.NotificationManager; import android.util.DisplayMetrics; import android.util.Log; import android.util.SparseIntArray; import android.util.Size; import android.view.Display; import android.view.MotionEvent; import android.view.View; import android.view.Menu; import android.view.MenuItem; import android.view.WindowManager; import android.view.Surface; import android.view.inputmethod.InputMethodManager; import android.view.KeyEvent; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.TextView; import android.widget.CheckBox; import android.content.ClipData; import android.content.ClipboardManager; import android.hardware.camera2.CameraManager; import android.hardware.camera2.CameraDevice; import android.hardware.camera2.CaptureRequest; import android.hardware.camera2.CaptureFailure; import android.hardware.camera2.CameraMetadata; import android.hardware.camera2.CameraCaptureSession; import android.hardware.camera2.CameraCharacteristics; import android.hardware.camera2.TotalCaptureResult; import android.hardware.camera2.params.StreamConfigurationMap; import android.media.Image; import android.media.ImageReader; import android.graphics.ImageFormat; import android.os.Handler; import android.os.HandlerThread; import android.location.Location; import android.location.LocationManager; import android.location.LocationListener; import java.io.File; import java.util.Map; import java.nio.ByteBuffer; import java.util.List; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; public class MainActivity extends Activity { private Map<String, ?> map; private MainActivity mainActivity; private boolean dtrunning = false; private DrawTermThread dthread; private int notificationId; private byte []jpegBytes; private String location; static { System.loadLibrary("drawterm"); } private static final SparseIntArray ORIENTATIONS = new SparseIntArray(); static { ORIENTATIONS.append(Surface.ROTATION_0, 0); ORIENTATIONS.append(Surface.ROTATION_90, 90); ORIENTATIONS.append(Surface.ROTATION_180, 180); ORIENTATIONS.append(Surface.ROTATION_270, 270); } static class CompareSizesByArea implements Comparator<Size> { @Override public int compare(Size lhs, Size rhs) { return Long.signum((long) lhs.getWidth() * lhs.getHeight() - (long) rhs.getWidth() * rhs.getHeight()); } } private static boolean contains(int[] modes, int mode) { if (modes == null) { return false; } for (int i : modes) { if (i == mode) { return true; } } return false; } public String getLocation() { LocationManager locationManager = ((LocationManager)getSystemService(Context.LOCATION_SERVICE)); location = ""; HandlerThread mBackgroundThread = new HandlerThread("Location Background"); mBackgroundThread.start(); locationManager.requestSingleUpdate(LocationManager.GPS_PROVIDER, new LocationListener() { @Override public void onLocationChanged(Location l) { location = l.getLatitude() + "\t" + l.getLongitude() + "\t" + l.getAltitude(); mBackgroundThread.quitSafely(); } @Override public void onProviderDisabled(String p) { mBackgroundThread.quitSafely(); } @Override public void onProviderEnabled(String p) { } @Override public void onStatusChanged(String p, int i, Bundle b) { } }, mBackgroundThread.getLooper()); try { mBackgroundThread.join(); } catch (Exception e) { e.printStackTrace(); } return location; } public void showNotification(String text) { Notification.Builder builder = new Notification.Builder(this) .setDefaults(Notification.DEFAULT_SOUND) .setSmallIcon(R.drawable.ic_small) .setContentText(text) .setStyle(new Notification.BigTextStyle().bigText(text)) .setPriority(Notification.PRIORITY_DEFAULT); ((NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE)).notify(notificationId, builder.build()); notificationId++; } public int numCameras() { try { return ((CameraManager)getSystemService(Context.CAMERA_SERVICE)).getCameraIdList().length; } catch (Exception e) { e.printStackTrace(); return 0; } } private static int sensorToDeviceRotation(CameraCharacteristics c, int deviceOrientation) { int sensorOrientation = c.get(CameraCharacteristics.SENSOR_ORIENTATION); deviceOrientation = ORIENTATIONS.get(deviceOrientation); if (c.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_FRONT) { deviceOrientation = -deviceOrientation; } return (sensorOrientation - deviceOrientation + 360) % 360; } public void takePicture(int id) { try { jpegBytes = null; HandlerThread mBackgroundThread = new HandlerThread("Camera Background"); mBackgroundThread.start(); Handler mBackgroundHandler = new Handler(mBackgroundThread.getLooper()); CameraManager manager = (CameraManager)getSystemService(Context.CAMERA_SERVICE); String []cameraIdList = manager.getCameraIdList(); CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraIdList[id]); StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP); Size size = Collections.max(Arrays.asList(map.getOutputSizes(ImageFormat.JPEG)), new CompareSizesByArea()); ImageReader reader = ImageReader.newInstance(size.getWidth(), size.getHeight(), ImageFormat.JPEG, 1); manager.openCamera(cameraIdList[id], new CameraDevice.StateCallback() { public void onOpened(CameraDevice device) { try { CaptureRequest.Builder captureBuilder = device.createCaptureRequest(CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG); captureBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO); Float minFocusDist = characteristics.get(CameraCharacteristics.LENS_INFO_MINIMUM_FOCUS_DISTANCE); if (!(minFocusDist == null || minFocusDist == 0)) { if (contains(characteristics.get(CameraCharacteristics.CONTROL_AF_AVAILABLE_MODES), CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE)) captureBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE); else captureBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_AUTO); } if (contains(characteristics.get(CameraCharacteristics.CONTROL_AE_AVAILABLE_MODES), CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH)) captureBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH); else captureBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON); if (contains(characteristics.get(CameraCharacteristics.CONTROL_AWB_AVAILABLE_MODES), CaptureRequest.CONTROL_AWB_MODE_AUTO)) captureBuilder.set(CaptureRequest.CONTROL_AWB_MODE, CameraMetadata.CONTROL_AWB_MODE_AUTO); captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, sensorToDeviceRotation(characteristics, getWindowManager().getDefaultDisplay().getRotation())); captureBuilder.addTarget(reader.getSurface()); reader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() { public void onImageAvailable(ImageReader reader) { Image image = null; try { image = reader.acquireLatestImage(); ByteBuffer buffer = image.getPlanes()[0].getBuffer(); jpegBytes = new byte[buffer.capacity()]; buffer.get(jpegBytes); } catch (Exception e) { e.printStackTrace(); } finally { if (image != null) { image.close(); } } } }, mBackgroundHandler); List<Surface> outputSurfaces = new ArrayList<Surface>(1); outputSurfaces.add(reader.getSurface()); device.createCaptureSession(outputSurfaces, new CameraCaptureSession.StateCallback() { public void onConfigured(CameraCaptureSession session) { try { List<CaptureRequest> captureRequests = new ArrayList<CaptureRequest>(10); for (int i = 0; i < 10; i++) captureRequests.add(captureBuilder.build()); session.captureBurst(captureRequests, new CameraCaptureSession.CaptureCallback() { public void onCaptureSequenceCompleted(CameraCaptureSession session, int sequenceId, long frameNumber) { Log.w("drawterm", "CaptureSession capture sequence completed"); sendPicture(jpegBytes); device.close(); } }, mBackgroundHandler); } catch (Exception e) { Log.w("drawterm", "CaptureSession capture failed"); e.printStackTrace(); sendPicture(jpegBytes); } } public void onConfigureFailed(CameraCaptureSession session) { Log.w("drawterm", "createCaptureSession configure failed"); sendPicture(jpegBytes); } }, mBackgroundHandler); } catch (Exception e) { e.printStackTrace(); sendPicture(jpegBytes); } } public void onDisconnected(CameraDevice device) { try { device.close(); } catch (Exception e) { e.printStackTrace(); } Log.e("drawterm", "openCamera onDisconnected"); } public void onError(CameraDevice device, int error) { try { device.close(); } catch (Exception e) { e.printStackTrace(); } Log.e("drawterm", "openCamera onError " + error); } public void onClosed(CameraDevice device) { try { mBackgroundThread.quitSafely(); mBackgroundThread.join(); } catch (Exception e) { e.printStackTrace(); } } }, mBackgroundHandler); } catch (Exception e) { e.printStackTrace(); sendPicture(jpegBytes); } } public void serverView(View v) { setContentView(R.layout.server_main); serverButtons(); String s = (String)map.get(((TextView)v).getText().toString()); String []a = s.split("\007"); ((EditText)findViewById(R.id.cpuServer)).setText((String)a[0]); ((EditText)findViewById(R.id.authServer)).setText((String)a[1]); ((EditText)findViewById(R.id.userName)).setText((String)a[2]); ((EditText)findViewById(R.id.passWord)).setText((String)a[3]); ((CheckBox)findViewById(R.id.aan)).setChecked(((String)a[4]).equals("true") ? true : false); ((CheckBox)findViewById(R.id.cmd)).setChecked(((String)a[5]).equals("true") ? true : false); ((CheckBox)findViewById(R.id.root)).setChecked(((String)a[6]).equals("true") ? true : false); } public void populateServers(Context context) { ListView ll = (ListView)findViewById(R.id.servers); ArrayAdapter<String> la = new ArrayAdapter<String>(this, R.layout.item_main); SharedPreferences settings = getSharedPreferences("DrawtermPrefs", 0); map = (Map<String, ?>)settings.getAll(); String key; Object []keys = map.keySet().toArray(); for (int i = 0; i < keys.length; i++) { key = (String)keys[i]; la.add(key); } ll.setAdapter(la); setDTSurface(null); dtrunning = false; } public void runDrawterm(String []args, String pass) { Resources res = getResources(); DisplayMetrics dm = res.getDisplayMetrics(); int wp = dm.widthPixels; int hp = dm.heightPixels; setContentView(R.layout.drawterm_main); Button kbutton = (Button)findViewById(R.id.keyboardToggle); kbutton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(final View view) { InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); imm.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, 0); } }); int rid = res.getIdentifier("navigation_bar_height", "dimen", "android"); if (rid > 0) { hp -= res.getDimensionPixelSize(rid); } LinearLayout ll = (LinearLayout)findViewById(R.id.dtButtons); hp -= ll.getHeight(); int w = (int)(wp * (160.0/dm.xdpi)); int h = (int)(hp * (160.0/dm.ydpi)); float ws = (float)wp/w; float hs = (float)hp/h; // only scale up if (ws < 1) { ws = 1; w = wp; } if (hs < 1) { hs = 1; h = hp; } MySurfaceView mView = new MySurfaceView(mainActivity, w, h, ws, hs); mView.getHolder().setFixedSize(w, h); LinearLayout l = (LinearLayout)findViewById(R.id.dlayout); l.addView(mView, 1, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT)); dthread = new DrawTermThread(args, pass, mainActivity); dthread.start(); dtrunning = true; } public void serverButtons() { Button button = (Button)findViewById(R.id.save); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String cpu = ((EditText)findViewById(R.id.cpuServer)).getText().toString(); String auth = ((EditText)findViewById(R.id.authServer)).getText().toString(); String user = ((EditText)findViewById(R.id.userName)).getText().toString(); String pass = ((EditText)findViewById(R.id.passWord)).getText().toString(); String aan = ((CheckBox)findViewById(R.id.aan)).isChecked() ? "true" : "false"; String cmd = ((CheckBox)findViewById(R.id.cmd)).isChecked() ? "true" : "false"; String root = ((CheckBox)findViewById(R.id.root)).isChecked() ? "true" : "false"; SharedPreferences settings = getSharedPreferences("DrawtermPrefs", 0); SharedPreferences.Editor editor = settings.edit(); editor.putString(user + "@" + cpu + " (auth=" + auth + ")", cpu + "\007" + auth + "\007" + user + "\007" + pass + "\007" + aan + "\007" + cmd + "\007" + root); editor.commit(); } }); button = (Button) findViewById(R.id.connect); button.setOnClickListener(new View.OnClickListener() { private String[] appendString(String []args, String s) { String ret[] = Arrays.copyOf(args, args.length + 1); ret[ret.length - 1] = s; return ret; } @Override public void onClick(final View view) { String cpu = ((EditText)findViewById(R.id.cpuServer)).getText().toString(); String auth = ((EditText)findViewById(R.id.authServer)).getText().toString(); String user = ((EditText)findViewById(R.id.userName)).getText().toString(); String pass = ((EditText)findViewById(R.id.passWord)).getText().toString(); String args[] = {"drawterm", "-h", cpu, "-a", auth, "-u", user}; if (((CheckBox)findViewById(R.id.aan)).isChecked()) args = appendString(args, "-p"); if (!((CheckBox)findViewById(R.id.cmd)).isChecked()) args = appendString(args, "-C"); if (!((CheckBox)findViewById(R.id.root)).isChecked()) args = appendString(args, "-R"); runDrawterm(args, pass); } }); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); mainActivity = this; setObject(); setContentView(R.layout.activity_main); populateServers(this); View fab = findViewById(R.id.fab); fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { setContentView(R.layout.server_main); serverButtons(); } }); } @Override public boolean dispatchKeyEvent(KeyEvent event) { if (!dtrunning) { return super.dispatchKeyEvent(event); } int k = event.getUnicodeChar(); if (k == 0) { k = event.getDisplayLabel(); if (k >= 'A' && k <= 'Z') k |= 0x20; } String chars = event.getCharacters(); if (k == 0 && chars != null) { for (int i = 0; i < chars.length(); i++) { k = chars.codePointAt(i); keyDown(k); keyUp(k); } return true; } if (k == 0) switch (event.getKeyCode()) { case KeyEvent.KEYCODE_DEL: k = 0x0008; break; case KeyEvent.KEYCODE_FORWARD_DEL: k = 0x007F; break; case KeyEvent.KEYCODE_ESCAPE: k = 0x001B; break; case KeyEvent.KEYCODE_MOVE_HOME: k = 0xF00D; break; case KeyEvent.KEYCODE_MOVE_END: k = 0xF018; break; case KeyEvent.KEYCODE_PAGE_UP: k = 0xF00F; break; case KeyEvent.KEYCODE_PAGE_DOWN: k = 0xF013; break; case KeyEvent.KEYCODE_INSERT: k = 0xF014; break; case KeyEvent.KEYCODE_SYSRQ: k = 0xF010; break; case KeyEvent.KEYCODE_DPAD_UP: k = 0xF00E; break; case KeyEvent.KEYCODE_DPAD_LEFT: k = 0xF011; break; case KeyEvent.KEYCODE_DPAD_RIGHT: k = 0xF012; break; case KeyEvent.KEYCODE_DPAD_DOWN: k = 0xF800; break; } if (k == 0) return true; if (event.isCtrlPressed()) { keyDown(0xF017); } if (event.isAltPressed() && k < 128) { keyDown(0xF015); } if (event.getAction() == KeyEvent.ACTION_DOWN) { keyDown(k); } else if (event.getAction() == KeyEvent.ACTION_UP) { keyUp(k); } if (event.isCtrlPressed()) { keyUp(0xF017); } if (event.isAltPressed() && k < 128) { keyUp(0xF015); } return true; } @Override public void onBackPressed() { } @Override public void onDestroy() { setDTSurface(null); dtrunning = false; exitDT(); super.onDestroy(); } public void setClipBoard(String str) { ClipboardManager cm = (ClipboardManager)getApplicationContext().getSystemService(Context.CLIPBOARD_SERVICE); if (cm != null) { ClipData cd = ClipData.newPlainText(null, str); cm.setPrimaryClip(cd); } } public String getClipBoard() { ClipboardManager cm = (ClipboardManager)getApplicationContext().getSystemService(Context.CLIPBOARD_SERVICE); if (cm != null) { ClipData cd = cm.getPrimaryClip(); if (cd != null) return (String)(cd.getItemAt(0).coerceToText(mainActivity.getApplicationContext()).toString()); } return ""; } public native void dtmain(Object[] args); public native void setPass(String arg); public native void setWidth(int arg); public native void setHeight(int arg); public native void setWidthScale(float arg); public native void setHeightScale(float arg); public native void setDTSurface(Surface surface); public native void setMouse(int[] args); public native void setObject(); public native void keyDown(int c); public native void keyUp(int c); public native void exitDT(); public native void sendPicture(byte[] array); }