Compare commits

...

14 Commits

Author SHA1 Message Date
Caten
553e5862ca Trixie text update 2026-02-06 18:41:17 +08:00
Caten
125791e44c Move fab button 2026-02-06 16:22:48 +08:00
Caten
587e93ca31 Fix links, update packages, update hangover, update readme, update avnc...... update code to v1.1.0 2026-02-06 10:58:04 +08:00
Caten
b2d45c95ac Fix hardcoded document provider name 2026-01-09 09:29:30 +08:00
Caten
b6b9ac61c7 Microphone support 2026-01-08 22:55:51 +08:00
Caten
45da44d078 Remove remaining uos texts 2026-01-08 08:43:19 +08:00
Caten
77fec49a75 Merge pull request #475 from Nriver/master
适配 Flutter 3.38+:使用官方 AssetManifest API 替换已移除的 json
2026-01-07 22:54:15 +08:00
Nate River
8cde9b878a Update asset loading mechanism in workflow.dart
Refactor asset loading to use AssetManifest API for better performance and clarity.
2026-01-07 17:29:44 +08:00
Caten
b15fe80e83 Merge pull request #424 from wcbing/master
Remove UOS-simulation for wechat (#418)
2025-11-01 15:16:54 +08:00
Caten
ae88dea9c5 Merge pull request #425 from wcbing/linuxqq
Update QQ
2025-11-01 15:16:42 +08:00
6425e0443e Remove UOS-simulation for wechat (#418) 2025-10-23 15:39:23 +08:00
Caten
010cf544ea fix 2025-10-21 20:52:29 +08:00
Caten
a4a2898214 Update issue template 2025-10-21 20:44:40 +08:00
wcbing
b2b642e7c0 Update QQ 2025-10-19 11:36:58 +08:00
29 changed files with 1067 additions and 190 deletions

View File

@@ -61,31 +61,17 @@ body:
- type: textarea
id: why-not-latest
attributes:
label: "若非最新版,必须说明原因"
label: "若非最新版,必须说明不使用最新版的原因"
placeholder: "详细解释原因..."
- type: textarea
id: steps
attributes:
label: "现问题的重现步骤"
label: "现问题的操作过程"
description: |
**为什么需要详细步骤?**
Linux的自由度极高任何操作都可能影响结果例如
- 是否通过sudo运行
- 是否修改过环境变量?
- 是否安装过第三方依赖?
placeholder: "也许可以从启动软件开始逐步描述..."
validations:
required: true
- type: textarea
id: logs
attributes:
label: "提供终端截图或其他相关信息"
description: |
**为什么需要这些?**
文字描述可能遗漏关键信息
placeholder: "粘贴日志文本或拖入图片..."
**请注意:**
请提供从启动软件开始到问题发生的**完整屏幕录制视频**而不要使用文字描述或截图因为根据以往的issue来看用户的描述会遗漏可能的细节。
由于Linux环境的复杂性任何操作细节如权限、环境配置等都可能影响问题的重现。确保你的问题在新安装的小小电脑上可以复现。
validations:
required: true
@@ -93,4 +79,4 @@ body:
attributes:
value: |
**问题优先级说明:**
本软件的初衷是安装PC级软件如WPS、CAJ Viewer、亿图图示。和这些软件相关的问题会得到重视。如果是其他问题得视情况(受限于精力和能力...没能修复的issue会保留以让更多人看到也许网友会有更好的解决办法
本软件的初衷是安装PC级软件如WPS、CAJ Viewer、亿图图示。小小电脑本身的问题,以及和这些软件相关的问题会得到重视。如果是其他问题尤其是第三方软件或Linux本身的使用方法等请在[discussion](https://github.com/Cateners/tiny_computer/discussions)区发布讨论

View File

@@ -60,7 +60,7 @@ body:
- type: textarea
id: why-not-latest
attributes:
label: "If not latest version, explanation is mandatory"
label: "If not using the latest version, you must explain the reason for not using the latest version"
placeholder: "Explain in detail..."
- type: textarea
@@ -68,23 +68,9 @@ body:
attributes:
label: "Steps to reproduce the issue"
description: |
**Why detailed steps?**
Linux offers extreme flexibility where any operation may affect results, such as:
- Did you run with sudo?
- Modified environment variables?
- Installed third-party dependencies?
placeholder: "Maybe start from launching the application..."
validations:
required: true
- type: textarea
id: logs
attributes:
label: "Provide terminal screenshots or other relevant information"
description: |
**Why is this needed?**
Text descriptions might omit critical details
placeholder: "Paste log text or drag images here..."
**Please note:**
Provide a **complete screen recording video** starting from launching the software until the issue occurs, rather than using text descriptions or screenshots. Based on past issues, user descriptions often omit potential details.
Due to the complexity of the Linux environment, any operational details (such as permissions, environment configurations, etc.) may affect issue reproduction. Ensure your issue can be reproduced on a freshly installed Tiny Computer.
validations:
required: true
@@ -92,4 +78,4 @@ body:
attributes:
value: |
**Issue Priority Explanation:**
This software's primary purpose is running PC-level applications like WPS, CAJ Viewer, and Edraw Max. Issues related to these applications will receive priority. Other issues will be handled case-by-case (limited by time and capabilities...). Unresolved issues will remain open for community visibility - maybe someone has a better solution!
The original purpose of this software is to install PC-level applications such as WPS, CAJ Viewer, and Edraw Max. Issues related to the Tiny Computer itself and problems associated with these software will be prioritized. For other issues, especially those involving third-party software or general Linux usage, please post in the [discussion](https://github.com/Cateners/tiny_computer/discussions) section.

View File

@@ -14,7 +14,8 @@ body:
attributes:
label: "必须说明使用场景和价值"
description: |
**为什么需要这个?(附用户调研数据或统计截图更佳,避免主观描述)**
**为什么需要这个?实现这个会对其他用户带来什么好处?开发者会花费许多时间在上面,这对开发者有什么好处?**
(简单来说,就是不要许愿,用充分的理由来说服我或其他潜在(?)的开发者吧!如果你想要一个功能,要么有时间自己学自己开发,要么用钱雇人做,要么等待其他和你想法一致且有时间或有钱的人来做)
因为精力有限我会更高可能采纳有价值且易实现的功能。没能处理的issue会保留以让更多人看到也许网友会有更好的解决办法
validations:
required: true

View File

@@ -14,7 +14,8 @@ body:
attributes:
label: "Must specify usage scenarios and value"
description: |
**Why is this needed? (User research data or screenshot statistics are preferred. Avoid subjective descriptions.)**
**Why is this needed? What benefits will implementing this bring to other users? Developers will spend a lot of time on this—whats in it for them?**
(In short, dont just make a wish—convince me or other potential (?) developers with solid reasoning! If you want a feature, either take the time to learn and develop it yourself, pay someone to do it, or wait for someone who shares your idea and has the time or money to implement it.)
Due to limited resources, I'm more likely to adopt valuable and easily implementable features. Unaddressed issues will remain visible for community solutions!
validations:
required: true

View File

@@ -5,7 +5,7 @@
给所有安卓 9 以上 arm64 设备的“PC 应用引擎”平替。你可以在小小电脑上安装 PC 级 WPS、CAJ Viewer、亿图图示等软件。
Run Debian Bookworm with XFCE, LXQt, or other desktop environments on Android—just with one click. Originally developed for Chinese users to run applications like WPS Office, it comes preinstalled with tools such as the Fcitx Pinyin input method. Please note that this app does not require Termux.
Run Debian Trixie with XFCE, LXQt, or other desktop environments on Android—just with one click. Originally developed for Chinese users to run applications like WPS Office, it comes preinstalled with tools such as the Fcitx Pinyin input method. Please note that this app does not require Termux.
To change the language inside the container, simply run the `tmoe` command, select “Manager” and navigate to the locale settings. The root filesystem was built using [tmoe](https://github.com/2moe/tmoe), so locale configuration is handled through it. You will also need to update the `LANG=zh_CN.UTF-8` environment variable in the startup command (go to Control → Advanced Settings → Startup Command) when switching to another language.

View File

@@ -59,6 +59,13 @@ android {
buildConfigField "String", "COMMIT", "\"" + ("git rev-parse HEAD\n".execute().getText().trim() ?: (System.getenv('CURRENT_COMMIT') ?: "NO_COMMIT")) + "\""
externalNativeBuild {
cmake {
cppFlags "-std=c++11"
arguments "-DANDROID_STL=c++_shared"
}
}
}
signingConfigs {
release {
@@ -100,6 +107,12 @@ android {
//checkReleaseBuilds false
abortOnError false
}
externalNativeBuild {
cmake {
path "src/main/cpp/CMakeLists.txt"
version "3.22.1"
}
}
packagingOptions {
pickFirst 'lib/arm64-v8a/libc++_shared.so'

View File

@@ -12,3 +12,6 @@
# 保持 Termux X11 所有内容
-keep class com.termux.x11.** { *; }
-keepclassmembers class com.termux.x11.** { *; }
-dontwarn javax.annotation.Nullable

View File

@@ -4,7 +4,7 @@
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
<application

View File

@@ -0,0 +1,11 @@
cmake_minimum_required(VERSION 3.18.1)
project("native-socket")
# 添加库
add_library(native-socket SHARED native-socket.cpp)
# 链接日志库
find_library(log-lib log)
# 指定目标属性
target_link_libraries(native-socket ${log-lib})

View File

@@ -0,0 +1,78 @@
#include <jni.h>
#include <string>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <android/log.h>
#include <cerrno>
#define LOG_TAG "NativeAudio"
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
int server_fd = -1;
int client_fd = -1;
extern "C" JNIEXPORT jint JNICALL
Java_com_example_tiny_1computer_AudioStream_nativeInit(JNIEnv *env, jobject thiz, jstring path) {
const char *socket_path = env->GetStringUTFChars(path, 0);
server_fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (server_fd == -1) {
LOGE("Socket creation failed");
return -1;
}
struct sockaddr_un addr;
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path) - 1);
unlink(socket_path); // Remove existing file if any
if (bind(server_fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
LOGE("Bind failed: %s", strerror(errno));
close(server_fd);
return -1;
}
if (listen(server_fd, 1) == -1) {
LOGE("Listen failed");
close(server_fd);
return -1;
}
env->ReleaseStringUTFChars(path, socket_path);
return 0;
}
extern "C" JNIEXPORT jint JNICALL
Java_com_example_tiny_1computer_AudioStream_nativeAccept(JNIEnv *env, jobject thiz) {
if (server_fd == -1) return -1;
// Blocks here until Linux connects
client_fd = accept(server_fd, NULL, NULL);
if (client_fd == -1) {
LOGE("Accept failed: %s", strerror(errno));
return -1;
}
return 0;
}
extern "C" JNIEXPORT jint JNICALL
Java_com_example_tiny_1computer_AudioStream_nativeSend(JNIEnv *env, jobject thiz, jbyteArray data, jint size) {
if (client_fd == -1) return -1;
jbyte *buffer = env->GetByteArrayElements(data, NULL);
ssize_t sent = write(client_fd, buffer, size);
env->ReleaseByteArrayElements(data, buffer, JNI_ABORT);
if (sent == -1 && errno != EAGAIN) {
LOGE("Write failed (Broken Pipe?)");
return -1;
}
return sent;
}
extern "C" JNIEXPORT void JNICALL
Java_com_example_tiny_1computer_AudioStream_nativeClose(JNIEnv *env, jobject thiz) {
if (client_fd != -1) { close(client_fd); client_fd = -1; }
if (server_fd != -1) { close(server_fd); server_fd = -1; }
}

View File

@@ -67,7 +67,7 @@ public class TinyDocumentsProvider extends DocumentsProvider {
@Override
public Cursor queryRoots(String[] projection) {
final MatrixCursor result = new MatrixCursor(projection != null ? projection : DEFAULT_ROOT_PROJECTION);
final String applicationName = "小小电脑";
final String applicationName = getContext().getString(R.string.tc_app_name);
final File BASE_DIR = new File(getContext().getFilesDir(), "containers");
final MatrixCursor.RowBuilder row = result.newRow();
row.add(Root.COLUMN_ROOT_ID, getDocIdForFile(BASE_DIR));

View File

@@ -0,0 +1,99 @@
package com.example.tiny_computer
import android.annotation.SuppressLint
import android.media.AudioFormat
import android.media.AudioRecord
import android.media.MediaRecorder
import android.util.Log
object AudioStream {
init {
System.loadLibrary("native-socket")
}
private var isStreaming = false
private var recordingThread: Thread? = null
// Native functions
private external fun nativeInit(path: String): Int
private external fun nativeAccept(): Int
private external fun nativeSend(data: ByteArray, size: Int): Int
private external fun nativeClose()
@SuppressLint("MissingPermission") // Ensure RECORD_AUDIO is granted in Manifest
fun startStreaming(path: String) {
if (isStreaming) return
isStreaming = true
recordingThread = Thread {
// 1. Initialize Socket Server
if (nativeInit(path) < 0) {
Log.e("AudioStream", "Failed to bind socket")
isStreaming = false
return@Thread
}
// 2. Wait for Linux client to connect (Blocking)
Log.d("AudioStream", "Waiting for connection on $path...")
if (nativeAccept() < 0) {
Log.e("AudioStream", "Accept failed")
isStreaming = false
return@Thread
}
Log.d("AudioStream", "Client connected!")
// 3. Setup AudioRecord
val sampleRate = 44100
val bufferSize = AudioRecord.getMinBufferSize(
sampleRate,
AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT
)
val recorder = AudioRecord(
MediaRecorder.AudioSource.MIC,
sampleRate,
AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT,
bufferSize
)
val data = ByteArray(bufferSize)
recorder.startRecording()
val discardMillis = 5000 // 丢弃前5秒
val discardBytes = (sampleRate * 2 * discardMillis / 1000).toInt() // 16bit = 2字节
var bytesRead = 0
// 先读取并丢弃初始数据
while (bytesRead < discardBytes && isStreaming) {
val readBytes = recorder.read(data, 0, minOf(bufferSize, discardBytes - bytesRead))
if (readBytes > 0) {
bytesRead += readBytes
}
}
// 4. Streaming Loop
while (isStreaming) {
val readBytes = recorder.read(data, 0, bufferSize)
if (readBytes > 0) {
val sent = nativeSend(data, readBytes)
if (sent < 0) break // Socket broken
}
}
// Cleanup
recorder.stop()
recorder.release()
nativeClose()
}
recordingThread?.start()
}
fun stopStreaming() {
isStreaming = false
nativeClose() // Unblocks the native Accept/Send if hung
recordingThread?.join()
recordingThread = null
}
}

View File

@@ -27,6 +27,12 @@ class MainActivity: FlutterActivity() {
"getNativeLibraryPath" -> {
result.success(getApplicationInfo().nativeLibraryDir)
}
"startStreaming" -> {
AudioStream.startStreaming(call.argument("path")!!)
}
"stopStreaming" -> {
AudioStream.stopStreaming()
}
else -> {
// 不支持的方法名
result.notImplemented()

View File

@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-all.zip

View File

@@ -19,7 +19,7 @@ pluginManagement {
plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version "8.7.3" apply false
id "com.android.application" version "8.9.1" apply false
id "org.jetbrains.kotlin.android" version "2.1.0" apply false
}

View File

@@ -181,6 +181,17 @@ tmoe还会安装gnome-keyring由于之前我做xfce包时会造成VSCode反
### 额外步骤
- 升级到Debian 13xfce, lxqtv1.1.0
- 更换内存分配器([原因](https://github.com/termux/proot/issues/313)。不过截至目前这个bug可能已经被修了虽然issue没关安装libtcmalloc-minimal4包并设置库/usr/lib/aarch64-linux-gnu/libtcmalloc_minimal.so.4到/etc/ld.so.preload
- 把/etc/apt/source.list的bookworm改为trixie
- sudo apt update, sudo apt full-upgrade, sudo apt autoremove
- 取消内存分配器的更改
- xfce版本重新修补了libtiff.so.5库
- 升级到GXDE 25gxdev1.1.0
- 更换内存分配器
- 使用AI重写的升级脚本(gxde-25-upgrade.sh),以便在不启动图形界面的情况下升级
- 禁用电源管理lxqtv1.1.0`mkdir -p ~/.config/autostart;cp /etc/xdg/autostart/lxqt-powermanagement.desktop ~/.config/autostart/;echo "Hidden=true" >> ~/.config/autostart/lxqt-powermanagement.desktop`
- 禁用MIT-SHM扩展v1.1.0/usr/local/bin/startvnc第372行添加set "${a}" "-extension" "MIT-SHM"
- 将桌面壁纸的配置从monitorBuiltinDisplay改为monitorbuiltinxfcev1.0.99疑似Termux:X11显示器名称改变导致壁纸失效
- 修复用vscode打开文件时只打开了vscode本身v1.0.25):去掉/usr/share/applications/code-no-sandbox.desktop的Exec的--unity-launch
- 修复选择文本时会把文本发送到剪切板v1.0.25):在/usr/local/bin/startvnc文件的start_tmoe_xvnc()的start_win10_tigervnc行前面加入`vncconfig -set SendPrimary=0 SetPrimary=0`

View File

@@ -19,10 +19,12 @@ fi
echo "最新版本: $latest_version"
hangover_url="https://github.com/AndreRH/hangover/releases/download/hangover-${latest_version}/hangover_${latest_version}_debian12_bookworm_arm64.tar"
hangover_url="https://github.com/AndreRH/hangover/releases/download/hangover-${latest_version}/hangover_${latest_version}_debian13_trixie_arm64.tar"
mirror_sites=(
"https://github.akams.cn/"
"https://gh-proxy.org/"
"https://cdn.gh-proxy.org/"
"https://edgeone.gh-proxy.org/"
"https://gh.llkk.cc/"
"https://github.moeyy.xyz/"
"https://mirror.ghproxy.com/"

View File

@@ -4,11 +4,13 @@ echo "正在更新软件包..."
sudo apt update
sudo apt upgrade -y
hangover_url="https://github.com/AndreRH/hangover/releases/download/hangover-10.14/hangover_10.14_debian12_bookworm_arm64.tar"
latest_version="10.14"
hangover_url="https://github.com/AndreRH/hangover/releases/download/hangover-11.0/hangover_11.0_debian13_trixie_arm64.tar"
latest_version="11.0"
mirror_sites=(
"https://github.akams.cn/"
"https://gh-proxy.org/"
"https://cdn.gh-proxy.org/"
"https://edgeone.gh-proxy.org/"
"https://gh.llkk.cc/"
"https://github.moeyy.xyz/"
"https://mirror.ghproxy.com/"

146
extra/gxde-25-upgrade.sh Normal file
View File

@@ -0,0 +1,146 @@
#!/bin/bash
# 定义颜色以便于阅读
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
echo -e "${GREEN}=== GXDE OS 15 -> 25 命令行升级工具 ===${NC}"
# 1. 检查 root 权限
if [ "$(id -u)" -ne 0 ]; then
echo -e "${RED}错误: 请使用 root 权限运行此脚本 (例如: sudo $0)${NC}"
exit 1
fi
# 2. 风险确认 (替代 Zenity)
echo -e "${YELLOW}警告:您即将执行 GXDE OS 15 到 25 的升级${NC}"
echo "• 该操作不可逆且存在风险"
echo "• 请确保系统已经更新到最新"
echo "• 请确保已做好数据备份"
echo "• 升级过程可能需要 1-3 小时,期间请勿关闭终端"
echo ""
read -p "您确定要继续吗?(输入 yes 继续,其他键取消): " confirm
if [ "$confirm" != "yes" ]; then
echo "操作已取消。"
exit 0
fi
echo -e "${YELLOW}再次确认:这是一个高风险操作!!!${NC}"
read -p "请输入 'I AGREE' (大写) 以确认并开始升级: " confirm_final
if [ "$confirm_final" != "I AGREE" ]; then
echo "操作已取消。"
exit 0
fi
echo -e "${GREEN}>>> 开始预处理...${NC}"
# 刷新缓存与修复依赖
echo "正在刷新系统包缓存..."
apt update
aptss update
export DEBIAN_FRONTEND=noninteractive
echo "正在检查和修复系统依赖问题..."
aptss install -f -yqq
# 删除冲突包
echo "正在移除 qtbase5-dev..."
apt autopurge qtbase5-dev -y
# 3. 替换软件源 (核心逻辑)
echo "正在替换软件源..."
# 备份并替换主源
sed -i 's/bookworm/trixie/g' /etc/apt/sources.list
# 处理 PPA 源
declare -A ppa_map=(
["/etc/apt/sources.list.d/gxde.list"]='s/bixie/lizhi/g'
["/etc/apt/sources.list.d/gxde-testing.list"]='s/tianlu/zhuangzhuang/g'
)
rm -vf /etc/apt/sources.list.d/gxde-bpo.list
for file in "${!ppa_map[@]}"; do
if [[ -f "$file" ]]; then
sed -i "${ppa_map[$file]}" "$file"
echo "已更新源文件: $file"
else
[[ "$file" =~ testing ]] && continue
echo -e "${RED}严重错误:关键源文件缺失 $file${NC}"
exit 1
fi
done
# 屏蔽旧的更新器
echo "正在屏蔽旧版更新器..."
rm -fv /usr/bin/gxde-app-upgrader
cat > /usr/bin/gxde-app-upgrader << EOF
#!/bin/bash
echo "警告:检测到您尚未完成系统大版本更新,请完成 CLI 更新流程!"
EOF
chmod +x /usr/bin/gxde-app-upgrader
# 刷新新源
echo "正在刷新新源缓存..."
apt update
aptss update
yes n | aptss install gxde-25-upgrader -yqq
echo -e "${GREEN}>>> 预处理完成,准备开始核心升级...${NC}"
echo -e "${YELLOW}注意:接下来的过程请保持网络畅通,不要中断脚本运行。${NC}"
sleep 3
# 4. 执行核心升级逻辑 (原 gxde-post-upgrade-fix 内容)
# 检查当前桌面环境状态
ANDROID_INSTALLED=0
DESKTOP_MISSING=0
dpkg -s gxde-desktop-android &>/dev/null && ANDROID_INSTALLED=1
dpkg -s gxde-desktop &>/dev/null || DESKTOP_MISSING=1
# 确定要安装的桌面包
DESKTOP_PKG="gxde-desktop"
if [ "$ANDROID_INSTALLED" -eq 1 ] && [ "$DESKTOP_MISSING" -eq 1 ]; then
DESKTOP_PKG="gxde-desktop-android"
echo "检测到 Android 环境,将安装: $DESKTOP_PKG"
else
echo "将在升级后安装: $DESKTOP_PKG"
fi
# 执行 Full Upgrade
echo -e "${GREEN}>>> 正在执行系统全面升级 (Full Upgrade)...这可能需要很长时间${NC}"
yes n | env DEBIAN_FRONTEND=noninteractive aptss full-upgrade \
-o DPkg::options::="--force-confdef" \
-o DPkg::options::="--force-confold" \
-o DPkg::options::="--force-overwrite" \
-yqq --assume-yes
# 处理 grub 配置问题 (Hack)
echo "正在处理 GRUB 配置..."
if [ -f /var/lib/dpkg/info/grub-pc.postinst ]; then
mv -v /var/lib/dpkg/info/grub-pc.postinst /var/lib/dpkg/info/grub-pc.postinst.bak
dpkg --configure -a
mv -v /var/lib/dpkg/info/grub-pc.postinst.bak /var/lib/dpkg/info/grub-pc.postinst
else
dpkg --configure -a
fi
# 安装/更新核心软件包
echo -e "${GREEN}>>> 正在安装/重装核心组件...${NC}"
yes n | env DEBIAN_FRONTEND=noninteractive aptss install gxde-app-upgrader --reinstall -yqq
if yes n | env DEBIAN_FRONTEND=noninteractive aptss install $DESKTOP_PKG deepin-kwin-x11 libdtkcore-dev deepin-desktop-base spark-store gxde-control-center --reinstall -yqq; then
# 启用服务
systemctl enable dde-filemanager-daemon.service || true
echo -e "${GREEN}-----------------------${NC}"
echo -e "${GREEN}升级成功完成!${NC}"
echo -e "${YELLOW}请按回车键重启您的计算机,或者按 Ctrl+C 稍后手动重启。${NC}"
read
reboot
else
echo -e "${RED}!!!!!! 升级过程中出现错误 !!!!!!${NC}"
echo "请保留此终端输出,并反馈给 QQ 群 881201853"
exit 1
fi

View File

@@ -41,6 +41,10 @@ Turnip驱动。根据[这里](https://github.com/xDoge26/proot-setup/issues/26#i
快捷指令的彩蛋。原本放在容器里,但显然放这里更为合适
#### extra/tiny_virtual_mic
麦克风客户端。实现见tiny_virtual_mic.c
#### caj, edraw
这些分别是cajviewer亿图图示的补丁
@@ -48,12 +52,6 @@ Turnip驱动。根据[这里](https://github.com/xDoge26/proot-setup/issues/26#i
- 亿图图示补丁的库文件是在小小电脑上下载了Qt对应版本源码后编译得到的
- 编译进行了两次第一次直接编译可以得到Gui和Widgets两个库。第二次编译带上XcbQpa虽然会编译失败但在这之前就可以得到XcbQpa的库。
#### wechat
微信的补丁。license, uos-lsb和uos-release来自星火的微信包或arch的wechat-uos打包我忘记到底是哪的了。不过都差不多
libssl1.1来自debian官方源。deepin-elf-verifier是我打的空包。
#### font
[小赖字体](https://github.com/lxgw/kose-font)用于修复wine的方块字

74
extra/tiny_virtual_mic.c Normal file
View File

@@ -0,0 +1,74 @@
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <pulse/simple.h>
#include <pulse/error.h>
#define BUFSIZE 4096
int main(int argc, char *argv[]) {
if (argc != 3) {
fprintf(stderr, "Usage: %s <socket_path> <target_device>\n", argv[0]);
return 1;
}
// 1. Setup PulseAudio
static const pa_sample_spec ss = {
.format = PA_SAMPLE_S16LE,
.rate = 44100,
.channels = 1
};
pa_buffer_attr attr;
attr.maxlength = (uint32_t) -1;
attr.tlength = pa_usec_to_bytes(60000, &ss); // 目标延迟设为 60ms
attr.prebuf = (uint32_t) -1;
attr.minreq = (uint32_t) -1;
attr.fragsize = (uint32_t) -1;
int error;
pa_simple *s = pa_simple_new(NULL, "AndroidStream", PA_STREAM_PLAYBACK, argv[2], "live_audio", &ss, NULL, &attr, &error);
if (!s) {
fprintf(stderr, "pa_simple_new() failed: %s\n", pa_strerror(error));
return 1;
}
// 2. Connect to Android Socket
int sock_fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (sock_fd < 0) {
perror("socket");
return 1;
}
struct sockaddr_un addr;
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, argv[1], sizeof(addr.sun_path) - 1);
printf("Connecting to %s...\n", argv[1]);
while (connect(sock_fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
printf("Waiting for server...\n");
sleep(1); // Retry logic since Android might start later
}
printf("Connected! Playing audio...\n");
// 3. Stream Loop
uint8_t buf[BUFSIZE];
while (1) {
ssize_t r = read(sock_fd, buf, sizeof(buf));
if (r <= 0) break;
if (pa_simple_write(s, buf, (size_t)r, &error) < 0) {
fprintf(stderr, "pa_simple_write() failed: %s\n", pa_strerror(error));
break;
}
}
// Cleanup
pa_simple_free(s);
close(sock_fd);
return 0;
}

363
extra/turnip.patch Normal file
View File

@@ -0,0 +1,363 @@
diff --git a/src/freedreno/vulkan/tu_shader.cc b/src/freedreno/vulkan/tu_shader.cc
index edc0ce1f6fe..e5b8e9bc44d 100644
--- a/src/freedreno/vulkan/tu_shader.cc
+++ b/src/freedreno/vulkan/tu_shader.cc
@@ -2556,10 +2556,10 @@ tu_upload_shader(struct tu_device *dev,
size += vpc_size;
}
- pthread_mutex_lock(&dev->pipeline_mutex);
+ mtx_lock(&dev->pipeline_mutex);
VkResult result = tu_suballoc_bo_alloc(&shader->bo, &dev->pipeline_suballoc,
size * 4, 128);
- pthread_mutex_unlock(&dev->pipeline_mutex);
+ mtx_unlock(&dev->pipeline_mutex);
if (result != VK_SUCCESS)
return result;
@@ -2589,9 +2589,9 @@ tu_upload_shader(struct tu_device *dev,
result = tu_setup_pvtmem(dev, shader, &pvtmem_config, pvtmem_size, per_wave);
if (result != VK_SUCCESS) {
- pthread_mutex_lock(&dev->pipeline_mutex);
+ mtx_lock(&dev->pipeline_mutex);
tu_suballoc_bo_free(&dev->pipeline_suballoc, &shader->bo);
- pthread_mutex_unlock(&dev->pipeline_mutex);
+ mtx_unlock(&dev->pipeline_mutex);
return result;
}
@@ -3427,10 +3427,10 @@ tu_empty_shader_create(struct tu_device *dev,
if (!shader)
return VK_ERROR_OUT_OF_HOST_MEMORY;
- pthread_mutex_lock(&dev->pipeline_mutex);
+ mtx_lock(&dev->pipeline_mutex);
VkResult result = tu_suballoc_bo_alloc(&shader->bo, &dev->pipeline_suballoc,
32 * 4, 128);
- pthread_mutex_unlock(&dev->pipeline_mutex);
+ mtx_unlock(&dev->pipeline_mutex);
if (result != VK_SUCCESS) {
vk_free(&dev->vk.alloc, shader);
@@ -3541,9 +3541,9 @@ tu_shader_destroy(struct tu_device *dev,
tu_cs_finish(&shader->cs);
TU_RMV(resource_destroy, dev, &shader->bo);
- pthread_mutex_lock(&dev->pipeline_mutex);
+ mtx_lock(&dev->pipeline_mutex);
tu_suballoc_bo_free(&dev->pipeline_suballoc, &shader->bo);
- pthread_mutex_unlock(&dev->pipeline_mutex);
+ mtx_unlock(&dev->pipeline_mutex);
if (shader->pvtmem_bo)
tu_bo_finish(dev, shader->pvtmem_bo);
diff --git a/src/freedreno/vulkan/tu_wsi.cc b/src/freedreno/vulkan/tu_wsi.cc
index 57cf9048b07..246a95dd894 100644
--- a/src/freedreno/vulkan/tu_wsi.cc
+++ b/src/freedreno/vulkan/tu_wsi.cc
@@ -47,6 +47,10 @@ tu_wsi_init(struct tu_physical_device *physical_device)
&options);
if (result != VK_SUCCESS)
return result;
+
+ if (strcmp(physical_device->instance->knl->name, "kgsl") == 0) {
+ physical_device->wsi_device.is_tu_kgsl = true;
+ }
physical_device->wsi_device.supports_modifiers = true;
physical_device->wsi_device.can_present_on_device =
diff --git a/src/util/anon_file.c b/src/util/anon_file.c
index a9ad2a2aad8..f5dcd5b3b48 100644
--- a/src/util/anon_file.c
+++ b/src/util/anon_file.c
@@ -117,6 +117,11 @@ get_or_create_user_temp_dir(char* buf, size_t len) {
int uid = getuid();
env = os_get_option("XDG_RUNTIME_DIR");
+#ifdef __linux__
+ if (!env) {
+ env = "/tmp";
+ }
+#endif
if (env && env[0] != '\0') {
snprintf(buf, len, "%s", env);
return buf;
diff --git a/src/util/u_process.c b/src/util/u_process.c
index 6846acd2e0b..8551c227b88 100644
--- a/src/util/u_process.c
+++ b/src/util/u_process.c
@@ -101,7 +101,7 @@ __getProgramName()
{
return strdup(program_invocation_short_name);
}
-#elif defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__) || DETECT_OS_ANDROID || defined(__NetBSD__)
+#elif defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__) || DETECT_OS_ANDROID || defined(__NetBSD__) || defined(__linux__)
#if defined(__NetBSD__)
# include <sys/param.h>
#endif
diff --git a/src/vulkan/wsi/wsi_common.c b/src/vulkan/wsi/wsi_common.c
index 6783fbd6efb..3a81c200c2a 100644
--- a/src/vulkan/wsi/wsi_common.c
+++ b/src/vulkan/wsi/wsi_common.c
@@ -2491,7 +2491,7 @@ wsi_common_queue_present(const struct wsi_device *wsi,
#endif
}
- if (wsi->sw) {
+ if (wsi->sw || (wsi->is_tu_kgsl && (swapchain->dma_buf_semaphore == VK_NULL_HANDLE))) {
wsi->WaitForFences(vk_device_to_handle(dev),
1, &swapchain->fences[image_index], true, ~0ull);
}
@@ -3217,7 +3217,7 @@ wsi_configure_cpu_image(const struct wsi_swapchain *chain,
const struct wsi_cpu_image_params *params,
struct wsi_image_info *info)
{
- assert(params->base.image_type == WSI_IMAGE_TYPE_CPU);
+ // assert(params->base.image_type == WSI_IMAGE_TYPE_CPU);
assert(chain->blit.type == WSI_SWAPCHAIN_NO_BLIT ||
chain->blit.type == WSI_SWAPCHAIN_BUFFER_BLIT);
diff --git a/src/vulkan/wsi/wsi_common.h b/src/vulkan/wsi/wsi_common.h
index c17a79c6b13..20c480babbc 100644
--- a/src/vulkan/wsi/wsi_common.h
+++ b/src/vulkan/wsi/wsi_common.h
@@ -152,6 +152,7 @@ struct wsi_device {
bool sw;
+ bool is_tu_kgsl;
/* Set to true if the implementation is ok with linear WSI images. */
bool wants_linear;
diff --git a/src/vulkan/wsi/wsi_common_display.c b/src/vulkan/wsi/wsi_common_display.c
index f72e85c5e66..ac83c92236a 100644
--- a/src/vulkan/wsi/wsi_common_display.c
+++ b/src/vulkan/wsi/wsi_common_display.c
@@ -516,6 +516,12 @@ struct wsi_display_sync {
static uint64_t fence_sequence;
+#ifdef __linux__
+static void thread_signal_handler (int signum) {
+ pthread_exit (0);
+}
+#endif
+
static void
_wsi_display_cleanup_state(struct wsi_display_swapchain *chain);
@@ -2024,7 +2030,9 @@ wsi_display_wait_thread(void *data)
.events = POLLIN
};
+#ifndef __linux__
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
+#endif
for (;;) {
int ret = poll(&pollfd, 1, -1);
if (ret > 0) {
@@ -2052,9 +2060,21 @@ wsi_display_start_wait_thread(struct wsi_display *wsi)
static void
wsi_display_stop_wait_thread(struct wsi_display *wsi)
{
+#ifdef __linux__
+ struct sigaction actions;
+ memset (&actions, 0, sizeof (actions));
+ sigemptyset (&actions.sa_mask);
+ actions.sa_flags = 0;
+ actions.sa_handler = thread_signal_handler;
+ sigaction (SIGUSR2, &actions, NULL);
+#endif
mtx_lock(&wsi->wait_mutex);
if (wsi->wait_thread) {
+#ifndef __linux__
pthread_cancel(wsi->wait_thread);
+#else
+ pthread_kill(wsi->wait_thread, SIGUSR2);
+#endif
pthread_join(wsi->wait_thread, NULL);
wsi->wait_thread = 0;
}
@@ -3456,7 +3476,9 @@ udev_event_listener_thread(void *data)
int udev_fd = udev_monitor_get_fd(mon);
+#ifndef __linux__
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
+#endif
for (;;) {
nfds_t nfds = 1;
@@ -3603,6 +3625,15 @@ wsi_display_finish_wsi(struct wsi_device *wsi_device,
struct wsi_display *wsi =
(struct wsi_display *) wsi_device->wsi[VK_ICD_WSI_PLATFORM_DISPLAY];
+#ifdef __linux__
+ struct sigaction actions;
+ memset (&actions, 0, sizeof (actions));
+ sigemptyset (&actions.sa_mask);
+ actions.sa_flags = 0;
+ actions.sa_handler = thread_signal_handler;
+ sigaction (SIGUSR2, &actions, NULL);
+#endif
+
if (wsi) {
wsi_for_each_connector(connector, wsi)
wsi_display_free_connector(wsi, connector);
@@ -3610,7 +3641,11 @@ wsi_display_finish_wsi(struct wsi_device *wsi_device,
wsi_display_stop_wait_thread(wsi);
if (wsi->hotplug_thread) {
+#ifndef __linux__
pthread_cancel(wsi->hotplug_thread);
+#else
+ pthread_kill(wsi->hotplug_thread, SIGUSR2);
+#endif
pthread_join(wsi->hotplug_thread, NULL);
}
diff --git a/src/vulkan/wsi/wsi_common_drm.c b/src/vulkan/wsi/wsi_common_drm.c
index fe297d3ca01..8c48b29d733 100644
--- a/src/vulkan/wsi/wsi_common_drm.c
+++ b/src/vulkan/wsi/wsi_common_drm.c
@@ -47,6 +47,9 @@
static VkResult
wsi_dma_buf_export_sync_file(int dma_buf_fd, int *sync_file_fd)
{
+ #if defined (__linux__)
+ return VK_ERROR_FEATURE_NOT_PRESENT;
+ #else
struct dma_buf_export_sync_file export = {
.flags = DMA_BUF_SYNC_RW,
.fd = -1,
@@ -64,11 +67,15 @@ wsi_dma_buf_export_sync_file(int dma_buf_fd, int *sync_file_fd)
*sync_file_fd = export.fd;
return VK_SUCCESS;
+ #endif
}
static VkResult
wsi_dma_buf_import_sync_file(int dma_buf_fd, int sync_file_fd)
{
+ #if defined (__linux__)
+ return VK_ERROR_FEATURE_NOT_PRESENT;
+ #else
struct dma_buf_import_sync_file import = {
.flags = DMA_BUF_SYNC_RW,
.fd = sync_file_fd,
@@ -84,6 +91,7 @@ wsi_dma_buf_import_sync_file(int dma_buf_fd, int sync_file_fd)
}
return VK_SUCCESS;
+ #endif
}
/**
diff --git a/src/vulkan/wsi/wsi_common_x11.c b/src/vulkan/wsi/wsi_common_x11.c
index 5e4b3a68d07..d19b8faa196 100644
--- a/src/vulkan/wsi/wsi_common_x11.c
+++ b/src/vulkan/wsi/wsi_common_x11.c
@@ -149,22 +149,7 @@ static bool
wsi_x11_check_dri3_compatible(const struct wsi_device *wsi_dev,
xcb_connection_t *conn)
{
- xcb_screen_iterator_t screen_iter =
- xcb_setup_roots_iterator(xcb_get_setup(conn));
- xcb_screen_t *screen = screen_iter.data;
-
- /* Open the DRI3 device from the X server. If we do not retrieve one we
- * assume our local device is compatible.
- */
- int dri3_fd = wsi_dri3_open(conn, screen->root, None);
- if (dri3_fd == -1)
- return true;
-
- bool match = wsi_dev->can_present_on_device(wsi_dev->pdevice, dri3_fd);
-
- close(dri3_fd);
-
- return match;
+ return true;
}
#endif
@@ -1453,8 +1438,6 @@ x11_present_to_x11_dri3(struct x11_swapchain *chain, uint32_t image_index,
!wsi_device->x11.ignore_suboptimal)
options |= XCB_PRESENT_OPTION_SUBOPTIMAL;
- xshmfence_reset(image->shm_fence);
-
if (!chain->base.image_info.explicit_sync) {
++chain->sent_image_count;
assert(chain->sent_image_count <= chain->base.image_count);
@@ -1832,11 +1815,6 @@ x11_acquire_next_image(struct wsi_swapchain *wsi_chain,
return result;
assert(*image_index < chain->base.image_count);
-#ifdef HAVE_X11_DRM
- if (chain->images[*image_index].shm_fence &&
- !chain->base.image_info.explicit_sync)
- xshmfence_await(chain->images[*image_index].shm_fence);
-#endif
return result;
}
@@ -2201,15 +2179,24 @@ x11_image_init(VkDevice device_h, struct x11_swapchain *chain,
if (fd == -1)
return VK_ERROR_OUT_OF_HOST_MEMORY;
- cookie =
- xcb_dri3_pixmap_from_buffer_checked(chain->conn,
- image->pixmap,
- chain->window,
- image->base.sizes[0],
- pCreateInfo->imageExtent.width,
- pCreateInfo->imageExtent.height,
- image->base.row_pitches[0],
- chain->depth, bpp, fd);
+ cookie = xcb_dri3_pixmap_from_buffers_checked(chain->conn,
+ image->pixmap,
+ chain->window,
+ image->base.num_planes,
+ pCreateInfo->imageExtent.width,
+ pCreateInfo->imageExtent.height,
+ image->base.row_pitches[0],
+ image->base.offsets[0],
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ chain->depth,
+ bpp,
+ 1274,
+ &fd);
}
error = xcb_request_check(chain->conn, cookie);
@@ -2239,6 +2226,9 @@ x11_image_init(VkDevice device_h, struct x11_swapchain *chain,
}
#endif
+ image->sync_fence = 0;
+ return VK_SUCCESS;
+
out_fence:
fence_fd = xshmfence_alloc_shm();
if (fence_fd < 0)
@@ -2281,12 +2271,6 @@ x11_image_finish(struct x11_swapchain *chain,
{
xcb_void_cookie_t cookie;
if (!chain->base.wsi->sw || chain->has_mit_shm) {
-#ifdef HAVE_X11_DRM
- cookie = xcb_sync_destroy_fence(chain->conn, image->sync_fence);
- xcb_discard_reply(chain->conn, cookie.sequence);
- xshmfence_unmap_shm(image->shm_fence);
-#endif
-
cookie = xcb_free_pixmap(chain->conn, image->pixmap);
xcb_discard_reply(chain->conn, cookie.sequence);
#ifdef HAVE_X11_DRM

View File

@@ -31,7 +31,6 @@
"reinstallBootPackage": "Reinstall Boot Package",
"getifaddrsBridge": "getifaddrs Bridge",
"fixGetifaddrsPermission": "Fix getifaddrs permission on Android 13",
"fakeUOSSystem": "Pretend System as UOS",
"displaySettings": "Display Settings",
"avncAdvantages": "AVNC provides better control experience than noVNC:\nTouchpad controls, two-finger tap for keyboard, auto clipboard, picture-in-picture mode, etc.",
"avncSettings": "AVNC Settings",
@@ -70,7 +69,7 @@
"dri3Requirement": "DRI3 requires Termux:X11 and Turnip",
"windowsAppSupport": "Windows App Support",
"hangoverDescription": "Run Windows apps using Hangover (running cross-arch apps on native Wine)!\n\nRunning Windows programs requires two layers of emulation (arch + system) - don't expect good performance!\n\nFor better speed, try enabling Graphics Acceleration. Crashes or failures are normal.\n\nRecommend moving Windows programs to desktop before running.\n\nBe patient. Even if GUI shows nothing. Check terminal - is it still running or stopped with error?\n\nOr check if the Windows app has official Linux arm64 version.",
"installHangoverStable": "Install Hangover Stable",
"installHangoverStable": "Install Hangover",
"installHangoverLatest": "Install Hangover Latest (may fail)",
"uninstallHangover": "Uninstall Hangover",
"clearWineData": "Clear Wine Data",
@@ -79,7 +78,7 @@
"userManual": "User Manual",
"openSourceLicenses": "Open Source Licenses",
"permissionUsage": "Permission Usage",
"privacyStatement": "\nThis app does not collect your private information.\n\nHowever, I cannot control behaviors of apps you install/use inside the container system (including via shortcut commands).\n\nRequested permissions are used for:\nFile permissions: accessing phone directories\nNotifications & accessibility: Required by Termux:X11",
"privacyStatement": "\nThis app does not collect your private information.\n\nHowever, I cannot control behaviors of apps you install/use inside the container system (including via shortcut commands).\n\nRequested permissions are used for:\nFile permissions: accessing phone directories\nNotifications & accessibility: Required by Termux:X11\nMicrophone permission: for using the microphone",
"supportAuthor": "Support Developers",
"recommendApp": "If you find it useful, please recommend to others!",
"projectUrl": "Project URL",
@@ -110,5 +109,7 @@
"updateRequest": "Please try to use the latest version. Visit the project address to check for the latest version.",
"avncScreenResize": "Adaptive Screen Size",
"avncResizeFactor": "Screen Scaling Ratio",
"avncResizeFactorValue": "Current scaling is"
"avncResizeFactorValue": "Current scaling is",
"microphoneSupport": "Microphone Support",
"startStreaming": "Start Microphone"
}

View File

@@ -31,7 +31,6 @@
"reinstallBootPackage": "重新安装引导包",
"getifaddrsBridge": "getifaddrs桥接",
"fixGetifaddrsPermission": "修复安卓13设备getifaddrs无权限",
"fakeUOSSystem": "伪装系统为UOS",
"displaySettings": "显示设置",
"avncAdvantages": "AVNC可以带来相比noVNC更好的操控体验\n如触摸板触控双指单击弹出键盘自动剪切板画中画模式等等。",
"avncSettings": "AVNC设置",
@@ -70,7 +69,7 @@
"dri3Requirement": "DRI3必须配合Termux:X11和Turnip使用",
"windowsAppSupport": "Windows应用支持",
"hangoverDescription": "使用Hangover在原生Wine运行跨架构应用运行Windows应用\n\n运行Windows程序需要经过架构和系统两层模拟不要对运行速度抱有期待\n\n需要速度可以尝试配合图形加速使用。当然程序崩溃甚至打不开也是正常的。\n\n建议将要运行的Windows程序连同程序文件夹移至桌面运行。\n\n你需要耐心。即使图形界面什么也没显示。看看终端还在继续输出吗还是停止在某个报错\n\n或者寻找该Windows软件官方是否提供Linux arm64版本。",
"installHangoverStable": "安装Hangover稳定版",
"installHangoverStable": "安装Hangover",
"installHangoverLatest": "安装Hangover最新版可能出错",
"uninstallHangover": "卸载Hangover",
"clearWineData": "清空Wine数据",
@@ -79,7 +78,7 @@
"userManual": "使用说明",
"openSourceLicenses": "开源许可",
"permissionUsage": "权限使用说明",
"privacyStatement": "\n本软件不会收集你的隐私信息。\n\n当然你在容器系统内部安装或使用的软件行为包括通过快捷指令就不受我控制了我不对其负责。\n\n本软件申请的权限用于以下目的\n文件相关权限用于系统访问手机目录\n通知和无障碍Termux:X11需要。",
"privacyStatement": "\n本软件不会收集你的隐私信息。\n\n当然你在容器系统内部安装或使用的软件行为包括通过快捷指令就不受我控制了我不对其负责。\n\n本软件申请的权限用于以下目的\n文件相关权限用于系统访问手机目录\n通知和无障碍Termux:X11需要。\n麦克风权限用于使用麦克风",
"supportAuthor": "支持作者",
"recommendApp": "如果认为好用的话,可以推荐给其他人用噢!",
"projectUrl": "项目地址",
@@ -110,5 +109,7 @@
"updateRequest": "请尽量使用最新版本。前往项目地址可查看最新版本。",
"avncScreenResize": "自适应屏幕尺寸",
"avncResizeFactor": "屏幕缩放比",
"avncResizeFactorValue": "当前缩放为"
"avncResizeFactorValue": "当前缩放为",
"microphoneSupport": "麦克风支持",
"startStreaming": "开启麦克风"
}

View File

@@ -31,7 +31,6 @@
"reinstallBootPackage": "重新安裝啟動套件",
"getifaddrsBridge": "getifaddrs 橋接",
"fixGetifaddrsPermission": "修復 Android 13 裝置 getifaddrs 無權限",
"fakeUOSSystem": "偽裝系統為 UOS",
"displaySettings": "顯示設定",
"avncAdvantages": "AVNC 可帶來比 noVNC 更好的操作體驗;如觸控板觸控、雙指單擊喚出鍵盤、自動剪貼簿、畫中畫模式等。",
"avncSettings": "AVNC 設定",
@@ -70,7 +69,7 @@
"dri3Requirement": "DRI3 必須配合 Termux:X11 與 Turnip 使用",
"windowsAppSupport": "Windows 應用支援",
"hangoverDescription": "使用 Hangover於原生 Wine 執行跨架構應用)來執行 Windows 應用!\n\n執行 Windows 程式需經過架構與系統雙層模擬,請勿對速度抱太大期望。",
"installHangoverStable": "安裝 Hangover 穩定版",
"installHangoverStable": "安裝 Hangover",
"installHangoverLatest": "安裝 Hangover 最新版(可能有錯誤)",
"uninstallHangover": "解除安裝 Hangover",
"clearWineData": "清除 Wine 資料",
@@ -79,7 +78,7 @@
"userManual": "使用說明",
"openSourceLicenses": "開源授權",
"permissionUsage": "權限使用說明",
"privacyStatement": "\n本軟體不會收集你的隱私資訊。\n\n當然你在容器系統內安裝或使用的軟體行為包括快捷指令不在本軟體控制範圍。",
"privacyStatement": "\n本軟體不會收集你的隱私資訊。\n\n當然你在容器系統內安裝或使用的軟體行為包括快捷指令不在本軟體控制範圍。\n\n本軟體申請的權限用於以下目的\n檔案相關權限用於系統存取手機目錄\n通知和無障礙Termux:X11 需要。\n麥克風權限用於使用麥克風。",
"supportAuthor": "支持作者",
"recommendApp": "如果覺得好用,可以推薦給其他人哦!",
"projectUrl": "專案網址",
@@ -110,5 +109,7 @@
"updateRequest": "請盡量使用最新版本。前往專案網址查看最新版本。",
"avncScreenResize": "自適應螢幕尺寸",
"avncResizeFactor": "螢幕縮放比",
"avncResizeFactorValue": "目前縮放為"
"avncResizeFactorValue": "目前縮放為",
"microphoneSupport": "麥克風支援",
"startStreaming": "開啟麥克風"
}

View File

@@ -170,7 +170,7 @@ class SettingPage extends StatefulWidget {
class _SettingPageState extends State<SettingPage> {
final List<bool> _expandState = [false, false, false, false, false, false];
final List<bool> _expandState = [false, false, false, false, false, false, false];
double _avncScaleFactor = Util.getGlobal("avncScaleFactor") as double;
@@ -328,11 +328,6 @@ class _SettingPageState extends State<SettingPage> {
G.prefs.setBool("getifaddrsBridge", value);
setState(() {});
},),
const SizedBox.square(dimension: 8),
SwitchListTile(title: Text(AppLocalizations.of(context)!.fakeUOSSystem), value: Util.getGlobal("uos") as bool, onChanged:(value) {
G.prefs.setBool("uos", value);
setState(() {});
},),
],))),
ExpansionPanel(
isExpanded: _expandState[2],
@@ -553,7 +548,7 @@ sed -i -E "s@^(VNC_RESOLUTION)=.*@\\1=${w}x${h}@" \$(command -v startvnc)""");
Text(AppLocalizations.of(context)!.hangoverDescription),
const SizedBox.square(dimension: 8),
Wrap(alignment: WrapAlignment.center, spacing: 4.0, runSpacing: 4.0, children: [
OutlinedButton(style: D.commandButtonStyle, child: Text("${AppLocalizations.of(context)!.installHangoverStable}10.14"), onPressed: () async {
OutlinedButton(style: D.commandButtonStyle, child: Text("${AppLocalizations.of(context)!.installHangoverStable}11.0"), onPressed: () async {
Util.termWrite("bash ~/.local/share/tiny/extra/install-hangover-stable");
G.pageIndex.value = 0;
}),
@@ -607,6 +602,37 @@ sed -i -E "s@^(VNC_RESOLUTION)=.*@\\1=${w}x${h}@" \$(command -v startvnc)""");
setState(() {});
},),
],))),
ExpansionPanel(
isExpanded: _expandState[6],
headerBuilder: ((context, isExpanded) {
return ListTile(title: Text(AppLocalizations.of(context)!.microphoneSupport), subtitle: Text(AppLocalizations.of(context)!.experimentalFeature));
}), body: Padding(padding: const EdgeInsets.all(12), child: Column(children: [
const SizedBox.square(dimension: 16),
SwitchListTile(title: Text(AppLocalizations.of(context)!.startStreaming), value: G.isStreaming, onChanged:(value) async {
if (value) {
await Permission.microphone.request();
if (await Permission.microphone.isGranted) {
String path = "/tmp/android_audio";
D.androidChannel.invokeMethod("startStreaming", {"path": "${G.dataPath}/containers/${G.currentContainer}$path"});
Util.termWrite("""
pactl load-module module-null-sink sink_name=AndroidSink sink_properties=device.description="Android_Audio_Stream"
pactl load-module module-remap-source master=AndroidSink.monitor source_name=AndroidMic source_properties=device.description="Android_Virtual_Mic"
pkill -f tiny_virtual_mic
tiny_virtual_mic $path AndroidSink &""");
G.pageIndex.value = 0;
}
} else {
Util.termWrite("""
pactl list short modules | grep "Android" | cut -f1 | xargs -L1 pactl unload-module
pkill -f tiny_virtual_mic""");
G.pageIndex.value = 0;
D.androidChannel.invokeMethod("stopStreaming", {});
}
G.isStreaming = value;
setState(() {});
},),
const SizedBox.square(dimension: 16),
],))),
],);
}
}
@@ -1179,7 +1205,7 @@ class TerminalPage extends StatelessWidget {
}, child: Text(D.termCommands[index]["name"]! as String));
}, separatorBuilder:(context, index) {
return const SizedBox.square(dimension: 4);
}, itemCount: D.termCommands.length))), SizedBox.fromSize(size: const Size(72, 0))])):const SizedBox.square(dimension: 0);
}, itemCount: D.termCommands.length)))])):const SizedBox.square(dimension: 0);
})
]);
}
@@ -1318,6 +1344,22 @@ class _MyHomePageState extends State<MyHomePage> {
return Scaffold(
appBar: AppBar(
title: Text(isLoadingComplete ? Util.getCurrentProp("name") : widget.title),
actions: [
Visibility(
visible: isLoadingComplete,
child: IconButton.filledTonal(
onPressed: () {
if (G.wasX11Enabled) {
Workflow.launchX11();
} else if (G.wasAvncEnabled) {
Workflow.launchAvnc();
} else {
Workflow.launchBrowser();
}
},
icon: const Icon(Icons.play_arrow),
tooltip: AppLocalizations.of(context)!.enterGUI))
],
),
body: isLoadingComplete
? ValueListenableBuilder(
@@ -1387,27 +1429,6 @@ class _MyHomePageState extends State<MyHomePage> {
);
},
),
floatingActionButton: ValueListenableBuilder(
valueListenable: G.pageIndex,
builder: (context, value, child) {
return Visibility(
visible: isLoadingComplete && (value == 0),
child: FloatingActionButton(
tooltip: AppLocalizations.of(context)!.enterGUI,
onPressed: () {
if (G.wasX11Enabled) {
Workflow.launchX11();
} else if (G.wasAvncEnabled) {
Workflow.launchAvnc();
} else {
Workflow.launchBrowser();
}
},
child: const Icon(Icons.play_arrow),
),
);
},
),
);
}
}

