From 936d4bce785ddc8749d8d030b4b69f48e918bce1 Mon Sep 17 00:00:00 2001 From: "Rodrigo Rodriguez (Pragmatismo)" Date: Fri, 12 Dec 2025 13:32:55 -0300 Subject: [PATCH] Initial commit: BotOS - Android ROM customization project --- .gitignore | 62 +++ Cargo.toml | 39 ++ README.md | 245 +++++++++++ build.rs | 3 + capabilities/default.json | 21 + gen/android/app/src/main/AndroidManifest.xml | 66 +++ .../app/src/main/res/values/themes.xml | 33 ++ icons/gb-bot.svg | 16 + icons/hdpi/ic_launcher.png | Bin 0 -> 1373 bytes icons/icon.png | Bin 0 -> 11582 bytes icons/mdpi/ic_launcher.png | Bin 0 -> 962 bytes icons/xhdpi/ic_launcher.png | Bin 0 -> 1664 bytes icons/xxhdpi/ic_launcher.png | Bin 0 -> 2899 bytes icons/xxxhdpi/ic_launcher.png | Bin 0 -> 3798 bytes rom/README.md | 56 +++ rom/gsi/README.md | 156 +++++++ .../pragmatismo/botos/AndroidProducts.mk | 10 + .../device/pragmatismo/botos/BoardConfig.mk | 40 ++ rom/gsi/device/pragmatismo/botos/device.mk | 77 ++++ rom/install.sh | 313 ++++++++++++++ rom/scripts/build-magisk-module.sh | 286 ++++++++++++ rom/scripts/debloat.sh | 406 ++++++++++++++++++ scripts/create-bootanimation.sh | 116 +++++ scripts/generate-icons.sh | 50 +++ src/lib.rs | 77 ++++ tauri.conf.json | 45 ++ 26 files changed, 2117 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.toml create mode 100644 README.md create mode 100644 build.rs create mode 100644 capabilities/default.json create mode 100644 gen/android/app/src/main/AndroidManifest.xml create mode 100644 gen/android/app/src/main/res/values/themes.xml create mode 100644 icons/gb-bot.svg create mode 100644 icons/hdpi/ic_launcher.png create mode 100644 icons/icon.png create mode 100644 icons/mdpi/ic_launcher.png create mode 100644 icons/xhdpi/ic_launcher.png create mode 100644 icons/xxhdpi/ic_launcher.png create mode 100644 icons/xxxhdpi/ic_launcher.png create mode 100644 rom/README.md create mode 100644 rom/gsi/README.md create mode 100644 rom/gsi/device/pragmatismo/botos/AndroidProducts.mk create mode 100644 rom/gsi/device/pragmatismo/botos/BoardConfig.mk create mode 100644 rom/gsi/device/pragmatismo/botos/device.mk create mode 100755 rom/install.sh create mode 100755 rom/scripts/build-magisk-module.sh create mode 100755 rom/scripts/debloat.sh create mode 100755 scripts/create-bootanimation.sh create mode 100755 scripts/generate-icons.sh create mode 100644 src/lib.rs create mode 100644 tauri.conf.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c75458b --- /dev/null +++ b/.gitignore @@ -0,0 +1,62 @@ +# Rust/Cargo build artifacts +target/ +Cargo.lock + +# Generated files (keep structure but ignore binaries) +*.so +*.a +*.o +*.dylib +*.dll +*.exe +*.bin +*.elf + +# Android build artifacts +*.apk +*.aab +*.dex +*.class +*.jar +gen/android/app/build/ +gen/android/.gradle/ +gen/android/build/ +gen/android/local.properties +*.keystore +*.jks + +# Tauri build artifacts +src-tauri/target/ + +# IDE +.idea/ +.vscode/ +*.swp +*.swo +*~ + +# OS files +.DS_Store +Thumbs.db + +# Debug files +*.pdb +*.dSYM/ + +# ROM build artifacts +rom/out/ +rom/*.img +rom/*.zip +*.img +*.zip + +# Magisk module builds +rom/scripts/*.zip + +# Logs +*.log + +# Temporary files +*.tmp +*.temp +.cache/ diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..55e1349 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,39 @@ +[package] +name = "botos" +version = "1.0.0" +edition = "2021" +description = "BotOS - Android launcher powered by General Bots" +license = "AGPL-3.0" + +[lib] +name = "botos_lib" +crate-type = ["staticlib", "cdylib", "rlib"] + +[dependencies] +# Core from botlib +botlib = { path = "../botlib", features = ["http-client"] } + +# Tauri with mobile features +tauri = { version = "2", features = ["unstable"] } +tauri-plugin-dialog = "2" +tauri-plugin-opener = "2" +tauri-plugin-notification = "2" +tauri-plugin-http = "2" +tauri-plugin-geolocation = "2" + +# Common +anyhow = "1.0" +chrono = { version = "0.4", features = ["serde"] } +log = "0.4" +android_logger = "0.14" +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +tokio = { version = "1.41", features = ["rt-multi-thread", "macros"] } +reqwest = { version = "0.12", features = ["json"] } + +[build-dependencies] +tauri-build = { version = "2", features = ["codegen"] } + +[features] +default = ["custom-protocol"] +custom-protocol = ["tauri/custom-protocol"] diff --git a/README.md b/README.md new file mode 100644 index 0000000..4c687df --- /dev/null +++ b/README.md @@ -0,0 +1,245 @@ +# BotOS - Android OS powered by General Bots + +**BotOS** transforma qualquer Android em um sistema dedicado ao General Bots, removendo todo bloatware de fabricantes (Samsung, Huawei, Xiaomi, etc) e substituindo pela interface GB. + +## Níveis de Instalação + +| Nível | Requisitos | O que faz | +|-------|-----------|-----------| +| **1** | Apenas ADB | Remove bloatware, instala BotOS como app | +| **2** | Root + Magisk | Boot animation GB, BotOS como system app | +| **3** | Bootloader desbloqueado | Substitui Android inteiro por BotOS | + +## Quick Start + +```bash +cd botos/rom +./install.sh +``` + +O instalador detecta automaticamente o dispositivo e mostra as opções disponíveis. + +## Arquitetura + +``` +┌─────────────────────────────────────────────────────────────────────────────┐ +│ NÍVEL 3: GSI │ +│ ┌─────────────────────────────────────────────────────────────────────────┐│ +│ │ Android AOSP customizado - Zero apps de fabricante ││ +│ │ Boot animation GB desde inicialização ││ +│ │ BotOS integrado como launcher único ││ +│ └─────────────────────────────────────────────────────────────────────────┘│ +├─────────────────────────────────────────────────────────────────────────────┤ +│ NÍVEL 2: MAGISK MODULE │ +│ ┌─────────────────────────────────────────────────────────────────────────┐│ +│ │ Android original + Magisk ││ +│ │ Bloatware removido via overlay ││ +│ │ Boot animation GB ││ +│ │ BotOS como system app privilegiado ││ +│ └─────────────────────────────────────────────────────────────────────────┘│ +├─────────────────────────────────────────────────────────────────────────────┤ +│ NÍVEL 1: DEBLOAT + APP │ +│ ┌─────────────────────────────────────────────────────────────────────────┐│ +│ │ Android original (Samsung/Huawei/Xiaomi/etc) ││ +│ │ Bloatware removido via ADB (sem root) ││ +│ │ BotOS instalado como app normal ││ +│ │ Pode ser definido como launcher padrão ││ +│ └─────────────────────────────────────────────────────────────────────────┘│ +└─────────────────────────────────────────────────────────────────────────────┘ + +┌─────────────────────────────────────────────────────────────────────────────┐ +│ BotOS App (Tauri) │ +├─────────────────────────────────────────────────────────────────────────────┤ +│ botui/ui/suite │ Tauri Android │ src/lib.rs (Rust) │ +│ (Interface Web) │ (WebView + NDK) │ (Backend + Hardware) │ +└─────────────────────────────────────────────────────────────────────────────┘ +``` + +## Estrutura do Projeto + +``` +botos/ +├── Cargo.toml # Dependências Rust/Tauri +├── tauri.conf.json # Config Tauri → botui/ui/suite +├── build.rs # Build script +├── src/lib.rs # Entry point Android +│ +├── icons/ +│ ├── gb-bot.svg # Ícone fonte +│ ├── icon.png (512x512) # Ícone principal +│ └── */ic_launcher.png # Ícones por densidade +│ +├── scripts/ +│ ├── generate-icons.sh # Gera PNGs do SVG +│ └── create-bootanimation.sh # Gera animação de boot +│ +├── capabilities/ +│ └── default.json # Permissões Tauri +│ +├── gen/android/ # Projeto Android gerado +│ └── app/src/main/ +│ ├── AndroidManifest.xml # HOME intent (launcher) +│ └── res/values/themes.xml # Tema dark GB +│ +└── rom/ # Tools de instalação + ├── install.sh # Instalador interativo + ├── scripts/ + │ ├── debloat.sh # Remove bloatware (sem root) + │ └── build-magisk-module.sh # Gera módulo Magisk + └── gsi/ + ├── README.md # Instruções GSI/AOSP + └── device/pragmatismo/botos/ # Device tree AOSP +``` + +## Pré-requisitos + +### Para compilar BotOS App + +```bash +# Rust e Android targets +rustup target add aarch64-linux-android armv7-linux-androideabi + +# Android SDK e NDK +export ANDROID_HOME=$HOME/Android/Sdk +export NDK_HOME=$ANDROID_HOME/ndk/25.2.9519653 + +# Tauri CLI +cargo install tauri-cli +``` + +### Para instalar em dispositivos + +```bash +# ADB +sudo apt install adb + +# Para gerar ícones/boot animation +sudo apt install librsvg2-bin imagemagick +``` + +## Compilação + +```bash +cd botos + +# Gerar ícones +./scripts/generate-icons.sh + +# Inicializar projeto Android +cargo tauri android init + +# Build APK +cargo tauri android build --release +``` + +## Instalação + +### Método Rápido (Interativo) + +```bash +cd botos/rom +chmod +x install.sh +./install.sh +``` + +### Método Manual + +#### Nível 1: Debloat + App (Sem Root) + +```bash +# Conectar dispositivo via USB (debug ativo) +cd botos/rom/scripts +./debloat.sh + +# Instalar APK +adb install ../gen/android/app/build/outputs/apk/release/app-release.apk + +# Definir como launcher: Home → BotOS → Sempre +``` + +#### Nível 2: Magisk Module (Com Root) + +```bash +# Gerar módulo +cd botos/rom/scripts +./build-magisk-module.sh + +# Copiar para dispositivo +adb push botos-magisk-v1.0.zip /sdcard/ + +# No celular: Magisk → Modules → + → Selecionar ZIP → Reboot +``` + +#### Nível 3: GSI (Bootloader Desbloqueado) + +Veja instruções detalhadas em `rom/gsi/README.md`. + +## Bloatware Removido + +O debloat remove automaticamente: + +**Samsung One UI:** +- Bixby, Samsung Pay, Samsung Pass +- Apps duplicados (Email, Calendar, Browser) +- AR Zone, Game Launcher + +**Huawei EMUI:** +- AppGallery, HiCloud, HiCar +- Huawei Browser, Music, Video + +**Xiaomi MIUI:** +- MSA (analytics), Mi Apps +- GetApps, Mi Cloud + +**Universal (todos):** +- Facebook, Instagram pré-instalados +- Netflix, Spotify pré-instalados +- Jogos como Candy Crush + +## Boot Animation + +Para customizar a animação de boot (requer root): + +```bash +# Gerar animação +./scripts/create-bootanimation.sh + +# Instalar (root) +adb root +adb remount +adb push bootanimation.zip /system/media/ +adb reboot +``` + +## Desenvolvimento + +```bash +# Dev mode (conecta ao dispositivo) +cargo tauri android dev + +# Logs +adb logcat -s BotOS:* +``` + +## Parceria Chuna + +BotOS foi criado para vendas/parcerias na Chuna, oferecendo: +- Celulares com sistema "limpo" - sem bloatware +- Interface única conectada ao General Bots +- Experiência simplificada para usuários finais +- Controle total do dispositivo + +## Recursos + +- 🏠 **Launcher Mode**: Substitui home screen +- 🤖 **Interface Chat**: botui/ui/suite +- 🦀 **Backend Rust**: Via Tauri +- 📍 **GPS**: Acesso a localização +- 📷 **Câmera**: Via plugins Tauri +- 🔔 **Notificações**: Push notifications +- 🌐 **Internet**: Comunicação com botserver +- 🎨 **Boot Animation**: Customizável com gb-bot.svg + +## Licença + +AGPL-3.0 diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..d860e1e --- /dev/null +++ b/build.rs @@ -0,0 +1,3 @@ +fn main() { + tauri_build::build() +} diff --git a/capabilities/default.json b/capabilities/default.json new file mode 100644 index 0000000..a77a62e --- /dev/null +++ b/capabilities/default.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://schema.tauri.app/config/2", + "identifier": "default", + "description": "BotOS default capabilities", + "windows": ["main"], + "permissions": [ + "core:default", + "dialog:default", + "opener:default", + "notification:default", + "http:default", + "geolocation:default", + { + "identifier": "http:default", + "allow": [ + { "url": "https://**" }, + { "url": "http://**" } + ] + } + ] +} diff --git a/gen/android/app/src/main/AndroidManifest.xml b/gen/android/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..49c861e --- /dev/null +++ b/gen/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gen/android/app/src/main/res/values/themes.xml b/gen/android/app/src/main/res/values/themes.xml new file mode 100644 index 0000000..146c7bb --- /dev/null +++ b/gen/android/app/src/main/res/values/themes.xml @@ -0,0 +1,33 @@ + + + + + + + + diff --git a/icons/gb-bot.svg b/icons/gb-bot.svg new file mode 100644 index 0000000..48f1314 --- /dev/null +++ b/icons/gb-bot.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/icons/hdpi/ic_launcher.png b/icons/hdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..97e407a6715b39ddc9009d619559e5e63ba7a87b GIT binary patch literal 1373 zcmV-j1)}%VO3A40pt2!=KMQU;d{R*sVt3Icy z?RCjnQFQ>0y2Q~zT>|^qvo1Mx5opS&+nGEHgSrTG$+IpwbrGnxGy>&tbyg;< zEk=)+2g$C+_P96t`Uu%5ZZYa6RrQwuA4zesy=WY=`eNcW2f0n)S(a}AXH<3E_lv4T zL=FOvE~%OaR;lV@o~`c{G(hL>c(12z9cYjBR^WCYLtlaJH0n-x+SUOp)MnTN)`35bx*L5Ao4ffO8i8_X1j?bb=Rv&?kq3c?+{Z6e^~);#gb-CA5xE)I13cMQ zzaQA5s=uf7Q-s(@@xrzkP6p!FVY9!cn@5LK^Y z{tu(l_~{^~K!VC>Q|}!6eac$+X8%K)b9f(EASIc)P0cKpFHhW zne}9I#bH(bx(YuHtjU9iI zW!~T#U@NdyM2-T}z_-9Tcl1n_+c?tTI`IiJz-6{zss4zW3- z?k-Q;|54R{fVV{CZL<008L|m&aeb z8E{o+fU~N4u_XV6lNUmAZFW;|sjRX9j~j9C^0g0{r1uzg?}><45n4!qgcJ>pV#Bzuw z(CJ8ilYeIvfi!!Vz9WY3F6_`q5AdV@dmItDo8>RUblc!{+d$^EzXY68)gSr{wJWjn zgN^~mTAzDt@MbLg(DpHCCg~g+fpSPKkhRkET75#>mrhcFjMc5@>J!>N29^Aiw^n|S f@9GoUzD)iDp9hzRAc#Km00000NkvXXu0mjfbXbD{ literal 0 HcmV?d00001 diff --git a/icons/icon.png b/icons/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..b9bff85f01f8b6e8fe3f9b93392514e13fc7dbe6 GIT binary patch literal 11582 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
    tD9}$*$esM^aLZ9 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 literal 0 HcmV?d00001 diff --git a/icons/xhdpi/ic_launcher.png b/icons/xhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..0ebf87c7f6da1d2eb16ab654a1c1eb3c2853c0bc GIT binary patch literal 1664 zcmV-`27md9P)k8FWQhbW?9;ba!ELWdL_~cP?peYja~^aAhuUa%Y?FJQ@H11`SC> zK~#90?VU@E6-5+=zXOvQdHBFV1O}D@u8_zAlxJdCN`eMW+!(_|7lJDVcP?D`oQb-0 zV~j3DL&TM6h#2KzG=Y^eCTw7MO)>)lCN7Y2Q8hXaU3cbISNEyDQ-5+cUEP13I)8U{ zRrRfN#TY}=AR^0wL13FZbQsuYj2Y7NDh$#z0bKA;0ryTSx&o{=#+<9)t8mQHb|3(Q z+#Y;@1;D#C`%)TBd;+ckcY2Di8Ds9Q)1R_v;uFvc&AOXtrT~XqlpU(gi%4i<7qk*M z?I~Vvj2W)epR#D2001IV=(I6L>h`59n%D((6tV!y$O0%M3!scFfHEo@1&PRP;89>Z zuok!LuroOU00CZ0AV785d%&zD1OR3OUnCHey6y8ABE%5jtptLhWpAhofbH|A za`J27Iba1aFUDhArC~>DD}i0k_o>=f>YY%=(YdsK;r<3}&<K{jGnUw!R7M~Tr< znTgm-z*0}ycfdMh%#S7blYlYi2Vfm=#B<6rU{5H2&_v8lvMvJm6%?Na)*EB4hB}oZ zMC2aeCu~FJagfmotwVvaj1@bis`#r}W4j~H_V6o@;(LlZ?!S{qO2_Xv=z&HB25Xjdg_&)mg zg^-1gf(kD(4g4q`f|%{kA7qq~1yDv7Kp9y8Wn=-Ap)P=k^oYnF5ji0uH=Laik=-KF zlRAHC1TN7QF3kq;^kH|q_?CK40(~Wxk}Khl)qZ0FzX!x{0O*+_I1_`^6X0WI{4oX4 z?1G*LR!`%+hk*VB`J+HnfM+T?w=VuDP+N)+k?X+xX`X(=7~|U)Ry+SpT#C5WaDFc| z1^Bh1bL--d0!;xvY2(~a6XcHrwzu6R^W~)_{NMey@CG5Yrpm#;P{HVpsFo*K@<48fe(P2H3a^qt1Eb+uj2%m!22N6 z+nXC|N3hv-%lfGRAJP z2wV*a`c-%Bn#ew_^3-=ags+P*T%>rv>_*`CK+fA>j5!JPi^vPuA5d+^ZjoJrO#rpX zojQU|uyhf-hwFRbl&L1k(k9RG^FeHZcfmUp-vx(a-fbxwcAIKZ+usi13tfsh=sCVk zM79QUCJzzW3_Rv3{xXQusoJh1tx^>XVe>?E)NXkZS%6Jd@IXQFW$efOdQug*iUvHz zD}e(pw?aq21^)oW!3P)!e&3Yn3+G^$1AL>9Az+hspBoy z$Hwg&Y?6yrG$UcteCKOF{ul1J-2$E{RbK>$-<*aBoocU_j$Z@;W?>W9X$PZj+fNEf z`0*(Kl=Do9;i zb@J}@{Fl6YG4`v~bhiy@;RbeieF^v(_zE~~DoWn1@*gtVKkn78ewQWRD9AB;A5qFTS3Jqt(Wj#>>}5* z*#Cmp#1-HpV4p_iN&cU3*|nOK)_SHwehDih3!scFfHJZG%1Bj!qA__poQuGfppieSL`ikvY47!d$Y+C6nAUG31&pMk&)MN;GoD=5{hm<(5k# z*>B0u$wZ@AZYxDIq=S=i^wW9${`tLL=luS7Ki}v1e7~RP`~30!yxa3GcYHBJx zCLxw^2A32GPfU)YFWbTZ04V|5+0mE8SSpWw5aOboQ(2IF-CLs2ZC}$_BMp7|LU&Mc zl7YtPHFO^!$6Mc4O~II;?w(2btzoviX1|nv-G;Ics8>c5YD2Qc8&Hmd9 z=$*3$aMS{9?a}uc*Z8a6`0?XlEQsOYEEK4PtX0MdD zWU<@f(#WwzYWShR9DA_K``GRDu)u=hQ)D4^8Vi8;N2+0$(bM;?gIlksT-7}d>XK9aQcFoQ@8jt#bOZma5K?IY8+e@)(Z*<$t5N746=p%zt zfi?=p{rr;eKo&Z^DMHf)Dz8o(Gi}DlYT;@>1q$jJo%{LX<0d=b)Y*pM;U<-8r*-|X zgCo~Mfp|>1-Tiy}ijl+RY+(lDp+bjP$G#3PUY84{O&T$wW}R!Ql>-0Mt_%JP(Qh9P zK+QYAPRrc1UKT%!#dw|C%gNI;+}chUGG?;epz;@Jm3s9>-t2I}7WE=06ohYAZIbPf zYNB96_u$>q^&XY@G=5n{TMa#@Dt4vuZmm_+WV0Vh%-~FF!KY2CnZ;zd*Nq?}p;ER5 zQ4Ku?v_CHG)vcFtt6TE=orMBzO2Zz{-^*AqJTiM_n{*Miaf_-p5O66Mrq5I&8deLF zSACs%euDix#f$yZP9YozJ-yz^gTE>1_fu;0$i<=a#TQ1D0-*8;$tYdQG_56A+-=LV zz_ex5vXI&z0#+?f8qB94Cw?2~X4k5jVI^WX{QmeVWl6Jwl1~M+Mg0h!qh+#hqrpqJ zWmkje%*%0abbD(i??fc4=tr^>oqj0OZrAw6QRK(a)-$LZR;NF@p&N$E{ARIH|2&C5 zCY0FcfJaVn6HHs8xN%t9opAgZonKcJ;$;AP%=WdX@quh8`@xBwZ&f5C(-!eeF{)4B z^&@v!7WEBeZk*zZo@-CQMDoF=7hF%8QTjqv8zir1Z6ecd(>h*8fJAH&$JR$(VxfDs z89NDYWG{evxDUk2SS-cB7!3s7gSKFE0$<8E2ziawtGAHFy(OMZe(4=uR`E9aKG|o^ zVg2AoN2}Yl!n*u+SoDna*mz^Ao4LmbRwdrjdv6)Ct~n;1x?34~w%;;2)R6U;E!k+I zgrGC>UsFs@>^A(FWzJuBGRfLgPPE*^C)5gkKW@8<>Wche`pKFrjgpKuw*zP$#9Iv+!z$HV%4Tw4{r{%6`#;NIn;q&%NFG@mbrh|V!;cQ4&l$z2 zC4rua5If~7IjyY?Q8#LZ1|A})1*JxTo#!a}`PZ0q%&P@muCi@{25bNSqgUKjTl(((I&po zN3NX`&y_nYM&fW4OZjl73ylxQw@Z++eyBxNZE{4813pFCG>TDJE*a$9VAtGn-@NbgUJOo2KqD1Ll-8Wg9=Mwg zKiNGG9uPM^NdCB|zPt(np{|wGv`D1&H_8MK>Bj-!pgAH_M&d|Bm8SNT^a1JZ8?8$P zm{p|X0Fc^nYB}SL`0)fVbFxX*{FiT<+TEH$pR8LYfX^jxg8X!Tq`HyN2W>$A*GZko zo_6DIC*E)IRr!);7w~YxaqVsmA&3*&V6WqG`XsXNA>OUif%lVT@nPo|DJ22)p-Bkl z+wI7yHA^wHNGHUVq);g{=`>v~HDCiCNa{fe|6$D`e?znSo+%GH@ zO()!@w`rZ=xgvtV2l!fRD9*6snQJ*DUA6cKM-+E~F-JCU{9-_OI%L-3Bvou@up7uN za;O%sHaM=T_;qJ3V5}@)ezST(ckgnj``d2rQ>nl|RP{L+`)j}{y}po0ypj@cI4vABkt+A>vX8S`p9~uOq)#8C1x92MHFNOvG0jRk8GLl+m=FgK_2Mjbw%w&gl(pwwAU z#3wQ1JJHXpY*gr|2d})uo=RRU-MO?epq;KO_mI}YuF zjk^BznOh*bpS>#nVRIZqd*W~VxwGV^E&36NAlW0uG76HI`{tyYt&qq$>P_Q+p;Rms zy!QL_;eBLSsH)|VY};NPw{!_>Mv8XNqx=a;8E%`W(!C5L3{PbC?ayGqtmd3G?G zfO#69?^5qEepSk90@wlAK;k$RMK6me?{amnESjj?CA)^>ugay^A62%_nnuSI<=3;% zqB^;}{op%t)n*V_Zs`)H|Fd0TA*IK#8oNYFFR-64Pg$Q=q9EL2-ZmV!GS@Q8-WP;kw)6BCO7|TYyPU6>n9YBCvv(uAV2k<7 zOTc1y4z8!QS&{(zyXQHNL5s~Bd?Od@*49`Q&LZ&5gvs3n2>#G z7+KOoD256d5j7%`C1ifn^Y8DE@ALiReb4LOd+s^sb?!aOO>?wAEha243;=+bjWq_# zqs-qB6yS~6iC{R72!&g_MFBvp!f!yzo?qec7UiNXU88Yfe$jCkBYlCmxH#?0p+QlX zE{6MRhei5RmrUdVK>U&o#@y*j-s0qC`a!(niJ3L>*M^!5+d^fnlqcwl zQ}NTMq#OkU+%U@DZTHOHI#hVwISbAA7p4Bp7>|tidyS#(Q8ssRa7+-p@N-dO9Xtena5MPSCzfCTt3qC)P+dbFUsV|qOVl_s9t*0gUvB_gWQO7 zkXZOI=_;(J)+!)qhgt8M6i}RL=E$?9!7ZOvT0am3fmUp-dz`z(ijQ4R_18l4A!?+S z+vWog&^VxEe19q(KuAedq3S@}a?Lr5SYe-ZKYqf$!su2T8c`#stGIch`pjCbiY^2x z6VVy{#p))W8Oc^;7chsJIA$>ufxnQidw$T}4L}^1%7OI@tiuefspYN}P;Cy~|}T_MY_j5rPKgW_=h$1Z$QRYTcRq23tV6&p31>VbE(MRpwUNR*Q=r7*QGg6iK#q_{4%wq0z__zRw8ucY6 zN30!T$AaB(%6Q&p0 z?EBD?r;d-E$^1a8%~8t-#IY>WWAVGsG%zs(?UKfuXKLW#8I<6=M%Le<%nQrcRAU6C zCr_}yj~u$255+ecRfPmZ4SuXVw0C+7e0H7cIidQ1lSBy?`~%(qi|tlyIt>`>|B!l7 z!P!Y^_@w2=Qx@A4)#16cS_R$9E|p4X$|96%AZk#$`!7XB+Lbve#$k8rtiBI!y+h`MvXc3_yI>Vq0<6P)ZUL znh1Y=Do6|&EJ*e~Pv%fpt*&zSxQg`Op4?NXMGD;}p|f~_H_q;%8R&m6S9*)bdxZrM zI|DE6=B<;;untLWr)xWxdSLquniyGirX+*(AP9K=rVblr^UZpcy+r3z?4KIlY5vMx zyZ;udV6h69U>RhJS5L0ho06PuHOa-$P@*3*L?VE=OaIdqILnxd)ioBFSSL5k589^j zOGb`9wShF67B2p*#dqj<5PZ z?&4im1T}LU7D`0_GlyRshw8l9Vf*8?1ZWDjY=uuH1h=3l>l zM&Ud}9DQ?dEZEH%`))gCPaEB1ydGLlVfE~sT;$sG_yKTBep$tX`@r)_x0q&HU>Er6mVo2lcPQ_e%Nql2jdw}a(T|?U4u-#@Q4kj4e-e1e(5?+xDBc@qTXchG%s;^ zzJ{=@%XuLh5qHX}W-n48ZfpdOszZ?iyBmQ=V3sp%I6Zi&2r2HY9rDs{K>@{FdeF+MXFzh|C(q=Ot) zY)PgBi)r$$AN0=hPYMG$N*^C{@+k_!JECvnDVEuQ-X+G%Qe5TslyD(7(OBE>b8`Fe z8Z$0Z&RQEGos^L@)9RWaq>IN-Nl*hXG%t~i`L~8>(Q(Vk#zXnCSs56gRdQ~M3WA!^ zYuS`dqb4g&e7h3ZIK~AS=!h6=L(>B7(tj5YY7OzU&A5av41hE`g@cYhE=kmaNI`0mg`^U^TXh`%` z;U*!ZVB%A7^dZw0)5CUu?8bb`tQ7lH3oUnrI9)a5mw(yHJk0ED`XcJZ=PBUK{xB#K zYG1IzjAi-|kOUOLi*Sl;7c1=aPPr$wt}EfW43m#t%{j7f6$kIVSr5n#ju(dbHJTg0 z4H>eHLHBnlDi^bu$<^g>(f}PWa&oXPgYJW9NWZxJ#&+V{3H@#yJMW$PkR-;ZLI1~!0 z1Ng&?%Q+_a3-^s2;ZwWVwimV`C-*T84(sfB0Jc?u?R@Keelz($3|1Z%wT!Y`!UhFm zomqWOYm6K5DK$^#zxQ1)*^l9+!$qTK#5*!#j;wlc%NYMlA#^@p!bG^saB_%KI{QitDW(T#0T+1M;TjD&QG{g(* z+Tb^6W_lSbf){d@nsc!*;|`-J!>0ssjWS7 zSE^i4m0?4X1odU?+A80&b%yv4?qS6BR_a{mMqf=s&LHGA-_o*22nl~d0g;(zfmw$q zw5BTk1;(ZJ*0$x8p(WVd=$KGmg#q__wxie$-PB{N23JtB|tbw46g$N^Kz z_WZn9TxH~3MEUifO+Q}R2j*@HdKYa%cE@s&HwBOX888MccUVqicerXtXq(!mWRHNc0~V&UZ& z#Ykf&BOW-vr%hZ zhnKAg$#%Ps*4TyeE2qw#V;1p zcm53&kj$ze-@BKhOY@+CWsgPgSU`fWZ_njtpP-~IIyBjbanH&j;vvBAF6$cmURrUE z;X(NCE~`xZZZ};L+|mxkf-iV2V27zdfA2Iq)lL{N`>c9QaYMQL5Bo%B$4Rl}m!$yD zS&9>i0#o)*sw9_>;=7GF_?JJs^_c{Wk9eqG!^&Z;pqf#MyzKAJ^Wimt5F;8VVM654 z!>jg$kFAPt^~REwj%x$q_gElDh&jEPsiFVHL{Om=EO22xrge%Q8OIfNP^d$WgM|`g#$FGk7b7(yR%IEm9oX0)M~In@1_is>_qw_LIcB)OU^bwu^{}&1k8c@U_#>%+n8=*B-WXZ3L-!qP2 z;grWE(3}DzbcW1on3L@D;EC literal 0 HcmV?d00001 diff --git a/rom/README.md b/rom/README.md new file mode 100644 index 0000000..f168f68 --- /dev/null +++ b/rom/README.md @@ -0,0 +1,56 @@ +# BotOS ROM - Sistema Android Customizado + +## Níveis de Customização + +### Nível 1: Debloat + Launcher (Sem Root) +Remove apps do fabricante via ADB e configura BotOS como launcher padrão. + +### Nível 2: Magisk Module (Com Root) +Módulo que substitui boot animation, launcher padrão, e remove bloatware permanentemente. + +### Nível 3: Custom GSI (Imagem Completa) +Android puro com BotOS integrado, sem nenhum app de fabricante. + +--- + +## Nível 1: Debloat sem Root + +```bash +# Conectar dispositivo via USB (debug USB ativado) +./scripts/debloat.sh +``` + +Remove apps Samsung, Huawei, Xiaomi sem precisar de root. + +## Nível 2: Magisk Module + +```bash +# Gerar módulo Magisk +./scripts/build-magisk-module.sh + +# Instalar via Magisk Manager +adb push botos-magisk.zip /sdcard/ +``` + +## Nível 3: GSI Build + +Requer ambiente de build AOSP. Veja `gsi/README.md`. + +--- + +## Fabricantes Suportados para Debloat + +- Samsung (One UI) +- Huawei (EMUI) +- Xiaomi (MIUI) +- Motorola +- LG +- Realme/OPPO (ColorOS) +- Vivo (FuntouchOS) + +## Requisitos + +- ADB instalado +- USB Debug ativado no dispositivo +- Para Nível 2+: Bootloader desbloqueado + Magisk +- Para Nível 3: Ambiente AOSP build (~200GB espaço) diff --git a/rom/gsi/README.md b/rom/gsi/README.md new file mode 100644 index 0000000..ca0ccee --- /dev/null +++ b/rom/gsi/README.md @@ -0,0 +1,156 @@ +# BotOS GSI - Generic System Image + +## O que é GSI? + +GSI (Generic System Image) é uma imagem Android pura que funciona em **qualquer dispositivo** com Project Treble (Android 8.0+). + +Com GSI você pode: +- Substituir COMPLETAMENTE o sistema do fabricante +- Ter Android puro + BotOS +- Zero bloatware Samsung/Huawei/Xiaomi +- Controle total da inicialização + +## Requisitos do Dispositivo + +1. **Project Treble** - Verificar com: + ```bash + adb shell getprop ro.treble.enabled + # Deve retornar "true" + ``` + +2. **Bootloader desbloqueado** + +3. **Partição system tipo A/B ou A-only**: + ```bash + adb shell getprop ro.build.ab_update + # "true" = A/B, vazio = A-only + ``` + +## Opções de GSI Base + +### Opção 1: Usar GSI existente + BotOS Magisk Module + +Mais simples. Use uma GSI pronta e instale o módulo BotOS: + +1. Baixe GSI de: https://github.com/nicograph/nicograph-gsi +2. Flash via fastboot +3. Instale Magisk +4. Instale botos-magisk.zip + +### Opção 2: Compilar AOSP com BotOS integrado + +Para controle total, compile o AOSP do zero. + +## Compilando AOSP com BotOS + +### Requisitos de Build + +```bash +# Ubuntu 20.04+ recomendado +# ~300GB de espaço em disco +# 16GB+ RAM +# CPU com muitos cores (compilação leva horas) + +# Instalar dependências +sudo apt install -y git-core gnupg flex bison build-essential \ + zip curl zlib1g-dev libc6-dev-i386 libncurses5 \ + x11proto-core-dev libx11-dev lib32z1-dev libgl1-mesa-dev \ + libxml2-utils xsltproc unzip fontconfig python3 +``` + +### Estrutura do Projeto + +``` +aosp/ +├── .repo/ # Repo tool metadata +├── build/ # Build system +├── device/ +│ └── pragmatismo/ +│ └── botos/ # Device config para BotOS +├── packages/ +│ └── apps/ +│ └── BotOS/ # App BotOS como system app +├── vendor/ +│ └── pragmatismo/ +│ └── botos/ # Vendor customizations +└── out/ # Build output +``` + +### Passo 1: Inicializar Repo + +```bash +mkdir aosp && cd aosp + +# Inicializar com Android 14 (ou versão desejada) +repo init -u https://android.googlesource.com/platform/manifest -b android-14.0.0_r1 + +# Sync (demora muito!) +repo sync -c -j$(nproc) --no-tags +``` + +### Passo 2: Criar Device Tree BotOS + +O device tree define configurações específicas do BotOS. + +Veja os arquivos em `device/pragmatismo/botos/` neste repositório. + +### Passo 3: Compilar + +```bash +source build/envsetup.sh +lunch botos_arm64-userdebug +make -j$(nproc) +``` + +### Passo 4: Flash + +```bash +# Entrar em fastboot mode +adb reboot fastboot + +# Flash GSI +fastboot flash system out/target/product/botos/system.img +fastboot flash vendor out/target/product/botos/vendor.img +fastboot flash boot out/target/product/botos/boot.img + +# Limpar dados (necessário para GSI) +fastboot -w + +# Reboot +fastboot reboot +``` + +## Arquivos de Configuração + +Os arquivos necessários estão em: +- `device/` - Device tree +- `vendor/` - Vendor customizations +- `packages/apps/BotOS/` - App BotOS + +## Alternativa: phh-treble GSI + +Para uma abordagem mais rápida, modifique o phh-treble GSI: + +```bash +git clone https://github.com/nicograph/nicograph-gsi +cd nicograph-gsi + +# Adicionar BotOS como system app +mkdir -p nicograph-files/system/priv-app/BotOS +cp /path/to/BotOS.apk nicograph-files/system/priv-app/BotOS/ + +# Adicionar boot animation +cp /path/to/bootanimation.zip nicograph-files/system/media/ + +# Rebuild +./build.sh +``` + +## Notas de Segurança + +⚠️ **AVISO**: Modificar system images pode: +- Invalidar garantia do dispositivo +- Causar brick se feito incorretamente +- Desabilitar recursos de segurança (SafetyNet, etc) + +Sempre tenha backup completo antes de qualquer modificação! diff --git a/rom/gsi/device/pragmatismo/botos/AndroidProducts.mk b/rom/gsi/device/pragmatismo/botos/AndroidProducts.mk new file mode 100644 index 0000000..caba6ff --- /dev/null +++ b/rom/gsi/device/pragmatismo/botos/AndroidProducts.mk @@ -0,0 +1,10 @@ +# BotOS Android Products +# Define os targets de build disponíveis + +PRODUCT_MAKEFILES := \ + $(LOCAL_DIR)/device.mk + +COMMON_LUNCH_CHOICES := \ + botos_arm64-userdebug \ + botos_arm64-user \ + botos_arm64-eng diff --git a/rom/gsi/device/pragmatismo/botos/BoardConfig.mk b/rom/gsi/device/pragmatismo/botos/BoardConfig.mk new file mode 100644 index 0000000..f201d58 --- /dev/null +++ b/rom/gsi/device/pragmatismo/botos/BoardConfig.mk @@ -0,0 +1,40 @@ +# BotOS Board Configuration +# Generic System Image (GSI) for ARM64 + +# Architecture +TARGET_ARCH := arm64 +TARGET_ARCH_VARIANT := armv8-a +TARGET_CPU_ABI := arm64-v8a +TARGET_CPU_VARIANT := generic + +TARGET_2ND_ARCH := arm +TARGET_2ND_ARCH_VARIANT := armv8-a +TARGET_2ND_CPU_ABI := armeabi-v7a +TARGET_2ND_CPU_VARIANT := generic + +# Treble +BOARD_VNDK_VERSION := current +PRODUCT_FULL_TREBLE := true + +# Partitions +BOARD_SYSTEMIMAGE_FILE_SYSTEM_TYPE := ext4 +BOARD_USERDATAIMAGE_FILE_SYSTEM_TYPE := ext4 +BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE := ext4 + +# System as root +BOARD_BUILD_SYSTEM_ROOT_IMAGE := true + +# Boot image +BOARD_KERNEL_BASE := 0x00000000 +BOARD_KERNEL_PAGESIZE := 4096 +BOARD_KERNEL_CMDLINE := androidboot.hardware=botos + +# Verified Boot +BOARD_AVB_ENABLE := true + +# SELinux +BOARD_SEPOLICY_DIRS += device/pragmatismo/botos/sepolicy + +# Recovery +TARGET_USERIMAGES_USE_EXT4 := true +TARGET_USERIMAGES_USE_F2FS := true diff --git a/rom/gsi/device/pragmatismo/botos/device.mk b/rom/gsi/device/pragmatismo/botos/device.mk new file mode 100644 index 0000000..196e5bf --- /dev/null +++ b/rom/gsi/device/pragmatismo/botos/device.mk @@ -0,0 +1,77 @@ +# BotOS Device Configuration + +# Inherit from common +$(call inherit-product, $(SRC_TARGET_DIR)/product/core_64_bit.mk) +$(call inherit-product, $(SRC_TARGET_DIR)/product/full_base.mk) + +# Product info +PRODUCT_NAME := botos +PRODUCT_DEVICE := botos +PRODUCT_BRAND := Pragmatismo +PRODUCT_MODEL := BotOS +PRODUCT_MANUFACTURER := Pragmatismo.io + +# Locales +PRODUCT_LOCALES := pt_BR en_US es_ES + +# ===================================================== +# BotOS Customizations +# ===================================================== + +# BotOS Launcher como app de sistema privilegiado +PRODUCT_PACKAGES += \ + BotOS + +# Boot animation customizada +PRODUCT_COPY_FILES += \ + device/pragmatismo/botos/media/bootanimation.zip:system/media/bootanimation.zip + +# Overlay para configurações padrão +DEVICE_PACKAGE_OVERLAYS += device/pragmatismo/botos/overlay + +# Propriedades do sistema +PRODUCT_PROPERTY_OVERRIDES += \ + ro.product.brand=Pragmatismo \ + ro.product.name=BotOS \ + ro.product.device=botos \ + ro.build.display.id=BotOS-1.0 \ + ro.botos.version=1.0 \ + persist.sys.language=pt \ + persist.sys.country=BR + +# Desabilitar analytics/telemetria +PRODUCT_PROPERTY_OVERRIDES += \ + ro.com.google.gmsversion= \ + ro.setupwizard.mode=DISABLED + +# Performance +PRODUCT_PROPERTY_OVERRIDES += \ + dalvik.vm.heapsize=512m \ + dalvik.vm.heapgrowthlimit=256m + +# ===================================================== +# Removido bloatware +# ===================================================== + +# NÃO incluir esses pacotes +PRODUCT_PACKAGES_REMOVED += \ + Calculator \ + Calendar \ + Camera2 \ + DeskClock \ + Email \ + Gallery2 \ + Music \ + QuickSearchBox + +# ===================================================== +# Apps mínimos necessários +# ===================================================== + +PRODUCT_PACKAGES += \ + Launcher3 \ + Settings \ + SystemUI \ + SettingsProvider \ + Shell \ + adb diff --git a/rom/install.sh b/rom/install.sh new file mode 100755 index 0000000..3309ab6 --- /dev/null +++ b/rom/install.sh @@ -0,0 +1,313 @@ +#!/bin/bash +# BotOS Installation Script +# Escolha o nível de instalação baseado no seu dispositivo +# +# Uso: ./install.sh + +set -e +cd "$(dirname "$0")" + +# Cores +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +CYAN='\033[0;36m' +NC='\033[0m' + +clear +echo -e "${CYAN}" +cat << 'BANNER' +╔══════════════════════════════════════════════════════════════════════════════╗ +║ ║ +║ ██████╗ ██████╗ ████████╗ ██████╗ ███████╗ ║ +║ ██╔══██╗██╔═══██╗╚══██╔══╝██╔═══██╗██╔════╝ ║ +║ ██████╔╝██║ ██║ ██║ ██║ ██║███████╗ ║ +║ ██╔══██╗██║ ██║ ██║ ██║ ██║╚════██║ ║ +║ ██████╔╝╚██████╔╝ ██║ ╚██████╔╝███████║ ║ +║ ╚═════╝ ╚═════╝ ╚═╝ ╚═════╝ ╚══════╝ ║ +║ ║ +║ Android OS by General Bots ║ +║ Pragmatismo.io ║ +║ ║ +╚══════════════════════════════════════════════════════════════════════════════╝ +BANNER +echo -e "${NC}" + +# ===================================================== +# Verificações +# ===================================================== + +check_adb() { + if ! command -v adb &> /dev/null; then + echo -e "${RED}ERRO: ADB não encontrado!${NC}" + echo "Instale com: sudo apt install adb" + return 1 + fi + return 0 +} + +check_device() { + if ! adb devices | grep -q "device$"; then + echo -e "${YELLOW}Nenhum dispositivo conectado.${NC}" + echo "" + echo "Para conectar:" + echo " 1. Ative 'Opções do desenvolvedor' no celular" + echo " (Configurações → Sobre → Tocar 7x no 'Número da versão')" + echo " 2. Ative 'Depuração USB'" + echo " 3. Conecte o cabo USB" + echo " 4. Autorize no celular quando solicitado" + echo "" + return 1 + fi + + DEVICE=$(adb shell getprop ro.product.model 2>/dev/null | tr -d '\r') + BRAND=$(adb shell getprop ro.product.brand 2>/dev/null | tr -d '\r') + ANDROID=$(adb shell getprop ro.build.version.release 2>/dev/null | tr -d '\r') + + echo -e "${GREEN}Dispositivo conectado: $BRAND $DEVICE (Android $ANDROID)${NC}" + return 0 +} + +check_root() { + if adb shell su -c "id" 2>/dev/null | grep -q "uid=0"; then + echo -e "${GREEN}Root detectado!${NC}" + return 0 + else + echo -e "${YELLOW}Dispositivo NÃO tem root.${NC}" + return 1 + fi +} + +check_magisk() { + if adb shell pm list packages 2>/dev/null | grep -q "com.topjohnwu.magisk"; then + echo -e "${GREEN}Magisk detectado!${NC}" + return 0 + else + return 1 + fi +} + +check_treble() { + local treble=$(adb shell getprop ro.treble.enabled 2>/dev/null | tr -d '\r') + if [ "$treble" == "true" ]; then + echo -e "${GREEN}Project Treble: Suportado${NC}" + return 0 + else + echo -e "${YELLOW}Project Treble: NÃO suportado${NC}" + return 1 + fi +} + +check_bootloader() { + local unlocked=$(adb shell getprop ro.boot.flash.locked 2>/dev/null | tr -d '\r') + if [ "$unlocked" == "0" ]; then + echo -e "${GREEN}Bootloader: Desbloqueado${NC}" + return 0 + else + echo -e "${YELLOW}Bootloader: Bloqueado${NC}" + return 1 + fi +} + +# ===================================================== +# Instalação +# ===================================================== + +install_level_1() { + echo -e "\n${BLUE}=== Nível 1: Debloat + BotOS Launcher ===${NC}" + echo "Removendo bloatware e instalando BotOS como app..." + echo "" + + # Executar debloat + bash scripts/debloat.sh +} + +install_level_2() { + echo -e "\n${BLUE}=== Nível 2: Magisk Module ===${NC}" + echo "Instalando módulo Magisk com boot animation + BotOS system app..." + echo "" + + # Verificar se tem APK compilado + if [ ! -f "../gen/android/app/build/outputs/apk/release/app-release.apk" ]; then + echo -e "${YELLOW}APK do BotOS não encontrado.${NC}" + echo "Compilando..." + cd .. + cargo tauri android build --release || { + echo -e "${RED}Erro na compilação. Configure o ambiente Tauri primeiro.${NC}" + return 1 + } + cd rom + fi + + # Gerar boot animation + if [ ! -f "../bootanimation.zip" ]; then + echo "Gerando boot animation..." + bash ../scripts/create-bootanimation.sh || true + fi + + # Build Magisk module + bash scripts/build-magisk-module.sh + + # Instalar + if [ -f "botos-magisk-v1.0.zip" ]; then + echo "Copiando módulo para dispositivo..." + adb push botos-magisk-v1.0.zip /sdcard/ + + echo "" + echo -e "${GREEN}Módulo copiado!${NC}" + echo "" + echo "Para completar a instalação:" + echo " 1. Abra o Magisk Manager no celular" + echo " 2. Vá em 'Modules' (Módulos)" + echo " 3. Toque em '+' e selecione 'botos-magisk-v1.0.zip'" + echo " 4. Reinicie o dispositivo" + fi +} + +install_level_3() { + echo -e "\n${BLUE}=== Nível 3: GSI Flash ===${NC}" + echo "Instalando GSI completa com BotOS..." + echo "" + + echo -e "${YELLOW}AVISO: Isso irá APAGAR todos os dados do dispositivo!${NC}" + echo "" + read -p "Tem certeza? Digite 'SIM' para continuar: " confirm + + if [ "$confirm" != "SIM" ]; then + echo "Cancelado." + return 1 + fi + + # Verificar requisitos + check_treble || { + echo -e "${RED}Dispositivo não suporta Project Treble.${NC}" + return 1 + } + + check_bootloader || { + echo -e "${YELLOW}Bootloader precisa ser desbloqueado primeiro.${NC}" + echo "" + echo "Instruções:" + echo " 1. Habilite 'OEM unlocking' nas opções do desenvolvedor" + echo " 2. adb reboot bootloader" + echo " 3. fastboot flashing unlock" + echo " 4. Confirme no dispositivo" + return 1 + fi + + echo "" + echo "Para GSI, você precisa:" + echo " 1. Baixar uma GSI base (ex: phh-treble)" + echo " 2. Ou compilar AOSP com os arquivos em gsi/" + echo "" + echo "Veja gsi/README.md para instruções detalhadas." +} + +show_device_info() { + echo -e "\n${BLUE}=== Informações do Dispositivo ===${NC}\n" + + check_device || return 1 + + echo "" + check_root && HAS_ROOT=1 || HAS_ROOT=0 + check_magisk && HAS_MAGISK=1 || HAS_MAGISK=0 + check_treble && HAS_TREBLE=1 || HAS_TREBLE=0 + check_bootloader && HAS_UNLOCKED=1 || HAS_UNLOCKED=0 + + echo "" + echo -e "${CYAN}Opções disponíveis para este dispositivo:${NC}" + echo "" + echo -e " ${GREEN}✓${NC} Nível 1 (Debloat + App) - Sempre disponível" + + if [ "$HAS_MAGISK" == "1" ]; then + echo -e " ${GREEN}✓${NC} Nível 2 (Magisk Module) - Magisk detectado" + else + echo -e " ${YELLOW}?${NC} Nível 2 (Magisk Module) - Requer Magisk instalado" + fi + + if [ "$HAS_TREBLE" == "1" ] && [ "$HAS_UNLOCKED" == "1" ]; then + echo -e " ${GREEN}✓${NC} Nível 3 (GSI) - Treble + Bootloader desbloqueado" + else + echo -e " ${RED}✗${NC} Nível 3 (GSI) - Requer Treble + bootloader desbloqueado" + fi +} + +# ===================================================== +# Menu Principal +# ===================================================== + +main_menu() { + while true; do + echo "" + echo -e "${CYAN}═══════════════════════════════════════════════════════════════${NC}" + echo -e "${CYAN} MENU DE INSTALAÇÃO ${NC}" + echo -e "${CYAN}═══════════════════════════════════════════════════════════════${NC}" + echo "" + echo " 1) Ver informações do dispositivo" + echo "" + echo " 2) Nível 1: Debloat + BotOS Launcher (SEM root)" + echo " Remove bloatware via ADB, instala BotOS como app" + echo "" + echo " 3) Nível 2: Magisk Module (COM root)" + echo " Boot animation GB, BotOS como system app, bloat removido" + echo "" + echo " 4) Nível 3: GSI Flash (Bootloader desbloqueado)" + echo " Substitui Android inteiro por BotOS" + echo "" + echo " 5) Compilar BotOS APK" + echo "" + echo " 6) Gerar Boot Animation" + echo "" + echo " 0) Sair" + echo "" + read -p "Escolha [0-6]: " choice + + case $choice in + 1) + check_adb && show_device_info + ;; + 2) + check_adb && check_device && install_level_1 + ;; + 3) + check_adb && check_device && install_level_2 + ;; + 4) + check_adb && check_device && install_level_3 + ;; + 5) + echo -e "\n${BLUE}Compilando BotOS APK...${NC}\n" + cd .. + cargo tauri android build --release + cd rom + echo -e "${GREEN}APK gerado em gen/android/app/build/outputs/apk/${NC}" + ;; + 6) + echo -e "\n${BLUE}Gerando boot animation...${NC}\n" + bash ../scripts/create-bootanimation.sh + ;; + 0) + echo -e "\n${GREEN}Até logo!${NC}\n" + exit 0 + ;; + *) + echo -e "${RED}Opção inválida${NC}" + ;; + esac + + echo "" + read -p "Pressione ENTER para continuar..." + clear + done +} + +# ===================================================== +# Início +# ===================================================== + +# Verificar se ADB está disponível +check_adb || exit 1 + +# Mostrar menu +main_menu diff --git a/rom/scripts/build-magisk-module.sh b/rom/scripts/build-magisk-module.sh new file mode 100755 index 0000000..364c6af --- /dev/null +++ b/rom/scripts/build-magisk-module.sh @@ -0,0 +1,286 @@ +#!/bin/bash +# Build BotOS Magisk Module +# Substitui boot animation, launcher padrão, e configurações do sistema +# +# O módulo será instalado via Magisk Manager + +set -e +cd "$(dirname "$0")/.." + +MODULE_DIR="magisk-module" +MODULE_ZIP="botos-magisk-v1.0.zip" + +echo "╔══════════════════════════════════════════════════════════════╗" +echo "║ Building BotOS Magisk Module ║" +echo "╚══════════════════════════════════════════════════════════════╝" +echo "" + +# Limpar e criar estrutura +rm -rf "$MODULE_DIR" +mkdir -p "$MODULE_DIR/META-INF/com/google/android" +mkdir -p "$MODULE_DIR/system/media" +mkdir -p "$MODULE_DIR/system/etc/permissions" +mkdir -p "$MODULE_DIR/system/priv-app/BotOS" +mkdir -p "$MODULE_DIR/common" + +# ===================================================== +# module.prop - Metadados do módulo +# ===================================================== +cat > "$MODULE_DIR/module.prop" << 'EOF' +id=botos +name=BotOS - General Bots Launcher +version=v1.0 +versionCode=1 +author=Pragmatismo.io +description=Transforma seu Android em BotOS - Remove bloatware, substitui boot animation e define BotOS como launcher padrão +EOF + +# ===================================================== +# update-binary - Script de instalação +# ===================================================== +cat > "$MODULE_DIR/META-INF/com/google/android/update-binary" << 'INSTALLER' +#!/sbin/sh + +################# +# Initialization +################# + +TMPDIR=/dev/tmp +PERSISTDIR=/sbin/.magisk/mirror/persist + +rm -rf $TMPDIR 2>/dev/null +mkdir -p $TMPDIR + +# echo before loading util_functions +ui_print() { echo "$1"; } + +require_new_magisk() { + ui_print "*******************************" + ui_print " Please install Magisk v20.4+! " + ui_print "*******************************" + exit 1 +} + +########################## +# Load util_functions.sh +########################## + +OUTFD=$2 +ZIPFILE=$3 + +mount /data 2>/dev/null + +[ -f /data/adb/magisk/util_functions.sh ] || require_new_magisk +. /data/adb/magisk/util_functions.sh +[ $MAGISK_VER_CODE -lt 20400 ] && require_new_magisk + +install_module +exit 0 +INSTALLER + +chmod 755 "$MODULE_DIR/META-INF/com/google/android/update-binary" + +# ===================================================== +# updater-script (vazio, necessário para compatibilidade) +# ===================================================== +echo "#MAGISK" > "$MODULE_DIR/META-INF/com/google/android/updater-script" + +# ===================================================== +# customize.sh - Script de customização pós-instalação +# ===================================================== +cat > "$MODULE_DIR/customize.sh" << 'CUSTOMIZE' +#!/system/bin/sh +# BotOS Magisk Module - Customization Script + +ui_print "╔══════════════════════════════════════════════════════════════╗" +ui_print "║ Installing BotOS ║" +ui_print "╚══════════════════════════════════════════════════════════════╝" +ui_print "" + +# Verificar arquitetura +ARCH=$(getprop ro.product.cpu.abi) +ui_print "- Device architecture: $ARCH" +ui_print "- Android version: $(getprop ro.build.version.release)" +ui_print "- Device: $(getprop ro.product.model)" +ui_print "" + +# Copiar boot animation se existir +if [ -f "$MODPATH/bootanimation.zip" ]; then + ui_print "- Installing custom boot animation..." + mkdir -p "$MODPATH/system/media" + cp "$MODPATH/bootanimation.zip" "$MODPATH/system/media/" +fi + +# Copiar APK do BotOS se existir +if [ -f "$MODPATH/BotOS.apk" ]; then + ui_print "- Installing BotOS launcher as system app..." + mkdir -p "$MODPATH/system/priv-app/BotOS" + cp "$MODPATH/BotOS.apk" "$MODPATH/system/priv-app/BotOS/" +fi + +# Configurar permissões +ui_print "- Setting permissions..." +set_perm_recursive $MODPATH 0 0 0755 0644 + +if [ -d "$MODPATH/system/priv-app" ]; then + set_perm_recursive "$MODPATH/system/priv-app" 0 0 0755 0644 +fi + +ui_print "" +ui_print "╔══════════════════════════════════════════════════════════════╗" +ui_print "║ BotOS installed successfully! ║" +ui_print "║ ║" +ui_print "║ After reboot: ║" +ui_print "║ 1. Press Home button ║" +ui_print "║ 2. Select 'BotOS' as default launcher ║" +ui_print "║ 3. Choose 'Always' ║" +ui_print "╚══════════════════════════════════════════════════════════════╝" +CUSTOMIZE + +chmod 755 "$MODULE_DIR/customize.sh" + +# ===================================================== +# post-fs-data.sh - Executado no boot (após fs montado) +# ===================================================== +cat > "$MODULE_DIR/post-fs-data.sh" << 'POSTFS' +#!/system/bin/sh +# BotOS - Post-FS-Data Script +# Executado após o sistema de arquivos ser montado + +MODDIR=${0%/*} + +# Log +log -t BotOS "BotOS module post-fs-data started" + +# Desabilitar apps de fabricante (overlay) +# Isso "esconde" os apps sem deletá-los +for bloat in \ + "com.facebook.katana" \ + "com.facebook.appmanager" \ + "com.facebook.services" \ + "com.samsung.android.bixby.agent" \ + "com.samsung.android.bixby.service" \ + "com.huawei.appmarket" \ + "com.miui.msa.global" \ + "com.miui.analytics" +do + # Criar diretório vazio para "substituir" o app + if [ -d "/system/app/$bloat" ]; then + mkdir -p "$MODDIR/system/app/$bloat" + touch "$MODDIR/system/app/$bloat/.replace" + fi + if [ -d "/system/priv-app/$bloat" ]; then + mkdir -p "$MODDIR/system/priv-app/$bloat" + touch "$MODDIR/system/priv-app/$bloat/.replace" + fi +done + +log -t BotOS "BotOS bloatware disabled via overlay" +POSTFS + +chmod 755 "$MODULE_DIR/post-fs-data.sh" + +# ===================================================== +# service.sh - Executado como serviço no boot +# ===================================================== +cat > "$MODULE_DIR/service.sh" << 'SERVICE' +#!/system/bin/sh +# BotOS - Service Script +# Executado como serviço após o boot completar + +MODDIR=${0%/*} + +# Aguardar boot completar +while [ "$(getprop sys.boot_completed)" != "1" ]; do + sleep 1 +done + +# Aguardar mais um pouco para sistema estabilizar +sleep 5 + +log -t BotOS "BotOS service started" + +# Configurar BotOS como launcher padrão (se instalado) +BOTOS_PKG="br.com.pragmatismo.botos" + +if pm list packages | grep -q "$BOTOS_PKG"; then + # Tentar definir como launcher padrão + # Nota: Isso pode não funcionar em todos os dispositivos + pm set-home-activity "$BOTOS_PKG/.MainActivity" 2>/dev/null || true + log -t BotOS "BotOS set as preferred launcher" +fi + +# Desabilitar analytics/telemetria de fabricantes +settings put global upload_apk_enable 0 2>/dev/null || true +settings put secure send_action_app_error 0 2>/dev/null || true + +# Ativar modo imersivo (esconde barra de navegação) +# settings put global policy_control immersive.full=* 2>/dev/null || true + +log -t BotOS "BotOS service configuration complete" +SERVICE + +chmod 755 "$MODULE_DIR/service.sh" + +# ===================================================== +# uninstall.sh - Script de desinstalação +# ===================================================== +cat > "$MODULE_DIR/uninstall.sh" << 'UNINSTALL' +#!/system/bin/sh +# BotOS - Uninstall Script + +# Restaurar launcher padrão do sistema +# (O Magisk automaticamente remove os overlays) + +log -t BotOS "BotOS module uninstalled" +UNINSTALL + +chmod 755 "$MODULE_DIR/uninstall.sh" + +# ===================================================== +# Copiar boot animation se existir +# ===================================================== +if [ -f "../bootanimation.zip" ]; then + echo "- Incluindo boot animation customizada..." + cp "../bootanimation.zip" "$MODULE_DIR/" +else + echo "- Boot animation não encontrada." + echo " Execute ../scripts/create-bootanimation.sh primeiro." +fi + +# ===================================================== +# Copiar APK do BotOS se existir +# ===================================================== +APK_PATH="../gen/android/app/build/outputs/apk/release/app-release.apk" +if [ -f "$APK_PATH" ]; then + echo "- Incluindo BotOS APK..." + cp "$APK_PATH" "$MODULE_DIR/BotOS.apk" +else + echo "- APK não encontrado." + echo " Compile com: cd .. && cargo tauri android build --release" +fi + +# ===================================================== +# Criar arquivo ZIP do módulo +# ===================================================== +echo "" +echo "Criando $MODULE_ZIP..." +cd "$MODULE_DIR" +zip -r "../$MODULE_ZIP" . -x "*.DS_Store" +cd .. + +echo "" +echo "╔══════════════════════════════════════════════════════════════╗" +echo "║ Magisk Module criado com sucesso! ║" +echo "╚══════════════════════════════════════════════════════════════╝" +echo "" +echo "Arquivo: $(pwd)/$MODULE_ZIP" +echo "" +echo "Para instalar:" +echo " 1. Copie para o dispositivo:" +echo " adb push $MODULE_ZIP /sdcard/" +echo "" +echo " 2. Abra o Magisk Manager" +echo " 3. Vá em 'Modules' → '+' → Selecione o ZIP" +echo " 4. Reinicie o dispositivo" +echo "" diff --git a/rom/scripts/debloat.sh b/rom/scripts/debloat.sh new file mode 100755 index 0000000..c9a5606 --- /dev/null +++ b/rom/scripts/debloat.sh @@ -0,0 +1,406 @@ +#!/bin/bash +# BotOS Debloat Script - Remove bloatware sem root +# Funciona via ADB shell pm uninstall --user 0 +# +# Uso: ./debloat.sh [samsung|huawei|xiaomi|all] + +set -e +cd "$(dirname "$0")/.." + +# Cores +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' + +echo -e "${BLUE}" +echo "╔══════════════════════════════════════════════════════════════╗" +echo "║ BotOS Debloat Tool v1.0 ║" +echo "║ Remove bloatware Samsung/Huawei/Xiaomi/etc ║" +echo "╚══════════════════════════════════════════════════════════════╝" +echo -e "${NC}" + +# Verificar ADB +if ! command -v adb &> /dev/null; then + echo -e "${RED}ERRO: ADB não encontrado!${NC}" + echo "Instale com: sudo apt install adb" + exit 1 +fi + +# Verificar dispositivo conectado +if ! adb devices | grep -q "device$"; then + echo -e "${RED}ERRO: Nenhum dispositivo conectado!${NC}" + echo "1. Ative 'Depuração USB' nas configurações do desenvolvedor" + echo "2. Conecte o cabo USB e autorize no celular" + exit 1 +fi + +DEVICE=$(adb shell getprop ro.product.model | tr -d '\r') +BRAND=$(adb shell getprop ro.product.brand | tr -d '\r') +echo -e "${GREEN}Dispositivo detectado: $BRAND $DEVICE${NC}" +echo "" + +# ===================================================== +# LISTAS DE BLOATWARE POR FABRICANTE +# ===================================================== + +# Samsung One UI +SAMSUNG_BLOAT=( + # Samsung Apps + "com.samsung.android.app.tips" + "com.samsung.android.bixby.agent" + "com.samsung.android.bixby.service" + "com.samsung.android.visionintelligence" + "com.samsung.android.app.routines" + "com.samsung.android.game.gamehome" + "com.samsung.android.game.gametools" + "com.samsung.android.app.spage" + "com.samsung.android.mateagent" + "com.samsung.android.app.watchmanagerstub" + "com.samsung.android.ardrawing" + "com.samsung.android.aremoji" + "com.samsung.android.arzone" + "com.samsung.android.stickercenter" + "com.samsung.android.app.dressroom" + "com.samsung.android.forest" + "com.samsung.android.app.social" + "com.samsung.android.livestickers" + "com.samsung.android.app.sharelive" + + # Samsung Duplicates (use Google apps instead) + "com.samsung.android.email.provider" + "com.samsung.android.calendar" + "com.samsung.android.contacts" + "com.samsung.android.messaging" + "com.sec.android.app.sbrowser" + + # Facebook bloatware (pre-installed) + "com.facebook.katana" + "com.facebook.appmanager" + "com.facebook.services" + "com.facebook.system" + + # Microsoft bloatware + "com.microsoft.skydrive" + "com.microsoft.office.excel" + "com.microsoft.office.word" + "com.microsoft.office.powerpoint" + "com.linkedin.android" + + # Other Samsung bloat + "com.samsung.android.spay" + "com.samsung.android.samsungpass" + "com.samsung.android.authfw" + "com.samsung.android.kidsinstaller" + "com.samsung.android.app.camera.sticker.facearavatar.preload" +) + +# Huawei EMUI +HUAWEI_BLOAT=( + "com.huawei.hiview" + "com.huawei.himovie.overseas" + "com.huawei.music" + "com.huawei.appmarket" + "com.huawei.browser" + "com.huawei.hifolder" + "com.huawei.gameassistant" + "com.huawei.tips" + "com.huawei.hwid" + "com.huawei.wallet" + "com.huawei.health" + "com.huawei.hicloud" + "com.huawei.compass" + "com.huawei.mirrorlink" + "com.huawei.hicar" + "com.huawei.hiai" + "com.huawei.intelligent" + "com.huawei.parentcontrol" + "com.huawei.securitymgr" + + # Facebook + "com.facebook.katana" + "com.facebook.appmanager" + "com.facebook.services" + + # Booking + "com.booking" +) + +# Xiaomi MIUI +XIAOMI_BLOAT=( + "com.miui.analytics" + "com.miui.msa.global" + "com.miui.daemon" + "com.miui.hybrid" + "com.miui.yellowpage" + "com.miui.videoplayer" + "com.miui.player" + "com.miui.compass" + "com.miui.cleanmaster" + "com.miui.gallery" + "com.miui.weather2" + "com.miui.notes" + "com.miui.calculator" + "com.miui.mishare.connectivity" + "com.xiaomi.glgm" + "com.xiaomi.joyose" + "com.xiaomi.mipicks" + "com.xiaomi.midrop" + "com.mi.android.globalminusscreen" + "com.mi.android.globallauncher" + "com.mi.health" + + # Games + "com.miui.bugreport" + "cn.wps.xiaomi.abroad.lite" + + # Facebook + "com.facebook.katana" + "com.facebook.appmanager" + "com.facebook.services" + "com.facebook.system" +) + +# Oppo/Realme ColorOS +OPPO_BLOAT=( + "com.coloros.gamespace" + "com.coloros.weather" + "com.coloros.compass2" + "com.coloros.filemanager" + "com.coloros.floatassistant" + "com.coloros.gallery3d" + "com.coloros.video" + "com.coloros.music" + "com.coloros.smartdrive" + "com.heytap.browser" + "com.heytap.music" + "com.heytap.cloud" + "com.oppo.market" + + # Facebook + "com.facebook.katana" + "com.facebook.appmanager" + "com.facebook.services" +) + +# Motorola +MOTO_BLOAT=( + "com.motorola.help" + "com.motorola.demo" + "com.motorola.motocare" + "com.motorola.ccc.mainplm" + "com.motorola.android.providers.settings" + "com.motorola.actions" + "com.motorola.gamemode" + + # Facebook + "com.facebook.katana" + "com.facebook.appmanager" + "com.facebook.services" +) + +# Universal bloatware (all vendors) +UNIVERSAL_BLOAT=( + # Facebook (pre-installed em quase todos) + "com.facebook.katana" + "com.facebook.appmanager" + "com.facebook.services" + "com.facebook.system" + "com.facebook.orca" + + # Netflix (pre-installed) + "com.netflix.mediaclient" + "com.netflix.partner.activation" + + # Spotify (pre-installed) + "com.spotify.music" + + # TikTok + "com.zhiliaoapp.musically" + "com.ss.android.ugc.trill" + + # Games pre-instalados + "com.king.candycrushsaga" + "com.gameloft.android.ANMP.GloftA9HM" +) + +# ===================================================== +# FUNÇÕES +# ===================================================== + +uninstall_package() { + local pkg=$1 + echo -n " Removendo $pkg... " + + # Verificar se está instalado + if adb shell pm list packages | grep -q "^package:$pkg$"; then + if adb shell pm uninstall -k --user 0 "$pkg" 2>/dev/null | grep -q "Success"; then + echo -e "${GREEN}OK${NC}" + return 0 + else + echo -e "${YELLOW}Falhou (protegido)${NC}" + return 1 + fi + else + echo -e "${YELLOW}Não instalado${NC}" + return 0 + fi +} + +debloat_list() { + local name=$1 + shift + local packages=("$@") + + echo -e "\n${BLUE}=== Removendo $name bloatware ===${NC}\n" + + local removed=0 + local failed=0 + + for pkg in "${packages[@]}"; do + if uninstall_package "$pkg"; then + ((removed++)) + else + ((failed++)) + fi + done + + echo -e "\n${GREEN}$removed removidos${NC}, ${YELLOW}$failed protegidos${NC}" +} + +detect_vendor() { + local brand=$(echo "$BRAND" | tr '[:upper:]' '[:lower:]') + + case "$brand" in + samsung) + echo "samsung" + ;; + huawei|honor) + echo "huawei" + ;; + xiaomi|redmi|poco) + echo "xiaomi" + ;; + oppo|realme|oneplus) + echo "oppo" + ;; + motorola) + echo "moto" + ;; + *) + echo "unknown" + ;; + esac +} + +install_botos_launcher() { + echo -e "\n${BLUE}=== Instalando BotOS Launcher ===${NC}\n" + + local apk="../gen/android/app/build/outputs/apk/release/app-release.apk" + + if [[ -f "$apk" ]]; then + adb install -r "$apk" + echo -e "${GREEN}BotOS instalado!${NC}" + + # Definir como launcher padrão + echo "Para definir como launcher padrão:" + echo " 1. Pressione o botão Home" + echo " 2. Selecione 'BotOS' na lista" + echo " 3. Escolha 'Sempre'" + else + echo -e "${YELLOW}APK não encontrado. Compile primeiro:${NC}" + echo " cd .. && cargo tauri android build --release" + fi +} + +enable_kiosk_mode() { + echo -e "\n${BLUE}=== Configurando Kiosk Mode ===${NC}\n" + + # Desabilitar navegação por gestos + adb shell settings put global policy_control immersive.full=* + + # Esconder barra de navegação + adb shell settings put global policy_control immersive.navigation=* + + echo -e "${GREEN}Kiosk mode ativado!${NC}" + echo "O usuário não poderá sair do app facilmente." +} + +# ===================================================== +# MAIN +# ===================================================== + +VENDOR_ARG=${1:-auto} + +if [[ "$VENDOR_ARG" == "auto" ]]; then + VENDOR=$(detect_vendor) + echo -e "Fabricante detectado: ${GREEN}$VENDOR${NC}" +else + VENDOR=$VENDOR_ARG +fi + +echo "" +echo "Opções:" +echo " 1) Debloat leve (apenas Facebook/bloat universal)" +echo " 2) Debloat médio (+ apps do fabricante duplicados)" +echo " 3) Debloat agressivo (remove TUDO do fabricante)" +echo " 4) Instalar BotOS e configurar launcher" +echo " 5) Ativar Kiosk Mode (travar no BotOS)" +echo " 6) Executar tudo (2 + 4 + 5)" +echo "" +read -p "Escolha [1-6]: " CHOICE + +case $CHOICE in + 1) + debloat_list "Universal" "${UNIVERSAL_BLOAT[@]}" + ;; + 2) + debloat_list "Universal" "${UNIVERSAL_BLOAT[@]}" + case $VENDOR in + samsung) debloat_list "Samsung" "${SAMSUNG_BLOAT[@]}" ;; + huawei) debloat_list "Huawei" "${HUAWEI_BLOAT[@]}" ;; + xiaomi) debloat_list "Xiaomi" "${XIAOMI_BLOAT[@]}" ;; + oppo) debloat_list "Oppo/Realme" "${OPPO_BLOAT[@]}" ;; + moto) debloat_list "Motorola" "${MOTO_BLOAT[@]}" ;; + esac + ;; + 3) + debloat_list "Universal" "${UNIVERSAL_BLOAT[@]}" + debloat_list "Samsung" "${SAMSUNG_BLOAT[@]}" + debloat_list "Huawei" "${HUAWEI_BLOAT[@]}" + debloat_list "Xiaomi" "${XIAOMI_BLOAT[@]}" + debloat_list "Oppo/Realme" "${OPPO_BLOAT[@]}" + debloat_list "Motorola" "${MOTO_BLOAT[@]}" + ;; + 4) + install_botos_launcher + ;; + 5) + enable_kiosk_mode + ;; + 6) + debloat_list "Universal" "${UNIVERSAL_BLOAT[@]}" + case $VENDOR in + samsung) debloat_list "Samsung" "${SAMSUNG_BLOAT[@]}" ;; + huawei) debloat_list "Huawei" "${HUAWEI_BLOAT[@]}" ;; + xiaomi) debloat_list "Xiaomi" "${XIAOMI_BLOAT[@]}" ;; + oppo) debloat_list "Oppo/Realme" "${OPPO_BLOAT[@]}" ;; + moto) debloat_list "Motorola" "${MOTO_BLOAT[@]}" ;; + esac + install_botos_launcher + enable_kiosk_mode + ;; + *) + echo "Opção inválida" + exit 1 + ;; +esac + +echo "" +echo -e "${GREEN}╔══════════════════════════════════════════════════════════════╗${NC}" +echo -e "${GREEN}║ Debloat concluído! ║${NC}" +echo -e "${GREEN}╚══════════════════════════════════════════════════════════════╝${NC}" +echo "" +echo "Reinicie o dispositivo para aplicar todas as mudanças:" +echo " adb reboot" diff --git a/scripts/create-bootanimation.sh b/scripts/create-bootanimation.sh new file mode 100755 index 0000000..cfdffad --- /dev/null +++ b/scripts/create-bootanimation.sh @@ -0,0 +1,116 @@ +#!/bin/bash +# Create Android boot animation from gb-bot.svg +# +# Boot animation format: +# - bootanimation.zip containing: +# - desc.txt (animation descriptor) +# - part0/, part1/ (frame folders with PNG images) +# +# To install (requires root): +# adb root +# adb push bootanimation.zip /system/media/bootanimation.zip +# adb reboot + +set -e +cd "$(dirname "$0")/.." + +SVG_FILE="icons/gb-bot.svg" +OUTPUT_DIR="bootanimation" +BOOT_ZIP="bootanimation.zip" + +# Animation settings +WIDTH=1080 +HEIGHT=1920 +FPS=30 +LOOP_COUNT=0 # 0 = infinite + +echo "Creating boot animation from $SVG_FILE..." + +# Check for required tools +if ! command -v rsvg-convert &> /dev/null; then + echo "ERROR: rsvg-convert not found!" + echo "Install with: sudo apt install librsvg2-bin" + exit 1 +fi + +if ! command -v convert &> /dev/null; then + echo "ERROR: ImageMagick convert not found!" + echo "Install with: sudo apt install imagemagick" + exit 1 +fi + +# Clean and create directories +rm -rf "$OUTPUT_DIR" +mkdir -p "$OUTPUT_DIR/part0" +mkdir -p "$OUTPUT_DIR/part1" + +# Generate base icon (centered, large) +ICON_SIZE=400 +rsvg-convert -w $ICON_SIZE -h $ICON_SIZE "$SVG_FILE" -o "$OUTPUT_DIR/icon_base.png" + +# Create background (dark theme matching GB branding) +convert -size ${WIDTH}x${HEIGHT} xc:'#1a1a2e' "$OUTPUT_DIR/background.png" + +# Part 0: Static logo appear (fade in effect via multiple frames) +echo "Generating part0 (fade in)..." +for i in $(seq 0 9); do + opacity=$((i * 10 + 10)) + frame=$(printf "%05d" $i) + + # Composite icon on background with opacity + convert "$OUTPUT_DIR/background.png" \ + \( "$OUTPUT_DIR/icon_base.png" -channel A -evaluate multiply $(echo "scale=2; $opacity/100" | bc) +channel \) \ + -gravity center -composite \ + "$OUTPUT_DIR/part0/${frame}.png" +done + +# Part 1: Pulsing animation (loop) +echo "Generating part1 (pulse loop)..." +for i in $(seq 0 29); do + frame=$(printf "%05d" $i) + + # Calculate scale for pulse effect (subtle) + scale=$(echo "scale=4; 1 + 0.05 * s($i * 3.14159 / 15)" | bc -l) + new_size=$(echo "scale=0; $ICON_SIZE * $scale / 1" | bc) + + # Resize icon for pulse effect + convert "$OUTPUT_DIR/icon_base.png" \ + -resize ${new_size}x${new_size} \ + "$OUTPUT_DIR/icon_pulse.png" + + # Composite on background + convert "$OUTPUT_DIR/background.png" \ + "$OUTPUT_DIR/icon_pulse.png" \ + -gravity center -composite \ + "$OUTPUT_DIR/part1/${frame}.png" +done + +# Create desc.txt +cat > "$OUTPUT_DIR/desc.txt" << EOF +$WIDTH $HEIGHT $FPS +p 1 0 part0 +p $LOOP_COUNT 0 part1 +EOF + +# Create bootanimation.zip +echo "Creating $BOOT_ZIP..." +cd "$OUTPUT_DIR" +zip -r0 "../$BOOT_ZIP" desc.txt part0 part1 +cd .. + +# Cleanup +rm -f "$OUTPUT_DIR/icon_base.png" "$OUTPUT_DIR/icon_pulse.png" "$OUTPUT_DIR/background.png" + +echo "" +echo "=========================================" +echo "Boot animation created: $BOOT_ZIP" +echo "=========================================" +echo "" +echo "To install (requires rooted device):" +echo " adb root" +echo " adb remount" +echo " adb push $BOOT_ZIP /system/media/bootanimation.zip" +echo " adb reboot" +echo "" +echo "Or for testing:" +echo " adb shell bootanimation" diff --git a/scripts/generate-icons.sh b/scripts/generate-icons.sh new file mode 100755 index 0000000..fd4bc41 --- /dev/null +++ b/scripts/generate-icons.sh @@ -0,0 +1,50 @@ +#!/bin/bash +# Generate Android icons from SVG +# Requires: inkscape or rsvg-convert + +set -e +cd "$(dirname "$0")/.." + +SVG_FILE="icons/gb-bot.svg" +ICON_DIR="icons" + +# Android icon sizes +declare -A SIZES=( + ["mdpi"]=48 + ["hdpi"]=72 + ["xhdpi"]=96 + ["xxhdpi"]=144 + ["xxxhdpi"]=192 +) + +echo "Generating Android icons from $SVG_FILE..." + +# Main icon (512x512 for store) +if command -v rsvg-convert &> /dev/null; then + rsvg-convert -w 512 -h 512 "$SVG_FILE" -o "$ICON_DIR/icon.png" + echo "Created icon.png (512x512)" + + # Generate density-specific icons + for density in "${!SIZES[@]}"; do + size=${SIZES[$density]} + mkdir -p "$ICON_DIR/$density" + rsvg-convert -w $size -h $size "$SVG_FILE" -o "$ICON_DIR/$density/ic_launcher.png" + echo "Created $density/ic_launcher.png (${size}x${size})" + done +elif command -v inkscape &> /dev/null; then + inkscape -w 512 -h 512 "$SVG_FILE" -o "$ICON_DIR/icon.png" + echo "Created icon.png (512x512)" + + for density in "${!SIZES[@]}"; do + size=${SIZES[$density]} + mkdir -p "$ICON_DIR/$density" + inkscape -w $size -h $size "$SVG_FILE" -o "$ICON_DIR/$density/ic_launcher.png" + echo "Created $density/ic_launcher.png (${size}x${size})" + done +else + echo "ERROR: Neither rsvg-convert nor inkscape found!" + echo "Install with: sudo apt install librsvg2-bin" + exit 1 +fi + +echo "Done! Icons generated in $ICON_DIR/" diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..6862936 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,77 @@ +//! BotOS - Android launcher powered by General Bots +//! +//! Minimal Android OS replacement using Tauri + botui +//! - Replaces default launcher (home screen) +//! - Access to camera, GPS, notifications +//! - Connects to General Bots server + +use tauri::Manager; + +#[cfg(target_os = "android")] +fn init_logger() { + android_logger::init_once( + android_logger::Config::default() + .with_max_level(log::LevelFilter::Info) + .with_tag("BotOS"), + ); +} + +#[cfg(not(target_os = "android"))] +fn init_logger() { + env_logger::init(); +} + +/// Tauri command: Get device info +#[tauri::command] +fn get_device_info() -> serde_json::Value { + serde_json::json!({ + "platform": "android", + "app": "BotOS", + "version": env!("CARGO_PKG_VERSION") + }) +} + +/// Tauri command: Send message to bot server +#[tauri::command] +async fn send_to_bot(message: String, server_url: String) -> Result { + let client = reqwest::Client::new(); + + let response = client + .post(&format!("{}/api/messages", server_url)) + .json(&serde_json::json!({ "text": message })) + .send() + .await + .map_err(|e| e.to_string())?; + + response.text().await.map_err(|e| e.to_string()) +} + +#[cfg_attr(mobile, tauri::mobile_entry_point)] +pub fn run() { + init_logger(); + log::info!("BotOS starting..."); + + tauri::Builder::default() + .plugin(tauri_plugin_dialog::init()) + .plugin(tauri_plugin_opener::init()) + .plugin(tauri_plugin_notification::init()) + .plugin(tauri_plugin_http::init()) + .plugin(tauri_plugin_geolocation::init()) + .invoke_handler(tauri::generate_handler![ + get_device_info, + send_to_bot + ]) + .setup(|app| { + log::info!("BotOS initialized, loading botui..."); + + #[cfg(debug_assertions)] + { + let window = app.get_webview_window("main").unwrap(); + window.open_devtools(); + } + + Ok(()) + }) + .run(tauri::generate_context!()) + .expect("error running BotOS"); +} diff --git a/tauri.conf.json b/tauri.conf.json new file mode 100644 index 0000000..c9a0450 --- /dev/null +++ b/tauri.conf.json @@ -0,0 +1,45 @@ +{ + "$schema": "https://schema.tauri.app/config/2", + "productName": "BotOS", + "version": "1.0.0", + "identifier": "br.com.pragmatismo.botos", + "build": { + "beforeDevCommand": "", + "beforeBuildCommand": "", + "frontendDist": "../botui/ui/suite" + }, + "app": { + "security": { + "csp": null + }, + "windows": [ + { + "title": "BotOS", + "fullscreen": true, + "resizable": false + } + ] + }, + "bundle": { + "active": true, + "targets": ["apk", "aab"], + "android": { + "minSdkVersion": 24 + }, + "icon": [ + "icons/icon.png" + ] + }, + "plugins": { + "notification": { + "enabled": true + }, + "http": { + "enabled": true, + "scope": ["https://**", "http://**"] + }, + "geolocation": { + "enabled": true + } + } +}