Clean up shortcut code.

This commit is contained in:
Greyson Parrelli 2018-08-06 14:42:22 -04:00
parent c3c44e324b
commit 5cdf5499d0
16 changed files with 105 additions and 48 deletions

View File

@ -214,7 +214,6 @@
android:windowSoftInputMode="stateUnchanged"
android:launchMode="singleTask"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"
android:exported="true"
android:parentActivityName=".ConversationListActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
@ -413,6 +412,11 @@
android:theme="@style/TextSecure.LightNoActionBar"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<activity android:name=".ShortcutLauncherActivity"
android:theme="@style/TextSecure.LightNoActionBar"
android:exported="true"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
<service android:enabled="true" android:name="org.thoughtcrime.securesms.service.WebRtcCallService"/>
<service android:enabled="true" android:name=".service.ApplicationMigrationService"/>
<service android:enabled="true" android:exported="false" android:name=".service.KeyCachingService"/>

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -1232,6 +1232,7 @@
<string name="conversation__menu_leave_group">Leave group</string>
<string name="conversation__menu_view_all_media">All media</string>
<string name="conversation__menu_conversation_settings">Conversation settings</string>
<string name="conversation__menu_add_shortcut">Add to home screen</string>
<!-- conversation_popup -->
<string name="conversation_popup__menu_expand_popup">Expand popup</string>
@ -1390,7 +1391,6 @@
<string name="prompt_passphrase_activity__signal_is_locked">Signal is locked</string>
<string name="prompt_passphrase_activity__tap_to_unlock">TAP TO UNLOCK</string>
<string name="RegistrationLockDialog_reminder">Reminder:</string>
<string name="conversation__menu_add_shortcut">Add to home screen</string>
<string name="recipient_preferences__about">About</string>
<!-- EOF -->

View File

