Merge tag '2.21.0.9'

This commit is contained in:
Michael Kirk 2018-03-06 16:43:33 -05:00
commit a1de99f1f1
23 changed files with 233 additions and 137 deletions

View File

@ -28,10 +28,13 @@ def execute_command(command):
print e.output
sys.exit(1)
def add_field(curl_command, form_key, form_value):
curl_command.append('-F')
curl_command.append("%s=%s" % (form_key, form_value))
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Precommit cleanup script.')
parser.add_argument('--file', help='used for starting a new version.')
parser.add_argument('--file', required=True, help='used for starting a new version.')
args = parser.parse_args()
@ -41,24 +44,30 @@ if __name__ == '__main__':
upload_url = params['url']
upload_fields = params['fields']
upload_key = upload_fields['key']
upload_key = upload_fields.pop('key')
upload_key = upload_key + os.path.splitext(args.file)[1]
upload_fields['key'] = upload_key
download_url = 'https://debuglogs.org/' + upload_key
print 'download_url:', download_url
curl_command = ['curl', '-v', '-i', '-X', 'POST']
# key must appear before other fields
add_field(curl_command, 'key', upload_key)
for field_name in upload_fields:
field_value = upload_fields[field_name]
curl_command.append('-F')
curl_command.append("'%s=%s'" % (field_name, field_value, ))
add_field(curl_command, field_name, upload_fields[field_name])
add_field(curl_command, "content-type", "application/octet-stream")
curl_command.append('-F')
curl_command.append("'file=@%s'" % (args.file,))
curl_command.append("file=@%s" % (args.file,))
curl_command.append(upload_url)
# execute_command(curl_command)
print ' '.join(curl_command)
print 'Running...'
execute_command(curl_command)
print 'download_url:', download_url

View File

@ -305,6 +305,8 @@
458E38371D668EBF0094BD24 /* OWSDeviceProvisioningURLParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 458E38361D668EBF0094BD24 /* OWSDeviceProvisioningURLParser.m */; };
458E383A1D6699FA0094BD24 /* OWSDeviceProvisioningURLParserTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 458E38391D6699FA0094BD24 /* OWSDeviceProvisioningURLParserTest.m */; };
459311FC1D75C948008DD4F0 /* OWSDeviceTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 459311FB1D75C948008DD4F0 /* OWSDeviceTableViewCell.m */; };
4598198E204E2F28009414F2 /* OWS108CallLoggingPreference.h in Headers */ = {isa = PBXBuildFile; fileRef = 4598198C204E2F28009414F2 /* OWS108CallLoggingPreference.h */; };
4598198F204E2F28009414F2 /* OWS108CallLoggingPreference.m in Sources */ = {isa = PBXBuildFile; fileRef = 4598198D204E2F28009414F2 /* OWS108CallLoggingPreference.m */; };
45A2F005204473A3002E978A /* NewMessage.aifc in Resources */ = {isa = PBXBuildFile; fileRef = 45A2F004204473A3002E978A /* NewMessage.aifc */; };
45A663C51F92EC760027B59E /* GroupTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45A663C41F92EC760027B59E /* GroupTableViewCell.swift */; };
45A6DAD61EBBF85500893231 /* ReminderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45A6DAD51EBBF85500893231 /* ReminderView.swift */; };
@ -886,6 +888,8 @@
459311FB1D75C948008DD4F0 /* OWSDeviceTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSDeviceTableViewCell.m; sourceTree = "<group>"; };
4597E94E1D8313C100040CDE /* sq */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sq; path = translations/sq.lproj/Localizable.strings; sourceTree = "<group>"; };
4597E94F1D8313CB00040CDE /* bg */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = bg; path = translations/bg.lproj/Localizable.strings; sourceTree = "<group>"; };
4598198C204E2F28009414F2 /* OWS108CallLoggingPreference.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OWS108CallLoggingPreference.h; sourceTree = "<group>"; };
4598198D204E2F28009414F2 /* OWS108CallLoggingPreference.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OWS108CallLoggingPreference.m; sourceTree = "<group>"; };
45A2F004204473A3002E978A /* NewMessage.aifc */ = {isa = PBXFileReference; lastKnownFileType = file; name = NewMessage.aifc; path = Signal/AudioFiles/NewMessage.aifc; sourceTree = SOURCE_ROOT; };
45A663C41F92EC760027B59E /* GroupTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupTableViewCell.swift; sourceTree = "<group>"; };
45A6DAD51EBBF85500893231 /* ReminderView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReminderView.swift; sourceTree = "<group>"; };
@ -1357,6 +1361,8 @@
346129F11FD5F31400532771 /* OWS106EnsureProfileComplete.swift */,
4503F1C2204711D200CEE724 /* OWS107LegacySounds.h */,
4503F1C1204711D200CEE724 /* OWS107LegacySounds.m */,
4598198C204E2F28009414F2 /* OWS108CallLoggingPreference.h */,
4598198D204E2F28009414F2 /* OWS108CallLoggingPreference.m */,
346129931FD1E30000532771 /* OWSDatabaseMigration.h */,
346129941FD1E30000532771 /* OWSDatabaseMigration.m */,
346129E51FD5C0C600532771 /* OWSDatabaseMigrationRunner.h */,
@ -2214,6 +2220,7 @@
34480B611FD0A98800BC14EF /* UIColor+OWS.h in Headers */,
453518961FC63DBF00210559 /* SignalMessaging.h in Headers */,
3461295A1FD1D74C00532771 /* Environment.h in Headers */,
4598198E204E2F28009414F2 /* OWS108CallLoggingPreference.h in Headers */,
34480B631FD0A98800BC14EF /* UIView+OWS.h in Headers */,
451F8A4B1FD715E1005CB9DA /* OWSGroupAvatarBuilder.h in Headers */,
347850721FDAEB17007B8332 /* OWSUserProfile.h in Headers */,
@ -2997,6 +3004,7 @@
451F8A481FD715BA005CB9DA /* OWSContactAvatarBuilder.m in Sources */,
4503F1C3204711D300CEE724 /* OWS107LegacySounds.m in Sources */,
346129A61FD1F09100532771 /* OWSContactsManager.m in Sources */,
4598198F204E2F28009414F2 /* OWS108CallLoggingPreference.m in Sources */,
346129D21FD2085A00532771 /* CommonStrings.swift in Sources */,
45F59A082028E4FB00E8D2B0 /* OWSAudioSession.swift in Sources */,
34612A071FD7238600532771 /* OWSContactsSyncing.m in Sources */,

