Skip to content

Commit

Permalink
Add self-implemented permission
Browse files Browse the repository at this point in the history
Although using runtime permission from Android is perfect enough, it still have two "problems":

1. MIUI (or maybe more OEMs) breaks custom runtime permission, users can only change Shizuku permission from Shizuku app
2. Possible system bug (#83)
  • Loading branch information
RikkaW committed Jan 9, 2021
1 parent e214511 commit 1a34716
Show file tree
Hide file tree
Showing 33 changed files with 953 additions and 145 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ void registerUidObserver(IUidObserver observer, int which, int cutpoint, String
void forceStopPackage(String packageName, int userId)
throws RemoteException;

int startActivityAsUser(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho,
int requestCode, int flags, ProfilerInfo profilerInfo,
Bundle options, int userId)
throws RemoteException;

@RequiresApi(26)
abstract class Stub extends Binder implements IActivityManager {

Expand Down
13 changes: 12 additions & 1 deletion manager/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,18 @@
<activity
android:name=".starter.StarterActivity"
android:label="@string/starter" />
<activity
android:name=".authorization.RequestPermissionActivity"
android:directBootAware="true"
android:excludeFromRecents="true"
android:exported="true"
android:permission="android.permission.INTERACT_ACROSS_USERS_FULL"
android:theme="@style/GrantPermissions">
<intent-filter>
<action android:name="${applicationId}.intent.action.REQUEST_PERMISSION" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>

<activity
android:name=".legacy.LegacyIsNotSupportedActivity"
Expand All @@ -64,7 +76,6 @@
android:theme="@style/GrantPermissions">
<intent-filter>
<action android:name="${applicationId}.intent.action.REQUEST_AUTHORIZATION" />

<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ class ShizukuApplication : Application() {
LocaleDelegate.defaultLocale = ShizukuSettings.getLocale()
DayNightDelegate.setApplicationContext(context)
DayNightDelegate.setDefaultNightMode(ShizukuSettings.getNightMode())
AuthorizationManager.init(context)
}

override fun onCreate() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,46 +1,42 @@
package moe.shizuku.manager.authorization;

import android.content.Context;
import android.content.pm.PackageInfo;

import java.util.ArrayList;
import java.util.List;

public class AuthorizationManager {

private static final AuthorizationManagerImpl IMPL;

static {
IMPL = new AuthorizationManagerImplV23();
}

public static void init(Context context) {
IMPL.init(context);
}

public static boolean granted(String packageName, int uid) {
return IMPL.granted(packageName, uid);
}

public static void revoke(String packageName, int uid) {
IMPL.revoke(packageName, uid);
package moe.shizuku.manager.authorization

import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.os.Process
import moe.shizuku.api.ShizukuService
import moe.shizuku.manager.Manifest
import moe.shizuku.manager.utils.ShizukuSystemApis
import java.util.*

object AuthorizationManager {

private const val FLAG_ALLOWED = 1 shl 1
private const val FLAG_DENIED = 1 shl 2
private const val MASK_PERMISSION = FLAG_ALLOWED or FLAG_DENIED

fun getPackages(pmFlags: Int): List<PackageInfo> {
val packages: MutableList<PackageInfo> = ArrayList()
for (pi in ShizukuSystemApis.getInstalledPackages(pmFlags or PackageManager.GET_PERMISSIONS, Process.myUid() / 100000)) {
if (pi.requestedPermissions == null) continue
for (p in pi.requestedPermissions) {
if (Manifest.permission.API_V23 == p) {
packages.add(pi)
break
}
}
}
return packages
}

public static void grant(String packageName, int uid) {
IMPL.grant(packageName, uid);
fun granted(packageName: String, uid: Int): Boolean {
return (ShizukuService.getFlagsForUid(uid, MASK_PERMISSION) and FLAG_ALLOWED) == FLAG_ALLOWED
}

public static List<PackageInfo> getPackages(int pmFlags) {
return IMPL.getPackages(pmFlags);
fun grant(packageName: String, uid: Int) {
ShizukuService.updateFlagsForUid(uid, MASK_PERMISSION, FLAG_ALLOWED)
}

public static List<PackageInfo> getGrantedPackages(int pmFlags) {
List<PackageInfo> packages = new ArrayList<>();
for (PackageInfo pi : IMPL.getPackages(pmFlags)) {
if (granted(pi.packageName, pi.applicationInfo.uid)) {
packages.add(pi);
}
}
return packages;
fun revoke(packageName: String, uid: Int) {
ShizukuService.updateFlagsForUid(uid, MASK_PERMISSION, 0)
}
}
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package moe.shizuku.manager.authorization

import android.app.Dialog
import android.content.pm.ApplicationInfo
import android.os.Bundle
import androidx.appcompat.app.AlertDialog
import moe.shizuku.api.ShizukuApiConstants.REQUEST_PERMISSION_REPLY_ALLOWED
import moe.shizuku.api.ShizukuApiConstants.REQUEST_PERMISSION_REPLY_IS_ONETIME
import moe.shizuku.api.ShizukuService
import moe.shizuku.manager.R
import moe.shizuku.manager.app.AppActivity
import moe.shizuku.manager.databinding.ConfirmationDialogBinding
import moe.shizuku.manager.utils.Logger.LOGGER
import rikka.html.text.HtmlCompat

class RequestPermissionActivity : AppActivity() {

private lateinit var dialog: Dialog

private fun setResult(requestUid: Int, requestPid: Int, requestCode: Int, allowed: Boolean, onetime: Boolean) {
val data = Bundle()
data.putBoolean(REQUEST_PERMISSION_REPLY_ALLOWED, allowed)
data.putBoolean(REQUEST_PERMISSION_REPLY_IS_ONETIME, onetime)
try {
ShizukuService.dispatchPermissionConfirmationResult(requestUid, requestPid, requestCode, data)
} catch (e: Throwable) {
LOGGER.e("dispatchPermissionConfirmationResult")
}
}

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

val uid = intent.getIntExtra("uid", -1)
val pid = intent.getIntExtra("pid", -1)
val requestCode = intent.getIntExtra("requestCode", -1)
val ai = intent.getParcelableExtra<ApplicationInfo>("applicationInfo")
if (uid == -1 || pid == -1 || ai == null) {
return
}

val label = try {
ai.loadLabel(packageManager)
} catch (e: Exception) {
ai.packageName
}

val binding = ConfirmationDialogBinding.inflate(layoutInflater).apply {
button1.setOnClickListener {
setResult(uid, pid, requestCode, allowed = true, onetime = false)
dialog.dismiss()
}
button3.setOnClickListener {
setResult(uid, pid, requestCode, allowed = false, onetime = true)
dialog.dismiss()
}
title.text = HtmlCompat.fromHtml(getString(R.string.permission_warning_template,
label, getString(R.string.permission_group_description)))
}

dialog = AlertDialog.Builder(this)
.setView(binding.root)
.setCancelable(false)
.setOnDismissListener { finish() }
.create()
dialog.setCanceledOnTouchOutside(false)
dialog.show()
}
}
67 changes: 67 additions & 0 deletions manager/src/main/res/layout/confirmation_dialog.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center"
android:layout_marginTop="24dp"
android:importantForAccessibility="no"
android:src="@drawable/ic_permission_24dp"
android:tint="?android:colorAccent"
android:tintMode="src_in" />

<TextView
android:id="@android:id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:paddingStart="24dp"
android:paddingTop="8dp"
android:paddingEnd="24dp"
android:paddingBottom="16dp"
android:textColor="?android:textColorPrimary"
android:textSize="20sp"
tools:text="@string/permission_warning_template" />

<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?android:dividerVertical" />

<TextView
android:id="@android:id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:selectableItemBackground"
android:fontFamily="sans-serif-medium"
android:gravity="center"
android:minHeight="56dp"
android:padding="16dp"
android:text="@string/grant_dialog_button_allow_always"
android:textColor="?android:colorAccent"
android:textSize="14sp" />

<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?android:dividerVertical" />

<TextView
android:id="@android:id/button3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:selectableItemBackground"
android:fontFamily="sans-serif-medium"
android:gravity="center"
android:minHeight="56dp"
android:padding="16dp"
android:text="@string/grant_dialog_button_deny"
android:textColor="?android:colorAccent"
android:textSize="14sp" />

</LinearLayout>
3 changes: 3 additions & 0 deletions manager/src/main/res/values-de/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,7 @@
<string name="dialog_adb_discovery_message">Bitte Wireless Debugging in Entwickleroptionen aktivieren. Wireless Debugging wird automatisch deaktiviert, wenn sich das Netzwerk ändert.
\n
\nHinweis: Deaktivieren Sie die Entwickleroptionen oder USB-Debugging nicht, oder Shizuku wird gestoppt.</string>
<string name="grant_dialog_button_allow_always">Immer zulassen</string>
<string name="grant_dialog_button_deny">Ablehnen</string>
<string name="permission_warning_template"><![CDATA[Zulassen, dass die App &lt;b&gt;%1$s&lt;/b&gt; Folgendes darf: %2$s?]]></string>
</resources>
3 changes: 3 additions & 0 deletions manager/src/main/res/values-ja/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,7 @@
<string name="home_status_service_is_running">%1$s 実行中</string>
<string name="home_adb_dialog_view_command_copy_button">コピー</string>
<string name="home_adb_title">コンピュータに接続して開始する</string>
<string name="grant_dialog_button_allow_always">常に許可</string>
<string name="grant_dialog_button_deny">許可しない</string>
<string name="permission_warning_template"><![CDATA[&lt;b&gt;%1$s&lt;/b&gt; に「%2$s」を許可しますか?]]></string>
</resources>
7 changes: 4 additions & 3 deletions manager/src/main/res/values-ko/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,7 @@
<string name="notification_channel_service_status">서비스 시작 상태</string>
<string name="notification_service_starting">Shizuku 서비스가 시작 중입니다…</string>
<string name="settings_user_interface">화면</string>
<string name="permission_label">상위 권한으로 시스템 API 접근</string>
<string name="permission_group_description">Shizuku에 접근</string>
<string name="permission_label">Shizuku에 접근</string>
<string name="notification_service_start_no_root">루트 권한을 요청하지 못했습니다.</string>
<string name="settings_start_on_boot">부팅 시 시작 (루트)</string>
<string name="settings_start_on_boot_summary">루트된 기기에서 Shizuku는 부팅 시 자동으로 시작할 수 있음</string>
Expand All @@ -82,11 +81,13 @@
<string name="home_status_service_version">%1$s, 버전 %2$d</string>
<string name="home_adb_description">루트 없이 Shizuku를 시작하기 위해 adb가 필요합니다. (컴퓨터 연결 필수) 이 작업은 다시 시작 시 마다 필요로 합니다. 자세한 정보는 &lt;b&gt;&lt;a href=\"%1$s\"&gt;도움말&lt;/a&gt;&lt;/b&gt;을 확인하세요.</string>
<string name="home_wireless_adb_description">안드로이드 11부터, 무선 디버깅은 기본으로 제공되는 기능입니다. &lt;b&gt;&lt;a href=\"%1$s\"&gt;도움말&lt;/a&gt;&lt;/b&gt;를 참조하세요.&lt;p&gt;모든 시스템 버전에서 작동하나, 안드로이드 11 이전은 무선 디버깅을 직접 사용 설정할 수 없습니다.</string>
<string name="permission_description">상위 권한으로 시스템 API를 사용할 수 있도록 허용합니다.</string>
<string name="home_status_service_version_update">%1$s, 버전 %2$d&lt;br&gt;다시 시작하여 버전 %3$d로 업데이트</string>
<string name="app_management_dialog_adb_is_limited_title">ADB의 권한이 제한됨</string>
<string name="app_management_dialog_adb_is_limited_message">높은 가능성으로, 기기 제조사에서 ADB의 권한을 제한한 것 입니다.&lt;p&gt;&lt;b&gt;&lt;a href=\"%1$s\"&gt;문서&lt;/a&gt;&lt;/b&gt;에 시스템에 대한 해결 방안이 있을 수 있습니다.</string>
<string name="dialog_legacy_not_support_title">%1$s는 지금의 Shizuku를 지원하지 않음</string>
<string name="dialog_legacy_not_support_message">구형 Shizuku는 2019년 3월에 지원이 중단되었습니다. 또한, 구형 Shizuku는 새로운 안드로이드 시스템에서 동작하지 않습니다.&lt;p&gt;업데이트하려면 &lt;b&gt;%1$s&lt;/b&gt; 개발자에게 확인하세요.</string>
<string name="dialog_requesting_legacy_message">&lt;b&gt;%1$s&lt;/b&gt;는 지금의 Shizuku를 지원하나, 구형 Shizuku를 요청하고 있습니다. Shizuku가 실행 중이지 않아서 발생할 수 있는 문제로, Shizuku 앱에서 확인하세요.&lt;p&gt;구형 Shizuku는 2019년 3월 부터 지원이 중단되었습니다.</string>
<string name="grant_dialog_button_allow_always">항상 허용</string>
<string name="grant_dialog_button_deny">거부</string>
<string name="permission_warning_template"><![CDATA[&lt;b&gt;%1$s&lt;/b&gt;에서 %2$s하도록 허용하시겠습니까?]]></string>
</resources>
5 changes: 4 additions & 1 deletion manager/src/main/res/values-pl/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@
<string name="home_adb_button_view_help">Przeczytaj pomoc</string>
<string name="toast_copied_to_clipboard">%s
\nzostał skopiowany do schowka.</string>
<string name="permission_group_description">Dostęp Shizuku</string>
<string name="notification_working">Działa…</string>
<string name="notification_service_start_failed">Błąd przy starcie usługi Shizuku.</string>
<string name="settings_startup">Rozruch</string>
Expand All @@ -54,4 +53,8 @@
<string name="dialog_adb_discovery_message">Proszę włączyć \"Debugowanie bezprzewodowe\" w \"Ustawieniach developerskich\". Debugowanie bezprzewodowe jest automatycznie wyłączane gdy przełączasz się między sieciami.
\n
\nNIE wyłączaj \"Ustawień developerskich\" lub \" Debugowania USB\" ponieważ jest wymagane do prawidłowego działania Shizuku.</string>
<string name="permission_label">Dostęp Shizuku</string>
<string name="grant_dialog_button_allow_always">Zawsze zezwalaj</string>
<string name="grant_dialog_button_deny">Odmów</string>
<string name="permission_warning_template"><![CDATA[Zezwolić aplikacji &lt;b&gt;%1$s&lt;/b&gt; na: %2$s?]]></string>
</resources>
Loading

0 comments on commit 1a34716

Please sign in to comment.