diff --git a/vector/src/debug/AndroidManifest.xml b/vector/src/debug/AndroidManifest.xml index 4ec47d4920..94fdb1b389 100644 --- a/vector/src/debug/AndroidManifest.xml +++ b/vector/src/debug/AndroidManifest.xml @@ -10,6 +10,7 @@ + () { views.debugAnalytics.setOnClickListener { startActivity(Intent(this, DebugAnalyticsActivity::class.java)) } + views.debugMemoryLeaks.setOnClickListener { openMemoryLeaksSettings() } views.debugTestTextViewLink.setOnClickListener { testTextViewLink() } views.debugOpenButtonStylesLight.setOnClickListener { startActivity(Intent(this, DebugVectorButtonStylesLightActivity::class.java)) @@ -130,6 +132,10 @@ class DebugMenuActivity : VectorBaseActivity() { startActivity(Intent(this, DebugPrivateSettingsActivity::class.java)) } + private fun openMemoryLeaksSettings() { + startActivity(Intent(this, DebugMemoryLeaksActivity::class.java)) + } + private fun renderQrCode(text: String) { views.debugQrCode.setData(text) } diff --git a/vector/src/debug/java/im/vector/app/features/debug/di/MavericksViewModelDebugModule.kt b/vector/src/debug/java/im/vector/app/features/debug/di/MavericksViewModelDebugModule.kt index 6ef7fe441a..8512bb8c6d 100644 --- a/vector/src/debug/java/im/vector/app/features/debug/di/MavericksViewModelDebugModule.kt +++ b/vector/src/debug/java/im/vector/app/features/debug/di/MavericksViewModelDebugModule.kt @@ -24,6 +24,7 @@ import im.vector.app.core.di.MavericksAssistedViewModelFactory import im.vector.app.core.di.MavericksViewModelComponent import im.vector.app.core.di.MavericksViewModelKey import im.vector.app.features.debug.analytics.DebugAnalyticsViewModel +import im.vector.app.features.debug.leak.DebugMemoryLeaksViewModel import im.vector.app.features.debug.settings.DebugPrivateSettingsViewModel @InstallIn(MavericksViewModelComponent::class) @@ -39,4 +40,10 @@ interface MavericksViewModelDebugModule { @IntoMap @MavericksViewModelKey(DebugPrivateSettingsViewModel::class) fun debugPrivateSettingsViewModelFactory(factory: DebugPrivateSettingsViewModel.Factory): MavericksAssistedViewModelFactory<*, *> + + @Binds + @IntoMap + @MavericksViewModelKey(DebugMemoryLeaksViewModel::class) + fun debugMemoryLeaksViewModelFactory(factory: DebugMemoryLeaksViewModel.Factory): MavericksAssistedViewModelFactory<*, *> + } diff --git a/vector/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksActivity.kt b/vector/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksActivity.kt new file mode 100644 index 0000000000..226c65e3ed --- /dev/null +++ b/vector/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksActivity.kt @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.debug.leak + +import dagger.hilt.android.AndroidEntryPoint +import im.vector.app.core.extensions.addFragment +import im.vector.app.core.platform.VectorBaseActivity +import im.vector.app.databinding.ActivitySimpleBinding + +@AndroidEntryPoint +class DebugMemoryLeaksActivity : VectorBaseActivity() { + + override fun getBinding() = ActivitySimpleBinding.inflate(layoutInflater) + + override fun initUiAndData() { + if (isFirstCreation()) { + addFragment( + views.simpleFragmentContainer, + DebugMemoryLeaksFragment::class.java + ) + } + } +} diff --git a/vector/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksFragment.kt b/vector/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksFragment.kt new file mode 100644 index 0000000000..d3e70e26e6 --- /dev/null +++ b/vector/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksFragment.kt @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.debug.leak + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.airbnb.mvrx.fragmentViewModel +import com.airbnb.mvrx.withState +import dagger.hilt.android.AndroidEntryPoint +import im.vector.app.core.epoxy.onClick +import im.vector.app.core.platform.VectorBaseFragment +import im.vector.app.databinding.FragmentDebugMemoryLeaksBinding + +@AndroidEntryPoint +class DebugMemoryLeaksFragment : VectorBaseFragment() { + + private val viewModel: DebugMemoryLeaksViewModel by fragmentViewModel() + + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentDebugMemoryLeaksBinding { + return FragmentDebugMemoryLeaksBinding.inflate(inflater, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + setViewListeners() + } + + private fun setViewListeners() { + views.enableMemoryLeakAnalysis.onClick { + viewModel.handle(DebugMemoryLeaksViewActions.EnableMemoryLeaksAnalysis(views.enableMemoryLeakAnalysis.isChecked)) + } + } + + override fun invalidate() = withState(viewModel) { viewState -> + views.enableMemoryLeakAnalysis.isChecked = viewState.isMemoryLeaksAnalysisEnabled + } +} diff --git a/vector/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksViewActions.kt b/vector/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksViewActions.kt new file mode 100644 index 0000000000..e1447ae345 --- /dev/null +++ b/vector/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksViewActions.kt @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.debug.leak + +import im.vector.app.core.platform.VectorViewModelAction + +sealed interface DebugMemoryLeaksViewActions : VectorViewModelAction { + data class EnableMemoryLeaksAnalysis(val isEnabled: Boolean) : DebugMemoryLeaksViewActions +} diff --git a/vector/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksViewModel.kt b/vector/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksViewModel.kt new file mode 100644 index 0000000000..617a6b2ecb --- /dev/null +++ b/vector/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksViewModel.kt @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2021 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.debug.leak + +import com.airbnb.mvrx.MavericksViewModelFactory +import dagger.assisted.Assisted +import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject +import im.vector.app.core.di.MavericksAssistedViewModelFactory +import im.vector.app.core.di.hiltMavericksViewModelFactory +import im.vector.app.core.platform.EmptyViewEvents +import im.vector.app.core.platform.VectorViewModel +import im.vector.app.features.settings.VectorPreferences +import im.vector.app.leakcanary.LeakCanaryProxy +import kotlinx.coroutines.launch + +class DebugMemoryLeaksViewModel @AssistedInject constructor( + @Assisted initialState: DebugMemoryLeaksViewState, + private val vectorPreferences: VectorPreferences, + private val leakCanaryProxy: LeakCanaryProxy, +) : VectorViewModel(initialState) { + + @AssistedFactory + interface Factory : MavericksAssistedViewModelFactory { + override fun create(initialState: DebugMemoryLeaksViewState): DebugMemoryLeaksViewModel + } + + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() + + init { + viewModelScope.launch { + refreshStateFromPreferences() + } + } + + override fun handle(action: DebugMemoryLeaksViewActions) { + when (action) { + is DebugMemoryLeaksViewActions.EnableMemoryLeaksAnalysis -> handleEnableMemoryLeaksAnalysis(action) + } + } + + private fun handleEnableMemoryLeaksAnalysis(action: DebugMemoryLeaksViewActions.EnableMemoryLeaksAnalysis) { + viewModelScope.launch { + vectorPreferences.enableMemoryLeakAnalysis(action.isEnabled) + leakCanaryProxy.enable(action.isEnabled) + refreshStateFromPreferences() + } + } + + private fun refreshStateFromPreferences() { + setState { copy(isMemoryLeaksAnalysisEnabled = vectorPreferences.isMemoryLeakAnalysisEnabled()) } + } +} diff --git a/vector/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksViewState.kt b/vector/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksViewState.kt new file mode 100644 index 0000000000..4e9fe4b402 --- /dev/null +++ b/vector/src/debug/java/im/vector/app/features/debug/leak/DebugMemoryLeaksViewState.kt @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.debug.leak + +import com.airbnb.mvrx.MavericksState + +data class DebugMemoryLeaksViewState( + val isMemoryLeaksAnalysisEnabled: Boolean = false +) : MavericksState diff --git a/vector/src/debug/res/layout/activity_debug_menu.xml b/vector/src/debug/res/layout/activity_debug_menu.xml index 8b38c17b35..b5efe0302c 100644 --- a/vector/src/debug/res/layout/activity_debug_menu.xml +++ b/vector/src/debug/res/layout/activity_debug_menu.xml @@ -1,5 +1,6 @@ + android:layout_height="wrap_content" + app:layout_anchor="@+id/scrollView2" + app:layout_anchorGravity="center"> +