View File

@ -38,7 +38,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>2.21.0.5</string>
<string>2.21.0.9</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>LOGS_EMAIL</key>

View File

@ -3203,7 +3203,7 @@ typedef enum : NSUInteger {
NSURL *fileURL = [NSURL fileURLWithPath:filepath];
// Setup audio session
BOOL configuredAudio = [OWSAudioSession.shared setRecordCategoryWithAudioActivity:self.voiceNoteAudioActivity];
BOOL configuredAudio = [OWSAudioSession.shared startRecordingAudioActivity:self.voiceNoteAudioActivity];
if (!configuredAudio) {
OWSFail(@"%@ Couldn't configure audio session", self.logTag);
[self cancelVoiceMemo];

View File

@ -9,13 +9,6 @@ private class IntroducingCustomNotificationAudioExperienceUpgradeViewController:
var buttonAction: ((UIButton) -> Void)?
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
// Opt users in to the new default sound ("note") after they've seen the splash screen.
OWSSounds.setGlobalNotificationSound(.note)
}
override func loadView() {
self.view = UIView.container()
@ -51,8 +44,8 @@ private class IntroducingCustomNotificationAudioExperienceUpgradeViewController:
let button = addButton(title: buttonTitle) { _ in
// dismiss the modally presented view controller, then proceed.
self.experienceUpgradesPageViewController.dismiss(animated: true) {
guard let fromViewController = UIApplication.shared.frontmostViewController as? HomeViewController else {
owsFail("unexpected frontmostViewController: \(String(describing: UIApplication.shared.frontmostViewController))")
guard let fromViewController = UIApplication.shared.frontmostViewController else {
owsFail("frontmostViewController was unexectedly nil")
return
}
@ -497,12 +490,15 @@ class ExperienceUpgradesPageViewController: OWSViewController, UIPageViewControl
let pageViewController: UIPageViewController
let editingDBConnection: YapDatabaseConnection
// MARK: - Initializers
required init(experienceUpgrades: [ExperienceUpgrade]) {
self.experienceUpgrades = experienceUpgrades
setPageControlAppearance()
self.editingDBConnection = OWSPrimaryStorage.shared().newDatabaseConnection()
self.pageViewController = UIPageViewController(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil)
super.init(nibName: nil, bundle: nil)
self.pageViewController.dataSource = self
@ -512,12 +508,7 @@ class ExperienceUpgradesPageViewController: OWSViewController, UIPageViewControl
@available(*, unavailable, message:"unavailable, use initWithExperienceUpgrade instead")
required init?(coder aDecoder: NSCoder) {
assert(false)
// This should never happen, but so as not to explode we give some bogus data
self.experienceUpgrades = [ExperienceUpgrade()]
self.pageViewController = UIPageViewController(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil)
super.init(coder: aDecoder)
self.pageViewController.dataSource = self
fatalError("unimplemented")
}
// MARK: - View lifecycle
@ -686,6 +677,16 @@ class ExperienceUpgradesPageViewController: OWSViewController, UIPageViewControl
allViewControllers.append(viewController)
}
override func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) {
// Blocking write before dismiss, to be sure they're marked as complete
// before HomeView.didAppear is re-fired.
self.editingDBConnection.readWrite { transaction in
Logger.info("\(self.logTag) marking all upgrades as seen.")
ExperienceUpgradeFinder.shared.markAllAsSeen(transaction: transaction)
}
super.dismiss(animated: flag, completion: completion)
}
func didTapDismissButton(sender: UIButton) {
Logger.debug("\(TAG) in \(#function)")
self.dismiss(animated: true)

View File

@ -47,7 +47,6 @@ typedef NS_ENUM(NSInteger, CellState) { kArchiveState, kInboxState };
@property (nonatomic) UISegmentedControl *segmentedControl;
@property (nonatomic) id previewingContext;
@property (nonatomic) NSSet<NSString *> *blockedPhoneNumberSet;
@property (nonatomic) BOOL hasShownAnyUnseenUpgradeExperiences;
@property (nonatomic) BOOL isViewVisible;
@property (nonatomic) BOOL isAppInBackground;
@ -287,6 +286,13 @@ typedef NS_ENUM(NSInteger, CellState) { kArchiveState, kInboxState };
[self updateBarButtonItems];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[self displayAnyUnseenUpgradeExperience];
}
- (void)updateBarButtonItems
{
const CGFloat kBarButtonSize = 44;
@ -510,19 +516,6 @@ typedef NS_ENUM(NSInteger, CellState) { kArchiveState, kInboxState };
});
}];
}
// We want to show the user the upgrade experience as soon as the app is visible to them.
// It cannot go in viewDidAppear, which is called while the app is in the background if
// we were launched from a voip notification.
if (!self.hasShownAnyUnseenUpgradeExperiences) {
dispatch_async(dispatch_get_main_queue(), ^{
if ([[UIApplication sharedApplication] applicationState] != UIApplicationStateActive) {
return;
}
[self displayAnyUnseenUpgradeExperience];
self.hasShownAnyUnseenUpgradeExperiences = YES;
});
}
}
#pragma mark - startup
@ -532,21 +525,12 @@ typedef NS_ENUM(NSInteger, CellState) { kArchiveState, kInboxState };
OWSAssertIsOnMainThread();
__block NSArray<ExperienceUpgrade *> *unseenUpgrades;
[self.editingDbConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
[self.uiDatabaseConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
unseenUpgrades = [ExperienceUpgradeFinder.sharedManager allUnseenWithTransaction:transaction];
}];
return unseenUpgrades;
}
- (void)markAllUpgradeExperiencesAsSeen
{
OWSAssertIsOnMainThread();
[self.editingDbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) {
[ExperienceUpgradeFinder.sharedManager markAllAsSeenWithTransaction:transaction];
}];
}
- (void)displayAnyUnseenUpgradeExperience
{
OWSAssertIsOnMainThread();
@ -556,11 +540,7 @@ typedef NS_ENUM(NSInteger, CellState) { kArchiveState, kInboxState };
if (unseenUpgrades.count > 0) {
ExperienceUpgradesPageViewController *experienceUpgradeViewController =
[[ExperienceUpgradesPageViewController alloc] initWithExperienceUpgrades:unseenUpgrades];
[self presentViewController:experienceUpgradeViewController
animated:YES
completion:^{
[self markAllUpgradeExperiencesAsSeen];
}];
[self presentViewController:experienceUpgradeViewController animated:YES completion:nil];
} else if (!self.hasBeenPresented && [ProfileViewController shouldDisplayProfileViewOnLaunch]) {
[ProfileViewController presentForUpgradeOrNag:self];
} else {

View File

@ -25,6 +25,7 @@
@property (nonatomic, readonly) NotificationType notificationPreviewType;
@property (nonatomic, readonly) NSMutableArray<NSDate *> *notificationHistory;
@property (nonatomic, nullable) OWSAudioPlayer *audioPlayer;
@end
@ -238,7 +239,8 @@
} else {
if (shouldPlaySound && [Environment.preferences soundInForeground]) {
OWSSound sound = [OWSSounds notificationSoundForThread:thread];
[OWSSounds playSound:sound quiet:YES shouldRespectSilentSwitch:YES];
self.audioPlayer = [OWSSounds audioPlayerForSound:sound];
[self.audioPlayer playAsForegroundAlert];
}
}
});
@ -343,8 +345,8 @@
} else {
if (shouldPlaySound && [Environment.preferences soundInForeground]) {
OWSSound sound = [OWSSounds notificationSoundForThread:thread];
// We play the "quiet" variation of sounds if possible for notifications in the foreground.
[OWSSounds playSound:sound quiet:YES shouldRespectSilentSwitch:YES];
self.audioPlayer = [OWSSounds audioPlayerForSound:sound];
[self.audioPlayer playAsForegroundAlert];
}
}
});

