diff --git a/.gitignore b/.gitignore index 91d7c59a9..aef3c14ae 100644 --- a/.gitignore +++ b/.gitignore @@ -43,3 +43,6 @@ extern/*/*/libs/ # Tests junit-report.xml + +# Screen dumps from Android Studio/DDMS +captures/ diff --git a/app/src/main/java/org/fdroid/fdroid/AppDetails.java b/app/src/main/java/org/fdroid/fdroid/AppDetails.java index 15e0539e4..fec76994c 100644 --- a/app/src/main/java/org/fdroid/fdroid/AppDetails.java +++ b/app/src/main/java/org/fdroid/fdroid/AppDetails.java @@ -107,7 +107,6 @@ public class AppDetails extends AppCompatActivity { private static final int REQUEST_PERMISSION_DIALOG = 3; private static final int REQUEST_UNINSTALL_DIALOG = 4; - public static final String EXTRA_APPID = "appid"; public static final String EXTRA_FROM = "from"; public static final String EXTRA_HINT_SEARCHING = "searching"; @@ -351,12 +350,12 @@ public class AppDetails extends AppCompatActivity { * and not externally. */ private String getPackageNameFromIntent(Intent intent) { - if (!intent.hasExtra(EXTRA_APPID)) { + if (!intent.hasExtra(AppDetails2.EXTRA_APPID)) { Log.e(TAG, "No package name found in the intent!"); return null; } - return intent.getStringExtra(EXTRA_APPID); + return intent.getStringExtra(AppDetails2.EXTRA_APPID); } @Override diff --git a/app/src/main/java/org/fdroid/fdroid/AppDetails2.java b/app/src/main/java/org/fdroid/fdroid/AppDetails2.java index a705211a4..1ce4ef10c 100644 --- a/app/src/main/java/org/fdroid/fdroid/AppDetails2.java +++ b/app/src/main/java/org/fdroid/fdroid/AppDetails2.java @@ -53,6 +53,7 @@ import org.fdroid.fdroid.views.apps.FeatureImage; public class AppDetails2 extends AppCompatActivity implements ShareChooserDialog.ShareChooserDialogListener, AppDetailsRecyclerViewAdapter.AppDetailsRecyclerViewAdapterCallbacks { + public static final String EXTRA_APPID = "appid"; private static final String TAG = "AppDetails2"; private static final int REQUEST_ENABLE_BLUETOOTH = 2; @@ -170,11 +171,11 @@ public class AppDetails2 extends AppCompatActivity implements ShareChooserDialog } private String getPackageNameFromIntent(Intent intent) { - if (!intent.hasExtra(AppDetails.EXTRA_APPID)) { + if (!intent.hasExtra(EXTRA_APPID)) { Log.e(TAG, "No package name found in the intent!"); return null; } - return intent.getStringExtra(AppDetails.EXTRA_APPID); + return intent.getStringExtra(EXTRA_APPID); } /** diff --git a/app/src/main/java/org/fdroid/fdroid/AppUpdateStatusManager.java b/app/src/main/java/org/fdroid/fdroid/AppUpdateStatusManager.java index c6d48b7cb..5f7788ef5 100644 --- a/app/src/main/java/org/fdroid/fdroid/AppUpdateStatusManager.java +++ b/app/src/main/java/org/fdroid/fdroid/AppUpdateStatusManager.java @@ -392,16 +392,16 @@ public final class AppUpdateStatusManager { /** * Get a {@link PendingIntent} for a {@link Notification} to send when it - * is clicked. {@link AppDetails} handles {@code Intent}s that are missing - * or bad {@link AppDetails#EXTRA_APPID}, so it does not need to be checked + * is clicked. {@link AppDetails2} handles {@code Intent}s that are missing + * or bad {@link AppDetails2#EXTRA_APPID}, so it does not need to be checked * here. */ private PendingIntent getAppDetailsIntent(Apk apk) { - Intent notifyIntent = new Intent(context, AppDetails.class) - .putExtra(AppDetails.EXTRA_APPID, apk.packageName); + Intent notifyIntent = new Intent(context, AppDetails2.class) + .putExtra(AppDetails2.EXTRA_APPID, apk.packageName); return TaskStackBuilder.create(context) - .addParentStack(AppDetails.class) + .addParentStack(AppDetails2.class) .addNextIntent(notifyIntent) .getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT); } diff --git a/app/src/main/java/org/fdroid/fdroid/AppUpdateStatusService.java b/app/src/main/java/org/fdroid/fdroid/AppUpdateStatusService.java index f9b0e370c..b3b43b54a 100644 --- a/app/src/main/java/org/fdroid/fdroid/AppUpdateStatusService.java +++ b/app/src/main/java/org/fdroid/fdroid/AppUpdateStatusService.java @@ -12,6 +12,7 @@ import org.fdroid.fdroid.data.App; import org.fdroid.fdroid.data.AppProvider; import org.fdroid.fdroid.data.Schema; import org.fdroid.fdroid.installer.ApkCache; +import org.fdroid.fdroid.installer.InstallManagerService; import java.util.ArrayList; import java.util.List; @@ -53,5 +54,6 @@ public class AppUpdateStatusService extends IntentService { } AppUpdateStatusManager.getInstance(this).addApks(apksReadyToInstall, AppUpdateStatusManager.Status.ReadyToInstall); + InstallManagerService.managePreviouslyDownloadedApks(this); } } \ No newline at end of file diff --git a/app/src/main/java/org/fdroid/fdroid/FDroid.java b/app/src/main/java/org/fdroid/fdroid/FDroid.java index f8a6a30ff..5aff91827 100644 --- a/app/src/main/java/org/fdroid/fdroid/FDroid.java +++ b/app/src/main/java/org/fdroid/fdroid/FDroid.java @@ -243,7 +243,7 @@ public class FDroid extends AppCompatActivity implements SearchView.OnQueryTextL if (!TextUtils.isEmpty(packageName)) { Utils.debugLog(TAG, "FDroid launched via app link for '" + packageName + "'"); Intent intentToInvoke = new Intent(this, AppDetails2.class); - intentToInvoke.putExtra(AppDetails.EXTRA_APPID, packageName); + intentToInvoke.putExtra(AppDetails2.EXTRA_APPID, packageName); startActivity(intentToInvoke); finish(); } else if (!TextUtils.isEmpty(query)) { diff --git a/app/src/main/java/org/fdroid/fdroid/NotificationHelper.java b/app/src/main/java/org/fdroid/fdroid/NotificationHelper.java index 258ef046b..55e3625d4 100644 --- a/app/src/main/java/org/fdroid/fdroid/NotificationHelper.java +++ b/app/src/main/java/org/fdroid/fdroid/NotificationHelper.java @@ -185,7 +185,7 @@ class NotificationHelper { if (entry.status == AppUpdateStatusManager.Status.Unknown) { return true; } else if ((entry.status == AppUpdateStatusManager.Status.Downloading || entry.status == AppUpdateStatusManager.Status.ReadyToInstall || entry.status == AppUpdateStatusManager.Status.InstallError) && - (AppDetails.isAppVisible(entry.app.packageName) || AppDetails2.isAppVisible(entry.app.packageName))) { + AppDetails2.isAppVisible(entry.app.packageName)) { // Ignore downloading, readyToInstall and installError if we are showing the details screen for this app return true; } diff --git a/app/src/main/java/org/fdroid/fdroid/installer/InstallManagerService.java b/app/src/main/java/org/fdroid/fdroid/installer/InstallManagerService.java index 51cc09f3d..7a80f3fc5 100644 --- a/app/src/main/java/org/fdroid/fdroid/installer/InstallManagerService.java +++ b/app/src/main/java/org/fdroid/fdroid/installer/InstallManagerService.java @@ -68,6 +68,16 @@ public class InstallManagerService extends Service { private static final String ACTION_INSTALL = "org.fdroid.fdroid.installer.action.INSTALL"; private static final String ACTION_CANCEL = "org.fdroid.fdroid.installer.action.CANCEL"; + /** + * The install manager service needs to monitor downloaded apks so that it can wait for a user to + * install them and respond accordingly. Usually the thing which starts listening for such events + * does so directly after a download is complete. This works great, except when the user then + * subsequently closes F-Droid and opens it at a later date. Under these circumstances, a background + * service will scan all downloaded apks and notify the user about them. When it does so, the + * install manager service needs to add listeners for if the apks get installed. + */ + private static final String ACTION_MANAGE_DOWNLOADED_APKS = "org.fdroid.fdroid.installer.action.ACTION_MANAGE_DOWNLOADED_APKS"; + private static final String EXTRA_APP = "org.fdroid.fdroid.installer.extra.APP"; private static final String EXTRA_APK = "org.fdroid.fdroid.installer.extra.APK"; @@ -108,13 +118,19 @@ public class InstallManagerService extends Service { public int onStartCommand(Intent intent, int flags, int startId) { Utils.debugLog(TAG, "onStartCommand " + intent); + String action = intent.getAction(); + + if (ACTION_MANAGE_DOWNLOADED_APKS.equals(action)) { + registerInstallerReceiversForDownlaodedApks(); + return START_NOT_STICKY; + } + String urlString = intent.getDataString(); if (TextUtils.isEmpty(urlString)) { Utils.debugLog(TAG, "empty urlString, nothing to do"); return START_NOT_STICKY; } - String action = intent.getAction(); if (ACTION_CANCEL.equals(action)) { DownloaderService.cancel(this, urlString); Apk apk = appUpdateStatusManager.getApk(urlString); @@ -292,6 +308,20 @@ public class InstallManagerService extends Service { DownloaderService.getIntentFilter(urlString)); } + /** + * For each app in the {@link AppUpdateStatusManager.Status#ReadyToInstall} state, setup listeners + * so that if the user installs it then we can respond accordingly. This makes sure that whether + * the user just finished downloading it, or whether they downloaded it a day ago but have not yet + * installed it, we get the same experience upon completing an install. + */ + private void registerInstallerReceiversForDownlaodedApks() { + for (AppUpdateStatusManager.AppUpdateStatus appStatus : AppUpdateStatusManager.getInstance(this).getAll()) { + if (appStatus.status == AppUpdateStatusManager.Status.ReadyToInstall) { + registerInstallerReceivers(Uri.parse(appStatus.getUniqueKey())); + } + } + } + private void registerInstallerReceivers(Uri downloadUri) { BroadcastReceiver installReceiver = new BroadcastReceiver() { @@ -363,4 +393,10 @@ public class InstallManagerService extends Service { intent.setData(Uri.parse(urlString)); context.startService(intent); } + + public static void managePreviouslyDownloadedApks(Context context) { + Intent intent = new Intent(context, InstallManagerService.class); + intent.setAction(ACTION_MANAGE_DOWNLOADED_APKS); + context.startService(intent); + } } diff --git a/app/src/main/java/org/fdroid/fdroid/views/apps/AppListActivity.java b/app/src/main/java/org/fdroid/fdroid/views/apps/AppListActivity.java index c8c3e777b..2da8b69ce 100644 --- a/app/src/main/java/org/fdroid/fdroid/views/apps/AppListActivity.java +++ b/app/src/main/java/org/fdroid/fdroid/views/apps/AppListActivity.java @@ -26,6 +26,7 @@ public class AppListActivity extends AppCompatActivity implements LoaderManager. public static final String EXTRA_CATEGORY = "org.fdroid.fdroid.views.apps.AppListActivity.EXTRA_CATEGORY"; public static final String EXTRA_SEARCH_TERMS = "org.fdroid.fdroid.views.apps.AppListActivity.EXTRA_SEARCH_TERMS"; + private RecyclerView appView; private AppListAdapter appAdapter; private String category; @@ -78,12 +79,11 @@ public class AppListActivity extends AppCompatActivity implements LoaderManager. appView.setHasFixedSize(true); appView.setLayoutManager(new LinearLayoutManager(this)); appView.setAdapter(appAdapter); + + parseIntentForSearchQuery(); } - @Override - protected void onResume() { - super.onResume(); - + private void parseIntentForSearchQuery() { Intent intent = getIntent(); category = intent.hasExtra(EXTRA_CATEGORY) ? intent.getStringExtra(EXTRA_CATEGORY) : null; searchTerms = intent.hasExtra(EXTRA_SEARCH_TERMS) ? intent.getStringExtra(EXTRA_SEARCH_TERMS) : null; diff --git a/app/src/main/java/org/fdroid/fdroid/views/apps/AppListItemController.java b/app/src/main/java/org/fdroid/fdroid/views/apps/AppListItemController.java index 7e6fa22eb..d434582fa 100644 --- a/app/src/main/java/org/fdroid/fdroid/views/apps/AppListItemController.java +++ b/app/src/main/java/org/fdroid/fdroid/views/apps/AppListItemController.java @@ -29,7 +29,6 @@ import android.widget.TextView; import com.nostra13.universalimageloader.core.DisplayImageOptions; import com.nostra13.universalimageloader.core.ImageLoader; -import org.fdroid.fdroid.AppDetails; import org.fdroid.fdroid.AppDetails2; import org.fdroid.fdroid.AppUpdateStatusManager; import org.fdroid.fdroid.R; @@ -254,6 +253,18 @@ public class AppListItemController extends RecyclerView.ViewHolder { return false; } + /** + * Queries the {@link AppUpdateStatusManager} and asks if the app was just successfully installed. + */ + private boolean wasSuccessfullyInstalled(@NonNull App app) { + for (AppUpdateStatusManager.AppUpdateStatus appStatus : AppUpdateStatusManager.getInstance(activity).getByPackageName(app.packageName)) { + if (appStatus.status == AppUpdateStatusManager.Status.Installed) { + return true; + } + } + return false; + } + /** * The app name {@link TextView} is used for a few reasons: * * Display name + summary of the app (most common). @@ -277,6 +288,8 @@ public class AppListItemController extends RecyclerView.ViewHolder { } } else if (isDownloading(app)) { name.setText(activity.getString(R.string.app_list__name__downloading_in_progress, app.name)); + } else if (wasSuccessfullyInstalled(app)) { + name.setText(activity.getString(R.string.app_list__name__successfully_installed, app.name)); } else { name.setText(Utils.formatAppNameAndSummary(app.name, app.summary)); } @@ -396,7 +409,7 @@ public class AppListItemController extends RecyclerView.ViewHolder { } Intent intent = new Intent(activity, AppDetails2.class); - intent.putExtra(AppDetails.EXTRA_APPID, currentApp.packageName); + intent.putExtra(AppDetails2.EXTRA_APPID, currentApp.packageName); if (Build.VERSION.SDK_INT >= 21) { Pair iconTransitionPair = Pair.create((View) icon, activity.getString(R.string.transition_app_item_icon)); Bundle bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(activity, iconTransitionPair).toBundle(); diff --git a/app/src/main/java/org/fdroid/fdroid/views/categories/AppCardController.java b/app/src/main/java/org/fdroid/fdroid/views/categories/AppCardController.java index bf80ab41a..343d9e5a0 100644 --- a/app/src/main/java/org/fdroid/fdroid/views/categories/AppCardController.java +++ b/app/src/main/java/org/fdroid/fdroid/views/categories/AppCardController.java @@ -22,7 +22,6 @@ import com.nostra13.universalimageloader.core.ImageLoader; import com.nostra13.universalimageloader.core.assist.FailReason; import com.nostra13.universalimageloader.core.listener.ImageLoadingListener; -import org.fdroid.fdroid.AppDetails; import org.fdroid.fdroid.AppDetails2; import org.fdroid.fdroid.R; import org.fdroid.fdroid.Utils; @@ -129,7 +128,7 @@ public class AppCardController extends RecyclerView.ViewHolder implements ImageL } Intent intent = new Intent(activity, AppDetails2.class); - intent.putExtra(AppDetails.EXTRA_APPID, currentApp.packageName); + intent.putExtra(AppDetails2.EXTRA_APPID, currentApp.packageName); if (Build.VERSION.SDK_INT >= 21) { Pair iconTransitionPair = Pair.create((View) icon, activity.getString(R.string.transition_app_item_icon)); diff --git a/app/src/main/java/org/fdroid/fdroid/views/fragments/AppListFragment.java b/app/src/main/java/org/fdroid/fdroid/views/fragments/AppListFragment.java index 3a91af37c..d156933a3 100644 --- a/app/src/main/java/org/fdroid/fdroid/views/fragments/AppListFragment.java +++ b/app/src/main/java/org/fdroid/fdroid/views/fragments/AppListFragment.java @@ -169,7 +169,7 @@ public abstract class AppListFragment extends ListFragment implements if (cursor != null) { final App app = new App(cursor); Intent intent = getAppDetailsIntent(useNewDetailsActivity); - intent.putExtra(AppDetails.EXTRA_APPID, app.packageName); + intent.putExtra(AppDetails2.EXTRA_APPID, app.packageName); intent.putExtra(AppDetails.EXTRA_FROM, getFromTitle()); if (Build.VERSION.SDK_INT >= 21) { Pair iconTransitionPair = Pair.create(view.findViewById(R.id.icon), diff --git a/app/src/main/java/org/fdroid/fdroid/views/fragments/PreferencesFragment.java b/app/src/main/java/org/fdroid/fdroid/views/fragments/PreferencesFragment.java index 1e9d97a0a..bd0ee94b2 100644 --- a/app/src/main/java/org/fdroid/fdroid/views/fragments/PreferencesFragment.java +++ b/app/src/main/java/org/fdroid/fdroid/views/fragments/PreferencesFragment.java @@ -13,12 +13,13 @@ import android.preference.PreferenceCategory; import android.support.v4.preference.PreferenceFragment; import android.text.TextUtils; -import org.fdroid.fdroid.AppDetails; +import org.fdroid.fdroid.AppDetails2; import org.fdroid.fdroid.CleanCacheService; import org.fdroid.fdroid.FDroidApp; import org.fdroid.fdroid.Preferences; import org.fdroid.fdroid.PreferencesActivity; import org.fdroid.fdroid.R; +import org.fdroid.fdroid.UpdateService; import org.fdroid.fdroid.installer.InstallHistoryService; import org.fdroid.fdroid.installer.PrivilegedInstaller; @@ -261,8 +262,8 @@ public class PreferencesFragment extends PreferenceFragment @Override public boolean onPreferenceClick(Preference preference) { // Open details of F-Droid Privileged - Intent intent = new Intent(getActivity(), AppDetails.class); - intent.putExtra(AppDetails.EXTRA_APPID, + Intent intent = new Intent(getActivity(), AppDetails2.class); + intent.putExtra(AppDetails2.EXTRA_APPID, PrivilegedInstaller.PRIVILEGED_EXTENSION_PACKAGE_NAME); startActivity(intent); @@ -271,21 +272,34 @@ public class PreferencesFragment extends PreferenceFragment }); } - @Override - public void onResume() { - super.onResume(); + /** + * If a user specifies they want to fetch updates automatically, then start the download of relevant + * updates as soon as they enable the feature. + * Also, if the user has the priv extention installed then change the label to indicate that it + * will actually _install_ apps, not just fetch their .apk file automatically. + */ + private void initAutoFetchUpdatesPreference() { + updateAutoDownloadPref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { - getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this); + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + if (newValue instanceof Boolean && (boolean) newValue) { + UpdateService.autoDownloadUpdates(getContext()); + } + return true; + } + }); - for (final String key : SUMMARIES_TO_UPDATE) { - updateSummary(key, false); + if (PrivilegedInstaller.isDefault(getContext())) { + updateAutoDownloadPref.setTitle(R.string.update_auto_install); + updateAutoDownloadPref.setSummary(R.string.update_auto_install_summary); } + } - currentKeepCacheTime = Preferences.get().getKeepCacheTime(); - - initPrivilegedInstallerPreference(); - initUpdatePrivilegedExtensionPreference(); - // this pref's default is dynamically set based on whether Orbot is installed + /** + * The default for "Use Tor" is dynamically set based on whether Orbot is installed. + */ + private void initUseTorPreference() { boolean useTor = Preferences.get().isTorEnabled(); useTorCheckPref.setDefaultValue(useTor); useTorCheckPref.setChecked(useTor); @@ -308,11 +322,24 @@ public class PreferencesFragment extends PreferenceFragment return true; } }); + } - if (PrivilegedInstaller.isDefault(getContext())) { - updateAutoDownloadPref.setTitle(R.string.update_auto_install); - updateAutoDownloadPref.setSummary(R.string.update_auto_install_summary); + @Override + public void onResume() { + super.onResume(); + + getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this); + + for (final String key : SUMMARIES_TO_UPDATE) { + updateSummary(key, false); } + + currentKeepCacheTime = Preferences.get().getKeepCacheTime(); + + initAutoFetchUpdatesPreference(); + initPrivilegedInstallerPreference(); + initUpdatePrivilegedExtensionPreference(); + initUseTorPreference(); } @Override diff --git a/app/src/main/java/org/fdroid/fdroid/views/main/MainActivity.java b/app/src/main/java/org/fdroid/fdroid/views/main/MainActivity.java index bd7711053..759ac2358 100644 --- a/app/src/main/java/org/fdroid/fdroid/views/main/MainActivity.java +++ b/app/src/main/java/org/fdroid/fdroid/views/main/MainActivity.java @@ -23,7 +23,6 @@ import com.ashokvarma.bottomnavigation.BadgeItem; import com.ashokvarma.bottomnavigation.BottomNavigationBar; import com.ashokvarma.bottomnavigation.BottomNavigationItem; -import org.fdroid.fdroid.AppDetails; import org.fdroid.fdroid.AppDetails2; import org.fdroid.fdroid.AppUpdateStatusManager; import org.fdroid.fdroid.FDroidApp; @@ -281,7 +280,7 @@ public class MainActivity extends AppCompatActivity implements BottomNavigationB if (!TextUtils.isEmpty(packageName)) { Utils.debugLog(TAG, "FDroid launched via app link for '" + packageName + "'"); Intent intentToInvoke = new Intent(this, AppDetails2.class); - intentToInvoke.putExtra(AppDetails.EXTRA_APPID, packageName); + intentToInvoke.putExtra(AppDetails2.EXTRA_APPID, packageName); startActivity(intentToInvoke); finish(); } else if (!TextUtils.isEmpty(query)) { diff --git a/app/src/main/java/org/fdroid/fdroid/views/main/MainViewAdapter.java b/app/src/main/java/org/fdroid/fdroid/views/main/MainViewAdapter.java index 7731c89c3..aeaf7e775 100644 --- a/app/src/main/java/org/fdroid/fdroid/views/main/MainViewAdapter.java +++ b/app/src/main/java/org/fdroid/fdroid/views/main/MainViewAdapter.java @@ -69,7 +69,8 @@ class MainViewAdapter extends RecyclerView.Adapter { holder.bindSwapView(); break; case R.id.updates: - holder.bindUpdates(); + // Hold of until onViewAttachedToWindow, because that is where we want to start listening + // for broadcast events (which is what the data binding does). break; case R.id.settings: holder.bindSettingsView(); diff --git a/app/src/main/java/org/fdroid/fdroid/views/main/MainViewController.java b/app/src/main/java/org/fdroid/fdroid/views/main/MainViewController.java index e5e804c3b..72a4dcd17 100644 --- a/app/src/main/java/org/fdroid/fdroid/views/main/MainViewController.java +++ b/app/src/main/java/org/fdroid/fdroid/views/main/MainViewController.java @@ -8,6 +8,7 @@ import android.support.v7.widget.RecyclerView; import android.view.View; import android.widget.Button; import android.widget.FrameLayout; +import android.widget.TextView; import org.fdroid.fdroid.R; import org.fdroid.fdroid.views.fragments.PreferencesFragment; @@ -75,6 +76,11 @@ class MainViewController extends RecyclerView.ViewHolder { public void bindSwapView() { View swapView = activity.getLayoutInflater().inflate(R.layout.main_tab_swap, frame, true); + // To allow for whitelabel versions of F-Droid, make sure not to hardcode "F-Droid" into our + // translation here. + TextView subtext = (TextView) swapView.findViewById(R.id.text2); + subtext.setText(activity.getString(R.string.nearby_splash__both_parties_need_fdroid, activity.getString(R.string.app_name))); + Button startButton = (Button) swapView.findViewById(R.id.button); startButton.setOnClickListener(new View.OnClickListener() { @Override diff --git a/app/src/main/java/org/fdroid/fdroid/views/updates/UpdatesAdapter.java b/app/src/main/java/org/fdroid/fdroid/views/updates/UpdatesAdapter.java index b144b957f..db2dc1824 100644 --- a/app/src/main/java/org/fdroid/fdroid/views/updates/UpdatesAdapter.java +++ b/app/src/main/java/org/fdroid/fdroid/views/updates/UpdatesAdapter.java @@ -57,6 +57,9 @@ import java.util.List; * repopulate it from the original source lists of data. When this is done, the adapter will notify * the recycler view that its data has changed. Sometimes it will also ask the recycler view to * scroll to the newly added item (if attached to the recycler view). + * + * TODO: If a user downloads an old version of an app (resulting in a new update being available + * instantly), then we need to refresh the list of apps to update. */ public class UpdatesAdapter extends RecyclerView.Adapter implements LoaderManager.LoaderCallbacks { @@ -84,16 +87,12 @@ public class UpdatesAdapter extends RecyclerView.Adapter loader) { } /** + * If this adapter is "active" then it is part of the current UI that the user is looking to. + * Under those circumstances, we want to make sure it is up to date, and also listen to the + * correct set of broadcasts. * Doesn't listen for {@link AppUpdateStatusManager#BROADCAST_APPSTATUS_CHANGED} because the * individual items in the recycler view will listen for the appropriate changes in state and * update themselves accordingly (if they are displayed). */ - public void listenForStatusUpdates() { + public void setIsActive() { + appsToShowStatus.clear(); + populateAppStatuses(); + notifyDataSetChanged(); + IntentFilter filter = new IntentFilter(); filter.addAction(AppUpdateStatusManager.BROADCAST_APPSTATUS_ADDED); filter.addAction(AppUpdateStatusManager.BROADCAST_APPSTATUS_REMOVED); diff --git a/app/src/main/java/org/fdroid/fdroid/views/updates/UpdatesViewBinder.java b/app/src/main/java/org/fdroid/fdroid/views/updates/UpdatesViewBinder.java index c48f802dd..50d287bfe 100644 --- a/app/src/main/java/org/fdroid/fdroid/views/updates/UpdatesViewBinder.java +++ b/app/src/main/java/org/fdroid/fdroid/views/updates/UpdatesViewBinder.java @@ -24,7 +24,7 @@ public class UpdatesViewBinder { } public void bind() { - adapter.listenForStatusUpdates(); + adapter.setIsActive(); } public void unbind() { diff --git a/app/src/main/res/drawable/nearby_splash.xml b/app/src/main/res/drawable/nearby_splash.xml new file mode 100644 index 000000000..cee12a2cf --- /dev/null +++ b/app/src/main/res/drawable/nearby_splash.xml @@ -0,0 +1,6 @@ + + + diff --git a/app/src/main/res/layout/app_details2_header.xml b/app/src/main/res/layout/app_details2_header.xml index 2c14167d6..c2b3ada6c 100755 --- a/app/src/main/res/layout/app_details2_header.xml +++ b/app/src/main/res/layout/app_details2_header.xml @@ -151,7 +151,6 @@ android:layout_marginStart="8dp" android:layout_weight="1" android:ellipsize="marquee" - android:padding="12dp" tools:text="THIS IS 2" /> diff --git a/app/src/main/res/layout/main_tab_swap.xml b/app/src/main/res/layout/main_tab_swap.xml index bc439185c..adc254e3e 100644 --- a/app/src/main/res/layout/main_tab_swap.xml +++ b/app/src/main/res/layout/main_tab_swap.xml @@ -4,60 +4,66 @@ xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" - android:layout_height="match_parent"> - - + android:layout_height="match_parent" + android:background="#FAFAFA"> - - - - + app:layout_constraintTop_toTopOf="parent" />