diff options
| author | Tyler Nijmeh <tylernij@gmail.com> | 2021-03-30 19:43:10 -0700 |
|---|---|---|
| committer | Tyler Nijmeh <tylernij@gmail.com> | 2021-03-30 19:43:10 -0700 |
| commit | 3636c8c51cc9221db8ef4ade6c4231b68bd553ba (patch) | |
| tree | f0fc5675e508a13bcae5414b7ce70311449a8dd4 /app | |
| parent | 00acb7483a1c207670062d15991a82266b91735c (diff) | |
Add permission validation
Signed-off-by: Tyler Nijmeh <tylernij@gmail.com>
Diffstat (limited to 'app')
| -rw-r--r-- | app/build.gradle | 16 | ||||
| -rw-r--r-- | app/src/main/AndroidManifest.xml | 11 | ||||
| -rw-r--r-- | app/src/main/java/com/draco/buoy/MainActivity.kt | 11 | ||||
| -rw-r--r-- | app/src/main/java/com/draco/buoy/utils/PermissionUtils.kt | 11 | ||||
| -rw-r--r-- | app/src/main/java/com/draco/buoy/viewmodels/MainActivityViewModel.kt | 7 | ||||
| -rw-r--r-- | app/src/main/java/com/draco/buoy/viewmodels/PermissionActivityViewModel.kt | 48 | ||||
| -rw-r--r-- | app/src/main/java/com/draco/buoy/views/MainActivity.kt | 28 | ||||
| -rw-r--r-- | app/src/main/java/com/draco/buoy/views/PermissionActivity.kt | 41 | ||||
| -rw-r--r-- | app/src/main/res/layout/activity_main.xml | 18 | ||||
| -rw-r--r-- | app/src/main/res/layout/activity_permission.xml | 50 | ||||
| -rw-r--r-- | app/src/main/res/values/strings.xml | 11 |
11 files changed, 221 insertions, 31 deletions
diff --git a/app/build.gradle b/app/build.gradle index 73089a1..7ab5e86 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -9,7 +9,7 @@ android { defaultConfig { applicationId "com.draco.buoy" - minSdk 21 + minSdk 23 targetSdk 30 versionCode 1 versionName "1.0" @@ -19,7 +19,8 @@ android { buildTypes { release { - minifyEnabled false + minifyEnabled true + shrinkResources true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } @@ -37,7 +38,16 @@ dependencies { implementation 'androidx.core:core-ktx:1.3.2' implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'com.google.android.material:material:1.3.0' - implementation 'androidx.constraintlayout:constraintlayout:2.0.4' + + implementation 'androidx.preference:preference-ktx:1.1.1' + implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.1' + + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1' + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.1' + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1' + + implementation 'com.google.android.gms:play-services-oss-licenses:17.0.0' + testImplementation 'junit:junit:4.+' androidTestImplementation 'androidx.test.ext:junit:1.1.2' androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 7cbf35d..1f0e401 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,23 +1,30 @@ <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" package="com.draco.buoy"> + <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" + tools:ignore="ProtectedPermissions" /> + <application android:allowBackup="true" + android:fullBackupContent="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.Buoy"> <activity - android:name=".MainActivity" + android:name=".views.MainActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> - <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> + + <activity android:name=".views.PermissionActivity" + android:label="@string/title_permission"/> </application> </manifest>
\ No newline at end of file diff --git a/app/src/main/java/com/draco/buoy/MainActivity.kt b/app/src/main/java/com/draco/buoy/MainActivity.kt deleted file mode 100644 index 18eb9db..0000000 --- a/app/src/main/java/com/draco/buoy/MainActivity.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.draco.buoy - -import androidx.appcompat.app.AppCompatActivity -import android.os.Bundle - -class MainActivity : AppCompatActivity() { - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(R.layout.activity_main) - } -}
\ No newline at end of file diff --git a/app/src/main/java/com/draco/buoy/utils/PermissionUtils.kt b/app/src/main/java/com/draco/buoy/utils/PermissionUtils.kt new file mode 100644 index 0000000..13dc385 --- /dev/null +++ b/app/src/main/java/com/draco/buoy/utils/PermissionUtils.kt @@ -0,0 +1,11 @@ +package com.draco.buoy.utils + +import android.content.Context +import android.content.pm.PackageManager + +class PermissionUtils { + companion object { + fun isPermissionsGranted(context: Context, permission: String): Boolean = + context.checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED + } +}
\ No newline at end of file diff --git a/app/src/main/java/com/draco/buoy/viewmodels/MainActivityViewModel.kt b/app/src/main/java/com/draco/buoy/viewmodels/MainActivityViewModel.kt new file mode 100644 index 0000000..443b494 --- /dev/null +++ b/app/src/main/java/com/draco/buoy/viewmodels/MainActivityViewModel.kt @@ -0,0 +1,7 @@ +package com.draco.buoy.viewmodels + +import android.app.Application +import androidx.lifecycle.AndroidViewModel + +class MainActivityViewModel(application: Application) : AndroidViewModel(application) { +}
\ No newline at end of file diff --git a/app/src/main/java/com/draco/buoy/viewmodels/PermissionActivityViewModel.kt b/app/src/main/java/com/draco/buoy/viewmodels/PermissionActivityViewModel.kt new file mode 100644 index 0000000..7ee2e58 --- /dev/null +++ b/app/src/main/java/com/draco/buoy/viewmodels/PermissionActivityViewModel.kt @@ -0,0 +1,48 @@ +package com.draco.buoy.viewmodels + +import android.app.Application +import androidx.lifecycle.AndroidViewModel +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.viewModelScope +import com.draco.buoy.utils.PermissionUtils +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch + +class PermissionActivityViewModel(application: Application) : AndroidViewModel(application) { + private val _permissionGranted = MutableLiveData(false) + val permissionGranted: LiveData<Boolean> = _permissionGranted + + private fun askRootPermission() { + try { + ProcessBuilder( + "su", + "-c", + "pm grant com.draco.purr android.permission.WRITE_SECURE_SETTINGS" + ).start() + } catch (_: Exception) {} + } + + private fun isWriteSecureSettingsPermissionGranted(): Boolean { + val context = getApplication<Application>().applicationContext + return PermissionUtils.isPermissionsGranted(context, android.Manifest.permission.WRITE_SECURE_SETTINGS) + } + + private fun startPermissionCheckLoop() { + viewModelScope.launch(Dispatchers.IO) { + while (!isWriteSecureSettingsPermissionGranted()) + delay(100) + _permissionGranted.postValue(true) + } + } + + init { + if (!isWriteSecureSettingsPermissionGranted()) { + viewModelScope.launch(Dispatchers.IO) { + askRootPermission() + } + startPermissionCheckLoop() + } + } +}
\ No newline at end of file diff --git a/app/src/main/java/com/draco/buoy/views/MainActivity.kt b/app/src/main/java/com/draco/buoy/views/MainActivity.kt new file mode 100644 index 0000000..10a56b9 --- /dev/null +++ b/app/src/main/java/com/draco/buoy/views/MainActivity.kt @@ -0,0 +1,28 @@ +package com.draco.buoy.views + +import android.content.Intent +import androidx.appcompat.app.AppCompatActivity +import android.os.Bundle +import androidx.activity.viewModels +import com.draco.buoy.R +import com.draco.buoy.utils.PermissionUtils +import com.draco.buoy.viewmodels.MainActivityViewModel + +class MainActivity : AppCompatActivity() { + private val viewModel: MainActivityViewModel by viewModels() + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_main) + + if (!PermissionUtils.isPermissionsGranted(this, android.Manifest.permission.WRITE_SECURE_SETTINGS)) { + goToPermissionActivity() + return + } + } + + private fun goToPermissionActivity() { + val intent = Intent(this, PermissionActivity::class.java) + startActivity(intent) + } +}
\ No newline at end of file diff --git a/app/src/main/java/com/draco/buoy/views/PermissionActivity.kt b/app/src/main/java/com/draco/buoy/views/PermissionActivity.kt new file mode 100644 index 0000000..d3b8b62 --- /dev/null +++ b/app/src/main/java/com/draco/buoy/views/PermissionActivity.kt @@ -0,0 +1,41 @@ +package com.draco.buoy.views + +import android.content.ClipData +import android.content.ClipboardManager +import android.content.Context +import android.os.Bundle +import android.widget.TextView +import androidx.activity.viewModels +import androidx.appcompat.app.AppCompatActivity +import com.draco.buoy.R +import com.draco.buoy.viewmodels.PermissionActivityViewModel +import com.google.android.material.snackbar.Snackbar + +class PermissionActivity : AppCompatActivity() { + private val viewModel: PermissionActivityViewModel by viewModels() + + private lateinit var command: TextView + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_permission) + + command = findViewById(R.id.command) + + command.setOnClickListener { + val clipboardManager = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager + val clip = ClipData.newPlainText("ADB Command", command.text.toString()) + clipboardManager.setPrimaryClip(clip) + + Snackbar.make(command, R.string.copied, Snackbar.LENGTH_SHORT).show() + } + + viewModel.permissionGranted.observe(this) { + if (it == true) + finish() + } + } + + /* Disallow exit */ + override fun onBackPressed() {} +}
\ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 4fc2444..24f3d6b 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,18 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> -<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:app="http://schemas.android.com/apk/res-auto" - xmlns:tools="http://schemas.android.com/tools" +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" - android:layout_height="match_parent" - tools:context=".MainActivity"> + android:layout_height="match_parent"> - <TextView - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:text="Hello World!" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintLeft_toLeftOf="parent" - app:layout_constraintRight_toRightOf="parent" - app:layout_constraintTop_toTopOf="parent" /> - -</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file +</RelativeLayout>
\ No newline at end of file diff --git a/app/src/main/res/layout/activity_permission.xml b/app/src/main/res/layout/activity_permission.xml new file mode 100644 index 0000000..48d4702 --- /dev/null +++ b/app/src/main/res/layout/activity_permission.xml @@ -0,0 +1,50 @@ +<?xml version="1.0" encoding="utf-8"?> +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent"> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_margin="24dp" + android:orientation="vertical"> + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + style="@style/TextAppearance.MaterialComponents.Headline2" + android:text="@string/permission_title" /> + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="32dp" + style="@style/TextAppearance.MaterialComponents.Headline5" + android:text="@string/permission_message" /> + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="32dp" + android:id="@+id/command" + android:fontFamily="monospace" + android:text="@string/permission_command" /> + </LinearLayout> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_margin="24dp" + android:orientation="vertical" + android:gravity="center" + android:layout_alignParentBottom="true"> + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginVertical="12dp" + style="@style/TextAppearance.MaterialComponents.Caption" + android:text="@string/please_wait" /> + <ProgressBar + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:indeterminate="true" + android:layout_marginHorizontal="64dp" + style="@style/Widget.AppCompat.ProgressBar.Horizontal" /> + </LinearLayout> +</RelativeLayout>
\ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 36f5960..619b965 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,3 +1,14 @@ <resources> <string name="app_name">Buoy</string> + + <string name="title_permission">Permissions</string> + + <string name="permission_title">Woah there!</string> + <string name="permission_message">We need a special permission to continue. Use ADB to run the following command (one line):</string> + <string name="permission_command">adb shell pm grant com.draco.buoy android.permission.WRITE_SECURE_SETTINGS</string> + + <string name="please_wait">Waiting for permission</string> + <string name="copied">Copied to clipboard</string> + + <string name="snackbar_intent_failed">Could not handle this action</string> </resources>
\ No newline at end of file |
