Android Open Source - AdFlake-Client-Android Ad Flake Layout






From Project

Back to project page AdFlake-Client-Android.

License

The source code is released under:

Apache License

If you think the Android project AdFlake-Client-Android listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/**
 * AdFlakeLayout.java (AdFlakeSDK-Android)
 *// w w w .j  a  v a2s . co  m
 * Copyright ? 2013 MADE GmbH - All Rights Reserved.
 *
 * Unauthorized copying of this file, via any medium is strictly prohibited
 * unless otherwise noted in the License section of this document header.
 *
 * @file AdFlakeLayout.java
 * @copyright 2013 MADE GmbH. All rights reserved.
 * @section License
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.adflake;

import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
import android.view.ViewGroup;
import android.widget.RelativeLayout;

import com.adflake.adapters.AdFlakeAdapter;
import com.adflake.obj.Custom;
import com.adflake.obj.Extra;
import com.adflake.obj.Ration;
import com.adflake.util.AdFlakeUtil;

/**
 * The AdFlakeLayout class manages the display of ADs as received from the
 * AdFlake server.
 */
public class AdFlakeLayout extends RelativeLayout
{
  public static final String ADFLAKE_KEY = "ADFLAKE_KEY";
  public WeakReference<Activity> activityReference;

  /**
   * The UI handler.
   * 
   * @note Only the UI thread can update the UI, so we need a Handler for UI
   *       callbacks
   */
  public final Handler handler = new Handler();

  /**
   * The background scheduler manages background threads.
   */
  public final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
  public Extra extra;

  public Custom currentCustom;

  /** @note This is just so our threads can reference us explicitly. */
  public WeakReference<RelativeLayout> superViewReference;

  public Ration activeRation;
  public Ration nextRation;

  public AdFlakeInterface adFlakeInterface;

  public AdFlakeManager adFlakeManager;

  /**
   * Instantiates a new ad flake layout.
   * 
   * @param context
   *            the context
   * @param adFlakeKey
   *            the ad flake key
   */
  public AdFlakeLayout(final Activity context, final String adFlakeKey)
  {
    super(context);
    init(context, adFlakeKey);
  }

  /**
   * Instantiates a new ad flake layout.
   * 
   * @param context
   *            the context
   * @param attrs
   *            the attrs
   */
  public AdFlakeLayout(Context context, AttributeSet attrs)
  {
    super(context, attrs);

    if (this.isInEditMode())
      return;

    // Retrieves AdFlake key.
    String key = getAdFlakeKey(context);
    init((Activity) context, key);
  }

  /**
   * Gets the optimal layout params.
   * 
   * @return the layout params
   */
  public LayoutParams getOptimalRelativeLayoutParams()
  {
    DisplayMetrics displayMetrics = getResources().getDisplayMetrics();

    final float density = displayMetrics.density;
    final int width = (int) (AdFlakeUtil.BANNER_DEFAULT_WIDTH * density);
    final int height = (int) (AdFlakeUtil.BANNER_DEFAULT_HEIGHT * density);

    return new RelativeLayout.LayoutParams(width, height);
  }

  /**
   * Sets the max height.
   * 
   * @param height
   *            the new max height
   */
  public void setMaxHeight(int height)
  {
    _maximumHeight = height;
  }

  /**
   * Sets the max width.
   * 
   * @param width
   *            the new max width
   */
  public void setMaxWidth(int width)
  {
    _maximumWidth = width;
  }

  /**
   * Gets the ad flake key.
   * 
   * @param context
   *            the context
   * @return the ad flake key
   */
  protected String getAdFlakeKey(Context context)
  {
    if (this.isInEditMode())
      return "EDITMODE";

    final String packageName = context.getPackageName();
    final String activityName = context.getClass().getName();
    final PackageManager pm = context.getPackageManager();
    Bundle bundle = null;
    // Attempts to retrieve Activity-specific AdFlake key first. If not
    // found, retrieve Application-wide AdFlake key.
    try
    {
      ActivityInfo activityInfo = pm.getActivityInfo(new ComponentName(packageName, activityName), PackageManager.GET_META_DATA);
      bundle = activityInfo.metaData;
      if (bundle != null)
      {
        return bundle.getString(AdFlakeLayout.ADFLAKE_KEY);
      }
    }
    catch (NameNotFoundException exception)
    {
      // Activity cannot be found. Shouldn't be here.
      return null;
    }

    try
    {
      ApplicationInfo appInfo = pm.getApplicationInfo(packageName, PackageManager.GET_META_DATA);
      bundle = appInfo.metaData;
      if (bundle != null)
      {
        return bundle.getString(AdFlakeLayout.ADFLAKE_KEY);
      }
    }
    catch (NameNotFoundException exception)
    {
      // Application cannot be found. Shouldn't be here.
      return null;
    }
    return null;
  }

