Skip to content

Commit

Permalink
Provide oss and play-store flavour
Browse files Browse the repository at this point in the history
  • Loading branch information
frimtec committed Sep 9, 2024
1 parent 00810e3 commit 069bd82
Show file tree
Hide file tree
Showing 25 changed files with 336 additions and 153 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ jobs:
java-version: 17

- name: Build debug APK
run: bash ./gradlew assembleDebug --stacktrace
run: bash ./gradlew assembleOssDebug --stacktrace
- name: Upload APK
uses: actions/upload-artifact@v4
with:
name: passist
path: ./app/build/outputs/apk/debug/app-debug.apk
path: ./app/build/outputs/apk/oss/debug/app-oss-debug.apk
8 changes: 4 additions & 4 deletions .github/workflows/deploy_release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ jobs:
GITHUB_TOKEN: ${{ github.token }}

- name: Build APK
run: bash ./gradlew assembleRelease --stacktrace -Dpurchase.validation.key=${{ secrets.PURCHASE_VALIDATION_KEY }}
run: bash ./gradlew assembleOssRelease --stacktrace

- name: Build AAB
run: bash ./gradlew :app:bundleRelease --stacktrace -Dpurchase.validation.key=${{ secrets.PURCHASE_VALIDATION_KEY }}
run: bash ./gradlew :app:bundlePlaystoreRelease --stacktrace -Dpurchase.validation.key=${{ secrets.PURCHASE_VALIDATION_KEY }}

- name: Setup build tool version variable
shell: bash
Expand All @@ -41,7 +41,7 @@ jobs:
name: Sign app APK
id: sign_app_apk
with:
releaseDirectory: app/build/outputs/apk/release
releaseDirectory: app/build/outputs/apk/oss/release
signingKeyBase64: ${{ secrets.SIGNING_KEY }}
alias: ${{ secrets.ALIAS }}
keyStorePassword: ${{ secrets.KEY_STORE_PASSWORD }}
Expand All @@ -53,7 +53,7 @@ jobs:
name: Sign app AAB
id: sign_app_aab
with:
releaseDirectory: app/build/outputs/bundle/release
releaseDirectory: app/build/outputs/bundle/playstoreRelease
signingKeyBase64: ${{ secrets.SIGNING_KEY }}
alias: ${{ secrets.ALIAS }}
keyStorePassword: ${{ secrets.KEY_STORE_PASSWORD }}
Expand Down
11 changes: 10 additions & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,15 @@ android {
unitTests.returnDefaultValues = true
}
namespace 'com.github.frimtec.android.pikettassist'

flavorDimensions = ["version"]
productFlavors {
playstore {
}
oss {
versionNameSuffix "-oss"
}
}
}

