Skip to content

Commit

Permalink
universal pip initial implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
legendsayantan committed Jun 20, 2024
1 parent 00f869c commit 5df671e
Show file tree
Hide file tree
Showing 12 changed files with 256 additions and 5 deletions.
7 changes: 4 additions & 3 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down
Binary file modified app/release/app-release.apk
Binary file not shown.
14 changes: 13 additions & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,18 @@
android:supportsRtl="true"
android:theme="@style/Theme.AdbTools"
tools:targetApi="31">
<receiver
android:name=".receivers.PipReceiver"
android:enabled="true"
android:exported="true"></receiver>

<activity
android:name=".ForcePipActivity"
android:exported="false" />
<activity
android:name=".PipStarterActivity"
android:excludeFromRecents="true"
android:exported="true" />

<service
android:name=".services.SoundMasterService"
Expand All @@ -50,9 +62,9 @@

<activity
android:name=".SoundMasterActivity"
android:excludeFromRecents="true"
android:exported="true"
android:label=""
android:excludeFromRecents="true"
android:theme="@style/DialogActivityTheme" />
<activity
android:name=".MixedAudioActivity"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,11 @@ class InitialActivity : AppCompatActivity() {
finish()
}
}

private fun startOnPip(intent:Intent){
val pipFlag = intent.getBooleanExtra("pip", false)
if(pipFlag){
startActivity(Intent(this, PipStarterActivity::class.java))
}
}
}
31 changes: 31 additions & 0 deletions app/src/main/java/com/legendsayantan/adbtools/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import com.google.android.material.textfield.TextInputEditText
import com.google.android.material.textfield.TextInputLayout
import com.legendsayantan.adbtools.lib.ShizukuRunner
import com.legendsayantan.adbtools.lib.Utils.Companion.initialiseStatusBar
import com.legendsayantan.adbtools.receivers.PipReceiver
import com.legendsayantan.adbtools.services.SoundMasterService
import java.util.UUID
/**
Expand All @@ -54,6 +55,7 @@ class MainActivity : AppCompatActivity() {
val cardLookBack = findViewById<MaterialCardView>(R.id.cardLookBack)
val cardMixedAudio = findViewById<MaterialCardView>(R.id.cardMixedAudio)
val cardSoundMaster = findViewById<MaterialCardView>(R.id.cardSoundMaster)
val cardForcePip = findViewById<MaterialCardView>(R.id.cardForcePip)
val cardShell = findViewById<MaterialCardView>(R.id.cardShell)
val cardIntentShell = findViewById<MaterialCardView>(R.id.cardIntentShell)
cardDebloat.setOnClickListener {
Expand Down Expand Up @@ -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() }
}
Expand Down
128 changes: 128 additions & 0 deletions app/src/main/java/com/legendsayantan/adbtools/PipStarterActivity.kt
Original file line number Diff line number Diff line change
@@ -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)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
Original file line number Diff line number Diff line change
@@ -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()
}
}
46 changes: 46 additions & 0 deletions app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,52 @@
</LinearLayout>
</com.google.android.material.card.MaterialCardView>

<com.google.android.material.card.MaterialCardView
android:id="@+id/cardForcePip"
style="@style/Theme.AdbTools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="90dp"
app:strokeWidth="1dp"
android:layout_marginVertical="10dp">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginHorizontal="15dp"
android:layout_marginVertical="15dp"
android:gravity="center"
android:orientation="vertical">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">

<com.google.android.material.textview.MaterialTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/universalpip"
android:textSize="22sp" />

<ImageView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginHorizontal="10dp"
app:srcCompat="@drawable/baseline_arrow_forward_24"
app:tint="?colorAccent" />

</LinearLayout>


<com.google.android.material.textview.MaterialTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/desc_universalpip" />

</LinearLayout>
</com.google.android.material.card.MaterialCardView>

<com.google.android.material.card.MaterialCardView
android:id="@+id/cardShell"
Expand Down
10 changes: 10 additions & 0 deletions app/src/main/res/layout/activity_pip_starter.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?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"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".PipStarterActivity">

</androidx.constraintlayout.widget.ConstraintLayout>
2 changes: 2 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,6 @@
<string name="none">None</string>
<string name="permission_error">Permission error! Open the shizuku app to learn more.</string>
<string name="shizuku_error">Shizuku Error!</string>
<string name="universalpip">UniversalPip beta</string>
<string name="desc_universalpip">Switch apps to picture-in-picture mode forcefully.</string>
</resources>
1 change: 1 addition & 0 deletions settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ dependencyResolutionManagement {
repositories {
google()
mavenCentral()
maven { url 'https://jitpack.io' }
}
}

Expand Down

0 comments on commit 5df671e

Please sign in to comment.