diff --git a/app/build.gradle b/app/build.gradle
index 8ea62ee..7b2e161 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -36,10 +36,11 @@ dependencies {
implementation "dev.rikka.shizuku:provider:12.1.0"
implementation 'com.google.code.gson:gson:2.10.1'
implementation 'androidx.core:core-ktx:1.13.1'
- implementation 'androidx.appcompat:appcompat:1.6.1'
- implementation 'com.google.android.material:material:1.11.0'
+ implementation 'androidx.appcompat:appcompat:1.7.0'
+ implementation 'com.google.android.material:material:1.12.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
- implementation 'androidx.activity:activity:1.9.0'
+ implementation 'androidx.activity:activity-ktx:1.9.0'
+
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
diff --git a/app/release/app-release.apk b/app/release/app-release.apk
index 69e1fe5..b0997a5 100644
Binary files a/app/release/app-release.apk and b/app/release/app-release.apk differ
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index e868867..9a3a21b 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -29,6 +29,18 @@
android:supportsRtl="true"
android:theme="@style/Theme.AdbTools"
tools:targetApi="31">
+
+
+
+
(R.id.cardLookBack)
val cardMixedAudio = findViewById(R.id.cardMixedAudio)
val cardSoundMaster = findViewById(R.id.cardSoundMaster)
+ val cardForcePip = findViewById(R.id.cardForcePip)
val cardShell = findViewById(R.id.cardShell)
val cardIntentShell = findViewById(R.id.cardIntentShell)
cardDebloat.setOnClickListener {
@@ -120,6 +122,35 @@ class MainActivity : AppCompatActivity() {
}
}
}
+ cardForcePip.setOnClickListener {
+ val intent = Intent(this, PipReceiver::class.java)
+ SoundMasterService.uiIntent = intent
+ val channelId = "notifications"
+ val notificationBuilder = NotificationCompat.Builder(applicationContext, channelId)
+ .setSmallIcon(R.drawable.outline_info_24)
+ .setContentTitle("Tap to toggle "+getString(R.string.universalpip))
+ .setOngoing(true)
+ .setContentIntent(
+ PendingIntent.getBroadcast(
+ this,
+ 0,
+ intent,
+ PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
+ )
+ )
+ .setPriority(NotificationCompat.PRIORITY_LOW)
+
+ // Show the notification.
+ with(NotificationManagerCompat.from(applicationContext)) {
+ if (ActivityCompat.checkSelfPermission(
+ applicationContext,
+ android.Manifest.permission.POST_NOTIFICATIONS
+ ) == PackageManager.PERMISSION_GRANTED
+ ) {
+ notify(4, notificationBuilder.build())
+ }
+ }
+ }
cardShell.setOnClickListener { localShell() }
cardIntentShell.setOnClickListener { intentShell() }
}
diff --git a/app/src/main/java/com/legendsayantan/adbtools/PipStarterActivity.kt b/app/src/main/java/com/legendsayantan/adbtools/PipStarterActivity.kt
new file mode 100644
index 0000000..4559fc3
--- /dev/null
+++ b/app/src/main/java/com/legendsayantan/adbtools/PipStarterActivity.kt
@@ -0,0 +1,128 @@
+package com.legendsayantan.adbtools
+
+import android.content.Context
+import android.os.Bundle
+import android.view.KeyEvent
+import androidx.activity.enableEdgeToEdge
+import androidx.appcompat.app.AppCompatActivity
+import com.legendsayantan.adbtools.lib.ShizukuRunner
+import java.util.Timer
+import kotlin.concurrent.timerTask
+
+class PipStarterActivity : AppCompatActivity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ enableEdgeToEdge()
+ intent.getStringExtra("package")
+ ?.let {
+ startActivity(packageManager.getLaunchIntentForPackage(it))
+ playVideo()
+ }
+ finish()
+ }
+
+ companion object {
+ fun Context.handlePip() {
+ ShizukuRunner.runAdbCommand("settings get global overlay_display_devices",object : ShizukuRunner.CommandResultListener{
+ override fun onCommandResult(output: String, done: Boolean) {
+ if(done){
+ if(output.trim().contains("null",true)){
+ enablePip()
+ }else{
+ disablePip()
+ }
+ }
+ }
+ })
+ }
+
+ fun Context.enablePip(){
+ Timer().schedule(timerTask {
+ ShizukuRunner.runAdbCommand(
+ "dumpsys window displays | grep -E 'mCurrentFocus'",
+ object : ShizukuRunner.CommandResultListener {
+ override fun onCommandResult(output: String, done: Boolean) {
+ if (done) {
+ val pipPackage = output.split(" ")[4].split("/")[0]
+ val metrics = resources.displayMetrics
+ val height = (metrics.widthPixels / (metrics.heightPixels.toFloat() / metrics.widthPixels))+100
+ ShizukuRunner.runAdbCommand("settings put global overlay_display_devices ${metrics.widthPixels}x${height.toInt()}/240",
+ object : ShizukuRunner.CommandResultListener {
+ override fun onCommandResult(
+ output: String,
+ done: Boolean
+ ) {
+ if (done) {
+ Timer().schedule(timerTask {
+ ShizukuRunner.runAdbCommand("dumpsys display | grep 'Display [0-9][0-9]*'",
+ object : ShizukuRunner.CommandResultListener {
+ override fun onCommandResult(
+ output: String,
+ done: Boolean
+ ) {
+ if (done) {
+ val newDisplayId =
+ "\\d+".toRegex()
+ .findAll(output)
+ .filter { it.value != "0" }
+ .map { it.value.toInt() }
+ .maxOrNull() ?: 0
+ println(output)
+ println(newDisplayId)
+ val command =
+ "am start -n $packageName/${PipStarterActivity::class.java.canonicalName} --es package $pipPackage --display $newDisplayId"
+ ShizukuRunner.runAdbCommand(
+ command,
+ object :
+ ShizukuRunner.CommandResultListener {
+ override fun onCommandResult(
+ output: String,
+ done: Boolean
+ ) {
+ if (done) {
+ println("PIP started")
+ }
+ }
+
+ override fun onCommandError(
+ error: String
+ ) {
+ disablePip()
+ println(error)
+ }
+ })
+ }
+ }
+
+ override fun onCommandError(error: String) {
+ disablePip()
+ println(error)
+ }
+ })
+ }, 500)
+ }
+ }
+ })
+ }
+ }
+ })
+ }, 1500)
+ }
+
+ fun disablePip() {
+ ShizukuRunner.runAdbCommand("settings put global overlay_display_devices null",
+ object : ShizukuRunner.CommandResultListener {
+ override fun onCommandResult(output: String, done: Boolean) {
+ playVideo()
+ }
+ })
+ }
+
+ fun playVideo() {
+ Timer().schedule(timerTask {
+ ShizukuRunner.runAdbCommand("input keyevent ${KeyEvent.KEYCODE_MEDIA_PLAY}",
+ object : ShizukuRunner.CommandResultListener {})
+ }, 1500)
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/legendsayantan/adbtools/lib/PlayBackThread.kt b/app/src/main/java/com/legendsayantan/adbtools/lib/PlayBackThread.kt
index 916f8dd..7da6bd1 100644
--- a/app/src/main/java/com/legendsayantan/adbtools/lib/PlayBackThread.kt
+++ b/app/src/main/java/com/legendsayantan/adbtools/lib/PlayBackThread.kt
@@ -27,7 +27,7 @@ class PlayBackThread(
val pkg: String,
private val mediaProjection: MediaProjection
) : Thread("$LOG_TAG : $pkg") {
- var playback = true
+ @Volatile var playback = true
val dataBuffer = ByteArray(BUF_SIZE)
var loadedCycles = 0
diff --git a/app/src/main/java/com/legendsayantan/adbtools/receivers/PipReceiver.kt b/app/src/main/java/com/legendsayantan/adbtools/receivers/PipReceiver.kt
new file mode 100644
index 0000000..685cb6a
--- /dev/null
+++ b/app/src/main/java/com/legendsayantan/adbtools/receivers/PipReceiver.kt
@@ -0,0 +1,13 @@
+package com.legendsayantan.adbtools.receivers
+
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import com.legendsayantan.adbtools.PipStarterActivity.Companion.handlePip
+
+class PipReceiver : BroadcastReceiver() {
+
+ override fun onReceive(context: Context, intent: Intent) {
+ context.handlePip()
+ }
+}
\ 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 1db18a9..b42942a 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -290,6 +290,52 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ 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 fa6254a..5bdf3a0 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -58,4 +58,6 @@
None
Permission error! Open the shizuku app to learn more.
Shizuku Error!
+ UniversalPip beta
+ Switch apps to picture-in-picture mode forcefully.
\ No newline at end of file
diff --git a/settings.gradle b/settings.gradle
index 1546069..2a3b902 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -10,6 +10,7 @@ dependencyResolutionManagement {
repositories {
google()
mavenCentral()
+ maven { url 'https://jitpack.io' }
}
}