SwapView base class so all swap views can just be XML
Almost all of the nearby/swap view classes could be condensed into a single base class that is instantiated in the view XML. This is the first step towards making that happen. It also lays the groundwork where "steps" are all SwapViews. The original concept of "steps" put all steps together, whether F-Droid could control them or not. For example, the Views were mixed with the system Bluetooth prompts. This is the first step towards converting the steps to always be SwapViews, which are always under control of this app. When coming back to a SwapView/step, it does not seem feasible to handle automatically restarting things like permissions and Bluetooth prompts. If there is a way, it should be possible to first load the proper SwapView instance, then trigger the system prompt. The makes the SwapView a pure View, without any Controller in it.
This commit is contained in:
parent
6a8f5fb4a7
commit
fe59522666
@ -15,7 +15,7 @@ import android.net.Uri;
|
|||||||
import android.net.wifi.WifiManager;
|
import android.net.wifi.WifiManager;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.support.annotation.IntDef;
|
import android.support.annotation.LayoutRes;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v4.app.NotificationCompat;
|
import android.support.v4.app.NotificationCompat;
|
||||||
@ -46,8 +46,6 @@ import rx.schedulers.Schedulers;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.OutputStreamWriter;
|
import java.io.OutputStreamWriter;
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -129,43 +127,21 @@ public class SwapService extends Service {
|
|||||||
return peerFinder;
|
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_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_SWAP_SUCCESS = 7;
|
|
||||||
public static final int STEP_CONFIRM_SWAP = 8;
|
|
||||||
|
|
||||||
/**
|
@LayoutRes
|
||||||
* Special view, that we don't really want to actually store against the
|
private int currentView = STEP_INTRO;
|
||||||
* {@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;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Current screen that the swap process is up to.
|
* Current screen that the swap process is up to.
|
||||||
* Will be one of the SwapState.STEP_* values.
|
|
||||||
*/
|
*/
|
||||||
@SwapStep
|
@LayoutRes
|
||||||
public int getStep() {
|
public int getCurrentView() {
|
||||||
return step;
|
return currentView;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SwapService setStep(@SwapStep int step) {
|
public void setCurrentView(@LayoutRes int currentView) {
|
||||||
this.step = step;
|
this.currentView = currentView;
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@ -269,18 +245,6 @@ public class SwapService extends Service {
|
|||||||
return peerRepo;
|
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_SWAP_SUCCESS, STEP_CONFIRM_SWAP, STEP_INITIAL_LOADING})
|
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
|
||||||
public @interface SwapStep {
|
|
||||||
}
|
|
||||||
|
|
||||||
// =================================================
|
// =================================================
|
||||||
// Have selected a specific peer to swap with
|
// Have selected a specific peer to swap with
|
||||||
// (Rather than showing a generic QR code to scan)
|
// (Rather than showing a generic QR code to scan)
|
||||||
|
76
app/src/full/java/org/fdroid/fdroid/localrepo/SwapView.java
Normal file
76
app/src/full/java/org/fdroid/fdroid/localrepo/SwapView.java
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
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.view.Menu;
|
||||||
|
import android.view.MenuInflater;
|
||||||
|
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;
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean buildMenu(Menu menu, @NonNull MenuInflater inflater) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
@LayoutRes
|
||||||
|
public int getLayoutResId() {
|
||||||
|
return layoutResId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLayoutResId(@LayoutRes int layoutResId) {
|
||||||
|
this.layoutResId = layoutResId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SwapWorkflowActivity getActivity() {
|
||||||
|
return (SwapWorkflowActivity) getContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ColorInt
|
||||||
|
public int getToolbarColour() {
|
||||||
|
return toolbarColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getToolbarTitle() {
|
||||||
|
return toolbarTitle;
|
||||||
|
}
|
||||||
|
}
|
@ -2,19 +2,13 @@ package org.fdroid.fdroid.views.swap;
|
|||||||
|
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.support.annotation.ColorRes;
|
|
||||||
import android.support.annotation.NonNull;
|
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.Menu;
|
|
||||||
import android.view.MenuInflater;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.RelativeLayout;
|
|
||||||
import android.widget.TextView;
|
|
||||||
import org.fdroid.fdroid.R;
|
import org.fdroid.fdroid.R;
|
||||||
import org.fdroid.fdroid.data.NewRepoConfig;
|
import org.fdroid.fdroid.data.NewRepoConfig;
|
||||||
import org.fdroid.fdroid.localrepo.SwapService;
|
import org.fdroid.fdroid.localrepo.SwapView;
|
||||||
|
|
||||||
public class ConfirmReceiveView extends RelativeLayout implements SwapWorkflowActivity.InnerView {
|
public class ConfirmReceiveView extends SwapView {
|
||||||
|
|
||||||
private NewRepoConfig config;
|
private NewRepoConfig config;
|
||||||
|
|
||||||
@ -35,10 +29,6 @@ public class ConfirmReceiveView extends RelativeLayout implements SwapWorkflowAc
|
|||||||
super(context, attrs, defStyleAttr, defStyleRes);
|
super(context, attrs, defStyleAttr, defStyleRes);
|
||||||
}
|
}
|
||||||
|
|
||||||
private SwapWorkflowActivity getActivity() {
|
|
||||||
return (SwapWorkflowActivity) getContext();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onFinishInflate() {
|
protected void onFinishInflate() {
|
||||||
super.onFinishInflate();
|
super.onFinishInflate();
|
||||||
@ -58,34 +48,7 @@ public class ConfirmReceiveView extends RelativeLayout implements SwapWorkflowAc
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@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) {
|
public void setup(NewRepoConfig config) {
|
||||||
this.config = config;
|
this.config = config;
|
||||||
TextView descriptionTextView = (TextView) findViewById(R.id.text_description);
|
|
||||||
descriptionTextView.setText(getResources().getString(R.string.swap_confirm_connect, config.getHost()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,23 +5,17 @@ import android.content.BroadcastReceiver;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.support.annotation.ColorRes;
|
|
||||||
import android.support.annotation.NonNull;
|
|
||||||
import android.support.v4.content.LocalBroadcastManager;
|
import android.support.v4.content.LocalBroadcastManager;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.Menu;
|
|
||||||
import android.view.MenuInflater;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.ProgressBar;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import org.fdroid.fdroid.R;
|
import org.fdroid.fdroid.R;
|
||||||
import org.fdroid.fdroid.UpdateService;
|
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 ConnectingView extends SwapView {
|
||||||
public class ConnectingView extends LinearLayout implements SwapWorkflowActivity.InnerView {
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
private static final String TAG = "ConnectingView";
|
private static final String TAG = "ConnectingView";
|
||||||
@ -44,10 +38,6 @@ public class ConnectingView extends LinearLayout implements SwapWorkflowActivity
|
|||||||
super(context, attrs, defStyleAttr, defStyleRes);
|
super(context, attrs, defStyleAttr, defStyleRes);
|
||||||
}
|
}
|
||||||
|
|
||||||
private SwapWorkflowActivity getActivity() {
|
|
||||||
return (SwapWorkflowActivity) getContext();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onFinishInflate() {
|
protected void onFinishInflate() {
|
||||||
super.onFinishInflate();
|
super.onFinishInflate();
|
||||||
@ -116,7 +106,7 @@ public class ConnectingView extends LinearLayout implements SwapWorkflowActivity
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Listens for feedback about a repo update process taking place.
|
* 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 {
|
class ConnectSwapReceiver extends Receiver {
|
||||||
|
|
||||||
@ -146,7 +136,7 @@ public class ConnectingView extends LinearLayout implements SwapWorkflowActivity
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onComplete() {
|
protected void onComplete() {
|
||||||
getActivity().showSwapSuccess();
|
getActivity().inflateSwapView(R.layout.swap_success);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -165,6 +155,7 @@ public class ConnectingView extends LinearLayout implements SwapWorkflowActivity
|
|||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
|
||||||
TextView progressText = (TextView) findViewById(R.id.heading);
|
TextView progressText = (TextView) findViewById(R.id.heading);
|
||||||
|
ProgressBar progressBar = findViewById(R.id.progress_bar);
|
||||||
TextView errorText = (TextView) findViewById(R.id.error);
|
TextView errorText = (TextView) findViewById(R.id.error);
|
||||||
Button backButton = (Button) findViewById(R.id.back);
|
Button backButton = (Button) findViewById(R.id.back);
|
||||||
|
|
||||||
@ -177,11 +168,13 @@ public class ConnectingView extends LinearLayout implements SwapWorkflowActivity
|
|||||||
}
|
}
|
||||||
|
|
||||||
progressText.setVisibility(View.VISIBLE);
|
progressText.setVisibility(View.VISIBLE);
|
||||||
|
progressBar.setVisibility(View.VISIBLE);
|
||||||
errorText.setVisibility(View.GONE);
|
errorText.setVisibility(View.GONE);
|
||||||
backButton.setVisibility(View.GONE);
|
backButton.setVisibility(View.GONE);
|
||||||
|
|
||||||
if (isError(intent)) {
|
if (isError(intent)) {
|
||||||
progressText.setVisibility(View.GONE);
|
progressText.setVisibility(View.GONE);
|
||||||
|
progressBar.setVisibility(View.GONE);
|
||||||
errorText.setVisibility(View.VISIBLE);
|
errorText.setVisibility(View.VISIBLE);
|
||||||
backButton.setVisibility(View.VISIBLE);
|
backButton.setVisibility(View.VISIBLE);
|
||||||
return;
|
return;
|
||||||
@ -192,29 +185,4 @@ public class ConnectingView 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -6,7 +6,6 @@ import android.content.Context;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.net.wifi.WifiManager;
|
import android.net.wifi.WifiManager;
|
||||||
import android.support.annotation.ColorRes;
|
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.v4.content.LocalBroadcastManager;
|
import android.support.v4.content.LocalBroadcastManager;
|
||||||
import android.support.v4.view.MenuItemCompat;
|
import android.support.v4.view.MenuItemCompat;
|
||||||
@ -17,14 +16,13 @@ import android.view.MenuInflater;
|
|||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.RelativeLayout;
|
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import org.fdroid.fdroid.FDroidApp;
|
import org.fdroid.fdroid.FDroidApp;
|
||||||
import org.fdroid.fdroid.R;
|
import org.fdroid.fdroid.R;
|
||||||
import org.fdroid.fdroid.localrepo.SwapService;
|
import org.fdroid.fdroid.localrepo.SwapView;
|
||||||
import org.fdroid.fdroid.net.WifiStateChangeService;
|
import org.fdroid.fdroid.net.WifiStateChangeService;
|
||||||
|
|
||||||
public class JoinWifiView extends RelativeLayout implements SwapWorkflowActivity.InnerView {
|
public class JoinWifiView extends SwapView {
|
||||||
|
|
||||||
public JoinWifiView(Context context) {
|
public JoinWifiView(Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
@ -43,10 +41,6 @@ public class JoinWifiView extends RelativeLayout implements SwapWorkflowActivity
|
|||||||
super(context, attrs, defStyleAttr, defStyleRes);
|
super(context, attrs, defStyleAttr, defStyleRes);
|
||||||
}
|
}
|
||||||
|
|
||||||
private SwapWorkflowActivity getActivity() {
|
|
||||||
return (SwapWorkflowActivity) getContext();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onFinishInflate() {
|
protected void onFinishInflate() {
|
||||||
super.onFinishInflate();
|
super.onFinishInflate();
|
||||||
@ -115,33 +109,13 @@ public class JoinWifiView extends RelativeLayout implements SwapWorkflowActivity
|
|||||||
next.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
|
next.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public boolean onMenuItemClick(MenuItem item) {
|
public boolean onMenuItemClick(MenuItem item) {
|
||||||
getActivity().showSelectApps();
|
getActivity().inflateInnerView(R.layout.swap_select_apps);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
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() {
|
private final BroadcastReceiver onWifiStateChange = new BroadcastReceiver() {
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
@ -2,7 +2,6 @@ package org.fdroid.fdroid.views.swap;
|
|||||||
|
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.support.annotation.ColorRes;
|
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.v4.view.MenuItemCompat;
|
import android.support.v4.view.MenuItemCompat;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
@ -11,12 +10,11 @@ import android.view.MenuInflater;
|
|||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.widget.CheckBox;
|
import android.widget.CheckBox;
|
||||||
import android.widget.CompoundButton;
|
import android.widget.CompoundButton;
|
||||||
import android.widget.RelativeLayout;
|
|
||||||
import org.fdroid.fdroid.Preferences;
|
import org.fdroid.fdroid.Preferences;
|
||||||
import org.fdroid.fdroid.R;
|
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) {
|
public NfcView(Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
@ -35,10 +33,6 @@ public class NfcView extends RelativeLayout implements SwapWorkflowActivity.Inne
|
|||||||
super(context, attrs, defStyleAttr, defStyleRes);
|
super(context, attrs, defStyleAttr, defStyleRes);
|
||||||
}
|
}
|
||||||
|
|
||||||
private SwapWorkflowActivity getActivity() {
|
|
||||||
return (SwapWorkflowActivity) getContext();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onFinishInflate() {
|
protected void onFinishInflate() {
|
||||||
super.onFinishInflate();
|
super.onFinishInflate();
|
||||||
@ -60,30 +54,10 @@ public class NfcView extends RelativeLayout implements SwapWorkflowActivity.Inne
|
|||||||
next.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
|
next.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public boolean onMenuItemClick(MenuItem item) {
|
public boolean onMenuItemClick(MenuItem item) {
|
||||||
getActivity().showWifiQr();
|
getActivity().inflateInnerView(R.layout.swap_wifi_qr);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,6 @@ import android.graphics.PorterDuff;
|
|||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.ColorRes;
|
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v4.app.LoaderManager;
|
import android.support.v4.app.LoaderManager;
|
||||||
@ -32,14 +31,13 @@ import android.widget.CompoundButton;
|
|||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.ListView;
|
import android.widget.ListView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import org.fdroid.fdroid.R;
|
import org.fdroid.fdroid.R;
|
||||||
import org.fdroid.fdroid.data.InstalledAppProvider;
|
import org.fdroid.fdroid.data.InstalledAppProvider;
|
||||||
import org.fdroid.fdroid.data.Schema.InstalledAppTable;
|
import org.fdroid.fdroid.data.Schema.InstalledAppTable;
|
||||||
import org.fdroid.fdroid.localrepo.SwapService;
|
import org.fdroid.fdroid.localrepo.SwapService;
|
||||||
|
import org.fdroid.fdroid.localrepo.SwapView;
|
||||||
|
|
||||||
public class SelectAppsView extends ListView implements
|
public class SelectAppsView extends SwapView implements
|
||||||
SwapWorkflowActivity.InnerView,
|
|
||||||
LoaderManager.LoaderCallbacks<Cursor>,
|
LoaderManager.LoaderCallbacks<Cursor>,
|
||||||
SearchView.OnQueryTextListener {
|
SearchView.OnQueryTextListener {
|
||||||
|
|
||||||
@ -60,33 +58,31 @@ public class SelectAppsView extends ListView implements
|
|||||||
super(context, attrs, defStyleAttr, defStyleRes);
|
super(context, attrs, defStyleAttr, defStyleRes);
|
||||||
}
|
}
|
||||||
|
|
||||||
private SwapWorkflowActivity getActivity() {
|
|
||||||
return (SwapWorkflowActivity) getContext();
|
|
||||||
}
|
|
||||||
|
|
||||||
private SwapService getState() {
|
private SwapService getState() {
|
||||||
return getActivity().getState();
|
return getActivity().getState();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final int LOADER_INSTALLED_APPS = 253341534;
|
private static final int LOADER_INSTALLED_APPS = 253341534;
|
||||||
|
|
||||||
|
private ListView listView;
|
||||||
private AppListAdapter adapter;
|
private AppListAdapter adapter;
|
||||||
private String currentFilterString;
|
private String currentFilterString;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onFinishInflate() {
|
protected void onFinishInflate() {
|
||||||
super.onFinishInflate();
|
super.onFinishInflate();
|
||||||
adapter = new AppListAdapter(this, getContext(),
|
listView = findViewById(R.id.list);
|
||||||
|
adapter = new AppListAdapter(listView, getContext(),
|
||||||
getContext().getContentResolver().query(InstalledAppProvider.getContentUri(),
|
getContext().getContentResolver().query(InstalledAppProvider.getContentUri(),
|
||||||
InstalledAppTable.Cols.ALL, null, null, null));
|
InstalledAppTable.Cols.ALL, null, null, null));
|
||||||
|
|
||||||
setAdapter(adapter);
|
listView.setAdapter(adapter);
|
||||||
setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
|
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
|
||||||
|
|
||||||
// either reconnect with an existing loader or start a new one
|
// either reconnect with an existing loader or start a new one
|
||||||
getActivity().getSupportLoaderManager().initLoader(LOADER_INSTALLED_APPS, null, this);
|
getActivity().getSupportLoaderManager().initLoader(LOADER_INSTALLED_APPS, null, this);
|
||||||
|
|
||||||
setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||||
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
|
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
|
||||||
toggleAppSelected(position);
|
toggleAppSelected(position);
|
||||||
}
|
}
|
||||||
@ -118,28 +114,6 @@ public class SelectAppsView extends ListView implements
|
|||||||
return true;
|
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) {
|
private void toggleAppSelected(int position) {
|
||||||
Cursor c = (Cursor) adapter.getItem(position);
|
Cursor c = (Cursor) adapter.getItem(position);
|
||||||
String packageName = c.getString(c.getColumnIndex(InstalledAppTable.Cols.Package.NAME));
|
String packageName = c.getString(c.getColumnIndex(InstalledAppTable.Cols.Package.NAME));
|
||||||
@ -174,13 +148,13 @@ public class SelectAppsView extends ListView implements
|
|||||||
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
|
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
|
||||||
adapter.swapCursor(cursor);
|
adapter.swapCursor(cursor);
|
||||||
|
|
||||||
for (int i = 0; i < getCount(); i++) {
|
for (int i = 0; i < listView.getCount(); i++) {
|
||||||
Cursor c = (Cursor) getItemAtPosition(i);
|
Cursor c = (Cursor) listView.getItemAtPosition(i);
|
||||||
String packageName = c.getString(c.getColumnIndex(InstalledAppTable.Cols.Package.NAME));
|
String packageName = c.getString(c.getColumnIndex(InstalledAppTable.Cols.Package.NAME));
|
||||||
getState().ensureFDroidSelected();
|
getState().ensureFDroidSelected();
|
||||||
for (String selected : getState().getAppsToSwap()) {
|
for (String selected : getState().getAppsToSwap()) {
|
||||||
if (TextUtils.equals(packageName, selected)) {
|
if (TextUtils.equals(packageName, selected)) {
|
||||||
setItemChecked(i, true);
|
listView.setItemChecked(i, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,28 +7,23 @@ import android.content.Context;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.graphics.LightingColorFilter;
|
import android.graphics.LightingColorFilter;
|
||||||
import android.support.annotation.ColorRes;
|
|
||||||
import android.support.annotation.NonNull;
|
|
||||||
import android.support.v4.content.LocalBroadcastManager;
|
import android.support.v4.content.LocalBroadcastManager;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.Menu;
|
|
||||||
import android.view.MenuInflater;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.ScrollView;
|
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import org.fdroid.fdroid.FDroidApp;
|
import org.fdroid.fdroid.FDroidApp;
|
||||||
import org.fdroid.fdroid.Preferences;
|
import org.fdroid.fdroid.Preferences;
|
||||||
import org.fdroid.fdroid.QrGenAsyncTask;
|
import org.fdroid.fdroid.QrGenAsyncTask;
|
||||||
import org.fdroid.fdroid.R;
|
import org.fdroid.fdroid.R;
|
||||||
import org.fdroid.fdroid.Utils;
|
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.net.WifiStateChangeService;
|
||||||
import org.fdroid.fdroid.views.swap.device.camera.CameraCharacteristicsChecker;
|
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";
|
private static final String TAG = "SendFDroidView";
|
||||||
|
|
||||||
@ -49,10 +44,6 @@ public class SendFDroidView extends ScrollView implements SwapWorkflowActivity.I
|
|||||||
super(context, attrs, defStyleAttr, defStyleRes);
|
super(context, attrs, defStyleAttr, defStyleRes);
|
||||||
}
|
}
|
||||||
|
|
||||||
private SwapWorkflowActivity getActivity() {
|
|
||||||
return (SwapWorkflowActivity) getContext();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onFinishInflate() {
|
protected void onFinishInflate() {
|
||||||
super.onFinishInflate();
|
super.onFinishInflate();
|
||||||
@ -96,31 +87,6 @@ public class SendFDroidView extends ScrollView implements SwapWorkflowActivity.I
|
|||||||
LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(onWifiStateChanged);
|
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")
|
@SuppressLint("HardwareIds")
|
||||||
private void setUIFromWifi() {
|
private void setUIFromWifi() {
|
||||||
if (TextUtils.isEmpty(FDroidApp.repo.address)) {
|
if (TextUtils.isEmpty(FDroidApp.repo.address)) {
|
||||||
|
@ -7,16 +7,12 @@ import android.content.Context;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.net.wifi.WifiConfiguration;
|
import android.net.wifi.WifiConfiguration;
|
||||||
import android.support.annotation.ColorRes;
|
|
||||||
import android.support.annotation.NonNull;
|
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v4.content.LocalBroadcastManager;
|
import android.support.v4.content.LocalBroadcastManager;
|
||||||
import android.support.v7.widget.SwitchCompat;
|
import android.support.v7.widget.SwitchCompat;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.Menu;
|
|
||||||
import android.view.MenuInflater;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.AdapterView;
|
import android.widget.AdapterView;
|
||||||
@ -25,13 +21,13 @@ import android.widget.CompoundButton;
|
|||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.ListView;
|
import android.widget.ListView;
|
||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
import android.widget.RelativeLayout;
|
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import cc.mvdan.accesspoint.WifiApControl;
|
import cc.mvdan.accesspoint.WifiApControl;
|
||||||
import org.fdroid.fdroid.FDroidApp;
|
import org.fdroid.fdroid.FDroidApp;
|
||||||
import org.fdroid.fdroid.R;
|
import org.fdroid.fdroid.R;
|
||||||
import org.fdroid.fdroid.Utils;
|
import org.fdroid.fdroid.Utils;
|
||||||
import org.fdroid.fdroid.localrepo.SwapService;
|
import org.fdroid.fdroid.localrepo.SwapService;
|
||||||
|
import org.fdroid.fdroid.localrepo.SwapView;
|
||||||
import org.fdroid.fdroid.localrepo.peers.Peer;
|
import org.fdroid.fdroid.localrepo.peers.Peer;
|
||||||
import org.fdroid.fdroid.net.WifiStateChangeService;
|
import org.fdroid.fdroid.net.WifiStateChangeService;
|
||||||
import rx.Subscriber;
|
import rx.Subscriber;
|
||||||
@ -40,7 +36,7 @@ import rx.Subscription;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
@SuppressWarnings("LineLength")
|
@SuppressWarnings("LineLength")
|
||||||
public class StartSwapView extends RelativeLayout implements SwapWorkflowActivity.InnerView {
|
public class StartSwapView extends SwapView {
|
||||||
|
|
||||||
private static final String TAG = "StartSwapView";
|
private static final String TAG = "StartSwapView";
|
||||||
|
|
||||||
@ -58,7 +54,6 @@ public class StartSwapView extends RelativeLayout implements SwapWorkflowActivit
|
|||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TargetApi(11)
|
|
||||||
public StartSwapView(Context context, AttributeSet attrs, int defStyleAttr) {
|
public StartSwapView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||||
super(context, attrs, 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() {
|
private SwapService getManager() {
|
||||||
return getActivity().getState();
|
return getActivity().getState();
|
||||||
}
|
}
|
||||||
@ -456,35 +447,4 @@ public class StartSwapView extends RelativeLayout implements SwapWorkflowActivit
|
|||||||
private void onPeerSelected(Peer peer) {
|
private void onPeerSelected(Peer peer) {
|
||||||
getActivity().swapWith(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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,6 @@ import android.net.Uri;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.support.annotation.ColorRes;
|
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v4.app.LoaderManager;
|
import android.support.v4.app.LoaderManager;
|
||||||
@ -47,7 +46,7 @@ import org.fdroid.fdroid.data.App;
|
|||||||
import org.fdroid.fdroid.data.AppProvider;
|
import org.fdroid.fdroid.data.AppProvider;
|
||||||
import org.fdroid.fdroid.data.Repo;
|
import org.fdroid.fdroid.data.Repo;
|
||||||
import org.fdroid.fdroid.data.Schema.AppMetadataTable;
|
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.Downloader;
|
||||||
import org.fdroid.fdroid.net.DownloaderService;
|
import org.fdroid.fdroid.net.DownloaderService;
|
||||||
|
|
||||||
@ -55,8 +54,7 @@ import java.util.List;
|
|||||||
import java.util.Timer;
|
import java.util.Timer;
|
||||||
import java.util.TimerTask;
|
import java.util.TimerTask;
|
||||||
|
|
||||||
public class SwapSuccessView extends ListView implements
|
public class SwapSuccessView extends SwapView implements
|
||||||
SwapWorkflowActivity.InnerView,
|
|
||||||
LoaderManager.LoaderCallbacks<Cursor>,
|
LoaderManager.LoaderCallbacks<Cursor>,
|
||||||
SearchView.OnQueryTextListener {
|
SearchView.OnQueryTextListener {
|
||||||
|
|
||||||
@ -77,10 +75,6 @@ public class SwapSuccessView extends ListView implements
|
|||||||
super(context, attrs, defStyleAttr, defStyleRes);
|
super(context, attrs, defStyleAttr, defStyleRes);
|
||||||
}
|
}
|
||||||
|
|
||||||
private SwapWorkflowActivity getActivity() {
|
|
||||||
return (SwapWorkflowActivity) getContext();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final int LOADER_SWAPABLE_APPS = 759283741;
|
private static final int LOADER_SWAPABLE_APPS = 759283741;
|
||||||
private static final String TAG = "SwapAppsView";
|
private static final String TAG = "SwapAppsView";
|
||||||
|
|
||||||
@ -102,8 +96,8 @@ public class SwapSuccessView extends ListView implements
|
|||||||
|
|
||||||
adapter = new AppListAdapter(getContext(), getContext().getContentResolver().query(
|
adapter = new AppListAdapter(getContext(), getContext().getContentResolver().query(
|
||||||
AppProvider.getRepoUri(repo), AppMetadataTable.Cols.ALL, null, null, null));
|
AppProvider.getRepoUri(repo), AppMetadataTable.Cols.ALL, null, null, null));
|
||||||
|
ListView listView = findViewById(R.id.list);
|
||||||
setAdapter(adapter);
|
listView.setAdapter(adapter);
|
||||||
|
|
||||||
// either reconnect with an existing loader or start a new one
|
// either reconnect with an existing loader or start a new one
|
||||||
getActivity().getSupportLoaderManager().initLoader(LOADER_SWAPABLE_APPS, null, this);
|
getActivity().getSupportLoaderManager().initLoader(LOADER_SWAPABLE_APPS, null, this);
|
||||||
@ -163,26 +157,6 @@ public class SwapSuccessView extends ListView implements
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getStep() {
|
|
||||||
return SwapService.STEP_SWAP_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
|
@Override
|
||||||
public CursorLoader onCreateLoader(int id, Bundle args) {
|
public CursorLoader onCreateLoader(int id, Bundle args) {
|
||||||
Uri uri = TextUtils.isEmpty(currentFilterString)
|
Uri uri = TextUtils.isEmpty(currentFilterString)
|
||||||
|
@ -17,7 +17,6 @@ import android.os.Build;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.support.annotation.ColorRes;
|
|
||||||
import android.support.annotation.LayoutRes;
|
import android.support.annotation.LayoutRes;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
@ -28,9 +27,9 @@ import android.support.v7.widget.Toolbar;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuInflater;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
import cc.mvdan.accesspoint.WifiApControl;
|
import cc.mvdan.accesspoint.WifiApControl;
|
||||||
import com.google.zxing.integration.android.IntentIntegrator;
|
import com.google.zxing.integration.android.IntentIntegrator;
|
||||||
@ -48,6 +47,7 @@ import org.fdroid.fdroid.installer.InstallManagerService;
|
|||||||
import org.fdroid.fdroid.installer.Installer;
|
import org.fdroid.fdroid.installer.Installer;
|
||||||
import org.fdroid.fdroid.localrepo.LocalRepoManager;
|
import org.fdroid.fdroid.localrepo.LocalRepoManager;
|
||||||
import org.fdroid.fdroid.localrepo.SwapService;
|
import org.fdroid.fdroid.localrepo.SwapService;
|
||||||
|
import org.fdroid.fdroid.localrepo.SwapView;
|
||||||
import org.fdroid.fdroid.localrepo.peers.Peer;
|
import org.fdroid.fdroid.localrepo.peers.Peer;
|
||||||
import org.fdroid.fdroid.net.BluetoothDownloader;
|
import org.fdroid.fdroid.net.BluetoothDownloader;
|
||||||
import org.fdroid.fdroid.net.HttpDownloader;
|
import org.fdroid.fdroid.net.HttpDownloader;
|
||||||
@ -68,6 +68,7 @@ import java.util.TimerTask;
|
|||||||
*/
|
*/
|
||||||
@SuppressWarnings("LineLength")
|
@SuppressWarnings("LineLength")
|
||||||
public class SwapWorkflowActivity extends AppCompatActivity {
|
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
|
* When connecting to a swap, we then go and initiate a connection with that
|
||||||
@ -87,28 +88,6 @@ public class SwapWorkflowActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
private ViewGroup container;
|
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 CONNECT_TO_SWAP = 1;
|
||||||
private static final int REQUEST_BLUETOOTH_ENABLE_FOR_SWAP = 2;
|
private static final int REQUEST_BLUETOOTH_ENABLE_FOR_SWAP = 2;
|
||||||
private static final int REQUEST_BLUETOOTH_DISCOVERABLE = 3;
|
private static final int REQUEST_BLUETOOTH_DISCOVERABLE = 3;
|
||||||
@ -116,7 +95,7 @@ public class SwapWorkflowActivity extends AppCompatActivity {
|
|||||||
private static final int REQUEST_WRITE_SETTINGS_PERMISSION = 5;
|
private static final int REQUEST_WRITE_SETTINGS_PERMISSION = 5;
|
||||||
|
|
||||||
private Toolbar toolbar;
|
private Toolbar toolbar;
|
||||||
private InnerView currentView;
|
private SwapView currentView;
|
||||||
private boolean hasPreparedLocalRepo;
|
private boolean hasPreparedLocalRepo;
|
||||||
private PrepareSwapRepo updateSwappableAppsTask;
|
private PrepareSwapRepo updateSwappableAppsTask;
|
||||||
private NewRepoConfig confirmSwapConfig;
|
private NewRepoConfig confirmSwapConfig;
|
||||||
@ -165,12 +144,50 @@ public class SwapWorkflowActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBackPressed() {
|
public void onBackPressed() {
|
||||||
if (currentView.getStep() == SwapService.STEP_INTRO) {
|
if (currentView.getLayoutResId() == SwapService.STEP_INTRO) {
|
||||||
SwapService.stop(this);
|
SwapService.stop(this); // TODO SwapService should always be running, while swap is running
|
||||||
finish();
|
finish();
|
||||||
} else {
|
} else {
|
||||||
int nextStep = currentView.getPreviousStep();
|
// TODO: Currently StartSwapView is handleed by the SwapWorkflowActivity as a special case, where
|
||||||
getService().setStep(nextStep);
|
// 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();
|
showRelevantView();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -310,7 +327,7 @@ public class SwapWorkflowActivity extends AppCompatActivity {
|
|||||||
private void showRelevantView(boolean forceReload) {
|
private void showRelevantView(boolean forceReload) {
|
||||||
|
|
||||||
if (service == null) {
|
if (service == null) {
|
||||||
showInitialLoading();
|
inflateSwapView(R.layout.swap_initial_loading);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -323,62 +340,50 @@ public class SwapWorkflowActivity extends AppCompatActivity {
|
|||||||
return;
|
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.
|
// Already showing the correct step, so don't bother changing anything.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (service.getStep()) {
|
int currentView = service.getCurrentView();
|
||||||
|
switch (currentView) {
|
||||||
case SwapService.STEP_INTRO:
|
case SwapService.STEP_INTRO:
|
||||||
showIntro();
|
showIntro();
|
||||||
break;
|
return;
|
||||||
case SwapService.STEP_SELECT_APPS:
|
case R.layout.swap_nfc:
|
||||||
showSelectApps();
|
if (!attemptToShowNfc()) {
|
||||||
break;
|
inflateSwapView(R.layout.swap_wifi_qr);
|
||||||
case SwapService.STEP_SHOW_NFC:
|
return;
|
||||||
showNfc();
|
|
||||||
break;
|
|
||||||
case SwapService.STEP_JOIN_WIFI:
|
|
||||||
showJoinWifi();
|
|
||||||
break;
|
|
||||||
case SwapService.STEP_WIFI_QR:
|
|
||||||
showWifiQr();
|
|
||||||
break;
|
|
||||||
case SwapService.STEP_SWAP_SUCCESS:
|
|
||||||
showSwapSuccess();
|
|
||||||
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_start_swap);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
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() {
|
public SwapService getState() {
|
||||||
return service;
|
return service;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showNfc() {
|
public SwapView inflateSwapView(@LayoutRes int viewRes) {
|
||||||
if (!attemptToShowNfc()) {
|
|
||||||
showWifiQr();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private InnerView inflateInnerView(@LayoutRes int viewRes) {
|
|
||||||
container.removeAllViews();
|
container.removeAllViews();
|
||||||
View view = ((LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE)).inflate(viewRes, container, false);
|
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
|
// 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_.
|
// 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) {
|
if (service == null) {
|
||||||
throw new IllegalStateException("We are not in the STEP_INITIAL_LOADING state, but the service is not ready.");
|
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.setTitle(currentView.getToolbarTitle());
|
||||||
toolbar.setNavigationIcon(R.drawable.ic_close_white_24dp);
|
toolbar.setNavigationIcon(R.drawable.ic_close_white_24dp);
|
||||||
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
|
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
|
||||||
@ -398,10 +403,6 @@ public class SwapWorkflowActivity extends AppCompatActivity {
|
|||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showInitialLoading() {
|
|
||||||
inflateInnerView(R.layout.swap_initial_loading);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void showIntro() {
|
public void showIntro() {
|
||||||
// If we were previously swapping with a specific client, forget that we were doing that,
|
// If we were previously swapping with a specific client, forget that we were doing that,
|
||||||
// as we are starting over now.
|
// as we are starting over now.
|
||||||
@ -414,11 +415,13 @@ public class SwapWorkflowActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inflateInnerView(R.layout.swap_start_swap);
|
inflateSwapView(R.layout.swap_start_swap);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showConfirmSwap(@NonNull NewRepoConfig config) {
|
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() {
|
public void startQrWorkflow() {
|
||||||
@ -435,14 +438,10 @@ public class SwapWorkflowActivity extends AppCompatActivity {
|
|||||||
})
|
})
|
||||||
.create().show();
|
.create().show();
|
||||||
} else {
|
} 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
|
* On {@code android-26}, only apps with privileges can access
|
||||||
* {@code WRITE_SETTINGS}. So this just shows the tethering settings
|
* {@code WRITE_SETTINGS}. So this just shows the tethering settings
|
||||||
@ -471,7 +470,7 @@ public class SwapWorkflowActivity extends AppCompatActivity {
|
|||||||
if (adapter == null
|
if (adapter == null
|
||||||
|| Build.VERSION.SDK_INT >= 23 // TODO make Bluetooth work with content:// URIs
|
|| Build.VERSION.SDK_INT >= 23 // TODO make Bluetooth work with content:// URIs
|
||||||
|| (!adapter.isEnabled() && getService().getWifiSwap().isConnected())) {
|
|| (!adapter.isEnabled() && getService().getWifiSwap().isConnected())) {
|
||||||
showSendFDroid();
|
inflateSwapView(R.layout.swap_send_fdroid);
|
||||||
} else {
|
} else {
|
||||||
sendFDroidBluetooth();
|
sendFDroidBluetooth();
|
||||||
}
|
}
|
||||||
@ -503,8 +502,8 @@ public class SwapWorkflowActivity extends AppCompatActivity {
|
|||||||
if (updateSwappableAppsTask == null && !hasPreparedLocalRepo) {
|
if (updateSwappableAppsTask == null && !hasPreparedLocalRepo) {
|
||||||
updateSwappableAppsTask = new PrepareSwapRepo(getService().getAppsToSwap());
|
updateSwappableAppsTask = new PrepareSwapRepo(getService().getAppsToSwap());
|
||||||
updateSwappableAppsTask.execute();
|
updateSwappableAppsTask.execute();
|
||||||
getService().setStep(SwapService.STEP_CONNECTING);
|
getService().setCurrentView(R.layout.swap_connecting);
|
||||||
inflateInnerView(R.layout.swap_connecting);
|
inflateSwapView(R.layout.swap_connecting);
|
||||||
} else {
|
} else {
|
||||||
onLocalRepoPrepared();
|
onLocalRepoPrepared();
|
||||||
}
|
}
|
||||||
@ -524,29 +523,13 @@ public class SwapWorkflowActivity extends AppCompatActivity {
|
|||||||
if (getService().isConnectingWithPeer()) {
|
if (getService().isConnectingWithPeer()) {
|
||||||
startSwappingWithPeer();
|
startSwappingWithPeer();
|
||||||
} else if (!attemptToShowNfc()) {
|
} else if (!attemptToShowNfc()) {
|
||||||
showWifiQr();
|
inflateSwapView(R.layout.swap_wifi_qr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startSwappingWithPeer() {
|
private void startSwappingWithPeer() {
|
||||||
getService().connectToPeer();
|
getService().connectToPeer();
|
||||||
inflateInnerView(R.layout.swap_connecting);
|
inflateSwapView(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 showSwapSuccess() {
|
|
||||||
inflateInnerView(R.layout.swap_success);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean attemptToShowNfc() {
|
private boolean attemptToShowNfc() {
|
||||||
@ -559,7 +542,7 @@ public class SwapWorkflowActivity extends AppCompatActivity {
|
|||||||
boolean nfcMessageReady = NfcHelper.setPushMessage(this, Utils.getSharingUri(FDroidApp.repo));
|
boolean nfcMessageReady = NfcHelper.setPushMessage(this, Utils.getSharingUri(FDroidApp.repo));
|
||||||
|
|
||||||
if (Preferences.get().showNfcDuringSwap() && nfcMessageReady) {
|
if (Preferences.get().showNfcDuringSwap() && nfcMessageReady) {
|
||||||
inflateInnerView(R.layout.swap_nfc);
|
inflateSwapView(R.layout.swap_nfc);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -567,7 +550,7 @@ public class SwapWorkflowActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
public void swapWith(Peer peer) {
|
public void swapWith(Peer peer) {
|
||||||
getService().swapWith(peer);
|
getService().swapWith(peer);
|
||||||
showSelectApps();
|
inflateSwapView(R.layout.swap_select_apps);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -580,7 +563,7 @@ public class SwapWorkflowActivity extends AppCompatActivity {
|
|||||||
*/
|
*/
|
||||||
public void swapWith(NewRepoConfig repoConfig) {
|
public void swapWith(NewRepoConfig repoConfig) {
|
||||||
Peer peer = repoConfig.toPeer();
|
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.
|
// 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
|
// 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.
|
// can or cannot be in STEP_INTRO with a full blown repo ready to swap.
|
||||||
@ -784,15 +767,14 @@ public class SwapWorkflowActivity extends AppCompatActivity {
|
|||||||
* the harder it becomes to reason about and debug the whole thing. Thus,this class
|
* 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
|
* will periodically dump the state to logcat so that it is easier to see when certain
|
||||||
* protocols are enabled/disabled.
|
* protocols are enabled/disabled.
|
||||||
*
|
* <p>
|
||||||
* To view only this output from logcat:
|
* To view only this output from logcat:
|
||||||
*
|
* <p>
|
||||||
* adb logcat | grep 'Swap Status'
|
* adb logcat | grep 'Swap Status'
|
||||||
*
|
* <p>
|
||||||
* To exclude this output from logcat (it is very noisy):
|
* To exclude this output from logcat (it is very noisy):
|
||||||
*
|
* <p>
|
||||||
* adb logcat | grep -v 'Swap Status'
|
* adb logcat | grep -v 'Swap Status'
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
class SwapDebug {
|
class SwapDebug {
|
||||||
|
|
||||||
|
@ -7,31 +7,26 @@ import android.content.Intent;
|
|||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.graphics.LightingColorFilter;
|
import android.graphics.LightingColorFilter;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.support.annotation.ColorRes;
|
|
||||||
import android.support.annotation.NonNull;
|
|
||||||
import android.support.v4.content.LocalBroadcastManager;
|
import android.support.v4.content.LocalBroadcastManager;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.Menu;
|
|
||||||
import android.view.MenuInflater;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.ScrollView;
|
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import org.fdroid.fdroid.FDroidApp;
|
import org.fdroid.fdroid.FDroidApp;
|
||||||
import org.fdroid.fdroid.Preferences;
|
import org.fdroid.fdroid.Preferences;
|
||||||
import org.fdroid.fdroid.QrGenAsyncTask;
|
import org.fdroid.fdroid.QrGenAsyncTask;
|
||||||
import org.fdroid.fdroid.R;
|
import org.fdroid.fdroid.R;
|
||||||
import org.fdroid.fdroid.Utils;
|
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.net.WifiStateChangeService;
|
||||||
import org.fdroid.fdroid.views.swap.device.camera.CameraCharacteristicsChecker;
|
import org.fdroid.fdroid.views.swap.device.camera.CameraCharacteristicsChecker;
|
||||||
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public class WifiQrView extends ScrollView implements SwapWorkflowActivity.InnerView {
|
public class WifiQrView extends SwapView {
|
||||||
|
|
||||||
private static final String TAG = "WifiQrView";
|
private static final String TAG = "WifiQrView";
|
||||||
|
|
||||||
@ -52,10 +47,6 @@ public class WifiQrView extends ScrollView implements SwapWorkflowActivity.Inner
|
|||||||
super(context, attrs, defStyleAttr, defStyleRes);
|
super(context, attrs, defStyleAttr, defStyleRes);
|
||||||
}
|
}
|
||||||
|
|
||||||
private SwapWorkflowActivity getActivity() {
|
|
||||||
return (SwapWorkflowActivity) getContext();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onFinishInflate() {
|
protected void onFinishInflate() {
|
||||||
super.onFinishInflate();
|
super.onFinishInflate();
|
||||||
@ -98,32 +89,6 @@ public class WifiQrView extends ScrollView implements SwapWorkflowActivity.Inner
|
|||||||
LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(onWifiStateChanged);
|
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() {
|
private void setUIFromWifi() {
|
||||||
|
|
||||||
if (TextUtils.isEmpty(FDroidApp.repo.address)) {
|
if (TextUtils.isEmpty(FDroidApp.repo.address)) {
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
<org.fdroid.fdroid.views.swap.ConfirmReceiveView
|
<org.fdroid.fdroid.views.swap.ConfirmReceiveView
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
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:orientation="vertical"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
@ -2,7 +2,9 @@
|
|||||||
|
|
||||||
<org.fdroid.fdroid.views.swap.ConnectingView
|
<org.fdroid.fdroid.views.swap.ConnectingView
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
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:orientation="vertical"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
@ -11,40 +13,40 @@
|
|||||||
android:id="@+id/heading"
|
android:id="@+id/heading"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentTop="true"
|
||||||
android:textSize="20sp"
|
android:textSize="20sp"
|
||||||
android:padding="30dp"
|
android:padding="30dp"
|
||||||
android:textAlignment="center"
|
android:textAlignment="center"
|
||||||
android:gravity="center"
|
android:gravity="center"/>
|
||||||
tools:text="Connecting with Nexus 4"
|
|
||||||
tools:ignore="UnusedAttribute"/>
|
|
||||||
|
|
||||||
<ProgressBar
|
<ProgressBar
|
||||||
|
android:id="@+id/progress_bar"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:indeterminate="true"
|
android:indeterminate="true"
|
||||||
android:layout_gravity="center"/>
|
android:layout_centerInParent="true"
|
||||||
|
android:layout_below="@+id/heading"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentTop="true"
|
||||||
android:id="@+id/error"
|
android:id="@+id/error"
|
||||||
android:textSize="20sp"
|
android:textSize="20sp"
|
||||||
android:textAlignment="center"
|
android:textAlignment="center"
|
||||||
android:gravity="center"
|
|
||||||
android:text="@string/swap_connection_misc_error"
|
android:text="@string/swap_connection_misc_error"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
android:padding="30dp"
|
android:padding="30dp"/>
|
||||||
tools:ignore="UnusedAttribute"/>
|
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:layout_below="@+id/error"
|
||||||
android:id="@+id/back"
|
android:id="@+id/back"
|
||||||
android:backgroundTint="@color/swap_light_blue"
|
android:backgroundTint="@color/swap_light_blue"
|
||||||
android:textColor="@android:color/white"
|
android:textColor="@android:color/white"
|
||||||
android:layout_gravity="center_horizontal"
|
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
android:text="@string/back"
|
android:text="@string/back"/>
|
||||||
tools:ignore="UnusedAttribute"/>
|
|
||||||
|
|
||||||
</org.fdroid.fdroid.views.swap.ConnectingView>
|
</org.fdroid.fdroid.views.swap.ConnectingView>
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
<org.fdroid.fdroid.views.swap.InitialLoadingView
|
<org.fdroid.fdroid.localrepo.SwapView
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
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:orientation="vertical"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
@ -24,4 +26,4 @@
|
|||||||
android:textColor="@android:color/white"
|
android:textColor="@android:color/white"
|
||||||
android:layout_centerHorizontal="true"/>
|
android:layout_centerHorizontal="true"/>
|
||||||
|
|
||||||
</org.fdroid.fdroid.views.swap.InitialLoadingView>
|
</org.fdroid.fdroid.localrepo.SwapView>
|
@ -3,6 +3,8 @@
|
|||||||
<org.fdroid.fdroid.views.swap.JoinWifiView
|
<org.fdroid.fdroid.views.swap.JoinWifiView
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
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:orientation="vertical"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
<org.fdroid.fdroid.views.swap.NfcView
|
<org.fdroid.fdroid.views.swap.NfcView
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
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:orientation="vertical"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
@ -2,8 +2,16 @@
|
|||||||
|
|
||||||
<org.fdroid.fdroid.views.swap.SelectAppsView
|
<org.fdroid.fdroid.views.swap.SelectAppsView
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
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:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="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>
|
</org.fdroid.fdroid.views.swap.SelectAppsView>
|
@ -3,10 +3,13 @@
|
|||||||
<org.fdroid.fdroid.views.swap.SendFDroidView
|
<org.fdroid.fdroid.views.swap.SendFDroidView
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
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:background="@color/swap_blue"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_width="wrap_content">
|
android:layout_width="wrap_content">
|
||||||
|
|
||||||
|
<ScrollView android:layout_width="match_parent" android:layout_height="match_parent">
|
||||||
<LinearLayout android:orientation="vertical"
|
<LinearLayout android:orientation="vertical"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
@ -46,5 +49,5 @@
|
|||||||
style="@style/SwapTheme.Wizard.QRScanWarningText"/>
|
style="@style/SwapTheme.Wizard.QRScanWarningText"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
</ScrollView>
|
||||||
</org.fdroid.fdroid.views.swap.SendFDroidView>
|
</org.fdroid.fdroid.views.swap.SendFDroidView>
|
@ -7,6 +7,9 @@
|
|||||||
<org.fdroid.fdroid.views.swap.StartSwapView
|
<org.fdroid.fdroid.views.swap.StartSwapView
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
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:orientation="vertical"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
@ -2,8 +2,16 @@
|
|||||||
|
|
||||||
<org.fdroid.fdroid.views.swap.SwapSuccessView
|
<org.fdroid.fdroid.views.swap.SwapSuccessView
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
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:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="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.SwapSuccessView>
|
</org.fdroid.fdroid.views.swap.SwapSuccessView>
|
@ -3,10 +3,13 @@
|
|||||||
<org.fdroid.fdroid.views.swap.WifiQrView
|
<org.fdroid.fdroid.views.swap.WifiQrView
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
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:background="@color/swap_blue"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_width="wrap_content">
|
android:layout_width="wrap_content">
|
||||||
|
|
||||||
|
<ScrollView android:layout_width="match_parent" android:layout_height="match_parent">
|
||||||
<LinearLayout android:orientation="vertical"
|
<LinearLayout android:orientation="vertical"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
@ -53,5 +56,5 @@
|
|||||||
style="@style/SwapTheme.Wizard.QRScanWarningText"/>
|
style="@style/SwapTheme.Wizard.QRScanWarningText"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
</ScrollView>
|
||||||
</org.fdroid.fdroid.views.swap.WifiQrView>
|
</org.fdroid.fdroid.views.swap.WifiQrView>
|
@ -3,4 +3,8 @@
|
|||||||
|
|
||||||
<integer name="unhidePin">1337</integer>
|
<integer name="unhidePin">1337</integer>
|
||||||
|
|
||||||
|
<declare-styleable name="SwapView">
|
||||||
|
<attr name="toolbarColor" format="color"/>
|
||||||
|
<attr name="toolbarTitle" format="string"/>
|
||||||
|
</declare-styleable>
|
||||||
</resources>
|
</resources>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user