Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

lightning and facebook api migration to android library projects

  • Loading branch information...
commit 49197aa076ad7fdabe15c851239af073563d7697 1 parent aa8e975
@nazarov-andrey nazarov-andrey authored
Showing with 181 additions and 1,926 deletions.
  1. +3 −0  .gitignore
  2. +15 −0 src/android/java/AndroidManifest.xml
  3. +17 −0 src/android/java/ant.properties
  4. +92 −0 src/android/java/build.xml
  5. +0 −316 src/android/java/com/facebook/android/AsyncFacebookRunner.java
  6. +0 −51 src/android/java/com/facebook/android/DialogError.java
  7. +0 −980 src/android/java/com/facebook/android/Facebook.java
  8. +0 −50 src/android/java/com/facebook/android/FacebookError.java
  9. +0 −198 src/android/java/com/facebook/android/FbDialog.java
  10. +0 −329 src/android/java/com/facebook/android/Util.java
  11. +20 −0 src/android/java/proguard-project.txt
  12. +16 −0 src/android/java/project.properties
  13. +13 −0 src/android/java/res/layout/main.xml
  14. +4 −0 src/android/java/res/values/strings.xml
  15. 0  src/android/java/{ → src}/com/android/vending/billing/IMarketBillingService.aidl
  16. +1 −1  src/android/java/{com/facebook → src/ru/redspell/lightning}/AndroidFB.java
  17. 0  src/android/java/{ → src}/ru/redspell/lightning/LightHttpLoader.java
  18. 0  src/android/java/{ → src}/ru/redspell/lightning/LightRenderer.java
  19. 0  src/android/java/{ → src}/ru/redspell/lightning/LightTexture.java
  20. +0 −1  src/android/java/{ → src}/ru/redspell/lightning/LightView.java
  21. 0  src/android/java/{ → src}/ru/redspell/lightning/ResourceParams.java
  22. 0  src/android/java/{ → src}/ru/redspell/lightning/UrlReq.java
  23. 0  src/android/java/{ → src}/ru/redspell/lightning/payments/BillingReceiver.java
  24. 0  src/android/java/{ → src}/ru/redspell/lightning/payments/BillingService.java
  25. 0  src/android/java/{ → src}/ru/redspell/lightning/payments/Consts.java
  26. 0  src/android/java/{ → src}/ru/redspell/lightning/payments/ResponseHandler.java
  27. 0  src/android/java/{ → src}/ru/redspell/lightning/payments/Security.java
  28. 0  src/android/java/{ → src}/ru/redspell/lightning/payments/utils/Base64.java
  29. 0  src/android/java/{ → src}/ru/redspell/lightning/payments/utils/Base64DecoderException.java
