﻿@echo off
rem 本文件是 UTF-8(带 BOM)，cmd 会自动按 UTF-8 读，不要加 chcp，加了反而会把行读歪
rem 有些电脑 PATH 不全，先把系统目录补上，免得 findstr / timeout 找不到
set "PATH=%SystemRoot%\System32;%SystemRoot%;%SystemRoot%\System32\Wbem;%PATH%"
setlocal EnableDelayedExpansion
title 一鹿成长 · 一键授权（电脑 ADB）
color 0B

echo ================================================================
echo   一鹿成长 · 一键授权
echo ----------------------------------------------------------------
echo   把这台电视 / 平板该给一鹿成长的系统权限一次授全：
echo     使用情况访问（统计各应用观看时长）
echo     显示在其他应用上层（锁屏盖在别的应用上面）
echo     后台不被省电清理（关机重启后守护还在）
echo     设备管理器（防止孩子强行停止）
echo     常驻通知（守护运行的那条通知）
echo     守护自愈（允许本应用自己恢复无障碍）
echo   只动一鹿成长自己的权限，没碰任何别的应用，随时可撤销。
echo   这就是 App 里「家长中心 - 更多设置 - 守护自检 - 用电脑授权」
echo   那一页上写的那只「一键授权.bat」。
echo ================================================================
echo.
echo 【开始之前】
echo   1. 设备上「设置 - 关于 - 版本号」连点 7 次，打开开发者选项
echo   2. 开发者选项里打开「USB 调试」（插数据线）
echo      或「网络调试 / ADB over network」（走局域网，Android 13 常见）
echo   3. 插线后设备会问「允许 USB 调试吗」，点「允许」（建议勾「始终允许」）
echo.
echo 提示：Android 13 起「通知」是单独一项权限，本脚本会一并打开；
echo       系统设置里没有「使用情况访问」入口的机型，也由本脚本代劳。
echo.

rem ---------- 找 adb ----------
set "ADB="
if exist "%~dp0adb.exe" set "ADB=%~dp0adb.exe"
if not defined ADB if exist "%~dp0platform-tools\adb.exe" set "ADB=%~dp0platform-tools\adb.exe"
if not defined ADB if exist "D:\Android\Sdk\platform-tools\adb.exe" set "ADB=D:\Android\Sdk\platform-tools\adb.exe"
if not defined ADB if defined ANDROID_HOME if exist "%ANDROID_HOME%\platform-tools\adb.exe" set "ADB=%ANDROID_HOME%\platform-tools\adb.exe"
if not defined ADB if defined ANDROID_SDK_ROOT if exist "%ANDROID_SDK_ROOT%\platform-tools\adb.exe" set "ADB=%ANDROID_SDK_ROOT%\platform-tools\adb.exe"
if not defined ADB if exist "%LOCALAPPDATA%\Android\Sdk\platform-tools\adb.exe" set "ADB=%LOCALAPPDATA%\Android\Sdk\platform-tools\adb.exe"
if not defined ADB for /f "delims=" %%i in ('where adb.exe 2^>nul') do if not defined ADB set "ADB=%%i"
if not defined ADB goto noadb
echo adb：!ADB!
"%ADB%" kill-server >nul 2>&1
"%ADB%" start-server >nul 2>&1
echo.

rem ---------- 找设备 ----------
call :scan
if !COUNT! gtr 0 goto pickdev
if !UNAUTH!==1 goto waitauth
goto askip

:waitauth
echo 设备还没授权。请在电视 / 平板的弹窗里点「允许」，正在等待（最多 60 秒）……
set /a TRY=0
:waitspin
set /a TRY+=1
if !TRY! gtr 20 goto askip
timeout /t 3 /nobreak >nul
call :scan
if !COUNT! gtr 0 goto pickdev
goto waitspin

:askip
echo 没有检测到通过数据线连接、且已授权的设备。
echo.
echo 如果你的电视 / 平板已打开「网络调试」，可以直接用局域网连：
echo   IP 在哪看：设置 - 关于 - 状态信息，或 设置 - 网络 - 有线网络
set "IP="
set /p "IP=请输入设备 IP（例如 192.168.1.23，直接回车放弃）: "
if not defined IP goto nosale
echo !IP! | find ":" >nul
if errorlevel 1 (set "TARGET=!IP!:5555") else (set "TARGET=!IP!")
echo 正在连接 !TARGET! ……
"%ADB%" connect !TARGET!
timeout /t 3 /nobreak >nul
call :scan
if !COUNT!==0 goto connfail
if !UNAUTH!==1 echo 设备上弹出了「允许调试吗」，请在设备上点「允许」。
if !UNAUTH!==1 timeout /t 6 /nobreak >nul
call :scan
if !COUNT!==0 goto connfail
goto pickdev

