/* * Copyright 2012 The Stanford MobiSocial Laboratory * * 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 mobisocial.musubi.ui; import gnu.trove.list.array.TLongArrayList; import java.util.Iterator; import java.util.List; import mobisocial.crypto.IBHashedIdentity; import mobisocial.crypto.IBHashedIdentity.Authority; import mobisocial.crypto.IBIdentity; import mobisocial.musubi.App; import mobisocial.musubi.model.MIdentity; import mobisocial.musubi.model.MMyAccount; import mobisocial.musubi.model.helpers.FeedManager; import mobisocial.musubi.model.helpers.IdentitiesManager; import mobisocial.musubi.model.helpers.MyAccountManager; import mobisocial.musubi.provider.MusubiContentProvider; import mobisocial.musubi.provider.MusubiContentProvider.Provided; import mobisocial.musubi.service.MusubiService; import mobisocial.musubi.util.Util; import android.app.AlertDialog; import android.app.Dialog; import android.content.DialogInterface; import android.content.Intent; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.graphics.Color; import android.net.Uri; import android.os.Bundle; import android.support.v4.app.DialogFragment; import android.util.Log; import android.view.View; import android.widget.Toast; /** * Accepts a friend represented by the given data uri. */ public class AcceptFriendActivity extends MusubiBaseActivity { Uri mUri; String mName; List<String> mTypes; List<String> mPrincipals; private SQLiteOpenHelper mDatabaseSource; private IdentitiesManager mIdentitiesManager; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mDatabaseSource = App.getDatabaseSource(this); mIdentitiesManager = new IdentitiesManager(mDatabaseSource); View view = new View(this); view.setBackgroundColor(Color.TRANSPARENT); setContentView(view); } @Override protected void onResume() { super.onResume(); if(getIntent() == null || getIntent().getData() == null) { Toast.makeText(this, "No data.", Toast.LENGTH_SHORT).show(); finish(); return; } mUri = getIntent().getData(); mName = mUri.getQueryParameter("n"); if (mName == null) { mName = "Unnamed Friend"; } mTypes = mUri.getQueryParameters("t"); mPrincipals = mUri.getQueryParameters("p"); if(mTypes.size() != mPrincipals.size()) { Toast.makeText(this, "Mismatched identity information", Toast.LENGTH_SHORT).show(); finish(); return; } if(mTypes.size() == 0) { Toast.makeText(this, "Missing identity information", Toast.LENGTH_SHORT).show(); finish(); return; } Iterator<String> i_types = mTypes.iterator(); Iterator<String> i_princiapls = mPrincipals.iterator(); TLongArrayList ids = new TLongArrayList(4); SQLiteDatabase db = mDatabaseSource.getWritableDatabase(); int num_facebook_ids = 0; String description = ""; try { db.beginTransaction(); while(i_types.hasNext()) { int type; try { type = Integer.parseInt(i_types.next()); } catch (NumberFormatException e) { continue; } String principal = i_princiapls.next(); Authority authority = IBHashedIdentity.Authority.values()[type]; if(authority == Authority.Local) { continue; } IBIdentity id = new IBIdentity(authority, principal, 0); long identId = mIdentitiesManager.getIdForIBHashedIdentity(id); MIdentity ident; if(identId == 0) { ident = new MIdentity(); ident.type_ = authority; ident.principal_ = principal; ident.principalHash_ = Util.sha256(ident.principal_.getBytes()); ident.principalShortHash_ = Util.shortHash(ident.principalHash_); ident.claimed_ = true; ident.musubiName_ = mName; identId = mIdentitiesManager.insertIdentity(ident); } else { ident = mIdentitiesManager.getIdentityForId(identId); ident.principal_ = principal; // implicitly checked by lookup ident.claimed_ = true; ident.musubiName_ = mName; mIdentitiesManager.updateIdentity(ident); } ids.add(identId); if(ident.type_ == Authority.Facebook) { num_facebook_ids++; } else { description += "\n" + ident.principal_; } } if(num_facebook_ids > 0) { description += "\n" + num_facebook_ids + " Facebook IDs"; } db.setTransactionSuccessful(); } catch(Exception e) { } finally { db.endTransaction(); } showDialog(AcceptFriendDialog.newInstance(mName, description, ids.toArray())); } public static class AcceptFriendDialog extends DialogFragment { public static AcceptFriendDialog newInstance(String name, String description, long[] ids) { AcceptFriendDialog d = new AcceptFriendDialog(); Bundle b = new Bundle(); b.putString("name", name); b.putString("description", description); b.putLongArray("ids", ids); d.setArguments(b); return d; } public AcceptFriendDialog() { } @Override public Dialog onCreateDialog(Bundle savedInstanceState) { Bundle args = getArguments(); final String name = args.getString("name"); final long[] ids = args.getLongArray("ids"); final String description = args.getString("description"); return new AlertDialog.Builder(getActivity()) .setTitle("Add contact?") .setMessage("Add " + name + " to contacts?" + description) .setPositiveButton("Yes", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { try { SQLiteOpenHelper databaseSource = App.getDatabaseSource(getActivity()); SQLiteDatabase db = databaseSource.getWritableDatabase(); db.beginTransaction(); boolean run_profile_push = false; try { IdentitiesManager identitiesManager = new IdentitiesManager(databaseSource); for(long id : ids) { MIdentity ident = identitiesManager.getIdentityForId(id); ident.whitelisted_ = true; ident.blocked_ = false; identitiesManager.updateIdentity(ident); } FeedManager feedManager = new FeedManager(databaseSource); MyAccountManager accountManager = new MyAccountManager(databaseSource); for(MIdentity persona : identitiesManager.getOwnedIdentities()) { if(persona.type_ == Authority.Local) continue; MMyAccount provisional_account = accountManager.getProvisionalWhitelistForIdentity(persona.id_); MMyAccount whitelist_account = accountManager.getWhitelistForIdentity(persona.id_); for(long id : ids) { MIdentity ident = identitiesManager.getIdentityForId(id); run_profile_push |= feedManager.addToWhitelistsIfNecessary(provisional_account, whitelist_account, persona, ident); } } db.setTransactionSuccessful(); } finally { db.endTransaction(); } if(run_profile_push) { getActivity().getContentResolver().notifyChange(MusubiService.FORCE_PROFILE_PUSH, null); } //TODO: sadly this wakes up profile push as well... we probably need to rescope some of these events getActivity().getContentResolver().notifyChange(MusubiService.WHITELIST_APPENDED, null); getActivity().getContentResolver().notifyChange(MusubiService.COLORLIST_CHANGED, null); Uri data = MusubiContentProvider.uriForItem(Provided.IDENTITIES_ID, ids[0]); String type = MusubiContentProvider.getType(Provided.IDENTITIES_ID); Intent view = new Intent(Intent.ACTION_VIEW); view.setDataAndType(data, type); startActivity(view); } catch (Exception e) { Toast.makeText(getActivity(), "Error adding contact.", Toast.LENGTH_LONG).show(); Log.e(TAG, "Error adding contact", e); } finally { dismiss(); getActivity().finish(); } } }) .setNegativeButton("No", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dismiss(); getActivity().finish(); } }).create(); } } }