[android] Add transport plugin toggles to NavDrawer

This commit is contained in:
Torsten Grote
2020-01-15 10:48:03 -03:00
committed by akwizgran
parent 0fec5d7783
commit 96e32ad64e
7 changed files with 319 additions and 160 deletions

View File

@@ -0,0 +1,117 @@
<?xml version="1.0" encoding="utf-8"?>
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<Transition
app:constraintSetEnd="@+id/end"
app:constraintSetStart="@id/start"
app:duration="1000">
<OnClick app:targetId="@+id/chevronView" />
</Transition>
<ConstraintSet android:id="@+id/start">
<Constraint
android:id="@+id/chevronView"
android:layout_width="0dp"
android:layout_height="24dp"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toTopOf="@+id/longRangeLabel"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/navigation"
app:layout_constraintVertical_bias="1.0">
<CustomAttribute
app:attributeName="crossfade"
app:customFloatValue="0" />
</Constraint>
</ConstraintSet>
<ConstraintSet android:id="@+id/end">
<Constraint
android:id="@+id/chevronView"
android:layout_width="0dp"
android:layout_height="24dp"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toTopOf="@+id/connectionsLabel"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintVertical_bias="1.0">
<CustomAttribute
app:attributeName="crossfade"
app:customFloatValue="1" />
</Constraint>
<Constraint
android:id="@+id/backgroundView"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/chevronView" />
<Constraint
android:id="@+id/torSwitch"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@id/nearbyLabel"
app:layout_constraintStart_toEndOf="parent" />
<Constraint
android:id="@+id/wifiSwitch"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@+id/btSwitch"
app:layout_constraintStart_toEndOf="parent" />
<Constraint
android:id="@+id/btSwitch"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="parent" />
<Constraint
android:id="@+id/longRangeLabel"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@+id/torSwitch"
app:layout_constraintStart_toEndOf="parent" />
<Constraint
android:id="@+id/nearbyLabel"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@+id/wifiSwitch"
app:layout_constraintStart_toEndOf="parent" />
<Constraint
android:id="@+id/torIcon"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/wifiIcon"
app:layout_constraintTop_toBottomOf="@+id/chevronView" />
<Constraint
android:id="@+id/wifiIcon"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/btIcon"
app:layout_constraintTop_toBottomOf="@+id/chevronView" />
<Constraint
android:id="@+id/btIcon"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/chevronView" />
<Constraint
android:id="@+id/connectionsLabel"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="@+id/torIcon"
app:layout_constraintEnd_toStartOf="@+id/torIcon"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/torIcon" />
</ConstraintSet>
</MotionScene>

View File