:connfail
echo.
echo × 连不上 !TARGET!。请检查：
echo   设备与电脑是否在同一个局域网（同一个路由器）
echo   设备「开发者选项 - 网络调试」是否真的打开
echo   部分电视的端口不是 5555，若你知道实际端口，请连「IP:端口」
echo   路由器是否开了「AP 隔离」（开了就互相 ping 不通，要关掉）
goto endfail

:pickdev
if !COUNT! gtr 1 goto manydev
set "SERIAL=!SERIAL1!"
goto haveone

:manydev
echo 检测到 !COUNT! 台设备：
"%ADB%" devices
echo 一次只处理一台：请拔掉其它设备，或直接输入要授权那台的序列号。
set "SERIAL="
set /p "SERIAL=序列号（上面第一列，回车放弃）: "
if not defined SERIAL goto endfail
goto haveone

:haveone
echo.
echo 使用设备：!SERIAL!
set "MODEL="
set "SDK="
for /f "delims=" %%i in ('"%ADB%" -s !SERIAL! shell getprop ro.product.model 2^>nul') do set "MODEL=%%i"
for /f "delims=" %%i in ('"%ADB%" -s !SERIAL! shell getprop ro.build.version.sdk 2^>nul') do set "SDK=%%i"
for /f "delims=" %%i in ('"%ADB%" -s !SERIAL! shell getprop ro.build.version.release 2^>nul') do set "REL=%%i"
echo 机型：!MODEL!  ·  Android !REL!（API !SDK!）
if "!SDK!"=="" goto endfail

rem ---------- 装了哪几个包 ----------
set "HASMAIN=0"
set "HASDEV=0"
"%ADB%" -s !SERIAL! shell pm path com.pinyalu.tv > "%TEMP%\pyl_p1.txt" 2>&1
findstr /C:"package:" "%TEMP%\pyl_p1.txt" >nul
if not errorlevel 1 set "HASMAIN=1"
"%ADB%" -s !SERIAL! shell pm path com.pinyalu.tv.dev > "%TEMP%\pyl_p2.txt" 2>&1
findstr /C:"package:" "%TEMP%\pyl_p2.txt" >nul
if not errorlevel 1 set "HASDEV=1"
if !HASMAIN!==1 goto showpkgs
if !HASDEV!==1 goto showpkgs
goto notinstalled

:showpkgs
if !HASMAIN!==1 echo √ 正式版一鹿成长（com.pinyalu.tv）已安装
if !HASDEV!==1 echo √ 测试版一鹿成长（com.pinyalu.tv.dev）已安装
echo.
set "OKS=0"
set "FAILS=0"
if !HASMAIN!==1 call :grantAll "com.pinyalu.tv" "com.pinyalu.tv/com.pinyalu.tv.guard.AdminReceiver" "正式版"
if !HASDEV!==1 call :grantAll "com.pinyalu.tv.dev" "com.pinyalu.tv.dev/com.pinyalu.tv.guard.AdminReceiver" "测试版"
goto summary

rem ================================================================
rem  子过程：对同一个包依次授权
rem ================================================================
:grantAll
set "PKG=%~1"
set "ADMIN=%~2"
set "TAG=%~3"
echo ---------- !TAG!（!PKG!）----------
call :step SECURE "pm grant !PKG! android.permission.WRITE_SECURE_SETTINGS"
call :step USAGE "appops set !PKG! GET_USAGE_STATS allow"
call :step OVERLAY "appops set !PKG! SYSTEM_ALERT_WINDOW allow"
call :step IDLE "dumpsys deviceidle whitelist +!PKG!"
call :step ADMIN "dpm set-active-admin !ADMIN!"
if !SDK! GEQ 33 call :step NOTIFY "pm grant !PKG! android.permission.POST_NOTIFICATIONS"
echo.
exit /b 0

