Merge branch 'first-run-index-update' into 'master'

First run index update

See merge request fdroid/fdroidclient!714
This commit is contained in:
Hans-Christoph Steiner 2018-07-20 11:23:22 +00:00
commit e374a3da5a
8 changed files with 72 additions and 52 deletions

View File

@ -70,8 +70,7 @@ errorprone:
- ./gradlew connectedCheck || (adb -e logcat -d '*:E' > logcat.txt; exit 1)
connected24:
only:
- fdroid/fdroidclient@master
retry: 1
<<: *test-template
variables:
AVD_SDK: "24"
@ -79,10 +78,6 @@ connected24:
AVD_PACKAGE: "system-images;android-${AVD_SDK};${AVD_TAG};armeabi-v7a"
<<: *connected-template
connected25:
<<: *test-template
<<: *connected-template
deploy_nightly:
stage: deploy
only:

View File

@ -13,8 +13,9 @@ import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import org.fdroid.fdroid.Preferences;
import org.fdroid.fdroid.R;
import org.fdroid.fdroid.UpdateService;
@ -40,6 +41,8 @@ class WhatsNewViewBinder implements LoaderManager.LoaderCallbacks<Cursor> {
private final TextView emptyState;
private final RecyclerView appList;
private ProgressBar progressBar;
WhatsNewViewBinder(final AppCompatActivity activity, FrameLayout parent) {
this.activity = activity;
@ -124,6 +127,19 @@ class WhatsNewViewBinder implements LoaderManager.LoaderCallbacks<Cursor> {
}
private void explainEmptyStateToUser() {
if (Preferences.get().isIndexNeverUpdated() && UpdateService.isUpdating()) {
if (progressBar != null) {
return;
}
LinearLayout linearLayout = (LinearLayout) appList.getParent();
progressBar = new ProgressBar(activity, null, android.R.attr.progressBarStyleLarge);
progressBar.setId(R.id.progress_bar);
linearLayout.addView(progressBar);
emptyState.setVisibility(View.GONE);
appList.setVisibility(View.GONE);
return;
}
StringBuilder emptyStateText = new StringBuilder();
emptyStateText.append(activity.getString(R.string.latest__empty_state__no_recent_apps));
emptyStateText.append("\n\n");

View File

@ -349,8 +349,9 @@ public class FDroidApp extends Application {
}
Preferences.setup(this);
Languages.setLanguage(this);
Preferences preferences = Preferences.get();
if (Preferences.get().promptToSendCrashReports()) {
if (preferences.promptToSendCrashReports()) {
ACRA.init(this);
if (isAcraProcess() || HidingManager.isHidden(this)) {
return;
@ -359,16 +360,15 @@ public class FDroidApp extends Application {
PRNGFixes.apply();
curTheme = Preferences.get().getTheme();
Preferences.get().configureProxy();
curTheme = preferences.getTheme();
preferences.configureProxy();
// bug specific to exactly 5.0 makes it only work with the old index
// which includes an ugly, hacky workaround
// https://gitlab.com/fdroid/fdroidclient/issues/1014
if (Build.VERSION.SDK_INT == 21) {
Preferences p = Preferences.get();
p.setExpertMode(true);
p.setForceOldIndex(true);
preferences.setExpertMode(true);
preferences.setForceOldIndex(true);
}
InstalledAppProviderService.compareToPackageManager(this);
@ -376,7 +376,7 @@ public class FDroidApp extends Application {
// If the user changes the preference to do with filtering rooted apps,
// it is easier to just notify a change in the app provider,
// so that the newly updated list will correctly filter relevant apps.
Preferences.get().registerAppsRequiringRootChangeListener(new Preferences.ChangeListener() {
preferences.registerAppsRequiringRootChangeListener(new Preferences.ChangeListener() {
@Override
public void onPreferenceChange() {
getContentResolver().notifyChange(AppProvider.getContentUri(), null);
@ -386,14 +386,14 @@ public class FDroidApp extends Application {
// If the user changes the preference to do with filtering anti-feature apps,
// it is easier to just notify a change in the app provider,
// so that the newly updated list will correctly filter relevant apps.
Preferences.get().registerAppsRequiringAntiFeaturesChangeListener(new Preferences.ChangeListener() {
preferences.registerAppsRequiringAntiFeaturesChangeListener(new Preferences.ChangeListener() {
@Override
public void onPreferenceChange() {
getContentResolver().notifyChange(AppProvider.getContentUri(), null);
}
});
Preferences.get().registerUnstableUpdatesChangeListener(new Preferences.ChangeListener() {
preferences.registerUnstableUpdatesChangeListener(new Preferences.ChangeListener() {
@Override
public void onPreferenceChange() {
AppProvider.Helper.calcSuggestedApks(FDroidApp.this);
@ -403,7 +403,6 @@ public class FDroidApp extends Application {
CleanCacheService.schedule(this);
notificationHelper = new NotificationHelper(getApplicationContext());
UpdateService.schedule(getApplicationContext());
bluetoothAdapter = getBluetoothAdapter();
// There are a couple things to pay attention to with this config: memory usage,
@ -452,21 +451,26 @@ public class FDroidApp extends Application {
.build();
ImageLoader.getInstance().init(config);
if (preferences.isIndexNeverUpdated()) {
// force this check to ensure it starts fetching the index on initial runs
networkState = ConnectivityMonitorService.getNetworkState(this);
}
ConnectivityMonitorService.registerAndStart(this);
UpdateService.schedule(getApplicationContext());
FDroidApp.initWifiSettings();
WifiStateChangeService.start(this, null);
// if the HTTPS pref changes, then update all affected things
Preferences.get().registerLocalRepoHttpsListeners(new ChangeListener() {
preferences.registerLocalRepoHttpsListeners(new ChangeListener() {
@Override
public void onPreferenceChange() {
WifiStateChangeService.start(getApplicationContext(), null);
}
});
configureTor(Preferences.get().isTorEnabled());
configureTor(preferences.isTorEnabled());
if (Preferences.get().isKeepingInstallHistory()) {
if (preferences.isKeepingInstallHistory()) {
InstallHistoryService.register(this);
}
@ -492,7 +496,7 @@ public class FDroidApp extends Application {
atStartTime.edit().putInt("build-version", Build.VERSION.SDK_INT).apply();
final String queryStringKey = "http-downloader-query-string";
if (Preferences.get().sendVersionAndUUIDToServers()) {
if (preferences.sendVersionAndUUIDToServers()) {
HttpDownloader.queryString = atStartTime.getString(queryStringKey, null);
if (HttpDownloader.queryString == null) {
UUID uuid = UUID.randomUUID();

View File

@ -101,7 +101,6 @@ public final class Preferences implements SharedPreferences.OnSharedPreferenceCh
public static final String PREF_PROXY_PORT = "proxyPort";
public static final String PREF_SHOW_NFC_DURING_SWAP = "showNfcDuringSwap";
public static final String PREF_POST_PRIVILEGED_INSTALL = "postPrivilegedInstall";
public static final String PREF_TRIED_EMPTY_UPDATE = "triedEmptyUpdate";
public static final String PREF_PREVENT_SCREENSHOTS = "preventScreenshots";
public static final String PREF_PANIC_EXIT = "pref_panic_exit";
public static final String PREF_PANIC_HIDE = "pref_panic_hide";
@ -114,10 +113,14 @@ public final class Preferences implements SharedPreferences.OnSharedPreferenceCh
public static final int OVER_NETWORK_ON_DEMAND = 1;
public static final int OVER_NETWORK_ALWAYS = 2;
// not shown in Settings
private static final String PREF_LAST_UPDATE_CHECK = "lastUpdateCheck";
// these preferences are not listed in preferences.xml so the defaults are set here
@SuppressWarnings("PMD.AvoidUsingHardCodedIP")
public static final String DEFAULT_PROXY_HOST = "127.0.0.1"; // TODO move to preferences.xml
public static final int DEFAULT_PROXY_PORT = 8118; // TODO move to preferences.xml
private static final int DEFAULT_LAST_UPDATE_CHECK = -1;
private static final boolean DEFAULT_SHOW_NFC_DURING_SWAP = true;
private static final boolean DEFAULT_POST_PRIVILEGED_INSTALL = false;
private static final boolean DEFAULT_PANIC_EXIT = true;
@ -321,18 +324,23 @@ public final class Preferences implements SharedPreferences.OnSharedPreferenceCh
}
}
/**
* Used the first time F-Droid is installed to flag whether or not we have tried to request
* apps from the repo. This is used so that when there is no apps available, we can differentiate
* between whether the repos actually have no apps (in which case we don't need to continue
* asking), or whether there is no apps because we have never actually asked to update the repos.
*/
public boolean hasTriedEmptyUpdate() {
return preferences.getBoolean(PREF_TRIED_EMPTY_UPDATE, IGNORED_B);
public long getLastUpdateCheck() {
return preferences.getLong(PREF_LAST_UPDATE_CHECK, DEFAULT_LAST_UPDATE_CHECK);
}
public void setTriedEmptyUpdate(boolean value) {
preferences.edit().putBoolean(PREF_TRIED_EMPTY_UPDATE, value).apply();
public void setLastUpdateCheck(long lastUpdateCheck) {
preferences.edit().putLong(PREF_LAST_UPDATE_CHECK, lastUpdateCheck).apply();
}
public void resetLastUpdateCheck() {
setLastUpdateCheck(DEFAULT_LAST_UPDATE_CHECK);
}
/**
* The first time the app has been run since fresh install or clearing all data.
*/
public boolean isIndexNeverUpdated() {
return getLastUpdateCheck() == DEFAULT_LAST_UPDATE_CHECK;
}
public boolean getUnstableUpdates() {

View File

@ -29,7 +29,6 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
@ -41,7 +40,6 @@ import android.support.annotation.NonNull;
import android.support.v4.app.JobIntentService;
import android.support.v4.app.NotificationCompat;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.preference.PreferenceManager;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;
@ -82,11 +80,11 @@ public class UpdateService extends JobIntentService {
public static final int STATUS_ERROR_LOCAL_SMALL = 4;
public static final int STATUS_INFO = 5;
private static final String STATE_LAST_UPDATED = "lastUpdateCheck";
private static final int JOB_ID = 0xfedcba;
private static final int NOTIFY_ID_UPDATING = 0;
private static UpdateService updateService;
private static Handler toastHandler;
private NotificationManager notificationManager;
@ -118,11 +116,19 @@ public class UpdateService extends JobIntentService {
}
/**
* Add work to the queue for processing now
* Add work to the queue for processing now.
* <p>
* This also shows a {@link Toast} if the Data/WiFi Settings make it so the
* update process is not allowed to run and the device is attached to a
* network (e.g. is not offline or in Airplane Mode).
*
* @see JobIntentService#enqueueWork(Context, Class, int, Intent)
*/
private static void enqueueWork(Context context, @NonNull Intent intent) {
if (FDroidApp.networkState > 0 && !Preferences.get().isOnDemandDownloadAllowed()) {
Toast.makeText(context, R.string.updates_disabled_by_settings, Toast.LENGTH_LONG).show();
}
enqueueWork(context, UpdateService.class, JOB_ID, intent);
}
@ -188,6 +194,8 @@ public class UpdateService extends JobIntentService {
/**
* Whether or not a repo update is currently in progress. Used to show feedback throughout
* the app to users, so they know something is happening.
*
* @see <a href="https://stackoverflow.com/a/608600">set a global variable when it is running that your client can check</a>
*/
public static boolean isUpdating() {
return updateService != null;
@ -239,8 +247,6 @@ public class UpdateService extends JobIntentService {
}
private static UpdateService updateService;
public static void stopNow(Context context) {
if (updateService != null) {
updateService.stopSelf(JOB_ID);
@ -494,10 +500,7 @@ public class UpdateService extends JobIntentService {
}
}
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
SharedPreferences.Editor e = prefs.edit();
e.putLong(STATE_LAST_UPDATED, System.currentTimeMillis());
e.apply();
fdroidPrefs.setLastUpdateCheck(System.currentTimeMillis());
if (errorRepos == 0) {
if (changes) {

View File

@ -1095,7 +1095,7 @@ public class DBHelper extends SQLiteOpenHelper {
private static void resetTransient(SQLiteDatabase db) {
Utils.debugLog(TAG, "Removing all index tables, they will be recreated next time F-Droid updates.");
Preferences.get().setTriedEmptyUpdate(false);
Preferences.get().resetLastUpdateCheck();
db.beginTransaction();
try {
@ -1147,7 +1147,7 @@ public class DBHelper extends SQLiteOpenHelper {
return;
}
Preferences.get().setTriedEmptyUpdate(false);
Preferences.get().resetLastUpdateCheck();
db.execSQL("drop table " + AppMetadataTable.NAME);
db.execSQL("drop table " + ApkTable.NAME);

View File

@ -158,16 +158,9 @@ public class MainActivity extends AppCompatActivity implements BottomNavigationB
bottomNavigation.selectTab(adapter.adapterPositionFromItemId(selectedMenuId));
}
/**
* The first time the app is run, we will have an empty app list. To deal with this, we will
* attempt to update with the default repo. However, if we have tried this at least once, then
* don't try to do it automatically again.
*/
private void initialRepoUpdateIfRequired() {
Preferences prefs = Preferences.get();
if (!prefs.hasTriedEmptyUpdate()) {
if (Preferences.get().isIndexNeverUpdated() && !UpdateService.isUpdating()) {
Utils.debugLog(TAG, "We haven't done an update yet. Forcing repo update.");
prefs.setTriedEmptyUpdate(true);
UpdateService.updateNow(this);
}
}

View File

@ -129,6 +129,7 @@ This often occurs with apps installed via Google Play or other sources, if they
<item quantity="one">Download update for %1$d app.</item>
<item quantity="other">Download updates for %1$d apps.</item>
</plurals>
<string name="updates_disabled_by_settings">All updates disabled by Data/WiFi Settings</string>
<string name="ok">OK</string>