Updater: The great cleanup
* Make final where possible * Remove unused casts, imports, methods, enums and constructors * Add null checks Change-Id: Idd1a16426dd1928e2ed9922f5a35ba32ce4f808b
This commit is contained in:
@@ -1,13 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:orientation="horizontal"
|
||||
android:id="@+id/main_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true"
|
||||
android:padding="16dp"
|
||||
android:weightSum="2">
|
||||
android:weightSum="2"
|
||||
android:baselineAligned="false">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="0dp"
|
||||
@@ -29,57 +30,57 @@
|
||||
android:fontFamily="sans-serif-light"
|
||||
android:paddingBottom="16dp"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textSize="56sp" />
|
||||
android:textSize="56sp"
|
||||
tools:text="LineageOS\n18.1" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/header_build_version"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/header_title"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textSize="14sp" />
|
||||
android:textSize="14sp"
|
||||
tools:text="Android 11"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/header_build_date"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/header_build_version"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textSize="14sp" />
|
||||
android:textSize="14sp"
|
||||
tools:text="2022-01-01"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/header_last_check"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/header_build_date"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textSize="14sp" />
|
||||
android:textSize="14sp"
|
||||
tools:text="Last checked: 2022-01-01"/>
|
||||
|
||||
</LinearLayout>
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/header_last_check"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:weightSum="2"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
android:id="@+id/refresh"
|
||||
android:drawableLeft="@drawable/ic_menu_refresh"
|
||||
android:drawableStart="@drawable/ic_menu_refresh"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="refresh"
|
||||
android:text="@string/menu_refresh"
|
||||
style="@style/Widget.AppCompat.Button.Borderless.Colored"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/preferences"
|
||||
android:drawableLeft="@drawable/ic_menu_preferences"
|
||||
android:drawableStart="@drawable/ic_menu_preferences"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="preferences"
|
||||
android:text="@string/menu_preferences"
|
||||
style="@style/Widget.AppCompat.Button.Borderless.Colored"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
@@ -16,7 +16,8 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal"
|
||||
android:weightSum="1">
|
||||
android:weightSum="1"
|
||||
android:baselineAligned="false">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
@@ -90,7 +91,8 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end"
|
||||
android:padding="8dp" />
|
||||
android:padding="8dp"
|
||||
android:contentDescription="@null" />
|
||||
<Button
|
||||
android:id="@id/update_action"
|
||||
style="@style/Widget.AppCompat.Button.Borderless.Colored"
|
||||
|
@@ -29,7 +29,7 @@
|
||||
android:entries="@array/menu_auto_updates_check_interval_entries" />
|
||||
</LinearLayout>
|
||||
|
||||
<Switch
|
||||
<androidx.appcompat.widget.SwitchCompat
|
||||
android:id="@+id/preferences_auto_delete_updates"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
@@ -37,7 +37,7 @@
|
||||
android:text="@string/menu_auto_delete_updates"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<Switch
|
||||
<androidx.appcompat.widget.SwitchCompat
|
||||
android:id="@+id/preferences_mobile_data_warning"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
@@ -45,7 +45,7 @@
|
||||
android:text="@string/menu_mobile_data_warning"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<Switch
|
||||
<androidx.appcompat.widget.SwitchCompat
|
||||
android:id="@+id/preferences_ab_perf_mode"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
@@ -53,7 +53,7 @@
|
||||
android:text="@string/menu_ab_perf_mode"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<Switch
|
||||
<androidx.appcompat.widget.SwitchCompat
|
||||
android:id="@+id/preferences_update_recovery"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
@@ -15,7 +15,8 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal"
|
||||
android:weightSum="1">
|
||||
android:weightSum="1"
|
||||
android:baselineAligned="false">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
@@ -89,7 +90,8 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end"
|
||||
android:padding="8dp" />
|
||||
android:padding="8dp"
|
||||
android:contentDescription="@null" />
|
||||
<Button
|
||||
android:id="@id/update_action"
|
||||
style="@style/Widget.AppCompat.Button.Borderless.Colored"
|
||||
|
@@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item
|
||||
android:id="@+id/menu_export_update"
|
||||
android:title="@string/menu_export_update" />
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The LineageOS Project
|
||||
* Copyright (C) 2017-2022 The LineageOS Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -94,11 +94,11 @@ public class ExportUpdateService extends Service {
|
||||
}
|
||||
|
||||
private class ExportRunnable implements Runnable {
|
||||
private File mSource;
|
||||
private File mDestination;
|
||||
private FileUtils.ProgressCallBack mProgressCallBack;
|
||||
private Runnable mRunnableComplete;
|
||||
private Runnable mRunnableFailed;
|
||||
private final File mSource;
|
||||
private final File mDestination;
|
||||
private final FileUtils.ProgressCallBack mProgressCallBack;
|
||||
private final Runnable mRunnableComplete;
|
||||
private final Runnable mRunnableFailed;
|
||||
|
||||
private ExportRunnable(File source, File destination,
|
||||
FileUtils.ProgressCallBack progressCallBack,
|
||||
@@ -131,13 +131,13 @@ public class ExportUpdateService extends Service {
|
||||
}
|
||||
|
||||
private void cleanUp() {
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
mDestination.delete();
|
||||
}
|
||||
}
|
||||
|
||||
private void startExporting(File source, File destination) {
|
||||
NotificationManager notificationManager =
|
||||
(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
|
||||
NotificationManager notificationManager = getSystemService(NotificationManager.class);
|
||||
NotificationChannel notificationChannel = new NotificationChannel(
|
||||
EXPORT_NOTIFICATION_CHANNEL,
|
||||
getString(R.string.export_channel_title),
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The LineageOS Project
|
||||
* Copyright (C) 2017-2022 The LineageOS Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -79,8 +79,7 @@ public class UpdaterReceiver extends BroadcastReceiver {
|
||||
.setStyle(new NotificationCompat.BigTextStyle().bigText(buildInfo))
|
||||
.setContentText(buildInfo);
|
||||
|
||||
NotificationManager nm = (NotificationManager) context.getSystemService(
|
||||
Context.NOTIFICATION_SERVICE);
|
||||
NotificationManager nm = context.getSystemService(NotificationManager.class);
|
||||
nm.createNotificationChannel(notificationChannel);
|
||||
nm.notify(0, builder.build());
|
||||
}
|
||||
@@ -88,7 +87,7 @@ public class UpdaterReceiver extends BroadcastReceiver {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (ACTION_INSTALL_REBOOT.equals(intent.getAction())) {
|
||||
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
|
||||
PowerManager pm = context.getSystemService(PowerManager.class);
|
||||
pm.reboot(null);
|
||||
} else if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
|
||||
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2017-2020 The LineageOS Project
|
||||
* Copyright (C) 2017-2022 The LineageOS Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.lineageos.updater;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.UiModeManager;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ComponentName;
|
||||
@@ -39,14 +40,13 @@ import android.view.View;
|
||||
import android.view.animation.Animation;
|
||||
import android.view.animation.LinearInterpolator;
|
||||
import android.view.animation.RotateAnimation;
|
||||
import android.widget.Button;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.Switch;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.appcompat.app.ActionBar;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.app.AppCompatDelegate;
|
||||
import androidx.appcompat.widget.SwitchCompat;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
import androidx.preference.PreferenceManager;
|
||||
@@ -92,10 +92,10 @@ public class UpdatesActivity extends UpdatesListActivity {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_updates);
|
||||
|
||||
UiModeManager uiModeManager = (UiModeManager) getSystemService(UI_MODE_SERVICE);
|
||||
UiModeManager uiModeManager = getSystemService(UiModeManager.class);
|
||||
mIsTV = uiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_TELEVISION;
|
||||
|
||||
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
|
||||
RecyclerView recyclerView = findViewById(R.id.recycler_view);
|
||||
mAdapter = new UpdatesListAdapter(this);
|
||||
recyclerView.setAdapter(mAdapter);
|
||||
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
|
||||
@@ -111,7 +111,7 @@ public class UpdatesActivity extends UpdatesListActivity {
|
||||
if (UpdaterController.ACTION_UPDATE_STATUS.equals(intent.getAction())) {
|
||||
String downloadId = intent.getStringExtra(UpdaterController.EXTRA_DOWNLOAD_ID);
|
||||
handleDownloadStatusChange(downloadId);
|
||||
mAdapter.notifyDataSetChanged();
|
||||
mAdapter.notifyItemChanged(downloadId);
|
||||
} else if (UpdaterController.ACTION_DOWNLOAD_PROGRESS.equals(intent.getAction()) ||
|
||||
UpdaterController.ACTION_INSTALL_PROGRESS.equals(intent.getAction())) {
|
||||
String downloadId = intent.getStringExtra(UpdaterController.EXTRA_DOWNLOAD_ID);
|
||||
@@ -124,31 +124,33 @@ public class UpdatesActivity extends UpdatesListActivity {
|
||||
};
|
||||
|
||||
if (!mIsTV) {
|
||||
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
getSupportActionBar().setDisplayShowTitleEnabled(false);
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
ActionBar actionBar = getSupportActionBar();
|
||||
if (actionBar != null) {
|
||||
actionBar.setDisplayShowTitleEnabled(false);
|
||||
actionBar.setDisplayHomeAsUpEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
TextView headerTitle = (TextView) findViewById(R.id.header_title);
|
||||
TextView headerTitle = findViewById(R.id.header_title);
|
||||
headerTitle.setText(getString(R.string.header_title_text,
|
||||
BuildInfoUtils.getBuildVersion()));
|
||||
|
||||
updateLastCheckedString();
|
||||
|
||||
TextView headerBuildVersion = (TextView) findViewById(R.id.header_build_version);
|
||||
TextView headerBuildVersion = findViewById(R.id.header_build_version);
|
||||
headerBuildVersion.setText(
|
||||
getString(R.string.header_android_version, Build.VERSION.RELEASE));
|
||||
|
||||
TextView headerBuildDate = (TextView) findViewById(R.id.header_build_date);
|
||||
TextView headerBuildDate = findViewById(R.id.header_build_date);
|
||||
headerBuildDate.setText(StringGenerator.getDateLocalizedUTC(this,
|
||||
DateFormat.LONG, BuildInfoUtils.getBuildDateTimestamp()));
|
||||
|
||||
if (!mIsTV) {
|
||||
// Switch between header title and appbar title minimizing overlaps
|
||||
final CollapsingToolbarLayout collapsingToolbar =
|
||||
(CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar);
|
||||
final AppBarLayout appBar = (AppBarLayout) findViewById(R.id.app_bar);
|
||||
final CollapsingToolbarLayout collapsingToolbar = findViewById(R.id.collapsing_toolbar);
|
||||
final AppBarLayout appBar = findViewById(R.id.app_bar);
|
||||
appBar.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
|
||||
boolean mIsShown = false;
|
||||
|
||||
@@ -175,18 +177,8 @@ public class UpdatesActivity extends UpdatesListActivity {
|
||||
appBar.setExpanded(false);
|
||||
}
|
||||
} else {
|
||||
findViewById(R.id.refresh).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
downloadUpdatesList(true);
|
||||
}
|
||||
});
|
||||
findViewById(R.id.preferences).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
showPreferencesDialog();
|
||||
}
|
||||
});
|
||||
findViewById(R.id.refresh).setOnClickListener(v -> downloadUpdatesList(true));
|
||||
findViewById(R.id.preferences).setOnClickListener(v -> showPreferencesDialog());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,22 +214,19 @@ public class UpdatesActivity extends UpdatesListActivity {
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.menu_refresh: {
|
||||
int itemId = item.getItemId();
|
||||
if (itemId == R.id.menu_refresh) {
|
||||
downloadUpdatesList(true);
|
||||
return true;
|
||||
}
|
||||
case R.id.menu_preferences: {
|
||||
} else if (itemId == R.id.menu_preferences) {
|
||||
showPreferencesDialog();
|
||||
return true;
|
||||
}
|
||||
case R.id.menu_show_changelog: {
|
||||
} else if (itemId == R.id.menu_show_changelog) {
|
||||
Intent openUrl = new Intent(Intent.ACTION_VIEW,
|
||||
Uri.parse(Utils.getChangelogURL(this)));
|
||||
startActivity(openUrl);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@@ -247,7 +236,7 @@ public class UpdatesActivity extends UpdatesListActivity {
|
||||
return true;
|
||||
}
|
||||
|
||||
private ServiceConnection mConnection = new ServiceConnection() {
|
||||
private final ServiceConnection mConnection = new ServiceConnection() {
|
||||
|
||||
@Override
|
||||
public void onServiceConnected(ComponentName className,
|
||||
@@ -330,6 +319,7 @@ public class UpdatesActivity extends UpdatesListActivity {
|
||||
}
|
||||
// In case we set a one-shot check because of a previous failure
|
||||
UpdatesCheckReceiver.cancelUpdatesCheck(this);
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
jsonNew.renameTo(json);
|
||||
} catch (IOException | JSONException e) {
|
||||
Log.e(TAG, "Could not read json", e);
|
||||
@@ -356,12 +346,11 @@ public class UpdatesActivity extends UpdatesListActivity {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponse(int statusCode, String url,
|
||||
DownloadClient.Headers headers) {
|
||||
public void onResponse(DownloadClient.Headers headers) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(File destination) {
|
||||
public void onSuccess() {
|
||||
runOnUiThread(() -> {
|
||||
Log.d(TAG, "List downloaded");
|
||||
processNewJson(jsonFile, jsonFileTmp, manualRefresh);
|
||||
@@ -394,7 +383,7 @@ public class UpdatesActivity extends UpdatesListActivity {
|
||||
String lastCheckString = getString(R.string.header_last_updates_check,
|
||||
StringGenerator.getDateLocalized(this, DateFormat.LONG, lastCheck),
|
||||
StringGenerator.getTimeLocalized(this, lastCheck));
|
||||
TextView headerLastCheck = (TextView) findViewById(R.id.header_last_check);
|
||||
TextView headerLastCheck = findViewById(R.id.header_last_check);
|
||||
headerLastCheck.setText(lastCheckString);
|
||||
}
|
||||
|
||||
@@ -451,14 +440,14 @@ public class UpdatesActivity extends UpdatesListActivity {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
private void showPreferencesDialog() {
|
||||
View view = LayoutInflater.from(this).inflate(R.layout.preferences_dialog, null);
|
||||
Spinner autoCheckInterval =
|
||||
view.findViewById(R.id.preferences_auto_updates_check_interval);
|
||||
Switch autoDelete = view.findViewById(R.id.preferences_auto_delete_updates);
|
||||
Switch dataWarning = view.findViewById(R.id.preferences_mobile_data_warning);
|
||||
Switch abPerfMode = view.findViewById(R.id.preferences_ab_perf_mode);
|
||||
Switch updateRecovery = view.findViewById(R.id.preferences_update_recovery);
|
||||
Spinner autoCheckInterval = view.findViewById(R.id.preferences_auto_updates_check_interval);
|
||||
SwitchCompat autoDelete = view.findViewById(R.id.preferences_auto_delete_updates);
|
||||
SwitchCompat dataWarning = view.findViewById(R.id.preferences_mobile_data_warning);
|
||||
SwitchCompat abPerfMode = view.findViewById(R.id.preferences_ab_perf_mode);
|
||||
SwitchCompat updateRecovery = view.findViewById(R.id.preferences_update_recovery);
|
||||
|
||||
if (!Utils.isABDevice()) {
|
||||
abPerfMode.setVisibility(View.GONE);
|
||||
@@ -471,7 +460,7 @@ public class UpdatesActivity extends UpdatesListActivity {
|
||||
abPerfMode.setChecked(prefs.getBoolean(Constants.PREF_AB_PERF_MODE, false));
|
||||
|
||||
if (getResources().getBoolean(R.bool.config_hideRecoveryUpdate)) {
|
||||
// Hide the update feature if explicitely requested.
|
||||
// Hide the update feature if explicitly requested.
|
||||
// Might be the case of A-only devices using prebuilt vendor images.
|
||||
updateRecovery.setVisibility(View.GONE);
|
||||
} else if (Utils.isRecoveryUpdateExecPresent()) {
|
||||
@@ -505,12 +494,9 @@ public class UpdatesActivity extends UpdatesListActivity {
|
||||
prefs.edit()
|
||||
.putInt(Constants.PREF_AUTO_UPDATES_CHECK_INTERVAL,
|
||||
autoCheckInterval.getSelectedItemPosition())
|
||||
.putBoolean(Constants.PREF_AUTO_DELETE_UPDATES,
|
||||
autoDelete.isChecked())
|
||||
.putBoolean(Constants.PREF_MOBILE_DATA_WARNING,
|
||||
dataWarning.isChecked())
|
||||
.putBoolean(Constants.PREF_AB_PERF_MODE,
|
||||
abPerfMode.isChecked())
|
||||
.putBoolean(Constants.PREF_AUTO_DELETE_UPDATES, autoDelete.isChecked())
|
||||
.putBoolean(Constants.PREF_MOBILE_DATA_WARNING, dataWarning.isChecked())
|
||||
.putBoolean(Constants.PREF_AB_PERF_MODE, abPerfMode.isChecked())
|
||||
.apply();
|
||||
|
||||
if (Utils.isUpdateCheckEnabled(this)) {
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The LineageOS Project
|
||||
* Copyright (C) 2017-2022 The LineageOS Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -84,17 +84,17 @@ public class UpdatesCheckReceiver extends BroadcastReceiver {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponse(int statusCode, String url,
|
||||
DownloadClient.Headers headers) {
|
||||
public void onResponse(DownloadClient.Headers headers) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(File destination) {
|
||||
public void onSuccess() {
|
||||
try {
|
||||
if (json.exists() && Utils.checkForNewUpdates(json, jsonNew)) {
|
||||
showNotification(context);
|
||||
updateRepeatingUpdatesCheck(context);
|
||||
}
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
jsonNew.renameTo(json);
|
||||
long currentMillis = System.currentTimeMillis();
|
||||
preferences.edit()
|
||||
@@ -123,8 +123,8 @@ public class UpdatesCheckReceiver extends BroadcastReceiver {
|
||||
}
|
||||
|
||||
private static void showNotification(Context context) {
|
||||
NotificationManager notificationManager =
|
||||
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
NotificationManager notificationManager = context.getSystemService(
|
||||
NotificationManager.class);
|
||||
NotificationChannel notificationChannel = new NotificationChannel(
|
||||
NEW_UPDATES_NOTIFICATION_CHANNEL,
|
||||
context.getString(R.string.new_updates_channel_title),
|
||||
@@ -159,7 +159,7 @@ public class UpdatesCheckReceiver extends BroadcastReceiver {
|
||||
}
|
||||
|
||||
PendingIntent updateCheckIntent = getRepeatingUpdatesCheckIntent(context);
|
||||
AlarmManager alarmMgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
|
||||
AlarmManager alarmMgr = context.getSystemService(AlarmManager.class);
|
||||
alarmMgr.setRepeating(AlarmManager.RTC, System.currentTimeMillis() +
|
||||
Utils.getUpdateCheckInterval(context), Utils.getUpdateCheckInterval(context),
|
||||
updateCheckIntent);
|
||||
@@ -170,7 +170,7 @@ public class UpdatesCheckReceiver extends BroadcastReceiver {
|
||||
}
|
||||
|
||||
public static void cancelRepeatingUpdatesCheck(Context context) {
|
||||
AlarmManager alarmMgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
|
||||
AlarmManager alarmMgr = context.getSystemService(AlarmManager.class);
|
||||
alarmMgr.cancel(getRepeatingUpdatesCheckIntent(context));
|
||||
}
|
||||
|
||||
@@ -183,7 +183,7 @@ public class UpdatesCheckReceiver extends BroadcastReceiver {
|
||||
public static void scheduleUpdatesCheck(Context context) {
|
||||
long millisToNextCheck = AlarmManager.INTERVAL_HOUR * 2;
|
||||
PendingIntent updateCheckIntent = getUpdatesCheckIntent(context);
|
||||
AlarmManager alarmMgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
|
||||
AlarmManager alarmMgr = context.getSystemService(AlarmManager.class);
|
||||
alarmMgr.set(AlarmManager.ELAPSED_REALTIME,
|
||||
SystemClock.elapsedRealtime() + millisToNextCheck,
|
||||
updateCheckIntent);
|
||||
@@ -193,7 +193,7 @@ public class UpdatesCheckReceiver extends BroadcastReceiver {
|
||||
}
|
||||
|
||||
public static void cancelUpdatesCheck(Context context) {
|
||||
AlarmManager alarmMgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
|
||||
AlarmManager alarmMgr = context.getSystemService(AlarmManager.class);
|
||||
alarmMgr.cancel(getUpdatesCheckIntent(context));
|
||||
Log.d(TAG, "Cancelling pending one-shot check");
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The LineageOS Project
|
||||
* Copyright (C) 2017-2022 The LineageOS Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -75,18 +75,11 @@ public class UpdatesDbHelper extends SQLiteOpenHelper {
|
||||
onUpgrade(db, oldVersion, newVersion);
|
||||
}
|
||||
|
||||
public long addUpdate(Update update) {
|
||||
public void addUpdateWithOnConflict(Update update, int conflictAlgorithm) {
|
||||
SQLiteDatabase db = getWritableDatabase();
|
||||
ContentValues values = new ContentValues();
|
||||
fillContentValues(update, values);
|
||||
return db.insert(UpdateEntry.TABLE_NAME, null, values);
|
||||
}
|
||||
|
||||
public long addUpdateWithOnConflict(Update update, int conflictAlgorithm) {
|
||||
SQLiteDatabase db = getWritableDatabase();
|
||||
ContentValues values = new ContentValues();
|
||||
fillContentValues(update, values);
|
||||
return db.insertWithOnConflict(UpdateEntry.TABLE_NAME, null, values, conflictAlgorithm);
|
||||
db.insertWithOnConflict(UpdateEntry.TABLE_NAME, null, values, conflictAlgorithm);
|
||||
}
|
||||
|
||||
private static void fillContentValues(Update update, ContentValues values) {
|
||||
@@ -99,52 +92,25 @@ public class UpdatesDbHelper extends SQLiteOpenHelper {
|
||||
values.put(UpdateEntry.COLUMN_NAME_SIZE, update.getFileSize());
|
||||
}
|
||||
|
||||
public boolean removeUpdate(String downloadId) {
|
||||
public void removeUpdate(String downloadId) {
|
||||
SQLiteDatabase db = getWritableDatabase();
|
||||
String selection = UpdateEntry.COLUMN_NAME_DOWNLOAD_ID + " = ?";
|
||||
String[] selectionArgs = {downloadId};
|
||||
return db.delete(UpdateEntry.TABLE_NAME, selection, selectionArgs) != 0;
|
||||
db.delete(UpdateEntry.TABLE_NAME, selection, selectionArgs);
|
||||
}
|
||||
|
||||
public boolean removeUpdate(long rowId) {
|
||||
SQLiteDatabase db = getWritableDatabase();
|
||||
String selection = UpdateEntry._ID + " = " + rowId;
|
||||
return db.delete(UpdateEntry.TABLE_NAME, selection, null) != 0;
|
||||
}
|
||||
|
||||
public boolean changeUpdateStatus(Update update) {
|
||||
public void changeUpdateStatus(Update update) {
|
||||
String selection = UpdateEntry.COLUMN_NAME_DOWNLOAD_ID + " = ?";
|
||||
String[] selectionArgs = {update.getDownloadId()};
|
||||
return changeUpdateStatus(selection, selectionArgs, update.getPersistentStatus());
|
||||
changeUpdateStatus(selection, selectionArgs, update.getPersistentStatus());
|
||||
}
|
||||
|
||||
public boolean changeUpdateStatus(long rowId, int status) {
|
||||
String selection = UpdateEntry._ID + " = " + rowId;
|
||||
return changeUpdateStatus(selection, null, status);
|
||||
}
|
||||
|
||||
private boolean changeUpdateStatus(String selection, String[] selectionArgs,
|
||||
private void changeUpdateStatus(String selection, String[] selectionArgs,
|
||||
int status) {
|
||||
SQLiteDatabase db = getWritableDatabase();
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(UpdateEntry.COLUMN_NAME_STATUS, status);
|
||||
return db.update(UpdateEntry.TABLE_NAME, values, selection, selectionArgs) != 0;
|
||||
}
|
||||
|
||||
public Update getUpdate(long rowId) {
|
||||
String selection = UpdateEntry._ID + " = " + rowId;
|
||||
return getUpdate(selection, null);
|
||||
}
|
||||
|
||||
public Update getUpdate(String downloadId) {
|
||||
String selection = UpdateEntry.COLUMN_NAME_DOWNLOAD_ID + " = ?";
|
||||
String[] selectionArgs = {downloadId};
|
||||
return getUpdate(selection, selectionArgs);
|
||||
}
|
||||
|
||||
private Update getUpdate(String selection, String[] selectionArgs) {
|
||||
List<Update> updates = getUpdates(selection, selectionArgs);
|
||||
return updates != null ? updates.get(0) : null;
|
||||
db.update(UpdateEntry.TABLE_NAME, values, selection, selectionArgs);
|
||||
}
|
||||
|
||||
public List<Update> getUpdates() {
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The LineageOS Project
|
||||
* Copyright (C) 2017-2022 The LineageOS Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package org.lineageos.updater;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.SharedPreferences;
|
||||
@@ -39,6 +38,7 @@ import android.widget.ImageButton;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.view.ContextThemeWrapper;
|
||||
import androidx.appcompat.view.menu.MenuBuilder;
|
||||
@@ -77,7 +77,7 @@ public class UpdatesListAdapter extends RecyclerView.Adapter<UpdatesListAdapter.
|
||||
private List<String> mDownloadIds;
|
||||
private String mSelectedDownload;
|
||||
private UpdaterController mUpdaterController;
|
||||
private UpdatesListActivity mActivity;
|
||||
private final UpdatesListActivity mActivity;
|
||||
|
||||
private AlertDialog infoDialog;
|
||||
|
||||
@@ -93,27 +93,27 @@ public class UpdatesListAdapter extends RecyclerView.Adapter<UpdatesListAdapter.
|
||||
}
|
||||
|
||||
public static class ViewHolder extends RecyclerView.ViewHolder {
|
||||
private Button mAction;
|
||||
private ImageButton mMenu;
|
||||
private final Button mAction;
|
||||
private final ImageButton mMenu;
|
||||
|
||||
private TextView mBuildDate;
|
||||
private TextView mBuildVersion;
|
||||
private TextView mBuildSize;
|
||||
private final TextView mBuildDate;
|
||||
private final TextView mBuildVersion;
|
||||
private final TextView mBuildSize;
|
||||
|
||||
private ProgressBar mProgressBar;
|
||||
private TextView mProgressText;
|
||||
private final ProgressBar mProgressBar;
|
||||
private final TextView mProgressText;
|
||||
|
||||
public ViewHolder(final View view) {
|
||||
super(view);
|
||||
mAction = (Button) view.findViewById(R.id.update_action);
|
||||
mMenu = (ImageButton) view.findViewById(R.id.update_menu);
|
||||
mAction = view.findViewById(R.id.update_action);
|
||||
mMenu = view.findViewById(R.id.update_menu);
|
||||
|
||||
mBuildDate = (TextView) view.findViewById(R.id.build_date);
|
||||
mBuildVersion = (TextView) view.findViewById(R.id.build_version);
|
||||
mBuildSize = (TextView) view.findViewById(R.id.build_size);
|
||||
mBuildDate = view.findViewById(R.id.build_date);
|
||||
mBuildVersion = view.findViewById(R.id.build_version);
|
||||
mBuildSize = view.findViewById(R.id.build_size);
|
||||
|
||||
mProgressBar = (ProgressBar) view.findViewById(R.id.progress_bar);
|
||||
mProgressText = (TextView) view.findViewById(R.id.progress_text);
|
||||
mProgressBar = view.findViewById(R.id.progress_bar);
|
||||
mProgressText = view.findViewById(R.id.progress_text);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,6 +125,7 @@ public class UpdatesListAdapter extends RecyclerView.Adapter<UpdatesListAdapter.
|
||||
mAlphaDisabledValue = tv.getFloat();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
|
||||
View view = LayoutInflater.from(viewGroup.getContext())
|
||||
@@ -133,7 +134,7 @@ public class UpdatesListAdapter extends RecyclerView.Adapter<UpdatesListAdapter.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewDetachedFromWindow(ViewHolder holder) {
|
||||
public void onViewDetachedFromWindow(@NonNull ViewHolder holder) {
|
||||
super.onViewDetachedFromWindow(holder);
|
||||
|
||||
if (infoDialog != null) {
|
||||
@@ -191,8 +192,8 @@ public class UpdatesListAdapter extends RecyclerView.Adapter<UpdatesListAdapter.
|
||||
String total = Formatter.formatShortFileSize(mActivity, update.getFileSize());
|
||||
String percentage = NumberFormat.getPercentInstance().format(
|
||||
update.getProgress() / 100.f);
|
||||
viewHolder.mProgressText.setText(mActivity.getString(R.string.list_download_progress_new,
|
||||
downloaded, total, percentage));
|
||||
viewHolder.mProgressText.setText(mActivity.getString(
|
||||
R.string.list_download_progress_new, downloaded, total, percentage));
|
||||
viewHolder.mProgressBar.setIndeterminate(false);
|
||||
viewHolder.mProgressBar.setProgress(update.getProgress());
|
||||
}
|
||||
@@ -229,7 +230,7 @@ public class UpdatesListAdapter extends RecyclerView.Adapter<UpdatesListAdapter.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(final ViewHolder viewHolder, int i) {
|
||||
public void onBindViewHolder(@NonNull final ViewHolder viewHolder, int i) {
|
||||
if (mDownloadIds == null) {
|
||||
viewHolder.mAction.setEnabled(false);
|
||||
return;
|
||||
@@ -311,7 +312,7 @@ public class UpdatesListAdapter extends RecyclerView.Adapter<UpdatesListAdapter.
|
||||
}
|
||||
|
||||
View checkboxView = LayoutInflater.from(mActivity).inflate(R.layout.checkbox_view, null);
|
||||
CheckBox checkbox = (CheckBox) checkboxView.findViewById(R.id.checkbox);
|
||||
CheckBox checkbox = checkboxView.findViewById(R.id.checkbox);
|
||||
checkbox.setText(R.string.checkbox_mobile_data_warning);
|
||||
|
||||
new AlertDialog.Builder(mActivity)
|
||||
@@ -370,7 +371,10 @@ public class UpdatesListAdapter extends RecyclerView.Adapter<UpdatesListAdapter.
|
||||
final boolean canInstall = Utils.canInstall(update);
|
||||
clickListener = enabled ? view -> {
|
||||
if (canInstall) {
|
||||
getInstallDialog(downloadId).show();
|
||||
AlertDialog.Builder installDialog = getInstallDialog(downloadId);
|
||||
if (installDialog != null) {
|
||||
installDialog.show();
|
||||
}
|
||||
} else {
|
||||
mActivity.showSnackbar(R.string.snack_update_not_installable,
|
||||
Snackbar.LENGTH_LONG);
|
||||
@@ -400,8 +404,7 @@ public class UpdatesListAdapter extends RecyclerView.Adapter<UpdatesListAdapter.
|
||||
button.setText(R.string.reboot);
|
||||
button.setEnabled(enabled);
|
||||
clickListener = enabled ? view -> {
|
||||
PowerManager pm =
|
||||
(PowerManager) mActivity.getSystemService(Context.POWER_SERVICE);
|
||||
PowerManager pm = mActivity.getSystemService(PowerManager.class);
|
||||
pm.reboot(null);
|
||||
} : null;
|
||||
}
|
||||
@@ -438,9 +441,7 @@ public class UpdatesListAdapter extends RecyclerView.Adapter<UpdatesListAdapter.
|
||||
|
||||
private View.OnClickListener getClickListener(final UpdateInfo update,
|
||||
final boolean canDelete, View anchor) {
|
||||
return view -> {
|
||||
startActionMode(update, canDelete, anchor);
|
||||
};
|
||||
return view -> startActionMode(update, canDelete, anchor);
|
||||
}
|
||||
|
||||
private AlertDialog.Builder getInstallDialog(final String downloadId) {
|
||||
@@ -509,17 +510,17 @@ public class UpdatesListAdapter extends RecyclerView.Adapter<UpdatesListAdapter.
|
||||
update.getPersistentStatus() == UpdateStatus.Persistent.VERIFIED);
|
||||
|
||||
popupMenu.setOnMenuItemClickListener(item -> {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.menu_delete_action:
|
||||
int itemId = item.getItemId();
|
||||
if (itemId == R.id.menu_delete_action) {
|
||||
getDeleteDialog(update.getDownloadId()).show();
|
||||
return true;
|
||||
case R.id.menu_copy_url:
|
||||
} else if (itemId == R.id.menu_copy_url) {
|
||||
Utils.addToClipboard(mActivity,
|
||||
mActivity.getString(R.string.label_download_url),
|
||||
update.getDownloadUrl(),
|
||||
mActivity.getString(R.string.toast_download_url_copied));
|
||||
return true;
|
||||
case R.id.menu_export_update:
|
||||
} else if (itemId == R.id.menu_export_update) {
|
||||
// TODO: start exporting once the permission has been granted
|
||||
boolean hasPermission = PermissionsUtils.checkAndRequestStoragePermission(
|
||||
mActivity, 0);
|
||||
@@ -561,9 +562,11 @@ public class UpdatesListAdapter extends RecyclerView.Adapter<UpdatesListAdapter.
|
||||
.setPositiveButton(android.R.string.ok, null)
|
||||
.setMessage(message)
|
||||
.show();
|
||||
TextView textView = (TextView) infoDialog.findViewById(android.R.id.message);
|
||||
TextView textView = infoDialog.findViewById(android.R.id.message);
|
||||
if (textView != null) {
|
||||
textView.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isBatteryLevelOk() {
|
||||
Intent intent = mActivity.registerReceiver(null,
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The LineageOS Project
|
||||
* Copyright (C) 2017-2022 The LineageOS Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -52,7 +52,7 @@ class ABUpdateInstaller {
|
||||
private final Context mContext;
|
||||
private String mDownloadId;
|
||||
|
||||
private UpdateEngine mUpdateEngine;
|
||||
private final UpdateEngine mUpdateEngine;
|
||||
private boolean mBound;
|
||||
|
||||
private boolean mFinalizing;
|
||||
@@ -130,11 +130,6 @@ class ABUpdateInstaller {
|
||||
return pref.getString(ABUpdateInstaller.PREF_INSTALLING_SUSPENDED_AB_ID, null) != null;
|
||||
}
|
||||
|
||||
static synchronized boolean isInstallingUpdateSuspended(Context context, String downloadId) {
|
||||
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
return downloadId.equals(pref.getString(ABUpdateInstaller.PREF_INSTALLING_SUSPENDED_AB_ID, null));
|
||||
}
|
||||
|
||||
static synchronized boolean isWaitingForReboot(Context context, String downloadId) {
|
||||
String waitingId = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
.getString(Constants.PREF_NEEDS_REBOOT_ID, null);
|
||||
@@ -155,10 +150,10 @@ class ABUpdateInstaller {
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
public boolean install(String downloadId) {
|
||||
public void install(String downloadId) {
|
||||
if (isInstallingUpdate(mContext)) {
|
||||
Log.e(TAG, "Already installing an update");
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
mDownloadId = downloadId;
|
||||
@@ -169,7 +164,7 @@ class ABUpdateInstaller {
|
||||
mUpdaterController.getActualUpdate(downloadId)
|
||||
.setStatus(UpdateStatus.INSTALLATION_FAILED);
|
||||
mUpdaterController.notifyUpdateChange(downloadId);
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
long offset;
|
||||
@@ -194,7 +189,7 @@ class ABUpdateInstaller {
|
||||
mUpdaterController.getActualUpdate(mDownloadId)
|
||||
.setStatus(UpdateStatus.INSTALLATION_FAILED);
|
||||
mUpdaterController.notifyUpdateChange(mDownloadId);
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mBound) {
|
||||
@@ -204,7 +199,7 @@ class ABUpdateInstaller {
|
||||
mUpdaterController.getActualUpdate(downloadId)
|
||||
.setStatus(UpdateStatus.INSTALLATION_FAILED);
|
||||
mUpdaterController.notifyUpdateChange(downloadId);
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,17 +217,16 @@ class ABUpdateInstaller {
|
||||
.putString(PREF_INSTALLING_AB_ID, mDownloadId)
|
||||
.apply();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean reconnect() {
|
||||
public void reconnect() {
|
||||
if (!isInstallingUpdate(mContext)) {
|
||||
Log.e(TAG, "reconnect: Not installing any update");
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (mBound) {
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
|
||||
mDownloadId = PreferenceManager.getDefaultSharedPreferences(mContext)
|
||||
@@ -242,10 +236,8 @@ class ABUpdateInstaller {
|
||||
mBound = mUpdateEngine.bind(mUpdateEngineCallback);
|
||||
if (!mBound) {
|
||||
Log.e(TAG, "Could not bind");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void installationDone(boolean needsReboot) {
|
||||
@@ -257,15 +249,15 @@ class ABUpdateInstaller {
|
||||
.apply();
|
||||
}
|
||||
|
||||
public boolean cancel() {
|
||||
public void cancel() {
|
||||
if (!isInstallingUpdate(mContext)) {
|
||||
Log.e(TAG, "cancel: Not installing any update");
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mBound) {
|
||||
Log.e(TAG, "Not connected to update engine");
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
mUpdateEngine.cancel();
|
||||
@@ -275,22 +267,21 @@ class ABUpdateInstaller {
|
||||
.setStatus(UpdateStatus.INSTALLATION_CANCELLED);
|
||||
mUpdaterController.notifyUpdateChange(mDownloadId);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setPerformanceMode(boolean enable) {
|
||||
mUpdateEngine.setPerformanceMode(enable);
|
||||
}
|
||||
|
||||
public boolean suspend() {
|
||||
public void suspend() {
|
||||
if (!isInstallingUpdate(mContext)) {
|
||||
Log.e(TAG, "cancel: Not installing any update");
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mBound) {
|
||||
Log.e(TAG, "Not connected to update engine");
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
mUpdateEngine.suspend();
|
||||
@@ -303,18 +294,17 @@ class ABUpdateInstaller {
|
||||
.putString(PREF_INSTALLING_SUSPENDED_AB_ID, mDownloadId)
|
||||
.apply();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean resume() {
|
||||
public void resume() {
|
||||
if (!isInstallingUpdateSuspended(mContext)) {
|
||||
Log.e(TAG, "cancel: No update is suspended");
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mBound) {
|
||||
Log.e(TAG, "Not connected to update engine");
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
mUpdateEngine.resume();
|
||||
@@ -329,6 +319,5 @@ class ABUpdateInstaller {
|
||||
.remove(PREF_INSTALLING_SUSPENDED_AB_ID)
|
||||
.apply();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The LineageOS Project
|
||||
* Copyright (C) 2017-2022 The LineageOS Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -113,7 +113,7 @@ class UpdateInstaller {
|
||||
Runnable copyUpdateRunnable = new Runnable() {
|
||||
private long mLastUpdate = -1;
|
||||
|
||||
FileUtils.ProgressCallBack mProgressCallBack = new FileUtils.ProgressCallBack() {
|
||||
final FileUtils.ProgressCallBack mProgressCallBack = new FileUtils.ProgressCallBack() {
|
||||
@Override
|
||||
public void update(int progress) {
|
||||
long now = SystemClock.elapsedRealtime();
|
||||
@@ -137,12 +137,14 @@ class UpdateInstaller {
|
||||
.setStatus(UpdateStatus.INSTALLATION_CANCELLED);
|
||||
mUpdaterController.getActualUpdate(update.getDownloadId())
|
||||
.setInstallProgress(0);
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
uncryptFile.delete();
|
||||
} else {
|
||||
installPackage(uncryptFile, update.getDownloadId());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Could not copy update", e);
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
uncryptFile.delete();
|
||||
mUpdaterController.getActualUpdate(update.getDownloadId())
|
||||
.setStatus(UpdateStatus.INSTALLATION_FAILED);
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The LineageOS Project
|
||||
* Copyright (C) 2017-2022 The LineageOS Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.lineageos.updater.controller;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
@@ -63,11 +64,7 @@ public class UpdaterController {
|
||||
private final File mDownloadRoot;
|
||||
|
||||
private int mActiveDownloads = 0;
|
||||
private Set<String> mVerifyingUpdates = new HashSet<>();
|
||||
|
||||
public static synchronized UpdaterController getInstance() {
|
||||
return sUpdaterController;
|
||||
}
|
||||
private final Set<String> mVerifyingUpdates = new HashSet<>();
|
||||
|
||||
protected static synchronized UpdaterController getInstance(Context context) {
|
||||
if (sUpdaterController == null) {
|
||||
@@ -80,8 +77,8 @@ public class UpdaterController {
|
||||
mBroadcastManager = LocalBroadcastManager.getInstance(context);
|
||||
mUpdatesDbHelper = new UpdatesDbHelper(context);
|
||||
mDownloadRoot = Utils.getDownloadPath(context);
|
||||
PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
|
||||
mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Updater");
|
||||
PowerManager powerManager = context.getSystemService(PowerManager.class);
|
||||
mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Updater:wakelock");
|
||||
mWakeLock.setReferenceCounted(false);
|
||||
mContext = context.getApplicationContext();
|
||||
|
||||
@@ -92,7 +89,7 @@ public class UpdaterController {
|
||||
}
|
||||
}
|
||||
|
||||
private class DownloadEntry {
|
||||
private static class DownloadEntry {
|
||||
final Update mUpdate;
|
||||
DownloadClient mDownloadClient;
|
||||
private DownloadEntry(Update update) {
|
||||
@@ -100,7 +97,7 @@ public class UpdaterController {
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, DownloadEntry> mDownloads = new HashMap<>();
|
||||
private final Map<String, DownloadEntry> mDownloads = new HashMap<>();
|
||||
|
||||
void notifyUpdateChange(String downloadId) {
|
||||
Intent intent = new Intent();
|
||||
@@ -156,8 +153,12 @@ public class UpdaterController {
|
||||
return new DownloadClient.DownloadCallback() {
|
||||
|
||||
@Override
|
||||
public void onResponse(int statusCode, String url, DownloadClient.Headers headers) {
|
||||
final Update update = mDownloads.get(downloadId).mUpdate;
|
||||
public void onResponse(DownloadClient.Headers headers) {
|
||||
final DownloadEntry entry = mDownloads.get(downloadId);
|
||||
if (entry == null) {
|
||||
return;
|
||||
}
|
||||
final Update update = entry.mUpdate;
|
||||
String contentLength = headers.get("Content-Length");
|
||||
if (contentLength != null) {
|
||||
try {
|
||||
@@ -177,28 +178,34 @@ public class UpdaterController {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(File destination) {
|
||||
public void onSuccess() {
|
||||
Log.d(TAG, "Download complete");
|
||||
Update update = mDownloads.get(downloadId).mUpdate;
|
||||
DownloadEntry entry = mDownloads.get(downloadId);
|
||||
if (entry != null) {
|
||||
Update update = entry.mUpdate;
|
||||
update.setStatus(UpdateStatus.VERIFYING);
|
||||
removeDownloadClient(mDownloads.get(downloadId));
|
||||
removeDownloadClient(entry);
|
||||
verifyUpdateAsync(downloadId);
|
||||
notifyUpdateChange(downloadId);
|
||||
tryReleaseWakelock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(boolean cancelled) {
|
||||
Update update = mDownloads.get(downloadId).mUpdate;
|
||||
if (cancelled) {
|
||||
Log.d(TAG, "Download cancelled");
|
||||
// Already notified
|
||||
} else {
|
||||
DownloadEntry entry = mDownloads.get(downloadId);
|
||||
if (entry != null) {
|
||||
Update update = entry.mUpdate;
|
||||
Log.e(TAG, "Download failed");
|
||||
removeDownloadClient(mDownloads.get(downloadId));
|
||||
removeDownloadClient(entry);
|
||||
update.setStatus(UpdateStatus.PAUSED_ERROR);
|
||||
notifyUpdateChange(downloadId);
|
||||
}
|
||||
}
|
||||
tryReleaseWakelock();
|
||||
}
|
||||
};
|
||||
@@ -210,9 +217,12 @@ public class UpdaterController {
|
||||
private int mProgress = 0;
|
||||
|
||||
@Override
|
||||
public void update(long bytesRead, long contentLength, long speed, long eta,
|
||||
boolean done) {
|
||||
Update update = mDownloads.get(downloadId).mUpdate;
|
||||
public void update(long bytesRead, long contentLength, long speed, long eta) {
|
||||
DownloadEntry entry = mDownloads.get(downloadId);
|
||||
if (entry == null) {
|
||||
return;
|
||||
}
|
||||
Update update = entry.mUpdate;
|
||||
if (contentLength <= 0) {
|
||||
if (update.getFileSize() <= 0) {
|
||||
return;
|
||||
@@ -224,7 +234,7 @@ public class UpdaterController {
|
||||
return;
|
||||
}
|
||||
final long now = SystemClock.elapsedRealtime();
|
||||
int progress = Math.round(bytesRead * 100 / contentLength);
|
||||
int progress = Math.round(bytesRead * 100f / contentLength);
|
||||
if (progress != mProgress || mLastUpdate - now > MAX_REPORT_INTERVAL_MS) {
|
||||
mProgress = progress;
|
||||
mLastUpdate = now;
|
||||
@@ -237,12 +247,16 @@ public class UpdaterController {
|
||||
};
|
||||
}
|
||||
|
||||
@SuppressLint("SetWorldReadable")
|
||||
private void verifyUpdateAsync(final String downloadId) {
|
||||
mVerifyingUpdates.add(downloadId);
|
||||
new Thread(() -> {
|
||||
Update update = mDownloads.get(downloadId).mUpdate;
|
||||
DownloadEntry entry = mDownloads.get(downloadId);
|
||||
if (entry != null) {
|
||||
Update update = entry.mUpdate;
|
||||
File file = update.getFile();
|
||||
if (file.exists() && verifyPackage(file)) {
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
file.setReadable(true, false);
|
||||
update.setPersistentStatus(UpdateStatus.Persistent.VERIFIED);
|
||||
mUpdatesDbHelper.changeUpdateStatus(update);
|
||||
@@ -255,6 +269,7 @@ public class UpdaterController {
|
||||
}
|
||||
mVerifyingUpdates.remove(downloadId);
|
||||
notifyUpdateChange(downloadId);
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
@@ -266,6 +281,7 @@ public class UpdaterController {
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Verification failed", e);
|
||||
if (file.exists()) {
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
file.delete();
|
||||
} else {
|
||||
// The download was probably stopped. Exit silently
|
||||
@@ -285,7 +301,7 @@ public class UpdaterController {
|
||||
} else if (update.getFileSize() > 0) {
|
||||
update.setStatus(UpdateStatus.PAUSED);
|
||||
int progress = Math.round(
|
||||
update.getFile().length() * 100 / update.getFileSize());
|
||||
update.getFile().length() * 100f / update.getFileSize());
|
||||
update.setProgress(progress);
|
||||
}
|
||||
break;
|
||||
@@ -293,15 +309,6 @@ public class UpdaterController {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setUpdatesNotAvailableOnline(List<String> downloadIds) {
|
||||
for (String downloadId : downloadIds) {
|
||||
DownloadEntry update = mDownloads.get(downloadId);
|
||||
if (update != null) {
|
||||
update.mUpdate.setAvailableOnline(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setUpdatesAvailableOnline(List<String> downloadIds, boolean purgeList) {
|
||||
List<String> toRemove = new ArrayList<>();
|
||||
for (DownloadEntry entry : mDownloads.values()) {
|
||||
@@ -327,9 +334,12 @@ public class UpdaterController {
|
||||
Log.d(TAG, "Adding download: " + updateInfo.getDownloadId());
|
||||
if (mDownloads.containsKey(updateInfo.getDownloadId())) {
|
||||
Log.d(TAG, "Download (" + updateInfo.getDownloadId() + ") already added");
|
||||
Update updateAdded = mDownloads.get(updateInfo.getDownloadId()).mUpdate;
|
||||
DownloadEntry entry = mDownloads.get(updateInfo.getDownloadId());
|
||||
if (entry != null) {
|
||||
Update updateAdded = entry.mUpdate;
|
||||
updateAdded.setAvailableOnline(availableOnline && updateAdded.getAvailableOnline());
|
||||
updateAdded.setDownloadUrl(updateInfo.getDownloadUrl());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
Update update = new Update(updateInfo);
|
||||
@@ -344,12 +354,18 @@ public class UpdaterController {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean startDownload(String downloadId) {
|
||||
@SuppressLint("WakelockTimeout")
|
||||
public void startDownload(String downloadId) {
|
||||
Log.d(TAG, "Starting " + downloadId);
|
||||
if (!mDownloads.containsKey(downloadId) || isDownloading(downloadId)) {
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
Update update = mDownloads.get(downloadId).mUpdate;
|
||||
DownloadEntry entry = mDownloads.get(downloadId);
|
||||
if (entry == null) {
|
||||
Log.e(TAG, "Could not get download entry");
|
||||
return;
|
||||
}
|
||||
Update update = entry.mUpdate;
|
||||
File destination = new File(mDownloadRoot, update.getName());
|
||||
if (destination.exists()) {
|
||||
destination = Utils.appendSequentialNumber(destination);
|
||||
@@ -369,28 +385,33 @@ public class UpdaterController {
|
||||
Log.e(TAG, "Could not build download client");
|
||||
update.setStatus(UpdateStatus.PAUSED_ERROR);
|
||||
notifyUpdateChange(downloadId);
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
addDownloadClient(mDownloads.get(downloadId), downloadClient);
|
||||
addDownloadClient(entry, downloadClient);
|
||||
update.setStatus(UpdateStatus.STARTING);
|
||||
notifyUpdateChange(downloadId);
|
||||
downloadClient.start();
|
||||
mWakeLock.acquire();
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean resumeDownload(String downloadId) {
|
||||
@SuppressLint("WakelockTimeout")
|
||||
public void resumeDownload(String downloadId) {
|
||||
Log.d(TAG, "Resuming " + downloadId);
|
||||
if (!mDownloads.containsKey(downloadId) || isDownloading(downloadId)) {
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
Update update = mDownloads.get(downloadId).mUpdate;
|
||||
DownloadEntry entry = mDownloads.get(downloadId);
|
||||
if (entry == null) {
|
||||
Log.e(TAG, "Could not get download entry");
|
||||
return;
|
||||
}
|
||||
Update update = entry.mUpdate;
|
||||
File file = update.getFile();
|
||||
if (file == null || !file.exists()) {
|
||||
Log.e(TAG, "The destination file of " + downloadId + " doesn't exist, can't resume");
|
||||
update.setStatus(UpdateStatus.PAUSED_ERROR);
|
||||
notifyUpdateChange(downloadId);
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
if (file.exists() && update.getFileSize() > 0 && file.length() >= update.getFileSize()) {
|
||||
Log.d(TAG, "File already downloaded, starting verification");
|
||||
@@ -411,31 +432,31 @@ public class UpdaterController {
|
||||
Log.e(TAG, "Could not build download client");
|
||||
update.setStatus(UpdateStatus.PAUSED_ERROR);
|
||||
notifyUpdateChange(downloadId);
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
addDownloadClient(mDownloads.get(downloadId), downloadClient);
|
||||
addDownloadClient(entry, downloadClient);
|
||||
update.setStatus(UpdateStatus.STARTING);
|
||||
notifyUpdateChange(downloadId);
|
||||
downloadClient.resume();
|
||||
mWakeLock.acquire();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean pauseDownload(String downloadId) {
|
||||
public void pauseDownload(String downloadId) {
|
||||
Log.d(TAG, "Pausing " + downloadId);
|
||||
if (!isDownloading(downloadId)) {
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
DownloadEntry entry = mDownloads.get(downloadId);
|
||||
if (entry != null) {
|
||||
entry.mDownloadClient.cancel();
|
||||
removeDownloadClient(entry);
|
||||
entry.mUpdate.setStatus(UpdateStatus.PAUSED);
|
||||
entry.mUpdate.setEta(0);
|
||||
entry.mUpdate.setSpeed(0);
|
||||
notifyUpdateChange(downloadId);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private void deleteUpdateAsync(final Update update) {
|
||||
@@ -448,12 +469,14 @@ public class UpdaterController {
|
||||
}).start();
|
||||
}
|
||||
|
||||
public boolean deleteUpdate(String downloadId) {
|
||||
public void deleteUpdate(String downloadId) {
|
||||
Log.d(TAG, "Cancelling " + downloadId);
|
||||
if (!mDownloads.containsKey(downloadId) || isDownloading(downloadId)) {
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
Update update = mDownloads.get(downloadId).mUpdate;
|
||||
DownloadEntry entry = mDownloads.get(downloadId);
|
||||
if (entry != null) {
|
||||
Update update = entry.mUpdate;
|
||||
update.setStatus(UpdateStatus.DELETED);
|
||||
update.setProgress(0);
|
||||
update.setPersistentStatus(UpdateStatus.Persistent.UNKNOWN);
|
||||
@@ -466,12 +489,7 @@ public class UpdaterController {
|
||||
} else {
|
||||
notifyUpdateChange(downloadId);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public Set<String> getIds() {
|
||||
return mDownloads.keySet();
|
||||
}
|
||||
|
||||
public List<UpdateInfo> getUpdates() {
|
||||
@@ -493,6 +511,7 @@ public class UpdaterController {
|
||||
}
|
||||
|
||||
public boolean isDownloading(String downloadId) {
|
||||
//noinspection ConstantConditions
|
||||
return mDownloads.containsKey(downloadId) &&
|
||||
mDownloads.get(downloadId).mDownloadClient != null;
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The LineageOS Project
|
||||
* Copyright (C) 2017-2022 The LineageOS Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -85,7 +85,7 @@ public class UpdaterService extends Service {
|
||||
|
||||
mUpdaterController = UpdaterController.getInstance(this);
|
||||
|
||||
mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
|
||||
mNotificationManager = getSystemService(NotificationManager.class);
|
||||
NotificationChannel notificationChannel = new NotificationChannel(
|
||||
ONGOING_NOTIFICATION_CHANNEL,
|
||||
getString(R.string.ongoing_channel_title),
|
||||
@@ -123,8 +123,7 @@ public class UpdaterService extends Service {
|
||||
handleInstallProgress(update);
|
||||
} else if (UpdaterController.ACTION_UPDATE_REMOVED.equals(intent.getAction())) {
|
||||
Bundle extras = mNotificationBuilder.getExtras();
|
||||
if (extras != null && downloadId.equals(
|
||||
extras.getString(UpdaterController.EXTRA_DOWNLOAD_ID))) {
|
||||
if (downloadId.equals(extras.getString(UpdaterController.EXTRA_DOWNLOAD_ID))) {
|
||||
mNotificationBuilder.setExtras(null);
|
||||
UpdateInfo update = mUpdaterController.getUpdate(downloadId);
|
||||
if (update.getStatus() != UpdateStatus.INSTALLED) {
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The LineageOS Project
|
||||
* Copyright (C) 2017-2022 The LineageOS Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,27 +17,23 @@ package org.lineageos.updater.download;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public interface DownloadClient {
|
||||
|
||||
interface DownloadCallback {
|
||||
void onResponse(int statusCode, String url, Headers headers);
|
||||
void onResponse(Headers headers);
|
||||
|
||||
void onSuccess(File destination);
|
||||
void onSuccess();
|
||||
|
||||
void onFailure(boolean cancelled);
|
||||
}
|
||||
|
||||
interface ProgressListener {
|
||||
void update(long bytesRead, long contentLength, long speed, long eta, boolean done);
|
||||
void update(long bytesRead, long contentLength, long speed, long eta);
|
||||
}
|
||||
|
||||
interface Headers {
|
||||
String get(String name);
|
||||
|
||||
Map<String, List<String>> getAll();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The LineageOS Project
|
||||
* Copyright (C) 2017-2022 The LineageOS Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -51,10 +51,6 @@ public class HttpURLConnectionClient implements DownloadClient {
|
||||
return mClient.getHeaderField(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, List<String>> getAll() {
|
||||
return mClient.getHeaderFields();
|
||||
}
|
||||
}
|
||||
|
||||
HttpURLConnectionClient(String url, File destination,
|
||||
@@ -179,8 +175,8 @@ public class HttpURLConnectionClient implements DownloadClient {
|
||||
String protocol = mClient.getURL().getProtocol();
|
||||
|
||||
class DuplicateLink {
|
||||
private String mUrl;
|
||||
private int mPriority;
|
||||
private final String mUrl;
|
||||
private final int mPriority;
|
||||
private DuplicateLink(String url, int priority) {
|
||||
mUrl = url;
|
||||
mPriority = priority;
|
||||
@@ -233,9 +229,11 @@ public class HttpURLConnectionClient implements DownloadClient {
|
||||
} catch (IOException e) {
|
||||
if (duplicates != null && !duplicates.isEmpty()) {
|
||||
DuplicateLink link = duplicates.poll();
|
||||
if (link != null) {
|
||||
duplicates.remove(link);
|
||||
newUrl = link.mUrl;
|
||||
Log.e(TAG, "Using duplicate link " + link.mUrl, e);
|
||||
}
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
@@ -255,7 +253,7 @@ public class HttpURLConnectionClient implements DownloadClient {
|
||||
responseCode = mClient.getResponseCode();
|
||||
}
|
||||
|
||||
mCallback.onResponse(responseCode, mClient.getURL().toString(), new Headers());
|
||||
mCallback.onResponse(new Headers());
|
||||
|
||||
if (mResume && isPartialContentCode(responseCode)) {
|
||||
mTotalBytesRead = mDestination.length();
|
||||
@@ -279,12 +277,11 @@ public class HttpURLConnectionClient implements DownloadClient {
|
||||
calculateSpeed();
|
||||
calculateEta();
|
||||
if (mProgressListener != null) {
|
||||
mProgressListener.update(mTotalBytesRead, mTotalBytes, mSpeed, mEta,
|
||||
false);
|
||||
mProgressListener.update(mTotalBytesRead, mTotalBytes, mSpeed, mEta);
|
||||
}
|
||||
}
|
||||
if (mProgressListener != null) {
|
||||
mProgressListener.update(mTotalBytesRead, mTotalBytes, mSpeed, mEta, true);
|
||||
mProgressListener.update(mTotalBytesRead, mTotalBytes, mSpeed, mEta);
|
||||
}
|
||||
|
||||
outputStream.flush();
|
||||
@@ -292,7 +289,7 @@ public class HttpURLConnectionClient implements DownloadClient {
|
||||
if (isInterrupted()) {
|
||||
mCallback.onFailure(true);
|
||||
} else {
|
||||
mCallback.onSuccess(mDestination);
|
||||
mCallback.onSuccess();
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The LineageOS Project
|
||||
* Copyright (C) 2017-2022 The LineageOS Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -34,9 +34,9 @@ public class FileUtils {
|
||||
}
|
||||
|
||||
private static class CallbackByteChannel implements ReadableByteChannel {
|
||||
private ProgressCallBack mCallback;
|
||||
private long mSize;
|
||||
private ReadableByteChannel mReadableByteChannel;
|
||||
private final ProgressCallBack mCallback;
|
||||
private final long mSize;
|
||||
private final ReadableByteChannel mReadableByteChannel;
|
||||
private long mSizeRead;
|
||||
private int mProgress;
|
||||
|
||||
@@ -86,13 +86,10 @@ public class FileUtils {
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Could not copy file", e);
|
||||
if (destFile.exists()) {
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
destFile.delete();
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public static void copyFile(File sourceFile, File destFile) throws IOException {
|
||||
copyFile(sourceFile, destFile, null);
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The LineageOS Project
|
||||
* Copyright (C) 2017-2022 The LineageOS Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -36,13 +36,6 @@ public final class StringGenerator {
|
||||
return f.format(date);
|
||||
}
|
||||
|
||||
public static String getTimeLocalizedUTC(Context context, long unixTimestamp) {
|
||||
DateFormat f = DateFormat.getTimeInstance(DateFormat.SHORT, getCurrentLocale(context));
|
||||
f.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
Date date = new Date(unixTimestamp * 1000);
|
||||
return f.format(date);
|
||||
}
|
||||
|
||||
public static String getDateLocalized(Context context, int dateFormat, long unixTimestamp) {
|
||||
DateFormat f = DateFormat.getDateInstance(dateFormat, getCurrentLocale(context));
|
||||
Date date = new Date(unixTimestamp * 1000);
|
||||
@@ -56,13 +49,6 @@ public final class StringGenerator {
|
||||
return f.format(date);
|
||||
}
|
||||
|
||||
public static String getDateTimeLocalized(Context context, long unixTimestamp) {
|
||||
DateFormat f = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.SHORT,
|
||||
getCurrentLocale(context));
|
||||
Date date = new Date(unixTimestamp * 1000);
|
||||
return f.format(date);
|
||||
}
|
||||
|
||||
public static String bytesToMegabytes(Context context, long bytes) {
|
||||
return String.format(getCurrentLocale(context), "%.0f", bytes / 1024.f / 1024.f);
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2017-2021 The LineageOS Project
|
||||
* Copyright (C) 2017-2022 The LineageOS Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -24,7 +24,6 @@ import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.NetworkInfo;
|
||||
import android.os.Environment;
|
||||
import android.os.SystemProperties;
|
||||
import android.os.storage.StorageManager;
|
||||
import android.preference.PreferenceManager;
|
||||
@@ -122,14 +121,14 @@ public class Utils {
|
||||
throws IOException, JSONException {
|
||||
List<UpdateInfo> updates = new ArrayList<>();
|
||||
|
||||
String json = "";
|
||||
StringBuilder json = new StringBuilder();
|
||||
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
|
||||
for (String line; (line = br.readLine()) != null;) {
|
||||
json += line;
|
||||
json.append(line);
|
||||
}
|
||||
}
|
||||
|
||||
JSONObject obj = new JSONObject(json);
|
||||
JSONObject obj = new JSONObject(json.toString());
|
||||
JSONArray updatesList = obj.getJSONArray("response");
|
||||
for (int i = 0; i < updatesList.length(); i++) {
|
||||
if (updatesList.isNull(i)) {
|
||||
@@ -186,15 +185,13 @@ public class Utils {
|
||||
}
|
||||
|
||||
public static boolean isNetworkAvailable(Context context) {
|
||||
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(
|
||||
Context.CONNECTIVITY_SERVICE);
|
||||
ConnectivityManager cm = context.getSystemService(ConnectivityManager.class);
|
||||
NetworkInfo info = cm.getActiveNetworkInfo();
|
||||
return !(info == null || !info.isConnected() || !info.isAvailable());
|
||||
}
|
||||
|
||||
public static boolean isOnWifiOrEthernet(Context context) {
|
||||
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(
|
||||
Context.CONNECTIVITY_SERVICE);
|
||||
ConnectivityManager cm = context.getSystemService(ConnectivityManager.class);
|
||||
NetworkInfo info = cm.getActiveNetworkInfo();
|
||||
return (info != null && (info.getType() == ConnectivityManager.TYPE_ETHERNET
|
||||
|| info.getType() == ConnectivityManager.TYPE_WIFI));
|
||||
@@ -206,8 +203,6 @@ public class Utils {
|
||||
* @param oldJson old update list
|
||||
* @param newJson new update list
|
||||
* @return true if newJson has at least a compatible update not available in oldJson
|
||||
* @throws IOException
|
||||
* @throws JSONException
|
||||
*/
|
||||
public static boolean checkForNewUpdates(File oldJson, File newJson)
|
||||
throws IOException, JSONException {
|
||||
@@ -264,6 +259,7 @@ public class Utils {
|
||||
return;
|
||||
}
|
||||
for (File file : uncryptFiles) {
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
@@ -273,7 +269,6 @@ public class Utils {
|
||||
* the user can't access and that might have stale files. This can happen if
|
||||
* the data of the application are wiped.
|
||||
*
|
||||
* @param context
|
||||
*/
|
||||
public static void cleanupDownloadsDir(Context context) {
|
||||
File downloadPath = getDownloadPath(context);
|
||||
@@ -290,6 +285,7 @@ public class Utils {
|
||||
lastUpdatePath != null) {
|
||||
File lastUpdate = new File(lastUpdatePath);
|
||||
if (lastUpdate.exists()) {
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
lastUpdate.delete();
|
||||
// Remove the pref not to delete the file if re-downloaded
|
||||
preferences.edit().remove(Constants.PREF_INSTALL_PACKAGE_PATH).apply();
|
||||
@@ -319,6 +315,7 @@ public class Utils {
|
||||
for (File file : files) {
|
||||
if (!knownPaths.contains(file.getAbsolutePath())) {
|
||||
Log.d(TAG, "Deleting " + file.getAbsolutePath());
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
@@ -367,7 +364,8 @@ public class Utils {
|
||||
return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN);
|
||||
}
|
||||
|
||||
public static void addToClipboard(Context context, String label, String text, String toastMessage) {
|
||||
public static void addToClipboard(Context context, String label, String text,
|
||||
String toastMessage) {
|
||||
ClipboardManager clipboard = (ClipboardManager) context.getSystemService(
|
||||
Context.CLIPBOARD_SERVICE);
|
||||
ClipData clip = ClipData.newPlainText(label, text);
|
||||
|
@@ -32,10 +32,6 @@ public class Update extends UpdateBase implements UpdateInfo {
|
||||
public Update() {
|
||||
}
|
||||
|
||||
public Update(UpdateBaseInfo update) {
|
||||
super(update);
|
||||
}
|
||||
|
||||
public Update(UpdateInfo update) {
|
||||
super(update);
|
||||
mStatus = update.getStatus();
|
||||
|
@@ -19,7 +19,6 @@ public enum UpdateStatus {
|
||||
UNKNOWN,
|
||||
STARTING,
|
||||
DOWNLOADING,
|
||||
DOWNLOADED,
|
||||
PAUSED,
|
||||
PAUSED_ERROR,
|
||||
DELETED,
|
||||
|
@@ -4,6 +4,7 @@ import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
@@ -21,8 +22,9 @@ public final class FlingBehavior extends AppBarLayout.Behavior {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onNestedFling(CoordinatorLayout coordinatorLayout, AppBarLayout child,
|
||||
View target, float velocityX, float velocityY, boolean consumed) {
|
||||
public boolean onNestedFling(@NonNull CoordinatorLayout coordinatorLayout,
|
||||
@NonNull AppBarLayout child, @NonNull View target,
|
||||
float velocityX, float velocityY, boolean consumed) {
|
||||
if (velocityY > 0 && !isPositive || velocityY < 0 && isPositive) {
|
||||
velocityY = velocityY * -1;
|
||||
}
|
||||
@@ -37,9 +39,10 @@ public final class FlingBehavior extends AppBarLayout.Behavior {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child,
|
||||
View target, int dx, int dy, int[] consumed) {
|
||||
super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed);
|
||||
public void onNestedPreScroll(@NonNull CoordinatorLayout coordinatorLayout,
|
||||
@NonNull AppBarLayout child, @NonNull View target,
|
||||
int dx, int dy, @NonNull int[] consumed, int type) {
|
||||
super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type);
|
||||
isPositive = dy > 0;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user