+ return receiver.retrieveProfile(address, Optional.absent(), unidentifiedAccess, SignalServiceProfile.RequestType.PROFILE).get(10, TimeUnit.SECONDS).getProfile();
+ } catch (InterruptedException | ExecutionException | TimeoutException e) {
+ throw new IOException("Failed to retrieve profile", e);
+ }
+ }
+
+ private SignalProfile getRecipientProfile(SignalServiceAddress address, Optional<UnidentifiedAccess> unidentifiedAccess, ProfileKey profileKey) throws IOException {
+ SignalProfileEntry profileEntry = account.getProfileStore().getProfile(address);
+ long now = new Date().getTime();
+ // Profiles are cache for 24h before retrieving them again
+ if (profileEntry == null || profileEntry.getProfile() == null || now - profileEntry.getLastUpdateTimestamp() > 24 * 60 * 60 * 1000) {
+ SignalProfile profile = retrieveRecipientProfile(address, unidentifiedAccess, profileKey);
+ profileEntry = new SignalProfileEntry(profileKey, now, profile);
+ account.getProfileStore().updateProfile(address, profileEntry);
+ }
+ return profileEntry.getProfile();
+ }
+
+ private SignalProfile retrieveRecipientProfile(SignalServiceAddress address, Optional<UnidentifiedAccess> unidentifiedAccess, ProfileKey profileKey) throws IOException {
+ final SignalServiceProfile encryptedProfile = getEncryptedRecipientProfile(address, unidentifiedAccess);
+
+ File avatarFile = null;
+ try {
+ avatarFile = encryptedProfile.getAvatar() == null ? null : retrieveProfileAvatar(address, encryptedProfile.getAvatar(), profileKey);
+ } catch (AssertionError e) {
+ System.err.println("Failed to retrieve profile avatar: " + e.getMessage());
+ }
+
+ ProfileCipher profileCipher = new ProfileCipher(profileKey);
+ try {
+ return new SignalProfile(
+ encryptedProfile.getIdentityKey(),
+ encryptedProfile.getName() == null ? null : new String(profileCipher.decryptName(Base64.decode(encryptedProfile.getName()))),
+ avatarFile,
+ encryptedProfile.getUnidentifiedAccess() == null || !profileCipher.verifyUnidentifiedAccess(Base64.decode(encryptedProfile.getUnidentifiedAccess())) ? null : encryptedProfile.getUnidentifiedAccess(),
+ encryptedProfile.isUnrestrictedUnidentifiedAccess(),
+ encryptedProfile.getCapabilities());
+ } catch (InvalidCiphertextException e) {
+ return null;