Skip to content

Commit

Permalink
News/Game Template tracking (#692)
Browse files Browse the repository at this point in the history
* Add news/game template checking to request agent.

* Remove gma framework from example ios project
  • Loading branch information
jjliu15 authored Nov 11, 2022
1 parent 42d333c commit 16dc8c5
Show file tree
Hide file tree
Showing 20 changed files with 413 additions and 33 deletions.
5 changes: 1 addition & 4 deletions .github/workflows/google_mobile_ads.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ jobs:
./gradlew test
iOS:
runs-on: macos-12
runs-on: macos-latest
timeout-minutes: 40
steps:
- uses: actions/checkout@v1
Expand All @@ -59,15 +59,12 @@ jobs:
- name: "Install Tools"
run: |
./.github/workflows/scripts/install-tools.sh
flutter config
- name: "Build iOS Example"
run: ./.github/workflows/scripts/build-example.sh ios ./lib/main.dart
- name: "Unit Tests"
run: |
cd packages/google_mobile_ads/ios
pod lib lint --allow-warnings
env:
DEVELOPER_DIR: /Applications/Xcode_14.0.1.app/Contents/Developer
flutter:
runs-on: ubuntu-latest
Expand Down
2 changes: 0 additions & 2 deletions .github/workflows/scripts/build-example.sh
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@ fi

if [ "$ACTION" == "ios" ]
then
flutter pub get;
pod repo update;
melos exec -c 1 --scope="$GOOGLEMOBILEADS_PLUGIN_SCOPE_EXAMPLE" -- \
flutter build ios --no-codesign --simulator --debug --target="$TARGET_FILE" --dart-define=CI=true
exit
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,16 +58,23 @@ class AdMessageCodec extends StandardMessageCodec {
@NonNull Context context;
@NonNull final FlutterAdSize.AdSizeFactory adSizeFactory;
@Nullable private MediationNetworkExtrasProvider mediationNetworkExtrasProvider;
@NonNull private final FlutterRequestAgentProvider requestAgentProvider;

AdMessageCodec(@NonNull Context context) {
AdMessageCodec(
@NonNull Context context, @NonNull FlutterRequestAgentProvider requestAgentProvider) {
this.context = context;
this.adSizeFactory = new FlutterAdSize.AdSizeFactory();
this.requestAgentProvider = requestAgentProvider;
}

@VisibleForTesting
AdMessageCodec(@NonNull Context context, @NonNull FlutterAdSize.AdSizeFactory adSizeFactory) {
AdMessageCodec(
@NonNull Context context,
@NonNull FlutterAdSize.AdSizeFactory adSizeFactory,
@NonNull FlutterRequestAgentProvider requestAgentProvider) {
this.context = context;
this.adSizeFactory = adSizeFactory;
this.requestAgentProvider = requestAgentProvider;
}

void setContext(@NonNull Context context) {
Expand Down Expand Up @@ -235,6 +242,7 @@ protected Object readValueOfType(byte type, ByteBuffer buffer) {
.setMediationNetworkExtrasIdentifier((String) readValueOfType(buffer.get(), buffer))
.setMediationNetworkExtrasProvider(mediationNetworkExtrasProvider)
.setAdMobExtras((Map<String, String>) readValueOfType(buffer.get(), buffer))
.setRequestAgent(requestAgentProvider.getRequestAgent())
.build();
case VALUE_REWARD_ITEM:
return new FlutterRewardedAd.FlutterRewardItem(
Expand Down Expand Up @@ -283,6 +291,7 @@ protected Object readValueOfType(byte type, ByteBuffer buffer) {
builder.setMediationNetworkExtrasIdentifier((String) readValueOfType(buffer.get(), buffer));
builder.setMediationNetworkExtrasProvider(mediationNetworkExtrasProvider);
builder.setAdMobExtras((Map<String, String>) readValueOfType(buffer.get(), buffer));
builder.setRequestAgent(requestAgentProvider.getRequestAgent());
return builder.build();
case VALUE_INITIALIZATION_STATE:
final String state = (String) readValueOfType(buffer.get(), buffer);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
public class Constants {
/** Version request agent. Should be bumped alongside plugin versions. */
public static final String REQUEST_AGENT_PREFIX_VERSIONED = "Flutter-GMA-2.2.0";
/** Prefix for news template */
public static final String REQUEST_AGENT_NEWS_TEMPLATE_PREFIX = "News";

public static final String REQUEST_AGENT_GAME_TEMPLATE_PREFIX = "Game";

static final String ERROR_CODE_UNEXPECTED_AD_TYPE = "unexpected_ad_type";
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

package io.flutter.plugins.googlemobileads;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.gms.ads.admanager.AdManagerAdRequest;
import java.util.List;
Expand Down Expand Up @@ -64,7 +65,8 @@ FlutterAdManagerAdRequest build() {
publisherProvidedId,
getMediationExtrasIdentifier(),
getMediationNetworkExtrasProvider(),
getAdMobExtras());
getAdMobExtras(),
getRequestAgent());
}
}

Expand All @@ -79,7 +81,8 @@ private FlutterAdManagerAdRequest(
@Nullable String publisherProvidedId,
@Nullable String mediationExtrasIdentifier,
@Nullable MediationNetworkExtrasProvider mediationNetworkExtrasProvider,
@Nullable Map<String, String> adMobExtras) {
@Nullable Map<String, String> adMobExtras,
@NonNull String requestAgent) {
super(
keywords,
contentUrl,
Expand All @@ -88,7 +91,8 @@ private FlutterAdManagerAdRequest(
httpTimeoutMillis,
mediationExtrasIdentifier,
mediationNetworkExtrasProvider,
adMobExtras);
adMobExtras,
requestAgent);
this.customTargeting = customTargeting;
this.customTargetingLists = customTargetingLists;
this.publisherProvidedId = publisherProvidedId;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package io.flutter.plugins.googlemobileads;

import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.ads.mediation.admob.AdMobAdapter;
import com.google.android.gms.ads.AdRequest;
Expand All @@ -34,6 +35,7 @@ class FlutterAdRequest {
@Nullable private final String mediationExtrasIdentifier;
@Nullable private final MediationNetworkExtrasProvider mediationNetworkExtrasProvider;
@Nullable private final Map<String, String> adMobExtras;
@NonNull private final String requestAgent;

protected static class Builder {
@Nullable private List<String> keywords;
Expand All @@ -44,6 +46,12 @@ protected static class Builder {
@Nullable private String mediationExtrasIdentifier;
@Nullable private MediationNetworkExtrasProvider mediationNetworkExtrasProvider;
@Nullable private Map<String, String> adMobExtras;
@NonNull private String requestAgent;

Builder setRequestAgent(String requestAgent) {
this.requestAgent = requestAgent;
return this;
}

Builder setKeywords(@Nullable List<String> keywords) {
this.keywords = keywords;
Expand Down Expand Up @@ -126,6 +134,11 @@ protected Map<String, String> getAdMobExtras() {
return adMobExtras;
}

@NonNull
protected String getRequestAgent() {
return requestAgent;
}

FlutterAdRequest build() {
return new FlutterAdRequest(
keywords,
Expand All @@ -135,7 +148,8 @@ FlutterAdRequest build() {
httpTimeoutMillis,
mediationExtrasIdentifier,
mediationNetworkExtrasProvider,
adMobExtras);
adMobExtras,
requestAgent);
}
}

Expand All @@ -147,7 +161,8 @@ protected FlutterAdRequest(
@Nullable Integer httpTimeoutMillis,
@Nullable String mediationExtrasIdentifier,
@Nullable MediationNetworkExtrasProvider mediationNetworkExtrasProvider,
@Nullable Map<String, String> adMobExtras) {
@Nullable Map<String, String> adMobExtras,
String requestAgent) {
this.keywords = keywords;
this.contentUrl = contentUrl;
this.nonPersonalizedAds = nonPersonalizedAds;
Expand All @@ -156,6 +171,7 @@ protected FlutterAdRequest(
this.mediationExtrasIdentifier = mediationExtrasIdentifier;
this.mediationNetworkExtrasProvider = mediationNetworkExtrasProvider;
this.adMobExtras = adMobExtras;
this.requestAgent = requestAgent;
}

/** Adds network extras to the ad request builder, if any. */
Expand Down Expand Up @@ -206,7 +222,7 @@ protected AdRequest.Builder updateAdRequestBuilder(AdRequest.Builder builder, St
if (httpTimeoutMillis != null) {
builder.setHttpTimeoutMillis(httpTimeoutMillis);
}
builder.setRequestAgent(Constants.REQUEST_AGENT_PREFIX_VERSIONED);
builder.setRequestAgent(requestAgent);
return builder;
}

Expand Down Expand Up @@ -249,6 +265,11 @@ protected Map<String, String> getAdMobExtras() {
return adMobExtras;
}

@NonNull
protected String getRequestAgent() {
return requestAgent;
}

@Override
public boolean equals(Object o) {
if (this == o) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package io.flutter.plugins.googlemobileads;

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Bundle;
import androidx.annotation.Nullable;

/** Class that helps detect whether the news or game template is being used. */
class FlutterRequestAgentProvider {

static final String GAME_VERSION_KEY =
"io.flutter.plugins.googlemobileads.FLUTTER_GAME_TEMPLATE_VERSION";
static final String NEWS_VERSION_KEY =
"io.flutter.plugins.googlemobileads.FLUTTER_NEWS_TEMPLATE_VERSION";

private final Context context;
@Nullable private String newsTemplateVersion;
@Nullable private String gameTemplateVersion;

FlutterRequestAgentProvider(Context context) {
this.context = context;
processGameAndNewsTemplateVersions(context);
}

private void processGameAndNewsTemplateVersions(Context context) {
try {
ApplicationInfo info =
context
.getApplicationContext()
.getPackageManager()
.getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA);
Bundle metaData = info.metaData;
if (metaData != null) {
gameTemplateVersion = info.metaData.getString(GAME_VERSION_KEY);
newsTemplateVersion = info.metaData.getString(NEWS_VERSION_KEY);
}
} catch (NameNotFoundException | ClassCastException e) {
// Do nothing
}
}

String getRequestAgent() {
StringBuilder sb = new StringBuilder();
sb.append(Constants.REQUEST_AGENT_PREFIX_VERSIONED);
if (newsTemplateVersion != null) {
sb.append("_");
sb.append(Constants.REQUEST_AGENT_NEWS_TEMPLATE_PREFIX);
sb.append("-");
sb.append(newsTemplateVersion);
}
if (gameTemplateVersion != null) {
sb.append("_");
sb.append(Constants.REQUEST_AGENT_GAME_TEMPLATE_PREFIX);
sb.append("-");
sb.append(gameTemplateVersion);
}
return sb.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,10 @@ private NativeAdFactory removeNativeAdFactory(String factoryId) {
@Override
public void onAttachedToEngine(FlutterPluginBinding binding) {
pluginBinding = binding;
adMessageCodec = new AdMessageCodec(binding.getApplicationContext());
adMessageCodec =
new AdMessageCodec(
binding.getApplicationContext(),
new FlutterRequestAgentProvider(binding.getApplicationContext()));
if (mediationNetworkExtrasProvider != null) {
adMessageCodec.setMediationNetworkExtrasProvider(mediationNetworkExtrasProvider);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,14 @@
public class AdMessageCodecTest {
AdMessageCodec codec;
AdSizeFactory mockAdSizeFactory;
FlutterRequestAgentProvider mockFlutterRequestAgentProvider;

@Before
public void setup() {
mockAdSizeFactory = mock(AdSizeFactory.class);
codec = new AdMessageCodec(mock(Context.class), mockAdSizeFactory);
mockFlutterRequestAgentProvider = mock(FlutterRequestAgentProvider.class);
codec =
new AdMessageCodec(mock(Context.class), mockAdSizeFactory, mockFlutterRequestAgentProvider);
}

@Test
Expand Down Expand Up @@ -283,6 +286,7 @@ public void encodeFlutterAdRequest() {

@Test
public void encodeFlutterAdManagerAdRequest() {
doReturn("mock-request-agent").when(mockFlutterRequestAgentProvider).getRequestAgent();
FlutterAdManagerAdRequest.Builder builder = new FlutterAdManagerAdRequest.Builder();
builder.setKeywords(Arrays.asList("1", "2", "3"));
builder.setContentUrl("contentUrl");
Expand All @@ -297,8 +301,10 @@ public void encodeFlutterAdManagerAdRequest() {
FlutterAdManagerAdRequest flutterAdManagerAdRequest = builder.build();

final ByteBuffer message = codec.encodeMessage(flutterAdManagerAdRequest);

assertEquals(codec.decodeMessage((ByteBuffer) message.position(0)), flutterAdManagerAdRequest);
FlutterAdManagerAdRequest decodedAdRequest =
(FlutterAdManagerAdRequest) codec.decodeMessage((ByteBuffer) message.position(0));
assertEquals(decodedAdRequest, flutterAdManagerAdRequest);
assertEquals(decodedAdRequest.getRequestAgent(), "mock-request-agent");
}

@Test
Expand Down
Loading

0 comments on commit 16dc8c5

Please sign in to comment.