dependencies {
Expand All @@ -70,7 +79,7 @@ dependencies {
implementation "com.takisoft.preferencex:preferencex:$takisoft_preferencex_version"
implementation "com.takisoft.preferencex:preferencex-ringtone:$takisoft_preferencex_version"
implementation "com.takisoft.preferencex:preferencex-datetimepicker:$takisoft_preferencex_version"
implementation "com.android.billingclient:billing:$android_billingclient_version"
playstoreImplementation "com.android.billingclient:billing:$android_billingclient_version"
implementation "com.github.frimtec:secure-sms-proxy-api:$secure_sms_proxy_api_version@aar"
testImplementation "org.junit.jupiter:junit-jupiter-api:$junit_version"
testImplementation "org.junit.jupiter:junit-jupiter-params:$junit_version"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package com.github.frimtec.android.pikettassist.ui;

import static com.android.billingclient.api.BillingClient.BillingResponseCode;
import static com.github.frimtec.android.pikettassist.donation.billing.BillingProvider.BillingState.PURCHASED;
import static com.github.frimtec.android.pikettassist.ui.BillingAdapter.BILLING_DIALOG_TAG;
import static com.github.frimtec.android.pikettassist.donation.BillingAdapter.BILLING_DIALOG_TAG;
import static com.github.frimtec.android.pikettassist.ui.billing.BillingProvider.BillingState.PURCHASED;
import static com.github.frimtec.android.pikettassist.ui.overview.StateFragment.REGISTER_SMS_ADAPTER_REQUEST_CODE;

import android.annotation.SuppressLint;
Expand Down Expand Up @@ -32,9 +31,8 @@

import com.github.frimtec.android.pikettassist.R;
import com.github.frimtec.android.pikettassist.action.Action;
import com.github.frimtec.android.pikettassist.donation.BillingAdapter;
import com.github.frimtec.android.pikettassist.donation.DonationFragment;
import com.github.frimtec.android.pikettassist.donation.billing.BillingManager;
import com.github.frimtec.android.pikettassist.donation.billing.BillingProvider;
import com.github.frimtec.android.pikettassist.service.LowSignalWorker;
import com.github.frimtec.android.pikettassist.service.PikettWorker;
import com.github.frimtec.android.pikettassist.service.ShiftService;
Expand All @@ -44,6 +42,7 @@
import com.github.frimtec.android.pikettassist.state.ApplicationState;
import com.github.frimtec.android.pikettassist.ui.about.AboutActivity;
import com.github.frimtec.android.pikettassist.ui.alerts.AlertListFragment;
import com.github.frimtec.android.pikettassist.ui.billing.BillingManagerContract;
import com.github.frimtec.android.pikettassist.ui.common.AbstractListFragment;
import com.github.frimtec.android.pikettassist.ui.common.ViewPager2Helper;
import com.github.frimtec.android.pikettassist.ui.overview.StateFragment;
Expand Down Expand Up @@ -98,8 +97,8 @@ public Fragment createFragment(int position) {
StateFragment stateFragment = new StateFragment();
stateFragment.setActivityFacade(new StateFragment.BillingAccess() {
@Override
public List<BillingProvider.BillingState> getProducts() {
return MainActivity.this.billingAdapter.getAllProducts();
public boolean isDonationReminderAppropriate() {
return billingAdapter.isDonationReminderAppropriate(getApplicationContext());
}

@Override
Expand Down Expand Up @@ -228,8 +227,8 @@ protected void onPause() {
protected void onResume() {
super.onResume();
registerBroadcastReceiver();
BillingManager billingManager = this.billingAdapter.getBillingManager();
if (billingManager != null && billingManager.getBillingClientResponseCode() == BillingResponseCode.OK) {
BillingManagerContract billingManager = this.billingAdapter.getBillingManager();
if (billingManager != null && billingManager.isBillingClientReady()) {
billingManager.queryPurchases();
}
refresh();
Expand Down Expand Up @@ -318,13 +317,7 @@ private void showDonationDialog() {
donationFragment.show(getSupportFragmentManager(), BILLING_DIALOG_TAG);

if (billingAdapter != null) {
int billingClientResponseCode = this.billingAdapter.getBillingManager().getBillingClientResponseCode();
switch (billingClientResponseCode) {
case BillingResponseCode.BILLING_UNAVAILABLE -> donationFragment.onManagerReady(null);
case BillingResponseCode.OK -> donationFragment.onManagerReady(this.billingAdapter);
default ->
Log.w(TAG, "Unhandled billing client response code: " + billingClientResponseCode);
}
donationFragment.onManagerReady(this.billingAdapter.getBillingManager().isBillingClientReady() ? this.billingAdapter : null);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.github.frimtec.android.pikettassist.ui.billing;

public interface BillingManagerContract {

boolean isBillingClientReady();

void queryPurchases();

void destroy();
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
package com.github.frimtec.android.pikettassist.donation.billing;
package com.github.frimtec.android.pikettassist.ui.billing;

import android.content.Context;

import java.util.Arrays;
import java.util.List;
Expand All @@ -12,7 +14,7 @@ enum BillingState {
PENDING
}

BillingManager getBillingManager();
BillingManagerContract getBillingManager();

BillingState getBronzeSponsor();

Expand All @@ -23,4 +25,6 @@ enum BillingState {
default List<BillingState> getAllProducts() {
return Arrays.asList(getBronzeSponsor(), getSilverSponsor(), getGoldSponsor());
}

boolean isDonationReminderAppropriate(Context context);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.github.frimtec.android.pikettassist.ui.billing;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.util.Log;

import java.time.Duration;
import java.time.Instant;
import java.util.Random;

public class DonationReminderHelper {

private static final String TAG = "DonationReminderHelper";

private static final Random RANDOM = new Random(System.currentTimeMillis());

public static boolean randomizedOn(Context context, float probability) {
long installationAgeInDays = Integer.MAX_VALUE;
if (context != null) {
try {
PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
installationAgeInDays = Duration.between(Instant.ofEpochMilli(packageInfo.firstInstallTime), Instant.now()).toDays();
} catch (PackageManager.NameNotFoundException e) {
Log.e(TAG, "Can not get package info", e);
}
}
return RANDOM.nextFloat() <= Math.min((installationAgeInDays - 30f) * 0.01f, probability);
}

}
Original file line number Diff line number Diff line change
@@ -1,25 +1,44 @@
package com.github.frimtec.android.pikettassist.ui.overview;

import static android.app.Activity.RESULT_OK;
import static android.widget.ExpandableListView.getPackedPositionGroup;
import static com.github.frimtec.android.pikettassist.service.system.Feature.SETTING_BATTERY_OPTIMIZATION_OFF;
import static com.github.frimtec.android.pikettassist.service.system.Feature.SETTING_DRAW_OVERLAYS;
import static com.github.frimtec.android.pikettassist.service.system.Feature.SETTING_SCHEDULE_EXACT_ALARM;
import static com.github.frimtec.android.pikettassist.ui.common.DurationFormatter.UnitNameProvider.siFormatter;
import static com.github.frimtec.android.pikettassist.ui.common.DurationFormatter.toDurationString;
import static com.github.frimtec.android.pikettassist.ui.overview.State.TrafficLight.RED;
import static com.github.frimtec.android.pikettassist.ui.overview.State.TrafficLight.YELLOW;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.util.Log;
import android.view.ContextMenu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.ExpandableListContextMenuInfo;

import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.github.frimtec.android.pikettassist.R;
import com.github.frimtec.android.pikettassist.domain.*;
import com.github.frimtec.android.pikettassist.donation.billing.BillingProvider.BillingState;
import com.github.frimtec.android.pikettassist.service.*;
import com.github.frimtec.android.pikettassist.domain.Contact;
import com.github.frimtec.android.pikettassist.domain.ContactPerson;
import com.github.frimtec.android.pikettassist.domain.OnOffState;
import com.github.frimtec.android.pikettassist.domain.Shift;
import com.github.frimtec.android.pikettassist.domain.ShiftState;
import com.github.frimtec.android.pikettassist.domain.TestAlarm;
import com.github.frimtec.android.pikettassist.domain.TestAlarmContext;
import com.github.frimtec.android.pikettassist.service.AlertService;
import com.github.frimtec.android.pikettassist.service.ContactPersonService;
import com.github.frimtec.android.pikettassist.service.OperationsCenterContactService;
import com.github.frimtec.android.pikettassist.service.ShiftService;
import com.github.frimtec.android.pikettassist.service.SmsListener;
import com.github.frimtec.android.pikettassist.service.dao.AlertDao;
import com.github.frimtec.android.pikettassist.service.dao.TestAlarmDao;
import com.github.frimtec.android.pikettassist.service.system.BatteryService;
Expand All @@ -40,29 +59,31 @@
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Random;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import static android.app.Activity.RESULT_OK;
import static android.widget.ExpandableListView.getPackedPositionGroup;
import static com.github.frimtec.android.pikettassist.donation.billing.BillingProvider.BillingState.NOT_LOADED;
import static com.github.frimtec.android.pikettassist.donation.billing.BillingProvider.BillingState.PURCHASED;
import static com.github.frimtec.android.pikettassist.service.system.Feature.*;
import static com.github.frimtec.android.pikettassist.ui.common.DurationFormatter.UnitNameProvider.siFormatter;
import static com.github.frimtec.android.pikettassist.ui.common.DurationFormatter.toDurationString;
import static com.github.frimtec.android.pikettassist.ui.overview.State.TrafficLight.RED;
import static com.github.frimtec.android.pikettassist.ui.overview.State.TrafficLight.YELLOW;

public class StateFragment extends AbstractListFragment<State, State> {

public static final int REGISTER_SMS_ADAPTER_REQUEST_CODE = 1000;
private static final int NOT_FOUND = -1;

public interface BillingAccess {

List<BillingState> getProducts();
boolean isDonationReminderAppropriate();

void showDonationDialog();
}
Expand Down Expand Up @@ -332,10 +353,7 @@ private void regularStates(List<State> states) {
}

if (billingAccess != null) {
List<BillingState> products = billingAccess.getProducts();
if (products.stream().allMatch(billing -> billing != NOT_LOADED) &&
products.stream().noneMatch(billing -> billing == PURCHASED) &&
randomizedOn()) {
if (billingAccess.isDonationReminderAppropriate()) {
DonationState donationState = new DonationState(stateContext);
states.add(this.random.nextInt(states.size() + 1), donationState);
}
Expand All @@ -349,20 +367,6 @@ private String toDuration(boolean pikettStateManuallyOn, ShiftState shiftState,
);
}

private boolean randomizedOn() {
long installationAgeInDays = Integer.MAX_VALUE;
Context context = getContext();
if (context != null) {
try {
PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
installationAgeInDays = Duration.between(Instant.ofEpochMilli(packageInfo.firstInstallTime), Instant.now()).toDays();
} catch (PackageManager.NameNotFoundException e) {
Log.e(TAG, "Can not get package info", e);
}
}
return this.random.nextFloat() <= Math.min((installationAgeInDays - 30f) * 0.01f, 0.3f);
}

private String formatDateTime(Instant time) {
return time != null ?
LocalDateTime.ofInstant(time, ZoneId.systemDefault()).format(DateTimeFormatter.ofPattern(StateFragment.DATE_TIME_FORMAT, Locale.getDefault())) : "";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.github.frimtec.android.pikettassist.donation;

import static com.github.frimtec.android.pikettassist.ui.billing.BillingProvider.BillingState.NOT_PURCHASED;
import static com.github.frimtec.android.pikettassist.ui.billing.DonationReminderHelper.randomizedOn;

import android.content.Context;

import androidx.fragment.app.FragmentActivity;

import com.github.frimtec.android.pikettassist.donation.billing.PaypalBillingManager;
import com.github.frimtec.android.pikettassist.ui.billing.BillingManagerContract;
import com.github.frimtec.android.pikettassist.ui.billing.BillingProvider;


public class BillingAdapter implements BillingProvider {

public static final String BILLING_DIALOG_TAG = "billing_dialog";

private final BillingManagerContract billingManager;

private final BillingState bronzeSponsor = NOT_PURCHASED;
private final BillingState silverSponsor = NOT_PURCHASED;
private final BillingState goldSponsor = NOT_PURCHASED;

public BillingAdapter(@SuppressWarnings("unused") FragmentActivity activity) {
this.billingManager = new PaypalBillingManager();
}

@Override
public BillingManagerContract getBillingManager() {
return billingManager;
}

public BillingState getBronzeSponsor() {
return bronzeSponsor;
}

@Override
public boolean isDonationReminderAppropriate(Context context) {
return randomizedOn(context, 0.05f);
}

public BillingState getSilverSponsor() {
return silverSponsor;
}

public BillingState getGoldSponsor() {
return goldSponsor;
}

public void destroy() {
this.billingManager.destroy();
}
}
Loading

0 comments on commit 069bd82

Please sign in to comment.