Skip to content

Commit

Permalink
Remove Replica dependency from ad helper (#909)
Browse files Browse the repository at this point in the history
* Fix ads fix and Use subscription pattern.

* remove Replica dependency from ad helper

---------

Co-authored-by: Jigar-f <[email protected]>
Co-authored-by: atavism <[email protected]>
  • Loading branch information
3 people authored Sep 13, 2023
1 parent 323c56a commit 9454418
Show file tree
Hide file tree
Showing 9 changed files with 132 additions and 64 deletions.
1 change: 1 addition & 0 deletions .run/main.dart.run.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="main.dart" type="FlutterRunConfigurationType" factoryName="Flutter">
<option name="additionalArgs" value="--dart-define=INTERSTITIAL_AD_UNIT_ID=ca-app-pub-2685698271254859/9922829329 --dart-define=DD_APPLICATION_ID=f8eabf3c-5db3-4f7e-8e6a-5a72433b46d2 --dart-define=DD_CLIENT_TOKEN=puba617ab01333a95a25a9d3709f04e1654" />
<option name="attachArgs" value="--profile" />
<option name="buildFlavor" value="prod" />
<option name="filePath" value="$PROJECT_DIR$/lib/main.dart" />
<method v="2" />
Expand Down
4 changes: 2 additions & 2 deletions android/app/libs/liblantern-all.aar
Git LFS file not shown
12 changes: 11 additions & 1 deletion android/app/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -190,4 +190,14 @@

##---------------Begin: proguard configuration for Signal ----------
-keep class org.whispersystems.** { *; }
##---------------End: proguard configuration for Signal ----------
##---------------End: proguard configuration for Signal ----------

-keep class com.google.ads.** # Don't proguard AdMob classes
-dontwarn com.google.ads.
-keep public class com.google.android.gms.ads.** {
public *;
}

-keep public class com.google.ads.** {
public *;
}
59 changes: 44 additions & 15 deletions android/app/src/main/kotlin/io/lantern/model/SessionModel.kt
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package io.lantern.model

import android.app.Activity
import android.content.Intent
import android.os.AsyncTask
import android.os.Build
import android.content.Intent
import androidx.core.content.ContextCompat
import com.google.gson.JsonObject
import com.google.protobuf.ByteString
Expand All @@ -23,7 +23,6 @@ import org.getlantern.lantern.MainActivity
import org.getlantern.lantern.R
import org.getlantern.lantern.activity.FreeKassaActivity_
import org.getlantern.lantern.activity.WebViewActivity_
import org.getlantern.mobilesdk.model.IssueReporter
import org.getlantern.lantern.datadog.Datadog
import org.getlantern.lantern.model.LanternHttpClient
import org.getlantern.lantern.model.LanternHttpClient.ProCallback
Expand All @@ -40,6 +39,7 @@ import org.getlantern.lantern.util.restartApp
import org.getlantern.lantern.util.showAlertDialog
import org.getlantern.lantern.util.showErrorDialog
import org.getlantern.mobilesdk.Logger
import org.getlantern.mobilesdk.model.IssueReporter
import org.getlantern.mobilesdk.model.SessionManager

/**
Expand All @@ -66,7 +66,11 @@ class SessionModel(
const val PATH_USER_LEVEL = "userLevel"

const val PATH_SPLIT_TUNNELING = "/splitTunneling"
const val SHOULD_SHOW_CAS_ADS = "shouldShowCASAds"
const val SHOULD_SHOW_GOOGLE_ADS = "shouldShowGoogleAds"
const val PATH_APPS_DATA = "/appsData/"


}

init {
Expand All @@ -87,30 +91,43 @@ class SessionModel(
// hard disable chat
tx.put(SessionManager.CHAT_ENABLED, false)
tx.put(PATH_SDK_VERSION, Internalsdk.sdkVersion())
//By Default set it to false
tx.put(SHOULD_SHOW_GOOGLE_ADS, false)
tx.put(SHOULD_SHOW_CAS_ADS, false)
}
updateAppsData()
checkAdsAvailability()
}

fun checkAdsAvailability() {
Logger.debug(TAG, "checkAdsAvailability called")
val googleAds = shouldShowAdsBasedRegion { LanternApp.getSession().shouldShowAdsEnabled() }
Logger.debug(TAG, "checkAdsAvailability with googleAds values $googleAds enable ${LanternApp.getSession().shouldShowAdsEnabled()}")
val casAds = shouldShowAdsBasedRegion { LanternApp.getSession().shouldCASShowAdsEnabled() }
Logger.debug(TAG, "checkAdsAvailability with cas values $googleAds enable ${LanternApp.getSession().shouldCASShowAdsEnabled()}")
db.mutate { tx ->
tx.put(SHOULD_SHOW_GOOGLE_ADS, googleAds)
tx.put(SHOULD_SHOW_CAS_ADS, casAds)
}
}


override fun doOnMethodCall(call: MethodCall, result: MethodChannel.Result) {
when (call.method) {
"authorizeViaEmail" -> authorizeViaEmail(call.argument("emailAddress")!!, result)
"shouldShowAds" -> {
result.success(shouldShowAdsBasedRegion {
LanternApp.getSession().shouldShowAdsEnabled()
})
}
"shouldCASShowAds" -> {
result.success(shouldShowAdsBasedRegion {
LanternApp.getSession().shouldCASShowAdsEnabled()
})
}
"checkEmailExists" -> checkEmailExists(call.argument("emailAddress")!!, result)
"requestLinkCode" -> requestLinkCode(result)
"resendRecoveryCode" -> sendRecoveryCode(result)
"validateRecoveryCode" -> validateRecoveryCode(call.argument("code")!!, result)
"approveDevice" -> approveDevice(call.argument("code")!!, result)
"removeDevice" -> removeDevice(call.argument("deviceId")!!, result)
"reportIssue" -> reportIssue(call.argument("email")!!, call.argument("issue")!!, call.argument("description")!!, result)
"reportIssue" -> reportIssue(
call.argument("email")!!,
call.argument("issue")!!,
call.argument("description")!!,
result
)

"applyRefCode" -> paymentsUtil.applyRefCode(call.argument("refCode")!!, result)
"redeemResellerCode" -> paymentsUtil.redeemResellerCode(
call.argument("email")!!,
Expand Down Expand Up @@ -158,12 +175,15 @@ class SessionModel(
activity.startActivity(intent)
}
}

"trackUserAction" -> {
Datadog.trackUserClick(call.argument("message")!!)
}

"acceptTerms" -> {
LanternApp.getSession().acceptTerms()
}

"setLanguage" -> {
LanternApp.getSession().setLanguage(call.argument("lang"))
}
Expand Down Expand Up @@ -572,9 +592,18 @@ class SessionModel(
)
}

private fun reportIssue(email: String, issue: String, description: String, methodCallResult: MethodChannel.Result) {
private fun reportIssue(
email: String,
issue: String,
description: String,
methodCallResult: MethodChannel.Result
) {
if (!Utils.isNetworkAvailable(activity)) {
methodCallResult.error("errorReportingIssue", activity.getString(R.string.no_internet_connection), null)
methodCallResult.error(
"errorReportingIssue",
activity.getString(R.string.no_internet_connection),
null
)
return
}
Logger.debug(TAG, "Reporting $issue issue on behalf of $email")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -543,6 +543,7 @@ class MainActivity :
//If user come here it mean user has all permissions needed
// Also user given permission for VPN service dialog as well
LanternApp.getSession().setHasFirstSessionCompleted(true)
sessionModel.checkAdsAvailability()
updateStatus(true)
startVpnService()
}
Expand Down Expand Up @@ -606,6 +607,7 @@ class MainActivity :
// this mean user has already given
// system permissions
LanternApp.getSession().setHasFirstSessionCompleted(true)
sessionModel.checkAdsAvailability()
}

}
Expand Down
53 changes: 32 additions & 21 deletions lib/ad_helper.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,13 @@ import 'package:clever_ads_solutions/public/AdCallback.dart';
import 'package:clever_ads_solutions/public/AdImpression.dart';
import 'package:clever_ads_solutions/public/AdTypes.dart';
import 'package:clever_ads_solutions/public/Audience.dart';
import 'package:clever_ads_solutions/public/ConsentFlow.dart';
import 'package:clever_ads_solutions/public/InitConfig.dart';
import 'package:clever_ads_solutions/public/InitializationListener.dart';
import 'package:clever_ads_solutions/public/MediationManager.dart';
import 'package:clever_ads_solutions/public/OnDismissListener.dart';
import 'package:flutter/foundation.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';
import 'package:logger/logger.dart';
import 'package:lantern/common/datadog.dart';
import 'package:lantern/replica/common.dart';

import 'common/session_model.dart';

enum AdType { Google, CAS }

Expand All @@ -29,6 +25,10 @@ const casAttributes = {
'provider': "CAS",
};

var logger = Logger(
printer: PrettyPrinter(),
);

class AdHelper {
static final AdHelper _instance = AdHelper._internal();

Expand Down Expand Up @@ -59,10 +59,9 @@ class AdHelper {
}

// Private methods to decide whether to load or show Google Ads or CAS ads based on conditions
Future<void> _decideAndLoadAds() async {
final shouldShowGoogleAds = await sessionModel.shouldShowAds();
final shouldShowCASAds = await sessionModel.shouldCASShowAds();

Future<void> _decideAndLoadAds(
{required bool shouldShowGoogleAds,
required bool shouldShowCASAds}) async {
logger.d(
'[Ads Manager] Google Ads enable $shouldShowGoogleAds: CAS Ads $shouldShowCASAds');
if (shouldShowGoogleAds) {
Expand Down Expand Up @@ -95,27 +94,32 @@ class AdHelper {

Future<void> _loadInterstitialAd() async {
//To avoid calling multiple ads request repeatedly
assert(interstitialAdUnitId!="","interstitialAdUnitId should not be null or empty");
if (_interstitialAd == null && _failedLoadAttempts < _maxFailAttempts) {
logger.i('[Ads Manager] Request: Making Google Ad request.');
await InterstitialAd.load(
adUnitId: interstitialAdUnitId,
request: const AdRequest(),
adLoadCallback: InterstitialAdLoadCallback(
onAdLoaded: (ad) {
_failedLoadAttempts = 0;
ad.fullScreenContentCallback = FullScreenContentCallback(
onAdClicked: (ad) {
logger.i('[Ads Manager] onAdClicked callback');
Datadog.trackUserTap('User tapped on interstitial ad', googleAttributes);
Datadog.trackUserTap(
'User tapped on interstitial ad', googleAttributes);
},
onAdShowedFullScreenContent: (ad) {
logger.i('[Ads Manager] Showing Ads');
Datadog.trackUserCustom('User shown interstitial ad', googleAttributes);
Datadog.trackUserCustom(
'User shown interstitial ad', googleAttributes);
},
onAdFailedToShowFullScreenContent: (ad, error) {
logger.i(
'[Ads Manager] onAdFailedToShowFullScreenContent callback');
Datadog.addError('Ad failed to show full screen content: $error',
attributes: googleAttributes);
Datadog.addError(
'Ad failed to show full screen content: $error',
attributes: googleAttributes);
//if ads fail to load let user turn on VPN
_postShowingAds();
},
Expand All @@ -131,7 +135,8 @@ class AdHelper {
onAdFailedToLoad: (err) {
_failedLoadAttempts++; // increment the count on failure
logger.i('[Ads Manager] failed to load $err');
Datadog.addError('failed to load interstitial ad: $err', attributes: googleAttributes);
Datadog.addError('failed to load interstitial ad: $err',
attributes: googleAttributes);
_postShowingAds();
},
),
Expand All @@ -143,12 +148,10 @@ class AdHelper {
if (_currentAdType == AdType.Google) {
_interstitialAd?.dispose();
_interstitialAd = null;
_failedLoadAttempts = 0; // Reset counter for Google Ads
logger.i(
'[Ads Manager] Post-show: Google Ad displayed. Resetting failed load attempts and requesting a new ad.');
_loadInterstitialAd();
} else if (_currentAdType == AdType.CAS) {
_failedCASLoadAttempts = 0; // Reset counter for CAS Ads
logger.i(
'[Ads Manager] Post-show: CAS Ad displayed. Resetting failed load attempts and requesting a new ad.');
_loadCASInterstitial();
Expand All @@ -162,8 +165,13 @@ class AdHelper {
}

// Public methods
Future<void> loadAds() async {
await _decideAndLoadAds();
Future<void> loadAds(
{required bool shouldShowGoogleAds,
required bool shouldShowCASAds}) async {
await _decideAndLoadAds(
shouldShowCASAds: shouldShowCASAds,
shouldShowGoogleAds: shouldShowGoogleAds,
);
}

Future<void> showAds() async {
Expand Down Expand Up @@ -211,14 +219,16 @@ class AdHelper {

void _onCASAdShowFailed() {
logger.e('[Ads Manager] Error: CAS Interstitial failed to display.');
Datadog.addError('Failed to display interstitial ad', attributes: casAttributes);
Datadog.addError('Failed to display interstitial ad',
attributes: casAttributes);
_failedCASLoadAttempts++;
_postShowingAds(); // Reload or decide the next action
}

void _onCASAdClosedOrComplete() {
logger.i('[Ads Manager] Completion: CAS Interstitial closed or completed.');
Datadog.trackUserCustom('Interstitial ad closed or completed', casAttributes);
Datadog.trackUserCustom(
'Interstitial ad closed or completed', casAttributes);
// Reset the counter when the ad successfully shows and closes/completes
_failedCASLoadAttempts = 0;
_postShowingAds();
Expand Down Expand Up @@ -278,7 +288,8 @@ class InterstitialListenerWrapper extends AdCallback {
onFailed.call();
logger.i(
'[CASIntegrationHelper] - InterstitialListenerWrapper onShowFailed-:$message');
Datadog.addError('Interstitial ad onShowFailed: $message', attributes: casAttributes);
Datadog.addError('Interstitial ad onShowFailed: $message',
attributes: casAttributes);
}

@override
Expand Down
24 changes: 14 additions & 10 deletions lib/common/session_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -161,16 +161,6 @@ class SessionModel extends Model {
.invokeMethod('getCountryCode', <String, dynamic>{});
}

Future<bool> shouldShowAds() async {
return await methodChannel
.invokeMethod('shouldShowAds', <String, dynamic>{});
}

Future<bool> shouldCASShowAds() async {
return await methodChannel
.invokeMethod('shouldCASShowAds', <String, dynamic>{});
}

Future<void> setLanguage(String lang) {
return methodChannel.invokeMethod('setLanguage', <String, dynamic>{
'lang': lang,
Expand Down Expand Up @@ -212,6 +202,20 @@ class SessionModel extends Model {
});
}

Widget shouldShowGoogleAds(ValueWidgetBuilder<bool> builder) {
return subscribedSingleValueBuilder<bool>(
'shouldShowGoogleAds',
builder: builder,
);
}

Widget shouldShowCASAds(ValueWidgetBuilder<bool> builder) {
return subscribedSingleValueBuilder<bool>(
'shouldShowCASAds',
builder: builder,
);
}

Widget selectedTab(ValueWidgetBuilder<String> builder) {
return subscribedSingleValueBuilder<String>(
'/selectedTab',
Expand Down
7 changes: 4 additions & 3 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,13 @@ import 'package:google_mobile_ads/google_mobile_ads.dart';
import 'package:lantern/app.dart';
import 'package:lantern/common/common.dart';


Future<void> main() async {
// CI will be true only when running appium test
var CI = const String.fromEnvironment('CI', defaultValue: 'false');
print('CI is running $CI');
if (CI == 'true') {
enableFlutterDriverExtension();
}

WidgetsFlutterBinding.ensureInitialized();
await _initGoogleMobileAds();
await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
Expand All @@ -21,5 +19,8 @@ Future<void> main() async {
Future<void> _initGoogleMobileAds() async {
await MobileAds.instance.initialize();
await MobileAds.instance.setAppMuted(true);
// await MobileAds.instance.updateRequestConfiguration(RequestConfiguration(testDeviceIds: ['D79728264130CE0918737B5A2178D362']));
await MobileAds.instance.updateRequestConfiguration(RequestConfiguration(testDeviceIds: ['D79728264130CE0918737B5A2178D362']));
MobileAds.instance.openAdInspector((p0) {
print('ad error $p0');
});
}
Loading

0 comments on commit 9454418

Please sign in to comment.