View File

@ -12,6 +12,7 @@
#import <SignalMessaging/DebugLogger.h>
#import <SignalMessaging/Environment.h>
#import <SignalServiceKit/AppContext.h>
#import <SignalServiceKit/MimeTypeUtil.h>
#import <SignalServiceKit/OWSPrimaryStorage.h>
#import <SignalServiceKit/TSAccountManager.h>
#import <SignalServiceKit/TSContactThread.h>
@ -150,6 +151,9 @@ typedef void (^DebugLogUploadFailure)(DebugLogUploader *uploader, NSError *error
NSString *fieldValue = fields[fieldName];
[formData appendPartWithFormData:[fieldValue dataUsingEncoding:NSUTF8StringEncoding] name:fieldName];
}
[formData appendPartWithFormData:[weakSelf.mimeType dataUsingEncoding:NSUTF8StringEncoding]
name:@"content-type"];
NSError *error;
BOOL success = [formData appendPartWithFileURL:weakSelf.fileUrl
name:@"file"
@ -168,7 +172,7 @@ typedef void (^DebugLogUploadFailure)(DebugLogUploader *uploader, NSError *error
[self succeedWithUrl:[NSURL URLWithString:urlString]];
}
failure:^(NSURLSessionDataTask *_Nullable task, NSError *error) {
DDLogError(@"%@ failed: %@", weakSelf.logTag, uploadUrl);
DDLogError(@"%@ upload: %@ failed with error: %@", weakSelf.logTag, uploadUrl, error);
[weakSelf failWithError:error];
}];
}
@ -427,7 +431,7 @@ typedef void (^DebugLogUploadFailure)(DebugLogUploader *uploader, NSError *error
__weak Pastelog *weakSelf = self;
self.currentUploader = [DebugLogUploader new];
[self.currentUploader uploadFileWithURL:[NSURL fileURLWithPath:zipFilePath]
mimeType:@"application/zip"
mimeType:OWSMimeTypeApplicationZip
success:^(DebugLogUploader *uploader, NSURL *url) {
if (uploader != weakSelf.currentUploader) {
// Ignore events from obsolete uploaders.

View File

@ -38,7 +38,7 @@ public class OWSVideoPlayer: NSObject {
}
public func play() {
OWSAudioSession.shared.setPlaybackCategory(audioActivity: self.audioActivity)
OWSAudioSession.shared.startPlaybackAudioActivity(self.audioActivity)
guard let item = avPlayer.currentItem else {
owsFail("\(logTag) video player item was unexpectedly nil")

View File

@ -33,13 +33,29 @@ public class OWSAudioSession: NSObject {
private var currentActivities: [Weak<AudioActivity>] = []
// Ignores hardware mute switch, plays through external speaker
public func setPlaybackCategory(audioActivity: AudioActivity) {
// Respects hardware mute switch, plays through external speaker, mixes with backround audio
// appropriate for foreground sound effects.
public func startAmbientAudioActivity(_ audioActivity: AudioActivity) {
Logger.debug("\(logTag) in \(#function)")
// In general, we should have put the audio session back to it's default
// category when we were done with whatever activity required it to be modified
assert(avAudioSession.category == AVAudioSessionCategorySoloAmbient)
startAudioActivity(audioActivity)
guard currentActivities.count == 1 else {
// We don't want to clobber the audio capabilities configured by (e.g.) media playback or an in-progress call
Logger.info("\(logTag) in \(#function) not touching audio session since another currentActivity exists.")
return
}
do {
try avAudioSession.setCategory(AVAudioSessionCategoryAmbient)
} catch {
owsFail("\(logTag) in \(#function) failed with error: \(error)")
}
}
// Ignores hardware mute switch, plays through external speaker
public func startPlaybackAudioActivity(_ audioActivity: AudioActivity) {
Logger.debug("\(logTag) in \(#function)")
startAudioActivity(audioActivity)
@ -50,13 +66,9 @@ public class OWSAudioSession: NSObject {
}
}
public func setRecordCategory(audioActivity: AudioActivity) -> Bool {
public func startRecordingAudioActivity(_ audioActivity: AudioActivity) -> Bool {
Logger.debug("\(logTag) in \(#function)")
// In general, we should have put the audio session back to it's default
// category when we were done with whatever activity required it to be modified
assert(avAudioSession.category == AVAudioSessionCategorySoloAmbient)
assert(avAudioSession.recordPermission() == .granted)
startAudioActivity(audioActivity)
@ -104,8 +116,6 @@ public class OWSAudioSession: NSObject {
}
do {
try avAudioSession.setCategory(AVAudioSessionCategorySoloAmbient)
// When playing audio in Signal, other apps audio (e.g. Music) is paused.
// By notifying when we deactivate, the other app can resume playback.
try avAudioSession.setActive(false, with: [.notifyOthersOnDeactivation])

View File

@ -20,7 +20,7 @@ typedef NS_ENUM(NSUInteger, OWSSound) {
OWSSound_Popcorn,
OWSSound_Pulse,
OWSSound_Synth,
OWSSound_ClassicNotification,
OWSSound_SignalClassic,
// Ringtone Sounds
OWSSound_Opening,
@ -48,9 +48,6 @@ typedef NS_ENUM(NSUInteger, OWSSound) {
+ (nullable NSString *)filenameForSound:(OWSSound)sound;
+ (void)playSound:(OWSSound)sound shouldRespectSilentSwitch:(BOOL)shouldRespectSilentSwitch;
+ (void)playSound:(OWSSound)sound quiet:(BOOL)quiet shouldRespectSilentSwitch:(BOOL)shouldRespectSilentSwitch;
#pragma mark - Notifications
+ (NSArray<NSNumber *> *)allNotificationSounds;

View File

@ -17,8 +17,6 @@ NSString *const kOWSSoundsStorageGlobalNotificationKey = @"kOWSSoundsStorageGlob
@property (nonatomic, readonly) YapDatabaseConnection *dbConnection;
@property (nonatomic, nullable) OWSAudioPlayer *audioPlayer;
@end
#pragma mark -
@ -70,13 +68,13 @@ NSString *const kOWSSoundsStorageGlobalNotificationKey = @"kOWSSoundsStorageGlob
@(OWSSound_Bamboo),
@(OWSSound_Chord),
@(OWSSound_Circles),
@(OWSSound_ClassicNotification),
@(OWSSound_Complete),
@(OWSSound_Hello),
@(OWSSound_Input),
@(OWSSound_Keys),
@(OWSSound_Popcorn),
@(OWSSound_Pulse),
@(OWSSound_SignalClassic),
@(OWSSound_Synth),
];
}
@ -114,8 +112,8 @@ NSString *const kOWSSoundsStorageGlobalNotificationKey = @"kOWSSoundsStorageGlob
return @"Pulse";
case OWSSound_Synth:
return @"Synth";
case OWSSound_ClassicNotification:
return @"Classic";
case OWSSound_SignalClassic:
return @"Signal Classic";
// Call Audio
case OWSSound_Opening:
@ -174,7 +172,7 @@ NSString *const kOWSSoundsStorageGlobalNotificationKey = @"kOWSSoundsStorageGlob
return (quiet ? @"pulse-quiet.aifc" : @"pulse.aifc");
case OWSSound_Synth:
return (quiet ? @"synth-quiet.aifc" : @"synth.aifc");
case OWSSound_ClassicNotification:
case OWSSound_SignalClassic:
return (quiet ? @"classic-quiet.aifc" : @"classic.aifc");
// Ringtone Sounds
@ -209,27 +207,6 @@ NSString *const kOWSSoundsStorageGlobalNotificationKey = @"kOWSSoundsStorageGlob
return url;
}
+ (void)playSound:(OWSSound)sound shouldRespectSilentSwitch:(BOOL)shouldRespectSilentSwitch
{
[self.sharedManager playSound:sound quiet:NO shouldRespectSilentSwitch:shouldRespectSilentSwitch];
}
+ (void)playSound:(OWSSound)sound quiet:(BOOL)quiet shouldRespectSilentSwitch:(BOOL)shouldRespectSilentSwitch
{
[self.sharedManager playSound:sound quiet:quiet shouldRespectSilentSwitch:shouldRespectSilentSwitch];
}
- (void)playSound:(OWSSound)sound quiet:(BOOL)quiet shouldRespectSilentSwitch:(BOOL)shouldRespectSilentSwitch
{
[self.audioPlayer stop];
self.audioPlayer = [OWSSounds audioPlayerForSound:sound quiet:quiet];
if (shouldRespectSilentSwitch) {
[self.audioPlayer playWithCurrentAudioCategory];
} else {
[self.audioPlayer playWithPlaybackAudioCategory];
}
}
#pragma mark - Notifications
+ (OWSSound)defaultNotificationSound
@ -282,11 +259,18 @@ NSString *const kOWSSoundsStorageGlobalNotificationKey = @"kOWSSoundsStorageGlob
DDLogDebug(@"%@ writing new default sound to %@", self.logTag, defaultSoundPath);
NSURL *_Nullable soundURL = [OWSSounds soundURLForSound:sound quiet:NO];
OWSAssert(soundURL);
NSData *soundData = ^{
if (soundURL) {
return [NSData dataWithContentsOfURL:soundURL];
} else {
OWSAssert(sound == OWSSound_None);
return [NSData new];
}
}();
// Quick way to achieve an atomic "copy" operation that allows overwriting if the user has previously specified
// a default notification sound.
NSData *soundData = [NSData dataWithContentsOfURL:soundURL];
BOOL success = [soundData writeToFile:defaultSoundPath atomically:YES];
// The globally configured sound the user has configured is unprotected, so that we can still play the sound if the

View File

@ -22,7 +22,7 @@ static NSString *const OWS107LegacySoundsMigrationId = @"107";
{
OWSAssert(transaction);
[OWSSounds setGlobalNotificationSound:OWSSound_ClassicNotification transaction:transaction];
[OWSSounds setGlobalNotificationSound:OWSSound_SignalClassic transaction:transaction];
}
@end

View File

@ -0,0 +1,13 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import "OWSDatabaseMigration.h"
NS_ASSUME_NONNULL_BEGIN
@interface OWS108CallLoggingPreference : OWSDatabaseMigration
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,31 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import "OWS108CallLoggingPreference.h"
#import "Environment.h"
#import "OWSPreferences.h"
#import <YapDatabase/YapDatabaseTransaction.h>
NS_ASSUME_NONNULL_BEGIN
// Increment a similar constant for every future DBMigration
static NSString *const OWS108CallLoggingPreferenceId = @"108";
@implementation OWS108CallLoggingPreference
+ (NSString *)migrationId
{
return OWS108CallLoggingPreferenceId;
}
- (void)runUpWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
{
OWSAssert(transaction);
[[Environment preferences] applyCallLoggingSettingsForLegacyUsersWithTransaction:transaction];
}
@end
NS_ASSUME_NONNULL_END

View File

@ -9,6 +9,7 @@
#import "OWS104CreateRecipientIdentities.h"
#import "OWS105AttachmentFilePaths.h"
#import "OWS107LegacySounds.h"
#import "OWS108CallLoggingPreference.h"
#import "OWSDatabaseMigration.h"
#import <SignalMessaging/SignalMessaging-Swift.h>
#import <SignalServiceKit/AppContext.h>
@ -40,7 +41,8 @@ NS_ASSUME_NONNULL_BEGIN
[[OWS104CreateRecipientIdentities alloc] initWithPrimaryStorage:primaryStorage],
[[OWS105AttachmentFilePaths alloc] initWithPrimaryStorage:primaryStorage],
[[OWS106EnsureProfileComplete alloc] initWithPrimaryStorage:primaryStorage],
[[OWS107LegacySounds alloc] initWithPrimaryStorage:primaryStorage]
[[OWS107LegacySounds alloc] initWithPrimaryStorage:primaryStorage],
[[OWS108CallLoggingPreference alloc] initWithPrimaryStorage:primaryStorage]
];
}

View File

@ -38,6 +38,9 @@ typedef NS_ENUM(NSInteger, AudioPlaybackState) {
// respects silent switch
- (void)playWithCurrentAudioCategory;
// respects silent switch, mixes with others
- (void)playAsForegroundAlert;
// will ensure sound is audible, even if silent switch is enabled
- (void)playWithPlaybackAudioCategory;

View File

@ -99,11 +99,20 @@ NS_ASSUME_NONNULL_BEGIN
- (void)playWithPlaybackAudioCategory
{
OWSAssertIsOnMainThread();
[OWSAudioSession.shared setPlaybackCategoryWithAudioActivity:self.audioActivity];
[OWSAudioSession.shared startPlaybackAudioActivity:self.audioActivity];
[self play];
}
- (void)playAsForegroundAlert
{
OWSAssertIsOnMainThread();
[OWSAudioSession.shared startAmbientAudioActivity:self.audioActivity];
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
[self play];
}
- (void)play
{
OWSAssertIsOnMainThread();

View File

@ -17,6 +17,8 @@ typedef NS_ENUM(NSUInteger, NotificationType) {
extern NSString *const OWSPreferencesSignalDatabaseCollection;
extern NSString *const OWSPreferencesKeyEnableDebugLog;
@class YapDatabaseReadWriteTransaction;
@interface OWSPreferences : NSObject
#pragma mark - Helpers
@ -64,6 +66,8 @@ extern NSString *const OWSPreferencesKeyEnableDebugLog;
#pragma mark - Legacy CallKit settings
- (void)applyCallLoggingSettingsForLegacyUsersWithTransaction:(YapDatabaseReadWriteTransaction *)transaction;
- (BOOL)isCallKitEnabled;
- (void)setIsCallKitEnabled:(BOOL)flag;

View File

@ -7,6 +7,7 @@
#import <SignalServiceKit/NSUserDefaults+OWS.h>
#import <SignalServiceKit/TSStorageHeaders.h>
#import <SignalServiceKit/YapDatabaseConnection+OWS.h>
#import <SignalServiceKit/YapDatabaseTransaction+OWS.h>
NS_ASSUME_NONNULL_BEGIN
@ -52,16 +53,35 @@ NSString *const OWSPreferencesKeySystemCallLogEnabled = @"OWSPreferencesKeySyste
- (nullable id)tryGetValueForKey:(NSString *)key
{
OWSAssert(key != nil);
return [OWSPrimaryStorage.dbReadConnection objectForKey:key inCollection:OWSPreferencesSignalDatabaseCollection];
__block id result;
[OWSPrimaryStorage.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction *_Nonnull transaction) {
result = [self tryGetValueForKey:key transaction:transaction];
}];
return result;
}
- (nullable id)tryGetValueForKey:(NSString *)key transaction:(YapDatabaseReadTransaction *)transaction
{
OWSAssert(key != nil);
return [transaction objectForKey:key inCollection:OWSPreferencesSignalDatabaseCollection];
}
- (void)setValueForKey:(NSString *)key toValue:(nullable id)value
{
[OWSPrimaryStorage.dbReadWriteConnection
readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) {
[self setValueForKey:key toValue:value transaction:transaction];
}];
}
- (void)setValueForKey:(NSString *)key
toValue:(nullable id)value
transaction:(YapDatabaseReadWriteTransaction *)transaction
{
OWSAssert(key != nil);
[OWSPrimaryStorage.dbReadWriteConnection setObject:value
forKey:key
inCollection:OWSPreferencesSignalDatabaseCollection];
[transaction setObject:value forKey:key inCollection:OWSPreferencesSignalDatabaseCollection];
}
#pragma mark - Specific Preferences
@ -184,21 +204,7 @@ NSString *const OWSPreferencesKeySystemCallLogEnabled = @"OWSPreferencesKeySyste
}
NSNumber *preference = [self tryGetValueForKey:OWSPreferencesKeySystemCallLogEnabled];
if (preference) {
return preference.boolValue;
} else {
// For legacy users, who may have previously intentionally disabled CallKit because they
// didn't want their calls showing up in the call log, we want to disable call logging
NSNumber *callKitPreference = [self tryGetValueForKey:OWSPreferencesKeyCallKitEnabled];
if (callKitPreference && !callKitPreference.boolValue) {
// user explicitly opted out of callKit, so disable system call logging.
return NO;
}
}
// For everyone else, including new users, enable by default.
return YES;
return preference ? preference.boolValue : YES;
}
- (void)setIsSystemCallLogEnabled:(BOOL)flag
@ -224,11 +230,42 @@ NSString *const OWSPreferencesKeySystemCallLogEnabled = @"OWSPreferencesKeySyste
// Therefore in versions of iOS after 11, we have no need of call privacy.
#pragma mark Legacy CallKit
// Be a little conservative with system call logging with legacy users, even though it's
// not synced to iCloud, users could be concerned to suddenly see caller names in their
// recent calls list.
- (void)applyCallLoggingSettingsForLegacyUsersWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
{
NSNumber *_Nullable callKitPreference =
[self tryGetValueForKey:OWSPreferencesKeyCallKitEnabled transaction:transaction];
BOOL wasUsingCallKit = callKitPreference ? [callKitPreference boolValue] : YES;
NSNumber *_Nullable callKitPrivacyPreference =
[self tryGetValueForKey:OWSPreferencesKeyCallKitPrivacyEnabled transaction:transaction];
BOOL wasUsingCallKitPrivacy = callKitPrivacyPreference ? callKitPrivacyPreference.boolValue : YES;
BOOL shouldLogCallsInRecents = ^{
if (wasUsingCallKit && !wasUsingCallKitPrivacy) {
// User was using CallKit and explicitly opted in to showing names/numbers,
// so it's OK to continue to show names/numbers in the system recents list.
return YES;
} else {
// User was not previously showing names/numbers in the system
// recents list, so don't opt them in.
return NO;
}
}();
DDLogInfo(@"%@ Migrating setting - System Call Log Enabled: %d", self.logTag, shouldLogCallsInRecents);
[self setValueForKey:OWSPreferencesKeySystemCallLogEnabled
toValue:@(shouldLogCallsInRecents)
transaction:transaction];
}
- (BOOL)isCallKitEnabled
{
if (@available(iOS 11, *)) {
OWSFail(@"%@ CallKit privacy is irrelevant for iOS11+", self.logTag);
return NO;
OWSFail(@"%@ CallKit is always enabled for iOS11+", self.logTag);
return YES;
}
NSNumber *preference = [self tryGetValueForKey:OWSPreferencesKeyCallKitEnabled];
@ -238,7 +275,7 @@ NSString *const OWSPreferencesKeySystemCallLogEnabled = @"OWSPreferencesKeySyste
- (void)setIsCallKitEnabled:(BOOL)flag
{
if (@available(iOS 11, *)) {
OWSFail(@"%@ CallKit privacy is irrelevant for iOS11+", self.logTag);
OWSFail(@"%@ CallKit is always enabled for iOS11+", self.logTag);
return;
}
@ -249,7 +286,7 @@ NSString *const OWSPreferencesKeySystemCallLogEnabled = @"OWSPreferencesKeySyste
- (BOOL)isCallKitEnabledSet
{
if (@available(iOS 11, *)) {
OWSFail(@"%@ CallKit privacy is irrelevant for iOS11+", self.logTag);
OWSFail(@"%@ CallKit is always enabled for iOS11+", self.logTag);
return NO;
}

View File

@ -1,10 +1,11 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
NS_ASSUME_NONNULL_BEGIN
extern NSString *const OWSMimeTypeApplicationOctetStream;
extern NSString *const OWSMimeTypeApplicationZip;
extern NSString *const OWSMimeTypeImagePng;
extern NSString *const OWSMimeTypeOversizeTextMessage;
extern NSString *const OWSMimeTypeUnknownForTests;

View File

@ -19,6 +19,7 @@ NSString *const OWSMimeTypeApplicationOctetStream = @"application/octet-stream";
NSString *const OWSMimeTypeImagePng = @"image/png";
NSString *const OWSMimeTypeOversizeTextMessage = @"text/x-signal-plain";
NSString *const OWSMimeTypeUnknownForTests = @"unknown/mimetype";
NSString *const OWSMimeTypeApplicationZip = @"application/zip";
NSString *const kOversizeTextAttachmentUTI = @"org.whispersystems.oversize-text-attachment";
NSString *const kOversizeTextAttachmentFileExtension = @"txt";
@ -1250,7 +1251,7 @@ NSString *const kSyncMessageFileExtension = @"bin";
@"application/yang" : @"yang",
@"application/yin+xml" : @"yin",
@"application/ynd.ms-pkipko" : @"pko",
@"application/zip" : @"zip",
OWSMimeTypeApplicationZip : @"zip",
@"audio/aac" : @"aac",
@"audio/adpcm" : @"adp",
@"audio/aiff" : @"aiff",
@ -2557,7 +2558,7 @@ NSString *const kSyncMessageFileExtension = @"bin";
@"z7" : @"application/x-zmachine",
@"z8" : @"application/x-zmachine",
@"zaz" : @"application/vnd.zzazz.deck+xml",
@"zip" : @"application/zip",
@"zip" : OWSMimeTypeApplicationZip,
@"zir" : @"application/vnd.zul",
@"zirz" : @"application/vnd.zul",
@"zmm" : @"application/vnd.handheld-entertainment+xml",

View File

@ -19,7 +19,7 @@
<key>CFBundleShortVersionString</key>
<string>2.21.0</string>
<key>CFBundleVersion</key>
<string>2.21.0.5</string>
<string>2.21.0.9</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>NSAppTransportSecurity</key>