package org.fdroid.fdroid.views.swap; import android.annotation.TargetApi; 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.TextView; import org.fdroid.fdroid.R; import org.fdroid.fdroid.UpdateService; import org.fdroid.fdroid.localrepo.SwapService; // TODO: Use this for the "Preparing local repo" dialog also. public class SwapConnecting extends LinearLayout implements SwapWorkflowActivity.InnerView { @SuppressWarnings("unused") private static final String TAG = "SwapConnecting"; public SwapConnecting(Context context) { super(context); } public SwapConnecting(Context context, AttributeSet attrs) { super(context, attrs); } @TargetApi(11) public SwapConnecting(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @TargetApi(21) public SwapConnecting(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(); ((TextView) findViewById(R.id.heading)).setText(R.string.swap_connecting); findViewById(R.id.back).setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { getActivity().showIntro(); } }); LocalBroadcastManager.getInstance(getActivity()).registerReceiver( repoUpdateReceiver, new IntentFilter(UpdateService.LOCAL_ACTION_STATUS)); LocalBroadcastManager.getInstance(getActivity()).registerReceiver( prepareSwapReceiver, new IntentFilter(SwapWorkflowActivity.PrepareSwapRepo.ACTION)); } /** * Remove relevant listeners/receivers/etc so that they do not receive and process events * when this view is not in use. */ @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(repoUpdateReceiver); LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(prepareSwapReceiver); } private final BroadcastReceiver repoUpdateReceiver = new ConnectSwapReceiver(); private final BroadcastReceiver prepareSwapReceiver = new PrepareSwapReceiver(); /** * Listens for feedback about a local repository being prepared: * * Apk files copied to the LocalHTTPD webroot * * index.html file prepared * * Icons will be copied to the webroot in the background and so are not part of this process. */ class PrepareSwapReceiver extends Receiver { @Override protected String getMessageExtra() { return SwapWorkflowActivity.PrepareSwapRepo.EXTRA_MESSAGE; } protected int getType(Intent intent) { return intent.getIntExtra(SwapWorkflowActivity.PrepareSwapRepo.EXTRA_TYPE, -1); } @Override protected boolean isComplete(Intent intent) { return getType(intent) == SwapWorkflowActivity.PrepareSwapRepo.TYPE_COMPLETE; } @Override protected boolean isError(Intent intent) { return getType(intent) == SwapWorkflowActivity.PrepareSwapRepo.TYPE_ERROR; } @Override protected void onComplete() { getActivity().onLocalRepoPrepared(); } } /** * Listens for feedback about a repo update process taking place. * * Tracks an index.jar download and show the progress messages */ class ConnectSwapReceiver extends Receiver { @Override protected String getMessageExtra() { return UpdateService.EXTRA_MESSAGE; } protected int getStatusCode(Intent intent) { return intent.getIntExtra(UpdateService.EXTRA_STATUS_CODE, -1); } @Override protected boolean isComplete(Intent intent) { int status = getStatusCode(intent); return status == UpdateService.STATUS_COMPLETE_AND_SAME || status == UpdateService.STATUS_COMPLETE_WITH_CHANGES; } @Override protected boolean isError(Intent intent) { int status = getStatusCode(intent); return status == UpdateService.STATUS_ERROR_GLOBAL || status == UpdateService.STATUS_ERROR_LOCAL || status == UpdateService.STATUS_ERROR_LOCAL_SMALL; } @Override protected void onComplete() { getActivity().showSwapConnected(); } } abstract class Receiver extends BroadcastReceiver { protected abstract String getMessageExtra(); protected abstract boolean isComplete(Intent intent); protected abstract boolean isError(Intent intent); protected abstract void onComplete(); @Override public void onReceive(Context context, Intent intent) { TextView progressText = (TextView) findViewById(R.id.heading); TextView errorText = (TextView) findViewById(R.id.error); Button backButton = (Button) findViewById(R.id.back); String message; if (intent.hasExtra(getMessageExtra())) { message = intent.getStringExtra(getMessageExtra()); if (message != null) { progressText.setText(message); } } progressText.setVisibility(View.VISIBLE); errorText.setVisibility(View.GONE); backButton.setVisibility(View.GONE); if (isError(intent)) { progressText.setVisibility(View.GONE); errorText.setVisibility(View.VISIBLE); backButton.setVisibility(View.VISIBLE); return; } if (isComplete(intent)) { onComplete(); } } } @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); } }