diff options
Diffstat (limited to 'ui/src/main/java/com/wireguard/android/activity/MainActivity.kt')
-rw-r--r-- | ui/src/main/java/com/wireguard/android/activity/MainActivity.kt | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/ui/src/main/java/com/wireguard/android/activity/MainActivity.kt b/ui/src/main/java/com/wireguard/android/activity/MainActivity.kt new file mode 100644 index 00000000..237a75f4 --- /dev/null +++ b/ui/src/main/java/com/wireguard/android/activity/MainActivity.kt @@ -0,0 +1,126 @@ +/* + * Copyright © 2017-2019 WireGuard LLC. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ +package com.wireguard.android.activity + +import android.content.Intent +import android.os.Bundle +import android.view.Menu +import android.view.MenuItem +import android.view.View +import android.widget.LinearLayout +import androidx.appcompat.app.ActionBar +import androidx.fragment.app.FragmentManager +import androidx.fragment.app.FragmentTransaction +import com.wireguard.android.R +import com.wireguard.android.fragment.TunnelDetailFragment +import com.wireguard.android.fragment.TunnelEditorFragment +import com.wireguard.android.model.ObservableTunnel + +/** + * CRUD interface for WireGuard tunnels. This activity serves as the main entry point to the + * WireGuard application, and contains several fragments for listing, viewing details of, and + * editing the configuration and interface state of WireGuard tunnels. + */ +class MainActivity : BaseActivity(), FragmentManager.OnBackStackChangedListener { + private var actionBar: ActionBar? = null + private var isTwoPaneLayout = false + + override fun onBackPressed() { + val backStackEntries = supportFragmentManager.backStackEntryCount + // If the two-pane layout does not have an editor open, going back should exit the app. + if (isTwoPaneLayout && backStackEntries <= 1) { + finish() + return + } + // Deselect the current tunnel on navigating back from the detail pane to the one-pane list. + if (!isTwoPaneLayout && backStackEntries == 1) { + supportFragmentManager.popBackStack() + selectedTunnel = null + return + } + super.onBackPressed() + } + + override fun onBackStackChanged() { + if (actionBar == null) return + // Do not show the home menu when the two-pane layout is at the detail view (see above). + val backStackEntries = supportFragmentManager.backStackEntryCount + val minBackStackEntries = if (isTwoPaneLayout) 2 else 1 + actionBar!!.setDisplayHomeAsUpEnabled(backStackEntries >= minBackStackEntries) + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.main_activity) + actionBar = supportActionBar + isTwoPaneLayout = findViewById<View>(R.id.master_detail_wrapper) is LinearLayout + supportFragmentManager.addOnBackStackChangedListener(this) + onBackStackChanged() + // Dispatch insets on back stack change + // This is required to ensure replaced fragments are also able to consume insets + findViewById<View>(R.id.master_detail_wrapper).setOnApplyWindowInsetsListener { _, insets -> + val fragmentManager = supportFragmentManager + fragmentManager.addOnBackStackChangedListener { + fragmentManager.fragments.forEach { + it.requireView().dispatchApplyWindowInsets(insets) + } + } + insets + } + } + + override fun onCreateOptionsMenu(menu: Menu): Boolean { + menuInflater.inflate(R.menu.main_activity, menu) + return true + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + return when (item.itemId) { + android.R.id.home -> { + // The back arrow in the action bar should act the same as the back button. + onBackPressed() + true + } + R.id.menu_action_edit -> { + supportFragmentManager.beginTransaction() + .replace(R.id.detail_container, TunnelEditorFragment()) + .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE) + .addToBackStack(null) + .commit() + true + } + // This menu item is handled by the editor fragment. + R.id.menu_action_save -> false + R.id.menu_settings -> { + startActivity(Intent(this, SettingsActivity::class.java)) + true + } + else -> super.onOptionsItemSelected(item) + } + } + + override fun onSelectedTunnelChanged(oldTunnel: ObservableTunnel?, + newTunnel: ObservableTunnel?) { + val fragmentManager = supportFragmentManager + val backStackEntries = fragmentManager.backStackEntryCount + if (newTunnel == null) { + // Clear everything off the back stack (all editors and detail fragments). + fragmentManager.popBackStackImmediate(0, FragmentManager.POP_BACK_STACK_INCLUSIVE) + return + } + if (backStackEntries == 2) { + // Pop the editor off the back stack to reveal the detail fragment. Use the immediate + // method to avoid the editor picking up the new tunnel while it is still visible. + fragmentManager.popBackStackImmediate() + } else if (backStackEntries == 0) { + // Create and show a new detail fragment. + fragmentManager.beginTransaction() + .add(R.id.detail_container, TunnelDetailFragment()) + .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE) + .addToBackStack(null) + .commit() + } + } +} |