Merge branch 'move-swap-views-towards-mvc' into 'master'

Move swap views towards MVC

See merge request fdroid/fdroidclient!822
This commit is contained in:
Hans-Christoph Steiner 2019-05-14 11:56:01 +00:00
commit 200548d6ba
33 changed files with 892 additions and 1216 deletions

View File

@ -79,7 +79,8 @@ errorprone:
unzip -qq -d $ANDROID_HOME emulator-linux-5264690.zip;
set +x;
fi
- grep Revision $ANDROID_HOME/emulator/source.properties
- grep -v '^License' $ANDROID_HOME/tools/source.properties
$ANDROID_HOME/emulator/source.properties
- alias sdkmanager
- echo y | sdkmanager "platforms;android-$AVD_SDK" > /dev/null

View File

@ -15,7 +15,7 @@ import android.net.Uri;
import android.net.wifi.WifiManager;
import android.os.AsyncTask;
import android.os.IBinder;
import android.support.annotation.IntDef;
import android.support.annotation.LayoutRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.NotificationCompat;
@ -46,8 +46,6 @@ import rx.schedulers.Schedulers;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Collections;
@ -129,43 +127,21 @@ public class SwapService extends Service {
return peerFinder;
}
// ==========================================================
// Manage the current step
// ("Step" refers to the current view being shown in the UI)
// ==========================================================
public static final int STEP_INTRO = 1;
public static final int STEP_SELECT_APPS = 2;
public static final int STEP_JOIN_WIFI = 3;
public static final int STEP_SHOW_NFC = 4;
public static final int STEP_WIFI_QR = 5;
public static final int STEP_CONNECTING = 6;
public static final int STEP_SUCCESS = 7;
public static final int STEP_CONFIRM_SWAP = 8;
/**
* Special view, that we don't really want to actually store against the
* {@link SwapService#step}. Rather, we use it for the purpose of specifying
* we are in the state waiting for the {@link SwapService} to get started and
* bound to the {@link SwapWorkflowActivity}.
*/
public static final int STEP_INITIAL_LOADING = 9;
@SwapStep
private int step = STEP_INTRO;
@LayoutRes
private int currentView = STEP_INTRO;
/**
* Current screen that the swap process is up to.
* Will be one of the SwapState.STEP_* values.
*/
@SwapStep
public int getStep() {
return step;
@LayoutRes
public int getCurrentView() {
return currentView;
}
public SwapService setStep(@SwapStep int step) {
this.step = step;
return this;
public void setCurrentView(@LayoutRes int currentView) {
this.currentView = currentView;
}
@NonNull
@ -269,18 +245,6 @@ public class SwapService extends Service {
return peerRepo;
}
/**
* Ensure that we don't get put into an incorrect state, by forcing people to pass valid
* states to setStep. Ideally this would be done by requiring an enum or something to
* be passed rather than in integer, however that is harder to persist on disk than an int.
* This is the same as, e.g. {@link Context#getSystemService(String)}
*/
@IntDef({STEP_INTRO, STEP_SELECT_APPS, STEP_JOIN_WIFI, STEP_SHOW_NFC, STEP_WIFI_QR,
STEP_CONNECTING, STEP_SUCCESS, STEP_CONFIRM_SWAP, STEP_INITIAL_LOADING})
@Retention(RetentionPolicy.SOURCE)
public @interface SwapStep {
}
// =================================================
// Have selected a specific peer to swap with
// (Rather than showing a generic QR code to scan)

View File

@ -0,0 +1,80 @@
package org.fdroid.fdroid.localrepo;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.TypedArray;
import android.support.annotation.ColorInt;
import android.support.annotation.LayoutRes;
import android.util.AttributeSet;
import android.widget.RelativeLayout;
import org.fdroid.fdroid.R;
import org.fdroid.fdroid.views.swap.SwapWorkflowActivity;
/**
* A {@link android.view.View} that registers to handle the swap events from
* {@link SwapService}.
*/
public class SwapView extends RelativeLayout {
public static final String TAG = "SwapView";
@ColorInt
public final int toolbarColor;
public final String toolbarTitle;
private int layoutResId;
protected String currentFilterString;
public SwapView(Context context) {
this(context, null);
}
public SwapView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public SwapView(Context context, AttributeSet attrs, int defStyleAttr) {
this(context, attrs, defStyleAttr, 0);
}
@TargetApi(21)
public SwapView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
final TypedArray a = context.obtainStyledAttributes(
attrs, R.styleable.SwapView, 0, 0);
toolbarColor = a.getColor(R.styleable.SwapView_toolbarColor,
getResources().getColor(R.color.swap_blue));
toolbarTitle = a.getString(R.styleable.SwapView_toolbarTitle);
a.recycle();
}
@LayoutRes
public int getLayoutResId() {
return layoutResId;
}
public void setLayoutResId(@LayoutRes int layoutResId) {
this.layoutResId = layoutResId;
}
public String getCurrentFilterString() {
return this.currentFilterString;
}
public void setCurrentFilterString(String currentFilterString) {
this.currentFilterString = currentFilterString;
}
public SwapWorkflowActivity getActivity() {
return (SwapWorkflowActivity) getContext();
}
@ColorInt
public int getToolbarColour() {
return toolbarColor;
}
public String getToolbarTitle() {
return toolbarTitle;
}
}

View File

@ -1,92 +0,0 @@
package org.fdroid.fdroid.views.swap;
import android.annotation.TargetApi;
import android.content.Context;
import android.support.annotation.ColorRes;
import android.support.annotation.NonNull;
import android.util.AttributeSet;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.widget.RelativeLayout;
import android.widget.TextView;
import org.fdroid.fdroid.R;
import org.fdroid.fdroid.data.NewRepoConfig;
import org.fdroid.fdroid.localrepo.SwapService;
public class ConfirmReceive extends RelativeLayout implements SwapWorkflowActivity.InnerView {
private NewRepoConfig config;
public ConfirmReceive(Context context) {
super(context);
}
public ConfirmReceive(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ConfirmReceive(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@TargetApi(21)
public ConfirmReceive(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
private SwapWorkflowActivity getActivity() {
return (SwapWorkflowActivity) getContext();
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
findViewById(R.id.no_button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
getActivity().denySwap();
}
});
findViewById(R.id.yes_button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
getActivity().swapWith(config);
}
});
}
@Override
public boolean buildMenu(Menu menu, @NonNull MenuInflater inflater) {
return true;
}
@Override
public int getStep() {
return SwapService.STEP_CONFIRM_SWAP;
}
@Override
public int getPreviousStep() {
return SwapService.STEP_INTRO;
}
@ColorRes
public int getToolbarColour() {
return R.color.swap_blue;
}
@Override
public String getToolbarTitle() {
return getResources().getString(R.string.swap_confirm);
}
public void setup(NewRepoConfig config) {
this.config = config;
TextView descriptionTextView = (TextView) findViewById(R.id.text_description);
descriptionTextView.setText(getResources().getString(R.string.swap_confirm_connect, config.getHost()));
}
}

View File

@ -0,0 +1,54 @@
package org.fdroid.fdroid.views.swap;
import android.annotation.TargetApi;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import org.fdroid.fdroid.R;
import org.fdroid.fdroid.data.NewRepoConfig;
import org.fdroid.fdroid.localrepo.SwapView;
public class ConfirmReceiveView extends SwapView {
private NewRepoConfig config;
public ConfirmReceiveView(Context context) {
super(context);
}
public ConfirmReceiveView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ConfirmReceiveView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@TargetApi(21)
public ConfirmReceiveView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
findViewById(R.id.no_button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
getActivity().denySwap();
}
});
findViewById(R.id.yes_button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
getActivity().swapWith(config);
}
});
}
public void setup(NewRepoConfig config) {
this.config = config;
}
}

View File

