diff --git a/src/org/fdroid/fdroid/views/swap/SelectAppsFragment.java b/src/org/fdroid/fdroid/views/swap/SelectAppsFragment.java index 5d7caf65e..58c9a273c 100644 --- a/src/org/fdroid/fdroid/views/swap/SelectAppsFragment.java +++ b/src/org/fdroid/fdroid/views/swap/SelectAppsFragment.java @@ -10,6 +10,7 @@ import android.support.v4.app.ListFragment; import android.support.v4.app.LoaderManager; import android.support.v4.content.CursorLoader; import android.support.v4.content.Loader; +import android.support.v4.widget.SimpleCursorAdapter; import android.text.TextUtils; import android.view.ActionMode; import android.view.ContextThemeWrapper; @@ -20,7 +21,6 @@ import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.SearchView; -import android.widget.SimpleCursorAdapter; import android.widget.TextView; import org.fdroid.fdroid.FDroidApp; import org.fdroid.fdroid.R; @@ -28,6 +28,7 @@ import org.fdroid.fdroid.data.InstalledAppProvider; import org.fdroid.fdroid.localrepo.LocalRepoManager; import java.util.HashSet; +import java.util.Set; public class SelectAppsFragment extends ListFragment implements LoaderManager.LoaderCallbacks, SearchView.OnQueryTextListener { @@ -36,6 +37,43 @@ public class SelectAppsFragment extends ListFragment private Drawable defaultAppIcon; private ActionMode mActionMode = null; private String mCurrentFilterString; + private Set previouslySelectedApps = new HashSet(); + + public Set getSelectedApps() { + return FDroidApp.selectedApps; + } + + @Override + public void onResume() { + super.onResume(); + previouslySelectedApps.clear(); + if (FDroidApp.selectedApps != null) { + previouslySelectedApps.addAll(FDroidApp.selectedApps); + } + } + + public boolean hasSelectionChanged() { + + Set currentlySelected = getSelectedApps(); + if (currentlySelected.size() != previouslySelectedApps.size()) { + return true; + } + + for (String current : currentlySelected) { + boolean found = false; + for (String previous : previouslySelectedApps) { + if (current.equals(previous)) { + found = true; + break; + } + } + if (!found) { + return true; + } + } + + return false; + } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { diff --git a/src/org/fdroid/fdroid/views/swap/SwapActivity.java b/src/org/fdroid/fdroid/views/swap/SwapActivity.java index ab2005a8d..363fbd646 100644 --- a/src/org/fdroid/fdroid/views/swap/SwapActivity.java +++ b/src/org/fdroid/fdroid/views/swap/SwapActivity.java @@ -1,13 +1,25 @@ package org.fdroid.fdroid.views.swap; +import android.app.ProgressDialog; +import android.content.Context; +import android.net.Uri; +import android.os.AsyncTask; import android.os.Bundle; import android.support.v4.app.FragmentManager; import android.support.v4.view.MenuItemCompat; import android.support.v7.app.ActionBarActivity; import android.view.Menu; import android.view.MenuItem; +import android.widget.Toast; +import org.fdroid.fdroid.FDroidApp; import org.fdroid.fdroid.Preferences; import org.fdroid.fdroid.R; +import org.fdroid.fdroid.Utils; +import org.fdroid.fdroid.localrepo.LocalRepoManager; + +import java.util.Set; +import java.util.Timer; +import java.util.TimerTask; public class SwapActivity extends ActionBarActivity implements SwapProcessManager { @@ -19,6 +31,9 @@ public class SwapActivity extends ActionBarActivity implements SwapProcessManage private MenuItem nextMenuItem; private String nextMenuItemLabel; + private Timer shutdownLocalRepoTimer; + private UpdateAsyncTask updateSwappableAppsTask = null; + private boolean hasPreparedLocalRepo = false; @Override public void onBackPressed() { @@ -39,8 +54,9 @@ public class SwapActivity extends ActionBarActivity implements SwapProcessManage if (current.equals(STATE_START_SWAP)) { onSelectApps(); } else if (current.equals(STATE_SELECT_APPS)) { - onJoinWifi(); + prepareLocalRepo(); } else if (current.equals(STATE_JOIN_WIFI)) { + startLocalRepo(); onAttemptNfc(); } else if (current.equals(STATE_NFC)) { onWifiQr(); @@ -155,4 +171,110 @@ public class SwapActivity extends ActionBarActivity implements SwapProcessManage showNextButton(); } + private void prepareLocalRepo() { + SelectAppsFragment fragment = (SelectAppsFragment)getSupportFragmentManager().findFragmentByTag(STATE_SELECT_APPS); + boolean needsUpdating = !hasPreparedLocalRepo || fragment.hasSelectionChanged(); + if (updateSwappableAppsTask == null && needsUpdating) { + updateSwappableAppsTask = new UpdateAsyncTask(this, fragment.getSelectedApps()); + updateSwappableAppsTask.execute(); + } else { + onJoinWifi(); + } + } + + /** + * Once the UpdateAsyncTask has finished preparing our repository index, we can + * show the next screen to the user. + */ + private void onLocalRepoPrepared() { + + updateSwappableAppsTask = null; + hasPreparedLocalRepo = true; + onJoinWifi(); + + } + + private void startLocalRepo() { + if (!FDroidApp.isLocalRepoServiceRunnig()) { + FDroidApp.startLocalRepoService(this); + } + + // reset the timer if viewing this Activity again + if (shutdownLocalRepoTimer != null) + shutdownLocalRepoTimer.cancel(); + + // automatically turn off after 15 minutes + shutdownLocalRepoTimer = new Timer(); + shutdownLocalRepoTimer.schedule(new TimerTask() { + @Override + public void run() { + FDroidApp.stopLocalRepoService(SwapActivity.this); + } + }, 900000); // 15 minutes + } + + class UpdateAsyncTask extends AsyncTask { + private static final String TAG = "UpdateAsyncTask"; + private ProgressDialog progressDialog; + private Set selectedApps; + private Uri sharingUri; + + public UpdateAsyncTask(Context c, Set apps) { + selectedApps = apps; + progressDialog = new ProgressDialog(c); + progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); + progressDialog.setTitle(R.string.updating); + sharingUri = Utils.getSharingUri(c, FDroidApp.repo); + } + + @Override + protected void onPreExecute() { + progressDialog.show(); + } + + @Override + protected Void doInBackground(Void... params) { + try { + final LocalRepoManager lrm = LocalRepoManager.get(SwapActivity.this); + publishProgress(getString(R.string.deleting_repo)); + lrm.deleteRepo(); + for (String app : selectedApps) { + publishProgress(String.format(getString(R.string.adding_apks_format), app)); + lrm.addApp(SwapActivity.this, app); + } + lrm.writeIndexPage(sharingUri.toString()); + publishProgress(getString(R.string.writing_index_jar)); + lrm.writeIndexJar(); + publishProgress(getString(R.string.linking_apks)); + lrm.copyApksToRepo(); + publishProgress(getString(R.string.copying_icons)); + // run the icon copy without progress, its not a blocker + new AsyncTask() { + + @Override + protected Void doInBackground(Void... params) { + lrm.copyIconsToRepo(); + return null; + } + }.execute(); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + @Override + protected void onProgressUpdate(String... progress) { + super.onProgressUpdate(progress); + progressDialog.setMessage(progress[0]); + } + + @Override + protected void onPostExecute(Void result) { + progressDialog.dismiss(); + Toast.makeText(SwapActivity.this, R.string.updated_local_repo, Toast.LENGTH_SHORT).show(); + onLocalRepoPrepared(); + } + } + } diff --git a/src/org/fdroid/fdroid/views/swap/WifiQrFragment.java b/src/org/fdroid/fdroid/views/swap/WifiQrFragment.java index 33c7c0c79..f9c559427 100644 --- a/src/org/fdroid/fdroid/views/swap/WifiQrFragment.java +++ b/src/org/fdroid/fdroid/views/swap/WifiQrFragment.java @@ -1,14 +1,11 @@ package org.fdroid.fdroid.views.swap; import android.annotation.TargetApi; -import android.app.ProgressDialog; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.graphics.LightingColorFilter; -import android.net.Uri; -import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.support.v4.app.Fragment; @@ -20,18 +17,13 @@ import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; -import android.widget.Toast; import org.fdroid.fdroid.FDroidApp; import org.fdroid.fdroid.QrGenAsyncTask; import org.fdroid.fdroid.R; import org.fdroid.fdroid.Utils; -import org.fdroid.fdroid.localrepo.LocalRepoManager; -import org.fdroid.fdroid.localrepo.LocalRepoService; import org.fdroid.fdroid.net.WifiStateChangeService; import java.util.Locale; -import java.util.Timer; -import java.util.TimerTask; public class WifiQrFragment extends Fragment { @@ -42,15 +34,6 @@ public class WifiQrFragment extends Fragment { } }; - private BroadcastReceiver onLocalRepoChange = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent i) { - setUIFromWifi(); - } - }; - - private Timer stopTimer; - @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.swap_wifi_qr, container, false); @@ -68,29 +51,6 @@ public class WifiQrFragment extends Fragment { LocalBroadcastManager.getInstance(getActivity()).registerReceiver(onWifiChange, new IntentFilter(WifiStateChangeService.BROADCAST)); - LocalBroadcastManager.getInstance(getActivity()).registerReceiver(onLocalRepoChange, - new IntentFilter(LocalRepoService.STATE)); - - // if no local repo exists, create one with only FDroid in it - if (!LocalRepoManager.get(getActivity()).xmlIndex.exists()) - new UpdateAsyncTask(getActivity(), new String[] { - getActivity().getPackageName(), - }).execute(); - - // start repo by default - FDroidApp.startLocalRepoService(getActivity()); - // reset the timer if viewing this Activity again - if (stopTimer != null) - stopTimer.cancel(); - // automatically turn off after 15 minutes - stopTimer = new Timer(); - stopTimer.schedule(new TimerTask() { - - @Override - public void run() { - FDroidApp.stopLocalRepoService(getActivity()); - } - }, 900000); // 15 minutes } @TargetApi(14) @@ -126,67 +86,4 @@ public class WifiQrFragment extends Fragment { } - class UpdateAsyncTask extends AsyncTask { - private static final String TAG = "UpdateAsyncTask"; - private ProgressDialog progressDialog; - private String[] selectedApps; - private Uri sharingUri; - - public UpdateAsyncTask(Context c, String[] apps) { - selectedApps = apps; - progressDialog = new ProgressDialog(c); - progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); - progressDialog.setTitle(R.string.updating); - sharingUri = Utils.getSharingUri(c, FDroidApp.repo); - } - - @Override - protected void onPreExecute() { - progressDialog.show(); - } - - @Override - protected Void doInBackground(Void... params) { - try { - final LocalRepoManager lrm = LocalRepoManager.get(getActivity()); - publishProgress(getString(R.string.deleting_repo)); - lrm.deleteRepo(); - for (String app : selectedApps) { - publishProgress(String.format(getString(R.string.adding_apks_format), app)); - lrm.addApp(getActivity(), app); - } - lrm.writeIndexPage(sharingUri.toString()); - publishProgress(getString(R.string.writing_index_jar)); - lrm.writeIndexJar(); - publishProgress(getString(R.string.linking_apks)); - lrm.copyApksToRepo(); - publishProgress(getString(R.string.copying_icons)); - // run the icon copy without progress, its not a blocker - new AsyncTask() { - - @Override - protected Void doInBackground(Void... params) { - lrm.copyIconsToRepo(); - return null; - } - }.execute(); - } catch (Exception e) { - e.printStackTrace(); - } - return null; - } - - @Override - protected void onProgressUpdate(String... progress) { - super.onProgressUpdate(progress); - progressDialog.setMessage(progress[0]); - } - - @Override - protected void onPostExecute(Void result) { - progressDialog.dismiss(); - Toast.makeText(getActivity(), R.string.updated_local_repo, Toast.LENGTH_SHORT).show(); - } - } - }