mirror of
https://github.com/vectras-team/termux-x11.git
synced 2024-11-23 06:41:02 +00:00
Cursor positioning fix. Starter is moved to main apk. Implemented shell-loader which loads started dynamically from main apk to avoid version mismatches between main apk and starter.
This commit is contained in:
parent
aa53a085d5
commit
8e38aa670a
@ -62,6 +62,15 @@ android {
|
||||
jniLibs.srcDirs 'src/main/jni/prebuilt'
|
||||
}
|
||||
}
|
||||
|
||||
packagingOptions {
|
||||
jniLibs {
|
||||
// This will allow us to use shared libraries inside *.apk, without unpacking
|
||||
// @agnostic-apollo is the best
|
||||
// https://github.com/termux/termux-x11/commit/6cdfb75c4451eef63f114a93baef5ba73b7cfd8c#commitcomment-77856313
|
||||
useLegacyPackaging false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -85,4 +94,5 @@ dependencies {
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
|
||||
implementation 'androidx.annotation:annotation:1.5.0'
|
||||
implementation 'androidx.drawerlayout:drawerlayout:1.1.1'
|
||||
compileOnly project(':app:stub')
|
||||
}
|
||||
|
@ -12,10 +12,7 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.Rect;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
@ -30,10 +27,7 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.app.NotificationCompat;
|
||||
import androidx.core.view.ViewCompat;
|
||||
import androidx.core.view.WindowInsetsCompat;
|
||||
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.view.InputDevice;
|
||||
import android.view.KeyEvent;
|
||||
@ -42,17 +36,11 @@ import android.view.Surface;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.SurfaceView;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.WindowInsets;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import com.termux.x11.utils.KeyboardUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
|
||||
|
||||
@SuppressWarnings({"ConstantConditions", "SameParameterValue", "SdCardPath"})
|
||||
@SuppressLint({"ClickableViewAccessibility", "StaticFieldLeak"})
|
||||
@ -98,33 +86,6 @@ public class LorieService extends Service implements View.OnApplyWindowInsetsLis
|
||||
if (isServiceRunningInForeground(this, LorieService.class)) return;
|
||||
|
||||
compositor = createLorieThread();
|
||||
|
||||
File outDir = new File(getApplicationInfo().dataDir, "files");
|
||||
File out = new File(outDir, "en_us.xkbmap");
|
||||
File apk = null;
|
||||
|
||||
try {
|
||||
PackageManager pm = getPackageManager();
|
||||
String apkPath = pm.getApplicationInfo(getPackageName(), 0).publicSourceDir;
|
||||
apk = new File(apkPath);
|
||||
} catch (Throwable ignored) {}
|
||||
|
||||
if (!out.exists() || (apk != null && apk.lastModified() > out.lastModified())) {
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
outDir.mkdirs();
|
||||
try (InputStream fin = getAssets().open("en_us.xkbmap")) {
|
||||
byte[] buffer = new byte[8192];
|
||||
int count;
|
||||
try (FileOutputStream fout = new FileOutputStream(out)) {
|
||||
while ((count = fin.read(buffer)) != -1)
|
||||
fout.write(buffer, 0, count);
|
||||
fout.flush();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
if (compositor == 0) {
|
||||
Log.e("LorieService", "compositor thread was not created");
|
||||
return;
|
||||
@ -450,21 +411,7 @@ public class LorieService extends Service implements View.OnApplyWindowInsetsLis
|
||||
|
||||
@Override
|
||||
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
|
||||
DisplayMetrics dm = new DisplayMetrics();
|
||||
Rect r = new Rect();
|
||||
int mmWidth, mmHeight;
|
||||
act.getWindowManager().getDefaultDisplay().getMetrics(dm);
|
||||
act.getWindow().getDecorView().getWindowVisibleDisplayFrame(r);
|
||||
|
||||
if (act.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
|
||||
mmWidth = (int) Math.round((width * 25.4) / dm.xdpi);
|
||||
mmHeight = (int) Math.round((height * 25.4) / dm.ydpi);
|
||||
} else {
|
||||
mmWidth = (int) Math.round((width * 25.4) / dm.ydpi);
|
||||
mmHeight = (int) Math.round((height * 25.4) / dm.xdpi);
|
||||
}
|
||||
|
||||
svc.windowChanged(holder.getSurface(), r.right, r.bottom, mmWidth, mmHeight);
|
||||
svc.windowChanged(holder.getSurface(), width, height);
|
||||
}
|
||||
|
||||
@Override public void surfaceCreated(SurfaceHolder holder) {}
|
||||
@ -538,8 +485,7 @@ public class LorieService extends Service implements View.OnApplyWindowInsetsLis
|
||||
act.runOnUiThread(()-> {
|
||||
SurfaceView v = act.findViewById(R.id.cursorView);
|
||||
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(w, h);
|
||||
params.leftMargin = x;
|
||||
params.topMargin = y;
|
||||
params.setMargins(x, y, 0, 0);
|
||||
|
||||
v.setLayoutParams(params);
|
||||
v.setVisibility(View.VISIBLE);
|
||||
@ -547,7 +493,7 @@ public class LorieService extends Service implements View.OnApplyWindowInsetsLis
|
||||
}
|
||||
|
||||
private native void cursorChanged(Surface surface);
|
||||
private native void windowChanged(Surface surface, int width, int height, int mmWidth, int mmHeight);
|
||||
private native void windowChanged(Surface surface, int width, int height);
|
||||
private native void touchDown(int id, float x, float y);
|
||||
private native void touchMotion(int id, float x, float y);
|
||||
private native void touchUp(int id);
|
||||
|
@ -228,16 +228,9 @@ public class Starter {
|
||||
private native int openLogFD();
|
||||
private static native void exec(String path, String[] argv);
|
||||
@SuppressWarnings("FieldMayBeFinal")
|
||||
private static Handler handler;
|
||||
private static Handler handler = new Handler();
|
||||
|
||||
static {
|
||||
Looper.prepareMainLooper();
|
||||
handler = new Handler();
|
||||
|
||||
String libPath = System.getenv("CLASSPATH") +
|
||||
"!/lib/" + Build.SUPPORTED_ABIS[0] +
|
||||
"/libx11-starter.so";
|
||||
System.err.println("Loading shared library: " + libPath);
|
||||
System.load(libPath);
|
||||
System.loadLibrary("x11-starter");
|
||||
}
|
||||
}
|
@ -1,3 +1,3 @@
|
||||
ROOT_PATH := $(call my-dir)
|
||||
include $(ROOT_PATH)/lorie/Android.mk
|
||||
include $(ROOT_PATH)/../../../../common/src/main/jni/Android.mk
|
||||
include $(ROOT_PATH)/starter/Android.mk
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include "ashmem.h"
|
||||
#include <shm.h>
|
||||
#include <csignal>
|
||||
|
||||
#include <android/native_window_jni.h>
|
||||
@ -13,6 +13,8 @@
|
||||
#include <dirent.h>
|
||||
#include <android/log.h>
|
||||
|
||||
#define DEFAULT_DPI 96
|
||||
|
||||
#pragma ide diagnostic ignored "hicpp-signed-bitwise"
|
||||
#define unused __attribute__((__unused__))
|
||||
#define always_inline __attribute__((always_inline)) inline
|
||||
@ -55,9 +57,27 @@ lorie_compositor::lorie_compositor(jobject thiz): lorie_compositor() {
|
||||
});
|
||||
}
|
||||
|
||||
__asm__ (
|
||||
" .global blob\n"
|
||||
" .global blob_size\n"
|
||||
" .section .rodata\n"
|
||||
" blob:\n"
|
||||
" .incbin \"en_us.xkbmap\"\n"
|
||||
" 1:\n"
|
||||
" blob_size:\n"
|
||||
" .int 1b - blob"
|
||||
);
|
||||
|
||||
extern jbyte blob[];
|
||||
extern int blob_size;
|
||||
|
||||
void lorie_compositor::get_keymap(int *fd, int *size) { // NOLINT(readability-convert-member-functions-to-static)
|
||||
int keymap_fd = open("/data/data/com.termux.x11/files/en_us.xkbmap", O_RDONLY);
|
||||
struct stat s = {};
|
||||
int keymap_fd = os_create_anonymous_file(blob_size);
|
||||
void *dest = mmap(nullptr, blob_size, PROT_READ | PROT_WRITE, MAP_SHARED, keymap_fd, 0);
|
||||
memcpy(dest, blob, blob_size);
|
||||
munmap(dest, blob_size);
|
||||
|
||||
struct stat s = {};
|
||||
fstat(keymap_fd, &s);
|
||||
*size = s.st_size; // NOLINT(cppcoreguidelines-narrowing-conversions)
|
||||
*fd = keymap_fd;
|
||||
@ -200,9 +220,9 @@ JNI_DECLARE(LorieService, cursorChanged)(JNIEnv *env, jobject thiz, jobject surf
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
JNI_DECLARE(LorieService, windowChanged)(JNIEnv *env, jobject thiz, jobject surface, jint width, jint height, jint mm_width, jint mm_height) {
|
||||
JNI_DECLARE(LorieService, windowChanged)(JNIEnv *env, jobject thiz, jobject surface, jint w, jint h) {
|
||||
EGLNativeWindowType win = surface?ANativeWindow_fromSurface(env, surface):nullptr;
|
||||
queue<&lorie_compositor::output_resize>(env, thiz, win, width, height, mm_width, mm_height);
|
||||
queue<&lorie_compositor::output_resize>(env, thiz, win, w, h, int(w*25.4/DEFAULT_DPI), int(h*25.4/DEFAULT_DPI));
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
|
22
app/src/main/jni/lorie/include/shm.h
Normal file
22
app/src/main/jni/lorie/include/shm.h
Normal file
@ -0,0 +1,22 @@
|
||||
#include "ashmem.h"
|
||||
|
||||
static inline int
|
||||
os_create_anonymous_file(size_t size) {
|
||||
int fd, ret;
|
||||
long flags;
|
||||
fd = open("/dev/ashmem", O_RDWR | O_CLOEXEC);
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
ret = ioctl(fd, ASHMEM_SET_SIZE, size);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
flags = fcntl(fd, F_GETFD);
|
||||
if (flags == -1)
|
||||
goto err;
|
||||
if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1)
|
||||
goto err;
|
||||
return fd;
|
||||
err:
|
||||
close(fd);
|
||||
return ret;
|
||||
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
2
starter/src/main/jni/Android.mk → app/src/main/jni/starter/Android.mk
Normal file → Executable file
2
starter/src/main/jni/Android.mk → app/src/main/jni/starter/Android.mk
Normal file → Executable file
@ -5,5 +5,3 @@ LOCAL_MODULE := x11-starter
|
||||
LOCAL_SRC_FILES := starter.c
|
||||
LOCAL_LDLIBS := -llog -ldl
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
||||
include $(LOCAL_PATH)/../../../../common/src/main/jni/Android.mk
|
0
starter/src/main/jni/starter.c → app/src/main/jni/starter/starter.c
Normal file → Executable file
0
starter/src/main/jni/starter.c → app/src/main/jni/starter/starter.c
Normal file → Executable file
@ -5,33 +5,38 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
<FrameLayout
|
||||
android:id="@+id/frame"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipToPadding="false"
|
||||
android:layoutDirection="ltr"
|
||||
android:id="@+id/frame">
|
||||
android:paddingLeft="0dp"
|
||||
android:paddingTop="0dp"
|
||||
android:paddingRight="0dp"
|
||||
android:paddingBottom="0dp">
|
||||
|
||||
<SurfaceView
|
||||
android:id="@+id/lorieView"
|
||||
android:visibility="visible"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
android:layout_height="match_parent"
|
||||
android:visibility="visible" />
|
||||
|
||||
<SurfaceView
|
||||
android:id="@+id/cursorView"
|
||||
android:visibility="invisible"
|
||||
android:layout_gravity="left|top"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="left|top"
|
||||
android:visibility="invisible" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/stub"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center_horizontal|center_vertical"
|
||||
android:background="@android:color/transparent"
|
||||
android:visibility="visible"
|
||||
android:orientation="vertical">
|
||||
android:gravity="center_horizontal|center_vertical"
|
||||
android:orientation="vertical"
|
||||
android:visibility="visible">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/x11_image"
|
||||
@ -74,10 +79,10 @@
|
||||
|
||||
<Button
|
||||
android:id="@+id/getting_started_button"
|
||||
android:visibility="gone"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/getting_started_button_text" />
|
||||
android:text="@string/getting_started_button_text"
|
||||
android:visibility="gone" />
|
||||
</LinearLayout>
|
||||
|
||||
</FrameLayout>
|
||||
|
@ -16,16 +16,16 @@ mkdir -p $PREFIX/bin/
|
||||
mkdir -p $PREFIX/libexec/termux-x11
|
||||
|
||||
cp termux-x11 $PREFIX/bin/
|
||||
cp termux-startx11 $PREFIX/libexec/termux-x11
|
||||
cp starter/build/outputs/apk/debug/starter-debug.apk \
|
||||
$PREFIX/libexec/termux-x11/starter.apk
|
||||
cp termux-startx11 $PREFIX/libexec/termux-x11/
|
||||
cp shell-loader/build/outputs/apk/debug/shell-loader-debug.apk \
|
||||
$PREFIX/libexec/termux-x11/loader.apk
|
||||
|
||||
mkdir -p $CONTROL_DIR
|
||||
cat <<EOF > $CONTROL_DIR/control
|
||||
Package: termux-x11
|
||||
Architecture: all
|
||||
Maintainer: Twaik Yont @twaik
|
||||
Version: 1.02.06
|
||||
Version: 1.02.07
|
||||
Homepage: https://github.com/termux/termux-x11
|
||||
Depends: xwayland
|
||||
Description: Companion package for termux-x11 app
|
||||
|
@ -1,4 +1,5 @@
|
||||
include ':starter:stub'
|
||||
include ':starter'
|
||||
include ':shell-loader:stub'
|
||||
include ':shell-loader'
|
||||
include ':common'
|
||||
include ':app:stub'
|
||||
include ':app'
|
||||
|
0
starter/.gitignore → shell-loader/.gitignore
vendored
Normal file → Executable file
0
starter/.gitignore → shell-loader/.gitignore
vendored
Normal file → Executable file
28
starter/build.gradle → shell-loader/build.gradle
Normal file → Executable file
28
starter/build.gradle → shell-loader/build.gradle
Normal file → Executable file
@ -15,25 +15,12 @@ android {
|
||||
versionName "0.1"
|
||||
}
|
||||
|
||||
externalNativeBuild {
|
||||
ndkBuild {
|
||||
path "src/main/jni/Android.mk"
|
||||
}
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
|
||||
packagingOptions {
|
||||
jniLibs {
|
||||
// This will allow us to use shared libraries inside *.apk, without unpacking
|
||||
// @agnostic-apollo is the best
|
||||
// https://github.com/termux/termux-x11/commit/6cdfb75c4451eef63f114a93baef5ba73b7cfd8c#commitcomment-77856313
|
||||
useLegacyPackaging false
|
||||
signingConfigs {
|
||||
debug {
|
||||
storeFile file('../app/testkey_untrusted.jks')
|
||||
keyAlias 'alias'
|
||||
storePassword 'xrj45yWGLbsO7W0v'
|
||||
keyPassword 'xrj45yWGLbsO7W0v'
|
||||
}
|
||||
}
|
||||
|
||||
@ -45,6 +32,5 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation project(':common')
|
||||
compileOnly project(':starter:stub')
|
||||
compileOnly project(':shell-loader:stub')
|
||||
}
|
1
shell-loader/src/main/AndroidManifest.xml
Executable file
1
shell-loader/src/main/AndroidManifest.xml
Executable file
@ -0,0 +1 @@
|
||||
<manifest package="com.termux.x11.starter" />
|
70
shell-loader/src/main/java/com/termux/x11/Loader.java
Executable file
70
shell-loader/src/main/java/com/termux/x11/Loader.java
Executable file
@ -0,0 +1,70 @@
|
||||
package com.termux.x11;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Build;
|
||||
import android.os.Looper;
|
||||
import android.util.Log;
|
||||
|
||||
import dalvik.system.PathClassLoader;
|
||||
|
||||
@SuppressLint("UnsafeDynamicallyLoadedCode")
|
||||
public class Loader {
|
||||
private final static String targetPackageName = "com.termux.x11";
|
||||
private final static String targetClassName = "com.termux.x11.starter.Starter";
|
||||
private final static String logTag = "Termux:X11 loader";
|
||||
|
||||
/**
|
||||
* Command-line entry point.
|
||||
* It is pretty simple.
|
||||
* 1. We check if application is installed.
|
||||
* 2. We check if target apk has the same signature as loader's apk.
|
||||
* It is needed for to prevent running code of potentially replaced malicious apk.
|
||||
* 3. We load target apk code with `PathClassLoader` and start target's main function.
|
||||
*
|
||||
* This way we can make this loader version-agnostic and keep it secure.
|
||||
* All application logic is located in target apk.
|
||||
*
|
||||
* @param args The command-line arguments
|
||||
*/
|
||||
@SuppressLint("WrongConstant")
|
||||
public static void main(String[] args) {
|
||||
Looper.prepareMainLooper();
|
||||
Log.i(logTag, "started");
|
||||
Context ctx = android.app.ActivityThread.systemMain().getSystemContext();
|
||||
PackageManager pm = ctx.getPackageManager();
|
||||
|
||||
try {
|
||||
String selfPath = System.getProperty("java.class.path");
|
||||
PackageInfo selfInfo = pm.getPackageArchiveInfo(selfPath, PackageManager.GET_SIGNATURES);
|
||||
@SuppressLint("PackageManagerGetSignatures")
|
||||
PackageInfo targetInfo = pm.getPackageInfo("com.termux.x11", PackageManager.GET_SIGNATURES);
|
||||
if (selfInfo.signatures.length != targetInfo.signatures.length
|
||||
|| selfInfo.signatures[0].hashCode() != targetInfo.signatures[0].hashCode()) {
|
||||
System.err.println("Signatures of this loader and target application " + targetPackageName + " do not match.");
|
||||
System.err.println("Please, reinstall both termux-x11 package and Termux:X11 application from the same source");
|
||||
System.exit(134);
|
||||
}
|
||||
|
||||
ApplicationInfo target = pm.getApplicationInfo(targetPackageName, 0);
|
||||
Log.i(logTag, "loading " + target.sourceDir + " of " + targetPackageName + " application");
|
||||
|
||||
String librarySearchPath = target.sourceDir + "!/lib/" + Build.SUPPORTED_ABIS[0] + "/";
|
||||
PathClassLoader classLoader = new PathClassLoader(target.sourceDir, librarySearchPath,
|
||||
ClassLoader.getSystemClassLoader());
|
||||
try {
|
||||
Class<?> targetClass = Class.forName(targetClassName, true, classLoader);
|
||||
Log.i(logTag, "starting " + targetClassName + "::main();");
|
||||
targetClass.getMethod("main", String[].class).invoke(null, (Object) args);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
28
shell-loader/stub/build.gradle
Executable file
28
shell-loader/stub/build.gradle
Executable file
@ -0,0 +1,28 @@
|
||||
plugins {
|
||||
id('com.android.library')
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion 30
|
||||
defaultConfig {
|
||||
minSdkVersion 24
|
||||
//noinspection ExpiredTargetSdkVersion
|
||||
targetSdkVersion 28
|
||||
}
|
||||
buildFeatures {
|
||||
buildConfig false
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
}
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'androidx.annotation:annotation:1.5.0'
|
||||
}
|
1
shell-loader/stub/src/main/AndroidManifest.xml
Executable file
1
shell-loader/stub/src/main/AndroidManifest.xml
Executable file
@ -0,0 +1 @@
|
||||
<manifest package="com.termux.x11.stub" />
|
11
shell-loader/stub/src/main/java/android/app/ActivityThread.java
Executable file
11
shell-loader/stub/src/main/java/android/app/ActivityThread.java
Executable file
@ -0,0 +1,11 @@
|
||||
package android.app;
|
||||
|
||||
public class ActivityThread {
|
||||
public static ActivityThread systemMain() {
|
||||
throw new RuntimeException("STUB");
|
||||
}
|
||||
|
||||
public ContextImpl getSystemContext() {
|
||||
throw new RuntimeException("STUB");
|
||||
}
|
||||
}
|
6
shell-loader/stub/src/main/java/android/app/ContextImpl.java
Executable file
6
shell-loader/stub/src/main/java/android/app/ContextImpl.java
Executable file
@ -0,0 +1,6 @@
|
||||
package android.app;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
public abstract class ContextImpl extends Context {
|
||||
}
|
21
starter/proguard-rules.pro
vendored
21
starter/proguard-rules.pro
vendored
@ -1,21 +0,0 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
# Uncomment this to preserve the line number information for
|
||||
# debugging stack traces.
|
||||
#-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
@ -1,7 +0,0 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.termux.x11.starter">
|
||||
|
||||
<application
|
||||
android:label="TermuxX11Starter"
|
||||
android:supportsRtl="true" />
|
||||
</manifest>
|
@ -1,4 +1,4 @@
|
||||
#!/data/data/com.termux/files/usr/bin/sh
|
||||
export CLASSPATH=/data/data/com.termux/files/usr/libexec/termux-x11/starter.apk
|
||||
export CLASSPATH=/data/data/com.termux/files/usr/libexec/termux-x11/loader.apk
|
||||
unset LD_LIBRARY_PATH LD_PRELOAD
|
||||
exec /system/bin/app_process / com.termux.x11.starter.Starter "$@"
|
||||
exec /system/bin/app_process / com.termux.x11.Loader "$@"
|
||||
|
Loading…
Reference in New Issue
Block a user