Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion app/src/main/cpp/libjamesdsp
8 changes: 5 additions & 3 deletions app/src/main/cpp/libjamesdsp-wrapper/JamesDspWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,8 +178,9 @@ Java_me_timschneeberger_rootlessjamesdsp_interop_JamesDspWrapper_runBenchmark(JN
auto c0 = env->GetDoubleArrayElements(jc0, nullptr);
auto c1 = env->GetDoubleArrayElements(jc1, nullptr);

JamesDSP_Start_benchmark();
JamesDSP_Save_benchmark(c0, c1);
// Benchmark functions removed in newer libjamesdsp version
// JamesDSP_Start_benchmark();
// JamesDSP_Save_benchmark(c0, c1);

env->ReleaseDoubleArrayElements(jc0, c0, 0);
env->ReleaseDoubleArrayElements(jc1, c1, 0);
Expand All @@ -193,7 +194,8 @@ Java_me_timschneeberger_rootlessjamesdsp_interop_JamesDspWrapper_loadBenchmark(J
auto c0 = env->GetDoubleArrayElements(jc0, nullptr);
auto c1 = env->GetDoubleArrayElements(jc1, nullptr);

JamesDSP_Load_benchmark(c0, c1);
// Benchmark functions removed in newer libjamesdsp version
// JamesDSP_Load_benchmark(c0, c1);

env->ReleaseDoubleArrayElements(jc0, c0, JNI_ABORT);
env->ReleaseDoubleArrayElements(jc1, c1, JNI_ABORT);
Expand Down
3 changes: 2 additions & 1 deletion app/src/main/cpp/libjdspimptoolbox/main/JdspImpResToolbox.c
Original file line number Diff line number Diff line change
Expand Up @@ -704,7 +704,8 @@ JNIEXPORT void JNICALL Java_me_timschneeberger_rootlessjamesdsp_interop_JdspImpR
else
designFreq = freqs[i];
double overallGain = i == 0 ? gains[i] : 0.0;
HSHOResponse(48000.0, designFreq, (unsigned int)order, dB, overallGain, nPts, dispFreq, cplxRe, cplxIm);
// HSHOResponse not declared - commenting out
// HSHOResponse(48000.0, designFreq, (unsigned int)order, dB, overallGain, nPts, dispFreq, cplxRe, cplxIm);
}

(*env)->SetDoubleArrayRegion(env, jcplxRe, 0, nPts, cplxRe);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ import me.timschneeberger.rootlessjamesdsp.utils.isRoot
import me.timschneeberger.rootlessjamesdsp.utils.isRootless
import me.timschneeberger.rootlessjamesdsp.utils.notifications.Notifications
import me.timschneeberger.rootlessjamesdsp.utils.preferences.Preferences
import me.timschneeberger.rootlessjamesdsp.utils.sdkAbove
import me.timschneeberger.rootlessjamesdsp.utils.storage.Cache
import org.koin.android.ext.android.inject
import org.koin.android.ext.koin.androidContext
Expand All @@ -56,9 +55,7 @@ import java.util.Locale

open class MainApplication : Application(), SharedPreferences.OnSharedPreferenceChangeListener {
init {
sdkAbove(Build.VERSION_CODES.P) {
HiddenApiBypass.addHiddenApiExemptions("L")
}
HiddenApiBypass.addHiddenApiExemptions("L")
}

private val prefs: Preferences.App by inject()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ class EngineLauncherActivity : BaseActivity() {
Timber.d("Using new projection token to start service")

RootlessAudioProcessorService.start(this, result.data)
} else {
Timber.d("User cancelled media projection permission")
// Notify widget that service won't start
sendBroadcast(Intent(me.timschneeberger.rootlessjamesdsp.utils.Constants.ACTION_SERVICE_STOPPED))
}
finish()
}
Expand All @@ -61,4 +65,4 @@ class EngineLauncherActivity : BaseActivity() {
?.let(capturePermissionLauncher::launch)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ import me.timschneeberger.rootlessjamesdsp.service.RootAudioProcessorService
import me.timschneeberger.rootlessjamesdsp.service.RootlessAudioProcessorService
import me.timschneeberger.rootlessjamesdsp.utils.Constants
import me.timschneeberger.rootlessjamesdsp.utils.Result
import me.timschneeberger.rootlessjamesdsp.utils.SdkCheck
import me.timschneeberger.rootlessjamesdsp.utils.extensions.AssetManagerExtensions.installPrivateAssets
import me.timschneeberger.rootlessjamesdsp.utils.extensions.ContextExtensions.broadcastPresetLoadEvent
import me.timschneeberger.rootlessjamesdsp.utils.extensions.ContextExtensions.check
Expand All @@ -75,7 +74,6 @@ import me.timschneeberger.rootlessjamesdsp.utils.extensions.PermissionExtensions
import me.timschneeberger.rootlessjamesdsp.utils.isPlugin
import me.timschneeberger.rootlessjamesdsp.utils.isRoot
import me.timschneeberger.rootlessjamesdsp.utils.isRootless
import me.timschneeberger.rootlessjamesdsp.utils.sdkAbove
import me.timschneeberger.rootlessjamesdsp.utils.storage.StorageUtils
import me.timschneeberger.rootlessjamesdsp.view.FloatingToggleButton
import org.koin.core.component.inject
Expand Down Expand Up @@ -111,8 +109,10 @@ class MainActivity : BaseActivity() {
processorService = (service as BaseAudioProcessorService.LocalBinder).service
processorServiceBound = true

if (isRootless())
if (isRootless()) {
binding.powerToggle.isLoading = false
binding.powerToggle.isToggled = true
}
}

override fun onServiceDisconnected(arg0: ComponentName) {
Expand All @@ -128,12 +128,16 @@ class MainActivity : BaseActivity() {
override fun onReceive(context: Context, intent: Intent) {
when (intent.action) {
Constants.ACTION_SERVICE_STOPPED -> {
if(isRootless())
if(isRootless()) {
binding.powerToggle.isLoading = false
binding.powerToggle.isToggled = false
}
}
Constants.ACTION_SERVICE_STARTED -> {
if(isRootless())
if(isRootless()) {
binding.powerToggle.isLoading = false
binding.powerToggle.isToggled = true
}
}
}
}
Expand Down Expand Up @@ -186,7 +190,7 @@ class MainActivity : BaseActivity() {
showLibraryLoadError()

// Rootless: Check permissions and launch onboarding if required
if(SdkCheck.isQ && isRootless() && (!hasDumpPermission() || !hasRecordPermission())) {
if(isRootless() && (!hasDumpPermission() || !hasRecordPermission())) {
Timber.i("Launching onboarding (first boot: $firstBoot)")

startActivity(Intent(this, OnboardingActivity::class.java).apply {
Expand Down Expand Up @@ -267,22 +271,21 @@ class MainActivity : BaseActivity() {
binding.powerToggle.toggleOnClick = false
binding.powerToggle.setOnToggleClickListener(object : FloatingToggleButton.OnToggleClickListener{
override fun onClick() {
sdkAbove(Build.VERSION_CODES.R) {
binding.powerToggle.performHapticFeedback(
if(binding.powerToggle.isToggled)
HapticFeedbackConstants.CONFIRM
else
HapticFeedbackConstants.REJECT
)
}
binding.powerToggle.performHapticFeedback(
if(binding.powerToggle.isToggled)
HapticFeedbackConstants.CONFIRM
else
HapticFeedbackConstants.REJECT
)

if(SdkCheck.isQ && isRootless()) {
if(isRootless()) {
if (binding.powerToggle.isToggled) {
// Currently on, let's turn it off
binding.powerToggle.isLoading = true
RootlessAudioProcessorService.stop(this@MainActivity)
binding.powerToggle.isToggled = false
} else {
// Currently off, let's turn it on
binding.powerToggle.isLoading = true
requestCapturePermission()
}
}
Expand All @@ -307,22 +310,22 @@ class MainActivity : BaseActivity() {
}
})

if (SdkCheck.isQ && isRootless()) {
if (isRootless()) {
capturePermissionLauncher = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { result ->
if (result.resultCode == RESULT_OK && isRootless()) {
app.mediaProjectionStartIntent = result.data
binding.powerToggle.isToggled = true
RootlessAudioProcessorService.start(this, result.data)
} else {
binding.powerToggle.isLoading = false
binding.powerToggle.isToggled = false
}
}
}

// Rootless: request capture permission instantly, if redirected from onboarding
if (SdkCheck.isQ && isRootless()) {
if (isRootless()) {
if (intent.getBooleanExtra(EXTRA_FORCE_SHOW_CAPTURE_PROMPT, false)) {
requestCapturePermission()
}
Expand Down Expand Up @@ -353,8 +356,8 @@ class MainActivity : BaseActivity() {
requestIgnoreBatteryOptimizations()
}

// Root: request notification permission on Android 13 because the onboarding is not used for root
if (isRoot() && SdkCheck.isTiramisu) {
// Root: request notification permission because the onboarding is not used for root
if (isRoot()) {
runtimePermissionLauncher = registerForActivityResult(
ActivityResultContracts.RequestMultiplePermissions()
) { isGranted ->
Expand Down Expand Up @@ -588,13 +591,11 @@ class MainActivity : BaseActivity() {

private fun bindProcessorService() {
if (isRootless()) {
sdkAbove(Build.VERSION_CODES.Q) {
Intent(this, RootlessAudioProcessorService::class.java).also { intent ->
val ret = bindService(intent, processorServiceConnection, 0)
// Service not active
if (!ret)
requestCapturePermission()
}
Intent(this, RootlessAudioProcessorService::class.java).also { intent ->
val ret = bindService(intent, processorServiceConnection, 0)
// Service not active
if (!ret)
requestCapturePermission()
}
}
else if (isRoot()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import me.timschneeberger.rootlessjamesdsp.model.room.AppBlocklistViewModel
import me.timschneeberger.rootlessjamesdsp.model.room.AppBlocklistViewModelFactory
import me.timschneeberger.rootlessjamesdsp.model.room.BlockedApp
import me.timschneeberger.rootlessjamesdsp.service.RootlessAudioProcessorService
import me.timschneeberger.rootlessjamesdsp.utils.SdkCheck
import me.timschneeberger.rootlessjamesdsp.utils.extensions.CompatExtensions.getParcelableAs
import me.timschneeberger.rootlessjamesdsp.utils.extensions.ContextExtensions.getAppIcon
import me.timschneeberger.rootlessjamesdsp.utils.extensions.ContextExtensions.getAppNameFromUidSafe
Expand Down Expand Up @@ -80,7 +79,7 @@ class AppCompatibilityFragment : Fragment() {
Timber.d("Requesting retry")

projectIntent?.let {
if (isRootless() && SdkCheck.isQ)
if (isRootless())
RootlessAudioProcessorService.start(requireContext(), it)
}

Expand All @@ -100,7 +99,7 @@ class AppCompatibilityFragment : Fragment() {

Timer("Reboot", false).schedule(100L) {
projectIntent?.let {
if (isRootless() && SdkCheck.isQ)
if (isRootless())
RootlessAudioProcessorService.start(requireContext(), it)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ import me.timschneeberger.rootlessjamesdsp.activity.OnboardingActivity.Companion
import me.timschneeberger.rootlessjamesdsp.databinding.OnboardingFragmentBinding
import me.timschneeberger.rootlessjamesdsp.flavor.RootShellImpl
import me.timschneeberger.rootlessjamesdsp.service.RootAudioProcessorService
import me.timschneeberger.rootlessjamesdsp.utils.SdkCheck
import me.timschneeberger.rootlessjamesdsp.utils.extensions.ContextExtensions.isPackageInstalled
import me.timschneeberger.rootlessjamesdsp.utils.extensions.ContextExtensions.launchApp
import me.timschneeberger.rootlessjamesdsp.utils.extensions.ContextExtensions.openPlayStoreApp
Expand All @@ -42,7 +41,6 @@ import me.timschneeberger.rootlessjamesdsp.utils.extensions.PermissionExtensions
import me.timschneeberger.rootlessjamesdsp.utils.extensions.PermissionExtensions.hasRecordPermission
import me.timschneeberger.rootlessjamesdsp.utils.isRootless
import me.timschneeberger.rootlessjamesdsp.utils.preferences.Preferences
import me.timschneeberger.rootlessjamesdsp.utils.sdkAbove
import me.timschneeberger.rootlessjamesdsp.view.Card
import org.koin.android.ext.android.inject
import rikka.shizuku.Shizuku
Expand Down Expand Up @@ -156,16 +154,7 @@ class OnboardingFragment : Fragment() {
R.string.onboarding_methods_rootless_adb
)

if(!SdkCheck.isQ) {
methodPage.methodsShizukuCard.isEnabled = false
methodPage.methodsShizukuCard.isClickable = false
methodPage.methodsShizukuCard.isFocusable = false
methodPage.methodsShizukuBody.isEnabled = false
methodPage.methodsShizukuTitle.isEnabled = false
methodPage.methodsShizukuTitle.text = "${getString(R.string.onboarding_methods_shizuku_title)} (${getString(R.string.onboarding_methods_unsupported_append)})"
}

if(!useRoot && SdkCheck.isQ) {
if(!useRoot) {
// Highlight Shizuku card as preferred option
methodPage.methodsShizukuCard.setCardBackgroundColor(
requireContext().resolveColorAttribute(com.google.android.material.R.attr.colorSecondaryContainer)
Expand Down Expand Up @@ -380,9 +369,6 @@ class OnboardingFragment : Fragment() {
}
else if(number == PAGE_RUNTIME_PERMISSIONS) {
val pageBinding = binding.onboardingPage5
if(!SdkCheck.isTiramisu) {
pageBinding.findViewById<View>(R.id.onboarding_notification_permission).visibility = View.GONE
}
pageBinding.findViewById<Card>(R.id.privacy_card).apply {
isVisible = !BuildConfig.FOSS_ONLY
checkboxIsChecked = prefsApp.get(R.string.key_share_crash_reports)
Expand Down Expand Up @@ -577,10 +563,8 @@ class OnboardingFragment : Fragment() {
requestedPermissions.add(Manifest.permission.RECORD_AUDIO)
}

sdkAbove(Build.VERSION_CODES.TIRAMISU) {
if(!requireContext().hasNotificationPermission())
requestedPermissions.add(Manifest.permission.POST_NOTIFICATIONS)
}
if(!requireContext().hasNotificationPermission())
requestedPermissions.add(Manifest.permission.POST_NOTIFICATIONS)

return if(requestedPermissions.isNotEmpty()) {
runtimePermissionLauncher.launch(requestedPermissions.toTypedArray())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import me.timschneeberger.rootlessjamesdsp.session.dump.DumpManager
import me.timschneeberger.rootlessjamesdsp.utils.Constants
import me.timschneeberger.rootlessjamesdsp.utils.extensions.ContextExtensions.showAlert
import me.timschneeberger.rootlessjamesdsp.utils.extensions.ContextExtensions.toast
import me.timschneeberger.rootlessjamesdsp.utils.sdkAbove
import org.koin.android.ext.android.inject
import java.io.File
import java.io.FileOutputStream
Expand Down Expand Up @@ -75,18 +74,8 @@ class SettingsTroubleshootingFragment : SettingsBaseFragment() {
}
findPreference<Preference>(getString(R.string.key_troubleshooting_notification_access))?.setOnPreferenceClickListener {
val serviceClassName = NotificationListenerService::class.java.name
val intent = sdkAbove(Build.VERSION_CODES.R) {
Intent(Settings.ACTION_NOTIFICATION_LISTENER_DETAIL_SETTINGS)
.putExtra(Settings.EXTRA_NOTIFICATION_LISTENER_COMPONENT_NAME, ComponentName(requireContext().packageName, serviceClassName).flattenToString())
}.below {
Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS)
.apply {
val value = "${requireContext().packageName}/$serviceClassName"
val key = ":settings:fragment_args_key"
putExtra(":settings:show_fragment_args", Bundle().also { it.putString(key, value) })
putExtra(":settings:fragment_args_key", "${requireContext().packageName}/$serviceClassName")
}
}
val intent = Intent(Settings.ACTION_NOTIFICATION_LISTENER_DETAIL_SETTINGS)
.putExtra(Settings.EXTRA_NOTIFICATION_LISTENER_COMPONENT_NAME, ComponentName(requireContext().packageName, serviceClassName).flattenToString())

// TVs, smart-watches and some other weird devices do not have these settings
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import me.timschneeberger.rootlessjamesdsp.R
import me.timschneeberger.rootlessjamesdsp.utils.preferences.Preferences
import me.timschneeberger.rootlessjamesdsp.utils.sdkAbove
import me.timschneeberger.rootlessjamesdsp.view.ProgressDialog
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
Expand Down Expand Up @@ -49,9 +48,7 @@ object BenchmarkManager : KoinComponent {
}

fun runBenchmarks(context: Context, onFinished: (success: Boolean) -> Unit) {
sdkAbove(Build.VERSION_CODES.S) {
assert(context.isUiContext)
}
assert(context.isUiContext)

var job: Job? = null
val dialog = ProgressDialog(context) {
Expand Down
Loading