Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

lightning and facebook api migration to android library projects

  • Loading branch information...
commit 49197aa076ad7fdabe15c851239af073563d7697 1 parent aa8e975
nazarov-andrey nazarov-andrey authored

Showing 29 changed files with 181 additions and 1,926 deletions. Show diff stats Hide diff stats

  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
3  .gitignore
@@ -14,3 +14,6 @@
14 14 local.properties
15 15 myconfig.ios
16 16 myconfig.macos
  17 +gen
  18 +bin
  19 +gen
15 src/android/java/AndroidManifest.xml
... ... @@ -0,0 +1,15 @@
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3 + package="ru.redspell.lightning"
  4 + android:versionCode="1"
  5 + android:versionName="1.0">
  6 + <application android:label="@string/app_name" >
  7 + <activity android:name="ACTIVITY_ENTRY_NAME"
  8 + android:label="@string/app_name">
  9 + <intent-filter>
  10 + <action android:name="android.intent.action.MAIN" />
  11 + <category android:name="android.intent.category.LAUNCHER" />
  12 + </intent-filter>
  13 + </activity>
  14 + </application>
  15 +</manifest>
17 src/android/java/ant.properties
... ... @@ -0,0 +1,17 @@
  1 +# This file is used to override default values used by the Ant build system.
  2 +#
  3 +# This file must be checked into Version Control Systems, as it is
  4 +# integral to the build system of your project.
  5 +
  6 +# This file is only used by the Ant script.
  7 +
  8 +# You can use this to override default values such as
  9 +# 'source.dir' for the location of your java source folder and
  10 +# 'out.dir' for the location of your output folder.
  11 +
  12 +# You can also use it define how the release builds are signed by declaring
  13 +# the following properties:
  14 +# 'key.store' for the location of your keystore and
  15 +# 'key.alias' for the name of the key to use.
  16 +# The password will be asked during the build when you use the 'release' target.
  17 +
92 src/android/java/build.xml
... ... @@ -0,0 +1,92 @@
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<project name="lightning" default="help">
  3 +
  4 + <!-- The local.properties file is created and updated by the 'android' tool.
  5 + It contains the path to the SDK. It should *NOT* be checked into
  6 + Version Control Systems. -->
  7 + <property file="local.properties" />
  8 +
  9 + <!-- The ant.properties file can be created by you. It is only edited by the
  10 + 'android' tool to add properties to it.
  11 + This is the place to change some Ant specific build properties.
  12 + Here are some properties you may want to change/update:
  13 +
  14 + source.dir
  15 + The name of the source directory. Default is 'src'.
  16 + out.dir
  17 + The name of the output directory. Default is 'bin'.
  18 +
  19 + For other overridable properties, look at the beginning of the rules
  20 + files in the SDK, at tools/ant/build.xml
  21 +
  22 + Properties related to the SDK location or the project target should
  23 + be updated using the 'android' tool with the 'update' action.
  24 +
  25 + This file is an integral part of the build system for your
  26 + application and should be checked into Version Control Systems.
  27 +
  28 + -->
  29 + <property file="ant.properties" />
  30 +
  31 + <!-- if sdk.dir was not set from one of the property file, then
  32 + get it from the ANDROID_HOME env var.
  33 + This must be done before we load project.properties since
  34 + the proguard config can use sdk.dir -->
  35 + <property environment="env" />
  36 + <condition property="sdk.dir" value="${env.ANDROID_HOME}">
  37 + <isset property="env.ANDROID_HOME" />
  38 + </condition>
  39 +
  40 + <!-- The project.properties file is created and updated by the 'android'
  41 + tool, as well as ADT.
  42 +
  43 + This contains project specific properties such as project target, and library
  44 + dependencies. Lower level build properties are stored in ant.properties
  45 + (or in .classpath for Eclipse projects).
  46 +
  47 + This file is an integral part of the build system for your
  48 + application and should be checked into Version Control Systems. -->
  49 + <loadproperties srcFile="project.properties" />
  50 +
  51 + <!-- quick check on sdk.dir -->
  52 + <fail
  53 + 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."
  54 + unless="sdk.dir"
  55 + />
  56 +
  57 + <!--
  58 + Import per project custom build rules if present at the root of the project.
  59 + This is the place to put custom intermediary targets such as:
  60 + -pre-build
  61 + -pre-compile
  62 + -post-compile (This is typically used for code obfuscation.
  63 + Compiled code location: ${out.classes.absolute.dir}
  64 + If this is not done in place, override ${out.dex.input.absolute.dir})
  65 + -post-package
  66 + -post-build
  67 + -pre-clean
  68 + -->
  69 + <import file="custom_rules.xml" optional="true" />
  70 +
  71 + <!-- Import the actual build file.
  72 +
  73 + To customize existing targets, there are two options:
  74 + - Customize only one target:
  75 + - copy/paste the target into this file, *before* the
  76 + <import> task.
  77 + - customize it to your needs.
  78 + - Customize the whole content of build.xml
  79 + - copy/paste the content of the rules files (minus the top node)
  80 + into this file, replacing the <import> task.
  81 + - customize to your needs.
  82 +
  83 + ***********************
  84 + ****** IMPORTANT ******
  85 + ***********************
  86 + In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
  87 + in order to avoid having your file be overridden by tools such as "android update project"
  88 + -->
  89 + <!-- version-tag: 1 -->
  90 + <import file="${sdk.dir}/tools/ant/build.xml" />
  91 +
  92 +</project>