  /**
   * Initializes this instance.
   * 
   * @param context
   *            the context
   * @param adFlakeKey
   *            the ad flake key
   */
  protected void init(final Activity context, final String adFlakeKey)
  {

    this.activityReference = new WeakReference<Activity>(context);
    this.superViewReference = new WeakReference<RelativeLayout>(this);
    this._adFlakeKey = adFlakeKey;
    this._hasWindow = true;
    this._isScheduled = true;

    if (!this.isInEditMode())
    {
      scheduler.schedule(new UpdateAdFlakeConfigurationRunnable(this, adFlakeKey), 0, TimeUnit.SECONDS);
    }
    setHorizontalScrollBarEnabled(false);
    setVerticalScrollBarEnabled(false);

    this._maximumWidth = 0;
    this._maximumHeight = 0;
  }

  /**
   * On measure.
   * 
   * @param widthMeasureSpec
   *            the width measure spec
   * @param heightMeasureSpec
   *            the height measure spec
   */
  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
  {
    int widthSize = MeasureSpec.getSize(widthMeasureSpec);
    int heightSize = MeasureSpec.getSize(heightMeasureSpec);

    if (_maximumWidth > 0 && widthSize > _maximumWidth)
    {
      widthMeasureSpec = MeasureSpec.makeMeasureSpec(_maximumWidth, MeasureSpec.AT_MOST);
    }

    if (_maximumHeight > 0 && heightSize > _maximumHeight)
    {
      heightMeasureSpec = MeasureSpec.makeMeasureSpec(_maximumHeight, MeasureSpec.AT_MOST);
    }

    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
  }

  /**
   * On window visibility changed.
   * 
   * @param visibility
   *            the visibility
   */
  @Override
  protected void onWindowVisibilityChanged(int visibility)
  {
    if (visibility == VISIBLE && !this.isInEditMode())
    {
      this._hasWindow = true;
      if (!this._isScheduled)
      {
        this._isScheduled = true;

        if (this.extra != null)
        {
          rotateThreadedNow();
        }
        else
        {
          scheduler.schedule(new UpdateAdFlakeConfigurationRunnable(this, _adFlakeKey), 0, TimeUnit.SECONDS);
        }
      }
    }
    else
    {
      this._hasWindow = false;
    }
  }

  /**
   * Rotate ad.
   */
  public void rotateAd()
  {
    if (!this._hasWindow)
    {
      this._isScheduled = false;
      return;
    }

    if (adFlakeManager.sleeperMode)
    {
      Log.d(AdFlakeUtil.ADFLAKE, "AdFlake has no rations and is in sleeper mode");
      return;
    }

    Log.i(AdFlakeUtil.ADFLAKE, "Rotating Ad");
    nextRation = adFlakeManager.getDartedRation();

    handler.post(new HandleAdRunnable(this));
  }

  /**
   * Initialize the proper ad view from nextRation.
   */
  @SuppressLint("DefaultLocale")
  private void handleAd()
  {
    // We shouldn't ever get to a state where nextRation is null unless all
    // networks fail
    if (nextRation == null)
    {
      Log.e(AdFlakeUtil.ADFLAKE, "nextRation is null!");
      rotateThreadedDelayed();
      return;
    }

    String rationInfo = String.format("Showing ad:\n\tnid: %s\n\tname: %s\n\ttype: %d\n\tkey: %s\n\tkey2: %s", nextRation.nid, nextRation.name, nextRation.type, nextRation.key, nextRation.key2);
    Log.d(AdFlakeUtil.ADFLAKE, rationInfo);

    try
    {
      // Tell the previous adapter that its view will be destroyed.
      if (this._previousAdapter != null)
      {
        this._previousAdapter.willDestroy();
      }
      this._previousAdapter = this._currentAdapter;
      this._currentAdapter = AdFlakeAdapter.getAdapterForRation(this, nextRation, true);
    }
    catch (Throwable t)
    {
      Log.w(AdFlakeUtil.ADFLAKE, "Caught an exception in adapter:", t);
      rollover();
      return;
    }
  }

