diff --git a/app/build.gradle b/app/build.gradle index 42e3e8050..e32763ef6 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -112,7 +112,6 @@ dependencies { implementation libs.androidx.preference implementation libs.androidx.localbroadcastmanager implementation libs.androidx.legacy.support.v4 - implementation libs.androidx.work.runtime // Google implementation libs.google.material diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 4903fd7ed..05c043dd8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -69,11 +69,6 @@ android:exported="false" android:parentActivityName=".activity.MainActivity" android:theme="@style/Theme.MaterialComponents.Light.DarkActionBar.App.NoActionBar" /> - - * This method is called when the task is completed. - */ - protected void removeProgressFragment(@IdRes int id) { - Fragment fragment = getSupportFragmentManager().findFragmentById(id); - if (fragment != null && fragment.isAdded()) { - getSupportFragmentManager().beginTransaction().remove(fragment).commit(); - } - findViewById(id).setVisibility(View.GONE); - } } diff --git a/app/src/main/java/org/openobservatory/ooniprobe/activity/MainActivity.java b/app/src/main/java/org/openobservatory/ooniprobe/activity/MainActivity.java index e656e059b..2d418afe5 100644 --- a/app/src/main/java/org/openobservatory/ooniprobe/activity/MainActivity.java +++ b/app/src/main/java/org/openobservatory/ooniprobe/activity/MainActivity.java @@ -1,7 +1,6 @@ package org.openobservatory.ooniprobe.activity; import static org.openobservatory.ooniprobe.common.service.RunTestService.CHANNEL_ID; -import static org.openobservatory.ooniprobe.common.worker.UpdateDescriptorsWorkerKt.PROGRESS; import android.Manifest; import android.content.Context; @@ -13,51 +12,34 @@ import android.os.Bundle; import android.os.PowerManager; import android.provider.Settings; -import android.view.View; import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.contract.ActivityResultContracts; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatDelegate; import androidx.core.content.ContextCompat; -import androidx.work.Constraints; -import androidx.work.ExistingPeriodicWorkPolicy; -import androidx.work.ExistingWorkPolicy; -import androidx.work.NetworkType; -import androidx.work.OneTimeWorkRequest; -import androidx.work.PeriodicWorkRequest; -import androidx.work.WorkInfo; -import androidx.work.WorkManager; import com.google.android.material.snackbar.Snackbar; import org.openobservatory.ooniprobe.R; -import org.openobservatory.ooniprobe.activity.reviewdescriptorupdates.ReviewDescriptorUpdatesActivity; import org.openobservatory.ooniprobe.common.Application; import org.openobservatory.ooniprobe.common.NotificationUtility; import org.openobservatory.ooniprobe.common.PreferenceManager; -import org.openobservatory.ooniprobe.common.TestDescriptorManager; import org.openobservatory.ooniprobe.common.ThirdPartyServices; import org.openobservatory.ooniprobe.common.service.ServiceUtil; -import org.openobservatory.ooniprobe.common.worker.AutoUpdateDescriptorsWorker; -import org.openobservatory.ooniprobe.common.worker.ManualUpdateDescriptorsWorker; import org.openobservatory.ooniprobe.databinding.ActivityMainBinding; import org.openobservatory.ooniprobe.domain.UpdatesNotificationManager; import org.openobservatory.ooniprobe.fragment.DashboardFragment; import org.openobservatory.ooniprobe.fragment.PreferenceGlobalFragment; import org.openobservatory.ooniprobe.fragment.ResultListFragment; -import org.openobservatory.ooniprobe.fragment.dynamicprogressbar.OONIRunDynamicProgressBar; -import org.openobservatory.ooniprobe.fragment.dynamicprogressbar.OnActionListener; -import org.openobservatory.ooniprobe.fragment.dynamicprogressbar.ProgressType; import java.io.Serializable; -import java.util.concurrent.TimeUnit; import javax.inject.Inject; import localhost.toolkit.app.fragment.ConfirmDialogFragment; -public class MainActivity extends ReviewUpdatesAbstractActivity implements ConfirmDialogFragment.OnConfirmedListener { +public class MainActivity extends AbstractActivity implements ConfirmDialogFragment.OnConfirmedListener { private static final String RES_ITEM = "resItem"; private static final String RES_SNACKBAR_MESSAGE = "resSnackbarMessage"; public static final String NOTIFICATION_DIALOG = "notification"; @@ -72,9 +54,6 @@ public class MainActivity extends ReviewUpdatesAbstractActivity implements Confi @Inject PreferenceManager preferenceManager; - @Inject - TestDescriptorManager descriptorManager; - private ActivityResultLauncher requestPermissionLauncher; public static Intent newIntent(Context context, int resItem) { @@ -158,115 +137,6 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { } } requestNotificationPermission(); - scheduleWorkers(); - onNewIntent(getIntent()); - } - - private void scheduleWorkers() { - WorkManager.getInstance(this) - .enqueueUniquePeriodicWork( - AutoUpdateDescriptorsWorker.UPDATED_DESCRIPTORS_WORK_NAME, - ExistingPeriodicWorkPolicy.KEEP, - new PeriodicWorkRequest.Builder(AutoUpdateDescriptorsWorker.class, 24, TimeUnit.HOURS) - .setConstraints( - new Constraints.Builder() - .setRequiredNetworkType(NetworkType.CONNECTED) - .build() - ).build() - ); - // TODO(aanorbel): add rules before checking updates - fetchManualUpdate(); - registerReviewLauncher(binding.bottomNavigation, () -> null); - } - - public void fetchManualUpdate() { - OneTimeWorkRequest manualWorkRequest = new OneTimeWorkRequest.Builder(ManualUpdateDescriptorsWorker.class) - .setConstraints( - new Constraints.Builder() - .setRequiredNetworkType(NetworkType.CONNECTED) - .build() - ).build(); - - WorkManager.getInstance(this) - .beginUniqueWork( - ManualUpdateDescriptorsWorker.UPDATED_DESCRIPTORS_WORK_NAME, - ExistingWorkPolicy.REPLACE, - manualWorkRequest - ).enqueue(); - - WorkManager.getInstance(this) - .getWorkInfoByIdLiveData(manualWorkRequest.getId()) - .observe(this, this::onManualUpdatesFetchComplete); - } - - - /** - * Listens to updates from the {@link ManualUpdateDescriptorsWorker}. - *

- * This method is called after the {@link ManualUpdateDescriptorsWorker} is enqueued. - * The {@link ManualUpdateDescriptorsWorker} task is to fetch updates for the descriptors. - *

- * If the task is successful, the {@link WorkInfo} object will contain the updated descriptors. - * Otherwise, the {@link WorkInfo} object will be null. - * - * @param workInfo The {@link WorkInfo} of the task. - */ - private void onManualUpdatesFetchComplete(WorkInfo workInfo) { - if (workInfo != null) { - if (workInfo.getProgress().getInt(PROGRESS,-1) >= 0) { - binding.reviewUpdateNotificationFragment.setVisibility(View.VISIBLE); - } - switch (workInfo.getState()) { - case SUCCEEDED -> { - String descriptor = workInfo.getOutputData().getString(ManualUpdateDescriptorsWorker.KEY_UPDATED_DESCRIPTORS); - if (descriptor == null) { - removeProgressFragment(R.id.review_update_notification_fragment); - return; - } - getSupportFragmentManager() - .beginTransaction() - .add( - R.id.review_update_notification_fragment, - OONIRunDynamicProgressBar.newInstance(ProgressType.REVIEW_LINK, new OnActionListener() { - @Override - public void onActionButtonCLicked() { - - getReviewUpdatesLauncher().launch( - ReviewDescriptorUpdatesActivity.newIntent( - MainActivity.this, - descriptor - ) - ); - removeProgressFragment(R.id.review_update_notification_fragment); - } - - @Override - public void onCloseButtonClicked() { - removeProgressFragment(R.id.review_update_notification_fragment); - } - }), - OONIRunDynamicProgressBar.getTAG() + "_review_update_success_notification" - ).commit(); - } - - case ENQUEUED -> getSupportFragmentManager() - .beginTransaction() - .add( - R.id.review_update_notification_fragment, - OONIRunDynamicProgressBar.newInstance(ProgressType.UPDATE_LINK, null), - OONIRunDynamicProgressBar.getTAG() + "_review_update_enqueued_notification" - ).commit(); - - case FAILED -> Snackbar.make( - binding.getRoot(), - R.string.Modal_Error, - Snackbar.LENGTH_LONG - ).setAnchorView(binding.bottomNavigation).show(); - - default -> { - } - } - } } private void requestNotificationPermission() { @@ -321,11 +191,11 @@ protected void onNewIntent(Intent intent) { binding.bottomNavigation.setSelectedItemId(intent.getIntExtra(RES_ITEM, R.id.dashboard)); } else if (intent.getExtras().containsKey(NOTIFICATION_DIALOG)) { new ConfirmDialogFragment.Builder() - .withTitle(intent.getExtras().getString("title")) - .withMessage(intent.getExtras().getString("message")) - .withNegativeButton("") - .withPositiveButton(getString(R.string.Modal_OK)) - .build().show(getSupportFragmentManager(), null); + .withTitle(intent.getExtras().getString("title")) + .withMessage(intent.getExtras().getString("message")) + .withNegativeButton("") + .withPositiveButton(getString(R.string.Modal_OK)) + .build().show(getSupportFragmentManager(), null); } } } diff --git a/app/src/main/java/org/openobservatory/ooniprobe/activity/OverviewActivity.java b/app/src/main/java/org/openobservatory/ooniprobe/activity/OverviewActivity.java index f318f64d1..344045758 100644 --- a/app/src/main/java/org/openobservatory/ooniprobe/activity/OverviewActivity.java +++ b/app/src/main/java/org/openobservatory/ooniprobe/activity/OverviewActivity.java @@ -16,28 +16,18 @@ import androidx.annotation.Nullable; import androidx.core.text.TextUtilsCompat; import androidx.core.view.ViewCompat; -import androidx.work.Constraints; -import androidx.work.Data; -import androidx.work.ExistingWorkPolicy; -import androidx.work.NetworkType; -import androidx.work.OneTimeWorkRequest; -import androidx.work.WorkInfo; -import androidx.work.WorkManager; import com.google.android.material.checkbox.MaterialCheckBox; -import com.google.android.material.snackbar.Snackbar; import org.openobservatory.engine.BaseNettest; import org.openobservatory.ooniprobe.R; import org.openobservatory.ooniprobe.activity.customwebsites.CustomWebsiteActivity; import org.openobservatory.ooniprobe.activity.overview.OverviewTestsExpandableListViewAdapter; import org.openobservatory.ooniprobe.activity.overview.OverviewViewModel; -import org.openobservatory.ooniprobe.activity.reviewdescriptorupdates.ReviewDescriptorUpdatesActivity; import org.openobservatory.ooniprobe.common.AbstractDescriptor; import org.openobservatory.ooniprobe.common.OONITests; import org.openobservatory.ooniprobe.common.PreferenceManager; import org.openobservatory.ooniprobe.common.ReadMorePlugin; -import org.openobservatory.ooniprobe.common.worker.ManualUpdateDescriptorsWorker; import org.openobservatory.ooniprobe.databinding.ActivityOverviewBinding; import org.openobservatory.ooniprobe.model.database.InstalledDescriptor; import org.openobservatory.ooniprobe.model.database.Result; @@ -51,7 +41,7 @@ import io.noties.markwon.Markwon; -public class OverviewActivity extends ReviewUpdatesAbstractActivity { +public class OverviewActivity extends AbstractActivity { private static final String TEST = "test"; ActivityOverviewBinding binding; @@ -165,10 +155,6 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { } setUpOnCLickListeners(); - registerReviewLauncher(binding.getRoot(), () -> { - binding.reviewUpdates.setVisibility(View.GONE); - return null; - }); } private void selectAllBtnStatusObserver(String selectAllBtnStatus) { @@ -200,74 +186,6 @@ private void setUpOnCLickListeners() { binding.customUrl.setOnClickListener(view -> customUrlClick()); binding.uninstallLink.setOnClickListener(view -> viewModel.uninstallLinkClicked(this, (InstalledDescriptor) descriptor)); binding.automaticUpdatesSwitch.setOnCheckedChangeListener((compoundButton, isChecked) -> viewModel.automaticUpdatesSwitchClicked(isChecked)); - if (descriptor instanceof InstalledDescriptor) { - binding.swipeRefresh.setOnRefreshListener(() -> { - Data.Builder data = new Data.Builder(); - data.putLongArray(ManualUpdateDescriptorsWorker.KEY_DESCRIPTOR_IDS, new long[]{Objects.requireNonNull(descriptor.getDescriptor()).getRunId()}); - OneTimeWorkRequest manualWorkRequest = new OneTimeWorkRequest.Builder(ManualUpdateDescriptorsWorker.class) - .setConstraints( - new Constraints.Builder() - .setRequiredNetworkType(NetworkType.CONNECTED) - .build() - ).setInputData(data.build()) - .build(); - - WorkManager.getInstance(this) - .beginUniqueWork( - ManualUpdateDescriptorsWorker.UPDATED_DESCRIPTORS_WORK_NAME, - ExistingWorkPolicy.REPLACE, - manualWorkRequest - ).enqueue(); - - WorkManager.getInstance(this) - .getWorkInfoByIdLiveData(manualWorkRequest.getId()) - .observe(this, this::onManualUpdatesFetchComplete); - - }); - } else { - binding.swipeRefresh.setEnabled(false); - } - } - - - /** - * Listens to updates from the {@link ManualUpdateDescriptorsWorker}. - *

- * This method is called after the {@link ManualUpdateDescriptorsWorker} is enqueued. - * The {@link ManualUpdateDescriptorsWorker} task is to fetch updates for the descriptors. - *

- * If the task is successful, the {@link WorkInfo} object will contain the updated descriptors. - * Otherwise, the {@link WorkInfo} object will be null. - * - * @param workInfo The {@link WorkInfo} of the task. - */ - private void onManualUpdatesFetchComplete(WorkInfo workInfo) { - if (workInfo != null) { - switch (workInfo.getState()) { - case SUCCEEDED -> { - binding.reviewUpdates.setVisibility(View.VISIBLE); - binding.reviewUpdates.setOnClickListener(view -> getReviewUpdatesLauncher().launch( - ReviewDescriptorUpdatesActivity.newIntent( - OverviewActivity.this, - workInfo.getOutputData().getString(ManualUpdateDescriptorsWorker.KEY_UPDATED_DESCRIPTORS) - ) - )); - binding.swipeRefresh.setRefreshing(false); - } - - case FAILED -> { - binding.swipeRefresh.setRefreshing(false); - Snackbar.make( - binding.getRoot(), - R.string.Modal_Error, - Snackbar.LENGTH_LONG - ).show(); - } - - default -> { - } - } - } } @Override diff --git a/app/src/main/java/org/openobservatory/ooniprobe/activity/ReviewUpdatesAbstractActivity.kt b/app/src/main/java/org/openobservatory/ooniprobe/activity/ReviewUpdatesAbstractActivity.kt deleted file mode 100644 index 5adff209b..000000000 --- a/app/src/main/java/org/openobservatory/ooniprobe/activity/ReviewUpdatesAbstractActivity.kt +++ /dev/null @@ -1,31 +0,0 @@ -package org.openobservatory.ooniprobe.activity - -import android.content.Intent -import android.util.Log -import android.view.View -import androidx.activity.result.ActivityResult -import androidx.activity.result.ActivityResultLauncher -import androidx.activity.result.contract.ActivityResultContracts -import com.google.android.material.snackbar.Snackbar -import org.openobservatory.ooniprobe.activity.reviewdescriptorupdates.ReviewDescriptorUpdatesActivity - -open class ReviewUpdatesAbstractActivity : AbstractActivity() { - var reviewUpdatesLauncher: ActivityResultLauncher? = null - - fun registerReviewLauncher(view: View, reviewCompletedListener: () -> Unit?) { - reviewUpdatesLauncher = - registerForActivityResult(ActivityResultContracts.StartActivityForResult()) - { result: ActivityResult -> - if (result.resultCode == RESULT_OK) { - reviewCompletedListener() - result.data?.let { intent: Intent -> - intent.getStringExtra(ReviewDescriptorUpdatesActivity.RESULT_MESSAGE) - ?.let { message: String -> - Snackbar.make(view, message, Snackbar.LENGTH_LONG) - .setAnchorView(view).show() - } - } - } - } - } -} \ No newline at end of file diff --git a/app/src/main/java/org/openobservatory/ooniprobe/activity/adddescriptor/AddDescriptorActivity.kt b/app/src/main/java/org/openobservatory/ooniprobe/activity/adddescriptor/AddDescriptorActivity.kt index 6fedc19fd..5b2a0a8d8 100644 --- a/app/src/main/java/org/openobservatory/ooniprobe/activity/adddescriptor/AddDescriptorActivity.kt +++ b/app/src/main/java/org/openobservatory/ooniprobe/activity/adddescriptor/AddDescriptorActivity.kt @@ -16,6 +16,9 @@ import androidx.databinding.BindingAdapter import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider import io.noties.markwon.Markwon +import org.openobservatory.engine.BaseNettest +import org.openobservatory.engine.OONIRunDescriptor +import org.openobservatory.engine.OONIRunNettest import org.openobservatory.ooniprobe.R import org.openobservatory.ooniprobe.activity.AbstractActivity import org.openobservatory.ooniprobe.activity.MainActivity @@ -82,19 +85,17 @@ class AddDescriptorActivity : AbstractActivity() { * @param iconName is the name of the drawable resource */ @JvmStatic - @BindingAdapter(value = ["resource","color"]) - fun setImageViewResource(imageView: ImageView, iconName: String?, color: Int?) { + @BindingAdapter(value = ["resource"]) + fun setImageViewResource(imageView: ImageView, iconName: String?) { + /* TODO(aanorbel): Update to parse the icon name and set the correct icon. + * Remember to ignore icons generated when generated doing this.*/ imageView.setImageResource( imageView.context.resources.getIdentifier( StringUtils.camelToSnake( iconName ), "drawable", imageView.context.packageName ) - ).apply { - color?.let { - imageView.setColorFilter(it) - } - } + ) } } diff --git a/app/src/main/java/org/openobservatory/ooniprobe/activity/adddescriptor/AddDescriptorViewModel.kt b/app/src/main/java/org/openobservatory/ooniprobe/activity/adddescriptor/AddDescriptorViewModel.kt index e0362696c..90d25ec08 100644 --- a/app/src/main/java/org/openobservatory/ooniprobe/activity/adddescriptor/AddDescriptorViewModel.kt +++ b/app/src/main/java/org/openobservatory/ooniprobe/activity/adddescriptor/AddDescriptorViewModel.kt @@ -1,11 +1,11 @@ package org.openobservatory.ooniprobe.activity.adddescriptor -import android.graphics.Color -import androidx.annotation.ColorInt import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import com.google.android.material.checkbox.MaterialCheckBox import com.google.android.material.checkbox.MaterialCheckBox.CheckedState +import org.openobservatory.engine.OONIRunDescriptor +import org.openobservatory.engine.OONIRunNettest import org.openobservatory.ooniprobe.activity.adddescriptor.adapter.GroupedItem import org.openobservatory.ooniprobe.common.LocaleUtils import org.openobservatory.ooniprobe.common.TestDescriptorManager @@ -38,10 +38,6 @@ class AddDescriptorViewModel constructor( this.descriptor.value = descriptor } - @ColorInt - fun getColor(): Int { - return Color.parseColor( descriptor.value?.color ?: "#495057") - } /** * This method is used to get the name of the descriptor. * Used by the UI during data binding. diff --git a/app/src/main/java/org/openobservatory/ooniprobe/activity/oonirun/OoniRunV2Activity.kt b/app/src/main/java/org/openobservatory/ooniprobe/activity/oonirun/OoniRunV2Activity.kt index b5a092621..5b4dc61bc 100644 --- a/app/src/main/java/org/openobservatory/ooniprobe/activity/oonirun/OoniRunV2Activity.kt +++ b/app/src/main/java/org/openobservatory/ooniprobe/activity/oonirun/OoniRunV2Activity.kt @@ -134,7 +134,7 @@ class OoniRunV2Activity : AbstractActivity() { descriptorResponse?.let { startActivity(AddDescriptorActivity.newIntent(this, descriptorResponse)) } ?: run { - finishWithError() + Toast.makeText(this, getString(R.string.Modal_Error), Toast.LENGTH_LONG).show() } } diff --git a/app/src/main/java/org/openobservatory/ooniprobe/activity/reviewdescriptorupdates/ReviewDescriptorUpdatesActivity.kt b/app/src/main/java/org/openobservatory/ooniprobe/activity/reviewdescriptorupdates/ReviewDescriptorUpdatesActivity.kt deleted file mode 100644 index ebe32bd45..000000000 --- a/app/src/main/java/org/openobservatory/ooniprobe/activity/reviewdescriptorupdates/ReviewDescriptorUpdatesActivity.kt +++ /dev/null @@ -1,364 +0,0 @@ -package org.openobservatory.ooniprobe.activity.reviewdescriptorupdates - -import android.content.Context -import android.content.Intent -import android.os.Build -import android.os.Bundle -import android.view.LayoutInflater -import android.view.Menu -import android.view.MenuInflater -import android.view.MenuItem -import android.view.View -import android.view.ViewGroup -import android.widget.BaseExpandableListAdapter -import android.widget.ImageView -import android.widget.TextView -import androidx.appcompat.widget.Toolbar -import androidx.fragment.app.Fragment -import androidx.fragment.app.FragmentActivity -import androidx.viewpager2.adapter.FragmentStateAdapter -import androidx.viewpager2.widget.ViewPager2.OnPageChangeCallback -import com.google.android.material.checkbox.MaterialCheckBox -import com.google.android.material.snackbar.Snackbar -import com.google.gson.Gson -import com.google.gson.internal.LinkedTreeMap -import org.openobservatory.engine.BaseNettest -import org.openobservatory.ooniprobe.R -import org.openobservatory.ooniprobe.activity.AbstractActivity -import org.openobservatory.ooniprobe.common.TestDescriptorManager -import org.openobservatory.ooniprobe.databinding.ActivityReviewDescriptorUpdatesBinding -import org.openobservatory.ooniprobe.databinding.FragmentDescriptorUpdateBinding -import org.openobservatory.ooniprobe.model.database.ITestDescriptor -import org.openobservatory.ooniprobe.model.database.InstalledDescriptor -import org.openobservatory.ooniprobe.model.database.TestDescriptor -import org.openobservatory.ooniprobe.test.test.AbstractTest -import java.text.SimpleDateFormat -import java.util.Locale -import javax.inject.Inject - -/** - * This activity is used to review the updates of the descriptors. - * When a new update is available, the user is prompted to review the changes. - * This activity is started by the [org.openobservatory.ooniprobe.activity.MainActivity] activity. - */ -class ReviewDescriptorUpdatesActivity : AbstractActivity() { - - companion object { - private const val DESCRIPTORS = "descriptors" - - @JvmField - var RESULT_MESSAGE = "result" - - /** - * This method is used to create an intent to start this activity. - * @param context is the context of the activity that calls this method - * @param descriptors is the descriptors to review - * @return an intent to start this activity - */ - @JvmStatic - fun newIntent(context: Context, descriptors: String?): Intent { - return Intent(context, ReviewDescriptorUpdatesActivity::class.java).putExtra( - DESCRIPTORS, - descriptors - ) - } - } - - @Inject - lateinit var descriptorManager: TestDescriptorManager - - @Inject - lateinit var gson: Gson - - private lateinit var reviewUpdatesPagingAdapter: ReviewUpdatesPagingAdapter - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - activityComponent.inject(this) - val binding = ActivityReviewDescriptorUpdatesBinding.inflate(layoutInflater) - setContentView(binding.root) - setSupportActionBar(binding.toolbar) - supportActionBar?.setDisplayHomeAsUpEnabled(false) - supportActionBar?.setDisplayShowHomeEnabled(false) - supportActionBar?.title = "Link Update" - val descriptorJson = intent.getStringExtra(DESCRIPTORS) - try { - /** - * **[descriptorJson]** is the json string of the intent. - * **[descriptors]** is the list of [TestDescriptor] objects obtained from **[descriptorJson]**. - * Because [TestDescriptor.nettests] is of type [Any], the gson library converts it to a [LinkedTreeMap]. - */ - val descriptors: List = - gson.fromJson(descriptorJson, Array::class.java) - .map { it.toTestDescriptor() } - - // Disable swipe behavior of viewpager - binding.viewpager.isUserInputEnabled = false - - reviewUpdatesPagingAdapter = ReviewUpdatesPagingAdapter(this, descriptors) - binding.viewpager.adapter = reviewUpdatesPagingAdapter - - /** - * The bottom bar menu item click listener. - * When the user clicks on the update button, the viewpager is swiped to the next page. - * When the user clicks on the last update, the activity is finished. - */ - val bottomBarOnMenuItemClickListener: Toolbar.OnMenuItemClickListener = - Toolbar.OnMenuItemClickListener { item -> - when (item.itemId) { - R.id.update_descriptor -> { - descriptorManager.updateFromNetwork(descriptors[binding.viewpager.currentItem]) - /** - * **[currPos]** is the current position of the viewpager. - * If the current position is not the last position, the viewpager is swiped to the next page. - * If the current position is the last position, the last update is saved in the shared preferences and the activity is finished. - */ - val currPos: Int = binding.viewpager.currentItem - if ((currPos + 1) != binding.viewpager.adapter?.itemCount) { - binding.viewpager.currentItem = currPos + 1 - } else { - setResult(RESULT_OK, Intent().putExtra(RESULT_MESSAGE, "Link(s) updated")) - finish() - } - true - } - - else -> false - } - } - binding.bottomBar.setOnMenuItemClickListener(bottomBarOnMenuItemClickListener) - - /** - * The viewpager page change callback. - * When the user swipes to the next page, the bottom bar menu item title is updated. - */ - binding.viewpager.registerOnPageChangeCallback(object : OnPageChangeCallback() { - override fun onPageSelected(position: Int) { - binding.bottomBar.menu.findItem(R.id.update_descriptor) - ?.let { - val countString = - "(${position + 1} of ${binding.viewpager.adapter?.itemCount})" - supportActionBar?.title = "Link Update $countString" - it.title = if ((position + 1) != binding.viewpager.adapter?.itemCount) { - "UPDATE $countString" - } else { - "UPDATE AND FINISH $countString" - } - } - - } - }) - - } catch (e: Exception) { - finish() - } - } - - override fun onCreateOptionsMenu(menu: Menu): Boolean { - val inflater: MenuInflater = menuInflater - inflater.inflate(R.menu.close, menu) - return true - } - - override fun onOptionsItemSelected(item: MenuItem): Boolean { - return when (item.itemId) { - R.id.close_button -> { - finish() - true - } - - else -> super.onOptionsItemSelected(item) - } - } -} - -/** - * This adapter is used to display the list of descriptors in the viewpager. - * @param fragmentActivity is the activity that contains the viewpager. - * @param descriptors is the list of descriptors to display. - */ -class ReviewUpdatesPagingAdapter( - fragmentActivity: FragmentActivity, - private val descriptors: List -) : FragmentStateAdapter(fragmentActivity) { - override fun getItemCount(): Int = descriptors.size - - override fun createFragment(position: Int): Fragment { - val fragment = DescriptorUpdateFragment() - fragment.arguments = Bundle().apply { - putSerializable(DESCRIPTOR, descriptors[position]) - } - return fragment - } -} - -private const val DESCRIPTOR = "descriptor" - -/** - * This fragment is used to display the details of a descriptor. - * It is used by [ReviewUpdatesPagingAdapter]. - * @param descriptor is the descriptor to display. - */ -class DescriptorUpdateFragment : Fragment() { - - private lateinit var binding: FragmentDescriptorUpdateBinding - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - binding = FragmentDescriptorUpdateBinding.inflate(inflater, container, false) - return binding.root - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - arguments?.takeIf { it.containsKey(DESCRIPTOR) }?.apply { - val descriptor: TestDescriptor = - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - getSerializable(DESCRIPTOR, TestDescriptor::class.java)!! - } else { - getSerializable(DESCRIPTOR) as TestDescriptor - } - val absDescriptor = InstalledDescriptor(descriptor) - binding.apply { - title.text = absDescriptor.title - author.text = "Created by ${descriptor.author} on ${ - SimpleDateFormat( - "MMM dd, yyyy", - Locale.getDefault() - ).format(descriptor.descriptorCreationTime) - }" - description.text = absDescriptor.description // Use markdown - icon.setImageResource(absDescriptor.getDisplayIcon(requireContext())) - val adapter = - ReviewDescriptorExpandableListAdapter(nettests = absDescriptor.nettests) - expandableListView.setAdapter(adapter) - // Expand all groups - for (i in 0 until adapter.groupCount) { - expandableListView.expandGroup(i) - } - } - } - } -} - -/** - * This adapter is used to display the list of nettests in the expandable list view. - * It is used by [DescriptorUpdateFragment] to display the list of nettests. - * @param nettests is the list of nettests to display. - */ -class ReviewDescriptorExpandableListAdapter( - val nettests: List, -) : BaseExpandableListAdapter() { - - /** - * @return Number of groups in the list. - */ - override fun getGroupCount(): Int = nettests.size - - /** - * @param groupPosition Position of the group in the list. - * @return Number of children in the group. - */ - override fun getChildrenCount(groupPosition: Int): Int = - nettests[groupPosition].inputs?.size ?: 0 - - /** - * @param groupPosition Position of the group in the list. - * @return [BaseNettest] object. - */ - override fun getGroup(groupPosition: Int): BaseNettest = nettests[groupPosition] - - /** - * @param groupPosition Position of the group in the list. - * @param childPosition Position of the child in the group. - * @return string item at position. - */ - override fun getChild(groupPosition: Int, childPosition: Int): String? = - nettests[groupPosition].inputs?.get(childPosition) - - /** - * @param groupPosition Position of the group in the list. - * @return Group position. - */ - override fun getGroupId(groupPosition: Int): Long = groupPosition.toLong() - - /** - * @param groupPosition Position of the group in the list. - * @param childPosition Position of the child in the group. - * @return Child position. - */ - override fun getChildId(groupPosition: Int, childPosition: Int): Long = childPosition.toLong() - - /** - * @return true if the same ID always refers to the same object. - */ - override fun hasStableIds(): Boolean = false - - /** - * @param groupPosition Position of the group in the list. - * @param isExpanded true if the group is expanded. - * @param convertView View of the group. - * @param parent Parent view. - * @return View of the group. - */ - override fun getGroupView( - groupPosition: Int, - isExpanded: Boolean, - convertView: View?, - parent: ViewGroup, - ): View { - val view = convertView ?: LayoutInflater.from(parent.context) - .inflate(R.layout.nettest_group_list_item, parent, false) - val groupItem = getGroup(groupPosition) - val groupIndicator = view.findViewById(R.id.group_indicator) - - val abstractNettest = AbstractTest.getTestByName(groupItem.name) - view.findViewById(R.id.group_name).text = - when (abstractNettest.labelResId == R.string.Test_Experimental_Fullname) { - true -> groupItem.name - false -> parent.context.resources.getText(abstractNettest.labelResId) - } - - val groupCheckBox = view.findViewById(R.id.groupCheckBox) - groupCheckBox.visibility = View.GONE - if (groupItem.inputs?.isNotEmpty() == true) { - if (isExpanded) { - groupIndicator.setImageResource(R.drawable.expand_less) - } else { - groupIndicator.setImageResource(R.drawable.expand_more) - } - } else { - groupIndicator.visibility = View.INVISIBLE - } - - return view - } - - /** - * @param groupPosition Position of the group in the list. - * @param childPosition Position of the child in the group. - * @param isLastChild True if the child is the last child in the group. - * @param convertView View object. - * @param parent ViewGroup object. - * @return View object. - */ - override fun getChildView( - groupPosition: Int, - childPosition: Int, - isLastChild: Boolean, - convertView: View?, - parent: ViewGroup - ): View { - val view = convertView ?: LayoutInflater.from(parent.context) - .inflate(R.layout.nettest_child_list_item, parent, false) - - view.findViewById(R.id.text).apply { - text = getChild(groupPosition, childPosition) - } - return view - } - - override fun isChildSelectable(groupPosition: Int, childPosition: Int): Boolean = false - -} \ No newline at end of file diff --git a/app/src/main/java/org/openobservatory/ooniprobe/activity/runtests/adapter/RunTestsExpandableListViewAdapter.kt b/app/src/main/java/org/openobservatory/ooniprobe/activity/runtests/adapter/RunTestsExpandableListViewAdapter.kt index 5c94b71c3..59fe79b54 100644 --- a/app/src/main/java/org/openobservatory/ooniprobe/activity/runtests/adapter/RunTestsExpandableListViewAdapter.kt +++ b/app/src/main/java/org/openobservatory/ooniprobe/activity/runtests/adapter/RunTestsExpandableListViewAdapter.kt @@ -8,11 +8,12 @@ import android.widget.ImageView import android.widget.TextView import org.openobservatory.ooniprobe.R import org.openobservatory.ooniprobe.activity.runtests.RunTestsViewModel -import org.openobservatory.ooniprobe.activity.runtests.RunTestsViewModel.Companion.SELECT_ALL import org.openobservatory.ooniprobe.activity.runtests.RunTestsViewModel.Companion.SELECT_NONE +import org.openobservatory.ooniprobe.activity.runtests.RunTestsViewModel.Companion.SELECT_ALL import org.openobservatory.ooniprobe.activity.runtests.RunTestsViewModel.Companion.SELECT_SOME import org.openobservatory.ooniprobe.activity.runtests.models.ChildItem import org.openobservatory.ooniprobe.activity.runtests.models.GroupItem +import org.openobservatory.ooniprobe.common.OONITests import org.openobservatory.ooniprobe.test.test.AbstractTest @@ -82,9 +83,7 @@ class RunTestsExpandableListViewAdapter( convertView ?: LayoutInflater.from(parent.context).inflate(R.layout.run_tests_group_list_item, parent, false) val groupItem = getGroup(groupPosition) convertView.findViewById(R.id.group_name).text = groupItem.title - val icon = convertView.findViewById(R.id.group_icon) - icon.setImageResource(groupItem.getDisplayIcon(parent.context)) - icon.setColorFilter(groupItem.color) + convertView.findViewById(R.id.group_icon).setImageResource(groupItem.getDisplayIcon(parent.context)) val groupIndicator = convertView.findViewById(R.id.group_indicator) val groupSelectionIndicator = convertView.findViewById(R.id.group_select_indicator) val selectedAllBtnStatus = viewModel.selectedAllBtnStatus.getValue() diff --git a/app/src/main/java/org/openobservatory/ooniprobe/adapters/DashboardAdapter.kt b/app/src/main/java/org/openobservatory/ooniprobe/adapters/DashboardAdapter.kt index de625836c..a731b0cff 100644 --- a/app/src/main/java/org/openobservatory/ooniprobe/adapters/DashboardAdapter.kt +++ b/app/src/main/java/org/openobservatory/ooniprobe/adapters/DashboardAdapter.kt @@ -62,10 +62,8 @@ class DashboardAdapter( icon.setImageResource(item.getDisplayIcon(holder.itemView.context)).also { if (item is InstalledDescriptor){ icon.setColorFilter(item.color) - holder.setIsRecyclable(false) } - } - } + } } holder.itemView.tag = item if (!item.isEnabled(preferenceManager)) { holder.setIsRecyclable(false) diff --git a/app/src/main/java/org/openobservatory/ooniprobe/common/OONIDescriptor.kt b/app/src/main/java/org/openobservatory/ooniprobe/common/OONIDescriptor.kt index e67604108..7d446fdb9 100644 --- a/app/src/main/java/org/openobservatory/ooniprobe/common/OONIDescriptor.kt +++ b/app/src/main/java/org/openobservatory/ooniprobe/common/OONIDescriptor.kt @@ -42,7 +42,7 @@ abstract class AbstractDescriptor( * @param preferenceManager The [PreferenceManager] instance used to resolve the status of each nettest. * @return Boolean Returns true if at least one nettest is enabled, false otherwise. */ - open fun isEnabled(preferenceManager: PreferenceManager): Boolean { + open fun isEnabled(preferenceManager: PreferenceManager): Boolean { return when (name) { OONITests.EXPERIMENTAL.label -> preferenceManager.isExperimentalOn OONITests.WEBSITES.label -> preferenceManager.countEnabledCategory() > 0 @@ -136,7 +136,7 @@ abstract class AbstractDescriptor( ) } ?: listOf()) }, - descriptor = this.descriptor + descriptor = descriptor ) } @@ -171,8 +171,8 @@ abstract class AbstractDescriptor( * @return String representing the preference prefix. */ fun preferencePrefix(): String { - return when (this.descriptor?.runId != null) { - true -> this.descriptor?.preferencePrefix() ?: "" + return when (descriptor?.runId != null) { + true -> descriptor?.preferencePrefix() ?: "" else -> "" } } diff --git a/app/src/main/java/org/openobservatory/ooniprobe/common/TestDescriptorManager.kt b/app/src/main/java/org/openobservatory/ooniprobe/common/TestDescriptorManager.kt index 338ec6249..d0e301ec8 100644 --- a/app/src/main/java/org/openobservatory/ooniprobe/common/TestDescriptorManager.kt +++ b/app/src/main/java/org/openobservatory/ooniprobe/common/TestDescriptorManager.kt @@ -100,11 +100,6 @@ class TestDescriptorManager @Inject constructor( return descriptor.save() } - fun getById(runId: Long): TestDescriptor? { - return SQLite.select().from(TestDescriptor::class.java) - .where(TestDescriptor_Table.runId.eq(runId)).querySingle() - } - fun getRunV2Descriptors(): List { return SQLite.select().from(TestDescriptor::class.java) .where(TestDescriptor_Table.isArchived.eq(false)).queryList() @@ -122,29 +117,4 @@ class TestDescriptorManager @Inject constructor( descriptor.testDescriptor.delete() } } - - fun getDescriptorWithAutoUpdateEnabled(): List { - return SQLite.select().from(TestDescriptor::class.java) - .where(TestDescriptor_Table.auto_update.eq(true)).queryList() - } - - fun getDescriptorWithAutoUpdateDisabled(): List { - return SQLite.select().from(TestDescriptor::class.java) - .where(TestDescriptor_Table.auto_update.eq(false)).queryList() - } - - fun updateFromNetwork(testDescriptor: TestDescriptor): Boolean { - getById(testDescriptor.runId)?.let { descriptor -> - testDescriptor.isAutoUpdate = descriptor.isAutoUpdate - return testDescriptor.save() - } ?: run { - return false - } - } - - fun getDescriptorsFromIds(ids: Array): List { - return SQLite.select().from(TestDescriptor::class.java) - .where(TestDescriptor_Table.runId.`in`(ids.toList())) - .queryList() - } } diff --git a/app/src/main/java/org/openobservatory/ooniprobe/common/worker/UpdateDescriptorsWorker.kt b/app/src/main/java/org/openobservatory/ooniprobe/common/worker/UpdateDescriptorsWorker.kt deleted file mode 100644 index ae9d7135b..000000000 --- a/app/src/main/java/org/openobservatory/ooniprobe/common/worker/UpdateDescriptorsWorker.kt +++ /dev/null @@ -1,173 +0,0 @@ -package org.openobservatory.ooniprobe.common.worker - -import android.content.Context -import android.util.Log -import androidx.work.Data -import androidx.work.Worker -import androidx.work.WorkerParameters -import org.openobservatory.ooniprobe.common.Application -import org.openobservatory.ooniprobe.common.PreferenceManager -import org.openobservatory.ooniprobe.common.TestDescriptorManager -import org.openobservatory.ooniprobe.common.ThirdPartyServices -import org.openobservatory.ooniprobe.model.database.TestDescriptor -import org.openobservatory.ooniprobe.model.database.shouldUpdate -import javax.inject.Inject - -var d: UpdateDescriptorsWorkerDependencies = UpdateDescriptorsWorkerDependencies() -const val PROGRESS = "PROGRESS" - -class AutoUpdateDescriptorsWorker( - context: Context, - workerParams: WorkerParameters -) : Worker(context, workerParams) { - - override fun doWork(): Result { - val app = applicationContext.applicationContext as Application - app.serviceComponent.inject(d) - return try { - Log.d(TAG, "Fetching descriptors from input") - - val updatedDescriptors: ArrayList = ArrayList() - - for (descriptor in d.testDescriptorManager.getDescriptorWithAutoUpdateEnabled()) { - Log.d(TAG, "Fetching updates for ${descriptor.runId}") - - val updatedDescriptor: TestDescriptor = - d.testDescriptorManager.fetchDescriptorFromRunId( - descriptor.runId, - applicationContext - ) - - if (descriptor.shouldUpdate(updatedDescriptor)) { - updatedDescriptor.isAutoUpdate = descriptor.isAutoUpdate - updatedDescriptor.isAutoRun = descriptor.isAutoRun - - Log.d(TAG, "Saving updates for ${descriptor.runId}") - - updatedDescriptor.save() - updatedDescriptors.add(updatedDescriptor) - } - } - - val outputData = Data.Builder() - .putString( - KEY_UPDATED_DESCRIPTORS, - (applicationContext as Application).gson.toJson(updatedDescriptors) - ).build() - - Log.e(TAG, "Descriptor updates complete") - - Result.success(outputData) - - } catch (exception: Exception) { - Log.e(TAG, "Error Updating") - exception.printStackTrace() - ThirdPartyServices.logException(exception) - Result.failure() - } - } - - companion object { - @JvmField - var UPDATED_DESCRIPTORS_WORK_NAME = - "${AutoUpdateDescriptorsWorker::class.java.name}.UPDATED_DESCRIPTORS_WORK_NAME" - - private val TAG = AutoUpdateDescriptorsWorker::class.java.simpleName - - private val UPDATE_DESCRIPTOR_CHANNEL: String = - AutoUpdateDescriptorsWorker::class.java.simpleName - - private val KEY_UPDATED_DESCRIPTORS = - "${AutoUpdateDescriptorsWorker::class.java.name}.KEY_UPDATED_DESCRIPTORS" - } -} - -class ManualUpdateDescriptorsWorker( - context: Context, - workerParams: WorkerParameters -) : Worker(context, workerParams) { - - override fun doWork(): Result { - - setProgressAsync(Data.Builder().putInt(PROGRESS, 0).build()) - - val app = applicationContext.applicationContext as Application - app.serviceComponent.inject(d) - - return try { - Log.d(TAG, "Fetching descriptors from input") - - val updatedDescriptors: ArrayList = ArrayList() - - val descriptors = inputData.getLongArray(KEY_DESCRIPTOR_IDS)?.let { - d.testDescriptorManager.getDescriptorsFromIds(it.toTypedArray()) - }.run { - d.testDescriptorManager.getDescriptorWithAutoUpdateDisabled() - } - - if(descriptors.isEmpty()) { - Log.e(TAG, "No descriptors to update") - return Result.success() - } - - for (descriptor in descriptors) { - Log.d(TAG, "Fetching updates for ${descriptor.runId}") - - val updatedDescriptor: TestDescriptor = - d.testDescriptorManager.fetchDescriptorFromRunId( - descriptor.runId, - applicationContext - ) - /** - * NOTE(aanorbel): Refine this logic to only update if the descriptor has changed. - * Consider explicit version compare. - */ - if (descriptor.shouldUpdate(updatedDescriptor)) { - updatedDescriptors.add(updatedDescriptor) - } - } - val outputData = Data.Builder() - .putString( - KEY_UPDATED_DESCRIPTORS, - (applicationContext as Application).gson.toJson(updatedDescriptors) - ).build() - - Log.e(TAG, "fetching updates complete") - - setProgressAsync(Data.Builder().putInt(PROGRESS, 100).build()) - Result.success(outputData) - - } catch (exception: Exception) { - Log.e(TAG, "Error Updating") - exception.printStackTrace() - ThirdPartyServices.logException(exception) - Result.failure() - } - } - - companion object { - @JvmField - var UPDATED_DESCRIPTORS_WORK_NAME = - "${AutoUpdateDescriptorsWorker::class.java.name}.UPDATED_DESCRIPTORS_WORK_NAME" - - private val TAG = AutoUpdateDescriptorsWorker::class.java.simpleName - - private val UPDATE_DESCRIPTOR_CHANNEL: String = - AutoUpdateDescriptorsWorker::class.java.simpleName - - @JvmField - var KEY_UPDATED_DESCRIPTORS = - "${AutoUpdateDescriptorsWorker::class.java.name}.KEY_UPDATED_DESCRIPTORS" - @JvmField - var KEY_DESCRIPTOR_IDS = - "${AutoUpdateDescriptorsWorker::class.java.name}.KEY_DESCRIPTOR_IDS" - } -} - -class UpdateDescriptorsWorkerDependencies { - @Inject - lateinit var testDescriptorManager: TestDescriptorManager - - @Inject - lateinit var preferenceManager: PreferenceManager -} diff --git a/app/src/main/java/org/openobservatory/ooniprobe/di/ActivityComponent.java b/app/src/main/java/org/openobservatory/ooniprobe/di/ActivityComponent.java index 3377b50d7..4ed40d976 100644 --- a/app/src/main/java/org/openobservatory/ooniprobe/di/ActivityComponent.java +++ b/app/src/main/java/org/openobservatory/ooniprobe/di/ActivityComponent.java @@ -1,6 +1,8 @@ package org.openobservatory.ooniprobe.di; +import org.openobservatory.ooniprobe.activity.adddescriptor.AddDescriptorActivity; +import org.openobservatory.ooniprobe.activity.customwebsites.CustomWebsiteActivity; import org.openobservatory.ooniprobe.activity.LogActivity; import org.openobservatory.ooniprobe.activity.MainActivity; import org.openobservatory.ooniprobe.activity.MeasurementDetailActivity; @@ -8,13 +10,10 @@ import org.openobservatory.ooniprobe.activity.OverviewActivity; import org.openobservatory.ooniprobe.activity.ProxyActivity; import org.openobservatory.ooniprobe.activity.ResultDetailActivity; -import org.openobservatory.ooniprobe.activity.RunningActivity; -import org.openobservatory.ooniprobe.activity.TextActivity; -import org.openobservatory.ooniprobe.activity.adddescriptor.AddDescriptorActivity; -import org.openobservatory.ooniprobe.activity.customwebsites.CustomWebsiteActivity; import org.openobservatory.ooniprobe.activity.oonirun.OoniRunV2Activity; -import org.openobservatory.ooniprobe.activity.reviewdescriptorupdates.ReviewDescriptorUpdatesActivity; import org.openobservatory.ooniprobe.activity.runtests.RunTestsActivity; +import org.openobservatory.ooniprobe.activity.RunningActivity; +import org.openobservatory.ooniprobe.activity.TextActivity; import org.openobservatory.ooniprobe.di.annotations.PerActivity; import dagger.Subcomponent; @@ -24,7 +23,6 @@ public interface ActivityComponent { void inject(OoniRunV2Activity activity); void inject(AddDescriptorActivity activity); - void inject(ReviewDescriptorUpdatesActivity activity); void inject(CustomWebsiteActivity activity); void inject(MainActivity activity); void inject(ProxyActivity activity); diff --git a/app/src/main/java/org/openobservatory/ooniprobe/di/ServiceComponent.java b/app/src/main/java/org/openobservatory/ooniprobe/di/ServiceComponent.java index ab6e4c85c..8ebf524ef 100644 --- a/app/src/main/java/org/openobservatory/ooniprobe/di/ServiceComponent.java +++ b/app/src/main/java/org/openobservatory/ooniprobe/di/ServiceComponent.java @@ -3,7 +3,6 @@ import org.openobservatory.ooniprobe.common.ResubmitTask; import org.openobservatory.ooniprobe.common.service.RunTestJobService; import org.openobservatory.ooniprobe.common.service.ServiceUtil; -import org.openobservatory.ooniprobe.common.worker.UpdateDescriptorsWorkerDependencies; import org.openobservatory.ooniprobe.di.annotations.PerService; import dagger.Subcomponent; @@ -14,5 +13,4 @@ public interface ServiceComponent { void inject(ResubmitTask.Dependencies dependencies); void inject(RunTestJobService service); void inject(ServiceUtil.Dependencies dependencies); - void inject(UpdateDescriptorsWorkerDependencies dependencies); } \ No newline at end of file diff --git a/app/src/main/java/org/openobservatory/ooniprobe/fragment/DashboardFragment.kt b/app/src/main/java/org/openobservatory/ooniprobe/fragment/DashboardFragment.kt index 426600f89..0e6ca912b 100644 --- a/app/src/main/java/org/openobservatory/ooniprobe/fragment/DashboardFragment.kt +++ b/app/src/main/java/org/openobservatory/ooniprobe/fragment/DashboardFragment.kt @@ -12,7 +12,6 @@ import androidx.recyclerview.widget.LinearLayoutManager import org.openobservatory.engine.BaseNettest import org.openobservatory.ooniprobe.R import org.openobservatory.ooniprobe.activity.AbstractActivity -import org.openobservatory.ooniprobe.activity.MainActivity import org.openobservatory.ooniprobe.activity.OverviewActivity import org.openobservatory.ooniprobe.activity.runtests.RunTestsActivity import org.openobservatory.ooniprobe.adapters.DashboardAdapter @@ -86,11 +85,6 @@ class DashboardFragment : Fragment(), View.OnClickListener { binding.lastTested.visibility = View.VISIBLE } } - - binding.swipeRefresh.setOnRefreshListener { - (requireActivity() as MainActivity).fetchManualUpdate() - binding.swipeRefresh.isRefreshing = false - } } override fun onResume() { diff --git a/app/src/main/java/org/openobservatory/ooniprobe/fragment/dynamicprogressbar/OONIRunDynamicProgressBar.kt b/app/src/main/java/org/openobservatory/ooniprobe/fragment/dynamicprogressbar/OONIRunDynamicProgressBar.kt index d8b5ef61e..91f9adaec 100644 --- a/app/src/main/java/org/openobservatory/ooniprobe/fragment/dynamicprogressbar/OONIRunDynamicProgressBar.kt +++ b/app/src/main/java/org/openobservatory/ooniprobe/fragment/dynamicprogressbar/OONIRunDynamicProgressBar.kt @@ -54,7 +54,6 @@ class OONIRunDynamicProgressBar : Fragment() { ProgressType.REVIEW_LINK -> { binding.progressBar.visibility = View.GONE binding.iconButton.visibility = View.VISIBLE - binding.actionButton.text = "Review" binding.progressText.text = "Link updates ready" } diff --git a/app/src/main/java/org/openobservatory/ooniprobe/model/database/TestDescriptor.kt b/app/src/main/java/org/openobservatory/ooniprobe/model/database/TestDescriptor.kt index daef1ca8e..8e66dbefa 100644 --- a/app/src/main/java/org/openobservatory/ooniprobe/model/database/TestDescriptor.kt +++ b/app/src/main/java/org/openobservatory/ooniprobe/model/database/TestDescriptor.kt @@ -17,8 +17,8 @@ import org.openobservatory.ooniprobe.activity.runtests.models.ChildItem import org.openobservatory.ooniprobe.activity.runtests.models.GroupItem import org.openobservatory.ooniprobe.common.AbstractDescriptor import org.openobservatory.ooniprobe.common.AppDatabase +import org.openobservatory.ooniprobe.common.OONITests import org.openobservatory.ooniprobe.common.PreferenceManager -import org.openobservatory.ooniprobe.common.resolveStatus import java.io.Serializable import java.util.Date import com.raizlabs.android.dbflow.annotation.TypeConverter as TypeConverterAnnotation @@ -65,19 +65,7 @@ class TestDescriptor( } } -/** - * Check if the descriptor should be updated based on the creation time of the descriptor and the creation time of the translations. - * - * @param updatedDescriptor The updated descriptor - * @return True if the descriptor should be updated based on the creation time of the descriptor and the creation time of the translations. - */ -fun TestDescriptor.shouldUpdate(updatedDescriptor: TestDescriptor): Boolean { - return (updatedDescriptor.descriptorCreationTime?.after(descriptorCreationTime) ?: true - || updatedDescriptor.translationCreationTime?.after(translationCreationTime) ?: true) -} - private const val DESCRIPTOR_TEST_NAME = "ooni_run" - class InstalledDescriptor( var testDescriptor: TestDescriptor ) : AbstractDescriptor( @@ -101,7 +89,7 @@ class InstalledDescriptor( false -> emptyList() }, - descriptor = testDescriptor) { + descriptor = testDescriptor ) { override fun isEnabled(preferenceManager: PreferenceManager): Boolean { return !testDescriptor.isArchived @@ -124,13 +112,13 @@ class InstalledDescriptor( dataUsage = this.dataUsage, nettests = this.nettests.map { nettest -> ChildItem( - selected = preferenceManager.resolveStatus( - name = nettest.name, - prefix = preferencePrefix(), - ), name = nettest.name, inputs = nettest.inputs + selected = when (this.name == OONITests.EXPERIMENTAL.label) { + true -> preferenceManager.isExperimentalOn + false -> preferenceManager.resolveStatus(nettest.name) + }, name = nettest.name, inputs = nettest.inputs ) }, - descriptor = this.testDescriptor + descriptor = testDescriptor ) } @@ -184,61 +172,3 @@ class NettestConverter : TypeConverter() { ).toList() } -class ITestDescriptor( - - var runId: Long = 0, - - var name: String = "", - - var nameIntl: HashMap? = null, - - var author: String = "", - - var shortDescription: String = "", - - var shortDescriptionIntl: HashMap? = null, - - var description: String = "", - - var descriptionIntl: HashMap? = null, - - var icon: String? = null, - - var color: String? = null, - - var animation: String? = null, - - var isArchived: Boolean = false, - - var isAutoRun: Boolean = true, - - var isAutoUpdate: Boolean = false, - - var descriptorCreationTime: Date? = null, - - var translationCreationTime: Date? = null, - - var nettests: List? = emptyList() -) : Serializable { - fun toTestDescriptor(): TestDescriptor { - return TestDescriptor( - runId = runId, - name = name, - nameIntl = nameIntl, - author = author, - shortDescription = shortDescription, - shortDescriptionIntl = shortDescriptionIntl, - description = description, - descriptionIntl = descriptionIntl, - icon = icon, - color = color, - animation = animation, - isArchived = isArchived, - isAutoRun = isAutoRun, - isAutoUpdate = isAutoUpdate, - descriptorCreationTime = descriptorCreationTime, - translationCreationTime = translationCreationTime, - nettests = nettests ?: emptyList() - ) - } -} diff --git a/app/src/main/res/layout/activity_add_descriptor.xml b/app/src/main/res/layout/activity_add_descriptor.xml index 36fbf7298..73cd5198e 100644 --- a/app/src/main/res/layout/activity_add_descriptor.xml +++ b/app/src/main/res/layout/activity_add_descriptor.xml @@ -51,8 +51,7 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:resource="@{viewmodel.descriptor.icon}" - tools:src="@drawable/settings_icon" - app:color="@{viewmodel.color}" /> + tools:src="@drawable/settings_icon" /> diff --git a/app/src/main/res/layout/activity_overview.xml b/app/src/main/res/layout/activity_overview.xml index fd0140a75..cb192a83f 100644 --- a/app/src/main/res/layout/activity_overview.xml +++ b/app/src/main/res/layout/activity_overview.xml @@ -1,242 +1,219 @@ - - - - - - + + + + + android:layout_marginTop="?attr/actionBarSize" + android:gravity="center_horizontal" + android:orientation="vertical" + android:paddingBottom="16dp" + app:layout_collapseMode="parallax"> + + - - + android:layout_margin="8dp" + android:orientation="horizontal" + android:transitionName="@string/transitionNameRuntime"> + android:orientation="vertical"> - - - - - - - - + + - - - - - + android:text="@string/Dashboard_Overview_LatestTest" + android:textColor="@android:color/white" /> -