316 src/android/java/com/facebook/android/AsyncFacebookRunner.java
... ... @@ -1,316 +0,0 @@
1   -/*
2   - * Copyright 2010 Facebook, Inc.
3   - *
4   - * Licensed under the Apache License, Version 2.0 (the "License");
5   - * you may not use this file except in compliance with the License.
6   - * You may obtain a copy of the License at
7   - *
8   - * http://www.apache.org/licenses/LICENSE-2.0
9   - *
10   - * Unless required by applicable law or agreed to in writing, software
11   - * distributed under the License is distributed on an "AS IS" BASIS,
12   - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   - * See the License for the specific language governing permissions and
14   - * limitations under the License.
15   - */
16   -
17   -package com.facebook.android;
18   -
19   -import java.io.FileNotFoundException;
20   -import java.io.IOException;
21   -import java.net.MalformedURLException;
22   -
23   -import android.content.Context;
24   -import android.os.Bundle;
25   -
26   -/**
27   - * A sample implementation of asynchronous API requests. This class provides
28   - * the ability to execute API methods and have the call return immediately,
29   - * without blocking the calling thread. This is necessary when accessing the
30   - * API in the UI thread, for instance. The request response is returned to
31   - * the caller via a callback interface, which the developer must implement.
32   - *
33   - * This sample implementation simply spawns a new thread for each request,
34   - * and makes the API call immediately. This may work in many applications,
35   - * but more sophisticated users may re-implement this behavior using a thread
36   - * pool, a network thread, a request queue, or other mechanism. Advanced
37   - * functionality could be built, such as rate-limiting of requests, as per
38   - * a specific application's needs.
39   - *
40   - * @see RequestListener
41   - * The callback interface.
42   - *
43   - * @author Jim Brusstar (jimbru@fb.com),
44   - * Yariv Sadan (yariv@fb.com),
45   - * Luke Shepard (lshepard@fb.com)
46   - */
47   -public class AsyncFacebookRunner {
48   -
49   - Facebook fb;
50   -
51   - public AsyncFacebookRunner(Facebook fb) {
52   - this.fb = fb;
53   - }
54   -
55   - /**
56   - * Invalidate the current user session by removing the access token in
57   - * memory, clearing the browser cookies, and calling auth.expireSession
58   - * through the API. The application will be notified when logout is
59   - * complete via the callback interface.
60   - *
61   - * Note that this method is asynchronous and the callback will be invoked
62   - * in a background thread; operations that affect the UI will need to be
63   - * posted to the UI thread or an appropriate handler.
64   - *
65   - * @param context
66   - * The Android context in which the logout should be called: it
67   - * should be the same context in which the login occurred in
68   - * order to clear any stored cookies
69   - * @param listener
70   - * Callback interface to notify the application when the request
71   - * has completed.
72   - * @param state
73   - * An arbitrary object used to identify the request when it
74   - * returns to the callback. This has no effect on the request
75   - * itself.
76   - */
77   - public void logout(final Context context,
78   - final RequestListener listener,
79   - final Object state) {
80   - new Thread() {
81   - @Override public void run() {
82   - try {
83   - String response = fb.logout(context);
84   - if (response.length() == 0 || response.equals("false")){
85   - listener.onFacebookError(new FacebookError(
86   - "auth.expireSession failed"), state);
87   - return;
88   - }
89   - listener.onComplete(response, state);
90   - } catch (FileNotFoundException e) {
91   - listener.onFileNotFoundException(e, state);
92   - } catch (MalformedURLException e) {
93   - listener.onMalformedURLException(e, state);
94   - } catch (IOException e) {
95   - listener.onIOException(e, state);
96   - }
97   - }
98   - }.start();
99   - }
100   -
101   - public void logout(final Context context, final RequestListener listener) {
102   - logout(context, listener, /* state */ null);
103   - }
104   -
105   - /**
106   - * Make a request to Facebook's old (pre-graph) API with the given
107   - * parameters. One of the parameter keys must be "method" and its value
108   - * should be a valid REST server API method.
109   - *
110   - * See http://developers.facebook.com/docs/reference/rest/
111   - *
112   - * Note that this method is asynchronous and the callback will be invoked
113   - * in a background thread; operations that affect the UI will need to be
114   - * posted to the UI thread or an appropriate handler.
115   - *
116   - * Example:
117   - * <code>
118   - * Bundle parameters = new Bundle();
119   - * parameters.putString("method", "auth.expireSession", new Listener());
120   - * String response = request(parameters);
121   - * </code>
122   - *
123   - * @param parameters
124   - * Key-value pairs of parameters to the request. Refer to the
125   - * documentation: one of the parameters must be "method".
126   - * @param listener
127   - * Callback interface to notify the application when the request
128   - * has completed.
129   - * @param state
130   - * An arbitrary object used to identify the request when it
131   - * returns to the callback. This has no effect on the request
132   - * itself.
133   - */
134   - public void request(Bundle parameters,
135   - RequestListener listener,
136   - final Object state) {
137   - request(null, parameters, "GET", listener, state);
138   - }
139   -
140   - public void request(Bundle parameters, RequestListener listener) {
141   - request(null, parameters, "GET", listener, /* state */ null);
142   - }
143   -
144   - /**
145   - * Make a request to the Facebook Graph API without any parameters.
146   - *
147   - * See http://developers.facebook.com/docs/api
148   - *
149   - * Note that this method is asynchronous and the callback will be invoked
150   - * in a background thread; operations that affect the UI will need to be
151   - * posted to the UI thread or an appropriate handler.
152   - *
153   - * @param graphPath
154   - * Path to resource in the Facebook graph, e.g., to fetch data
155   - * about the currently logged authenticated user, provide "me",
156   - * which will fetch http://graph.facebook.com/me
157   - * @param listener
158   - * Callback interface to notify the application when the request
159   - * has completed.
160   - * @param state
161   - * An arbitrary object used to identify the request when it
162   - * returns to the callback. This has no effect on the request
163   - * itself.
164   - */
165   - public void request(String graphPath,
166   - RequestListener listener,
167   - final Object state) {
168   - request(graphPath, new Bundle(), "GET", listener, state);
169   - }
170   -
171   - public void request(String graphPath, RequestListener listener) {
172   - request(graphPath, new Bundle(), "GET", listener, /* state */ null);
173   - }
174   -
175   - /**
176   - * Make a request to the Facebook Graph API with the given string parameters
177   - * using an HTTP GET (default method).
178   - *
179   - * See http://developers.facebook.com/docs/api
180   - *
181   - * Note that this method is asynchronous and the callback will be invoked
182   - * in a background thread; operations that affect the UI will need to be
183   - * posted to the UI thread or an appropriate handler.
184   - *
185   - * @param graphPath
186   - * Path to resource in the Facebook graph, e.g., to fetch data
187   - * about the currently logged authenticated user, provide "me",
188   - * which will fetch http://graph.facebook.com/me
189   - * @param parameters
190   - * key-value string parameters, e.g. the path "search" with
191   - * parameters "q" : "facebook" would produce a query for the
192   - * following graph resource:
193   - * https://graph.facebook.com/search?q=facebook
194   - * @param listener
195   - * Callback interface to notify the application when the request
196   - * has completed.
197   - * @param state
198   - * An arbitrary object used to identify the request when it
199   - * returns to the callback. This has no effect on the request
200   - * itself.
201   - */
202   - public void request(String graphPath,
203   - Bundle parameters,
204   - RequestListener listener,
205   - final Object state) {
206   - request(graphPath, parameters, "GET", listener, state);
207   - }
208   -
209   - public void request(String graphPath,
210   - Bundle parameters,
211   - RequestListener listener) {
212   - request(graphPath, parameters, "GET", listener, /* state */ null);
213   - }
214   -
215   - /**
216   - * Make a request to the Facebook Graph API with the given HTTP method and
217   - * string parameters. Note that binary data parameters (e.g. pictures) are
218   - * not yet supported by this helper function.
219   - *
220   - * See http://developers.facebook.com/docs/api
221   - *
222   - * Note that this method is asynchronous and the callback will be invoked
223   - * in a background thread; operations that affect the UI will need to be
224   - * posted to the UI thread or an appropriate handler.
225   - *
226   - * @param graphPath
227   - * Path to resource in the Facebook graph, e.g., to fetch data
228   - * about the currently logged authenticated user, provide "me",
229   - * which will fetch http://graph.facebook.com/me
230   - * @param parameters
231   - * key-value string parameters, e.g. the path "search" with
232   - * parameters {"q" : "facebook"} would produce a query for the
233   - * following graph resource:
234   - * https://graph.facebook.com/search?q=facebook
235   - * @param httpMethod
236   - * http verb, e.g. "POST", "DELETE"
237   - * @param listener
238   - * Callback interface to notify the application when the request
239   - * has completed.
240   - * @param state
241   - * An arbitrary object used to identify the request when it
242   - * returns to the callback. This has no effect on the request
243   - * itself.
244   - */
245   - public void request(final String graphPath,
246   - final Bundle parameters,
247   - final String httpMethod,
248   - final RequestListener listener,
249   - final Object state) {
250   - new Thread() {
251   - @Override public void run() {
252   - try {
253   - String resp = fb.request(graphPath, parameters, httpMethod);
254   - listener.onComplete(resp, state);
255   - } catch (FileNotFoundException e) {
256   - listener.onFileNotFoundException(e, state);
257   - } catch (MalformedURLException e) {
258   - listener.onMalformedURLException(e, state);
259   - } catch (IOException e) {
260   - listener.onIOException(e, state);
261   - }
262   - }
263   - }.start();
264   - }
265   -
266   - /**
267   - * Callback interface for API requests.
268   - *
269   - * Each method includes a 'state' parameter that identifies the calling
270   - * request. It will be set to the value passed when originally calling the
271   - * request method, or null if none was passed.
272   - */
273   - public static interface RequestListener {
274   -
275   - /**
276   - * Called when a request completes with the given response.
277   - *
278   - * Executed by a background thread: do not update the UI in this method.
279   - */
280   - public void onComplete(String response, Object state);
281   -
282   - /**
283   - * Called when a request has a network or request error.
284   - *
285   - * Executed by a background thread: do not update the UI in this method.
286   - */
287   - public void onIOException(IOException e, Object state);
288   -
289   - /**
290   - * Called when a request fails because the requested resource is
291   - * invalid or does not exist.
292   - *
293   - * Executed by a background thread: do not update the UI in this method.
294   - */
295   - public void onFileNotFoundException(FileNotFoundException e,
296   - Object state);
297   -
298   - /**
299   - * Called if an invalid graph path is provided (which may result in a
300   - * malformed URL).
301   - *
302   - * Executed by a background thread: do not update the UI in this method.
303   - */
304   - public void onMalformedURLException(MalformedURLException e,
305   - Object state);
306   -
307   - /**
308   - * Called when the server-side Facebook method fails.
309   - *
310   - * Executed by a background thread: do not update the UI in this method.
311   - */
312   - public void onFacebookError(FacebookError e, Object state);
313   -
314   - }
315   -
316   -}
51 src/android/java/com/facebook/android/DialogError.java
... ... @@ -1,51 +0,0 @@
1   -/*
2   - * Copyright 2010 Facebook, Inc.
3   - *
4   - * Licensed under the Apache License, Version 2.0 (the "License");
5   - * you may not use this file except in compliance with the License.
6   - * You may obtain a copy of the License at
7   - *
8   - * http://www.apache.org/licenses/LICENSE-2.0
9   - *
10   - * Unless required by applicable law or agreed to in writing, software
11   - * distributed under the License is distributed on an "AS IS" BASIS,
12   - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   - * See the License for the specific language governing permissions and
14   - * limitations under the License.
15   - */
16   -
17   -package com.facebook.android;
18   -
19   -/**
20   - * Encapsulation of Dialog Error.
21   - *
22   - * @author ssoneff@facebook.com
23   - */
24   -public class DialogError extends Throwable {
25   -
26   - private static final long serialVersionUID = 1L;
27   -
28   - /**
29   - * The ErrorCode received by the WebView: see
30   - * http://developer.android.com/reference/android/webkit/WebViewClient.html
31   - */
32   - private int mErrorCode;
33   -
34   - /** The URL that the dialog was trying to load */
35   - private String mFailingUrl;
36   -
37   - public DialogError(String message, int errorCode, String failingUrl) {
38   - super(message);
39   - mErrorCode = errorCode;
40   - mFailingUrl = failingUrl;
41   - }
42   -
43   - int getErrorCode() {
44   - return mErrorCode;
45   - }
46   -
47   - String getFailingUrl() {
48   - return mFailingUrl;
49   - }
50   -
51   -}
980 src/android/java/com/facebook/android/Facebook.java
... ... @@ -1,980 +0,0 @@
1   -/*
2   - * Copyright 2010 Facebook, Inc.
3   - *
4   - * Licensed under the Apache License, Version 2.0 (the "License");
5   - * you may not use this file except in compliance with the License.
6   - * You may obtain a copy of the License at
7   - *
8   - * http://www.apache.org/licenses/LICENSE-2.0
9   - *
10   - * Unless required by applicable law or agreed to in writing, software
11   - * distributed under the License is distributed on an "AS IS" BASIS,
12   - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   - * See the License for the specific language governing permissions and
14   - * limitations under the License.
15   - */
16   -
17   -package com.facebook.android;
18   -
19   -import java.io.FileNotFoundException;
20   -import java.io.IOException;
21   -import java.net.MalformedURLException;
22   -
23   -import android.Manifest;
24   -import android.app.Activity;
25   -import android.content.ActivityNotFoundException;
26   -import android.content.ComponentName;
27   -import android.content.Context;
28   -import android.content.Intent;
29   -import android.content.ServiceConnection;
30   -import android.content.pm.PackageInfo;
31   -import android.content.pm.PackageManager;
32   -import android.content.pm.PackageManager.NameNotFoundException;
33   -import android.content.pm.ResolveInfo;
34   -import android.content.pm.Signature;
35   -import android.os.Bundle;
36   -import android.os.Handler;
37   -import android.os.IBinder;
38   -import android.os.Message;
39   -import android.os.Messenger;
40   -import android.os.RemoteException;
41   -import android.text.TextUtils;
42   -import android.webkit.CookieSyncManager;
43   -
44   -/**
45   - * Main Facebook object for interacting with the Facebook developer API.
46   - * Provides methods to log in and log out a user, make requests using the REST
47   - * and Graph APIs, and start user interface interactions with the API (such as
48   - * pop-ups promoting for credentials, permissions, stream posts, etc.)
49   - *
50   - * @author Jim Brusstar (jimbru@facebook.com),
51   - * Yariv Sadan (yariv@facebook.com),
52   - * Luke Shepard (lshepard@facebook.com)
53   - */
54   -public class Facebook {
55   -
56   - // Strings used in the authorization flow
57   - public static final String REDIRECT_URI = "fbconnect://success";
58   - public static final String CANCEL_URI = "fbconnect://cancel";
59   - public static final String TOKEN = "access_token";
60   - public static final String EXPIRES = "expires_in";
61   - public static final String SINGLE_SIGN_ON_DISABLED = "service_disabled";
62   -
63   - public static final int FORCE_DIALOG_AUTH = -1;
64   -
65   - private static final String LOGIN = "oauth";
66   -
67   - // Used as default activityCode by authorize(). See authorize() below.
68   - private static final int DEFAULT_AUTH_ACTIVITY_CODE = 32665;
69   -
70   - // Facebook server endpoints: may be modified in a subclass for testing
71   - protected static String DIALOG_BASE_URL =
72   - "https://m.facebook.com/dialog/";
73   - protected static String GRAPH_BASE_URL =
74   - "https://graph.facebook.com/";
75   - protected static String RESTSERVER_URL =
76   - "https://api.facebook.com/restserver.php";
77   -
78   - private String mAccessToken = null;
79   - private long mLastAccessUpdate = 0;
80   - private long mAccessExpires = 0;
81   - private String mAppId;
82   -
83   - private Activity mAuthActivity;
84   - private String[] mAuthPermissions;
85   - private int mAuthActivityCode;
86   - private DialogListener mAuthDialogListener;
87   -
88   - // If the last time we extended the access token was more than 24 hours ago
89   - // we try to refresh the access token again.
90   - final private long REFRESH_TOKEN_BARRIER = 24L * 60L * 60L * 1000L;
91   -
92   - /**
93   - * Constructor for Facebook object.
94   - *
95   - * @param appId
96   - * Your Facebook application ID. Found at
97   - * www.facebook.com/developers/apps.php.
98   - */
99   - public Facebook(String appId) {
100   - if (appId == null) {
101   - throw new IllegalArgumentException(
102   - "You must specify your application ID when instantiating " +
103   - "a Facebook object. See README for details.");
104   - }
105   - mAppId = appId;
106   - }
107   -
108   - /**
109   - * Default authorize method. Grants only basic permissions.
110   - *
111   - * See authorize() below for @params.
112   - */
113   - public void authorize(Activity activity, final DialogListener listener) {
114   - authorize(activity, new String[] {}, DEFAULT_AUTH_ACTIVITY_CODE,
115   - listener);
116   - }
117   -
118   - /**
119   - * Authorize method that grants custom permissions.
120   - *
121   - * See authorize() below for @params.
122   - */
123   - public void authorize(Activity activity, String[] permissions,
124   - final DialogListener listener) {
125   - authorize(activity, permissions, DEFAULT_AUTH_ACTIVITY_CODE, listener);
126   - }
127   -
128   - /**
129   - * Full authorize method.
130   - *
131   - * Starts either an Activity or a dialog which prompts the user to log in to
132   - * Facebook and grant the requested permissions to the given application.
133   - *
134   - * This method will, when possible, use Facebook's single sign-on for
135   - * Android to obtain an access token. This involves proxying a call through
136   - * the Facebook for Android stand-alone application, which will handle the
137   - * authentication flow, and return an OAuth access token for making API
138   - * calls.
139   - *
140   - * Because this process will not be available for all users, if single
141   - * sign-on is not possible, this method will automatically fall back to the
142   - * OAuth 2.0 User-Agent flow. In this flow, the user credentials are handled
143   - * by Facebook in an embedded WebView, not by the client application. As
144   - * such, the dialog makes a network request and renders HTML content rather
145   - * than a native UI. The access token is retrieved from a redirect to a
146   - * special URL that the WebView handles.
147   - *
148   - * Note that User credentials could be handled natively using the OAuth 2.0
149   - * Username and Password Flow, but this is not supported by this SDK.
150   - *
151   - * See http://developers.facebook.com/docs/authentication/ and
152   - * http://wiki.oauth.net/OAuth-2 for more details.
153   - *
154   - * Note that this method is asynchronous and the callback will be invoked in
155   - * the original calling thread (not in a background thread).
156   - *
157   - * Also note that requests may be made to the API without calling authorize
158   - * first, in which case only public information is returned.
159   - *
160   - * IMPORTANT: Note that single sign-on authentication will not function
161   - * correctly if you do not include a call to the authorizeCallback() method
162   - * in your onActivityResult() function! Please see below for more
163   - * information. single sign-on may be disabled by passing FORCE_DIALOG_AUTH
164   - * as the activityCode parameter in your call to authorize().
165   - *
166   - * @param activity
167   - * The Android activity in which we want to display the
168   - * authorization dialog.
169   - * @param applicationId
170   - * The Facebook application identifier e.g. "350685531728"
171   - * @param permissions
172   - * A list of permissions required for this application: e.g.
173   - * "read_stream", "publish_stream", "offline_access", etc. see
174   - * http://developers.facebook.com/docs/authentication/permissions
175   - * This parameter should not be null -- if you do not require any
176   - * permissions, then pass in an empty String array.
177   - * @param activityCode
178   - * Single sign-on requires an activity result to be called back
179   - * to the client application -- if you are waiting on other
180   - * activities to return data, pass a custom activity code here to
181   - * avoid collisions. If you would like to force the use of legacy
182   - * dialog-based authorization, pass FORCE_DIALOG_AUTH for this
183   - * parameter. Otherwise just omit this parameter and Facebook
184   - * will use a suitable default. See
185   - * http://developer.android.com/reference/android/
186   - * app/Activity.html for more information.
187   - * @param listener
188   - * Callback interface for notifying the calling application when
189   - * the authentication dialog has completed, failed, or been
190   - * canceled.
191   - */
192   - public void authorize(Activity activity, String[] permissions,
193   - int activityCode, final DialogListener listener) {
194   -
195   - boolean singleSignOnStarted = false;
196   -
197   - mAuthDialogListener = listener;
198   -
199   - // Prefer single sign-on, where available.
200   - if (activityCode >= 0) {
201   - singleSignOnStarted = startSingleSignOn(activity, mAppId,
202   - permissions, activityCode);
203   - }
204   - // Otherwise fall back to traditional dialog.
205   - if (!singleSignOnStarted) {
206   - startDialogAuth(activity, permissions);
207   - }
208   - }
209   -
210   - /**
211   - * Internal method to handle single sign-on backend for authorize().
212   - *
213   - * @param activity
214   - * The Android Activity that will parent the ProxyAuth Activity.
215   - * @param applicationId
216   - * The Facebook application identifier.
217   - * @param permissions
218   - * A list of permissions required for this application. If you do
219   - * not require any permissions, pass an empty String array.
220   - * @param activityCode
221   - * Activity code to uniquely identify the result Intent in the
222   - * callback.
223   - */
224   - private boolean startSingleSignOn(Activity activity, String applicationId,
225   - String[] permissions, int activityCode) {
226   - boolean didSucceed = true;
227   - Intent intent = new Intent();
228   -
229   - intent.setClassName("com.facebook.katana",
230   - "com.facebook.katana.ProxyAuth");
231   - intent.putExtra("client_id", applicationId);
232   - if (permissions.length > 0) {
233   - intent.putExtra("scope", TextUtils.join(",", permissions));
234   - }
235   -
236   - // Verify that the application whose package name is
237   - // com.facebook.katana.ProxyAuth
238   - // has the expected FB app signature.
239   - if (!validateActivityIntent(activity, intent)) {
240   - return false;
241   - }
242   -
243   - mAuthActivity = activity;
244   - mAuthPermissions = permissions;
245   - mAuthActivityCode = activityCode;
246   - try {
247   - activity.startActivityForResult(intent, activityCode);
248   - } catch (ActivityNotFoundException e) {
249   - didSucceed = false;
250   - }
251   -
252   - return didSucceed;
253   - }
254   -
255   - /**
256   - * Helper to validate an activity intent by resolving and checking the
257   - * provider's package signature.
258   - *
259   - * @param context
260   - * @param intent
261   - * @return true if the service intent resolution happens successfully and the
262   - * signatures match.
263   - */
264   - private boolean validateActivityIntent(Context context, Intent intent) {
265   - ResolveInfo resolveInfo =
266   - context.getPackageManager().resolveActivity(intent, 0);
267   - if (resolveInfo == null) {
268   - return false;
269   - }
270   -
271   - return validateAppSignatureForPackage(
272   - context,
273   - resolveInfo.activityInfo.packageName);
274   - }
275   -
276   -
277   - /**
278   - * Helper to validate a service intent by resolving and checking the
279   - * provider's package signature.
280   - *
281   - * @param context
282   - * @param intent
283   - * @return true if the service intent resolution happens successfully and the
284   - * signatures match.
285   - */
286   - private boolean validateServiceIntent(Context context, Intent intent) {
287   - ResolveInfo resolveInfo =
288   - context.getPackageManager().resolveService(intent, 0);
289   - if (resolveInfo == null) {
290   - return false;
291   - }
292   -
293   - return validateAppSignatureForPackage(
294   - context,
295   - resolveInfo.serviceInfo.packageName);
296   - }
297   -
298   - /**
299   - * Query the signature for the application that would be invoked by the
300   - * given intent and verify that it matches the FB application's signature.
301   - *
302   - * @param context
303   - * @param packageName
304   - * @return true if the app's signature matches the expected signature.
305   - */
306   - private boolean validateAppSignatureForPackage(Context context,
307   - String packageName) {
308   -
309   - PackageInfo packageInfo;
310   - try {
311   - packageInfo = context.getPackageManager().getPackageInfo(
312   - packageName, PackageManager.GET_SIGNATURES);
313   - } catch (NameNotFoundException e) {
314   - return false;
315   - }
316   -
317   - for (Signature signature : packageInfo.signatures) {
318   - if (signature.toCharsString().equals(FB_APP_SIGNATURE)) {
319   - return true;
320   - }
321   - }
322   - return false;
323   - }
324   -
325   - /**
326   - * Internal method to handle dialog-based authentication backend for
327   - * authorize().
328   - *
329   - * @param activity
330   - * The Android Activity that will parent the auth dialog.
331   - * @param applicationId
332   - * The Facebook application identifier.
333   - * @param permissions
334   - * A list of permissions required for this application. If you do
335   - * not require any permissions, pass an empty String array.
336   - */
337   - private void startDialogAuth(Activity activity, String[] permissions) {
338   - Bundle params = new Bundle();
339   - if (permissions.length > 0) {
340   - params.putString("scope", TextUtils.join(",", permissions));
341   - }
342   - CookieSyncManager.createInstance(activity);
343   - dialog(activity, LOGIN, params, new DialogListener() {
344   -
345   - public void onComplete(Bundle values) {
346   - // ensure any cookies set by the dialog are saved
347   - CookieSyncManager.getInstance().sync();
348   - setAccessToken(values.getString(TOKEN));
349   - setAccessExpiresIn(values.getString(EXPIRES));
350   - if (isSessionValid()) {
351   - Util.logd("Facebook-authorize", "Login Success! access_token="
352   - + getAccessToken() + " expires="
353   - + getAccessExpires());
354   - mAuthDialogListener.onComplete(values);
355   - } else {
356   - mAuthDialogListener.onFacebookError(new FacebookError(
357   - "Failed to receive access token."));
358   - }
359   - }
360   -
361   - public void onError(DialogError error) {
362   - Util.logd("Facebook-authorize", "Login failed: " + error);
363   - mAuthDialogListener.onError(error);
364   - }
365   -
366   - public void onFacebookError(FacebookError error) {
367   - Util.logd("Facebook-authorize", "Login failed: " + error);
368   - mAuthDialogListener.onFacebookError(error);
369   - }
370   -
371   - public void onCancel() {
372   - Util.logd("Facebook-authorize", "Login canceled");
373   - mAuthDialogListener.onCancel();
374   - }
375   - });
376   - }
377   -
378   - /**
379   - * IMPORTANT: This method must be invoked at the top of the calling
380   - * activity's onActivityResult() function or Facebook authentication will
381   - * not function properly!
382   - *
383   - * If your calling activity does not currently implement onActivityResult(),
384   - * you must implement it and include a call to this method if you intend to
385   - * use the authorize() method in this SDK.
386   - *
387   - * For more information, see
388   - * http://developer.android.com/reference/android/app/
389   - * Activity.html#onActivityResult(int, int, android.content.Intent)
390   - */
391   - public void authorizeCallback(int requestCode, int resultCode, Intent data) {
392   - if (requestCode == mAuthActivityCode) {
393   -
394   - // Successfully redirected.
395   - if (resultCode == Activity.RESULT_OK) {
396   -
397   - // Check OAuth 2.0/2.10 error code.
398   - String error = data.getStringExtra("error");
399   - if (error == null) {
400   - error = data.getStringExtra("error_type");
401   - }
402   -
403   - // A Facebook error occurred.
404   - if (error != null) {
405   - if (error.equals(SINGLE_SIGN_ON_DISABLED)
406   - || error.equals("AndroidAuthKillSwitchException")) {
407   - Util.logd("Facebook-authorize", "Hosted auth currently "
408   - + "disabled. Retrying dialog auth...");
409   - startDialogAuth(mAuthActivity, mAuthPermissions);
410   - } else if (error.equals("access_denied")
411   - || error.equals("OAuthAccessDeniedException")) {
412   - Util.logd("Facebook-authorize", "Login canceled by user.");
413   - mAuthDialogListener.onCancel();
414   - } else {
415   - String description = data.getStringExtra("error_description");
416   - if (description != null) {
417   - error = error + ":" + description;
418   - }
419   - Util.logd("Facebook-authorize", "Login failed: " + error);
420   - mAuthDialogListener.onFacebookError(
421   - new FacebookError(error));
422   - }
423   -
424   - // No errors.
425   - } else {
426   - setAccessToken(data.getStringExtra(TOKEN));
427   - setAccessExpiresIn(data.getStringExtra(EXPIRES));
428   - if (isSessionValid()) {
429   - Util.logd("Facebook-authorize",
430   - "Login Success! access_token="
431   - + getAccessToken() + " expires="
432   - + getAccessExpires());
433   - mAuthDialogListener.onComplete(data.getExtras());
434   - } else {
435   - mAuthDialogListener.onFacebookError(new FacebookError(
436   - "Failed to receive access token."));
437   - }
438   - }
439   -
440   - // An error occurred before we could be redirected.
441   - } else if (resultCode == Activity.RESULT_CANCELED) {
442   -
443   - // An Android error occured.
444   - if (data != null) {
445   - Util.logd("Facebook-authorize",
446   - "Login failed: " + data.getStringExtra("error"));
447   - mAuthDialogListener.onError(
448   - new DialogError(
449   - data.getStringExtra("error"),
450   - data.getIntExtra("error_code", -1),
451   - data.getStringExtra("failing_url")));
452   -
453   - // User pressed the 'back' button.
454   - } else {
455   - Util.logd("Facebook-authorize", "Login canceled by user.");
456   - mAuthDialogListener.onCancel();
457   - }
458   - }
459   - }
460   - }
461   -
462   - /**
463   - * Refresh OAuth access token method. Binds to Facebook for Android
464   - * stand-alone application application to refresh the access token. This
465   - * method tries to connect to the Facebook App which will handle the
466   - * authentication flow, and return a new OAuth access token. This method
467   - * will automatically replace the old token with a new one. Note that this
468   - * method is asynchronous and the callback will be invoked in the original
469   - * calling thread (not in a background thread).
470   - *
471   - * @param context
472   - * The Android Context that will be used to bind to the Facebook
473   - * RefreshToken Service
474   - * @param serviceListener
475   - * Callback interface for notifying the calling application when
476   - * the refresh request has completed or failed (can be null). In
477   - * case of a success a new token can be found inside the result
478   - * Bundle under Facebook.ACCESS_TOKEN key.
479   - * @return true if the binding to the RefreshToken Service was created
480   - */
481   - public boolean extendAccessToken(Context context, ServiceListener serviceListener) {
482   - Intent intent = new Intent();
483   -
484   - intent.setClassName("com.facebook.katana",
485   - "com.facebook.katana.platform.TokenRefreshService");
486   -
487   - // Verify that the application whose package name is
488   - // com.facebook.katana
489   - // has the expected FB app signature.
490   - if (!validateServiceIntent(context, intent)) {
491   - return false;
492   - }
493   -
494   - return context.bindService(intent,
495   - new TokenRefreshServiceConnection(context, serviceListener),
496   - Context.BIND_AUTO_CREATE);
497   - }
498   -
499   - /**
500   - * Calls extendAccessToken if shouldExtendAccessToken returns true.
501   - *
502   - * @return the same value as extendAccessToken if the the token requires
503   - * refreshing, true otherwise
504   - */
505   - public boolean extendAccessTokenIfNeeded(Context context, ServiceListener serviceListener) {
506   - if (shouldExtendAccessToken()) {
507   - return extendAccessToken(context, serviceListener);
508   - }
509   - return true;
510   - }
511   -
512   - /**
513   - * Check if the access token requires refreshing.
514   - *
515   - * @return true if the last time a new token was obtained was over 24 hours ago.
516   - */
517   - public boolean shouldExtendAccessToken() {
518   - return isSessionValid() &&
519   - (System.currentTimeMillis() - mLastAccessUpdate >= REFRESH_TOKEN_BARRIER);
520   - }
521   -
522   - /**
523   - * Handles connection to the token refresh service (this service is a part
524   - * of Facebook App).
525   - */
526   - private class TokenRefreshServiceConnection implements ServiceConnection {
527   -
528   - final Messenger messageReceiver = new Messenger(new Handler() {
529   - @Override
530   - public void handleMessage(Message msg) {
531   - String token = msg.getData().getString(TOKEN);
532   - long expiresAt = msg.getData().getLong(EXPIRES) * 1000L;
533   -
534   - // To avoid confusion we should return the expiration time in
535   - // the same format as the getAccessExpires() function - that
536   - // is in milliseconds.
537   - Bundle resultBundle = (Bundle) msg.getData().clone();
538   - resultBundle.putLong(EXPIRES, expiresAt);
539   -
540   - if (token != null) {
541   - setAccessToken(token);
542   - setAccessExpires(expiresAt);
543   - if (serviceListener != null) {
544   - serviceListener.onComplete(resultBundle);
545   - }
546   - } else if (serviceListener != null) { // extract errors only if client wants them
547   - String error = msg.getData().getString("error");
548   - if (msg.getData().containsKey("error_code")) {
549   - int errorCode = msg.getData().getInt("error_code");
550   - serviceListener.onFacebookError(new FacebookError(error, null, errorCode));
551   - } else {
552   - serviceListener.onError(new Error(error != null ? error
553   - : "Unknown service error"));
554   - }
555   - }
556   -
557   - // The refreshToken function should be called rarely,
558   - // so there is no point in keeping the binding open.
559   - applicationsContext.unbindService(TokenRefreshServiceConnection.this);
560   - }
561   - });
562   -
563   - final ServiceListener serviceListener;
564   - final Context applicationsContext;
565   -
566   - Messenger messageSender = null;
567   -
568