/* Copyright (C) 2023-2024 Andreas Shimokawa, José Rebelo This file is part of Gadgetbridge. Gadgetbridge is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Gadgetbridge is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.activities.loyaltycards; import static nodomain.freeyourgadget.gadgetbridge.activities.loyaltycards.LoyaltyCardsSettingsConst.LOYALTY_CARDS_CATIMA_NOT_COMPATIBLE; import static nodomain.freeyourgadget.gadgetbridge.activities.loyaltycards.LoyaltyCardsSettingsConst.LOYALTY_CARDS_CATIMA_NOT_INSTALLED; import static nodomain.freeyourgadget.gadgetbridge.activities.loyaltycards.LoyaltyCardsSettingsConst.LOYALTY_CARDS_CATIMA_PACKAGE; import static nodomain.freeyourgadget.gadgetbridge.activities.loyaltycards.LoyaltyCardsSettingsConst.LOYALTY_CARDS_CATIMA_PERMISSIONS; import static nodomain.freeyourgadget.gadgetbridge.activities.loyaltycards.LoyaltyCardsSettingsConst.LOYALTY_CARDS_INSTALL_CATIMA; import static nodomain.freeyourgadget.gadgetbridge.activities.loyaltycards.LoyaltyCardsSettingsConst.LOYALTY_CARDS_OPEN_CATIMA; import static nodomain.freeyourgadget.gadgetbridge.activities.loyaltycards.LoyaltyCardsSettingsConst.LOYALTY_CARDS_SYNC; import static nodomain.freeyourgadget.gadgetbridge.activities.loyaltycards.LoyaltyCardsSettingsConst.LOYALTY_CARDS_SYNC_GROUPS; import static nodomain.freeyourgadget.gadgetbridge.activities.loyaltycards.LoyaltyCardsSettingsConst.PREF_KEY_HEADER_LOYALTY_CARDS_CATIMA; import static nodomain.freeyourgadget.gadgetbridge.activities.loyaltycards.LoyaltyCardsSettingsConst.PREF_KEY_HEADER_LOYALTY_CARDS_SYNC; import static nodomain.freeyourgadget.gadgetbridge.activities.loyaltycards.LoyaltyCardsSettingsConst.PREF_KEY_HEADER_LOYALTY_CARDS_SYNC_OPTIONS; import android.content.ActivityNotFoundException; import android.content.Intent; import android.content.pm.PackageManager; import android.net.Uri; import android.os.Bundle; import android.text.TextUtils; import android.widget.Toast; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import androidx.preference.ListPreference; import androidx.preference.MultiSelectListPreference; import androidx.preference.Preference; import androidx.preference.PreferenceCategory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.HashSet; import java.util.List; import java.util.Set; import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.activities.AbstractPreferenceFragment; import nodomain.freeyourgadget.gadgetbridge.capabilities.loyaltycards.CatimaContentProvider; import nodomain.freeyourgadget.gadgetbridge.capabilities.loyaltycards.CatimaManager; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.util.GB; import nodomain.freeyourgadget.gadgetbridge.util.StringUtils; public class LoyaltyCardsSettingsFragment extends AbstractPreferenceFragment { private static final Logger LOG = LoggerFactory.getLogger(LoyaltyCardsSettingsFragment.class); static final String FRAGMENT_TAG = "LOYALTY_CARDS_SETTINGS_FRAGMENT"; private GBDevice device; private void setSettingsFileSuffix(final String settingsFileSuffix) { final Bundle args = new Bundle(); args.putString("settingsFileSuffix", settingsFileSuffix); setArguments(args); } private void setDevice(final GBDevice device) { final Bundle args = getArguments() != null ? getArguments() : new Bundle(); args.putParcelable("device", device); setArguments(args); } @Override public void onCreatePreferences(final Bundle savedInstanceState, final String rootKey) { final Bundle arguments = getArguments(); if (arguments == null) { return; } final String settingsFileSuffix = arguments.getString("settingsFileSuffix", null); this.device = arguments.getParcelable("device"); if (settingsFileSuffix == null) { return; } getPreferenceManager().setSharedPreferencesName("devicesettings_" + settingsFileSuffix); setPreferencesFromResource(R.xml.loyalty_cards, rootKey); reloadPreferences(null); } static LoyaltyCardsSettingsFragment newInstance(GBDevice device) { final String settingsFileSuffix = device.getAddress(); final LoyaltyCardsSettingsFragment fragment = new LoyaltyCardsSettingsFragment(); fragment.setSettingsFileSuffix(settingsFileSuffix); fragment.setDevice(device); return fragment; } protected void reloadPreferences(final String catimaPackageName) { final CatimaManager catimaManager = new CatimaManager(requireContext()); final List installedCatimaPackages = catimaManager.findInstalledCatimaPackages(); final boolean catimaInstalled = !installedCatimaPackages.isEmpty(); final ListPreference catimaPackagePreference = findPreference(LOYALTY_CARDS_CATIMA_PACKAGE); if (catimaPackagePreference != null) { catimaPackagePreference.setEntries(installedCatimaPackages.toArray(new CharSequence[0])); catimaPackagePreference.setEntryValues(installedCatimaPackages.toArray(new CharSequence[0])); catimaPackagePreference.setVisible(installedCatimaPackages.size() > 1); catimaPackagePreference.setOnPreferenceChangeListener((preference, newValue) -> { LOG.info("Catima package preference changed to {}", newValue); reloadPreferences((String) newValue); return true; }); if (catimaInstalled) { // Ensure the currently selected value is actually an installed Catima package if (StringUtils.isNullOrEmpty(catimaPackagePreference.getValue()) || !installedCatimaPackages.contains(catimaPackagePreference.getValue())) { catimaPackagePreference.setValue(installedCatimaPackages.get(0).toString()); } } } final String finalCatimaPackageName; if (catimaPackageName != null) { finalCatimaPackageName = catimaPackageName; } else if (catimaPackagePreference != null) { finalCatimaPackageName = catimaPackagePreference.getValue(); } else { LOG.warn("This should never happen - catima package not found"); finalCatimaPackageName = "this.should.never.happen"; } final CatimaContentProvider catima = new CatimaContentProvider(requireContext(), finalCatimaPackageName); final Preference openCatimaPreference = findPreference(LOYALTY_CARDS_OPEN_CATIMA); if (openCatimaPreference != null) { openCatimaPreference.setVisible(catimaInstalled); openCatimaPreference.setOnPreferenceClickListener(preference -> { if (catimaPackagePreference != null) { final PackageManager packageManager = requireContext().getPackageManager(); final Intent launchIntent = packageManager.getLaunchIntentForPackage(finalCatimaPackageName); if (launchIntent != null) { startActivity(launchIntent); } } return true; }); } final Preference catimaNotInstalledPreference = findPreference(LOYALTY_CARDS_CATIMA_NOT_INSTALLED); if (catimaNotInstalledPreference != null) { catimaNotInstalledPreference.setVisible(!catimaInstalled); } final Preference installCatimaPreference = findPreference(LOYALTY_CARDS_INSTALL_CATIMA); if (installCatimaPreference != null) { installCatimaPreference.setVisible(!catimaInstalled); installCatimaPreference.setOnPreferenceClickListener(preference -> { installCatima(); return true; }); } final boolean permissionGranted = ContextCompat.checkSelfPermission(requireContext(), catima.getReadPermission()) == PackageManager.PERMISSION_GRANTED; final Preference catimaPermissionsPreference = findPreference(LOYALTY_CARDS_CATIMA_PERMISSIONS); if (catimaPermissionsPreference != null) { catimaPermissionsPreference.setVisible(catimaInstalled && !permissionGranted); catimaPermissionsPreference.setOnPreferenceClickListener(preference -> { ActivityCompat.requestPermissions( requireActivity(), new String[]{catima.getReadPermission()}, LoyaltyCardsSettingsActivity.PERMISSION_REQUEST_CODE ); return true; }); } final boolean catimaCompatible = catima.isCatimaCompatible(); final Preference catimaNotCompatiblePreference = findPreference(LOYALTY_CARDS_CATIMA_NOT_COMPATIBLE); if (catimaNotCompatiblePreference != null) { catimaNotCompatiblePreference.setVisible(catimaInstalled && permissionGranted && !catimaCompatible); } final Preference syncPreference = findPreference(LOYALTY_CARDS_SYNC); if (syncPreference != null) { syncPreference.setEnabled(catimaInstalled && catimaCompatible && permissionGranted); syncPreference.setOnPreferenceClickListener(preference -> { catimaManager.sync(device); return true; }); } final PreferenceCategory headerCatima = findPreference(PREF_KEY_HEADER_LOYALTY_CARDS_CATIMA); if (headerCatima != null) { boolean allHidden = true; for (int i = 0; i < headerCatima.getPreferenceCount(); i++) { if (headerCatima.getPreference(i).isVisible()) { allHidden = false; break; } } headerCatima.setVisible(!allHidden); } if (catimaInstalled && catimaCompatible && permissionGranted) { final MultiSelectListPreference syncGroups = findPreference(LOYALTY_CARDS_SYNC_GROUPS); if (syncGroups != null) { final List groups = catima.getGroups(); final CharSequence[] entries = groups.toArray(new CharSequence[0]); syncGroups.setEntries(entries); syncGroups.setEntryValues(entries); // Remove groups that do not exist anymore from the summary final Set values = new HashSet<>(syncGroups.getValues()); final Set toRemove = new HashSet<>(); for (final String group : values) { if (!groups.contains(group)) { toRemove.add(group); } } values.removeAll(toRemove); syncGroups.setSummary(TextUtils.join(", ", values)); } } final boolean allowSync = catimaInstalled && permissionGranted && catimaCompatible; final PreferenceCategory syncCategory = findPreference(PREF_KEY_HEADER_LOYALTY_CARDS_SYNC); if (syncCategory != null) { for (int i = 0; i < syncCategory.getPreferenceCount(); i++) { syncCategory.getPreference(i).setEnabled(allowSync); } } final PreferenceCategory syncOptionsCategory = findPreference(PREF_KEY_HEADER_LOYALTY_CARDS_SYNC_OPTIONS); if (syncOptionsCategory != null) { for (int i = 0; i < syncOptionsCategory.getPreferenceCount(); i++) { syncOptionsCategory.getPreference(i).setEnabled(allowSync); } } } private void installCatima() { try { startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=me.hackerchick.catima"))); } catch (final ActivityNotFoundException e) { GB.toast(requireContext(), requireContext().getString(R.string.loyalty_cards_install_catima_fail), Toast.LENGTH_LONG, GB.WARN); } } }