View File

@@ -86,7 +86,6 @@ class Util {
//String defaultVirglOpt 默认virgl环境变量
//bool reinstallBootstrap = false 下次启动是否重装引导包
//bool getifaddrsBridge = false 下次启动是否桥接getifaddrs
//bool uos = false 下次启动是否伪装UOS
//bool virgl = false 下次启动是否启用virgl
//bool wakelock = false 屏幕常亮
//bool isHidpiEnabled = false 是否开启高分辨率
@@ -114,7 +113,6 @@ class Util {
case "isStickyKey" : return b ? G.prefs.getBool(key)! : (value){G.prefs.setBool(key, value); return value;}(true);
case "reinstallBootstrap" : return b ? G.prefs.getBool(key)! : (value){G.prefs.setBool(key, value); return value;}(false);
case "getifaddrsBridge" : return b ? G.prefs.getBool(key)! : (value){G.prefs.setBool(key, value); return value;}(false);
case "uos" : return b ? G.prefs.getBool(key)! : (value){G.prefs.setBool(key, value); return value;}(false);
case "virgl" : return b ? G.prefs.getBool(key)! : (value){G.prefs.setBool(key, value); return value;}(false);
case "turnip" : return b ? G.prefs.getBool(key)! : (value){G.prefs.setBool(key, value); return value;}(false);
case "dri3" : return b ? G.prefs.getBool(key)! : (value){G.prefs.setBool(key, value); return value;}(false);
@@ -125,7 +123,6 @@ class Util {
case "avncResizeDesktop" : return b ? G.prefs.getBool(key)! : (value){G.prefs.setBool(key, value); return value;}(true);
case "avncScaleFactor" : return b ? G.prefs.getDouble(key)!.clamp(-1.0, 1.0) : (value){G.prefs.setDouble(key, value); return value;}(-0.5);
case "useX11" : return b ? G.prefs.getBool(key)! : (value){G.prefs.setBool(key, value); return value;}(false);
case "defaultFFmpegCommand" : return b ? G.prefs.getString(key)! : (value){G.prefs.setString(key, value); return value;}("-hide_banner -an -max_delay 1000000 -r 30 -f android_camera -camera_index 0 -i 0:0 -vf scale=iw/2:-1 -rtsp_transport udp -f rtsp rtsp://127.0.0.1:8554/stream");
case "defaultVirglCommand" : return b ? G.prefs.getString(key)! : (value){G.prefs.setString(key, value); return value;}("--use-egl-surfaceless --use-gles --socket-path=\$CONTAINER_DIR/tmp/.virgl_test");
case "defaultVirglOpt" : return b ? G.prefs.getString(key)! : (value){G.prefs.setString(key, value); return value;}("GALLIUM_DRIVER=virpipe");
case "defaultTurnipOpt" : return b ? G.prefs.getString(key)! : (value){G.prefs.setString(key, value); return value;}("MESA_LOADER_DRIVER_OVERRIDE=zink VK_ICD_FILENAMES=/home/tiny/.local/share/tiny/extra/freedreno_icd.aarch64.json TU_DEBUG=noconform");
@@ -149,7 +146,7 @@ class Util {
return m[key];
}
switch (key) {
case "name" : return (value){addCurrentProp(key, value); return value;}("Debian Bookworm");
case "name" : return (value){addCurrentProp(key, value); return value;}("Debian Trixie");
case "boot" : return (value){addCurrentProp(key, value); return value;}(D.boot);
case "vnc" : return (value){addCurrentProp(key, value); return value;}("startnovnc &");
case "vncUrl" : return (value){addCurrentProp(key, value); return value;}("http://localhost:36082/vnc.html?host=localhost&port=36082&autoconnect=true&resize=remote&password=12345678");
@@ -367,15 +364,15 @@ class D {
{"name":"安装科学计算软件Octave", "command":"sudo apt update && sudo apt install -y octave"},
{"name":"卸载Octave", "command":"sudo apt autoremove --purge -y octave"},
{"name":"安装WPS", "command":r"""cat << 'EOF' | sh && sudo dpkg --configure -a && sudo apt update && sudo apt install -y /tmp/wps.deb
wget https://github.akams.cn/https://github.com/tiny-computer/third-party-archives/releases/download/archives/wps-office_11.1.0.11720_arm64.deb -O /tmp/wps.deb
wget https://mirrors.sdu.edu.cn/spark-store/arm64-store/office/wps-office/wps-office_11.1.0.11720-fix3_arm64.deb -O /tmp/wps.deb
EOF
rm /tmp/wps.deb"""},
{"name":"卸载WPS", "command":"sudo apt autoremove --purge -y wps-office"},
{"name":"安装CAJViewer", "command":"wget https://download.cnki.net/net.cnki.cajviewer_1.3.20-1_arm64.deb -O /tmp/caj.deb && sudo apt update && sudo apt install -y /tmp/caj.deb && bash /home/tiny/.local/share/tiny/caj/postinst; rm /tmp/caj.deb"},
{"name":"卸载CAJViewer", "command":"sudo apt autoremove --purge -y net.cnki.cajviewer && bash /home/tiny/.local/share/tiny/caj/postrm"},
{"name":"安装CAJViewer", "command":"wget https://download.cnki.net/cajPackage/tongxinUOS/signed_cajviewer_9.5.0-25268_arm64.deb -O /tmp/caj.deb && sudo apt update && sudo apt install -y /tmp/caj.deb; rm /tmp/caj.deb"},
{"name":"卸载CAJViewer", "command":"sudo apt autoremove --purge -y cajviewer"},
{"name":"安装亿图图示", "command":"wget https://cc-download.wondershare.cc/business/prd/edrawmax_13.1.0-1_arm64_binner.deb -O /tmp/edraw.deb && sudo apt update && sudo apt install -y /tmp/edraw.deb && bash /home/tiny/.local/share/tiny/edraw/postinst; rm /tmp/edraw.deb"},
{"name":"卸载亿图图示", "command":"sudo apt autoremove --purge -y edrawmax libldap-2.4-2"},
{"name":"安装QQ", "command":"""wget \$(curl -s https://im.qq.com/rainbow/linuxQQDownload | grep -oP '"armDownloadUrl":{[^}]*"deb":"\\K[^"]+') -O /tmp/qq.deb && sudo apt update && sudo apt install -y /tmp/qq.deb && sed -i 's#Exec=/opt/QQ/qq %U#Exec=/opt/QQ/qq --no-sandbox %U#g' /usr/share/applications/qq.desktop; rm /tmp/qq.deb"""},
{"name":"安装QQ", "command":"""wget \$(curl -s https://cdn-go.cn/qq-web/im.qq.com_new/latest/rainbow/linuxConfig.js | grep -oP '"armDownloadUrl":{[^}]*"deb":"\\K[^"]+') -O /tmp/qq.deb && sudo apt update && sudo apt install -y /tmp/qq.deb && sed -i 's#Exec=/opt/QQ/qq %U#Exec=/opt/QQ/qq --no-sandbox %U#g' /usr/share/applications/qq.desktop; rm /tmp/qq.deb"""},
{"name":"卸载QQ", "command":"sudo apt autoremove --purge -y linuxqq"},
{"name":"安装微信", "command":"wget https://dldir1v6.qq.com/weixin/Universal/Linux/WeChatLinux_arm64.deb -O /tmp/wechat.deb && sudo apt update && sudo apt install -y /tmp/wechat.deb && echo '安装完成。如果你使用微信只是为了传输文件那么可以考虑使用支持SAF的文件管理器质感文件直接访问小小电脑所有文件。'; rm /tmp/wechat.deb"},
{"name":"卸载微信", "command":"sudo apt autoremove --purge -y wechat"},
@@ -520,11 +517,7 @@ class G {
static late VirtualKeyboard keyboard; //存储ctrl, shift, alt状态
static bool maybeCtrlJ = false; //为了区分按下的ctrl+J和enter而准备的变量
static ValueNotifier<double> termFontScale = ValueNotifier(1); //终端字体大小存储为G.prefs的termFontScale
static bool isStreamServerStarted = false;
static bool isStreaming = false;
//static int? streamingPid;
static String streamingOutput = "";
static late Pty streamServerPty;
//static int? virglPid;
static ValueNotifier<int> pageIndex = ValueNotifier(0); //主界面索引
static ValueNotifier<bool> terminalPageChange = ValueNotifier(true); //更改值,用于刷新小键盘
@@ -535,7 +528,6 @@ class G {
static bool wasAvncEnabled = false;
static bool wasX11Enabled = false;
static late SharedPreferences prefs;
}
@@ -587,7 +579,12 @@ ln -sf ../applib/libexec_tar.so \$DATA_DIR/bin/tar
ln -sf ../applib/libexec_virgl_test_server.so \$DATA_DIR/bin/virgl_test_server
ln -sf ../applib/libexec_getifaddrs_bridge_server.so \$DATA_DIR/bin/getifaddrs_bridge_server
ln -sf ../applib/libexec_pulseaudio.so \$DATA_DIR/bin/pulseaudio
ln -sf ../applib/libacl.so \$DATA_DIR/lib/libacl.so
ln -sf ../applib/libandroid-selinux.so \$DATA_DIR/lib/libandroid-selinux.so
ln -sf ../applib/libattr.so \$DATA_DIR/lib/libattr.so
ln -sf ../applib/libbusybox.so \$DATA_DIR/lib/libbusybox.so.1.37.0
ln -sf ../applib/libiconv.so \$DATA_DIR/lib/libiconv.so
ln -sf ../applib/libpcre2-8.so \$DATA_DIR/lib/libpcre2-8.so
ln -sf ../applib/libtalloc.so \$DATA_DIR/lib/libtalloc.so.2
ln -sf ../applib/libvirglrenderer.so \$DATA_DIR/lib/libvirglrenderer.so
ln -sf ../applib/libepoxy.so \$DATA_DIR/lib/libepoxy.so
@@ -614,7 +611,14 @@ chmod 1777 tmp
Util.createDirFromString("${G.dataPath}/containers/0/.l2s");
//这个是容器rootfs被split命令分成了xa*放在assets里
//首次启动,就用这个,别让用户另选了
for (String name in jsonDecode(await rootBundle.loadString('AssetManifest.json')).keys.where((String e) => e.startsWith("assets/xa")).map((String e) => e.split("/").last).toList()) {
//使用 AssetManifest API 获取 assets/xa* 文件列表
final AssetManifest manifest = await AssetManifest.loadFromAssetBundle(rootBundle);
final List<String> xaFiles = manifest
.listAssets()
.where((String key) => key.startsWith('assets/xa'))
.map((String key) => key.split('/').last)
.toList();
for (String name in xaFiles) {
await Util.copyAsset("assets/$name", "${G.dataPath}/$name");
}
//-J
@@ -654,7 +658,7 @@ ${Localizations.localeOf(G.homePageStateContext).languageCode == 'zh' ? "" : "ec
//$DATA_DIR是数据文件夹, $CONTAINER_DIR是容器根目录
//Termux:X11的启动命令并不在这里面而是写死了。这下成💩山代码了:P
await G.prefs.setStringList("containersInfo", ["""{
"name":"Debian Bookworm",
"name":"Debian Trixie",
"boot":"${Localizations.localeOf(G.homePageStateContext).languageCode == 'zh' ? D.boot : D.boot.replaceFirst('LANG=zh_CN.UTF-8', 'LANG=en_US.UTF-8').replaceFirst('公共', 'Public').replaceFirst('图片', 'Pictures').replaceFirst('音乐', 'Music').replaceFirst('视频', 'Videos').replaceFirst('下载', 'Downloads').replaceFirst('文档', 'Documents').replaceFirst('照片', 'Photos')}",
"vnc":"startnovnc &",
"vncUrl":"http://localhost:36082/vnc.html?host=localhost&port=36082&autoconnect=true&resize=remote&password=12345678",
@@ -752,10 +756,6 @@ exit
if (Util.getGlobal("isHidpiEnabled")) {
extraOpt += "${Util.getGlobal("defaultHidpiOpt")} ";
}
if (Util.getGlobal("uos")) {
extraMount += "--mount=\$DATA_DIR/tiny/wechat/uos-lsb:/etc/lsb-release --mount=\$DATA_DIR/tiny/wechat/uos-release:/usr/lib/os-release ";
extraMount += "--mount=\$DATA_DIR/tiny/wechat/license/var/uos:/var/uos --mount=\$DATA_DIR/tiny/wechat/license/var/lib/uos-license:/var/lib/uos-license ";
}
if (Util.getGlobal("virgl")) {
Util.execute("""
export DATA_DIR=${G.dataPath}
@@ -776,6 +776,7 @@ ${G.dataPath}/bin/virgl_test_server ${Util.getGlobal("defaultVirglCommand")}""")
}
extraMount += "--mount=\$DATA_DIR/tiny/font:/usr/share/fonts/tiny ";
extraMount += "--mount=\$DATA_DIR/tiny/extra/cmatrix:/home/tiny/.local/bin/cmatrix ";
extraMount += "--mount=\$DATA_DIR/tiny/extra/tiny_virtual_mic:/home/tiny/.local/bin/tiny_virtual_mic ";
Util.termWrite(
"""
export DATA_DIR=${G.dataPath}
@@ -841,7 +842,7 @@ clear""");
}
static Future<void> launchXServer() async {
await X11Flutter.launchXServer("${G.dataPath}/containers/${G.currentContainer}/tmp", "${G.dataPath}/containers/${G.currentContainer}/usr/share/X11/xkb", [":4"]);
await X11Flutter.launchXServer("${G.dataPath}/containers/${G.currentContainer}/tmp", "${G.dataPath}/containers/${G.currentContainer}/usr/share/X11/xkb", [":4", "-extension", "MIT-SHM"]);
}
static Future<void> launchX11() async {

View File

@@ -21,8 +21,8 @@ packages:
dependency: "direct main"
description:
path: "."
ref: "4008565259f88fe4613b885979f79e439bc5a420"
resolved-ref: "4008565259f88fe4613b885979f79e439bc5a420"
ref: "44f24477b85b009cf84d6c7be25a929128eed728"
resolved-ref: "44f24477b85b009cf84d6c7be25a929128eed728"
url: "https://github.com/tiny-computer/avnc_flutter.git"
source: git
version: "0.0.1"
@@ -46,10 +46,10 @@ packages:
dependency: "direct main"
description:
name: clipboard
sha256: "1920c0337f8808be4166c5f1b236301ff381ef69633b0757c502d97f1f740102"
sha256: c0ba5e7214035b824549473fa134870bc544fff0d7b89170d4756c0ac2c0239d
url: "https://pub.dev"
source: hosted
version: "2.0.2"
version: "3.0.14"
clock:
dependency: transitive
description:
@@ -58,6 +58,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.1.2"
code_assets:
dependency: transitive
description:
name: code_assets
sha256: "83ccdaa064c980b5596c35dd64a8d3ecc68620174ab9b90b6343b753aa721687"
url: "https://pub.dev"
source: hosted
version: "1.0.0"
collection:
dependency: transitive
description:
@@ -74,6 +82,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.1.2"
crypto:
dependency: transitive
description:
name: crypto
sha256: c8ea0233063ba03258fbcf2ca4d6dadfefe14f02fab57702265467a19f27fadf
url: "https://pub.dev"
source: hosted
version: "3.0.7"
dbus:
dependency: transitive
description:
@@ -86,10 +102,10 @@ packages:
dependency: "direct main"
description:
name: device_info_plus
sha256: "98f28b42168cc509abc92f88518882fd58061ea372d7999aecc424345c7bff6a"
sha256: "4df8babf73058181227e18b08e6ea3520cf5fc5d796888d33b7cb0f33f984b7c"
url: "https://pub.dev"
source: hosted
version: "11.5.0"
version: "12.3.0"
device_info_plus_platform_interface:
dependency: transitive
description:
@@ -110,10 +126,10 @@ packages:
dependency: transitive
description:
name: equatable
sha256: "567c64b3cb4cf82397aac55f4f0cbd3ca20d77c6c03bedbc4ceaddc08904aef7"
sha256: "3e0141505477fd8ad55d6eb4e7776d3fe8430be8e497ccb1521370c3f21a3e2b"
url: "https://pub.dev"
source: hosted
version: "2.0.7"
version: "2.0.8"
fake_async:
dependency: transitive
description:
@@ -126,10 +142,10 @@ packages:
dependency: transitive
description:
name: ffi
sha256: "289279317b4b16eb2bb7e271abccd4bf84ec9bdcbe999e278a94b804f5630418"
sha256: d07d37192dbf97461359c1518788f203b0c9102cfd2c35a716b823741219542c
url: "https://pub.dev"
source: hosted
version: "2.1.4"
version: "2.1.5"
file:
dependency: transitive
description:
@@ -174,14 +190,30 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
glob:
dependency: transitive
description:
name: glob
sha256: c3f1ee72c96f8f78935e18aa8cecced9ab132419e8625dc187e1c2408efc20de
url: "https://pub.dev"
source: hosted
version: "2.1.3"
hooks:
dependency: transitive
description:
name: hooks
sha256: "7a08a0d684cb3b8fb604b78455d5d352f502b68079f7b80b831c62220ab0a4f6"
url: "https://pub.dev"
source: hosted
version: "1.0.1"
http:
dependency: "direct main"
description:
name: http
sha256: bb2ce4590bc2667c96f318d68cac1b5a7987ec819351d32b1c987239a815e007
sha256: "87721a4a50b19c7f1d49001e51409bddc46303966ce89a65af4f4e6004896412"
url: "https://pub.dev"
source: hosted
version: "1.5.0"
version: "1.6.0"
http_parser:
dependency: transitive
description:
@@ -202,10 +234,10 @@ packages:
dependency: transitive
description:
name: leak_tracker
sha256: "8dcda04c3fc16c14f48a7bb586d4be1f0d1572731b6d81d51772ef47c02081e0"
sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de"
url: "https://pub.dev"
source: hosted
version: "11.0.1"
version: "11.0.2"
leak_tracker_flutter_testing:
dependency: transitive
description:
@@ -226,10 +258,18 @@ packages:
dependency: transitive
description:
name: lints
sha256: a5e2b223cb7c9c8efdc663ef484fdd95bb243bff242ef5b13e26883547fce9a0
sha256: "12f842a479589fea194fe5c5a3095abc7be0c1f2ddfa9a0e76aed1dbd26a87df"
url: "https://pub.dev"
source: hosted
version: "6.0.0"
version: "6.1.0"
logging:
dependency: transitive
description:
name: logging
sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61
url: "https://pub.dev"
source: hosted
version: "1.3.0"
matcher:
dependency: transitive
description:
@@ -250,18 +290,26 @@ packages:
dependency: transitive
description:
name: meta
sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c
sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394"
url: "https://pub.dev"
source: hosted
version: "1.16.0"
version: "1.17.0"
native_toolchain_c:
dependency: transitive
description:
name: native_toolchain_c
sha256: "89e83885ba09da5fdf2cdacc8002a712ca238c28b7f717910b34bcd27b0d03ac"
url: "https://pub.dev"
source: hosted
version: "0.17.4"
network_info_plus:
dependency: "direct main"
description:
name: network_info_plus
sha256: f926b2ba86aa0086a0dfbb9e5072089bc213d854135c1712f1d29fc89ba3c877
sha256: "2866dadcbee2709e20d67737a1556f5675b8b0cdcf2c1659ba74bc21bffede4f"
url: "https://pub.dev"
source: hosted
version: "6.1.4"
version: "7.0.0"
network_info_plus_platform_interface:
dependency: transitive
description:
@@ -278,14 +326,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.5.0"
objective_c:
dependency: transitive
description:
name: objective_c
sha256: "983c7fa1501f6dcc0cb7af4e42072e9993cb28d73604d25ebf4dab08165d997e"
url: "https://pub.dev"
source: hosted
version: "9.2.5"
package_info_plus:
dependency: transitive
description:
name: package_info_plus
sha256: "16eee997588c60225bda0488b6dcfac69280a6b7a3cf02c741895dd370a02968"
sha256: f69da0d3189a4b4ceaeb1a3defb0f329b3b352517f52bed4290f83d4f06bc08d
url: "https://pub.dev"
source: hosted
version: "8.3.1"
version: "9.0.0"
package_info_plus_platform_interface:
dependency: transitive
description:
@@ -314,18 +370,18 @@ packages:
dependency: transitive
description:
name: path_provider_android
sha256: "993381400e94d18469750e5b9dcb8206f15bc09f9da86b9e44a9b0092a0066db"
sha256: f2c65e21139ce2c3dad46922be8272bb5963516045659e71bb16e151c93b580e
url: "https://pub.dev"
source: hosted
version: "2.2.18"
version: "2.2.22"
path_provider_foundation:
dependency: transitive
description:
name: path_provider_foundation
sha256: "16eef174aacb07e09c351502740fa6254c165757638eba1e9116b0a781201bbd"
sha256: "2a376b7d6392d80cd3705782d2caa734ca4727776db0b6ec36ef3f1855197699"
url: "https://pub.dev"
source: hosted
version: "2.4.2"
version: "2.6.0"
path_provider_linux:
dependency: transitive
description:
@@ -422,6 +478,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.8"
pub_semver:
dependency: transitive
description:
name: pub_semver
sha256: "5bfcf68ca79ef689f8990d1160781b4bad40a3bd5e5218ad4076ddb7f4081585"
url: "https://pub.dev"
source: hosted
version: "2.2.0"
quiver:
dependency: transitive
description:
@@ -442,26 +506,26 @@ packages:
dependency: "direct main"
description:
name: shared_preferences
sha256: "6e8bf70b7fef813df4e9a36f658ac46d107db4b4cfe1048b477d4e453a8159f5"
sha256: "2939ae520c9024cb197fc20dee269cd8cdbf564c8b5746374ec6cacdc5169e64"
url: "https://pub.dev"
source: hosted
version: "2.5.3"
version: "2.5.4"
shared_preferences_android:
dependency: transitive
description:
name: shared_preferences_android
sha256: a2608114b1ffdcbc9c120eb71a0e207c71da56202852d4aab8a5e30a82269e74
sha256: cbc40be9be1c5af4dab4d6e0de4d5d3729e6f3d65b89d21e1815d57705644a6f
url: "https://pub.dev"
source: hosted
version: "2.4.12"
version: "2.4.20"
shared_preferences_foundation:
dependency: transitive
description:
name: shared_preferences_foundation
sha256: "6a52cfcdaeac77cad8c97b539ff688ccfc458c007b4db12be584fbe5c0e49e03"
sha256: "4e7eaffc2b17ba398759f1151415869a34771ba11ebbccd1b0145472a619a64f"
url: "https://pub.dev"
source: hosted
version: "2.5.4"
version: "2.5.6"
shared_preferences_linux:
dependency: transitive
description:
@@ -543,10 +607,10 @@ packages:
dependency: transitive
description:
name: test_api
sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00"
sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55
url: "https://pub.dev"
source: hosted
version: "0.7.6"
version: "0.7.7"
typed_data:
dependency: transitive
description:
@@ -567,34 +631,34 @@ packages:
dependency: transitive
description:
name: url_launcher_android
sha256: "69ee86740f2847b9a4ba6cffa74ed12ce500bbe2b07f3dc1e643439da60637b7"
sha256: "767344bf3063897b5cf0db830e94f904528e6dd50a6dfaf839f0abf509009611"
url: "https://pub.dev"
source: hosted
version: "6.3.18"
version: "6.3.28"
url_launcher_ios:
dependency: transitive
description:
name: url_launcher_ios
sha256: d80b3f567a617cb923546034cc94bfe44eb15f989fe670b37f26abdb9d939cb7
sha256: cfde38aa257dae62ffe79c87fab20165dfdf6988c1d31b58ebf59b9106062aad
url: "https://pub.dev"
source: hosted
version: "6.3.4"
version: "6.3.6"
url_launcher_linux:
dependency: transitive
description:
name: url_launcher_linux
sha256: "4e9ba368772369e3e08f231d2301b4ef72b9ff87c31192ef471b380ef29a4935"
sha256: d5e14138b3bc193a0f63c10a53c94b91d399df0512b1f29b94a043db7482384a
url: "https://pub.dev"
source: hosted
version: "3.2.1"
version: "3.2.2"
url_launcher_macos:
dependency: transitive
description:
name: url_launcher_macos
sha256: c043a77d6600ac9c38300567f33ef12b0ef4f4783a2c1f00231d2b1941fea13f
sha256: "368adf46f71ad3c21b8f06614adb38346f193f3a59ba8fe9a2fd74133070ba18"
url: "https://pub.dev"
source: hosted
version: "3.2.3"
version: "3.2.5"
url_launcher_platform_interface:
dependency: transitive
description:
@@ -607,18 +671,18 @@ packages:
dependency: transitive
description:
name: url_launcher_web
sha256: "4bd2b7b4dc4d4d0b94e5babfffbca8eac1a126c7f3d6ecbc1a11013faa3abba2"
sha256: d0412fcf4c6b31ecfdb7762359b7206ffba3bbffd396c6d9f9c4616ece476c1f
url: "https://pub.dev"
source: hosted
version: "2.4.1"
version: "2.4.2"
url_launcher_windows:
dependency: transitive
description:
name: url_launcher_windows
sha256: "3284b6d2ac454cf34f114e1d3319866fdd1e19cdc329999057e44ffe936cfa77"
sha256: "712c70ab1b99744ff066053cbe3e80c73332b38d46e5e945c98689b2e66fc15f"
url: "https://pub.dev"
source: hosted
version: "3.1.4"
version: "3.1.5"
vector_math:
dependency: transitive
description:
@@ -631,26 +695,26 @@ packages:
dependency: transitive
description:
name: vm_service
sha256: ddfa8d30d89985b96407efce8acbdd124701f96741f2d981ca860662f1c0dc02
sha256: "45caa6c5917fa127b5dbcfbd1fa60b14e583afdc08bfc96dda38886ca252eb60"
url: "https://pub.dev"
source: hosted
version: "15.0.0"
version: "15.0.2"
wakelock_plus:
dependency: "direct main"
description:
name: wakelock_plus
sha256: a474e314c3e8fb5adef1f9ae2d247e57467ad557fa7483a2b895bc1b421c5678
sha256: "9296d40c9adbedaba95d1e704f4e0b434be446e2792948d0e4aa977048104228"
url: "https://pub.dev"
source: hosted
version: "1.3.2"
version: "1.4.0"
wakelock_plus_platform_interface:
dependency: transitive
description:
name: wakelock_plus_platform_interface
sha256: e10444072e50dbc4999d7316fd303f7ea53d31c824aa5eb05d7ccbdd98985207
sha256: "036deb14cd62f558ca3b73006d52ce049fabcdcb2eddfe0bf0fe4e8a943b5cf2"
url: "https://pub.dev"
source: hosted
version: "1.2.3"
version: "1.3.0"
web:
dependency: transitive
description:
@@ -663,18 +727,18 @@ packages:
dependency: "direct main"
description:
name: webview_flutter
sha256: c3e4fe614b1c814950ad07186007eff2f2e5dd2935eba7b9a9a1af8e5885f1ba
sha256: a3da219916aba44947d3a5478b1927876a09781174b5a2b67fa5be0555154bf9
url: "https://pub.dev"
source: hosted
version: "4.13.0"
version: "4.13.1"
webview_flutter_android:
dependency: transitive
description:
name: webview_flutter_android
sha256: "9a25f6b4313978ba1c2cda03a242eea17848174912cfb4d2d8ee84a556f248e3"
sha256: eeeb3fcd5f0ff9f8446c9f4bbc18a99b809e40297528a3395597d03aafb9f510
url: "https://pub.dev"
source: hosted
version: "4.10.1"
version: "4.10.11"
webview_flutter_platform_interface:
dependency: transitive
description:
@@ -687,18 +751,18 @@ packages:
dependency: transitive
description:
name: webview_flutter_wkwebview
sha256: fb46db8216131a3e55bcf44040ca808423539bc6732e7ed34fb6d8044e3d512f
sha256: e49f378ed066efb13fc36186bbe0bd2425630d4ea0dbc71a18fdd0e4d8ed8ebc
url: "https://pub.dev"
source: hosted
version: "3.23.0"
version: "3.23.5"
win32:
dependency: transitive
description:
name: win32
sha256: "66814138c3562338d05613a6e368ed8cfb237ad6d64a9e9334be3f309acfca03"
sha256: d7cb55e04cd34096cd3a79b3330245f54cb96a370a1c27adb3c84b917de8b08e
url: "https://pub.dev"
source: hosted
version: "5.14.0"
version: "5.15.0"
win32_registry:
dependency: transitive
description:
@@ -740,6 +804,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "4.0.0"
yaml:
dependency: transitive
description:
name: yaml
sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce
url: "https://pub.dev"
source: hosted
version: "3.1.3"
zmodem:
dependency: transitive
description:
@@ -749,5 +821,5 @@ packages:
source: hosted
version: "0.0.6"
sdks:
dart: ">=3.8.1 <4.0.0"
flutter: ">=3.29.0"
dart: ">=3.10.3 <4.0.0"
flutter: ">=3.38.4"

View File

@@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix.
version: 1.0.100+20250912
version: 1.1.0+20260205
environment:
sdk: '>=3.1.0 <4.0.0'
@@ -33,17 +33,17 @@ dependencies:
xterm: ^4.0.0
flutter_pty: ^0.4.2
path_provider: ^2.1.5
webview_flutter: ^4.13.0
webview_flutter: ^4.13.1
permission_handler: ^12.0.1
http: ^1.5.0
http: ^1.6.0
retry: ^3.1.2
url_launcher: ^6.3.2
shared_preferences: ^2.5.3
clipboard: ^2.0.2
wakelock_plus: ^1.3.2
shared_preferences: ^2.5.4
clipboard: ^3.0.14
wakelock_plus: ^1.4.0
dynamic_color: ^1.8.1
network_info_plus: ^6.1.4
device_info_plus: ^11.5.0
network_info_plus: ^7.0.0
device_info_plus: ^12.3.0
flutter_localizations:
sdk: flutter
intl: any
@@ -54,7 +54,7 @@ dependencies:
avnc_flutter:
git:
url: https://github.com/tiny-computer/avnc_flutter.git
ref: 4008565259f88fe4613b885979f79e439bc5a420
ref: 44f24477b85b009cf84d6c7be25a929128eed728
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.