@@ -1,17 +1,15 @@
package org.briarproject.briar.android.navdrawer;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.content.res.Configuration;
import android.net.Uri;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.widget.ImageView;
import android.widget.ScrollView;
import android.widget.TextView;
import com.google.android.material.navigation.NavigationView;
@@ -21,10 +19,7 @@ import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
import org.briarproject.bramble.api.plugin.BluetoothConstants;
import org.briarproject.bramble.api.plugin.LanTcpConstants;
import org.briarproject.bramble.api.plugin.Plugin.State;
import org.briarproject.bramble.api.plugin.TorConstants;
import org.briarproject.bramble.api.plugin.TransportId;
import org.briarproject.briar.R;
import org.briarproject.briar.android.activity.ActivityComponent;
@@ -39,25 +34,22 @@ import org.briarproject.briar.android.logout.SignOutFragment;
import org.briarproject.briar.android.privategroup.list.GroupListFragment;
import org.briarproject.briar.android.settings.SettingsActivity;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
import javax.inject.Inject;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.widget.Toolbar;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import static android.view.View.GONE;
import static android.view.View.INVISIBLE;
import static android.view.View.VISIBLE;
import static androidx.core.view.GravityCompat.START;
import static androidx.drawerlayout.widget.DrawerLayout.LOCK_MODE_LOCKED_CLOSED;
@@ -65,8 +57,6 @@ import static androidx.fragment.app.FragmentManager.POP_BACK_STACK_INCLUSIVE;
import static java.util.Objects.requireNonNull;
import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.RUNNING;
import static org.briarproject.bramble.api.plugin.Plugin.State.ACTIVE;
import static org.briarproject.bramble.api.plugin.Plugin.State.ENABLING;
import static org.briarproject.briar.android.BriarService.EXTRA_STARTUP_FAILED;
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_PASSWORD;
import static org.briarproject.briar.android.navdrawer.IntentRouter.handleExternalIntent;
@@ -102,11 +92,9 @@ public class NavDrawerActivity extends BriarActivity implements
LifecycleManager lifecycleManager;
private DrawerLayout drawerLayout;
private ScrollView drawerScrollView;
private NavigationView navigation;
private List<Transport> transports;
private BaseAdapter transportsAdapter;
@Override
public void injectActivity(ActivityComponent component) {
component.inject(this);
@@ -118,10 +106,26 @@ public class NavDrawerActivity extends BriarActivity implements
exitIfStartupFailed(getIntent());
setContentView(R.layout.activity_nav_drawer);
drawerScrollView = findViewById(R.id.drawerScrollView);
drawerScrollView.getViewTreeObserver().addOnGlobalLayoutListener(
new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
// hide/show chevron depending on whether we can scroll
View chevronView = findViewById(R.id.chevronView);
if (drawerScrollView.canScrollVertically(1)) {
chevronView.setVisibility(VISIBLE);
} else {
chevronView.setVisibility(INVISIBLE);
}
drawerScrollView.getViewTreeObserver()
.removeOnGlobalLayoutListener(this);
}
});
Toolbar toolbar = findViewById(R.id.toolbar);
drawerLayout = findViewById(R.id.drawer_layout);
navigation = findViewById(R.id.navigation);
GridView transportsView = findViewById(R.id.transportsView);
setSupportActionBar(toolbar);
ActionBar actionBar = requireNonNull(getSupportActionBar());
@@ -134,9 +138,6 @@ public class NavDrawerActivity extends BriarActivity implements
drawerLayout.addDrawerListener(drawerToggle);
navigation.setNavigationItemSelectedListener(this);
initializeTransports(getLayoutInflater());
transportsView.setAdapter(transportsAdapter);
lockManager.isLockable().observe(this, this::setLockVisible);
if (lifecycleManager.getLifecycleState().isAfter(RUNNING)) {
@@ -152,10 +153,8 @@ public class NavDrawerActivity extends BriarActivity implements
}
@Override
@SuppressLint("NewApi")
public void onStart() {
super.onStart();
updateTransports();
lockManager.checkIfLockable();
controller.showExpiryWarning(new UiResultHandler<Boolean>(this) {
@Override
@@ -373,109 +372,9 @@ public class NavDrawerActivity extends BriarActivity implements
expiryWarning.setVisibility(VISIBLE);
}
private void initializeTransports(LayoutInflater inflater) {
transports = new ArrayList<>(3);
Transport tor = new Transport();
tor.id = TorConstants.ID;
tor.state = controller.getTransportState(tor.id);
tor.iconId = R.drawable.transport_tor;
tor.textId = R.string.transport_tor;
transports.add(tor);
Transport bt = new Transport();
bt.id = BluetoothConstants.ID;
bt.state = controller.getTransportState(bt.id);
bt.iconId = R.drawable.transport_bt;
bt.textId = R.string.transport_bt;
transports.add(bt);
Transport lan = new Transport();
lan.id = LanTcpConstants.ID;
lan.state = controller.getTransportState(lan.id);
lan.iconId = R.drawable.transport_lan;
lan.textId = R.string.transport_lan;
transports.add(lan);
transportsAdapter = new BaseAdapter() {
@Override
public int getCount() {
return transports.size();
}
@Override
public Transport getItem(int position) {
return transports.get(position);
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView,
ViewGroup parent) {
View view;
if (convertView != null) {
view = convertView;
} else {
view = inflater.inflate(R.layout.list_item_transport,
parent, false);
}
Transport t = getItem(position);
int c;
if (t.state == ACTIVE) {
c = ContextCompat.getColor(NavDrawerActivity.this,
R.color.briar_green_light);
} else if (t.state == ENABLING) {
c = ContextCompat.getColor(NavDrawerActivity.this,
R.color.briar_yellow);
} else {
c = ContextCompat.getColor(NavDrawerActivity.this,
android.R.color.tertiary_text_light);
}
ImageView icon = view.findViewById(R.id.imageView);
icon.setImageDrawable(ContextCompat
.getDrawable(NavDrawerActivity.this, t.iconId));
icon.setColorFilter(c);
TextView text = view.findViewById(R.id.textView);
text.setText(getString(t.textId));
return view;
}
};
}
private void updateTransports() {
if (transports == null || transportsAdapter == null) return;
for (Transport t : transports) {
t.state = controller.getTransportState(t.id);
}
transportsAdapter.notifyDataSetChanged();
}
@Override
public void stateUpdate(TransportId id, State state) {
if (transports == null || transportsAdapter == null) return;
for (Transport t : transports) {
if (t.id.equals(id)) {
t.state = state;
transportsAdapter.notifyDataSetChanged();
break;
}
}
// TODO
}
@UiThread
private static class Transport {
private TransportId id;
private State state;
private int iconId;
private int textId;
}
}

View File

@@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<group>
<path
android:fillColor="#000000"
android:pathData="M20,9H4v2h16V9zM4,15h16v-2H4v2z" />
</group>
</vector>

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView 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/drawerScrollView"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="@color/window_background"
@@ -22,37 +22,21 @@
app:itemBackground="@drawable/navigation_item_background"
app:itemIconTint="?attr/colorControlNormal"
app:itemTextColor="?android:textColorPrimary"
app:layout_constraintBottom_toTopOf="@+id/chevronView"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0"
app:layout_constraintVertical_chainStyle="spread_inside"
app:menu="@menu/navigation_drawer" />
<View
android:id="@+id/divider1"
style="@style/Divider.Horizontal"
android:layout_width="0dp"
app:layout_constraintEnd_toEndOf="@+id/navigation"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/navigation" />
<View
android:id="@+id/spacer"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@+id/transports"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/divider1"
app:layout_constraintVertical_weight="1" />
<include
android:id="@+id/transports"
layout="@layout/transports_list"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/navigation"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/spacer"
tools:layout_height="75dp" />
app:layout_constraintTop_toBottomOf="@+id/navigation" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -1,19 +1,162 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<merge 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:layout_width="match_parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
tools:parentTag="androidx.constraintlayout.widget.ConstraintLayout"
tools:showIn="@layout/navigation_menu">
<View style="@style/Divider.Horizontal" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/chevronView"
android:layout_width="0dp"
android:layout_height="24dp"
android:layout_marginBottom="8dp"
android:background="@color/divider"
android:src="@drawable/chevron_down_white"
app:tint="?attr/colorControlNormal"
app:layout_constraintBottom_toTopOf="@+id/longRangeLabel"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/navigation"
app:layout_constraintVertical_bias="1.0"
tools:ignore="ContentDescription"
tools:visibility="visible" />
<GridView
android:id="@+id/transportsView"
android:layout_width="match_parent"
<View
android:id="@+id/backgroundView"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="8dp"
android:background="@color/item_background_highlight"
app:layout_constraintBottom_toTopOf="@+id/nearbyLabel"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/chevronView" />
<TextView
android:id="@+id/longRangeLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:listSelector="@android:color/transparent"
android:numColumns="3"
tools:listitem="@layout/list_item_transport" />
android:layout_marginBottom="8dp"
android:text="@string/transport_internet"
android:textSize="12sp"
app:layout_constraintBottom_toTopOf="@+id/torSwitch"
app:layout_constraintStart_toStartOf="@+id/torIcon" />
</LinearLayout>
<ImageView
android:id="@+id/torIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:src="@drawable/transport_tor"
app:layout_constraintBottom_toBottomOf="@+id/torSwitch"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/torSwitch"
app:tint="@color/briar_green"
tools:ignore="ContentDescription" />
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/torSwitch"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:layout_marginBottom="16dp"
android:text="@string/transport_tor"
app:layout_constraintBottom_toTopOf="@id/nearbyLabel"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/torIcon"
tools:checked="true" />
<TextView
android:id="@+id/nearbyLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginBottom="8dp"
android:gravity="center_vertical"
android:text="@string/transport_nearby"
android:textSize="12sp"
app:layout_constraintBottom_toTopOf="@+id/wifiSwitch"
app:layout_constraintStart_toStartOf="@+id/torIcon" />
<ImageView
android:id="@+id/wifiIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:src="@drawable/transport_lan"
app:layout_constraintBottom_toBottomOf="@+id/wifiSwitch"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/wifiSwitch"
app:tint="@color/briar_green"
tools:checked="true"
tools:ignore="ContentDescription" />
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/wifiSwitch"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:layout_marginBottom="8dp"
android:text="@string/transport_lan"
app:layout_constraintBottom_toTopOf="@+id/btSwitch"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/wifiIcon"
tools:checked="true" />
<ImageView
android:id="@+id/btIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:src="@drawable/transport_bt"
app:layout_constraintBottom_toBottomOf="@+id/btSwitch"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/btSwitch"
app:tint="@color/briar_green"
tools:checked="true"
tools:ignore="ContentDescription" />
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/btSwitch"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:layout_marginBottom="8dp"
android:text="@string/transport_bt"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/btIcon"
app:layout_constraintVertical_bias="1.0"
tools:checked="true" />
<TextView
android:id="@+id/connectionsLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:text="@string/transport_connection"
android:textSize="12sp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="@+id/torIcon"
app:layout_constraintEnd_toStartOf="@+id/torIcon"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/torIcon" />
</merge>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<menu
xmlns:android="http://schemas.android.com/apk/res/android">
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<group android:checkableBehavior="single">
<item
@@ -30,7 +30,8 @@
android:id="@+id/nav_btn_lock"
android:icon="@drawable/startup_lock"
android:title="@string/lock_button"
android:visible="false"/>
android:visible="false"
tools:visible="false" />
<item
android:id="@+id/nav_btn_signout"
android:icon="@drawable/ic_signout"

View File

@@ -70,7 +70,10 @@
<string name="sign_out_button">Sign Out</string>
<!-- Transports -->
<string name="transport_tor">Internet</string>
<string name="transport_connection">Connections</string>
<string name="transport_internet">Internet</string>
<string name="transport_tor">Tor</string>
<string name="transport_nearby">Nearby</string>
<string name="transport_bt">Bluetooth</string>
<string name="transport_lan">Wi-Fi</string>