/**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* You are hereby granted a non-exclusive, worldwide, royalty-free license to use,
* copy, modify, and distribute this software in source code or binary form for use
* in connection with the web services and APIs provided by Facebook.
*
* As with any software that integrates with the Facebook platform, your use of
* this software is subject to the Facebook Developer Principles and Policies
* [http://developers.facebook.com/policy/]. This copyright notice shall be
* included in all copies or substantial portions of the software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package com.facebook.internal;
import android.Manifest;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Looper;
import android.util.Log;
import com.facebook.CustomTabActivity;
import com.facebook.FacebookActivity;
import com.facebook.FacebookException;
import com.facebook.FacebookSdk;
import com.facebook.FacebookSdkNotInitializedException;
import java.util.Collection;
import java.util.List;
/**
* 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 final class Validate {
private static final String TAG = Validate.class.getName();
private static final String NO_INTERNET_PERMISSION_REASON =
"No internet permissions granted for the app, please add " +
"<uses-permission android:name=\"android.permission.INTERNET\" /> " +
"to your AndroidManifest.xml.";
private static final String FACEBOOK_ACTIVITY_NOT_FOUND_REASON =
"FacebookActivity is not declared in the AndroidManifest.xml, please add " +
"com.facebook.FacebookActivity to your AndroidManifest.xml file. See " +
"https://developers.facebook.com/docs/android/getting-started for more info.";
private static final String CUSTOM_TAB_REDIRECT_ACTIVITY_NOT_FOUND_REASON =
"FacebookActivity is declared incorrectly in the AndroidManifest.xml, please " +
"add com.facebook.FacebookActivity to your AndroidManifest.xml file. " +
"See https://developers.facebook.com/docs/android/getting-started for more info.";
private static final String CONTENT_PROVIDER_NOT_FOUND_REASON =
"A ContentProvider for this app was not set up in the AndroidManifest.xml, please " +
"add %s as a provider to your AndroidManifest.xml file. See " +
"https://developers.facebook.com/docs/sharing/android for more info.";
private static final String CONTENT_PROVIDER_BASE = "com.facebook.app.FacebookContentProvider";
public static void notNull(Object arg, String name) {
if (arg == null) {
throw new NullPointerException("Argument '" + name + "' cannot be null");
}
}
public static <T> void notEmpty(Collection<T> container, String name) {
if (container.isEmpty()) {
throw new IllegalArgumentException("Container '" + name + "' cannot be empty");
}
}
public static <T> void containsNoNulls(Collection<T> container, String name) {
Validate.notNull(container, name);
for (T item : container) {
if (item == null) {
throw new NullPointerException("Container '" + name +
"' cannot contain null values");
}
}
}
public static void containsNoNullOrEmpty(Collection<String> container, String name) {
Validate.notNull(container, name);
for (String item : container) {
if (item == null) {
throw new NullPointerException("Container '" + name +
"' cannot contain null values");
}
if (item.length() == 0) {
throw new IllegalArgumentException("Container '" + name +
"' cannot contain empty values");
}
}
}
public static <T> void notEmptyAndContainsNoNulls(Collection<T> container, String name) {
Validate.containsNoNulls(container, name);
Validate.notEmpty(container, name);
}
public static void runningOnUiThread() {
if (!Looper.getMainLooper().equals(Looper.myLooper())) {
throw new FacebookException("This method should be called from the UI thread");
}
}
public static void notNullOrEmpty(String arg, String name) {
if (Utility.isNullOrEmpty(arg)) {
throw new IllegalArgumentException("Argument '" + name + "' cannot be null or empty");
}
}
public static void oneOf(Object arg, String name, Object... values) {
for (Object value : values) {
if (value != null) {
if (value.equals(arg)) {
return;
}
} else {
if (arg == null) {
return;
}
}
}
throw new IllegalArgumentException("Argument '" + name +
"' was not one of the allowed values");
}
public static void sdkInitialized() {
if (!FacebookSdk.isInitialized()) {
throw new FacebookSdkNotInitializedException(
"The SDK has not been initialized, make sure to call " +
"FacebookSdk.sdkInitialize() first.");
}
}
public static String hasAppID() {
String id = FacebookSdk.getApplicationId();
if (id == null) {
throw new IllegalStateException("No App ID found, please set the App ID.");
}
return id;
}
public static String hasClientToken() {
String token = FacebookSdk.getClientToken();
if (token == null) {
throw new IllegalStateException("No Client Token found, please set the Client Token.");
}
return token;
}
public static void hasInternetPermissions(Context context) {
Validate.hasInternetPermissions(context, true);
}
public static void hasInternetPermissions(Context context, boolean shouldThrow) {
Validate.notNull(context, "context");
if (context.checkCallingOrSelfPermission(Manifest.permission.INTERNET) ==
PackageManager.PERMISSION_DENIED) {
if (shouldThrow) {
throw new IllegalStateException(NO_INTERNET_PERMISSION_REASON);
} else {
Log.w(TAG, NO_INTERNET_PERMISSION_REASON);
}
}
}
public static boolean hasWiFiPermission(Context context) {
return hasPermission(context, Manifest.permission.ACCESS_WIFI_STATE);
}
public static boolean hasChangeWifiStatePermission(Context context) {
return hasPermission(context, Manifest.permission.CHANGE_WIFI_STATE);
}
public static boolean hasLocationPermission(Context context) {
return hasPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION)
|| hasPermission(context, Manifest.permission.ACCESS_FINE_LOCATION);
}
public static boolean hasBluetoothPermission(Context context) {
return hasPermission(context, Manifest.permission.BLUETOOTH)
&& hasPermission(context, Manifest.permission.BLUETOOTH_ADMIN);
}
public static boolean hasPermission(Context context, String permission) {
return context.checkCallingOrSelfPermission(permission) ==
PackageManager.PERMISSION_GRANTED;
}
public static void hasFacebookActivity(Context context) {
Validate.hasFacebookActivity(context, true);
}
@SuppressWarnings("WrongConstant")
public static void hasFacebookActivity(Context context, boolean shouldThrow) {
Validate.notNull(context, "context");
PackageManager pm = context.getPackageManager();
ActivityInfo activityInfo = null;
if (pm != null) {
ComponentName componentName =
new ComponentName(context, FacebookActivity.class);
try {
activityInfo = pm.getActivityInfo(componentName, PackageManager.GET_ACTIVITIES);
} catch (PackageManager.NameNotFoundException e) {
// ignore
}
}
if (activityInfo == null) {
if (shouldThrow) {
throw new IllegalStateException(FACEBOOK_ACTIVITY_NOT_FOUND_REASON);
} else {
Log.w(TAG, FACEBOOK_ACTIVITY_NOT_FOUND_REASON);
}
}
}
public static void checkCustomTabRedirectActivity(Context context) {
Validate.checkCustomTabRedirectActivity(context, true);
}
public static void checkCustomTabRedirectActivity(Context context, boolean shouldThrow) {
if (!hasCustomTabRedirectActivity(context)) {
if (shouldThrow) {
throw new IllegalStateException(CUSTOM_TAB_REDIRECT_ACTIVITY_NOT_FOUND_REASON);
} else {
Log.w(TAG, CUSTOM_TAB_REDIRECT_ACTIVITY_NOT_FOUND_REASON);
}
}
}
public static boolean hasCustomTabRedirectActivity(Context context) {
Validate.notNull(context, "context");
PackageManager pm = context.getPackageManager();
List<ResolveInfo> infos = null;
if (pm != null) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.addCategory(Intent.CATEGORY_BROWSABLE);
intent.setData(Uri.parse("fb" + FacebookSdk.getApplicationId() + "://authorize"));
infos = pm.queryIntentActivities(intent, PackageManager.GET_RESOLVED_FILTER);
}
boolean hasActivity = false;
if (infos != null) {
for (ResolveInfo info : infos) {
ActivityInfo activityInfo = info.activityInfo;
if (activityInfo.name.equals(CustomTabActivity.class.getName())) {
hasActivity = true;
} else {
// another application is listening for this url scheme, don't open
// Custom Tab for security reasons
return false;
}
}
}
return hasActivity;
}
public static void hasContentProvider(Context context) {
Validate.notNull(context, "context");
String appId = Validate.hasAppID();
PackageManager pm = context.getPackageManager();
if (pm != null) {
String providerName = CONTENT_PROVIDER_BASE + appId;
if (pm.resolveContentProvider(providerName, 0) == null) {
throw new IllegalStateException(
String.format(CONTENT_PROVIDER_NOT_FOUND_REASON, providerName));
}
}
}
}