@ -5,49 +5,39 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.annotation.ColorRes;
import android.support.annotation.NonNull;
import android.support.v4.content.LocalBroadcastManager;
import android.util.AttributeSet;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import org.fdroid.fdroid.R;
import org.fdroid.fdroid.UpdateService;
import org.fdroid.fdroid.localrepo.SwapService;
import org.fdroid.fdroid.localrepo.SwapView;
// TODO: Use this for the "Preparing local repo" dialog also.
public class SwapConnecting extends LinearLayout implements SwapWorkflowActivity.InnerView {
public class ConnectingView extends SwapView {
@SuppressWarnings("unused")
private static final String TAG = "SwapConnecting";
private static final String TAG = "ConnectingView";
public SwapConnecting(Context context) {
public ConnectingView(Context context) {
super(context);
}
public SwapConnecting(Context context, AttributeSet attrs) {
public ConnectingView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@TargetApi(11)
public SwapConnecting(Context context, AttributeSet attrs, int defStyleAttr) {
public ConnectingView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@TargetApi(21)
public SwapConnecting(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
public ConnectingView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
private SwapWorkflowActivity getActivity() {
return (SwapWorkflowActivity) getContext();
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
@ -116,7 +106,7 @@ public class SwapConnecting extends LinearLayout implements SwapWorkflowActivity
/**
* Listens for feedback about a repo update process taking place.
* * Tracks an index.jar download and show the progress messages
* Tracks an index.jar download and show the progress messages
*/
class ConnectSwapReceiver extends Receiver {
@ -146,7 +136,7 @@ public class SwapConnecting extends LinearLayout implements SwapWorkflowActivity
@Override
protected void onComplete() {
getActivity().showSwapConnected();
getActivity().inflateSwapView(R.layout.swap_success);
}
}
@ -165,6 +155,7 @@ public class SwapConnecting extends LinearLayout implements SwapWorkflowActivity
public void onReceive(Context context, Intent intent) {
TextView progressText = (TextView) findViewById(R.id.heading);
ProgressBar progressBar = findViewById(R.id.progress_bar);
TextView errorText = (TextView) findViewById(R.id.error);
Button backButton = (Button) findViewById(R.id.back);
@ -177,11 +168,13 @@ public class SwapConnecting extends LinearLayout implements SwapWorkflowActivity
}
progressText.setVisibility(View.VISIBLE);
progressBar.setVisibility(View.VISIBLE);
errorText.setVisibility(View.GONE);
backButton.setVisibility(View.GONE);
if (isError(intent)) {
progressText.setVisibility(View.GONE);
progressBar.setVisibility(View.GONE);
errorText.setVisibility(View.VISIBLE);
backButton.setVisibility(View.VISIBLE);
return;
@ -192,29 +185,4 @@ public class SwapConnecting extends LinearLayout implements SwapWorkflowActivity
}
}
}
@Override
public boolean buildMenu(Menu menu, @NonNull MenuInflater inflater) {
return true;
}
@Override
public int getStep() {
return SwapService.STEP_CONNECTING;
}
@Override
public int getPreviousStep() {
return SwapService.STEP_SELECT_APPS;
}
@ColorRes
public int getToolbarColour() {
return R.color.swap_bright_blue;
}
@Override
public String getToolbarTitle() {
return getResources().getString(R.string.swap_connecting);
}
}

View File

@ -1,58 +0,0 @@
package org.fdroid.fdroid.views.swap;
import android.annotation.TargetApi;
import android.content.Context;
import android.support.annotation.ColorRes;
import android.support.annotation.NonNull;
import android.util.AttributeSet;
import android.view.Menu;
import android.view.MenuInflater;
import android.widget.RelativeLayout;
import org.fdroid.fdroid.R;
import org.fdroid.fdroid.localrepo.SwapService;
public class InitialLoadingView extends RelativeLayout implements SwapWorkflowActivity.InnerView {
public InitialLoadingView(Context context) {
super(context);
}
public InitialLoadingView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public InitialLoadingView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@TargetApi(21)
public InitialLoadingView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
public boolean buildMenu(Menu menu, @NonNull MenuInflater inflater) {
return true;
}
@Override
public int getStep() {
return SwapService.STEP_INITIAL_LOADING;
}
@Override
public int getPreviousStep() {
return SwapService.STEP_JOIN_WIFI;
}
@ColorRes
public int getToolbarColour() {
return R.color.swap_blue;
}
@Override
public String getToolbarTitle() {
return getResources().getString(R.string.swap);
}
}

View File

@ -6,25 +6,18 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.wifi.WifiManager;
import android.support.annotation.ColorRes;
import android.support.annotation.NonNull;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v4.view.MenuItemCompat;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import org.fdroid.fdroid.FDroidApp;
import org.fdroid.fdroid.R;
import org.fdroid.fdroid.localrepo.SwapService;
import org.fdroid.fdroid.localrepo.SwapView;
import org.fdroid.fdroid.net.WifiStateChangeService;
public class JoinWifiView extends RelativeLayout implements SwapWorkflowActivity.InnerView {
public class JoinWifiView extends SwapView {
public JoinWifiView(Context context) {
super(context);
@ -43,10 +36,6 @@ public class JoinWifiView extends RelativeLayout implements SwapWorkflowActivity
super(context, attrs, defStyleAttr, defStyleRes);
}
private SwapWorkflowActivity getActivity() {
return (SwapWorkflowActivity) getContext();
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
@ -106,42 +95,6 @@ public class JoinWifiView extends RelativeLayout implements SwapWorkflowActivity
getActivity().startActivity(new Intent(WifiManager.ACTION_PICK_WIFI_NETWORK));
}
@Override
public boolean buildMenu(Menu menu, @NonNull MenuInflater inflater) {
inflater.inflate(R.menu.swap_next, menu);
MenuItem next = menu.findItem(R.id.action_next);
MenuItemCompat.setShowAsAction(next,
MenuItemCompat.SHOW_AS_ACTION_ALWAYS | MenuItemCompat.SHOW_AS_ACTION_WITH_TEXT);
next.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
getActivity().showSelectApps();
return true;
}
});
return true;
}
@Override
public int getStep() {
return SwapService.STEP_JOIN_WIFI;
}
@Override
public int getPreviousStep() {
return SwapService.STEP_INTRO;
}
@ColorRes
public int getToolbarColour() {
return R.color.swap_blue;
}
@Override
public String getToolbarTitle() {
return getResources().getString(R.string.swap_join_same_wifi);
}
private final BroadcastReceiver onWifiStateChange = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {

View File

@ -2,21 +2,14 @@ package org.fdroid.fdroid.views.swap;
import android.annotation.TargetApi;
import android.content.Context;
import android.support.annotation.ColorRes;
import android.support.annotation.NonNull;
import android.support.v4.view.MenuItemCompat;
import android.util.AttributeSet;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.RelativeLayout;
import org.fdroid.fdroid.Preferences;
import org.fdroid.fdroid.R;
import org.fdroid.fdroid.localrepo.SwapService;
import org.fdroid.fdroid.localrepo.SwapView;
public class NfcView extends RelativeLayout implements SwapWorkflowActivity.InnerView {
public class NfcView extends SwapView {
public NfcView(Context context) {
super(context);
@ -35,10 +28,6 @@ public class NfcView extends RelativeLayout implements SwapWorkflowActivity.Inne
super(context, attrs, defStyleAttr, defStyleRes);
}
private SwapWorkflowActivity getActivity() {
return (SwapWorkflowActivity) getContext();
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
@ -50,40 +39,4 @@ public class NfcView extends RelativeLayout implements SwapWorkflowActivity.Inne
}
});
}
@Override
public boolean buildMenu(Menu menu, @NonNull MenuInflater inflater) {
inflater.inflate(R.menu.swap_skip, menu);
MenuItem next = menu.findItem(R.id.action_next);
MenuItemCompat.setShowAsAction(next,
MenuItemCompat.SHOW_AS_ACTION_ALWAYS | MenuItemCompat.SHOW_AS_ACTION_WITH_TEXT);
next.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
getActivity().showWifiQr();
return true;
}
});
return true;
}
@Override
public int getStep() {
return SwapService.STEP_SHOW_NFC;
}
@Override
public int getPreviousStep() {
return SwapService.STEP_JOIN_WIFI;
}
@ColorRes
public int getToolbarColour() {
return R.color.swap_blue;
}
@Override
public String getToolbarTitle() {
return getResources().getString(R.string.swap_nfc_title);
}
}

