Blame | Last modification | View Log | RSS feed
/*** Copyright 2010-present Facebook.** 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.facebook.internal;import android.content.Context;import android.database.Cursor;import android.net.Uri;import android.os.Looper;import android.util.Log;import com.facebook.FacebookException;import java.lang.reflect.Method;/*** com.facebook.internal is solely for the use of other packages within the Facebook SDK for Android. Use of* any of the classes in this package is unsupported, and they may be modified or removed without warning at* any time.*/public class AttributionIdentifiers {private static final String TAG = AttributionIdentifiers.class.getCanonicalName();private static final Uri ATTRIBUTION_ID_CONTENT_URI =Uri.parse("content://com.facebook.katana.provider.AttributionIdProvider");private static final String ATTRIBUTION_ID_COLUMN_NAME = "aid";private static final String ANDROID_ID_COLUMN_NAME = "androidid";private static final String LIMIT_TRACKING_COLUMN_NAME = "limit_tracking";// com.google.android.gms.common.ConnectionResult.SUCCESSprivate static final int CONNECTION_RESULT_SUCCESS = 0;private static final long IDENTIFIER_REFRESH_INTERVAL_MILLIS = 3600 * 1000;private String attributionId;private String androidAdvertiserId;private boolean limitTracking;private long fetchTime;private static AttributionIdentifiers recentlyFetchedIdentifiers;private static AttributionIdentifiers getAndroidId(Context context) {AttributionIdentifiers identifiers = new AttributionIdentifiers();try {// We can't call getAdvertisingIdInfo on the main thread or the app will potentially// freeze, if this is the case throw:if (Looper.myLooper() == Looper.getMainLooper()) {throw new FacebookException("getAndroidId cannot be called on the main thread.");}Method isGooglePlayServicesAvailable = Utility.getMethodQuietly("com.google.android.gms.common.GooglePlayServicesUtil","isGooglePlayServicesAvailable",Context.class);if (isGooglePlayServicesAvailable == null) {return identifiers;}Object connectionResult = Utility.invokeMethodQuietly(null, isGooglePlayServicesAvailable, context);if (!(connectionResult instanceof Integer) || (Integer) connectionResult != CONNECTION_RESULT_SUCCESS) {return identifiers;}Method getAdvertisingIdInfo = Utility.getMethodQuietly("com.google.android.gms.ads.identifier.AdvertisingIdClient","getAdvertisingIdInfo",Context.class);if (getAdvertisingIdInfo == null) {return identifiers;}Object advertisingInfo = Utility.invokeMethodQuietly(null, getAdvertisingIdInfo, context);if (advertisingInfo == null) {return identifiers;}Method getId = Utility.getMethodQuietly(advertisingInfo.getClass(), "getId");Method isLimitAdTrackingEnabled = Utility.getMethodQuietly(advertisingInfo.getClass(), "isLimitAdTrackingEnabled");if (getId == null || isLimitAdTrackingEnabled == null) {return identifiers;}identifiers.androidAdvertiserId = (String) Utility.invokeMethodQuietly(advertisingInfo, getId);identifiers.limitTracking = (Boolean) Utility.invokeMethodQuietly(advertisingInfo, isLimitAdTrackingEnabled);} catch (Exception e) {Utility.logd("android_id", e);}return identifiers;}public static AttributionIdentifiers getAttributionIdentifiers(Context context) {if (recentlyFetchedIdentifiers != null &&System.currentTimeMillis() - recentlyFetchedIdentifiers.fetchTime < IDENTIFIER_REFRESH_INTERVAL_MILLIS) {return recentlyFetchedIdentifiers;}AttributionIdentifiers identifiers = getAndroidId(context);Cursor c = null;try {String [] projection = {ATTRIBUTION_ID_COLUMN_NAME, ANDROID_ID_COLUMN_NAME, LIMIT_TRACKING_COLUMN_NAME};c = context.getContentResolver().query(ATTRIBUTION_ID_CONTENT_URI, projection, null, null, null);if (c == null || !c.moveToFirst()) {return identifiers;}int attributionColumnIndex = c.getColumnIndex(ATTRIBUTION_ID_COLUMN_NAME);int androidIdColumnIndex = c.getColumnIndex(ANDROID_ID_COLUMN_NAME);int limitTrackingColumnIndex = c.getColumnIndex(LIMIT_TRACKING_COLUMN_NAME);identifiers.attributionId = c.getString(attributionColumnIndex);// if we failed to call Google's APIs directly (due to improper integration by the client), it may be// possible for the local facebook application to relay it to us.if (androidIdColumnIndex > 0 && limitTrackingColumnIndex > 0 && identifiers.getAndroidAdvertiserId() == null) {identifiers.androidAdvertiserId = c.getString(androidIdColumnIndex);identifiers.limitTracking = Boolean.parseBoolean(c.getString(limitTrackingColumnIndex));}} catch (Exception e) {Log.d(TAG, "Caught unexpected exception in getAttributionId(): " + e.toString());return null;} finally {if (c != null) {c.close();}}identifiers.fetchTime = System.currentTimeMillis();recentlyFetchedIdentifiers = identifiers;return identifiers;}public String getAttributionId() {return attributionId;}public String getAndroidAdvertiserId() {return androidAdvertiserId;}public boolean isTrackingLimited() {return limitTracking;}}