View
3  .gitignore
@@ -14,3 +14,6 @@
local.properties
myconfig.ios
myconfig.macos
+gen
+bin
+gen
View
15 src/android/java/AndroidManifest.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="ru.redspell.lightning"
+ android:versionCode="1"
+ android:versionName="1.0">
+ <application android:label="@string/app_name" >
+ <activity android:name="ACTIVITY_ENTRY_NAME"
+ android:label="@string/app_name">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
View
17 src/android/java/ant.properties
@@ -0,0 +1,17 @@
+# This file is used to override default values used by the Ant build system.
+#
+# This file must be checked into Version Control Systems, as it is
+# integral to the build system of your project.
+
+# This file is only used by the Ant script.
+
+# You can use this to override default values such as
+# 'source.dir' for the location of your java source folder and
+# 'out.dir' for the location of your output folder.
+
+# You can also use it define how the release builds are signed by declaring
+# the following properties:
+# 'key.store' for the location of your keystore and
+# 'key.alias' for the name of the key to use.
+# The password will be asked during the build when you use the 'release' target.
+
View
92 src/android/java/build.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="lightning" default="help">
+
+ <!-- The local.properties file is created and updated by the 'android' tool.
+ It contains the path to the SDK. It should *NOT* be checked into
+ Version Control Systems. -->
+ <property file="local.properties" />
+
+ <!-- The ant.properties file can be created by you. It is only edited by the
+ 'android' tool to add properties to it.
+ This is the place to change some Ant specific build properties.
+ Here are some properties you may want to change/update:
+
+ source.dir
+ The name of the source directory. Default is 'src'.
+ out.dir
+ The name of the output directory. Default is 'bin'.
+
+ For other overridable properties, look at the beginning of the rules
+ files in the SDK, at tools/ant/build.xml
+
+ Properties related to the SDK location or the project target should
+ be updated using the 'android' tool with the 'update' action.
+
+ This file is an integral part of the build system for your
+ application and should be checked into Version Control Systems.
+
+ -->
+ <property file="ant.properties" />
+
+ <!-- if sdk.dir was not set from one of the property file, then
+ get it from the ANDROID_HOME env var.
+ This must be done before we load project.properties since
+ the proguard config can use sdk.dir -->
+ <property environment="env" />
+ <condition property="sdk.dir" value="${env.ANDROID_HOME}">
+ <isset property="env.ANDROID_HOME" />
+ </condition>
+
+ <!-- The project.properties file is created and updated by the 'android'
+ tool, as well as ADT.
+
+ This contains project specific properties such as project target, and library
+ dependencies. Lower level build properties are stored in ant.properties
+ (or in .classpath for Eclipse projects).
+
+ This file is an integral part of the build system for your
+ application and should be checked into Version Control Systems. -->
+ <loadproperties srcFile="project.properties" />
+
+ <!-- quick check on sdk.dir -->
+ <fail
+ message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable."
+ unless="sdk.dir"
+ />
+
+ <!--
+ Import per project custom build rules if present at the root of the project.
+ This is the place to put custom intermediary targets such as:
+ -pre-build
+ -pre-compile
+ -post-compile (This is typically used for code obfuscation.
+ Compiled code location: ${out.classes.absolute.dir}
+ If this is not done in place, override ${out.dex.input.absolute.dir})
+ -post-package
+ -post-build
+ -pre-clean
+ -->
+ <import file="custom_rules.xml" optional="true" />
+
+ <!-- Import the actual build file.
+
+ To customize existing targets, there are two options:
+ - Customize only one target:
+ - copy/paste the target into this file, *before* the
+ <import> task.
+ - customize it to your needs.
+ - Customize the whole content of build.xml
+ - copy/paste the content of the rules files (minus the top node)
+ into this file, replacing the <import> task.
+ - customize to your needs.
+
+ ***********************
+ ****** IMPORTANT ******
+ ***********************
+ In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
+ in order to avoid having your file be overridden by tools such as "android update project"
+ -->
+ <!-- version-tag: 1 -->
+ <import file="${sdk.dir}/tools/ant/build.xml" />
+
+</project>
View
316 src/android/java/com/facebook/android/AsyncFacebookRunner.java
@@ -1,316 +0,0 @@
-/*
- * Copyright 2010 Facebook, Inc.
- *
- * 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.android;
-
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.net.MalformedURLException;
-
-import android.content.Context;
-import android.os.Bundle;
-
-/**
- * A sample implementation of asynchronous API requests. This class provides
- * the ability to execute API methods and have the call return immediately,
- * without blocking the calling thread. This is necessary when accessing the
- * API in the UI thread, for instance. The request response is returned to
- * the caller via a callback interface, which the developer must implement.
- *
- * This sample implementation simply spawns a new thread for each request,
- * and makes the API call immediately. This may work in many applications,
- * but more sophisticated users may re-implement this behavior using a thread
- * pool, a network thread, a request queue, or other mechanism. Advanced
- * functionality could be built, such as rate-limiting of requests, as per
- * a specific application's needs.
- *
- * @see RequestListener
- * The callback interface.
- *
- * @author Jim Brusstar (jimbru@fb.com),
- * Yariv Sadan (yariv@fb.com),
- * Luke Shepard (lshepard@fb.com)
- */
-public class AsyncFacebookRunner {
-
- Facebook fb;
-
- public AsyncFacebookRunner(Facebook fb) {
- this.fb = fb;
- }
-
- /**
- * Invalidate the current user session by removing the access token in
- * memory, clearing the browser cookies, and calling auth.expireSession
- * through the API. The application will be notified when logout is
- * complete via the callback interface.
- *
- * Note that this method is asynchronous and the callback will be invoked
- * in a background thread; operations that affect the UI will need to be
- * posted to the UI thread or an appropriate handler.
- *
- * @param context
- * The Android context in which the logout should be called: it
- * should be the same context in which the login occurred in
- * order to clear any stored cookies
- * @param listener
- * Callback interface to notify the application when the request
- * has completed.
- * @param state
- * An arbitrary object used to identify the request when it
- * returns to the callback. This has no effect on the request
- * itself.
- */
- public void logout(final Context context,
- final RequestListener listener,
- final Object state) {
- new Thread() {
- @Override public void run() {
- try {
- String response = fb.logout(context);
- if (response.length() == 0 || response.equals("false")){
- listener.onFacebookError(new FacebookError(
- "auth.expireSession failed"), state);
- return;
- }
- listener.onComplete(response, state);
- } catch (FileNotFoundException e) {
- listener.onFileNotFoundException(e, state);
- } catch (MalformedURLException e) {
- listener.onMalformedURLException(e, state);
- } catch (IOException e) {
- listener.onIOException(e, state);
- }
- }
- }.start();
- }
-
- public void logout(final Context context, final RequestListener listener) {
- logout(context, listener, /* state */ null);
- }
-
- /**
- * Make a request to Facebook's old (pre-graph) API with the given
- * parameters. One of the parameter keys must be "method" and its value
- * should be a valid REST server API method.
- *
- * See http://developers.facebook.com/docs/reference/rest/
- *
- * Note that this method is asynchronous and the callback will be invoked
- * in a background thread; operations that affect the UI will need to be
- * posted to the UI thread or an appropriate handler.
- *
- * Example:
- * <code>
- * Bundle parameters = new Bundle();
- * parameters.putString("method", "auth.expireSession", new Listener());
- * String response = request(parameters);
- * </code>
- *
- * @param parameters
- * Key-value pairs of parameters to the request. Refer to the
- * documentation: one of the parameters must be "method".
- * @param listener
- * Callback interface to notify the application when the request
- * has completed.
- * @param state
- * An arbitrary object used to identify the request when it
- * returns to the callback. This has no effect on the request
- * itself.
- */
- public void request(Bundle parameters,
- RequestListener listener,
- final Object state) {
- request(null, parameters, "GET", listener, state);
- }
-
- public void request(Bundle parameters, RequestListener listener) {
- request(null, parameters, "GET", listener, /* state */ null);
- }
-
- /**
- * Make a request to the Facebook Graph API without any parameters.
- *
- * See http://developers.facebook.com/docs/api
- *
- * Note that this method is asynchronous and the callback will be invoked
- * in a background thread; operations that affect the UI will need to be
- * posted to the UI thread or an appropriate handler.
- *
- * @param graphPath
- * Path to resource in the Facebook graph, e.g., to fetch data
- * about the currently logged authenticated user, provide "me",
- * which will fetch http://graph.facebook.com/me
- * @param listener
- * Callback interface to notify the application when the request
- * has completed.
- * @param state
- * An arbitrary object used to identify the request when it
- * returns to the callback. This has no effect on the request
- * itself.
- */
- public void request(String graphPath,
- RequestListener listener,
- final Object state) {
- request(graphPath, new Bundle(), "GET", listener, state);
- }
-
- public void request(String graphPath, RequestListener listener) {
- request(graphPath, new Bundle(), "GET", listener, /* state */ null);
- }
-
- /**
- * Make a request to the Facebook Graph API with the given string parameters
- * using an HTTP GET (default method).
- *
- * See http://developers.facebook.com/docs/api
- *
- * Note that this method is asynchronous and the callback will be invoked
- * in a background thread; operations that affect the UI will need to be
- * posted to the UI thread or an appropriate handler.
- *
- * @param graphPath
- * Path to resource in the Facebook graph, e.g., to fetch data
- * about the currently logged authenticated user, provide "me",
- * which will fetch http://graph.facebook.com/me
- * @param parameters
- * key-value string parameters, e.g. the path "search" with
- * parameters "q" : "facebook" would produce a query for the
- * following graph resource:
- * https://graph.facebook.com/search?q=facebook
- * @param listener
- * Callback interface to notify the application when the request
- * has completed.
- * @param state
- * An arbitrary object used to identify the request when it
- * returns to the callback. This has no effect on the request
- * itself.
- */
- public void request(String graphPath,
- Bundle parameters,
- RequestListener listener,
- final Object state) {
- request(graphPath, parameters, "GET", listener, state);
- }
-
- public void request(String graphPath,
- Bundle parameters,
- RequestListener listener) {
- request(graphPath, parameters, "GET", listener, /* state */ null);
- }
-
- /**
- * Make a request to the Facebook Graph API with the given HTTP method and
- * string parameters. Note that binary data parameters (e.g. pictures) are
- * not yet supported by this helper function.
- *
- * See http://developers.facebook.com/docs/api
- *
- * Note that this method is asynchronous and the callback will be invoked
- * in a background thread; operations that affect the UI will need to be
- * posted to the UI thread or an appropriate handler.
- *
- * @param graphPath
- * Path to resource in the Facebook graph, e.g., to fetch data
- * about the currently logged authenticated user, provide "me",
- * which will fetch http://graph.facebook.com/me
- * @param parameters
- * key-value string parameters, e.g. the path "search" with
- * parameters {"q" : "facebook"} would produce a query for the
- * following graph resource:
- * https://graph.facebook.com/search?q=facebook
- * @param httpMethod
- * http verb, e.g. "POST", "DELETE"
- * @param listener
- * Callback interface to notify the application when the request
- * has completed.
- * @param state
- * An arbitrary object used to identify the request when it
- * returns to the callback. This has no effect on the request
- * itself.
- */
- public void request(final String graphPath,
- final Bundle parameters,
- final String httpMethod,
- final RequestListener listener,
- final Object state) {
- new Thread() {
- @Override public void run() {
- try {
- String resp = fb.request(graphPath, parameters, httpMethod);
- listener.onComplete(resp, state);
- } catch (FileNotFoundException e) {
- listener.onFileNotFoundException(e, state);
- } catch (MalformedURLException e) {
- listener.onMalformedURLException(e, state);
- } catch (IOException e) {
- listener.onIOException(e, state);
- }
- }
- }.start();
- }
-
- /**
- * Callback interface for API requests.
- *
- * Each method includes a 'state' parameter that identifies the calling
- * request. It will be set to the value passed when originally calling the
- * request method, or null if none was passed.
- */
- public static interface RequestListener {
-
- /**
- * Called when a request completes with the given response.
- *
- * Executed by a background thread: do not update the UI in this method.
- */
- public void onComplete(String response, Object state);
-
- /**
- * Called when a request has a network or request error.
- *
- * Executed by a background thread: do not update the UI in this method.
- */
- public void onIOException(IOException e, Object state);
-
- /**
- * Called when a request fails because the requested resource is
- * invalid or does not exist.
- *
- * Executed by a background thread: do not update the UI in this method.
- */
- public void onFileNotFoundException(FileNotFoundException e,
- Object state);
-
- /**
- * Called if an invalid graph path is provided (which may result in a
- * malformed URL).
- *
- * Executed by a background thread: do not update the UI in this method.
- */
- public void onMalformedURLException(MalformedURLException e,
- Object state);
-
- /**
- * Called when the server-side Facebook method fails.
- *
- * Executed by a background thread: do not update the UI in this method.
- */
- public void onFacebookError(FacebookError e, Object state);
-
- }
-
-}
View
51 src/android/java/com/facebook/android/DialogError.java
@@ -1,51 +0,0 @@
-/*
- * Copyright 2010 Facebook, Inc.
- *
- * 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.android;
-
-/**
- * Encapsulation of Dialog Error.
- *
- * @author ssoneff@facebook.com
- */
-public class DialogError extends Throwable {
-
- private static final long serialVersionUID = 1L;
-
- /**
- * The ErrorCode received by the WebView: see
- * http://developer.android.com/reference/android/webkit/WebViewClient.html
- */
- private int mErrorCode;
-
- /** The URL that the dialog was trying to load */
- private String mFailingUrl;
-
- public DialogError(String message, int errorCode, String failingUrl) {
- super(message);
- mErrorCode = errorCode;
- mFailingUrl = failingUrl;
- }
-
- int getErrorCode() {
- return mErrorCode;
- }
-
- String getFailingUrl() {
- return mFailingUrl;
- }
-
-}
View
980 src/android/java/com/facebook/android/Facebook.java
@@ -1,980 +0,0 @@
-/*
- * Copyright 2010 Facebook, Inc.
- *
- * 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.android;
-
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.net.MalformedURLException;
-
-import android.Manifest;
-import android.app.Activity;
-import android.content.ActivityNotFoundException;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.ResolveInfo;
-import android.content.pm.Signature;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.Messenger;
-import android.os.RemoteException;
-import android.text.TextUtils;
-import android.webkit.CookieSyncManager;
-
-/**
- * Main Facebook object for interacting with the Facebook developer API.
- * Provides methods to log in and log out a user, make requests using the REST
- * and Graph APIs, and start user interface interactions with the API (such as
- * pop-ups promoting for credentials, permissions, stream posts, etc.)
- *
- * @author Jim Brusstar (jimbru@facebook.com),
- * Yariv Sadan (yariv@facebook.com),
- * Luke Shepard (lshepard@facebook.com)
- */
-public class Facebook {
-
- // Strings used in the authorization flow
- public static final String REDIRECT_URI = "fbconnect://success";
- public static final String CANCEL_URI = "fbconnect://cancel";
- public static final String TOKEN = "access_token";
- public static final String EXPIRES = "expires_in";
- public static final String SINGLE_SIGN_ON_DISABLED = "service_disabled";
-
- public static final int FORCE_DIALOG_AUTH = -1;
-
- private static final String LOGIN = "oauth";
-
- // Used as default activityCode by authorize(). See authorize() below.
- private static final int DEFAULT_AUTH_ACTIVITY_CODE = 32665;
-
- // Facebook server endpoints: may be modified in a subclass for testing
- protected static String DIALOG_BASE_URL =
- "https://m.facebook.com/dialog/";
- protected static String GRAPH_BASE_URL =
- "https://graph.facebook.com/";
- protected static String RESTSERVER_URL =
- "https://api.facebook.com/restserver.php";
-
- private String mAccessToken = null;
- private long mLastAccessUpdate = 0;
- private long mAccessExpires = 0;
- private String mAppId;
-
- private Activity mAuthActivity;
- private String[] mAuthPermissions;
- private int mAuthActivityCode;
- private DialogListener mAuthDialogListener;
-
- // If the last time we extended the access token was more than 24 hours ago
- // we try to refresh the access token again.
- final private long REFRESH_TOKEN_BARRIER = 24L * 60L * 60L * 1000L;
-
- /**
- * Constructor for Facebook object.
- *
- * @param appId
- * Your Facebook application ID. Found at
- * www.facebook.com/developers/apps.php.
- */
- public Facebook(String appId) {
- if (appId == null) {
- throw new IllegalArgumentException(
- "You must specify your application ID when instantiating " +
- "a Facebook object. See README for details.");
- }
- mAppId = appId;
- }
-
- /**
- * Default authorize method. Grants only basic permissions.
- *
- * See authorize() below for @params.
- */
- public void authorize(Activity activity, final DialogListener listener) {
- authorize(activity, new String[] {}, DEFAULT_AUTH_ACTIVITY_CODE,
- listener);
- }
-
- /**
- * Authorize method that grants custom permissions.
- *
- * See authorize() below for @params.
- */
- public void authorize(Activity activity, String[] permissions,
- final DialogListener listener) {
- authorize(activity, permissions, DEFAULT_AUTH_ACTIVITY_CODE, listener);
- }
-
- /**
- * Full authorize method.
- *
- * Starts either an Activity or a dialog which prompts the user to log in to
- * Facebook and grant the requested permissions to the given application.
- *
- * This method will, when possible, use Facebook's single sign-on for
- * Android to obtain an access token. This involves proxying a call through
- * the Facebook for Android stand-alone application, which will handle the
- * authentication flow, and return an OAuth access token for making API
- * calls.
- *
- * Because this process will not be available for all users, if single
- * sign-on is not possible, this method will automatically fall back to the
- * OAuth 2.0 User-Agent flow. In this flow, the user credentials are handled
- * by Facebook in an embedded WebView, not by the client application. As
- * such, the dialog makes a network request and renders HTML content rather
- * than a native UI. The access token is retrieved from a redirect to a
- * special URL that the WebView handles.
- *
- * Note that User credentials could be handled natively using the OAuth 2.0
- * Username and Password Flow, but this is not supported by this SDK.
- *
- * See http://developers.facebook.com/docs/authentication/ and
- * http://wiki.oauth.net/OAuth-2 for more details.
- *
- * Note that this method is asynchronous and the callback will be invoked in
- * the original calling thread (not in a background thread).
- *
- * Also note that requests may be made to the API without calling authorize
- * first, in which case only public information is returned.
- *
- * IMPORTANT: Note that single sign-on authentication will not function
- * correctly if you do not include a call to the authorizeCallback() method
- * in your onActivityResult() function! Please see below for more
- * information. single sign-on may be disabled by passing FORCE_DIALOG_AUTH
- * as the activityCode parameter in your call to authorize().
- *
- * @param activity
- * The Android activity in which we want to display the
- * authorization dialog.
- * @param applicationId
- * The Facebook application identifier e.g. "350685531728"
- * @param permissions
- * A list of permissions required for this application: e.g.
- * "read_stream", "publish_stream", "offline_access", etc. see
- * http://developers.facebook.com/docs/authentication/permissions
- * This parameter should not be null -- if you do not require any
- * permissions, then pass in an empty String array.
- * @param activityCode
- * Single sign-on requires an activity result to be called back
- * to the client application -- if you are waiting on other
- * activities to return data, pass a custom activity code here to
- * avoid collisions. If you would like to force the use of legacy
- * dialog-based authorization, pass FORCE_DIALOG_AUTH for this
- * parameter. Otherwise just omit this parameter and Facebook
- * will use a suitable default. See
- * http://developer.android.com/reference/android/
- * app/Activity.html for more information.
- * @param listener
- * Callback interface for notifying the calling application when
- * the authentication dialog has completed, failed, or been
- * canceled.
- */
- public void authorize(Activity activity, String[] permissions,
- int activityCode, final DialogListener listener) {
-
- boolean singleSignOnStarted = false;
-
- mAuthDialogListener = listener;
-
- // Prefer single sign-on, where available.
- if (activityCode >= 0) {
- singleSignOnStarted = startSingleSignOn(activity, mAppId,
- permissions, activityCode);
- }
- // Otherwise fall back to traditional dialog.
- if (!singleSignOnStarted) {
- startDialogAuth(activity, permissions);
- }
- }
-
- /**
- * Internal method to handle single sign-on backend for authorize().
- *
- * @param activity
- * The Android Activity that will parent the ProxyAuth Activity.
- * @param applicationId
- * The Facebook application identifier.
- * @param permissions
- * A list of permissions required for this application. If you do
- * not require any permissions, pass an empty String array.
- * @param activityCode
- * Activity code to uniquely identify the result Intent in the
- * callback.
- */
- private boolean startSingleSignOn(Activity activity, String applicationId,
- String[] permissions, int activityCode) {
- boolean didSucceed = true;
- Intent intent = new Intent();
-
- intent.setClassName("com.facebook.katana",
- "com.facebook.katana.ProxyAuth");
- intent.putExtra("client_id", applicationId);
- if (permissions.length > 0) {
- intent.putExtra("scope", TextUtils.join(",", permissions));
- }
-
- // Verify that the application whose package name is
- // com.facebook.katana.ProxyAuth
- // has the expected FB app signature.
- if (!validateActivityIntent(activity, intent)) {
- return false;
- }
-
- mAuthActivity = activity;
- mAuthPermissions = permissions;
- mAuthActivityCode = activityCode;
- try {
- activity.startActivityForResult(intent, activityCode);
- } catch (ActivityNotFoundException e) {
- didSucceed = false;
- }
-
- return didSucceed;
- }
-
- /**
- * Helper to validate an activity intent by resolving and checking the
- * provider's package signature.
- *
- * @param context
- * @param intent
- * @return true if the service intent resolution happens successfully and the
- * signatures match.
- */
- private boolean validateActivityIntent(Context context, Intent intent) {
- ResolveInfo resolveInfo =
- context.getPackageManager().resolveActivity(intent, 0);
- if (resolveInfo == null) {
- return false;
- }
-
- return validateAppSignatureForPackage(
- context,
- resolveInfo.activityInfo.packageName);
- }
-
-
- /**
- * Helper to validate a service intent by resolving and checking the
- * provider's package signature.
- *
- * @param context
- * @param intent
- * @return true if the service intent resolution happens successfully and the
- * signatures match.
- */
- private boolean validateServiceIntent(Context context, Intent intent) {
- ResolveInfo resolveInfo =
- context.getPackageManager().resolveService(intent, 0);
- if (resolveInfo == null) {
- return false;
- }
-
- return validateAppSignatureForPackage(
- context,
- resolveInfo.serviceInfo.packageName);
- }
-
- /**
- * Query the signature for the application that would be invoked by the
- * given intent and verify that it matches the FB application's signature.
- *
- * @param context
- * @param packageName
- * @return true if the app's signature matches the expected signature.
- */
- private boolean validateAppSignatureForPackage(Context context,
- String packageName) {
-
- PackageInfo packageInfo;
- try {
- packageInfo = context.getPackageManager().getPackageInfo(
- packageName, PackageManager.GET_SIGNATURES);
- } catch (NameNotFoundException e) {
- return false;
- }
-
- for (Signature signature : packageInfo.signatures) {
- if (signature.toCharsString().equals(FB_APP_SIGNATURE)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Internal method to handle dialog-based authentication backend for
- * authorize().
- *
- * @param activity
- * The Android Activity that will parent the auth dialog.
- * @param applicationId
- * The Facebook application identifier.
- * @param permissions
- * A list of permissions required for this application. If you do
- * not require any permissions, pass an empty String array.
- */
- private void startDialogAuth(Activity activity, String[] permissions) {
- Bundle params = new Bundle();
- if (permissions.length > 0) {
- params.putString("scope", TextUtils.join(",", permissions));
- }
- CookieSyncManager.createInstance(activity);
- dialog(activity, LOGIN, params, new DialogListener() {
-
- public void onComplete(Bundle values) {
- // ensure any cookies set by the dialog are saved
- CookieSyncManager.getInstance().sync();
- setAccessToken(values.getString(TOKEN));
- setAccessExpiresIn(values.getString(EXPIRES));
- if (isSessionValid()) {
- Util.logd("Facebook-authorize", "Login Success! access_token="
- + getAccessToken() + " expires="
- + getAccessExpires());
- mAuthDialogListener.onComplete(values);
- } else {
- mAuthDialogListener.onFacebookError(new FacebookError(
- "Failed to receive access token."));
- }
- }
-
- public void onError(DialogError error) {
- Util.logd("Facebook-authorize", "Login failed: " + error);
- mAuthDialogListener.onError(error);
- }
-
- public void onFacebookError(FacebookError error) {
- Util.logd("Facebook-authorize", "Login failed: " + error);
- mAuthDialogListener.onFacebookError(error);
- }
-
- public void onCancel() {
- Util.logd("Facebook-authorize", "Login canceled");
- mAuthDialogListener.onCancel();
- }
- });
- }
-
- /**
- * IMPORTANT: This method must be invoked at the top of the calling
- * activity's onActivityResult() function or Facebook authentication will
- * not function properly!
- *
- * If your calling activity does not currently implement onActivityResult(),
- * you must implement it and include a call to this method if you intend to
- * use the authorize() method in this SDK.
- *
- * For more information, see
- * http://developer.android.com/reference/android/app/
- * Activity.html#onActivityResult(int, int, android.content.Intent)
- */
- public void authorizeCallback(int requestCode, int resultCode, Intent data) {
- if (requestCode == mAuthActivityCode) {
-
- // Successfully redirected.
- if (resultCode == Activity.RESULT_OK) {
-
- // Check OAuth 2.0/2.10 error code.
- String error = data.getStringExtra("error");
- if (error == null) {
- error = data.getStringExtra("error_type");
- }
-
- // A Facebook error occurred.
- if (error != null) {
- if (error.equals(SINGLE_SIGN_ON_DISABLED)
- || error.equals("AndroidAuthKillSwitchException")) {
- Util.logd("Facebook-authorize", "Hosted auth currently "
- + "disabled. Retrying dialog auth...");
- startDialogAuth(mAuthActivity, mAuthPermissions);
- } else if (error.equals("access_denied")
- || error.equals("OAuthAccessDeniedException")) {
- Util.logd("Facebook-authorize", "Login canceled by user.");
- mAuthDialogListener.onCancel();
- } else {
- String description = data.getStringExtra("error_description");
- if (description != null) {
- error = error + ":" + description;
- }
- Util.logd("Facebook-authorize", "Login failed: " + error);
- mAuthDialogListener.onFacebookError(
- new FacebookError(error));
- }
-
- // No errors.
- } else {
- setAccessToken(data.getStringExtra(TOKEN));
- setAccessExpiresIn(data.getStringExtra(EXPIRES));
- if (isSessionValid()) {
- Util.logd("Facebook-authorize",
- "Login Success! access_token="
- + getAccessToken() + " expires="
- + getAccessExpires());
- mAuthDialogListener.onComplete(data.getExtras());
- } else {
- mAuthDialogListener.onFacebookError(new FacebookError(
- "Failed to receive access token."));
- }
- }
-
- // An error occurred before we could be redirected.
- } else if (resultCode == Activity.RESULT_CANCELED) {
-
- // An Android error occured.
- if (data != null) {
- Util.logd("Facebook-authorize",
- "Login failed: " + data.getStringExtra("error"));
- mAuthDialogListener.onError(
- new DialogError(
- data.getStringExtra("error"),
- data.getIntExtra("error_code", -1),
- data.getStringExtra("failing_url")));
-
- // User pressed the 'back' button.
- } else {
- Util.logd("Facebook-authorize", "Login canceled by user.");
- mAuthDialogListener.onCancel();
- }
- }
- }
- }
-
- /**
- * Refresh OAuth access token method. Binds to Facebook for Android
- * stand-alone application application to refresh the access token. This
- * method tries to connect to the Facebook App which will handle the
- * authentication flow, and return a new OAuth access token. This method
- * will automatically replace the old token with a new one. Note that this
- * method is asynchronous and the callback will be invoked in the original
- * calling thread (not in a background thread).
- *
- * @param context
- * The Android Context that will be used to bind to the Facebook
- * RefreshToken Service
- * @param serviceListener
- * Callback interface for notifying the calling application when
- * the refresh request has completed or failed (can be null). In
- * case of a success a new token can be found inside the result
- * Bundle under Facebook.ACCESS_TOKEN key.
- * @return true if the binding to the RefreshToken Service was created
- */
- public boolean extendAccessToken(Context context, ServiceListener serviceListener) {
- Intent intent = new Intent();
-
- intent.setClassName("com.facebook.katana",
- "com.facebook.katana.platform.TokenRefreshService");
-
- // Verify that the application whose package name is
- // com.facebook.katana
- // has the expected FB app signature.
- if (!validateServiceIntent(context, intent)) {
- return false;
- }
-
- return context.bindService(intent,
- new TokenRefreshServiceConnection(context, serviceListener),
- Context.BIND_AUTO_CREATE);
- }
-
- /**
- * Calls extendAccessToken if shouldExtendAccessToken returns true.
- *
- * @return the same value as extendAccessToken if the the token requires
- * refreshing, true otherwise
- */
- public boolean extendAccessTokenIfNeeded(Context context, ServiceListener serviceListener) {
- if (shouldExtendAccessToken()) {
- return extendAccessToken(context, serviceListener);
- }
- return true;
- }
-
- /**
- * Check if the access token requires refreshing.
- *
- * @return true if the last time a new token was obtained was over 24 hours ago.
- */
- public boolean shouldExtendAccessToken() {
- return isSessionValid() &&
- (System.currentTimeMillis() - mLastAccessUpdate >= REFRESH_TOKEN_BARRIER);
- }
-
- /**
- * Handles connection to the token refresh service (this service is a part
- * of Facebook App).
- */
- private class TokenRefreshServiceConnection implements ServiceConnection {
-
- final Messenger messageReceiver = new Messenger(new Handler() {
- @Override
- public void handleMessage(Message msg) {
- String token = msg.getData().getString(TOKEN);
- long expiresAt = msg.getData().getLong(EXPIRES) * 1000L;
-
- // To avoid confusion we should return the expiration time in
- // the same format as the getAccessExpires() function - that
- // is in milliseconds.
- Bundle resultBundle = (Bundle) msg.getData().clone();
- resultBundle.putLong(EXPIRES, expiresAt);
-
- if (token != null) {
- setAccessToken(token);
- setAccessExpires(expiresAt);
- if (serviceListener != null) {
- serviceListener.onComplete(resultBundle);
- }
- } else if (serviceListener != null) { // extract errors only if client wants them
- String error = msg.getData().getString("error");
- if (msg.getData().containsKey("error_code")) {
- int errorCode = msg.getData().getInt("error_code");
- serviceListener.onFacebookError(new FacebookError(error, null, errorCode));
- } else {
- serviceListener.onError(new Error(error != null ? error
- : "Unknown service error"));
- }
- }
-
- // The refreshToken function should be called rarely,
- // so there is no point in keeping the binding open.
- applicationsContext.unbindService(TokenRefreshServiceConnection.this);
- }
- });
-
- final ServiceListener serviceListener;
- final Context applicationsContext;
-
- Messenger messageSender = null;
-
- public TokenRefreshServiceConnection(Context applicationsContext,
- ServiceListener serviceListener) {
- this.applicationsContext = applicationsContext;
- this.serviceListener = serviceListener;
- }
-
- @Override
- public void onServiceConnected(ComponentName className, IBinder service) {
- messageSender = new Messenger(service);
- refreshToken();
- }
-
- @Override
- public void onServiceDisconnected(ComponentName arg) {
- serviceListener.onError(new Error("Service disconnected"));
- // We returned an error so there's no point in
- // keeping the binding open.
- applicationsContext.unbindService(TokenRefreshServiceConnection.this);
- }
-
- private void refreshToken() {
- Bundle requestData = new Bundle();
- requestData.putString(TOKEN, mAccessToken);
-
- Message request = Message.obtain();
- request.setData(requestData);
- request.replyTo = messageReceiver;
-
- try {
- messageSender.send(request);
- } catch (RemoteException e) {
- serviceListener.onError(new Error("Service connection error"));
- }
- }
- };
-
- /**
- * Invalidate the current user session by removing the access token in
- * memory, clearing the browser cookie, and calling auth.expireSession
- * through the API.
- *
- * Note that this method blocks waiting for a network response, so do not
- * call it in a UI thread.
- *
- * @param context
- * The Android context in which the logout should be called: it
- * should be the same context in which the login occurred in
- * order to clear any stored cookies
- * @throws IOException
- * @throws MalformedURLException
- * @return JSON string representation of the auth.expireSession response
- * ("true" if successful)
- */
- public String logout(Context context)
- throws MalformedURLException, IOException {
- Util.clearCookies(context);
- Bundle b = new Bundle();
- b.putString("method", "auth.expireSession");
- String response = request(b);
- setAccessToken(null);
- setAccessExpires(0);
- return response;
- }
-
- /**
- * Make a request to Facebook's old (pre-graph) API with the given
- * parameters. One of the parameter keys must be "method" and its value
- * should be a valid REST server API method.
- *
- * See http://developers.facebook.com/docs/reference/rest/
- *
- * Note that this method blocks waiting for a network response, so do not
- * call it in a UI thread.
- *
- * Example:
- * <code>
- * Bundle parameters = new Bundle();
- * parameters.putString("method", "auth.expireSession");
- * String response = request(parameters);
- * </code>
- *
- * @param parameters
- * Key-value pairs of parameters to the request. Refer to the
- * documentation: one of the parameters must be "method".
- * @throws IOException
- * if a network error occurs
- * @throws MalformedURLException
- * if accessing an invalid endpoint
- * @throws IllegalArgumentException
- * if one of the parameters is not "method"
- * @return JSON string representation of the response
- */
- public String request(Bundle parameters)
- throws MalformedURLException, IOException {
- if (!parameters.containsKey("method")) {
- throw new IllegalArgumentException("API method must be specified. "
- + "(parameters must contain key \"method\" and value). See"
- + " http://developers.facebook.com/docs/reference/rest/");
- }
- return request(null, parameters, "GET");
- }
-
- /**
- * Make a request to the Facebook Graph API without any parameters.
- *
- * See http://developers.facebook.com/docs/api
- *
- * Note that this method blocks waiting for a network response, so do not
- * call it in a UI thread.
- *
- * @param graphPath
- * Path to resource in the Facebook graph, e.g., to fetch data
- * about the currently logged authenticated user, provide "me",
- * which will fetch http://graph.facebook.com/me
- * @throws IOException
- * @throws MalformedURLException
- * @return JSON string representation of the response
- */
- public String request(String graphPath)
- throws MalformedURLException, IOException {
- return request(graphPath, new Bundle(), "GET");
- }
-
- /**
- * Make a request to the Facebook Graph API with the given string parameters
- * using an HTTP GET (default method).
- *
- * See http://developers.facebook.com/docs/api
- *
- * Note that this method blocks waiting for a network response, so do not
- * call it in a UI thread.
- *
- * @param graphPath
- * Path to resource in the Facebook graph, e.g., to fetch data
- * about the currently logged authenticated user, provide "me",
- * which will fetch http://graph.facebook.com/me
- * @param parameters
- * key-value string parameters, e.g. the path "search" with
- * parameters "q" : "facebook" would produce a query for the
- * following graph resource:
- * https://graph.facebook.com/search?q=facebook
- * @throws IOException
- * @throws MalformedURLException
- * @return JSON string representation of the response
- */
- public String request(String graphPath, Bundle parameters)
- throws MalformedURLException, IOException {
- return request(graphPath, parameters, "GET");
- }
-
- /**
- * Synchronously make a request to the Facebook Graph API with the given
- * HTTP method and string parameters. Note that binary data parameters
- * (e.g. pictures) are not yet supported by this helper function.
- *
- * See http://developers.facebook.com/docs/api
- *
- * Note that this method blocks waiting for a network response, so do not
- * call it in a UI thread.
- *
- * @param graphPath
- * Path to resource in the Facebook graph, e.g., to fetch data
- * about the currently logged authenticated user, provide "me",
- * which will fetch http://graph.facebook.com/me
- * @param params
- * Key-value string parameters, e.g. the path "search" with
- * parameters {"q" : "facebook"} would produce a query for the
- * following graph resource:
- * https://graph.facebook.com/search?q=facebook
- * @param httpMethod
- * http verb, e.g. "GET", "POST", "DELETE"
- * @throws IOException
- * @throws MalformedURLException
- * @return JSON string representation of the response
- */
- public String request(String graphPath, Bundle params, String httpMethod)
- throws FileNotFoundException, MalformedURLException, IOException {
- params.putString("format", "json");
- if (isSessionValid()) {
- params.putString(TOKEN, getAccessToken());
- }
- String url = (graphPath != null) ? GRAPH_BASE_URL + graphPath
- : RESTSERVER_URL;
- return Util.openUrl(url, httpMethod, params);
- }
-
- /**
- * Generate a UI dialog for the request action in the given Android context.
- *
- * Note that this method is asynchronous and the callback will be invoked in
- * the original calling thread (not in a background thread).
- *
- * @param context
- * The Android context in which we will generate this dialog.
- * @param action
- * String representation of the desired method: e.g. "login",
- * "stream.publish", ...
- * @param listener
- * Callback interface to notify the application when the dialog
- * has completed.
- */
- public void dialog(Context context, String action,
- DialogListener listener) {
- dialog(context, action, new Bundle(), listener);
- }
-
- /**
- * Generate a UI dialog for the request action in the given Android context
- * with the provided parameters.
- *
- * Note that this method is asynchronous and the callback will be invoked in
- * the original calling thread (not in a background thread).
- *
- * @param context
- * The Android context in which we will generate this dialog.
- * @param action
- * String representation of the desired method: e.g. "feed" ...
- * @param parameters
- * String key-value pairs to be passed as URL parameters.
- * @param listener
- * Callback interface to notify the application when the dialog
- * has completed.
- */
- public void dialog(Context context, String action, Bundle parameters,
- final DialogListener listener) {
-
- String endpoint = DIALOG_BASE_URL + action;
- parameters.putString("display", "touch");
- parameters.putString("redirect_uri", REDIRECT_URI);
-
- if (action.equals(LOGIN)) {
- parameters.putString("type", "user_agent");
- parameters.putString("client_id", mAppId);
- } else {
- parameters.putString("app_id", mAppId);
- }
-
- if (isSessionValid()) {
- parameters.putString(TOKEN, getAccessToken());
- }
- String url = endpoint + "?" + Util.encodeUrl(parameters);
- if (context.checkCallingOrSelfPermission(Manifest.permission.INTERNET)
- != PackageManager.PERMISSION_GRANTED) {
- Util.showAlert(context, "Error",
- "Application requires permission to access the Internet");
- } else {
- new FbDialog(context, url, listener).show();
- }
- }
-
- /**
- * @return boolean - whether this object has an non-expired session token
- */
- public boolean isSessionValid() {
- return (getAccessToken() != null) &&
- ((getAccessExpires() == 0) ||
- (System.currentTimeMillis() < getAccessExpires()));
- }
-
- /**
- * Retrieve the OAuth 2.0 access token for API access: treat with care.
- * Returns null if no session exists.
- *
- * @return String - access token
- */
- public String getAccessToken() {
- return mAccessToken;
- }
-
- /**
- * Retrieve the current session's expiration time (in milliseconds since
- * Unix epoch), or 0 if the session doesn't expire or doesn't exist.
- *
- * @return long - session expiration time
- */
- public long getAccessExpires() {
- return mAccessExpires;
- }
-
- /**
- * Set the OAuth 2.0 access token for API access.
- *
- * @param token - access token
- */
- public void setAccessToken(String token) {
- mAccessToken = token;
- mLastAccessUpdate = System.currentTimeMillis();
- }
-
- /**
- * Set the current session's expiration time (in milliseconds since Unix
- * epoch), or 0 if the session doesn't expire.
- *
- * @param time - timestamp in milliseconds
- */
- public void setAccessExpires(long time) {
- mAccessExpires = time;
- }
-
- /**
- * Set the current session's duration (in seconds since Unix epoch), or "0"
- * if session doesn't expire.
- *
- * @param expiresIn
- * - duration in seconds (or 0 if the session doesn't expire)
- */
- public void setAccessExpiresIn(String expiresIn) {
- if (expiresIn != null) {
- long expires = expiresIn.equals("0")
- ? 0
- : System.currentTimeMillis() + Long.parseLong(expiresIn) * 1000L;
- setAccessExpires(expires);
- }
- }
-
- public String getAppId() {
- return mAppId;
- }
-
- public void setAppId(String appId) {
- mAppId = appId;
- }
-
- /**
- * Callback interface for dialog requests.
- *
- */
- public static interface DialogListener {
-
- /**
- * Called when a dialog completes.
- *
- * Executed by the thread that initiated the dialog.
- *
- * @param values
- * Key-value string pairs extracted from the response.
- */
- public void onComplete(Bundle values);
-
- /**
- * Called when a Facebook responds to a dialog with an error.
- *
- * Executed by the thread that initiated the dialog.
- *
- */
- public void onFacebookError(FacebookError e);
-
- /**
- * Called when a dialog has an error.
- *
- * Executed by the thread that initiated the dialog.
- *
- */
- public void onError(DialogError e);
-
- /**
- * Called when a dialog is canceled by the user.
- *
- * Executed by the thread that initiated the dialog.
- *
- */
- public void onCancel();
-
- }
-
- /**
- * Callback interface for service requests.
- */
- public static interface ServiceListener {
-
- /**
- * Called when a service request completes.
- *
- * @param values
- * Key-value string pairs extracted from the response.
- */
- public void onComplete(Bundle values);
-
- /**
- * Called when a Facebook server responds to the request with an error.
- */
- public void onFacebookError(FacebookError e);
-
- /**
- * Called when a Facebook Service responds to the request with an error.
- */
- public void onError(Error e);
-
- }
-
- public static final String FB_APP_SIGNATURE =
- "30820268308201d102044a9c4610300d06092a864886f70d0101040500307a310"
- + "b3009060355040613025553310b30090603550408130243413112301006035504"
- + "07130950616c6f20416c746f31183016060355040a130f46616365626f6f6b204"
- + "d6f62696c653111300f060355040b130846616365626f6f6b311d301b06035504"
- + "03131446616365626f6f6b20436f72706f726174696f6e3020170d30393038333"
- + "13231353231365a180f32303530303932353231353231365a307a310b30090603"
- + "55040613025553310b30090603550408130243413112301006035504071309506"
- + "16c6f20416c746f31183016060355040a130f46616365626f6f6b204d6f62696c"
- + "653111300f060355040b130846616365626f6f6b311d301b06035504031314466"
- + "16365626f6f6b20436f72706f726174696f6e30819f300d06092a864886f70d01"
- + "0101050003818d0030818902818100c207d51df8eb8c97d93ba0c8c1002c928fa"
- + "b00dc1b42fca5e66e99cc3023ed2d214d822bc59e8e35ddcf5f44c7ae8ade50d7"
- + "e0c434f500e6c131f4a2834f987fc46406115de2018ebbb0d5a3c261bd97581cc"
- + "fef76afc7135a6d59e8855ecd7eacc8f8737e794c60a761c536b72b11fac8e603"
- + "f5da1a2d54aa103b8a13c0dbc10203010001300d06092a864886f70d010104050"
- + "0038181005ee9be8bcbb250648d3b741290a82a1c9dc2e76a0af2f2228f1d9f9c"
- + "4007529c446a70175c5a900d5141812866db46be6559e2141616483998211f4a6"
- + "73149fb2232a10d247663b26a9031e15f84bc1c74d141ff98a02d76f85b2c8ab2"
- + "571b6469b232d8e768a7f7ca04f7abe4a775615916c07940656b58717457b42bd"
- + "928a2";
-
-}
View
50 src/android/java/com/facebook/android/FacebookError.java
@@ -1,50 +0,0 @@
-/*
- * Copyright 2010 Facebook, Inc.
- *
- * 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.android;
-
-/**
- * Encapsulation of a Facebook Error: a Facebook request that could not be
- * fulfilled.
- *
- * @author ssoneff@facebook.com
- */
-public class FacebookError extends RuntimeException {
-
- private static final long serialVersionUID = 1L;
-
- private int mErrorCode = 0;
- private String mErrorType;
-
- public FacebookError(String message) {
- super(message);
- }
-
- public FacebookError(String message, String type, int code) {
- super(message);
- mErrorType = type;
- mErrorCode = code;
- }
-
- public int getErrorCode() {
- return mErrorCode;
- }
-
- public String getErrorType() {
- return mErrorType;
- }
-
-}
View
198 src/android/java/com/facebook/android/FbDialog.java
@@ -1,198 +0,0 @@
-/*
- * Copyright 2010 Facebook, Inc.
- *
- * 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.android;
-
-import android.app.Dialog;
-import android.app.ProgressDialog;
-import android.content.Context;
-import android.content.Intent;
-import android.graphics.Bitmap;
-import android.graphics.Color;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewGroup.LayoutParams;
-import android.view.Window;
-import android.webkit.WebView;
-import android.webkit.WebViewClient;
-import android.widget.FrameLayout;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import ru.redspell.lighttest.R;
-
-import com.facebook.android.Facebook.DialogListener;
-
-public class FbDialog extends Dialog {
-
- static final int FB_BLUE = 0xFF6D84B4;
- static final float[] DIMENSIONS_DIFF_LANDSCAPE = {20, 60};
- static final float[] DIMENSIONS_DIFF_PORTRAIT = {40, 60};
- static final FrameLayout.LayoutParams FILL =
- new FrameLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
- ViewGroup.LayoutParams.FILL_PARENT);
- static final int MARGIN = 4;
- static final int PADDING = 2;
- static final String DISPLAY_STRING = "touch";
- static final String FB_ICON = "icon.png";
-
- private String mUrl;
- private DialogListener mListener;
- private ProgressDialog mSpinner;
- private ImageView mCrossImage;
- private WebView mWebView;
- private FrameLayout mContent;
-
- public FbDialog(Context context, String url, DialogListener listener) {
- super(context, android.R.style.Theme_Translucent_NoTitleBar);
- mUrl = url;
- mListener = listener;
- }
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- mSpinner = new ProgressDialog(getContext());
- mSpinner.requestWindowFeature(Window.FEATURE_NO_TITLE);
- mSpinner.setMessage("Loading...");
-
- requestWindowFeature(Window.FEATURE_NO_TITLE);
- mContent = new FrameLayout(getContext());
-
- /* Create the 'x' image, but don't add to the mContent layout yet
- * at this point, we only need to know its drawable width and height
- * to place the webview
- */
- createCrossImage();
-
- /* Now we know 'x' drawable width and height,
- * layout the webivew and add it the mContent layout
- */
- int crossWidth = mCrossImage.getDrawable().getIntrinsicWidth();
- setUpWebView(crossWidth / 2);
-
- /* Finally add the 'x' image to the mContent layout and
- * add mContent to the Dialog view
- */
- mContent.addView(mCrossImage, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
- addContentView(mContent, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
- }
-
- private void createCrossImage() {
- mCrossImage = new ImageView(getContext());
- // Dismiss the dialog when user click on the 'x'
- mCrossImage.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- mListener.onCancel();
- FbDialog.this.dismiss();
- }
- });
- Drawable crossDrawable = getContext().getResources().getDrawable(R.drawable.close);
- mCrossImage.setImageDrawable(crossDrawable);
- /* 'x' should not be visible while webview is loading
- * make it visible only after webview has fully loaded
- */
- mCrossImage.setVisibility(View.INVISIBLE);
- }
-
- private void setUpWebView(int margin) {
- LinearLayout webViewContainer = new LinearLayout(getContext());
- mWebView = new WebView(getContext());
- mWebView.setVerticalScrollBarEnabled(false);
- mWebView.setHorizontalScrollBarEnabled(false);
- mWebView.setWebViewClient(new FbDialog.FbWebViewClient());
- mWebView.getSettings().setJavaScriptEnabled(true);
- mWebView.loadUrl(mUrl);
- mWebView.setLayoutParams(FILL);
- mWebView.setVisibility(View.INVISIBLE);
- mWebView.getSettings().setSavePassword(false);
-
- webViewContainer.setPadding(margin, margin, margin, margin);
- webViewContainer.addView(mWebView);
- mContent.addView(webViewContainer);
- }
-
- private class FbWebViewClient extends WebViewClient {
-
- @Override
- public boolean shouldOverrideUrlLoading(WebView view, String url) {
- Util.logd("Facebook-WebView", "Redirect URL: " + url);
- if (url.startsWith(Facebook.REDIRECT_URI)) {
- Bundle values = Util.parseUrl(url);
-
- String error = values.getString("error");
- if (error == null) {
- error = values.getString("error_type");
- }
-
- if (error == null) {
- mListener.onComplete(values);
- } else if (error.equals("access_denied") ||
- error.equals("OAuthAccessDeniedException")) {
- mListener.onCancel();
- } else {
- mListener.onFacebookError(new FacebookError(error));
- }
-
- FbDialog.this.dismiss();
- return true;
- } else if (url.startsWith(Facebook.CANCEL_URI)) {
- mListener.onCancel();
- FbDialog.this.dismiss();
- return true;
- } else if (url.contains(DISPLAY_STRING)) {
- return false;
- }
- // launch non-dialog URLs in a full browser
- getContext().startActivity(
- new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
- return true;
- }
-
- @Override
- public void onReceivedError(WebView view, int errorCode,
- String description, String failingUrl) {
- super.onReceivedError(view, errorCode, description, failingUrl);
- mListener.onError(
- new DialogError(description, errorCode, failingUrl));
- FbDialog.this.dismiss();
- }
-
- @Override
- public void onPageStarted(WebView view, String url, Bitmap favicon) {
- Util.logd("Facebook-WebView", "Webview loading URL: " + url);
- super.onPageStarted(view, url, favicon);
- mSpinner.show();
- }
-
- @Override
- public void onPageFinished(WebView view, String url) {
- super.onPageFinished(view, url);
- mSpinner.dismiss();
- /*
- * Once webview is fully loaded, set the mContent background to be transparent
- * and make visible the 'x' image.
- */
- mContent.setBackgroundColor(Color.TRANSPARENT);
- mWebView.setVisibility(View.VISIBLE);
- mCrossImage.setVisibility(View.VISIBLE);
- }
- }
-}
View
329 src/android/java/com/facebook/android/Util.java
@@ -1,329 +0,0 @@
-/*
- * Copyright 2010 Facebook, Inc.
- *
- * 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.android;
-
-import java.io.BufferedOutputStream;
-import java.io.BufferedReader;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.net.HttpURLConnection;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLDecoder;
-import java.net.URLEncoder;
-
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import android.app.AlertDialog.Builder;
-import android.content.Context;
-import android.os.Bundle;
-import android.util.Log;
-import android.webkit.CookieManager;
-import android.webkit.CookieSyncManager;
-
-/**
- * Utility class supporting the Facebook Object.
- *
- * @author ssoneff@facebook.com
- *
- */
-public final class Util {
-
- /**
- * Set this to true to enable log output. Remember to turn this back off
- * before releasing. Sending sensitive data to log is a security risk.
- */
- private static boolean ENABLE_LOG = false;
-
- /**
- * Generate the multi-part post body providing the parameters and boundary
- * string
- *
- * @param parameters the parameters need to be posted
- * @param boundary the random string as boundary
- * @return a string of the post body
- */
- public static String encodePostBody(Bundle parameters, String boundary) {
- if (parameters == null) return "";
- StringBuilder sb = new StringBuilder();
-
- for (String key : parameters.keySet()) {
- Object parameter = parameters.get(key);
- if (!(parameter instanceof String)) {
- continue;
- }
-
- sb.append("Content-Disposition: form-data; name=\"" + key +
- "\"\r\n\r\n" + (String)parameter);
- sb.append("\r\n" + "--" + boundary + "\r\n");
- }
-
- return sb.toString();
- }
-
- public static String encodeUrl(Bundle parameters) {
- if (parameters == null) {
- return "";
- }
-
- StringBuilder sb = new StringBuilder();
- boolean first = true;
- for (String key : parameters.keySet()) {
- Object parameter = parameters.get(key);
- if (!(parameter instanceof String)) {
- continue;
- }
-
- if (first) first = false; else sb.append("&");
- sb.append(URLEncoder.encode(key) + "=" +
- URLEncoder.encode(parameters.getString(key)));
- }
- return sb.toString();
- }
-
- public static Bundle decodeUrl(String s) {
- Bundle params = new Bundle();
- if (s != null) {
- String array[] = s.split("&");
- for (String parameter : array) {
- String v[] = parameter.split("=");
- if (v.length == 2) {
- params.putString(URLDecoder.decode(v[0]),
- URLDecoder.decode(v[1]));
- }
- }
- }
- return params;
- }
-
- /**
- * Parse a URL query and fragment parameters into a key-value bundle.
- *
- * @param url the URL to parse
- * @return a dictionary bundle of keys and values
- */
- public static Bundle parseUrl(String url) {
- // hack to prevent MalformedURLException
- url = url.replace("fbconnect", "http");
- try {
- URL u = new URL(url);
- Bundle b = decodeUrl(u.getQuery());
- b.putAll(decodeUrl(u.getRef()));
- return b;
- } catch (MalformedURLException e) {
- return new Bundle();
- }
- }
-
-
- /**
- * Connect to an HTTP URL and return the response as a string.
- *
- * Note that the HTTP method override is used on non-GET requests. (i.e.
- * requests are made as "POST" with method specified in the body).
- *
- * @param url - the resource to open: must be a welformed URL
- * @param method - the HTTP method to use ("GET", "POST", etc.)
- * @param params - the query parameter for the URL (e.g. access_token=foo)
- * @return the URL contents as a String
- * @throws MalformedURLException - if the URL format is invalid
- * @throws IOException - if a network problem occurs
- */
- public static String openUrl(String url, String method, Bundle params)
- throws MalformedURLException, IOException {
- // random string as boundary for multi-part http post
- String strBoundary = "3i2ndDfv2rTHiSisAbouNdArYfORhtTPEefj3q2f";
- String endLine = "\r\n";
-
- OutputStream os;
-
- if (method.equals("GET")) {
- url = url + "?" + encodeUrl(params);
- }
- Util.logd("Facebook-Util", method + " URL: " + url);
- HttpURLConnection conn =
- (HttpURLConnection) new URL(url).openConnection();
- conn.setRequestProperty("User-Agent", System.getProperties().
- getProperty("http.agent") + " FacebookAndroidSDK");
- if (!method.equals("GET")) {
- Bundle dataparams = new Bundle();
- for (String key : params.keySet()) {
- Object parameter = params.get(key);
- if (parameter instanceof byte[]) {
- dataparams.putByteArray(key, (byte[])parameter);
- }
- }
-
- // use method override
- if (!params.containsKey("method")) {
- params.putString("method", method);
- }
-
- if (params.containsKey("access_token")) {
- String decoded_token =
- URLDecoder.decode(params.getString("access_token"));
- params.putString("access_token", decoded_token);
- }
-
- conn.setRequestMethod("POST");
- conn.setRequestProperty(
- "Content-Type",
- "multipart/form-data;boundary="+strBoundary);
- conn.setDoOutput(true);
- conn.setDoInput(true);
- conn.setRequestProperty("Connection", "Keep-Alive");
- conn.connect();
- os = new BufferedOutputStream(conn.getOutputStream());
-
- os.write(("--" + strBoundary +endLine).getBytes());
- os.write((encodePostBody(params, strBoundary)).getBytes());
- os.write((endLine + "--" + strBoundary + endLine).getBytes());
-
- if (!dataparams.isEmpty()) {
-
- for (String key: dataparams.keySet()){
- os.write(("Content-Disposition: form-data; filename=\"" + key + "\"" + endLine).getBytes());
- os.write(("Content-Type: content/unknown" + endLine + endLine).getBytes());
- os.write(dataparams.getByteArray(key));
- os.write((endLine + "--" + strBoundary + endLine).getBytes());
-
- }
- }
- os.flush();
- }
-
- String response = "";
- try {
- response = read(conn.getInputStream());
- } catch (FileNotFoundException e) {
- // Error Stream contains JSON that we can parse to a FB error
- response = read(conn.getErrorStream());
- }
- return response;
- }
-
- private static String read(InputStream in) throws IOException {
- StringBuilder sb = new StringBuilder();
- BufferedReader r = new BufferedReader(new InputStreamReader(in), 1000);
- for (String line = r.readLine(); line != null; line = r.readLine()) {
- sb.append(line);
- }
- in.close();
- return sb.toString();
- }
-
- public static void clearCookies(Context context) {
- // Edge case: an illegal state exception is thrown if an instance of
- // CookieSyncManager has not be created. CookieSyncManager is normally
- // created by a WebKit view, but this might happen if you start the
- // app, restore saved state, and click logout before running a UI
- // dialog in a WebView -- in which case the app crashes
- @SuppressWarnings("unused")
- CookieSyncManager cookieSyncMngr =
- CookieSyncManager.createInstance(context);
- CookieManager cookieManager = CookieManager.getInstance();
- cookieManager.removeAllCookie();
- }
-
- /**
- * Parse a server response into a JSON Object. This is a basic
- * implementation using org.json.JSONObject representation. More
- * sophisticated applications may wish to do their own parsing.
- *
- * The parsed JSON is checked for a variety of error fields and
- * a FacebookException is thrown if an error condition is set,
- * populated with the error message and error type or code if
- * available.
- *
- * @param response - string representation of the response
- * @return the response as a JSON Object
- * @throws JSONException - if the response is not valid JSON
- * @throws FacebookError - if an error condition is set
- */
- public static JSONObject parseJson(String response)
- throws JSONException, FacebookError {
- // Edge case: when sending a POST request to /[post_id]/likes
- // the return value is 'true' or 'false'. Unfortunately
- // these values cause the JSONObject constructor to throw
- // an exception.
- if (response.equals("false")) {
- throw new FacebookError("request failed");
- }
- if (response.equals("true")) {
- response = "{value : true}";
- }
- JSONObject json = new JSONObject(response);
-
- // errors set by the server are not consistent
- // they depend on the method and endpoint
- if (json.has("error")) {
- JSONObject error = json.getJSONObject("error");
- throw new FacebookError(
- error.getString("message"), error.getString("type"), 0);
- }
- if (json.has("error_code") && json.has("error_msg")) {
- throw new FacebookError(json.getString("error_msg"), "",
- Integer.parseInt(json.getString("error_code")));
- }
- if (json.has("error_code")) {
- throw new FacebookError("request failed", "",
- Integer.parseInt(json.getString("error_code")));
- }
- if (json.has("error_msg")) {
- throw new FacebookError(json.getString("error_msg"));
- }
- if (json.has("error_reason")) {
- throw new FacebookError(json.getString("error_reason"));
- }
- return json;
- }
-
- /**
- * Display a simple alert dialog with the given text and title.
- *
- * @param context
- * Android context in which the dialog should be displayed
- * @param title
- * Alert dialog title
- * @param text
- * Alert dialog message
- */
- public static void showAlert(Context context, String title, String text) {
- Builder alertBuilder = new Builder(context);
- alertBuilder.setTitle(title);
- alertBuilder.setMessage(text);
- alertBuilder.create().show();
- }
-
- /**
- * A proxy for Log.d api that kills log messages in release build. It
- * not recommended to send sensitive information to log output in
- * shipping apps.
- *
- * @param tag
- * @param msg
- */
- public static void logd(String tag, String msg) {
- if (ENABLE_LOG) {
- Log.d(tag, msg);
- }
- }
-}
View
20 src/android/java/proguard-project.txt
@@ -0,0 +1,20 @@
+# To enable ProGuard in your project, edit project.properties
+# to define the proguard.config property as described in that file.
+#
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in ${sdk.dir}/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the ProGuard
+# include property in project.properties.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
View
16 src/android/java/project.properties
@@ -0,0 +1,16 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system edit
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+#
+# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
+#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
+
+android.library=true
+# Project target.
+target=android-8
+android.library.reference.1=../../social/facebook/android/facebook
View
13 src/android/java/res/layout/main.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ >
+<TextView
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:text="Hello World, ACTIVITY_ENTRY_NAME"
+ />
+</LinearLayout>
+
View
4 src/android/java/res/values/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="app_name">ACTIVITY_ENTRY_NAME</string>
+</resources>
View
0  ...ending/billing/IMarketBillingService.aidl → ...ending/billing/IMarketBillingService.aidl
File renamed without changes
View
2  src/android/java/com/facebook/AndroidFB.java → .../src/ru/redspell/lightning/AndroidFB.java
@@ -1,4 +1,4 @@
-package com.facebook;
+package ru.redspell.lightning;
import android.content.Intent;
import com.facebook.android.*;
View
0  ...u/redspell/lightning/LightHttpLoader.java → ...u/redspell/lightning/LightHttpLoader.java
File renamed without changes
View
0  .../ru/redspell/lightning/LightRenderer.java → .../ru/redspell/lightning/LightRenderer.java
File renamed without changes
View
0  ...a/ru/redspell/lightning/LightTexture.java → ...c/ru/redspell/lightning/LightTexture.java
File renamed without changes
View
1  ...java/ru/redspell/lightning/LightView.java → .../src/ru/redspell/lightning/LightView.java
@@ -39,7 +39,6 @@
import android.media.AudioManager;
import android.os.Process;
-import com.facebook.AndroidFB;
public class LightView extends GLSurfaceView {
View
0  ...ru/redspell/lightning/ResourceParams.java → ...ru/redspell/lightning/ResourceParams.java
File renamed without changes
View
0  ...id/java/ru/redspell/lightning/UrlReq.java → ...ava/src/ru/redspell/lightning/UrlReq.java
File renamed without changes
View
0  ...l/lightning/payments/BillingReceiver.java → ...l/lightning/payments/BillingReceiver.java
File renamed without changes
View
0  ...ll/lightning/payments/BillingService.java → ...ll/lightning/payments/BillingService.java
File renamed without changes
View
0  ...u/redspell/lightning/payments/Consts.java → ...u/redspell/lightning/payments/Consts.java
File renamed without changes
View
0  ...l/lightning/payments/ResponseHandler.java → ...l/lightning/payments/ResponseHandler.java
File renamed without changes
View
0  ...redspell/lightning/payments/Security.java → ...redspell/lightning/payments/Security.java
File renamed without changes
View
0  ...pell/lightning/payments/utils/Base64.java → ...pell/lightning/payments/utils/Base64.java
File renamed without changes
View
0  ...ayments/utils/Base64DecoderException.java → ...ayments/utils/Base64DecoderException.java
File renamed without changes
Please sign in to comment.
Something went wrong with that request. Please try again.