View File

@ -8,22 +8,16 @@ import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.ColorRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.view.MenuItemCompat;
import android.support.v4.widget.CursorAdapter;
import android.support.v7.widget.SearchView;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
@ -32,16 +26,13 @@ import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import org.fdroid.fdroid.R;
import org.fdroid.fdroid.data.InstalledAppProvider;
import org.fdroid.fdroid.data.Schema.InstalledAppTable;
import org.fdroid.fdroid.localrepo.SwapService;
import org.fdroid.fdroid.localrepo.SwapView;
public class SelectAppsView extends ListView implements
SwapWorkflowActivity.InnerView,
LoaderManager.LoaderCallbacks<Cursor>,
SearchView.OnQueryTextListener {
public class SelectAppsView extends SwapView implements LoaderManager.LoaderCallbacks<Cursor> {
public SelectAppsView(Context context) {
super(context);
@ -60,86 +51,34 @@ public class SelectAppsView extends ListView implements
super(context, attrs, defStyleAttr, defStyleRes);
}
private SwapWorkflowActivity getActivity() {
return (SwapWorkflowActivity) getContext();
}
private SwapService getState() {
return getActivity().getState();
}
private static final int LOADER_INSTALLED_APPS = 253341534;
private ListView listView;
private AppListAdapter adapter;
private String currentFilterString;
@Override
protected void onFinishInflate() {
super.onFinishInflate();
adapter = new AppListAdapter(this, getContext(),
listView = findViewById(R.id.list);
adapter = new AppListAdapter(listView, getContext(),
getContext().getContentResolver().query(InstalledAppProvider.getContentUri(),
InstalledAppTable.Cols.ALL, null, null, null));
setAdapter(adapter);
setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
listView.setAdapter(adapter);
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
// either reconnect with an existing loader or start a new one
getActivity().getSupportLoaderManager().initLoader(LOADER_INSTALLED_APPS, null, this);
getActivity().getSupportLoaderManager().initLoader(R.layout.swap_select_apps, null, this);
setOnItemClickListener(new AdapterView.OnItemClickListener() {
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
toggleAppSelected(position);
}
});
}
@Override
public boolean buildMenu(Menu menu, @NonNull MenuInflater inflater) {
inflater.inflate(R.menu.swap_next_search, menu);
MenuItem nextMenuItem = menu.findItem(R.id.action_next);
int flags = MenuItemCompat.SHOW_AS_ACTION_ALWAYS | MenuItemCompat.SHOW_AS_ACTION_WITH_TEXT;
MenuItemCompat.setShowAsAction(nextMenuItem, flags);
nextMenuItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
getActivity().onAppsSelected();
return true;
}
});
SearchView searchView = new SearchView(getActivity());
MenuItem searchMenuItem = menu.findItem(R.id.action_search);
MenuItemCompat.setActionView(searchMenuItem, searchView);
MenuItemCompat.setShowAsAction(searchMenuItem, MenuItemCompat.SHOW_AS_ACTION_IF_ROOM);
searchView.setOnQueryTextListener(this);
return true;
}
@Override
public int getStep() {
return SwapService.STEP_SELECT_APPS;
}
@Override
public int getPreviousStep() {
// TODO: The STEP_JOIN_WIFI step isn't shown first, need to make it
// so that it is, or so that this doesn't go back there.
return getState().isConnectingWithPeer() ? SwapService.STEP_INTRO : SwapService.STEP_JOIN_WIFI;
}
@ColorRes
public int getToolbarColour() {
return R.color.swap_bright_blue;
}
@Override
public String getToolbarTitle() {
return getResources().getString(R.string.swap_choose_apps);
}
private void toggleAppSelected(int position) {
Cursor c = (Cursor) adapter.getItem(position);
String packageName = c.getString(c.getColumnIndex(InstalledAppTable.Cols.Package.NAME));
@ -174,13 +113,13 @@ public class SelectAppsView extends ListView implements
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
adapter.swapCursor(cursor);
for (int i = 0; i < getCount(); i++) {
Cursor c = (Cursor) getItemAtPosition(i);
for (int i = 0; i < listView.getCount(); i++) {
Cursor c = (Cursor) listView.getItemAtPosition(i);
String packageName = c.getString(c.getColumnIndex(InstalledAppTable.Cols.Package.NAME));
getState().ensureFDroidSelected();
for (String selected : getState().getAppsToSwap()) {
if (TextUtils.equals(packageName, selected)) {
setItemChecked(i, true);
listView.setItemChecked(i, true);
}
}
}
@ -191,26 +130,6 @@ public class SelectAppsView extends ListView implements
adapter.swapCursor(null);
}
@Override
public boolean onQueryTextChange(String newText) {
String newFilter = !TextUtils.isEmpty(newText) ? newText : null;
if (currentFilterString == null && newFilter == null) {
return true;
}
if (currentFilterString != null && currentFilterString.equals(newFilter)) {
return true;
}
currentFilterString = newFilter;
getActivity().getSupportLoaderManager().restartLoader(LOADER_INSTALLED_APPS, null, this);
return true;
}
@Override
public boolean onQueryTextSubmit(String query) {
// this is not needed since we respond to every change in text
return true;
}
private class AppListAdapter extends CursorAdapter {
@Nullable

View File

@ -7,28 +7,23 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.LightingColorFilter;
import android.support.annotation.ColorRes;
import android.support.annotation.NonNull;
import android.support.v4.content.LocalBroadcastManager;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ScrollView;
import android.widget.TextView;
import org.fdroid.fdroid.FDroidApp;
import org.fdroid.fdroid.Preferences;
import org.fdroid.fdroid.QrGenAsyncTask;
import org.fdroid.fdroid.R;
import org.fdroid.fdroid.Utils;
import org.fdroid.fdroid.localrepo.SwapService;
import org.fdroid.fdroid.localrepo.SwapView;
import org.fdroid.fdroid.net.WifiStateChangeService;
import org.fdroid.fdroid.views.swap.device.camera.CameraCharacteristicsChecker;
public class SendFDroidView extends ScrollView implements SwapWorkflowActivity.InnerView {
public class SendFDroidView extends SwapView {
private static final String TAG = "SendFDroidView";
@ -49,10 +44,6 @@ public class SendFDroidView extends ScrollView implements SwapWorkflowActivity.I
super(context, attrs, defStyleAttr, defStyleRes);
}
private SwapWorkflowActivity getActivity() {
return (SwapWorkflowActivity) getContext();
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
@ -96,31 +87,6 @@ public class SendFDroidView extends ScrollView implements SwapWorkflowActivity.I
LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(onWifiStateChanged);
}
@Override
public boolean buildMenu(Menu menu, @NonNull MenuInflater inflater) {
return false;
}
@Override
public int getStep() {
return SwapService.STEP_INTRO;
}
@Override
public int getPreviousStep() {
return SwapService.STEP_INTRO;
}
@ColorRes
public int getToolbarColour() {
return R.color.swap_blue;
}
@Override
public String getToolbarTitle() {
return getResources().getString(R.string.swap_send_fdroid);
}
@SuppressLint("HardwareIds")
private void setUIFromWifi() {
if (TextUtils.isEmpty(FDroidApp.repo.address)) {

View File

@ -7,16 +7,12 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.wifi.WifiConfiguration;
import android.support.annotation.ColorRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.widget.SwitchCompat;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
@ -25,13 +21,13 @@ import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
import cc.mvdan.accesspoint.WifiApControl;
import org.fdroid.fdroid.FDroidApp;
import org.fdroid.fdroid.R;
import org.fdroid.fdroid.Utils;
import org.fdroid.fdroid.localrepo.SwapService;
import org.fdroid.fdroid.localrepo.SwapView;
import org.fdroid.fdroid.localrepo.peers.Peer;
import org.fdroid.fdroid.net.WifiStateChangeService;
import rx.Subscriber;
@ -40,7 +36,7 @@ import rx.Subscription;
import java.util.ArrayList;
@SuppressWarnings("LineLength")
public class StartSwapView extends RelativeLayout implements SwapWorkflowActivity.InnerView {
public class StartSwapView extends SwapView {
private static final String TAG = "StartSwapView";
@ -58,7 +54,6 @@ public class StartSwapView extends RelativeLayout implements SwapWorkflowActivit
super(context, attrs);
}
@TargetApi(11)
public StartSwapView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@ -91,10 +86,6 @@ public class StartSwapView extends RelativeLayout implements SwapWorkflowActivit
}
private SwapWorkflowActivity getActivity() {
return (SwapWorkflowActivity) getContext();
}
private SwapService getManager() {
return getActivity().getState();
}
@ -456,35 +447,4 @@ public class StartSwapView extends RelativeLayout implements SwapWorkflowActivit
private void onPeerSelected(Peer peer) {
getActivity().swapWith(peer);
}
@Override
public boolean buildMenu(Menu menu, @NonNull MenuInflater inflater) {
return false;
}
@Override
public int getStep() {
return SwapService.STEP_INTRO;
}
@Override
public int getPreviousStep() {
// TODO: Currently this is handleed by the SwapWorkflowActivity as a special case, where
// if getStep is STEP_INTRO, don't even bother asking for getPreviousStep. But that is a
// bit messy. It would be nicer if this was handled using the same mechanism as everything
// else.
return SwapService.STEP_INTRO;
}
@Override
@ColorRes
public int getToolbarColour() {
return R.color.swap_bright_blue;
}
@Override
public String getToolbarTitle() {
return getResources().getString(R.string.swap_nearby);
}
}

View File

@ -12,22 +12,16 @@ import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.ColorRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v4.view.MenuItemCompat;
import android.support.v4.widget.CursorAdapter;
import android.support.v7.widget.SearchView;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
@ -47,7 +41,7 @@ import org.fdroid.fdroid.data.App;
import org.fdroid.fdroid.data.AppProvider;
import org.fdroid.fdroid.data.Repo;
import org.fdroid.fdroid.data.Schema.AppMetadataTable;
import org.fdroid.fdroid.localrepo.SwapService;
import org.fdroid.fdroid.localrepo.SwapView;
import org.fdroid.fdroid.net.Downloader;
import org.fdroid.fdroid.net.DownloaderService;
@ -55,35 +49,26 @@ import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
public class SwapAppsView extends ListView implements
SwapWorkflowActivity.InnerView,
LoaderManager.LoaderCallbacks<Cursor>,
SearchView.OnQueryTextListener {
public class SwapSuccessView extends SwapView implements LoaderManager.LoaderCallbacks<Cursor> {
private static final String TAG = "SwapAppsView";
public SwapAppsView(Context context) {
public SwapSuccessView(Context context) {
super(context);
}
public SwapAppsView(Context context, AttributeSet attrs) {
public SwapSuccessView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SwapAppsView(Context context, AttributeSet attrs, int defStyleAttr) {
public SwapSuccessView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@TargetApi(21)
public SwapAppsView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
public SwapSuccessView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
private SwapWorkflowActivity getActivity() {
return (SwapWorkflowActivity) getContext();
}
private static final int LOADER_SWAPABLE_APPS = 759283741;
private static final String TAG = "SwapAppsView";
private Repo repo;
private AppListAdapter adapter;
private String currentFilterString;
@ -102,11 +87,11 @@ public class SwapAppsView extends ListView implements
adapter = new AppListAdapter(getContext(), getContext().getContentResolver().query(
AppProvider.getRepoUri(repo), AppMetadataTable.Cols.ALL, null, null, null));
setAdapter(adapter);
ListView listView = findViewById(R.id.list);
listView.setAdapter(adapter);
// either reconnect with an existing loader or start a new one
getActivity().getSupportLoaderManager().initLoader(LOADER_SWAPABLE_APPS, null, this);
getActivity().getSupportLoaderManager().initLoader(R.layout.swap_success, null, this);
LocalBroadcastManager.getInstance(getActivity()).registerReceiver(
pollForUpdatesReceiver, new IntentFilter(UpdateService.LOCAL_ACTION_STATUS));
@ -148,41 +133,6 @@ public class SwapAppsView extends ListView implements
}, 5000);
}
@Override
public boolean buildMenu(Menu menu, @NonNull MenuInflater inflater) {
inflater.inflate(R.menu.swap_search, menu);
SearchView searchView = new SearchView(getActivity());
MenuItem searchMenuItem = menu.findItem(R.id.action_search);
MenuItemCompat.setActionView(searchMenuItem, searchView);
MenuItemCompat.setShowAsAction(searchMenuItem, MenuItemCompat.SHOW_AS_ACTION_ALWAYS);
searchView.setOnQueryTextListener(this);
return true;
}
@Override
public int getStep() {
return SwapService.STEP_SUCCESS;
}
@Override
public int getPreviousStep() {
return SwapService.STEP_INTRO;
}
@ColorRes
public int getToolbarColour() {
return R.color.swap_bright_blue;
}
@Override
public String getToolbarTitle() {
return getResources().getString(R.string.swap_success);
}
@Override
public CursorLoader onCreateLoader(int id, Bundle args) {
Uri uri = TextUtils.isEmpty(currentFilterString)
@ -203,26 +153,6 @@ public class SwapAppsView extends ListView implements
adapter.swapCursor(null);
}
@Override
public boolean onQueryTextChange(String newText) {
String newFilter = !TextUtils.isEmpty(newText) ? newText : null;
if (currentFilterString == null && newFilter == null) {
return true;
}
if (currentFilterString != null && currentFilterString.equals(newFilter)) {
return true;
}
currentFilterString = newFilter;
getActivity().getSupportLoaderManager().restartLoader(LOADER_SWAPABLE_APPS, null, this);
return true;
}
@Override
public boolean onQueryTextSubmit(String query) {
// this is not needed since we respond to every change in text
return true;
}
private class AppListAdapter extends CursorAdapter {
private class ViewHolder {

View File

@ -17,20 +17,25 @@ import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.provider.Settings;
import android.support.annotation.ColorRes;
import android.support.annotation.LayoutRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.StringRes;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.SearchView;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
import cc.mvdan.accesspoint.WifiApControl;
import com.google.zxing.integration.android.IntentIntegrator;
@ -48,6 +53,7 @@ import org.fdroid.fdroid.installer.InstallManagerService;
import org.fdroid.fdroid.installer.Installer;
import org.fdroid.fdroid.localrepo.LocalRepoManager;
import org.fdroid.fdroid.localrepo.SwapService;
import org.fdroid.fdroid.localrepo.SwapView;
import org.fdroid.fdroid.localrepo.peers.Peer;
import org.fdroid.fdroid.net.BluetoothDownloader;
import org.fdroid.fdroid.net.HttpDownloader;
@ -68,6 +74,7 @@ import java.util.TimerTask;
*/
@SuppressWarnings("LineLength")
public class SwapWorkflowActivity extends AppCompatActivity {
private static final String TAG = "SwapWorkflowActivity";
/**
* When connecting to a swap, we then go and initiate a connection with that
@ -87,28 +94,6 @@ public class SwapWorkflowActivity extends AppCompatActivity {
private ViewGroup container;
/**
* A UI component (subclass of {@link View}) which forms part of the swap workflow.
* There is a one to one mapping between an {@link org.fdroid.fdroid.views.swap.SwapWorkflowActivity.InnerView}
* and a {@link SwapService.SwapStep}, and these views know what
* the previous view before them should be.
*/
public interface InnerView {
/** @return True if the menu should be shown. */
boolean buildMenu(Menu menu, @NonNull MenuInflater inflater);
/** @return The step that this view represents. */
@SwapService.SwapStep int getStep();
@SwapService.SwapStep int getPreviousStep();
@ColorRes int getToolbarColour();
String getToolbarTitle();
}
private static final String TAG = "SwapWorkflowActivity";
private static final int CONNECT_TO_SWAP = 1;
private static final int REQUEST_BLUETOOTH_ENABLE_FOR_SWAP = 2;
private static final int REQUEST_BLUETOOTH_DISCOVERABLE = 3;
@ -116,7 +101,7 @@ public class SwapWorkflowActivity extends AppCompatActivity {
private static final int REQUEST_WRITE_SETTINGS_PERMISSION = 5;
private Toolbar toolbar;
private InnerView currentView;
private SwapView currentView;
private boolean hasPreparedLocalRepo;
private PrepareSwapRepo updateSwappableAppsTask;
private NewRepoConfig confirmSwapConfig;
@ -165,12 +150,50 @@ public class SwapWorkflowActivity extends AppCompatActivity {
@Override
public void onBackPressed() {
if (currentView.getStep() == SwapService.STEP_INTRO) {
SwapService.stop(this);
if (currentView.getLayoutResId() == SwapService.STEP_INTRO) {
SwapService.stop(this); // TODO SwapService should always be running, while swap is running
finish();
} else {
int nextStep = currentView.getPreviousStep();
getService().setStep(nextStep);
// TODO: Currently StartSwapView is handleed by the SwapWorkflowActivity as a special case, where
// if getLayoutResId is STEP_INTRO, don't even bother asking for getPreviousStep. But that is a
// bit messy. It would be nicer if this was handled using the same mechanism as everything
// else.
int nextStep = -1;
switch (currentView.getLayoutResId()) {
case R.layout.swap_confirm_receive:
nextStep = SwapService.STEP_INTRO;
break;
case R.layout.swap_connecting:
nextStep = R.layout.swap_select_apps;
break;
case R.layout.swap_initial_loading:
nextStep = R.layout.swap_join_wifi;
break;
case R.layout.swap_join_wifi:
nextStep = SwapService.STEP_INTRO;
break;
case R.layout.swap_nfc:
nextStep = R.layout.swap_join_wifi;
break;
case R.layout.swap_select_apps:
// TODO: The STEP_JOIN_WIFI step isn't shown first, need to make it
// so that it is, or so that this doesn't go back there.
nextStep = getState().isConnectingWithPeer() ? SwapService.STEP_INTRO : R.layout.swap_join_wifi;
break;
case R.layout.swap_send_fdroid:
nextStep = SwapService.STEP_INTRO;
break;
case R.layout.swap_start_swap:
nextStep = SwapService.STEP_INTRO;
break;
case R.layout.swap_success:
nextStep = SwapService.STEP_INTRO;
break;
case R.layout.swap_wifi_qr:
nextStep = R.layout.swap_join_wifi;
break;
}
getService().setCurrentView(nextStep);
showRelevantView();
}
}
@ -194,7 +217,7 @@ public class SwapWorkflowActivity extends AppCompatActivity {
toolbar.setTitleTextAppearance(getApplicationContext(), R.style.SwapTheme_Wizard_Text_Toolbar);
setSupportActionBar(toolbar);
container = (ViewGroup) findViewById(R.id.fragment_container);
container = (ViewGroup) findViewById(R.id.container);
localBroadcastManager = LocalBroadcastManager.getInstance(this);
wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
@ -211,9 +234,99 @@ public class SwapWorkflowActivity extends AppCompatActivity {
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
menu.clear();
boolean parent = super.onPrepareOptionsMenu(menu);
boolean inner = currentView != null && currentView.buildMenu(menu, getMenuInflater());
return parent || inner;
MenuInflater menuInflater = getMenuInflater();
switch (currentView.getLayoutResId()) {
case R.layout.swap_select_apps:
menuInflater.inflate(R.menu.swap_next_search, menu);
setUpNextButton(menu, R.string.next);
setUpSearchView(menu);
return true;
case R.layout.swap_success:
menuInflater.inflate(R.menu.swap_search, menu);
setUpSearchView(menu);
return true;
case R.layout.swap_join_wifi:
menuInflater.inflate(R.menu.swap_next, menu);
setUpNextButton(menu, R.string.next);
return true;
case R.layout.swap_nfc:
menuInflater.inflate(R.menu.swap_next, menu);
setUpNextButton(menu, R.string.skip);
return true;
}
return super.onPrepareOptionsMenu(menu);
}
private void setUpNextButton(Menu menu, @StringRes int titleResId) {
MenuItem next = menu.findItem(R.id.action_next);
CharSequence title = getString(titleResId);
next.setTitle(title);
next.setTitleCondensed(title);
MenuItemCompat.setShowAsAction(next,
MenuItemCompat.SHOW_AS_ACTION_ALWAYS | MenuItemCompat.SHOW_AS_ACTION_WITH_TEXT);
next.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
sendNext();
return true;
}
});
}
void sendNext() {
int currentLayoutResId = currentView.getLayoutResId();
switch (currentLayoutResId) {
case R.layout.swap_select_apps:
onAppsSelected();
break;
case R.layout.swap_join_wifi:
inflateSwapView(R.layout.swap_select_apps);
break;
case R.layout.swap_nfc:
inflateSwapView(R.layout.swap_wifi_qr);
break;
}
}
private void setUpSearchView(Menu menu) {
SearchView searchView = new SearchView(this);
MenuItem searchMenuItem = menu.findItem(R.id.action_search);
MenuItemCompat.setActionView(searchMenuItem, searchView);
MenuItemCompat.setShowAsAction(searchMenuItem, MenuItemCompat.SHOW_AS_ACTION_IF_ROOM);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String newText) {
String currentFilterString = currentView.getCurrentFilterString();
String newFilter = !TextUtils.isEmpty(newText) ? newText : null;
if (currentFilterString == null && newFilter == null) {
return true;
}
if (currentFilterString != null && currentFilterString.equals(newFilter)) {
return true;
}
currentView.setCurrentFilterString(newFilter);
if (currentView instanceof SelectAppsView) {
getSupportLoaderManager().restartLoader(currentView.getLayoutResId(), null,
(SelectAppsView) currentView);
} else if (currentView instanceof SwapSuccessView) {
getSupportLoaderManager().restartLoader(currentView.getLayoutResId(), null,
(SwapSuccessView) currentView);
} else {
throw new IllegalStateException(currentView.getClass() + " does not have Loader!");
}
return true;
}
@Override
public boolean onQueryTextChange(String s) {
return true;
}
});
}
@Override
@ -310,7 +423,7 @@ public class SwapWorkflowActivity extends AppCompatActivity {
private void showRelevantView(boolean forceReload) {
if (service == null) {
showInitialLoading();
inflateSwapView(R.layout.swap_initial_loading);
return;
}
@ -323,62 +436,50 @@ public class SwapWorkflowActivity extends AppCompatActivity {
return;
}
if (!forceReload && (container.getVisibility() == View.GONE || currentView != null && currentView.getStep() == service.getStep())) {
if (!forceReload && (container.getVisibility() == View.GONE || currentView != null && currentView.getLayoutResId() == service.getCurrentView())) {
// Already showing the correct step, so don't bother changing anything.
return;
}
switch (service.getStep()) {
int currentView = service.getCurrentView();
switch (currentView) {
case SwapService.STEP_INTRO:
showIntro();
break;
case SwapService.STEP_SELECT_APPS:
showSelectApps();
break;
case SwapService.STEP_SHOW_NFC:
showNfc();
break;
case SwapService.STEP_JOIN_WIFI:
showJoinWifi();
break;
case SwapService.STEP_WIFI_QR:
showWifiQr();
break;
case SwapService.STEP_SUCCESS:
showSwapConnected();
break;
case SwapService.STEP_CONNECTING:
// TODO: Properly decide what to do here (i.e. returning to the activity after it was connecting)...
inflateInnerView(R.layout.swap_blank);
break;
return;
case R.layout.swap_nfc:
if (!attemptToShowNfc()) {
inflateSwapView(R.layout.swap_wifi_qr);
return;
}
break;
case R.layout.swap_connecting:
// TODO: Properly decide what to do here (i.e. returning to the activity after it was connecting)...
inflateSwapView(R.layout.swap_start_swap);
return;
}
inflateSwapView(currentView);
}
public SwapService getState() {
return service;
}
private void showNfc() {
if (!attemptToShowNfc()) {
showWifiQr();
}
}
private InnerView inflateInnerView(@LayoutRes int viewRes) {
public SwapView inflateSwapView(@LayoutRes int viewRes) {
container.removeAllViews();
View view = ((LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE)).inflate(viewRes, container, false);
currentView = (InnerView) view;
currentView = (SwapView) view;
currentView.setLayoutResId(viewRes);
// Don't actually set the step to STEP_INITIAL_LOADING, as we are going to use this view
// purely as a placeholder for _whatever view is meant to be shown_.
if (currentView.getStep() != SwapService.STEP_INITIAL_LOADING) {
if (currentView.getLayoutResId() != R.layout.swap_initial_loading) {
if (service == null) {
throw new IllegalStateException("We are not in the STEP_INITIAL_LOADING state, but the service is not ready.");
}
service.setStep(currentView.getStep());
service.setCurrentView(currentView.getLayoutResId());
}
toolbar.setBackgroundColor(getResources().getColor(currentView.getToolbarColour()));
toolbar.setBackgroundColor(currentView.getToolbarColour());
toolbar.setTitle(currentView.getToolbarTitle());
toolbar.setNavigationIcon(R.drawable.ic_close_white_24dp);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@ -398,10 +499,6 @@ public class SwapWorkflowActivity extends AppCompatActivity {
finish();
}
private void showInitialLoading() {
inflateInnerView(R.layout.swap_initial_loading);
}
public void showIntro() {
// If we were previously swapping with a specific client, forget that we were doing that,
// as we are starting over now.
@ -414,11 +511,13 @@ public class SwapWorkflowActivity extends AppCompatActivity {
}
}
inflateInnerView(R.layout.swap_blank);
inflateSwapView(R.layout.swap_start_swap);
}
private void showConfirmSwap(@NonNull NewRepoConfig config) {
((ConfirmReceive) inflateInnerView(R.layout.swap_confirm_receive)).setup(config);
((ConfirmReceiveView) inflateSwapView(R.layout.swap_confirm_receive)).setup(config);
TextView descriptionTextView = (TextView) findViewById(R.id.text_description);
descriptionTextView.setText(getResources().getString(R.string.swap_confirm_connect, config.getHost()));
}
public void startQrWorkflow() {
@ -435,14 +534,10 @@ public class SwapWorkflowActivity extends AppCompatActivity {
})
.create().show();
} else {
showWifiQr();
inflateSwapView(R.layout.swap_wifi_qr);
}
}
public void showSelectApps() {
inflateInnerView(R.layout.swap_select_apps);
}
/**
* On {@code android-26}, only apps with privileges can access
* {@code WRITE_SETTINGS}. So this just shows the tethering settings
@ -471,7 +566,7 @@ public class SwapWorkflowActivity extends AppCompatActivity {
if (adapter == null
|| Build.VERSION.SDK_INT >= 23 // TODO make Bluetooth work with content:// URIs
|| (!adapter.isEnabled() && getService().getWifiSwap().isConnected())) {
showSendFDroid();
inflateSwapView(R.layout.swap_send_fdroid);
} else {
sendFDroidBluetooth();
}
@ -503,8 +598,8 @@ public class SwapWorkflowActivity extends AppCompatActivity {
if (updateSwappableAppsTask == null && !hasPreparedLocalRepo) {
updateSwappableAppsTask = new PrepareSwapRepo(getService().getAppsToSwap());
updateSwappableAppsTask.execute();
getService().setStep(SwapService.STEP_CONNECTING);
inflateInnerView(R.layout.swap_connecting);
getService().setCurrentView(R.layout.swap_connecting);
inflateSwapView(R.layout.swap_connecting);
} else {
onLocalRepoPrepared();
}
@ -524,29 +619,13 @@ public class SwapWorkflowActivity extends AppCompatActivity {
if (getService().isConnectingWithPeer()) {
startSwappingWithPeer();
} else if (!attemptToShowNfc()) {
showWifiQr();
inflateSwapView(R.layout.swap_wifi_qr);
}
}
private void startSwappingWithPeer() {
getService().connectToPeer();
inflateInnerView(R.layout.swap_connecting);
}
private void showJoinWifi() {
inflateInnerView(R.layout.swap_join_wifi);
}
public void showWifiQr() {
inflateInnerView(R.layout.swap_wifi_qr);
}
public void showSendFDroid() {
inflateInnerView(R.layout.swap_send_fdroid);
}
public void showSwapConnected() {
inflateInnerView(R.layout.swap_success);
inflateSwapView(R.layout.swap_connecting);
}
private boolean attemptToShowNfc() {
@ -559,7 +638,7 @@ public class SwapWorkflowActivity extends AppCompatActivity {
boolean nfcMessageReady = NfcHelper.setPushMessage(this, Utils.getSharingUri(FDroidApp.repo));
if (Preferences.get().showNfcDuringSwap() && nfcMessageReady) {
inflateInnerView(R.layout.swap_nfc);
inflateSwapView(R.layout.swap_nfc);
return true;
}
return false;
@ -567,7 +646,7 @@ public class SwapWorkflowActivity extends AppCompatActivity {
public void swapWith(Peer peer) {
getService().swapWith(peer);
showSelectApps();
inflateSwapView(R.layout.swap_select_apps);
}
/**
@ -580,7 +659,7 @@ public class SwapWorkflowActivity extends AppCompatActivity {
*/
public void swapWith(NewRepoConfig repoConfig) {
Peer peer = repoConfig.toPeer();
if (getService().getStep() == SwapService.STEP_INTRO || getService().getStep() == SwapService.STEP_CONFIRM_SWAP) {
if (getService().getCurrentView() == SwapService.STEP_INTRO || getService().getCurrentView() == R.layout.swap_confirm_receive) {
// This will force the "Select apps to swap" workflow to begin.
// TODO: Find a better way to decide whether we need to select the apps. Not sure if we
// can or cannot be in STEP_INTRO with a full blown repo ready to swap.
@ -784,15 +863,14 @@ public class SwapWorkflowActivity extends AppCompatActivity {
* the harder it becomes to reason about and debug the whole thing. Thus,this class
* will periodically dump the state to logcat so that it is easier to see when certain
* protocols are enabled/disabled.
*
* <p>
* To view only this output from logcat:
*
* <p>
* adb logcat | grep 'Swap Status'
*
* <p>
* To exclude this output from logcat (it is very noisy):
*
* <p>
* adb logcat | grep -v 'Swap Status'
*
*/
class SwapDebug {

View File

@ -7,31 +7,26 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.LightingColorFilter;
import android.net.Uri;
import android.support.annotation.ColorRes;
import android.support.annotation.NonNull;
import android.support.v4.content.LocalBroadcastManager;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ScrollView;
import android.widget.TextView;
import org.fdroid.fdroid.FDroidApp;
import org.fdroid.fdroid.Preferences;
import org.fdroid.fdroid.QrGenAsyncTask;
import org.fdroid.fdroid.R;
import org.fdroid.fdroid.Utils;
import org.fdroid.fdroid.localrepo.SwapService;
import org.fdroid.fdroid.localrepo.SwapView;
import org.fdroid.fdroid.net.WifiStateChangeService;
import org.fdroid.fdroid.views.swap.device.camera.CameraCharacteristicsChecker;
import java.util.Locale;
import java.util.Set;
public class WifiQrView extends ScrollView implements SwapWorkflowActivity.InnerView {
public class WifiQrView extends SwapView {
private static final String TAG = "WifiQrView";
@ -52,10 +47,6 @@ public class WifiQrView extends ScrollView implements SwapWorkflowActivity.Inner
super(context, attrs, defStyleAttr, defStyleRes);
}
private SwapWorkflowActivity getActivity() {
return (SwapWorkflowActivity) getContext();
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
@ -98,32 +89,6 @@ public class WifiQrView extends ScrollView implements SwapWorkflowActivity.Inner
LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(onWifiStateChanged);
}
@Override
public boolean buildMenu(Menu menu, @NonNull MenuInflater inflater) {
return false;
}
@Override
public int getStep() {
return SwapService.STEP_WIFI_QR;
}
@Override
public int getPreviousStep() {
// TODO: Find a way to make this optionally go back to the NFC screen if appropriate.
return SwapService.STEP_JOIN_WIFI;
}
@ColorRes
public int getToolbarColour() {
return R.color.swap_blue;
}
@Override
public String getToolbarTitle() {
return getResources().getString(R.string.swap_scan_qr);
}
private void setUIFromWifi() {
if (TextUtils.isEmpty(FDroidApp.repo.address)) {

View File

@ -1,11 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/header"
android:layout_width="match_parent"
android:layout_height="130dp"
android:layout_alignParentTop="true"
tools:showIn="@layout/swap_blank">
tools:showIn="@layout/swap_start_swap">
<ImageView
android:layout_width="match_parent"

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/header"
android:layout_width="match_parent"
android:layout_height="wrap_content"

View File

@ -17,7 +17,7 @@
tools:ignore="UnusedAttribute"/>
<FrameLayout
android:id="@+id/fragment_container"
android:id="@+id/container"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>

View File

@ -1,210 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- TODO: Add paddingStart in places where there is only paddingLeft. However Android Studio lint
gives an error, which is discussed here:
http://stackoverflow.com/questions/27449776/conflicting-lint-messages-regarding-paddingstart-usage?lq=1
-->
<org.fdroid.fdroid.views.swap.StartSwapView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".views.swap.SwapWorkflowActivity">
<!-- Misc header -->
<include layout="@layout/start_swap_header" />
<!-- Bluetooth swap status + toggle -->
<LinearLayout
android:id="@+id/bluetooth_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/header"
android:padding="10dp"
android:orientation="horizontal">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:tint="@color/swap_grey_icon"
android:src="@drawable/ic_bluetooth_white" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingLeft="15dp"
android:paddingStart="15dp"
android:layout_weight="1.00"
tools:ignore="RtlSymmetry">
<TextView
android:id="@+id/bluetooth_visible"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="@string/swap_visible_bluetooth"
android:textSize="18sp" />
<TextView
android:id="@+id/device_id_bluetooth"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="SP-120"
android:textColor="@color/swap_light_text" />
</LinearLayout>
<android.support.v7.widget.SwitchCompat
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:enabled="false"
android:id="@+id/switch_bluetooth" />
</LinearLayout>
<!-- WiFi swap status + toggle -->
<LinearLayout
android:id="@+id/wifi_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/bluetooth_info"
android:padding="10dp"
android:orientation="horizontal">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:tint="@color/swap_grey_icon"
android:src="@drawable/ic_network_wifi_white" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingLeft="15dp"
android:paddingStart="15dp"
android:layout_weight="1.00"
tools:ignore="RtlSymmetry">
<TextView
android:id="@+id/wifi_visible"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="@string/swap_not_visible_wifi"
android:textSize="18sp" />
<TextView
android:id="@+id/device_id_wifi"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/swap_wifi_device_name"
android:textColor="@color/swap_light_text" />
<TextView
android:id="@+id/wifi_network"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="wifi network name"
android:textColor="@color/swap_bright_blue"
android:textSize="16sp" />
</LinearLayout>
<android.support.v7.widget.SwitchCompat
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:enabled="false"
android:id="@+id/switch_wifi" />
</LinearLayout>
<!-- Feedback for "searching for nearby people..." -->
<LinearLayout
android:id="@+id/feedback_searching"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/wifi_info"
android:paddingStart="20dp"
android:paddingEnd="20dp"
android:paddingBottom="5dp"
android:paddingTop="20dp">
<TextView
android:id="@+id/text_people_nearby"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@string/swap_people_nearby"
android:textColor="@color/swap_light_text"
android:layout_weight="1.00"/>
<ProgressBar
android:id="@+id/searching_people_nearby"
android:layout_width="24dp"
android:layout_height="24dp"
android:indeterminate="true" />
</LinearLayout>
<!-- Buttons to help the user when they can't find any peers. Shown at bottom of relative layout -->
<LinearLayout
android:id="@+id/cant_find_peers"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true">
<Button
android:id="@+id/btn_send_fdroid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableLeft="@drawable/ic_fdroid_grey"
android:drawableStart="@drawable/ic_fdroid_grey"
android:text="@string/swap_send_fdroid"
android:drawablePadding="10dp"
android:paddingLeft="25dp"
android:paddingRight="25dp"
android:paddingEnd="25dp"
android:background="@android:color/transparent" />
<Button
android:id="@+id/btn_qr_scanner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableLeft="@drawable/ic_qr_grey"
android:drawableStart="@drawable/ic_qr_grey"
android:text="@string/swap_scan_qr"
android:drawablePadding="10dp"
android:paddingLeft="25dp"
android:paddingRight="25dp"
android:paddingEnd="25dp"
android:background="@android:color/transparent" />
</LinearLayout>
<!-- Heading for "can't find peers" -->
<TextView
android:id="@+id/header_cant_find_peers"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@id/cant_find_peers"
android:text="@string/swap_cant_find_peers"
android:paddingLeft="20dp"
android:paddingStart="20dp"
android:paddingRight="20dp"
android:paddingEnd="20dp"
android:paddingTop="20dp"
android:textColor="@color/swap_light_text" />
<!-- List of all currently known peers (i.e. bluetooth and wifi devices that have been identified -->
<ListView
android:id="@+id/list_people_nearby"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/feedback_searching"
android:layout_above="@id/header_cant_find_peers">
</ListView>
</org.fdroid.fdroid.views.swap.StartSwapView>

View File

@ -1,7 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<org.fdroid.fdroid.views.swap.ConfirmReceive xmlns:android="http://schemas.android.com/apk/res/android"
<org.fdroid.fdroid.views.swap.ConfirmReceiveView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:swap="http://schemas.android.com/apk/res-auto"
swap:toolbarTitle="@string/swap_confirm"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
@ -73,4 +76,4 @@
</LinearLayout>
</org.fdroid.fdroid.views.swap.ConfirmReceive>
</org.fdroid.fdroid.views.swap.ConfirmReceiveView>

View File

@ -1,8 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<org.fdroid.fdroid.views.swap.SwapConnecting
<org.fdroid.fdroid.views.swap.ConnectingView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:swap="http://schemas.android.com/apk/res-auto"
swap:toolbarColor="@color/swap_bright_blue"
swap:toolbarTitle="@string/swap_connecting"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
@ -11,40 +13,40 @@
android:id="@+id/heading"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:textSize="20sp"
android:padding="30dp"
android:textAlignment="center"
android:gravity="center"
tools:text="Connecting with Nexus 4"
tools:ignore="UnusedAttribute" />
android:gravity="center"/>
<ProgressBar
android:id="@+id/progress_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminate="true"
android:layout_gravity="center" />
android:layout_centerInParent="true"
android:layout_below="@+id/heading"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:id="@+id/error"
android:textSize="20sp"
android:textAlignment="center"
android:gravity="center"
android:text="@string/swap_connection_misc_error"
android:visibility="gone"
android:padding="30dp"
tools:ignore="UnusedAttribute" />
android:padding="30dp"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_below="@+id/error"
android:id="@+id/back"
android:backgroundTint="@color/swap_light_blue"
android:textColor="@android:color/white"
android:layout_gravity="center_horizontal"
android:visibility="gone"
android:text="@string/back"
tools:ignore="UnusedAttribute" />
android:text="@string/back"/>
</org.fdroid.fdroid.views.swap.SwapConnecting>
</org.fdroid.fdroid.views.swap.ConnectingView>

View File

@ -1,6 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<org.fdroid.fdroid.views.swap.InitialLoadingView xmlns:android="http://schemas.android.com/apk/res/android"
<org.fdroid.fdroid.localrepo.SwapView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:swap="http://schemas.android.com/apk/res-auto"
swap:toolbarTitle="@string/swap"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
@ -23,4 +26,4 @@
android:textColor="@android:color/white"
android:layout_centerHorizontal="true"/>
</org.fdroid.fdroid.views.swap.InitialLoadingView>
</org.fdroid.fdroid.localrepo.SwapView>

View File

@ -1,10 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<org.fdroid.fdroid.views.swap.JoinWifiView xmlns:android="http://schemas.android.com/apk/res/android"
<org.fdroid.fdroid.views.swap.JoinWifiView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:swap="http://schemas.android.com/apk/res-auto"
swap:toolbarTitle="@string/swap_join_same_wifi"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
android:background="@color/swap_blue"
tools:context=".views.swap.SwapWorkflowActivity">

View File

@ -1,6 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<org.fdroid.fdroid.views.swap.NfcView xmlns:android="http://schemas.android.com/apk/res/android"
<org.fdroid.fdroid.views.swap.NfcView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:swap="http://schemas.android.com/apk/res-auto"
swap:toolbarTitle="@string/swap_nfc_title"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"

View File

@ -2,8 +2,17 @@
<org.fdroid.fdroid.views.swap.SelectAppsView
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
xmlns:swap="http://schemas.android.com/apk/res-auto"
swap:toolbarColor="@color/swap_bright_blue"
swap:toolbarTitle="@string/swap_choose_apps"
android:id="@+id/select_apps"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"/>
</org.fdroid.fdroid.views.swap.SelectAppsView>

View File

@ -3,10 +3,13 @@
<org.fdroid.fdroid.views.swap.SendFDroidView
xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:swap="http://schemas.android.com/apk/res-auto"
swap:toolbarTitle="@string/swap_send_fdroid"
android:background="@color/swap_blue"
android:layout_height="match_parent"
android:layout_width="wrap_content">
<ScrollView android:layout_width="match_parent" android:layout_height="match_parent">
<LinearLayout android:orientation="vertical"
android:gravity="center"
android:layout_width="wrap_content"
@ -46,5 +49,5 @@
style="@style/SwapTheme.Wizard.QRScanWarningText"/>
</LinearLayout>
</ScrollView>
</org.fdroid.fdroid.views.swap.SendFDroidView>

View File

@ -0,0 +1,213 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- TODO: Add paddingStart in places where there is only paddingLeft. However Android Studio lint
gives an error, which is discussed here:
http://stackoverflow.com/questions/27449776/conflicting-lint-messages-regarding-paddingstart-usage?lq=1
-->
<org.fdroid.fdroid.views.swap.StartSwapView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:swap="http://schemas.android.com/apk/res-auto"
swap:toolbarColor="@color/swap_bright_blue"
swap:toolbarTitle="@string/swap_nearby"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".views.swap.SwapWorkflowActivity">
<!-- Misc header -->
<include layout="@layout/start_swap_header"/>
<!-- Bluetooth swap status + toggle -->
<LinearLayout
android:id="@+id/bluetooth_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/header"
android:padding="10dp"
android:orientation="horizontal">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:tint="@color/swap_grey_icon"
android:src="@drawable/ic_bluetooth_white"/>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingLeft="15dp"
android:paddingStart="15dp"
android:layout_weight="1.00"
tools:ignore="RtlSymmetry">
<TextView
android:id="@+id/bluetooth_visible"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="@string/swap_visible_bluetooth"
android:textSize="18sp"/>
<TextView
android:id="@+id/device_id_bluetooth"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="SP-120"
android:textColor="@color/swap_light_text"/>
</LinearLayout>
<android.support.v7.widget.SwitchCompat
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:enabled="false"
android:id="@+id/switch_bluetooth"/>
</LinearLayout>
<!-- WiFi swap status + toggle -->
<LinearLayout
android:id="@+id/wifi_info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/bluetooth_info"
android:padding="10dp"
android:orientation="horizontal">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:tint="@color/swap_grey_icon"
android:src="@drawable/ic_network_wifi_white"/>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingLeft="15dp"
android:paddingStart="15dp"
android:layout_weight="1.00"
tools:ignore="RtlSymmetry">
<TextView
android:id="@+id/wifi_visible"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="@string/swap_not_visible_wifi"
android:textSize="18sp"/>
<TextView
android:id="@+id/device_id_wifi"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/swap_wifi_device_name"
android:textColor="@color/swap_light_text"/>
<TextView
android:id="@+id/wifi_network"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="wifi network name"
android:textColor="@color/swap_bright_blue"
android:textSize="16sp"/>
</LinearLayout>
<android.support.v7.widget.SwitchCompat
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:enabled="false"
android:id="@+id/switch_wifi"/>
</LinearLayout>
<!-- Feedback for "searching for nearby people..." -->
<LinearLayout
android:id="@+id/feedback_searching"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/wifi_info"
android:paddingStart="20dp"
android:paddingEnd="20dp"
android:paddingBottom="5dp"
android:paddingTop="20dp">
<TextView
android:id="@+id/text_people_nearby"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@string/swap_people_nearby"
android:textColor="@color/swap_light_text"
android:layout_weight="1.00"/>
<ProgressBar
android:id="@+id/searching_people_nearby"
android:layout_width="24dp"
android:layout_height="24dp"
android:indeterminate="true"/>
</LinearLayout>
<!-- Buttons to help the user when they can't find any peers. Shown at bottom of relative layout -->
<LinearLayout
android:id="@+id/cant_find_peers"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true">
<Button
android:id="@+id/btn_send_fdroid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableLeft="@drawable/ic_fdroid_grey"
android:drawableStart="@drawable/ic_fdroid_grey"
android:text="@string/swap_send_fdroid"
android:drawablePadding="10dp"
android:paddingLeft="25dp"
android:paddingRight="25dp"
android:paddingEnd="25dp"
android:background="@android:color/transparent"/>
<Button
android:id="@+id/btn_qr_scanner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableLeft="@drawable/ic_qr_grey"
android:drawableStart="@drawable/ic_qr_grey"
android:text="@string/swap_scan_qr"
android:drawablePadding="10dp"
android:paddingLeft="25dp"
android:paddingRight="25dp"
android:paddingEnd="25dp"
android:background="@android:color/transparent"/>
</LinearLayout>
<!-- Heading for "can't find peers" -->
<TextView
android:id="@+id/header_cant_find_peers"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@id/cant_find_peers"
android:text="@string/swap_cant_find_peers"
android:paddingLeft="20dp"
android:paddingStart="20dp"
android:paddingRight="20dp"
android:paddingEnd="20dp"
android:paddingTop="20dp"
android:textColor="@color/swap_light_text"/>
<!-- List of all currently known peers (i.e. bluetooth and wifi devices that have been identified -->
<ListView
android:id="@+id/list_people_nearby"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/feedback_searching"
android:layout_above="@id/header_cant_find_peers">
</ListView>
</org.fdroid.fdroid.views.swap.StartSwapView>

View File

@ -1,9 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<org.fdroid.fdroid.views.swap.SwapAppsView
<org.fdroid.fdroid.views.swap.SwapSuccessView
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
xmlns:swap="http://schemas.android.com/apk/res-auto"
swap:toolbarColor="@color/swap_bright_blue"
swap:toolbarTitle="@string/swap_success"
android:id="@+id/swap_success"
android:layout_width="match_parent"
android:layout_height="match_parent">
</org.fdroid.fdroid.views.swap.SwapAppsView>
<ListView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"/>
</org.fdroid.fdroid.views.swap.SwapSuccessView>

View File

@ -3,10 +3,13 @@
<org.fdroid.fdroid.views.swap.WifiQrView
xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:swap="http://schemas.android.com/apk/res-auto"
swap:toolbarTitle="@string/swap_scan_qr"
android:background="@color/swap_blue"
android:layout_height="match_parent"
android:layout_width="wrap_content">
<ScrollView android:layout_width="match_parent" android:layout_height="match_parent">
<LinearLayout android:orientation="vertical"
android:gravity="center"
android:layout_width="wrap_content"
@ -53,5 +56,5 @@
style="@style/SwapTheme.Wizard.QRScanWarningText"/>
</LinearLayout>
</ScrollView>
</org.fdroid.fdroid.views.swap.WifiQrView>

View File

@ -1,12 +0,0 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/action_next"
android:icon="@drawable/ic_arrow_forward_white"
android:title="@string/skip"
android:titleCondensed="@string/skip"/>
<!-- Currently in a style, but that style probably wont work on 8 -> 11 devices -->
<!--android:drawable="@drawable/swap_action_button_skin"-->
</menu>

View File

@ -3,4 +3,8 @@
<integer name="unhidePin">1337</integer>
<declare-styleable name="SwapView">
<attr name="toolbarColor" format="color"/>
<attr name="toolbarTitle" format="string"/>
</declare-styleable>
</resources>