Clean up sample code to look better.

Change-Id: I91bdfc7ce2d32f23dc7ce9a4276cba37d7fafc42
This commit is contained in:
Megha Joshi
2010-08-13 10:57:39 -07:00
parent 4779ab6f9a
commit c51da235c2
15 changed files with 430 additions and 300 deletions

View File

@@ -13,7 +13,6 @@
* License for the specific language governing permissions and limitations under * License for the specific language governing permissions and limitations under
* the License. * the License.
*/ */
package com.example.android.samplesync; package com.example.android.samplesync;
public class Constants { public class Constants {
@@ -26,7 +25,5 @@ public class Constants {
/** /**
* Authtoken type string. * Authtoken type string.
*/ */
public static final String AUTHTOKEN_TYPE = public static final String AUTHTOKEN_TYPE = "com.example.android.samplesync";
"com.example.android.samplesync";
} }

View File

@@ -13,7 +13,6 @@
* License for the specific language governing permissions and limitations under * License for the specific language governing permissions and limitations under
* the License. * the License.
*/ */
package com.example.android.samplesync.authenticator; package com.example.android.samplesync.authenticator;
import android.app.Service; import android.app.Service;
@@ -26,7 +25,9 @@ import android.util.Log;
* and returns its IBinder. * and returns its IBinder.
*/ */
public class AuthenticationService extends Service { public class AuthenticationService extends Service {
private static final String TAG = "AuthenticationService"; private static final String TAG = "AuthenticationService";
private Authenticator mAuthenticator; private Authenticator mAuthenticator;
@Override @Override
@@ -47,9 +48,8 @@ public class AuthenticationService extends Service {
@Override @Override
public IBinder onBind(Intent intent) { public IBinder onBind(Intent intent) {
if (Log.isLoggable(TAG, Log.VERBOSE)) { if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, Log.v(TAG, "getBinder()... returning the AccountAuthenticator binder for intent "
"getBinder()... returning the AccountAuthenticator binder for intent " + intent);
+ intent);
} }
return mAuthenticator.getIBinder(); return mAuthenticator.getIBinder();
} }

View File

@@ -13,7 +13,6 @@
* License for the specific language governing permissions and limitations under * License for the specific language governing permissions and limitations under
* the License. * the License.
*/ */
package com.example.android.samplesync.authenticator; package com.example.android.samplesync.authenticator;
import android.accounts.AbstractAccountAuthenticator; import android.accounts.AbstractAccountAuthenticator;
@@ -33,6 +32,7 @@ import com.example.android.samplesync.client.NetworkUtilities;
* authenticating accounts in the com.example.android.samplesync domain. * authenticating accounts in the com.example.android.samplesync domain.
*/ */
class Authenticator extends AbstractAccountAuthenticator { class Authenticator extends AbstractAccountAuthenticator {
// Authentication Service context // Authentication Service context
private final Context mContext; private final Context mContext;
@@ -41,34 +41,25 @@ class Authenticator extends AbstractAccountAuthenticator {
mContext = context; mContext = context;
} }
/**
* {@inheritDoc}
*/
@Override @Override
public Bundle addAccount(AccountAuthenticatorResponse response, public Bundle addAccount(AccountAuthenticatorResponse response, String accountType,
String accountType, String authTokenType, String[] requiredFeatures, String authTokenType, String[] requiredFeatures, Bundle options) {
Bundle options) {
final Intent intent = new Intent(mContext, AuthenticatorActivity.class); final Intent intent = new Intent(mContext, AuthenticatorActivity.class);
intent.putExtra(AuthenticatorActivity.PARAM_AUTHTOKEN_TYPE, intent.putExtra(AuthenticatorActivity.PARAM_AUTHTOKEN_TYPE, authTokenType);
authTokenType); intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);
intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE,
response);
final Bundle bundle = new Bundle(); final Bundle bundle = new Bundle();
bundle.putParcelable(AccountManager.KEY_INTENT, intent); bundle.putParcelable(AccountManager.KEY_INTENT, intent);
return bundle; return bundle;
} }
/**
* {@inheritDoc}
*/
@Override @Override
public Bundle confirmCredentials(AccountAuthenticatorResponse response, public Bundle confirmCredentials(AccountAuthenticatorResponse response, Account account,
Account account, Bundle options) { Bundle options) {
if (options != null && options.containsKey(AccountManager.KEY_PASSWORD)) { if (options != null && options.containsKey(AccountManager.KEY_PASSWORD)) {
final String password = final String password = options.getString(AccountManager.KEY_PASSWORD);
options.getString(AccountManager.KEY_PASSWORD); final boolean verified = onlineConfirmPassword(account.name, password);
final boolean verified =
onlineConfirmPassword(account.name, password);
final Bundle result = new Bundle(); final Bundle result = new Bundle();
result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, verified); result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, verified);
return result; return result;
@@ -76,45 +67,35 @@ class Authenticator extends AbstractAccountAuthenticator {
// Launch AuthenticatorActivity to confirm credentials // Launch AuthenticatorActivity to confirm credentials
final Intent intent = new Intent(mContext, AuthenticatorActivity.class); final Intent intent = new Intent(mContext, AuthenticatorActivity.class);
intent.putExtra(AuthenticatorActivity.PARAM_USERNAME, account.name); intent.putExtra(AuthenticatorActivity.PARAM_USERNAME, account.name);
intent.putExtra(AuthenticatorActivity.PARAM_CONFIRMCREDENTIALS, true); intent.putExtra(AuthenticatorActivity.PARAM_CONFIRM_CREDENTIALS, true);
intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);
response);
final Bundle bundle = new Bundle(); final Bundle bundle = new Bundle();
bundle.putParcelable(AccountManager.KEY_INTENT, intent); bundle.putParcelable(AccountManager.KEY_INTENT, intent);
return bundle; return bundle;
} }
/**
* {@inheritDoc}
*/
@Override @Override
public Bundle editProperties(AccountAuthenticatorResponse response, public Bundle editProperties(AccountAuthenticatorResponse response, String accountType) {
String accountType) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
/**
* {@inheritDoc}
*/
@Override @Override
public Bundle getAuthToken(AccountAuthenticatorResponse response, public Bundle getAuthToken(AccountAuthenticatorResponse response, Account account,
Account account, String authTokenType, Bundle loginOptions) { String authTokenType, Bundle loginOptions) {
if (!authTokenType.equals(Constants.AUTHTOKEN_TYPE)) { if (!authTokenType.equals(Constants.AUTHTOKEN_TYPE)) {
final Bundle result = new Bundle(); final Bundle result = new Bundle();
result.putString(AccountManager.KEY_ERROR_MESSAGE, result.putString(AccountManager.KEY_ERROR_MESSAGE, "invalid authTokenType");
"invalid authTokenType");
return result; return result;
} }
final AccountManager am = AccountManager.get(mContext); final AccountManager am = AccountManager.get(mContext);
final String password = am.getPassword(account); final String password = am.getPassword(account);
if (password != null) { if (password != null) {
final boolean verified = final boolean verified = onlineConfirmPassword(account.name, password);
onlineConfirmPassword(account.name, password);
if (verified) { if (verified) {
final Bundle result = new Bundle(); final Bundle result = new Bundle();
result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name); result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
result.putString(AccountManager.KEY_ACCOUNT_TYPE, result.putString(AccountManager.KEY_ACCOUNT_TYPE, Constants.ACCOUNT_TYPE);
Constants.ACCOUNT_TYPE);
result.putString(AccountManager.KEY_AUTHTOKEN, password); result.putString(AccountManager.KEY_AUTHTOKEN, password);
return result; return result;
} }
@@ -123,33 +104,25 @@ class Authenticator extends AbstractAccountAuthenticator {
// Activity that will prompt the user for the password. // Activity that will prompt the user for the password.
final Intent intent = new Intent(mContext, AuthenticatorActivity.class); final Intent intent = new Intent(mContext, AuthenticatorActivity.class);
intent.putExtra(AuthenticatorActivity.PARAM_USERNAME, account.name); intent.putExtra(AuthenticatorActivity.PARAM_USERNAME, account.name);
intent.putExtra(AuthenticatorActivity.PARAM_AUTHTOKEN_TYPE, intent.putExtra(AuthenticatorActivity.PARAM_AUTHTOKEN_TYPE, authTokenType);
authTokenType); intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);
intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE,
response);
final Bundle bundle = new Bundle(); final Bundle bundle = new Bundle();
bundle.putParcelable(AccountManager.KEY_INTENT, intent); bundle.putParcelable(AccountManager.KEY_INTENT, intent);
return bundle; return bundle;
} }
/**
* {@inheritDoc}
*/
@Override @Override
public String getAuthTokenLabel(String authTokenType) { public String getAuthTokenLabel(String authTokenType) {
if (authTokenType.equals(Constants.AUTHTOKEN_TYPE)) { if (Constants.AUTHTOKEN_TYPE.equals(authTokenType)) {
return mContext.getString(R.string.label); return mContext.getString(R.string.label);
} }
return null; return null;
} }
/**
* {@inheritDoc}
*/
@Override @Override
public Bundle hasFeatures(AccountAuthenticatorResponse response, public Bundle hasFeatures(AccountAuthenticatorResponse response, Account account,
Account account, String[] features) { String[] features) {
final Bundle result = new Bundle(); final Bundle result = new Bundle();
result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, false); result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, false);
return result; return result;
@@ -159,24 +132,20 @@ class Authenticator extends AbstractAccountAuthenticator {
* Validates user's password on the server * Validates user's password on the server
*/ */
private boolean onlineConfirmPassword(String username, String password) { private boolean onlineConfirmPassword(String username, String password) {
return NetworkUtilities.authenticate(username, password, return NetworkUtilities
null/* Handler */, null/* Context */); .authenticate(username, password, null/* Handler */, null/* Context */);
} }
/**
* {@inheritDoc}
*/
@Override @Override
public Bundle updateCredentials(AccountAuthenticatorResponse response, public Bundle updateCredentials(AccountAuthenticatorResponse response, Account account,
Account account, String authTokenType, Bundle loginOptions) { String authTokenType, Bundle loginOptions) {
final Intent intent = new Intent(mContext, AuthenticatorActivity.class); final Intent intent = new Intent(mContext, AuthenticatorActivity.class);
intent.putExtra(AuthenticatorActivity.PARAM_USERNAME, account.name); intent.putExtra(AuthenticatorActivity.PARAM_USERNAME, account.name);
intent.putExtra(AuthenticatorActivity.PARAM_AUTHTOKEN_TYPE, intent.putExtra(AuthenticatorActivity.PARAM_AUTHTOKEN_TYPE, authTokenType);
authTokenType); intent.putExtra(AuthenticatorActivity.PARAM_CONFIRM_CREDENTIALS, false);
intent.putExtra(AuthenticatorActivity.PARAM_CONFIRMCREDENTIALS, false);
final Bundle bundle = new Bundle(); final Bundle bundle = new Bundle();
bundle.putParcelable(AccountManager.KEY_INTENT, intent); bundle.putParcelable(AccountManager.KEY_INTENT, intent);
return bundle; return bundle;
} }
} }