@ -26,6 +26,7 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Configuration;
import android.content.res.TypedArray;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.PorterDuff.Mode;
import android.graphics.drawable.ColorDrawable;
@ -39,6 +40,9 @@ import android.provider.ContactsContract;
import android.provider.Telephony;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.content.pm.ShortcutInfoCompat;
import android.support.v4.content.pm.ShortcutManagerCompat;
import android.support.v4.graphics.drawable.IconCompat;
import android.support.v4.view.MenuItemCompat;
import android.support.v4.view.WindowCompat;
import android.support.v7.app.ActionBar;
@ -781,32 +785,47 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
private void handleAddShortcut() {
Log.i(TAG, "Creating home screen shortcut for recipient " + recipient.getAddress());
Intent launchIntent = new Intent(getApplicationContext(), ConversationActivity.class);
new AsyncTask<Void, Void, IconCompat>() {
launchIntent.putExtra(ADDRESS_EXTRA, recipient.getAddress().serialize());
launchIntent.putExtra(TEXT_EXTRA, getIntent().getStringExtra(ConversationActivity.TEXT_EXTRA));
launchIntent.setDataAndType(getIntent().getData(), getIntent().getType());
@Override
protected IconCompat doInBackground(Void... voids) {
Context context = getApplicationContext();
IconCompat icon = null;
long existingThread = DatabaseFactory.getThreadDatabase(this).getThreadIdIfExistsFor(recipient);
if (recipient.getContactPhoto() != null) {
try {
icon = IconCompat.createWithAdaptiveBitmap(BitmapFactory.decodeStream(recipient.getContactPhoto().openInputStream(context)));
} catch (IOException e) {
Log.w(TAG, "Failed to decode contact photo during shortcut creation. Falling back to generic icon.", e);
}
}
launchIntent.putExtra(ConversationActivity.THREAD_ID_EXTRA, existingThread);
launchIntent.putExtra(ConversationActivity.DISTRIBUTION_TYPE_EXTRA, ThreadDatabase.DistributionTypes.DEFAULT);
if (icon == null) {
icon = IconCompat.createWithResource(context, recipient.isGroupRecipient() ? R.mipmap.ic_group_shortcut
: R.mipmap.ic_person_shortcut);
}
launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
launchIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
return icon;
}
Intent intent = new Intent();
final String name = Optional.fromNullable(recipient.getProfileName())
.or(Optional.fromNullable(recipient.getName()))
.or(recipient.toShortString());
// these constants are deprecated but their replacement (ShortcutManager) is available only from API level 25
intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, launchIntent);
intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, name);
intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, Intent.ShortcutIconResource.fromContext(getApplicationContext(), R.mipmap.ic_launcher));
intent.setAction("com.android.launcher.action.INSTALL_SHORTCUT");
@Override
protected void onPostExecute(IconCompat icon) {
Context context = getApplicationContext();
String name = Optional.fromNullable(recipient.getName())
.or(Optional.fromNullable(recipient.getProfileName()))
.or(recipient.toShortString());
getApplicationContext().sendBroadcast(intent);
Toast.makeText(this, getString(R.string.ConversationActivity_added_to_home_screen), Toast.LENGTH_LONG).show();
ShortcutInfoCompat shortcutInfo = new ShortcutInfoCompat.Builder(context, recipient.getAddress().serialize() + '-' + System.currentTimeMillis())
.setShortLabel(name)
.setIcon(icon)
.setIntent(ShortcutLauncherActivity.createIntent(context, recipient.getAddress()))
.build();
if (ShortcutManagerCompat.requestPinShortcut(context, shortcutInfo, null)) {
Toast.makeText(context, getString(R.string.ConversationActivity_added_to_home_screen), Toast.LENGTH_LONG).show();
}
}
}.execute();
}
private void handleLeavePushGroup() {
@ -1380,7 +1399,8 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
private void initializeResources() {
if (recipient != null) recipient.removeListener(this);
recipient = getRecipientFromExtras(getIntent(), this);
recipient = Recipient.from(this, getIntent().getParcelableExtra(ADDRESS_EXTRA), true);
threadId = getIntent().getLongExtra(THREAD_ID_EXTRA, -1);
archived = getIntent().getBooleanExtra(IS_ARCHIVED_EXTRA, false);
distributionType = getIntent().getIntExtra(DISTRIBUTION_TYPE_EXTRA, ThreadDatabase.DistributionTypes.DEFAULT);
@ -1395,26 +1415,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
recipient.addListener(this);
}
/**
* Extracts the Recipient instance from the extras contained in the intent.
*
* This can be passed in two ways:
*
* - If the intent was started from inside the app, the address is a parcelable Address instance.
* - If it was launched from the home screen then it is a serialised (stringified) form of the Address, as home screen
* shortcuts cannot contain instances of Address (see BadParcelableException).
*/
static Recipient getRecipientFromExtras(@NonNull Intent intent, @NonNull Context context) {
Address address;
final Address parcelableAddress = intent.getParcelableExtra(ADDRESS_EXTRA);
if(parcelableAddress != null) {
address = parcelableAddress;
} else {
address = Address.fromSerialized((String) intent.getExtras().get(ADDRESS_EXTRA));
}
return Recipient.from(context, address, true);
}
private void initializeProfiles() {
if (!isSecureText) {
Log.i(TAG, "SMS contact, no profile fetch needed.");

View File

@ -206,7 +206,7 @@ public class ConversationFragment extends Fragment
}
private void initializeResources() {
this.recipient = ConversationActivity.getRecipientFromExtras(getActivity().getIntent(), getActivity());
this.recipient = Recipient.from(getActivity(), getActivity().getIntent().getParcelableExtra(ConversationActivity.ADDRESS_EXTRA), true);
this.threadId = this.getActivity().getIntent().getLongExtra(ConversationActivity.THREAD_ID_EXTRA, -1);
this.lastSeen = this.getActivity().getIntent().getLongExtra(ConversationActivity.LAST_SEEN_EXTRA, -1);
this.startingPosition = this.getActivity().getIntent().getIntExtra(ConversationActivity.STARTING_POSITION_EXTRA, -1);

View File

@ -0,0 +1,42 @@
package org.thoughtcrime.securesms;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.TaskStackBuilder;
import android.support.v7.app.AppCompatActivity;
import org.thoughtcrime.securesms.database.Address;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.util.CommunicationActions;
public class ShortcutLauncherActivity extends AppCompatActivity {
private static final String KEY_SERIALIZED_ADDRESS = "serialized_address";
public static Intent createIntent(@NonNull Context context, @NonNull Address address) {
Intent intent = new Intent(context, ShortcutLauncherActivity.class);
intent.setAction(Intent.ACTION_MAIN);
intent.putExtra(KEY_SERIALIZED_ADDRESS, address.serialize());
return intent;
}
@SuppressLint("StaticFieldLeak")
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String serializedAddress = getIntent().getStringExtra(KEY_SERIALIZED_ADDRESS);
Address address = Address.fromSerialized(serializedAddress);
Recipient recipient = Recipient.from(this, address, true);
TaskStackBuilder backStack = TaskStackBuilder.create(this)
.addNextIntent(new Intent(this, ConversationListActivity.class));
CommunicationActions.startConversation(this, recipient, null, backStack);
finish();
}
}

View File

@ -8,6 +8,7 @@ import android.net.Uri;
import android.os.AsyncTask;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.TaskStackBuilder;
import android.text.TextUtils;
import org.thoughtcrime.securesms.ConversationActivity;
@ -43,9 +44,14 @@ public class CommunicationActions {
.execute();
}
public static void startConversation(@NonNull Context context,
@NonNull Recipient recipient,
@Nullable String text)
public static void startConversation(@NonNull Context context, @NonNull Recipient recipient, @Nullable String text) {
startConversation(context, recipient, text, null);
}
public static void startConversation(@NonNull Context context,
@NonNull Recipient recipient,
@Nullable String text,
@Nullable TaskStackBuilder backStack)
{
new AsyncTask<Void, Void, Long>() {
@Override
@ -64,7 +70,12 @@ public class CommunicationActions {
intent.putExtra(ConversationActivity.TEXT_EXTRA, text);
}
context.startActivity(intent);
if (backStack != null) {
backStack.addNextIntent(intent);
backStack.startActivities();
} else {
context.startActivity(intent);
}
}
}.execute();
}