  /**
   * Rotate immediately.
   */
  public void rotateThreadedNow()
  {
    scheduler.schedule(new RotateAdRunnable(this), 0, TimeUnit.SECONDS);
  }

  /**
   * Rotate in extra.cycleTime seconds.
   */
  public void rotateThreadedDelayed()
  {
    Log.d(AdFlakeUtil.ADFLAKE, "Will call rotateAd() in " + extra.cycleTime + " seconds");
    scheduler.schedule(new RotateAdRunnable(this), extra.cycleTime, TimeUnit.SECONDS);
  }

  /**
   * Remove old views and push the new adView.
   * 
   * @param subView
   *            the sub view
   */
  public void pushSubView(ViewGroup subView)
  {
    RelativeLayout superView = superViewReference.get();
    if (superView == null)
    {
      return;
    }
    superView.removeAllViews();

    RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(android.view.ViewGroup.LayoutParams.WRAP_CONTENT, android.view.ViewGroup.LayoutParams.WRAP_CONTENT);
    layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT);
    superView.addView(subView, layoutParams);

    Log.d(AdFlakeUtil.ADFLAKE, "Added subview");

    this.activeRation = nextRation;
    sendImpressionToMetricServer();

    if (this.adFlakeInterface != null)
    {
      this.adFlakeInterface.adFlakeDidPushAdSubView(this);
    }
  }

  /**
   * Rollover.
   */
  public void rollover()
  {
    if (adFlakeManager.sleeperMode)
    {
      Log.d(AdFlakeUtil.ADFLAKE, "AdFlake has no rations and is in sleeper mode");
      return;
    }

    nextRation = adFlakeManager.getRationForCurrentRolloverListPosition();
    handler.post(new HandleAdRunnable(this));
  }

  /**
   * Send impression to metric server.
   */
  private void sendImpressionToMetricServer()
  {
    if (activeRation == null)
      return;

    sendImpressionToMetricServerForRation(activeRation);
  }

  /**
   * Send impression to metric server.
   */
  private void sendImpressionToMetricServerForRation(Ration ration)
  {
    if (ration == null)
      return;

    String url = String.format(AdFlakeUtil.urlImpression, adFlakeManager.adFlakeKey, ration.nid, ration.type, adFlakeManager.deviceIDHash, adFlakeManager.localeString, AdFlakeUtil.VERSION);
    scheduler.schedule(new PingUrlRunnable(url), 0, TimeUnit.SECONDS);
  }

  /**
   * Send ad click to metric server.
   */
  private void sendAdClickToMetricServer()
  {
    if (activeRation == null)
      return;

    sendAdClickToMetricServerForRation(activeRation);
  }

  /**
   * Send ad click to metric server.
   */
  private void sendAdClickToMetricServerForRation(Ration ration)
  {
    if (ration == null)
      return;

    String url = String.format(AdFlakeUtil.urlClick, adFlakeManager.adFlakeKey, ration.nid, ration.type, adFlakeManager.deviceIDHash, adFlakeManager.localeString, AdFlakeUtil.VERSION);
    scheduler.schedule(new PingUrlRunnable(url), 0, TimeUnit.SECONDS);
  }

  /**
   * On intercept touch event. We intercept clicks to provide raw metrics.
   * 
   * @param event
   *            the event
   * @return true, if successful
   */
  @Override
  public boolean onInterceptTouchEvent(MotionEvent event)
  {
    if (this.isInEditMode())
      return false;

    switch (event.getAction())
    {
    // Sending on an ACTION_DOWN isn't 100% correct... user could have
    // touched
    // down and dragged out. Unlikely though.
      case MotionEvent.ACTION_DOWN:
        Log.d(AdFlakeUtil.ADFLAKE, "Intercepted ACTION_DOWN event");
        if (activeRation != null)
        {
          sendAdClickToMetricServer();

          if (activeRation.type == 9)
          {
            if (currentCustom != null && currentCustom.link != null)
            {
              Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(currentCustom.link));
              intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
              try
              {
                if (activityReference == null)
                {
                  return false;
                }
                Activity activity = activityReference.get();
                if (activity == null)
                {
                  return false;
                }
                activity.startActivity(intent);
              }
              catch (Exception e)
              {
                Log.w(AdFlakeUtil.ADFLAKE, "Could not handle click to " + currentCustom.link, e);
              }
            }
            else
            {
              Log.w(AdFlakeUtil.ADFLAKE, "In onInterceptTouchEvent(), but custom or custom.link is null");
            }
          }
          break;
        }
    }

    // Return false so subViews can process event normally.
    return false;
  }

  /**
   * The Interface AdFlakeInterface provides methods to react to changes of a
   * AdFlakeLayout.
   */
  public interface AdFlakeInterface
  {

    /**
     * Invoked when a GenericAdapter instance is handled.
     */
    public void adFlakeGeneric();

    /**
     * Invoked when a banner ad's view has been pushed into the
     * AdFlakeLayout.
     * 
     * @param layout
     *            the layout
     */
    public void adFlakeDidPushAdSubView(AdFlakeLayout layout);

    public void adFlakeDidPresentFullScreenModal(AdFlakeLayout layout);

    public void adFlakeWillPresentFullScreenModal(AdFlakeLayout layout);

    public void adFlakeWillPresentVideoAdModal(AdFlakeLayout layout);

    public void adFlakeDidFailToRequestVideoAd(AdFlakeLayout layout);

    public void adFlakeUserDidWatchEntireVideo(AdFlakeLayout layout);

    public void adFlakeDidLoadVideoAd(AdFlakeLayout layout);
  }

  /**
   * Sets the ad flake interface.
   * 
   * @param i
   *            the new ad flake interface
   */
  public void setAdFlakeInterface(AdFlakeInterface i)
  {
    this.adFlakeInterface = i;
  }

  /**
   * The Class UpdateAdFlakeConfigurationRunnable fetches the AdFlake
   * configuration from the server.
   */
  private static class UpdateAdFlakeConfigurationRunnable implements Runnable
  {
    private WeakReference<AdFlakeLayout> _adFlakeLayoutReference;
    private String _adFlakeKey;

    /**
     * Instantiates a new update ad flake configuration runnable.
     * 
     * @param adFlakeLayout
     *            the ad flake layout
     * @param adFlakeKey
     *            the ad flake key
     */
    public UpdateAdFlakeConfigurationRunnable(AdFlakeLayout adFlakeLayout, String adFlakeKey)
    {
      _adFlakeLayoutReference = new WeakReference<AdFlakeLayout>(adFlakeLayout);
      _adFlakeKey = adFlakeKey;
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Runnable#run()
     */
    public void run()
    {
      final AdFlakeLayout adFlakeLayout = _adFlakeLayoutReference.get();
      if (adFlakeLayout != null)
      {
        Activity activity = adFlakeLayout.activityReference.get();
        if (activity == null)
        {
          return;
        }

        if (adFlakeLayout.adFlakeManager == null)
        {
          adFlakeLayout.adFlakeManager = new AdFlakeManager(new WeakReference<Context>(activity.getApplicationContext()), _adFlakeKey);
        }

        if (!adFlakeLayout._hasWindow)
        {
          adFlakeLayout._isScheduled = false;
          return;
        }

        adFlakeLayout.adFlakeManager.fetchConfigFromServer();
        adFlakeLayout.extra = adFlakeLayout.adFlakeManager.getExtra();

        if (adFlakeLayout.adFlakeManager.videoAdsAvailable)
        {
          // NOTE: we have to prepare the video adapters since they
          // preload

          adFlakeLayout.handler.post(new Runnable()
          {

            @Override
            public void run()
            {
              adFlakeLayout.prepareVideoAdapters();
            }
          });
        }

        if (adFlakeLayout.adFlakeManager.sleeperMode == true)
        {
          // NOTE: if we do not have a configuration it's highly
          // probable that
          // we're in sleeper more, so only check every 10 minutes
          adFlakeLayout.scheduler.schedule(this, 600, TimeUnit.SECONDS);
        }
        else if (adFlakeLayout.extra == null)
        {
          adFlakeLayout.scheduler.schedule(this, 30, TimeUnit.SECONDS);
        }
        else
        {
          adFlakeLayout.rotateAd();
        }
      }
    }
  }

  /**
   * The Class HandleAdRunnable Callback for external networks.
   */
  private static class HandleAdRunnable implements Runnable
  {
    private WeakReference<AdFlakeLayout> adFlakeLayoutReference;

    /**
     * Instantiates a new handle ad runnable.
     * 
     * @param adFlakeLayout
     *            the ad flake layout
     */
    public HandleAdRunnable(AdFlakeLayout adFlakeLayout)
    {
      adFlakeLayoutReference = new WeakReference<AdFlakeLayout>(adFlakeLayout);
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Runnable#run()
     */
    public void run()
    {
      AdFlakeLayout adFlakeLayout = adFlakeLayoutReference.get();
      if (adFlakeLayout != null)
      {
        adFlakeLayout.handleAd();
      }
    }
  }

  /**
   * The Class PushAdViewRunnable inserts the specified ViewGroup into as
   * primary view into the AdFlakeLayout.
   */
  public static class PushAdViewRunnable implements Runnable
  {
    private WeakReference<AdFlakeLayout> adFlakeLayoutReference;
    private ViewGroup nextView;

    /**
     * Instantiates a new view ad runnable.
     * 
     * @param adFlakeLayout
     *            the ad flake layout
     * @param nextView
     *            the next view
     */
    public PushAdViewRunnable(AdFlakeLayout adFlakeLayout, ViewGroup nextView)
    {
      adFlakeLayoutReference = new WeakReference<AdFlakeLayout>(adFlakeLayout);
      this.nextView = nextView;
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Runnable#run()
     */
    public void run()
    {
      AdFlakeLayout adFlakeLayout = adFlakeLayoutReference.get();
      if (adFlakeLayout != null)
      {
        adFlakeLayout.pushSubView(nextView);
      }
    }
  }

  /**
   * The Class RotateAdRunnable rotates the current ad.
   */
  private static class RotateAdRunnable implements Runnable
  {
    private WeakReference<AdFlakeLayout> adFlakeLayoutReference;

    /**
     * Instantiates a new rotate ad runnable.
     * 
     * @param adFlakeLayout
     *            the ad flake layout
     */
    public RotateAdRunnable(AdFlakeLayout adFlakeLayout)
    {
      adFlakeLayoutReference = new WeakReference<AdFlakeLayout>(adFlakeLayout);
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Runnable#run()
     */
    public void run()
    {
      AdFlakeLayout adFlakeLayout = adFlakeLayoutReference.get();
      if (adFlakeLayout != null)
      {
        adFlakeLayout.rotateAd();
      }
    }
  }

  /**
   * The Class PingUrlRunnable performs a HTTP get with the specified URL and
   * ignores the result. This is basically used to trigger a remote operation
   * on the server.
   */
  private static class PingUrlRunnable implements Runnable
  {
    private String url;

    /**
     * Instantiates a new ping url runnable.
     * 
     * @param url
     *            the url
     */
    public PingUrlRunnable(String url)
    {
      this.url = url;
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Runnable#run()
     */
    public void run()
    {
      Log.d(AdFlakeUtil.ADFLAKE, "Pinging URL: " + url);

      HttpClient httpClient = new DefaultHttpClient();
      HttpGet httpGet = new HttpGet(url);

      try
      {
        httpClient.execute(httpGet);
      }
      catch (ClientProtocolException e)
      {
        Log.e(AdFlakeUtil.ADFLAKE, "Caught ClientProtocolException in PingUrlRunnable", e);
      }
      catch (IOException e)
      {
        Log.e(AdFlakeUtil.ADFLAKE, "Caught IOException in PingUrlRunnable", e);
      }
    }
  }

  /**
   * Adapter did fail to receive ad with error. This method should be invoked
   * by adapter when an error occured during the retrieval of a remote ad.
   * 
   * @param adapter
   *            the adapter
   * @param string
   *            the string
   */
  public void adapterDidFailToReceiveAdWithError(AdFlakeAdapter adapter, String string)
  {
    this.rollover();

    Log.e(AdFlakeUtil.ADFLAKE, "ERROR: " + adapter.getRation().name + ": " + string);
  }

  /**
   * Adapter did receive ad. This method should be invoked by adapter when a
   * remote ad has been fetched successfully and the specified view is ready
   * to be displayed in the AdWhirlLayout.
   * 
   * @param adapter
   *            the adapter
   * @param view
   *            the view
   */
  public void adapterDidReceiveAd(AdFlakeAdapter adapter, ViewGroup view)
  {
    this.adFlakeManager.resetRollover();
    this.handler.post(new PushAdViewRunnable(this, view));
    this.rotateThreadedDelayed();
  }

  public void prepareVideoAdapters()
  {
    this.adFlakeManager.prepareVideoAdaptersForLayout(this);
  }

  private void requestVideoAdAndPresent(boolean presentVideoAd)
  {
    if (!adFlakeManager.videoAdsAvailable)
    {
      Log.d(AdFlakeUtil.ADFLAKE, "video ads are not available");
      this.adFlakeInterface.adFlakeDidFailToRequestVideoAd(this);
      return;
    }
    if (_usedVideoRations != null)
    {
      // this means that an interstitial request is already active
      Log.d(AdFlakeUtil.ADFLAKE, "interstitial request already active for layout");
      this.adFlakeInterface.adFlakeDidFailToRequestVideoAd(this);
      return;
    }
    if (_videoAdLoaded)
    {
      if (presentVideoAd)
      {
        presentLoadedVideoAd();
        return;
      }
      Log.e(AdFlakeUtil.ADFLAKE, "VIDEO ERROR: video already loaded");
      this.adFlakeInterface.adFlakeDidFailToRequestVideoAd(this);
      return;
    }

    _autoPresentVideoAd = presentVideoAd;
    _usedVideoRations = new ArrayList<Ration>();

    tryRequestNextVideoAd();
  }

  public void requestVideoAd()
  {
    requestVideoAdAndPresent(false);
  }

  public void requestAndPresentVideoAd()
  {
    requestVideoAdAndPresent(true);
  }

  private void didFailActiveVideoAdRequest()
  {
    this.adFlakeInterface.adFlakeDidFailToRequestVideoAd(this);
    _usedVideoRations = null;
    _autoPresentVideoAd = false;
  }

  private void tryRequestNextVideoAd()
  {
    if (_usedVideoRations == null)
    {
      Log.d(AdFlakeUtil.ADFLAKE, "no request active");
      this.adFlakeInterface.adFlakeDidFailToRequestVideoAd(this);
      return;
    }
    if (_usedVideoRations.size() == this.adFlakeManager.getVideoRationCount())
    {
      Log.d(AdFlakeUtil.ADFLAKE, "no video ads left to try");
      didFailActiveVideoAdRequest();
      return;
    }
    if (_videoAdLoaded)
    {
      Log.e(AdFlakeUtil.ADFLAKE, "VIDEO ERROR: video already loaded");
      didFailActiveVideoAdRequest();
      return;
    }

    Ration videoRation = this.adFlakeManager.getNextDartedVideoRation(_usedVideoRations);

    if (videoRation == null)
    {
      Log.d(AdFlakeUtil.ADFLAKE, "video ads are not available");
      didFailActiveVideoAdRequest();
      return;
    }

    if (_currentVideoAdapter != null && _currentVideoAdapter.getRation() == videoRation)
    {
      Log.d(AdFlakeUtil.ADFLAKE, "already played network, increasing chance for other networks");
      // increase chance of using another network's ad
      videoRation = this.adFlakeManager.getNextDartedVideoRation(_usedVideoRations);
    }

    _usedVideoRations.add(videoRation);

    String rationInfo = String.format("Showing ad:\n\tnid: %s\n\tname: %s\n\ttype: %d\n\tkey: %s\n\tkey2: %s", videoRation.nid, videoRation.name, videoRation.type, videoRation.key,
        videoRation.key2);
    Log.d(AdFlakeUtil.ADFLAKE, rationInfo);

    try
    {
      // Tell the previous adapter that its view will be destroyed.
      if (this._previousVideoAdapter != null)
      {
        this._previousVideoAdapter.willDestroy();
      }
      this._previousVideoAdapter = this._currentAdapter;
      this._currentVideoAdapter = AdFlakeAdapter.getAdapterForRation(this, videoRation, false);
      this._currentVideoAdapter.handle();
    }
    catch (Throwable t)
    {
      Log.w(AdFlakeUtil.ADFLAKE, "Caught an exception in adapter:", t);

      tryRequestNextVideoAd();
      return;
    }
  }

  /**
   * @param adapter
   * @param string
   */
  public void adapterDidFailToReceiveVideoAdWithError(AdFlakeAdapter adapter, String string)
  {
    Log.e(AdFlakeUtil.ADFLAKE, "VIDEOAD ERROR: " + adapter.getRation().name + ": " + string);
    tryRequestNextVideoAd();
  }

  /**
   * 
   * @return
   */
  public boolean isVideoAdLoaded()
  {
    return _videoAdLoaded;
  }

  /**
   * 
   */
  public void presentLoadedVideoAd()
  {
    if (!_videoAdLoaded || this._currentVideoAdapter == null)
    {
      if (_autoPresentVideoAd)
      {
        Log.e(AdFlakeUtil.ADFLAKE, "VIDEOAD ERROR: load and present failed");
        didFailActiveVideoAdRequest();
      }
      Log.e(AdFlakeUtil.ADFLAKE, "VIDEOAD ERROR: No video loaded");
      return;
    }

    if (this.adFlakeInterface != null)
    {
      this.adFlakeInterface.adFlakeWillPresentVideoAdModal(this);
      this.adFlakeInterface.adFlakeWillPresentFullScreenModal(this);
    }

    sendImpressionToMetricServerForRation(_currentVideoAdapter.getRation());

    _currentVideoAdapter.playLoadedVideoAd();

    _videoAdLoaded = false;
    _autoPresentVideoAd = false;
  }

  /**
   * 
   * @param adapter
   */
  public void adapterDidReceiveVideoAd(AdFlakeAdapter adapter)
  {
    _usedVideoRations = null;
    _videoAdLoaded = true;

    if (this.adFlakeInterface != null)
    {
      this.adFlakeInterface.adFlakeDidLoadVideoAd(this);
    }

    if (_autoPresentVideoAd)
    {
      presentLoadedVideoAd();
    }
  }

  /**
   * 
   * @param adapter
   */
  public void adapterDidFinishVideoAd(AdFlakeAdapter adapter, boolean userDidWatchEntireVideo)
  {
    if (this.adFlakeInterface != null)
    {
      this.adFlakeInterface.adFlakeDidPresentFullScreenModal(this);

      if (userDidWatchEntireVideo)
        this.adFlakeInterface.adFlakeUserDidWatchEntireVideo(this);
    }

    _videoAdLoaded = false;
  }

  /**
   * 
   * @return
   */
  public Ration getCurrentVideoRation()
  {
    if (_currentVideoAdapter == null)
      return null;

    return _currentVideoAdapter.getRation();
  }

  private String _adFlakeKey;

  /** Added so we can tell the previous adapter that it is being destroyed. */
  private AdFlakeAdapter _previousAdapter;
  private AdFlakeAdapter _currentAdapter;

  private AdFlakeAdapter _previousVideoAdapter;
  private AdFlakeAdapter _currentVideoAdapter;
  private List<Ration> _usedVideoRations;
  private boolean _autoPresentVideoAd;
  private boolean _videoAdLoaded;

  private boolean _hasWindow;
  private boolean _isScheduled;

  private int _maximumWidth;

  private int _maximumHeight;
}




Java Source Code List

com.adflake.AdFlakeLayout.java
com.adflake.AdFlakeManager.java
com.adflake.AdFlakeTargeting.java
com.adflake.adapters.AdColonyVideoAdsAdapter.java
com.adflake.adapters.AdFlakeAdapter.java
com.adflake.adapters.AmazonAdsAdapter.java
com.adflake.adapters.AppBrainAppLiftAdapter.java
com.adflake.adapters.BeachfrontVideoAdsAdapter.java
com.adflake.adapters.CustomAdapter.java
com.adflake.adapters.EventAdapter.java
com.adflake.adapters.GenericAdapter.java
com.adflake.adapters.GoogleAdMobAdsAdapter.java
com.adflake.adapters.GoogleAdMobVideoAdsAdapter.java
com.adflake.adapters.GreystripeAdapter.java
com.adflake.adapters.InMobiAdapter.java
com.adflake.adapters.JumptapAdapter.java
com.adflake.adapters.KomliMobileAdAdapter.java
com.adflake.adapters.LeadBoltAdapter.java
com.adflake.adapters.MdotMAdapter.java
com.adflake.adapters.MillennialAdapter.java
com.adflake.adapters.MobClixAdapter.java
com.adflake.adapters.MobFoxAdapter.java
com.adflake.adapters.TodacellAdapter.java
com.adflake.obj.Custom.java
com.adflake.obj.Extra.java
com.adflake.obj.Ration.java
com.adflake.sampleapp.SampleActivity.java
com.adflake.util.AdFlakeUtil.java