View File

@@ -13,7 +13,6 @@
* License for the specific language governing permissions and limitations under * License for the specific language governing permissions and limitations under
* the License. * the License.
*/ */
package com.example.android.samplesync.authenticator; package com.example.android.samplesync.authenticator;
import android.accounts.Account; import android.accounts.Account;
@@ -42,16 +41,28 @@ import com.example.android.samplesync.client.NetworkUtilities;
* Activity which displays login screen to the user. * Activity which displays login screen to the user.
*/ */
public class AuthenticatorActivity extends AccountAuthenticatorActivity { public class AuthenticatorActivity extends AccountAuthenticatorActivity {
public static final String PARAM_CONFIRMCREDENTIALS = "confirmCredentials";
/** The Intent flag to confirm credentials. **/
public static final String PARAM_CONFIRM_CREDENTIALS = "confirmCredentials";
/** The Intent extra to store password. **/
public static final String PARAM_PASSWORD = "password"; public static final String PARAM_PASSWORD = "password";
/** The Intent extra to store username. **/
public static final String PARAM_USERNAME = "username"; public static final String PARAM_USERNAME = "username";
/** The Intent extra to store authtoken type. **/
public static final String PARAM_AUTHTOKEN_TYPE = "authtokenType"; public static final String PARAM_AUTHTOKEN_TYPE = "authtokenType";
/** The tag used to log to adb console. **/
private static final String TAG = "AuthenticatorActivity"; private static final String TAG = "AuthenticatorActivity";
private AccountManager mAccountManager; private AccountManager mAccountManager;
private Thread mAuthThread; private Thread mAuthThread;
private String mAuthtoken; private String mAuthtoken;
private String mAuthtokenType; private String mAuthtokenType;
/** /**
@@ -62,14 +73,18 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity {
/** for posting authentication attempts back to UI thread */ /** for posting authentication attempts back to UI thread */
private final Handler mHandler = new Handler(); private final Handler mHandler = new Handler();
private TextView mMessage; private TextView mMessage;
private String mPassword; private String mPassword;
private EditText mPasswordEdit; private EditText mPasswordEdit;
/** Was the original caller asking for an entirely new account? */ /** Was the original caller asking for an entirely new account? */
protected boolean mRequestNewAccount = false; protected boolean mRequestNewAccount = false;
private String mUsername; private String mUsername;
private EditText mUsernameEdit; private EditText mUsernameEdit;
/** /**
@@ -77,6 +92,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity {
*/ */
@Override @Override
public void onCreate(Bundle icicle) { public void onCreate(Bundle icicle) {
Log.i(TAG, "onCreate(" + icicle + ")"); Log.i(TAG, "onCreate(" + icicle + ")");
super.onCreate(icicle); super.onCreate(icicle);
mAccountManager = AccountManager.get(this); mAccountManager = AccountManager.get(this);
@@ -85,19 +101,15 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity {
mUsername = intent.getStringExtra(PARAM_USERNAME); mUsername = intent.getStringExtra(PARAM_USERNAME);
mAuthtokenType = intent.getStringExtra(PARAM_AUTHTOKEN_TYPE); mAuthtokenType = intent.getStringExtra(PARAM_AUTHTOKEN_TYPE);
mRequestNewAccount = mUsername == null; mRequestNewAccount = mUsername == null;
mConfirmCredentials = mConfirmCredentials = intent.getBooleanExtra(PARAM_CONFIRM_CREDENTIALS, false);
intent.getBooleanExtra(PARAM_CONFIRMCREDENTIALS, false);
Log.i(TAG, " request new: " + mRequestNewAccount); Log.i(TAG, " request new: " + mRequestNewAccount);
requestWindowFeature(Window.FEATURE_LEFT_ICON); requestWindowFeature(Window.FEATURE_LEFT_ICON);
setContentView(R.layout.login_activity); setContentView(R.layout.login_activity);
getWindow().setFeatureDrawableResource(Window.FEATURE_LEFT_ICON, getWindow().setFeatureDrawableResource(Window.FEATURE_LEFT_ICON,
android.R.drawable.ic_dialog_alert); android.R.drawable.ic_dialog_alert);
mMessage = (TextView) findViewById(R.id.message); mMessage = (TextView) findViewById(R.id.message);
mUsernameEdit = (EditText) findViewById(R.id.username_edit); mUsernameEdit = (EditText) findViewById(R.id.username_edit);
mPasswordEdit = (EditText) findViewById(R.id.password_edit); mPasswordEdit = (EditText) findViewById(R.id.password_edit);
mUsernameEdit.setText(mUsername); mUsernameEdit.setText(mUsername);
mMessage.setText(getMessage()); mMessage.setText(getMessage());
} }
@@ -152,7 +164,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity {
* *
* @param the confirmCredentials result. * @param the confirmCredentials result.
*/ */
protected void finishConfirmCredentials(boolean result) { private void finishConfirmCredentials(boolean result) {
Log.i(TAG, "finishConfirmCredentials()"); Log.i(TAG, "finishConfirmCredentials()");
final Account account = new Account(mUsername, Constants.ACCOUNT_TYPE); final Account account = new Account(mUsername, Constants.ACCOUNT_TYPE);
mAccountManager.setPassword(account, mPassword); mAccountManager.setPassword(account, mPassword);
@@ -164,7 +176,6 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity {
} }
/** /**
*
* Called when response is received from the server for authentication * Called when response is received from the server for authentication
* request. See onAuthenticationResult(). Sets the * request. See onAuthenticationResult(). Sets the
* AccountAuthenticatorResult which is sent back to the caller. Also sets * AccountAuthenticatorResult which is sent back to the caller. Also sets
@@ -172,26 +183,22 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity {
* *
* @param the confirmCredentials result. * @param the confirmCredentials result.
*/ */
private void finishLogin() {
protected void finishLogin() {
Log.i(TAG, "finishLogin()"); Log.i(TAG, "finishLogin()");
final Account account = new Account(mUsername, Constants.ACCOUNT_TYPE); final Account account = new Account(mUsername, Constants.ACCOUNT_TYPE);
if (mRequestNewAccount) { if (mRequestNewAccount) {
mAccountManager.addAccountExplicitly(account, mPassword, null); mAccountManager.addAccountExplicitly(account, mPassword, null);
// Set contacts sync for this account. // Set contacts sync for this account.
ContentResolver.setSyncAutomatically(account, ContentResolver.setSyncAutomatically(account, ContactsContract.AUTHORITY, true);
ContactsContract.AUTHORITY, true);
} else { } else {
mAccountManager.setPassword(account, mPassword); mAccountManager.setPassword(account, mPassword);
} }
final Intent intent = new Intent(); final Intent intent = new Intent();
mAuthtoken = mPassword; mAuthtoken = mPassword;
intent.putExtra(AccountManager.KEY_ACCOUNT_NAME, mUsername); intent.putExtra(AccountManager.KEY_ACCOUNT_NAME, mUsername);
intent intent.putExtra(AccountManager.KEY_ACCOUNT_TYPE, Constants.ACCOUNT_TYPE);
.putExtra(AccountManager.KEY_ACCOUNT_TYPE, Constants.ACCOUNT_TYPE); if (mAuthtokenType != null && mAuthtokenType.equals(Constants.AUTHTOKEN_TYPE)) {
if (mAuthtokenType != null
&& mAuthtokenType.equals(Constants.AUTHTOKEN_TYPE)) {
intent.putExtra(AccountManager.KEY_AUTHTOKEN, mAuthtoken); intent.putExtra(AccountManager.KEY_AUTHTOKEN, mAuthtoken);
} }
setAccountAuthenticatorResult(intent.getExtras()); setAccountAuthenticatorResult(intent.getExtras());
@@ -202,7 +209,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity {
/** /**
* Hides the progress UI for a lengthy operation. * Hides the progress UI for a lengthy operation.
*/ */
protected void hideProgress() { private void hideProgress() {
dismissDialog(0); dismissDialog(0);
} }
@@ -210,6 +217,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity {
* Called when the authentication process completes (see attemptLogin()). * Called when the authentication process completes (see attemptLogin()).
*/ */
public void onAuthenticationResult(boolean result) { public void onAuthenticationResult(boolean result) {
Log.i(TAG, "onAuthenticationResult(" + result + ")"); Log.i(TAG, "onAuthenticationResult(" + result + ")");
// Hide the progress dialog // Hide the progress dialog
hideProgress(); hideProgress();
@@ -223,14 +231,12 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity {
Log.e(TAG, "onAuthenticationResult: failed to authenticate"); Log.e(TAG, "onAuthenticationResult: failed to authenticate");
if (mRequestNewAccount) { if (mRequestNewAccount) {
// "Please enter a valid username/password. // "Please enter a valid username/password.
mMessage mMessage.setText(getText(R.string.login_activity_loginfail_text_both));
.setText(getText(R.string.login_activity_loginfail_text_both));
} else { } else {
// "Please enter a valid password." (Used when the // "Please enter a valid password." (Used when the
// account is already in the database but the password // account is already in the database but the password
// doesn't work.) // doesn't work.)
mMessage mMessage.setText(getText(R.string.login_activity_loginfail_text_pwonly));
.setText(getText(R.string.login_activity_loginfail_text_pwonly));
} }
} }
} }
@@ -243,8 +249,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity {
if (TextUtils.isEmpty(mUsername)) { if (TextUtils.isEmpty(mUsername)) {
// If no username, then we ask the user to log in using an // If no username, then we ask the user to log in using an
// appropriate service. // appropriate service.
final CharSequence msg = final CharSequence msg = getText(R.string.login_activity_newaccount_text);
getText(R.string.login_activity_newaccount_text);
return msg; return msg;
} }
if (TextUtils.isEmpty(mPassword)) { if (TextUtils.isEmpty(mPassword)) {
@@ -257,7 +262,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity {
/** /**
* Shows the progress UI for a lengthy operation. * Shows the progress UI for a lengthy operation.
*/ */
protected void showProgress() { private void showProgress() {
showDialog(0); showDialog(0);
} }
} }

View File

@@ -13,7 +13,6 @@
* License for the specific language governing permissions and limitations under * License for the specific language governing permissions and limitations under
* the License. * the License.
*/ */
package com.example.android.samplesync.client; package com.example.android.samplesync.client;
import android.accounts.Account; import android.accounts.Account;
@@ -52,21 +51,36 @@ import java.util.TimeZone;
/** /**
* Provides utility methods for communicating with the server. * Provides utility methods for communicating with the server.
*/ */
public class NetworkUtilities { final public class NetworkUtilities {
/** The tag used to log to adb console. **/
private static final String TAG = "NetworkUtilities"; private static final String TAG = "NetworkUtilities";
public static final String PARAM_USERNAME = "username";
/** The Intent extra to store password. **/
public static final String PARAM_PASSWORD = "password"; public static final String PARAM_PASSWORD = "password";
/** The Intent extra to store username. **/
public static final String PARAM_USERNAME = "username";
public static final String PARAM_UPDATED = "timestamp"; public static final String PARAM_UPDATED = "timestamp";
public static final String USER_AGENT = "AuthenticationService/1.0"; public static final String USER_AGENT = "AuthenticationService/1.0";
public static final int REGISTRATION_TIMEOUT = 30 * 1000; // ms
public static final String BASE_URL = public static final int REGISTRATION_TIMEOUT_MS = 30 * 1000; // ms
"https://samplesyncadapter.appspot.com";
public static final String BASE_URL = "https://samplesyncadapter.appspot.com";
public static final String AUTH_URI = BASE_URL + "/auth"; public static final String AUTH_URI = BASE_URL + "/auth";
public static final String FETCH_FRIEND_UPDATES_URI =
BASE_URL + "/fetch_friend_updates"; public static final String FETCH_FRIEND_UPDATES_URI = BASE_URL + "/fetch_friend_updates";
public static final String FETCH_STATUS_URI = BASE_URL + "/fetch_status"; public static final String FETCH_STATUS_URI = BASE_URL + "/fetch_status";
private static HttpClient mHttpClient; private static HttpClient mHttpClient;
private NetworkUtilities() {
}
/** /**
* Configures the httpClient to connect to the URL provided. * Configures the httpClient to connect to the URL provided.
*/ */
@@ -74,10 +88,9 @@ public class NetworkUtilities {
if (mHttpClient == null) { if (mHttpClient == null) {
mHttpClient = new DefaultHttpClient(); mHttpClient = new DefaultHttpClient();
final HttpParams params = mHttpClient.getParams(); final HttpParams params = mHttpClient.getParams();
HttpConnectionParams.setConnectionTimeout(params, HttpConnectionParams.setConnectionTimeout(params, REGISTRATION_TIMEOUT_M);
REGISTRATION_TIMEOUT); HttpConnectionParams.setSoTimeout(params, REGISTRATION_TIMEOUT_MS);
HttpConnectionParams.setSoTimeout(params, REGISTRATION_TIMEOUT); ConnManagerParams.setTimeout(params, REGISTRATION_TIMEOUT_MS);
ConnManagerParams.setTimeout(params, REGISTRATION_TIMEOUT);
} }
} }
@@ -94,7 +107,6 @@ public class NetworkUtilities {
try { try {
runnable.run(); runnable.run();
} finally { } finally {
} }
} }
}; };
@@ -113,10 +125,10 @@ public class NetworkUtilities {
* @return boolean The boolean result indicating whether the user was * @return boolean The boolean result indicating whether the user was
* successfully authenticated. * successfully authenticated.
*/ */
public static boolean authenticate(String username, String password, public static boolean authenticate(String username, String password, Handler handler,
Handler handler, final Context context) { final Context context) {
final HttpResponse resp;
final HttpResponse resp;
final ArrayList<NameValuePair> params = new ArrayList<NameValuePair>(); final ArrayList<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair(PARAM_USERNAME, username)); params.add(new BasicNameValuePair(PARAM_USERNAME, username));
params.add(new BasicNameValuePair(PARAM_PASSWORD, password)); params.add(new BasicNameValuePair(PARAM_PASSWORD, password));
@@ -131,7 +143,6 @@ public class NetworkUtilities {
post.addHeader(entity.getContentType()); post.addHeader(entity.getContentType());
post.setEntity(entity); post.setEntity(entity);
maybeCreateHttpClient(); maybeCreateHttpClient();
try { try {
resp = mHttpClient.execute(post); resp = mHttpClient.execute(post);
if (resp.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { if (resp.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
@@ -189,8 +200,9 @@ public class NetworkUtilities {
* @param context The caller Activity's context * @param context The caller Activity's context
* @return Thread The thread on which the network mOperations are executed. * @return Thread The thread on which the network mOperations are executed.
*/ */
public static Thread attemptAuth(final String username, public static Thread attemptAuth(final String username, final String password,
final String password, final Handler handler, final Context context) { final Handler handler, final Context context) {
final Runnable runnable = new Runnable() { final Runnable runnable = new Runnable() {
public void run() { public void run() {
authenticate(username, password, handler, context); authenticate(username, password, handler, context);
@@ -208,32 +220,27 @@ public class NetworkUtilities {
* @param lastUpdated The last time that sync was performed * @param lastUpdated The last time that sync was performed
* @return list The list of updates received from the server. * @return list The list of updates received from the server.
*/ */
public static List<User> fetchFriendUpdates(Account account, public static List<User> fetchFriendUpdates(Account account, String authtoken, Date lastUpdated)
String authtoken, Date lastUpdated) throws JSONException, throws JSONException, ParseException, IOException, AuthenticationException {
ParseException, IOException, AuthenticationException {
final ArrayList<User> friendList = new ArrayList<User>(); final ArrayList<User> friendList = new ArrayList<User>();
final ArrayList<NameValuePair> params = new ArrayList<NameValuePair>(); final ArrayList<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair(PARAM_USERNAME, account.name)); params.add(new BasicNameValuePair(PARAM_USERNAME, account.name));
params.add(new BasicNameValuePair(PARAM_PASSWORD, authtoken)); params.add(new BasicNameValuePair(PARAM_PASSWORD, authtoken));
if (lastUpdated != null) { if (lastUpdated != null) {
final SimpleDateFormat formatter = final SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd HH:mm");
new SimpleDateFormat("yyyy/MM/dd HH:mm");
formatter.setTimeZone(TimeZone.getTimeZone("UTC")); formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
params.add(new BasicNameValuePair(PARAM_UPDATED, formatter params.add(new BasicNameValuePair(PARAM_UPDATED, formatter.format(lastUpdated)));
.format(lastUpdated)));
} }
Log.i(TAG, params.toString()); Log.i(TAG, params.toString());
HttpEntity entity = null; HttpEntity entity = null;
entity = new UrlEncodedFormEntity(params); entity = new UrlEncodedFormEntity(params);
final HttpPost post = new HttpPost(FETCH_FRIEND_UPDATES_URI); final HttpPost post = new HttpPost(FETCH_FRIEND_UPDATES_URI);
post.addHeader(entity.getContentType()); post.addHeader(entity.getContentType());
post.setEntity(entity); post.setEntity(entity);
maybeCreateHttpClient(); maybeCreateHttpClient();
final HttpResponse resp = mHttpClient.execute(post); final HttpResponse resp = mHttpClient.execute(post);
final String response = EntityUtils.toString(resp.getEntity()); final String response = EntityUtils.toString(resp.getEntity());
if (resp.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { if (resp.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
// Succesfully connected to the samplesyncadapter server and // Succesfully connected to the samplesyncadapter server and
// authenticated. // authenticated.
@@ -245,12 +252,10 @@ public class NetworkUtilities {
} }
} else { } else {
if (resp.getStatusLine().getStatusCode() == HttpStatus.SC_UNAUTHORIZED) { if (resp.getStatusLine().getStatusCode() == HttpStatus.SC_UNAUTHORIZED) {
Log.e(TAG, Log.e(TAG, "Authentication exception in fetching remote contacts");
"Authentication exception in fetching remote contacts");
throw new AuthenticationException(); throw new AuthenticationException();
} else { } else {
Log.e(TAG, "Server error in fetching remote contacts: " Log.e(TAG, "Server error in fetching remote contacts: " + resp.getStatusLine());
+ resp.getStatusLine());
throw new IOException(); throw new IOException();
} }
} }
@@ -265,24 +270,21 @@ public class NetworkUtilities {
* account * account
* @return list The list of status messages received from the server. * @return list The list of status messages received from the server.
*/ */
public static List<User.Status> fetchFriendStatuses(Account account, public static List<User.Status> fetchFriendStatuses(Account account, String authtoken)
String authtoken) throws JSONException, ParseException, IOException, throws JSONException, ParseException, IOException, AuthenticationException {
AuthenticationException {
final ArrayList<User.Status> statusList = new ArrayList<User.Status>(); final ArrayList<User.Status> statusList = new ArrayList<User.Status>();
final ArrayList<NameValuePair> params = new ArrayList<NameValuePair>(); final ArrayList<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair(PARAM_USERNAME, account.name)); params.add(new BasicNameValuePair(PARAM_USERNAME, account.name));
params.add(new BasicNameValuePair(PARAM_PASSWORD, authtoken)); params.add(new BasicNameValuePair(PARAM_PASSWORD, authtoken));
HttpEntity entity = null; HttpEntity entity = null;
entity = new UrlEncodedFormEntity(params); entity = new UrlEncodedFormEntity(params);
final HttpPost post = new HttpPost(FETCH_STATUS_URI); final HttpPost post = new HttpPost(FETCH_STATUS_URI);
post.addHeader(entity.getContentType()); post.addHeader(entity.getContentType());
post.setEntity(entity); post.setEntity(entity);
maybeCreateHttpClient(); maybeCreateHttpClient();
final HttpResponse resp = mHttpClient.execute(post); final HttpResponse resp = mHttpClient.execute(post);
final String response = EntityUtils.toString(resp.getEntity()); final String response = EntityUtils.toString(resp.getEntity());
if (resp.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { if (resp.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
// Succesfully connected to the samplesyncadapter server and // Succesfully connected to the samplesyncadapter server and
// authenticated. // authenticated.
@@ -293,8 +295,7 @@ public class NetworkUtilities {
} }
} else { } else {
if (resp.getStatusLine().getStatusCode() == HttpStatus.SC_UNAUTHORIZED) { if (resp.getStatusLine().getStatusCode() == HttpStatus.SC_UNAUTHORIZED) {
Log.e(TAG, Log.e(TAG, "Authentication exception in fetching friend status list");
"Authentication exception in fetching friend status list");
throw new AuthenticationException(); throw new AuthenticationException();
} else { } else {
Log.e(TAG, "Server error in fetching friend status list"); Log.e(TAG, "Server error in fetching friend status list");
@@ -303,5 +304,4 @@ public class NetworkUtilities {
} }
return statusList; return statusList;
} }
} }

View File

@@ -13,7 +13,6 @@
* License for the specific language governing permissions and limitations under * License for the specific language governing permissions and limitations under
* the License. * the License.
*/ */
package com.example.android.samplesync.client; package com.example.android.samplesync.client;
import android.util.Log; import android.util.Log;
@@ -23,16 +22,24 @@ import org.json.JSONObject;
/** /**
* Represents a sample SyncAdapter user * Represents a sample SyncAdapter user
*/ */
public class User { final public class User {
private final String mUserName; private final String mUserName;
private final String mFirstName; private final String mFirstName;
private final String mLastName; private final String mLastName;
private final String mCellPhone; private final String mCellPhone;
private final String mOfficePhone; private final String mOfficePhone;
private final String mHomePhone; private final String mHomePhone;
private final String mEmail; private final String mEmail;
private final boolean mDeleted; private final boolean mDeleted;
private final int mUserId; private final int mUserId;
public int getUserId() { public int getUserId() {
@@ -71,9 +78,9 @@ public class User {
return mDeleted; return mDeleted;
} }
public User(String name, String firstName, String lastName, private User(String name, String firstName, String lastName, String cellPhone,
String cellPhone, String officePhone, String homePhone, String email, String officePhone, String homePhone, String email, Boolean deleted, Integer userId) {
Boolean deleted, Integer userId) {
mUserName = name; mUserName = name;
mFirstName = firstName; mFirstName = firstName;
mLastName = lastName; mLastName = lastName;
@@ -92,34 +99,33 @@ public class User {
* @return user The new instance of Voiper user created from the JSON data. * @return user The new instance of Voiper user created from the JSON data.
*/ */
public static User valueOf(JSONObject user) { public static User valueOf(JSONObject user) {
try { try {
final String userName = user.getString("u"); final String userName = user.getString("u");
final String firstName = user.has("f") ? user.getString("f") : null; final String firstName = user.has("f") ? user.getString("f") : null;
final String lastName = user.has("l") ? user.getString("l") : null; final String lastName = user.has("l") ? user.getString("l") : null;
final String cellPhone = user.has("m") ? user.getString("m") : null; final String cellPhone = user.has("m") ? user.getString("m") : null;
final String officePhone = final String officePhone = user.has("o") ? user.getString("o") : null;
user.has("o") ? user.getString("o") : null;
final String homePhone = user.has("h") ? user.getString("h") : null; final String homePhone = user.has("h") ? user.getString("h") : null;
final String email = user.has("e") ? user.getString("e") : null; final String email = user.has("e") ? user.getString("e") : null;
final boolean deleted = final boolean deleted = user.has("d") ? user.getBoolean("d") : false;
user.has("d") ? user.getBoolean("d") : false;
final int userId = user.getInt("i"); final int userId = user.getInt("i");
return new User(userName, firstName, lastName, cellPhone, return new User(userName, firstName, lastName, cellPhone, officePhone, homePhone,
officePhone, homePhone, email, deleted, userId); email, deleted, userId);
} catch (final Exception ex) { } catch (final Exception ex) {
Log.i("User", "Error parsing JSON user object" + ex.toString()); Log.i("User", "Error parsing JSON user object" + ex.toString());
} }
return null; return null;
} }
/** /**
* Represents the User's status messages * Represents the User's status messages
* *
*/ */
public static class Status { final public static class Status {
private final Integer mUserId; private final Integer mUserId;
private final String mStatus; private final String mStatus;
public int getUserId() { public int getUserId() {
@@ -146,5 +152,4 @@ public class User {
return null; return null;
} }
} }
} }

View File

@@ -13,7 +13,6 @@
* License for the specific language governing permissions and limitations under * License for the specific language governing permissions and limitations under
* the License. * the License.
*/ */
package com.example.android.samplesync.platform; package com.example.android.samplesync.platform;
import android.content.ContentProviderOperation; import android.content.ContentProviderOperation;
@@ -29,12 +28,14 @@ import java.util.ArrayList;
/** /**
* This class handles execution of batch mOperations on Contacts provider. * This class handles execution of batch mOperations on Contacts provider.
*/ */
public class BatchOperation { final public class BatchOperation {
private final String TAG = "BatchOperation"; private final String TAG = "BatchOperation";
private final ContentResolver mResolver; private final ContentResolver mResolver;
// List for storing the batch mOperations // List for storing the batch mOperations
ArrayList<ContentProviderOperation> mOperations; private final ArrayList<ContentProviderOperation> mOperations;
public BatchOperation(Context context, ContentResolver resolver) { public BatchOperation(Context context, ContentResolver resolver) {
mResolver = resolver; mResolver = resolver;
@@ -50,6 +51,7 @@ public class BatchOperation {
} }
public void execute() { public void execute() {
if (mOperations.size() == 0) { if (mOperations.size() == 0) {
return; return;
} }
@@ -63,5 +65,4 @@ public class BatchOperation {
} }
mOperations.clear(); mOperations.clear();
} }
} }

View File

@@ -13,7 +13,6 @@
* License for the specific language governing permissions and limitations under * License for the specific language governing permissions and limitations under
* the License. * the License.
*/ */
package com.example.android.samplesync.platform; package com.example.android.samplesync.platform;
import android.content.ContentResolver; import android.content.ContentResolver;
@@ -41,10 +40,12 @@ import java.util.List;
* Class for managing contacts sync related mOperations * Class for managing contacts sync related mOperations
*/ */
public class ContactManager { public class ContactManager {
/** /**
* Custom IM protocol used when storing status messages. * Custom IM protocol used when storing status messages.
*/ */
public static final String CUSTOM_IM_PROTOCOL = "SampleSyncAdapter"; public static final String CUSTOM_IM_PROTOCOL = "SampleSyncAdapter";
private static final String TAG = "ContactManager"; private static final String TAG = "ContactManager";
/** /**
@@ -54,13 +55,12 @@ public class ContactManager {
* @param account The username for the account * @param account The username for the account
* @param users The list of users * @param users The list of users
*/ */
public static synchronized void syncContacts(Context context, public static synchronized void syncContacts(Context context, String account, List<User> users) {
String account, List<User> users) {
long userId; long userId;
long rawContactId = 0; long rawContactId = 0;
final ContentResolver resolver = context.getContentResolver(); final ContentResolver resolver = context.getContentResolver();
final BatchOperation batchOperation = final BatchOperation batchOperation = new BatchOperation(context, resolver);
new BatchOperation(context, resolver);
Log.d(TAG, "In SyncContacts"); Log.d(TAG, "In SyncContacts");
for (final User user : users) { for (final User user : users) {
userId = user.getUserId(); userId = user.getUserId();
@@ -69,8 +69,7 @@ public class ContactManager {
if (rawContactId != 0) { if (rawContactId != 0) {
if (!user.isDeleted()) { if (!user.isDeleted()) {
// update contact // update contact
updateContact(context, resolver, account, user, updateContact(context, resolver, account, user, rawContactId, batchOperation);
rawContactId, batchOperation);
} else { } else {
// delete contact // delete contact
deleteContact(context, rawContactId, batchOperation); deleteContact(context, rawContactId, batchOperation);
@@ -98,17 +97,15 @@ public class ContactManager {
* @param accountName the username of the logged in user * @param accountName the username of the logged in user
* @param statuses the list of statuses to store * @param statuses the list of statuses to store
*/ */
public static void insertStatuses(Context context, String username, public static void insertStatuses(Context context, String username, List<User.Status> list) {
List<User.Status> list) {
final ContentValues values = new ContentValues(); final ContentValues values = new ContentValues();
final ContentResolver resolver = context.getContentResolver(); final ContentResolver resolver = context.getContentResolver();
final BatchOperation batchOperation = final BatchOperation batchOperation = new BatchOperation(context, resolver);
new BatchOperation(context, resolver);
for (final User.Status status : list) { for (final User.Status status : list) {
// Look up the user's sample SyncAdapter data row // Look up the user's sample SyncAdapter data row
final long userId = status.getUserId(); final long userId = status.getUserId();
final long profileId = lookupProfile(resolver, userId); final long profileId = lookupProfile(resolver, userId);
// Insert the activity into the stream // Insert the activity into the stream
if (profileId > 0) { if (profileId > 0) {
values.put(StatusUpdates.DATA_ID, profileId); values.put(StatusUpdates.DATA_ID, profileId);
@@ -117,15 +114,11 @@ public class ContactManager {
values.put(StatusUpdates.CUSTOM_PROTOCOL, CUSTOM_IM_PROTOCOL); values.put(StatusUpdates.CUSTOM_PROTOCOL, CUSTOM_IM_PROTOCOL);
values.put(StatusUpdates.IM_ACCOUNT, username); values.put(StatusUpdates.IM_ACCOUNT, username);
values.put(StatusUpdates.IM_HANDLE, status.getUserId()); values.put(StatusUpdates.IM_HANDLE, status.getUserId());
values.put(StatusUpdates.STATUS_RES_PACKAGE, context values.put(StatusUpdates.STATUS_RES_PACKAGE, context.getPackageName());
.getPackageName());
values.put(StatusUpdates.STATUS_ICON, R.drawable.icon); values.put(StatusUpdates.STATUS_ICON, R.drawable.icon);
values.put(StatusUpdates.STATUS_LABEL, R.string.label); values.put(StatusUpdates.STATUS_LABEL, R.string.label);
batchOperation.add(ContactOperations.newInsertCpo(StatusUpdates.CONTENT_URI, true)
batchOperation .withValues(values).build());
.add(ContactOperations.newInsertCpo(
StatusUpdates.CONTENT_URI, true).withValues(values)
.build());
// A sync adapter should batch operations on multiple contacts, // A sync adapter should batch operations on multiple contacts,
// because it will make a dramatic performance difference. // because it will make a dramatic performance difference.
if (batchOperation.size() >= 50) { if (batchOperation.size() >= 50) {
@@ -143,16 +136,16 @@ public class ContactManager {
* @param accountName the account the contact belongs to * @param accountName the account the contact belongs to
* @param user the sample SyncAdapter User object * @param user the sample SyncAdapter User object
*/ */
private static void addContact(Context context, String accountName, private static void addContact(Context context, String accountName, User user,
User user, BatchOperation batchOperation) { BatchOperation batchOperation) {
// Put the data in the contacts provider // Put the data in the contacts provider
final ContactOperations contactOp = final ContactOperations contactOp =
ContactOperations.createNewContact(context, user.getUserId(), ContactOperations.createNewContact(context, user.getUserId(), accountName,
accountName, batchOperation); batchOperation);
contactOp.addName(user.getFirstName(), user.getLastName()).addEmail( contactOp.addName(user.getFirstName(), user.getLastName()).addEmail(user.getEmail())
user.getEmail()).addPhone(user.getCellPhone(), Phone.TYPE_MOBILE) .addPhone(user.getCellPhone(), Phone.TYPE_MOBILE).addPhone(user.getHomePhone(),
.addPhone(user.getHomePhone(), Phone.TYPE_OTHER).addProfileAction( Phone.TYPE_OTHER).addProfileAction(user.getUserId());
user.getUserId());
} }
/** /**
@@ -165,76 +158,57 @@ public class ContactManager {
* @param rawContactId the unique Id for this rawContact in contacts * @param rawContactId the unique Id for this rawContact in contacts
* provider * provider
*/ */
private static void updateContact(Context context, private static void updateContact(Context context, ContentResolver resolver,
ContentResolver resolver, String accountName, User user, String accountName, User user, long rawContactId, BatchOperation batchOperation) {
long rawContactId, BatchOperation batchOperation) {
Uri uri; Uri uri;
String cellPhone = null; String cellPhone = null;
String otherPhone = null; String otherPhone = null;
String email = null; String email = null;
final Cursor c = final Cursor c =
resolver.query(Data.CONTENT_URI, DataQuery.PROJECTION, resolver.query(Data.CONTENT_URI, DataQuery.PROJECTION, DataQuery.SELECTION,
DataQuery.SELECTION,
new String[] {String.valueOf(rawContactId)}, null); new String[] {String.valueOf(rawContactId)}, null);
final ContactOperations contactOp = final ContactOperations contactOp =
ContactOperations.updateExistingContact(context, rawContactId, ContactOperations.updateExistingContact(context, rawContactId, batchOperation);
batchOperation);
try { try {
while (c.moveToNext()) { while (c.moveToNext()) {
final long id = c.getLong(DataQuery.COLUMN_ID); final long id = c.getLong(DataQuery.COLUMN_ID);
final String mimeType = c.getString(DataQuery.COLUMN_MIMETYPE); final String mimeType = c.getString(DataQuery.COLUMN_MIMETYPE);
uri = ContentUris.withAppendedId(Data.CONTENT_URI, id); uri = ContentUris.withAppendedId(Data.CONTENT_URI, id);
if (mimeType.equals(StructuredName.CONTENT_ITEM_TYPE)) { if (mimeType.equals(StructuredName.CONTENT_ITEM_TYPE)) {
final String lastName = final String lastName = c.getString(DataQuery.COLUMN_FAMILY_NAME);
c.getString(DataQuery.COLUMN_FAMILY_NAME); final String firstName = c.getString(DataQuery.COLUMN_GIVEN_NAME);
final String firstName = contactOp.updateName(uri, firstName, lastName, user.getFirstName(), user
c.getString(DataQuery.COLUMN_GIVEN_NAME); .getLastName());
contactOp.updateName(uri, firstName, lastName, user } else if (mimeType.equals(Phone.CONTENT_ITEM_TYPE)) {
.getFirstName(), user.getLastName());
}
else if (mimeType.equals(Phone.CONTENT_ITEM_TYPE)) {
final int type = c.getInt(DataQuery.COLUMN_PHONE_TYPE); final int type = c.getInt(DataQuery.COLUMN_PHONE_TYPE);
if (type == Phone.TYPE_MOBILE) { if (type == Phone.TYPE_MOBILE) {
cellPhone = c.getString(DataQuery.COLUMN_PHONE_NUMBER); cellPhone = c.getString(DataQuery.COLUMN_PHONE_NUMBER);
contactOp.updatePhone(cellPhone, user.getCellPhone(), contactOp.updatePhone(cellPhone, user.getCellPhone(), uri);
uri);
} else if (type == Phone.TYPE_OTHER) { } else if (type == Phone.TYPE_OTHER) {
otherPhone = c.getString(DataQuery.COLUMN_PHONE_NUMBER); otherPhone = c.getString(DataQuery.COLUMN_PHONE_NUMBER);
contactOp.updatePhone(otherPhone, user.getHomePhone(), contactOp.updatePhone(otherPhone, user.getHomePhone(), uri);
uri);
} }
} } else if (Data.MIMETYPE.equals(Email.CONTENT_ITEM_TYPE)) {
else if (Data.MIMETYPE.equals(Email.CONTENT_ITEM_TYPE)) {
email = c.getString(DataQuery.COLUMN_EMAIL_ADDRESS); email = c.getString(DataQuery.COLUMN_EMAIL_ADDRESS);
contactOp.updateEmail(user.getEmail(), email, uri); contactOp.updateEmail(user.getEmail(), email, uri);
} }
} // while } // while
} finally { } finally {
c.close(); c.close();
} }
// Add the cell phone, if present and not updated above // Add the cell phone, if present and not updated above
if (cellPhone == null) { if (cellPhone == null) {
contactOp.addPhone(user.getCellPhone(), Phone.TYPE_MOBILE); contactOp.addPhone(user.getCellPhone(), Phone.TYPE_MOBILE);
} }
// Add the other phone, if present and not updated above // Add the other phone, if present and not updated above
if (otherPhone == null) { if (otherPhone == null) {
contactOp.addPhone(user.getHomePhone(), Phone.TYPE_OTHER); contactOp.addPhone(user.getHomePhone(), Phone.TYPE_OTHER);
} }
// Add the email address, if present and not updated above // Add the email address, if present and not updated above
if (email == null) { if (email == null) {
contactOp.addEmail(user.getEmail()); contactOp.addEmail(user.getEmail());
} }
} }
/** /**
@@ -246,9 +220,9 @@ public class ContactManager {
*/ */
private static void deleteContact(Context context, long rawContactId, private static void deleteContact(Context context, long rawContactId,
BatchOperation batchOperation) { BatchOperation batchOperation) {
batchOperation.add(ContactOperations.newDeleteCpo( batchOperation.add(ContactOperations.newDeleteCpo(
ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId), ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId), true).build());
true).build());
} }
/** /**
@@ -260,11 +234,11 @@ public class ContactManager {
* @return the RawContact id, or 0 if not found * @return the RawContact id, or 0 if not found
*/ */
private static long lookupRawContact(ContentResolver resolver, long userId) { private static long lookupRawContact(ContentResolver resolver, long userId) {
long authorId = 0; long authorId = 0;
final Cursor c = final Cursor c =
resolver.query(RawContacts.CONTENT_URI, UserIdQuery.PROJECTION, resolver.query(RawContacts.CONTENT_URI, UserIdQuery.PROJECTION, UserIdQuery.SELECTION,
UserIdQuery.SELECTION, new String[] {String.valueOf(userId)}, new String[] {String.valueOf(userId)}, null);
null);
try { try {
if (c.moveToFirst()) { if (c.moveToFirst()) {
authorId = c.getLong(UserIdQuery.COLUMN_ID); authorId = c.getLong(UserIdQuery.COLUMN_ID);
@@ -286,11 +260,11 @@ public class ContactManager {
* @return the profile Data row id, or 0 if not found * @return the profile Data row id, or 0 if not found
*/ */
private static long lookupProfile(ContentResolver resolver, long userId) { private static long lookupProfile(ContentResolver resolver, long userId) {
long profileId = 0; long profileId = 0;
final Cursor c = final Cursor c =
resolver.query(Data.CONTENT_URI, ProfileQuery.PROJECTION, resolver.query(Data.CONTENT_URI, ProfileQuery.PROJECTION, ProfileQuery.SELECTION,
ProfileQuery.SELECTION, new String[] {String.valueOf(userId)}, new String[] {String.valueOf(userId)}, null);
null);
try { try {
if (c != null && c.moveToFirst()) { if (c != null && c.moveToFirst()) {
profileId = c.getLong(ProfileQuery.COLUMN_ID); profileId = c.getLong(ProfileQuery.COLUMN_ID);
@@ -307,22 +281,30 @@ public class ContactManager {
* Constants for a query to find a contact given a sample SyncAdapter user * Constants for a query to find a contact given a sample SyncAdapter user
* ID. * ID.
*/ */
private interface ProfileQuery { final private static class ProfileQuery {
private ProfileQuery() {
}
public final static String[] PROJECTION = new String[] {Data._ID}; public final static String[] PROJECTION = new String[] {Data._ID};
public final static int COLUMN_ID = 0; public final static int COLUMN_ID = 0;
public static final String SELECTION = public static final String SELECTION =
Data.MIMETYPE + "='" + SampleSyncAdapterColumns.MIME_PROFILE Data.MIMETYPE + "='" + SampleSyncAdapterColumns.MIME_PROFILE + "' AND "
+ "' AND " + SampleSyncAdapterColumns.DATA_PID + "=?"; + SampleSyncAdapterColumns.DATA_PID + "=?";
} }
/** /**
* Constants for a query to find a contact given a sample SyncAdapter user * Constants for a query to find a contact given a sample SyncAdapter user
* ID. * ID.
*/ */
private interface UserIdQuery { final private static class UserIdQuery {
public final static String[] PROJECTION =
new String[] {RawContacts._ID}; private UserIdQuery() {
}
public final static String[] PROJECTION = new String[] {RawContacts._ID};
public final static int COLUMN_ID = 0; public final static int COLUMN_ID = 0;
@@ -334,21 +316,34 @@ public class ContactManager {
/** /**
* Constants for a query to get contact data for a given rawContactId * Constants for a query to get contact data for a given rawContactId
*/ */
private interface DataQuery { final private static class DataQuery {
private DataQuery() {
}
public static final String[] PROJECTION = public static final String[] PROJECTION =
new String[] {Data._ID, Data.MIMETYPE, Data.DATA1, Data.DATA2, new String[] {Data._ID, Data.MIMETYPE, Data.DATA1, Data.DATA2, Data.DATA3,};
Data.DATA3,};
public static final int COLUMN_ID = 0; public static final int COLUMN_ID = 0;
public static final int COLUMN_MIMETYPE = 1; public static final int COLUMN_MIMETYPE = 1;
public static final int COLUMN_DATA1 = 2; public static final int COLUMN_DATA1 = 2;
public static final int COLUMN_DATA2 = 3; public static final int COLUMN_DATA2 = 3;
public static final int COLUMN_DATA3 = 4; public static final int COLUMN_DATA3 = 4;
public static final int COLUMN_PHONE_NUMBER = COLUMN_DATA1; public static final int COLUMN_PHONE_NUMBER = COLUMN_DATA1;
public static final int COLUMN_PHONE_TYPE = COLUMN_DATA2; public static final int COLUMN_PHONE_TYPE = COLUMN_DATA2;
public static final int COLUMN_EMAIL_ADDRESS = COLUMN_DATA1; public static final int COLUMN_EMAIL_ADDRESS = COLUMN_DATA1;
public static final int COLUMN_EMAIL_TYPE = COLUMN_DATA2; public static final int COLUMN_EMAIL_TYPE = COLUMN_DATA2;
public static final int COLUMN_GIVEN_NAME = COLUMN_DATA2; public static final int COLUMN_GIVEN_NAME = COLUMN_DATA2;
public static final int COLUMN_FAMILY_NAME = COLUMN_DATA3; public static final int COLUMN_FAMILY_NAME = COLUMN_DATA3;
public static final String SELECTION = Data.RAW_CONTACT_ID + "=?"; public static final String SELECTION = Data.RAW_CONTACT_ID + "=?";

View File

@@ -13,7 +13,6 @@
* License for the specific language governing permissions and limitations under * License for the specific language governing permissions and limitations under
* the License. * the License.
*/ */
package com.example.android.samplesync.platform; package com.example.android.samplesync.platform;
import android.content.ContentProviderOperation; import android.content.ContentProviderOperation;
@@ -38,12 +37,19 @@ import com.example.android.samplesync.R;
public class ContactOperations { public class ContactOperations {
private final ContentValues mValues; private final ContentValues mValues;
private ContentProviderOperation.Builder mBuilder; private ContentProviderOperation.Builder mBuilder;
private final BatchOperation mBatchOperation; private final BatchOperation mBatchOperation;
private final Context mContext; private final Context mContext;
private boolean mYield; private boolean mYield;
private long mRawContactId; private long mRawContactId;
private int mBackReference; private int mBackReference;
private boolean mIsNewContact; private boolean mIsNewContact;
/** /**
@@ -55,10 +61,10 @@ public class ContactOperations {
* @param accountName the username of the current login * @param accountName the username of the current login
* @return instance of ContactOperations * @return instance of ContactOperations
*/ */
public static ContactOperations createNewContact(Context context, public static ContactOperations createNewContact(Context context, int userId,
int userId, String accountName, BatchOperation batchOperation) { String accountName, BatchOperation batchOperation) {
return new ContactOperations(context, userId, accountName,
batchOperation); return new ContactOperations(context, userId, accountName, batchOperation);
} }
/** /**
@@ -69,8 +75,9 @@ public class ContactOperations {
* @param rawContactId the unique Id of the existing rawContact * @param rawContactId the unique Id of the existing rawContact
* @return instance of ContactOperations * @return instance of ContactOperations
*/ */
public static ContactOperations updateExistingContact(Context context, public static ContactOperations updateExistingContact(Context context, long rawContactId,
long rawContactId, BatchOperation batchOperation) { BatchOperation batchOperation) {
return new ContactOperations(context, rawContactId, batchOperation); return new ContactOperations(context, rawContactId, batchOperation);
} }
@@ -83,19 +90,18 @@ public class ContactOperations {
public ContactOperations(Context context, int userId, String accountName, public ContactOperations(Context context, int userId, String accountName,
BatchOperation batchOperation) { BatchOperation batchOperation) {
this(context, batchOperation); this(context, batchOperation);
mBackReference = mBatchOperation.size(); mBackReference = mBatchOperation.size();
mIsNewContact = true; mIsNewContact = true;
mValues.put(RawContacts.SOURCE_ID, userId); mValues.put(RawContacts.SOURCE_ID, userId);
mValues.put(RawContacts.ACCOUNT_TYPE, Constants.ACCOUNT_TYPE); mValues.put(RawContacts.ACCOUNT_TYPE, Constants.ACCOUNT_TYPE);
mValues.put(RawContacts.ACCOUNT_NAME, accountName); mValues.put(RawContacts.ACCOUNT_NAME, accountName);
mBuilder = mBuilder = newInsertCpo(RawContacts.CONTENT_URI, true).withValues(mValues);
newInsertCpo(RawContacts.CONTENT_URI, true).withValues(mValues);
mBatchOperation.add(mBuilder.build()); mBatchOperation.add(mBuilder.build());
} }
public ContactOperations(Context context, long rawContactId, public ContactOperations(Context context, long rawContactId, BatchOperation batchOperation) {
BatchOperation batchOperation) {
this(context, batchOperation); this(context, batchOperation);
mIsNewContact = false; mIsNewContact = false;
mRawContactId = rawContactId; mRawContactId = rawContactId;
@@ -109,16 +115,15 @@ public class ContactOperations {
* @return instance of ContactOperations * @return instance of ContactOperations
*/ */
public ContactOperations addName(String firstName, String lastName) { public ContactOperations addName(String firstName, String lastName) {
mValues.clear(); mValues.clear();
if (!TextUtils.isEmpty(firstName)) { if (!TextUtils.isEmpty(firstName)) {
mValues.put(StructuredName.GIVEN_NAME, firstName); mValues.put(StructuredName.GIVEN_NAME, firstName);
mValues.put(StructuredName.MIMETYPE, mValues.put(StructuredName.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
StructuredName.CONTENT_ITEM_TYPE);
} }
if (!TextUtils.isEmpty(lastName)) { if (!TextUtils.isEmpty(lastName)) {
mValues.put(StructuredName.FAMILY_NAME, lastName); mValues.put(StructuredName.FAMILY_NAME, lastName);
mValues.put(StructuredName.MIMETYPE, mValues.put(StructuredName.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
StructuredName.CONTENT_ITEM_TYPE);
} }
if (mValues.size() > 0) { if (mValues.size() > 0) {
addInsertOp(); addInsertOp();
@@ -188,8 +193,7 @@ public class ContactOperations {
* @param uri Uri for the existing raw contact to be updated * @param uri Uri for the existing raw contact to be updated
* @return instance of ContactOperations * @return instance of ContactOperations
*/ */
public ContactOperations updateEmail(String email, String existingEmail, public ContactOperations updateEmail(String email, String existingEmail, Uri uri) {
Uri uri) {
if (!TextUtils.equals(existingEmail, email)) { if (!TextUtils.equals(existingEmail, email)) {
mValues.clear(); mValues.clear();
mValues.put(Email.DATA, email); mValues.put(Email.DATA, email);
@@ -207,10 +211,11 @@ public class ContactOperations {
* @param uri Uri for the existing raw contact to be updated * @param uri Uri for the existing raw contact to be updated
* @return instance of ContactOperations * @return instance of ContactOperations
*/ */
public ContactOperations updateName(Uri uri, String existingFirstName, public ContactOperations updateName(Uri uri, String existingFirstName, String existingLastName,
String existingLastName, String firstName, String lastName) { String firstName, String lastName) {
Log.i("ContactOperations", "ef=" + existingFirstName + "el="
+ existingLastName + "f=" + firstName + "l=" + lastName); Log.i("ContactOperations", "ef=" + existingFirstName + "el=" + existingLastName + "f="
+ firstName + "l=" + lastName);
mValues.clear(); mValues.clear();
if (!TextUtils.equals(existingFirstName, firstName)) { if (!TextUtils.equals(existingFirstName, firstName)) {
mValues.put(StructuredName.GIVEN_NAME, firstName); mValues.put(StructuredName.GIVEN_NAME, firstName);
@@ -232,8 +237,7 @@ public class ContactOperations {
* @param uri Uri for the existing raw contact to be updated * @param uri Uri for the existing raw contact to be updated
* @return instance of ContactOperations * @return instance of ContactOperations
*/ */
public ContactOperations updatePhone(String existingNumber, String phone, public ContactOperations updatePhone(String existingNumber, String phone, Uri uri) {
Uri uri) {
if (!TextUtils.equals(phone, existingNumber)) { if (!TextUtils.equals(phone, existingNumber)) {
mValues.clear(); mValues.clear();
mValues.put(Phone.NUMBER, phone); mValues.put(Phone.NUMBER, phone);
@@ -260,16 +264,14 @@ public class ContactOperations {
* Adds an insert operation into the batch * Adds an insert operation into the batch
*/ */
private void addInsertOp() { private void addInsertOp() {
if (!mIsNewContact) { if (!mIsNewContact) {
mValues.put(Phone.RAW_CONTACT_ID, mRawContactId); mValues.put(Phone.RAW_CONTACT_ID, mRawContactId);
} }
mBuilder = mBuilder = newInsertCpo(addCallerIsSyncAdapterParameter(Data.CONTENT_URI), mYield);
newInsertCpo(addCallerIsSyncAdapterParameter(Data.CONTENT_URI),
mYield);
mBuilder.withValues(mValues); mBuilder.withValues(mValues);
if (mIsNewContact) { if (mIsNewContact) {
mBuilder mBuilder.withValueBackReference(Data.RAW_CONTACT_ID, mBackReference);
.withValueBackReference(Data.RAW_CONTACT_ID, mBackReference);
} }
mYield = false; mYield = false;
mBatchOperation.add(mBuilder.build()); mBatchOperation.add(mBuilder.build());
@@ -284,28 +286,23 @@ public class ContactOperations {
mBatchOperation.add(mBuilder.build()); mBatchOperation.add(mBuilder.build());
} }
public static ContentProviderOperation.Builder newInsertCpo(Uri uri, public static ContentProviderOperation.Builder newInsertCpo(Uri uri, boolean yield) {
boolean yield) { return ContentProviderOperation.newInsert(addCallerIsSyncAdapterParameter(uri))
return ContentProviderOperation.newInsert( .withYieldAllowed(yield);
addCallerIsSyncAdapterParameter(uri)).withYieldAllowed(yield);
} }
public static ContentProviderOperation.Builder newUpdateCpo(Uri uri, public static ContentProviderOperation.Builder newUpdateCpo(Uri uri, boolean yield) {
boolean yield) { return ContentProviderOperation.newUpdate(addCallerIsSyncAdapterParameter(uri))
return ContentProviderOperation.newUpdate( .withYieldAllowed(yield);
addCallerIsSyncAdapterParameter(uri)).withYieldAllowed(yield);
} }
public static ContentProviderOperation.Builder newDeleteCpo(Uri uri, public static ContentProviderOperation.Builder newDeleteCpo(Uri uri, boolean yield) {
boolean yield) { return ContentProviderOperation.newDelete(addCallerIsSyncAdapterParameter(uri))
return ContentProviderOperation.newDelete( .withYieldAllowed(yield);
addCallerIsSyncAdapterParameter(uri)).withYieldAllowed(yield);
} }
private static Uri addCallerIsSyncAdapterParameter(Uri uri) { private static Uri addCallerIsSyncAdapterParameter(Uri uri) {
return uri.buildUpon().appendQueryParameter( return uri.buildUpon().appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true")
ContactsContract.CALLER_IS_SYNCADAPTER, "true").build(); .build();
} }
} }

View File

@@ -20,7 +20,11 @@ import android.provider.ContactsContract.Data;
/* /*
* The standard columns representing contact's info from social apps. * The standard columns representing contact's info from social apps.
*/ */
public interface SampleSyncAdapterColumns { public final class SampleSyncAdapterColumns {
private SampleSyncAdapterColumns() {
}
/** /**
* MIME-type used when storing a profile {@link Data} entry. * MIME-type used when storing a profile {@link Data} entry.
*/ */
@@ -28,7 +32,8 @@ public interface SampleSyncAdapterColumns {
"vnd.android.cursor.item/vnd.samplesyncadapter.profile"; "vnd.android.cursor.item/vnd.samplesyncadapter.profile";
public static final String DATA_PID = Data.DATA1; public static final String DATA_PID = Data.DATA1;
public static final String DATA_SUMMARY = Data.DATA2;
public static final String DATA_DETAIL = Data.DATA3;
public static final String DATA_SUMMARY = Data.DATA2;
public static final String DATA_DETAIL = Data.DATA3;
} }

View File

@@ -13,7 +13,6 @@
* License for the specific language governing permissions and limitations under * License for the specific language governing permissions and limitations under
* the License. * the License.
*/ */
package com.example.android.samplesync.syncadapter; package com.example.android.samplesync.syncadapter;
import android.accounts.Account; import android.accounts.Account;
@@ -46,9 +45,11 @@ import java.util.List;
* platform ContactOperations provider. * platform ContactOperations provider.
*/ */
public class SyncAdapter extends AbstractThreadedSyncAdapter { public class SyncAdapter extends AbstractThreadedSyncAdapter {
private static final String TAG = "SyncAdapter"; private static final String TAG = "SyncAdapter";
private final AccountManager mAccountManager; private final AccountManager mAccountManager;
private final Context mContext; private final Context mContext;
private Date mLastUpdated; private Date mLastUpdated;
@@ -62,18 +63,17 @@ public class SyncAdapter extends AbstractThreadedSyncAdapter {
@Override @Override
public void onPerformSync(Account account, Bundle extras, String authority, public void onPerformSync(Account account, Bundle extras, String authority,
ContentProviderClient provider, SyncResult syncResult) { ContentProviderClient provider, SyncResult syncResult) {
List<User> users; List<User> users;
List<Status> statuses; List<Status> statuses;
String authtoken = null; String authtoken = null;
try { try {
// use the account manager to request the credentials // use the account manager to request the credentials
authtoken = authtoken =
mAccountManager.blockingGetAuthToken(account, mAccountManager
Constants.AUTHTOKEN_TYPE, true /* notifyAuthFailure */); .blockingGetAuthToken(account, Constants.AUTHTOKEN_TYPE, true /* notifyAuthFailure */);
// fetch updates from the sample service over the cloud // fetch updates from the sample service over the cloud
users = users = NetworkUtilities.fetchFriendUpdates(account, authtoken, mLastUpdated);
NetworkUtilities.fetchFriendUpdates(account, authtoken,
mLastUpdated);
// update the last synced date. // update the last synced date.
mLastUpdated = new Date(); mLastUpdated = new Date();
// update platform contacts. // update platform contacts.
@@ -91,8 +91,7 @@ public class SyncAdapter extends AbstractThreadedSyncAdapter {
Log.e(TAG, "IOException", e); Log.e(TAG, "IOException", e);
syncResult.stats.numIoExceptions++; syncResult.stats.numIoExceptions++;
} catch (final AuthenticationException e) { } catch (final AuthenticationException e) {
mAccountManager.invalidateAuthToken(Constants.ACCOUNT_TYPE, mAccountManager.invalidateAuthToken(Constants.ACCOUNT_TYPE, authtoken);
authtoken);
syncResult.stats.numAuthExceptions++; syncResult.stats.numAuthExceptions++;
Log.e(TAG, "AuthenticationException", e); Log.e(TAG, "AuthenticationException", e);
} catch (final ParseException e) { } catch (final ParseException e) {

View File

@@ -13,7 +13,6 @@
* License for the specific language governing permissions and limitations under * License for the specific language governing permissions and limitations under
* the License. * the License.
*/ */
package com.example.android.samplesync.syncadapter; package com.example.android.samplesync.syncadapter;
import android.app.Service; import android.app.Service;
@@ -26,12 +25,11 @@ import android.os.IBinder;
* IBinder. * IBinder.
*/ */
public class SyncService extends Service { public class SyncService extends Service {
private static final Object sSyncAdapterLock = new Object(); private static final Object sSyncAdapterLock = new Object();
private static SyncAdapter sSyncAdapter = null; private static SyncAdapter sSyncAdapter = null;
/*
* {@inheritDoc}
*/
@Override @Override
public void onCreate() { public void onCreate() {
synchronized (sSyncAdapterLock) { synchronized (sSyncAdapterLock) {
@@ -41,9 +39,6 @@ public class SyncService extends Service {
} }
} }
/*
* {@inheritDoc}
*/
@Override @Override
public IBinder onBind(Intent intent) { public IBinder onBind(Intent intent) {
return sSyncAdapter.getSyncAdapterBinder(); return sSyncAdapter.getSyncAdapterBinder();

View File

@@ -0,0 +1,32 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* 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.example.android.apis;
import junit.framework.Test;
import junit.framework.TestSuite;
import android.test.suitebuilder.TestSuiteBuilder;
/**
* A test suite containing all tests for SampleSyncAdapter.
*
*/
public class AllTests extends TestSuite {
public static Test suite() {
return new TestSuiteBuilder(AllTests.class).includeAllPackagesUnderHere().build();
}
}

View File

@@ -0,0 +1,78 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* 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.example.android.samplesync.authenticator;
import android.app.Activity;
import android.app.Instrumentation;
import android.content.Context;
import android.content.Intent;
import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.SmallTest;
import android.view.View;
/**
* This is a series of unit tests for the {@link AuthenticatorActivity} class.
*/
@SmallTest
public class AuthenticatorActivityTests extends
ActivityInstrumentationTestCase2<AuthenticatorActivity> {
private static final int ACTIVITY_WAIT = 10000;
private Instrumentation mInstrumentation;
private Context mContext;
public AuthenticatorActivityTests() {
super(AuthenticatorActivity.class);
}
/**
* Common setup code for all tests. Sets up a default launch intent, which
* some tests will use (others will override).
*/
@Override
protected void setUp() throws Exception {
super.setUp();
mInstrumentation = this.getInstrumentation();
mContext = mInstrumentation.getTargetContext();
}
@Override
protected void tearDown() throws Exception {
super.tearDown();
}
/**
* Confirm that Login is presented.
*/
@SmallTest
public void testLoginOffered() {
Instrumentation.ActivityMonitor monitor =
mInstrumentation.addMonitor(AuthenticatorActivity.class.getName(), null, false);
Intent intent = new Intent(mContext, AuthenticatorActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mInstrumentation.startActivitySync(intent);
Activity activity = mInstrumentation.waitForMonitorWithTimeout(monitor, ACTIVITY_WAIT);
View loginbutton = activity.findViewById(R.id.ok_button);
int expected = View.VISIBLE;
assertEquals(expected, loginbutton.getVisibility());
}
}

View File

@@ -0,0 +1,52 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* 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.example.android.samplesync.client;
import com.example.android.samplesync.client.User;
import junit.framework.TestCase;
import org.json.JSONObject;
public class UserTest extends TestCase {
@SmallTest
public void testConstructor() throws Exception {
User user =
new User("mjoshi", "Megha", "Joshi", "1-650-335-5681", "1-650-111-5681",
"1-650-222-5681", "test@google.com", false, 1);
assertEquals("Megha", user.getFirstName());
assertEquals("Joshi", user.getLastName());
assertEquals("mjoshi", user.getUserName());
assertEquals(1, user.getUserId());
assertEquals("1-650-335-5681", user.getCellPhone());
assertEquals(false, user.isDeleted());
}
@SmallTest
public void testValueOf() throws Exception {
JSONObject jsonObj = new JSONObject();
jsonObj.put("u", "mjoshi");
jsonObj.put("f", "Megha");
jsonObj.put("l", "Joshi");
jsonObj.put("i", 1);
User user = User.valueOf(jsonObj);
assertEquals("Megha", user.getFirstName());
assertEquals("Joshi", user.getLastName());
assertEquals("mjoshi", user.getUserName());
assertEquals(1, user.getUserId());
}
}