Skip to content

Commit

Permalink
Merge branch 'xWTF-master'
Browse files Browse the repository at this point in the history
  • Loading branch information
aistra0528 committed Apr 5, 2024
2 parents 705582b + ebd5d16 commit a27b7fc
Show file tree
Hide file tree
Showing 10 changed files with 154 additions and 21 deletions.
46 changes: 46 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,52 @@ Active admin set to component {com.aistra.hail/com.aistra.hail.receiver.DeviceAd

- `IPackageManager.setPackagesSuspendedAsUser`方法暂停应用。

### 特权系统应用 - 停用

此模式通过调用接口:

- `ActivityManager.forceStopPackage`强行停止应用。
- `PackageManager.setApplicationEnabledSetting`停用应用。

需要设置特许权限许可名单:

```xml
<?xml version="1.0" encoding="utf-8"?>
<permissions>
<privapp-permissions package="com.aistra.hail">
<permission name="android.permission.PACKAGE_USAGE_STATS"/>
<permission name="android.permission.FORCE_STOP_PACKAGES"/>
<permission name="android.permission.CHANGE_COMPONENT_ENABLED_STATE"/>
</privapp-permissions>
</permissions>
```

并将雹安装为特权系统应用。

推荐方法是在构建 ROM 时导入雹,`Android.bp`配置示例:

```bp
android_app_import {
name: "Hail",
apk: "Hail.apk",
privileged: true,
dex_preopt: {
enabled: false,
},
presigned: true,
preprocessed: true,
required: ["privapp-permissions_com.aistra.hail.xml"]
}
prebuilt_etc {
name: "privapp-permissions_com.aistra.hail.xml",
src: "privapp-permissions.xml",
sub_dir: "permissions",
}
```

## 恢复

### 通过 adb
Expand Down
46 changes: 46 additions & 0 deletions README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,52 @@ This mode invoke non-SDK interface:

- `IPackageManager.setPackagesSuspendedAsUser` to suspend apps.

### Privileged System App - Disable

This mode calls the following APIs:

- `ActivityManager.forceStopPackage` to kill apps.
- `PackageManager.setApplicationEnabledSetting` to disable apps.

The following privapp-permissions is required:

```xml
<?xml version="1.0" encoding="utf-8"?>
<permissions>
<privapp-permissions package="com.aistra.hail">
<permission name="android.permission.PACKAGE_USAGE_STATS"/>
<permission name="android.permission.FORCE_STOP_PACKAGES"/>
<permission name="android.permission.CHANGE_COMPONENT_ENABLED_STATE"/>
</privapp-permissions>
</permissions>
```

To use this mode, you should install Hail as a privileged system app.

The recommended approach is to import Hail when building your ROM, here's an example for `Android.bp`:

```bp
android_app_import {
name: "Hail",
apk: "Hail.apk",
privileged: true,
dex_preopt: {
enabled: false,
},
presigned: true,
preprocessed: true,
required: ["privapp-permissions_com.aistra.hail.xml"]
}
prebuilt_etc {
name: "privapp-permissions_com.aistra.hail.xml",
src: "privapp-permissions.xml",
sub_dir: "permissions",
}
```

## Revert

### By adb
Expand Down
5 changes: 5 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ android {
versionName = "1.8.1"
}

// Do not compress the dex files, so the apk can be imported as a privileged app
androidResources {
noCompress += "dex"
}

val signing = if (file("../signing.properties").exists()) {
signingConfigs.create("release") {
val props = `java.util`.Properties().apply { load(file("../signing.properties").reader()) }
Expand Down
6 changes: 6 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@
<uses-permission
android:name="android.permission.PACKAGE_USAGE_STATS"
tools:ignore="ProtectedPermissions"/>
<uses-permission
android:name="android.permission.FORCE_STOP_PACKAGES"
tools:ignore="ProtectedPermissions"/>
<uses-permission
android:name="android.permission.CHANGE_COMPONENT_ENABLED_STATE"
tools:ignore="ProtectedPermissions"/>
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<uses-permission android:name="com.oasisfeng.island.permission.FREEZE_PACKAGE"/>
<uses-permission android:name="com.oasisfeng.island.permission.SUSPEND_PACKAGE"/>
Expand Down
1 change: 1 addition & 0 deletions app/src/main/kotlin/com/aistra/hail/app/AppManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ object AppManager {
HailData.MODE_SHIZUKU_SUSPEND -> HShizuku.setAppSuspended(packageName, frozen)
HailData.MODE_ISLAND_HIDE -> HIsland.setAppHidden(packageName, frozen)
HailData.MODE_ISLAND_SUSPEND -> HIsland.setAppSuspended(packageName, frozen)
HailData.MODE_PRIVAPP_DISABLE -> HPackages.setAppDisabled(packageName, frozen)
else -> false
}

Expand Down
6 changes: 6 additions & 0 deletions app/src/main/kotlin/com/aistra/hail/app/HailData.kt
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,18 @@ object HailData {
const val KEY_FROZEN = "frozen"
const val WORKING_MODE = "working_mode"
const val MODE_DEFAULT = "default"

const val OWNER = "owner_"
const val DHIZUKU = "dhizuku_"
const val SU = "su_"
const val SHIZUKU = "shizuku_"
const val ISLAND = "island_"
const val PRIVAPP = "privapp_"

const val DISABLE = "disable"
const val HIDE = "hide"
const val SUSPEND = "suspend"

const val MODE_OWNER_HIDE = OWNER + HIDE
const val MODE_OWNER_SUSPEND = OWNER + SUSPEND
const val MODE_DHIZUKU_HIDE = DHIZUKU + HIDE
Expand All @@ -47,6 +51,8 @@ object HailData {
const val MODE_SHIZUKU_SUSPEND = SHIZUKU + SUSPEND
const val MODE_ISLAND_HIDE = ISLAND + HIDE
const val MODE_ISLAND_SUSPEND = ISLAND + SUSPEND
const val MODE_PRIVAPP_DISABLE = PRIVAPP + DISABLE

private const val TILE_ACTION = "tile_action"
private const val HOME_FONT_SIZE = "home_font_size"
const val DYNAMIC_SHORTCUT_ACTION = "dynamic_shortcut_action"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,7 @@ import android.content.Intent
import android.content.pm.PackageManager
import android.os.Bundle
import android.provider.Settings
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.view.*
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.content.res.AppCompatResources
import androidx.core.app.NotificationManagerCompat
Expand All @@ -27,22 +22,9 @@ import com.aistra.hail.app.AppManager
import com.aistra.hail.app.HailApi
import com.aistra.hail.app.HailData
import com.aistra.hail.databinding.DialogInputBinding
import com.aistra.hail.extensions.applyDefaultInsetter
import com.aistra.hail.extensions.isLandscape
import com.aistra.hail.extensions.isRtl
import com.aistra.hail.extensions.marginRelative
import com.aistra.hail.extensions.paddingRelative
import com.aistra.hail.extensions.*
import com.aistra.hail.ui.main.MainActivity
import com.aistra.hail.utils.AppIconCache
import com.aistra.hail.utils.HDhizuku
import com.aistra.hail.utils.HIsland
import com.aistra.hail.utils.HLog
import com.aistra.hail.utils.HPolicy
import com.aistra.hail.utils.HShell
import com.aistra.hail.utils.HShortcuts
import com.aistra.hail.utils.HSystem
import com.aistra.hail.utils.HTarget
import com.aistra.hail.utils.HUI
import com.aistra.hail.utils.*
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.textview.MaterialTextView
import com.rosan.dhizuku.api.Dhizuku
Expand Down Expand Up @@ -319,6 +301,11 @@ class SettingsFragment : PreferenceFragmentCompat(), Preference.OnPreferenceChan
HIsland.checkOwnerApp()
}
}

mode.startsWith(HailData.PRIVAPP) -> if (!HPackages.isPrivilegedApp(app.packageName)) {
HUI.showToast(R.string.permission_denied)
return false
}
}

return true
Expand Down
33 changes: 33 additions & 0 deletions app/src/main/kotlin/com/aistra/hail/utils/HPackages.kt
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package com.aistra.hail.utils

import android.app.ActivityManager
import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
import androidx.core.content.getSystemService
import com.aistra.hail.HailApp.Companion.app
import org.lsposed.hiddenapibypass.HiddenApiBypass

object HPackages {
val myUserId get() = android.os.Process.myUserHandle().hashCode()
Expand Down Expand Up @@ -48,6 +51,36 @@ object HPackages {
}
} ?: false

fun isPrivilegedApp(packageName: String): Boolean = getApplicationInfoOrNull(packageName)?.let {
(ApplicationInfo::class.java.getField("privateFlags").get(it) as Int) and 8 == 8
} ?: false

fun canUninstallNormally(packageName: String): Boolean =
getApplicationInfoOrNull(packageName)?.sourceDir?.startsWith("/data") ?: false

private fun forceStopApp(packageName: String) = runCatching {
app.getSystemService<ActivityManager>()!!.let {
if (HTarget.P) HiddenApiBypass.invoke(it::class.java, it, "forceStopPackage", packageName)
else it::class.java.getMethod("forceStopPackage", String::class.java).invoke(it, packageName)
}
true
}.getOrElse {
HLog.e(it)
false
}

fun setAppDisabled(packageName: String, disabled: Boolean): Boolean {
getApplicationInfoOrNull(packageName) ?: return false
if (disabled) forceStopApp(packageName)
runCatching {
val newState = when {
!disabled -> PackageManager.COMPONENT_ENABLED_STATE_ENABLED
else -> PackageManager.COMPONENT_ENABLED_STATE_DISABLED
}
app.packageManager.setApplicationEnabledSetting(packageName, newState, 0)
}.onFailure {
HLog.e(it)
}
return isAppDisabled(packageName) == disabled
}
}
2 changes: 2 additions & 0 deletions app/src/main/res/values/arrays.xml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
<item>@string/mode_owner_suspend</item>
<item>@string/mode_island_hide</item>
<item>@string/mode_island_suspend</item>
<item>@string/mode_privapp_disable</item>
</string-array>
<string-array name="working_mode_values">
<item>default</item>
Expand All @@ -58,6 +59,7 @@
<item>owner_suspend</item>
<item>island_hide</item>
<item>island_suspend</item>
<item>privapp_disable</item>
</string-array>
<string-array name="donate_payment_entries">
<item>@string/donate_alipay</item>
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
<string name="mode_shizuku_disable">Shizuku - Disable</string>
<string name="mode_shizuku_hide">Shizuku - Hide</string>
<string name="mode_shizuku_suspend">Shizuku - Suspend</string>
<string name="mode_privapp_disable">Privileged System App - Disable</string>
<string name="title_set_owner">Set Device Owner</string>
<string name="msg_set_owner">Issue the command from adb:\n%s</string>
<string name="title_remove_owner">Remove Device Owner</string>
Expand Down

0 comments on commit a27b7fc

Please sign in to comment.