:step
set "CODE=%~1"
set "CMD=%~2"
set "LABEL="
if "%CODE%"=="SECURE" set "LABEL=守护自愈（允许本应用自己恢复无障碍）"
if "%CODE%"=="USAGE" set "LABEL=使用情况访问（统计各应用观看时长）"
if "%CODE%"=="OVERLAY" set "LABEL=显示在其他应用上层（锁屏盖在最上面）"
if "%CODE%"=="IDLE" set "LABEL=后台不被省电清理"
if "%CODE%"=="ADMIN" set "LABEL=设备管理器（防止强行停止）"
if "%CODE%"=="NOTIFY" set "LABEL=常驻通知（Android 13 起需单独授权）"
"%ADB%" -s !SERIAL! shell !CMD! > "%TEMP%\pyl_step.txt" 2>&1
set "GOOD=0"
findstr /I /C:"Success" /C:"already" "%TEMP%\pyl_step.txt" >nul
if not errorlevel 1 set "GOOD=1"
set "BAD=0"
findstr /I /C:"Exception" /C:"Error:" /C:"Permission denial" /C:"not a changeable" /C:"Unknown" "%TEMP%\pyl_step.txt" >nul
if not errorlevel 1 set "BAD=1"
if !GOOD!==1 set "BAD=0"
if !BAD!==1 (
    echo   [未成功] !LABEL!
    echo            命令：!CMD!
    type "%TEMP%\pyl_step.txt"
    set /a FAILS+=1
) else (
    echo   [完成] !LABEL!
    set /a OKS+=1
)
exit /b 0

rem ================================================================
:summary
echo ================================================================
echo   本次结果：成功 !OKS! 项，未成功 !FAILS! 项
echo ================================================================
if !FAILS! GTR 0 goto somefail
echo 全部授权完成。现在到设备上：
echo   一鹿成长 - 家长中心 - 更多设置 - 守护自检，点右下「我已执行，重新检测」
echo   几项变绿之后，再打开「禁止卸载一鹿成长」和「按时锁屏」就齐了。
echo.
echo 说明：
echo   · 设备管理器已挂上，孩子从系统设置里「强行停止」会被拦；
echo   · 省电白名单已加，重启后守护能自己回来；
echo   · 「禁止卸载」还差最后一步：若要做成系统级防卸载（设备所有者），
echo     请再运行同目录的「开启平板防卸载.ps1」（要求设备上没有登录任何账号）。
goto endok

:somefail
echo 有几步没成功，多数是机型限制，不影响主要功能：
echo   · 「设备管理器」失败：常见于已绑定厂商账号的机器，可在
echo     设置 - 安全 - 设备管理应用 里手动勾选一鹿成长；
echo   · 「使用情况访问」失败：去 设置 - 应用 - 特殊应用权限 - 使用情况访问，
echo     把一鹿成长打开（Android 13 部分机型藏在这里）；
echo   · 「显示在其他应用上层」失败：去 设置 - 应用 - 特殊应用权限 - 显示在其他应用上层；
echo   · 「常驻通知」失败：去 设置 - 应用 - 一鹿成长 - 通知，允许通知；
echo   · 其余项失败可把上面的原始输出截图发我，我按机型再调。
echo.
echo 所有失败项都可以在系统设置里手动补，不影响已经成功的部分。
goto endok

:noadb
echo × 没找到 adb.exe（Android 调试工具）。
echo   解决：把本 bat 放进「platform-tools」文件夹（和 adb.exe 同一个目录）再双击；
echo         或先装 Android SDK Platform-Tools，装完再双击本 bat。
goto endfail

:nosale
echo.
echo × 没有可用的设备，先不授权了。
echo   插数据线：开发者选项里打开「USB 调试」，设备弹窗点「允许」；
echo   走局域网：开发者选项里打开「网络调试」，记下设备 IP 后重跑本 bat 并输入 IP。
goto endfail

:notinstalled
echo × 这台设备上还没装一鹿成长（正式版和测试版都没找到）。
echo   先把 APK 装上（同目录里的「一鹿成长-V1.0.x-正式签名版.apk」取最新那个），再重跑本 bat。
echo   注意：APK 要在设备上点开安装，或用 adb install -r 装。
goto endfail

:endok
echo.
pause
exit /b 0

:endfail
echo.
pause
exit /b 1

rem ---------- 扫描当前连接的、已授权设备 ----------
:scan
set "COUNT=0"
set "SERIAL1="
set "SERIAL2="
set "UNAUTH=0"
for /f "skip=1 tokens=1,2" %%a in ('"%ADB%" devices 2^>nul') do (
    if /i "%%b"=="device" (
        set /a COUNT+=1
        if !COUNT!==1 set "SERIAL1=%%a"
        if !COUNT!==2 set "SERIAL2=%%a"
    )
    if /i "%%b"=="unauthorized" set "UNAUTH=1"
    if /i "%%b"=="offline" set "UNAUTH=1"
)
exit /b 0
