Skip to content

Commit 4f60274

Browse files
committed
Physical LED count
1 parent 1bf814f commit 4f60274

File tree

6 files changed

+116
-41
lines changed

6 files changed

+116
-41
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
TARGET := iphone:clang:latest:11.0
22
INSTALL_TARGET_PROCESSES = TrollLEDs
33
ARCHS = arm64
4-
PACKAGE_VERSION = 1.5.0
4+
PACKAGE_VERSION = 1.6.0
55

66
include $(THEOS)/makefiles/common.mk
77

README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515

1616
Quad-LEDs devices are devices with four programmatically configurable flashlight LEDs, two white and two amber. This includes the devices such as iPhone 11 and iPad Pro 3rd generation.
1717

18+
### Sliders
19+
1820
There are four sliders in the app:
1921

2022
1. `Cool LED 0` - The brightness of the first white LED
@@ -26,6 +28,18 @@ Each slider can be adjusted independently. The more the value, the more brightne
2628

2729
Devices with four physical LEDs such as iPad Pro 3rd generation will get the maximum brightness of the LEDs when all sliders are set to 100%. However, devices with two physical LEDs such as iPhone 11 will get the maximum brightness of the LEDs when `Cool LED 0` and `Warm LED 0` are set to 100%, while the others are set to 0%. The `Cool LED 1` and `Warm LED 1` sliders only act as a low brightness mode for their `LED 0` equivalent.
2830

31+
### Physical LED Count
32+
33+
Despite being categorized as a quad-LEDs device, it may have only two physical LEDs. TrollLEDs allows you to explicitly set the physical LED count in the app (There is no good way to automatically detect the physical LED count, yet).
34+
35+
If the value is set to `Dual`:
36+
37+
1. The app shortcut `Amber On` will maximize the `Warm LED 0` slider only
38+
2. The app shortcut `White On` will maximize the `Cool LED 0` slider only
39+
3. The app shortcut `All On` will maximize the `Cool LED 0` and `Warm LED 0` sliders only
40+
41+
If the value is set to `Quad`, the app shortcuts will maximize all related sliders.
42+
2943
## Usage (Dual-LEDs Devices)
3044

3145
Dual-LEDs devices are devices with two programmatically configurable flashlight LEDs, such as iPhone 5s and iPhone SE 1st generation.

Resources/Info.plist

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,9 @@
4444
<string>iPhoneOS</string>
4545
</array>
4646
<key>CFBundleShortVersionString</key>
47-
<string>1.5.0</string>
47+
<string>1.6.0</string>
4848
<key>CFBundleVersion</key>
49-
<string>1.5.0</string>
49+
<string>1.6.0</string>
5050
<key>LSRequiresIPhoneOS</key>
5151
<true/>
5252
<key>MinimumOSVersion</key>

TLDeviceManager.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,9 @@
1212
OpaqueFigCaptureStreamRef streamRef;
1313
CMBaseObjectSetPropertyFunction streamSetProperty;
1414
BOOL legacyLEDs;
15-
BOOL quadLEDs;
1615
}
1716
@property (nonatomic, strong) NSString *currentError;
1817
- (BOOL)isLegacyLEDs;
19-
- (BOOL)isQuadLEDs;
2018
- (BOOL)setupStream;
2119
- (void)releaseStream;
2220
- (void)initVendor;

TLDeviceManager.m

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,9 @@ - (void)checkType {
2222
CFMutableDictionaryRef (*IOServiceMatching)(const char *name) = (CFMutableDictionaryRef (*)(const char *))dlsym(IOKit, "IOServiceMatching");
2323
mach_port_t (*IOServiceGetMatchingService)(mach_port_t masterPort, CFDictionaryRef matching) = (mach_port_t (*)(mach_port_t, CFDictionaryRef))dlsym(IOKit, "IOServiceGetMatchingService");
2424
kern_return_t (*IOObjectRelease)(mach_port_t object) = (kern_return_t (*)(mach_port_t))dlsym(IOKit, "IOObjectRelease");
25-
mach_port_t h13 = IOServiceGetMatchingService(*kIOMasterPortDefault, IOServiceMatching("AppleH13CamIn"));
2625
mach_port_t h9 = IOServiceGetMatchingService(*kIOMasterPortDefault, IOServiceMatching("AppleH9CamIn"));
2726
mach_port_t h6 = IOServiceGetMatchingService(*kIOMasterPortDefault, IOServiceMatching("AppleH6CamIn"));
28-
quadLEDs = h13;
2927
legacyLEDs = h9 || h6;
30-
if (h13) IOObjectRelease(h13);
3128
if (h9) IOObjectRelease(h9);
3229
if (h6) IOObjectRelease(h6);
3330
}
@@ -109,10 +106,6 @@ - (BOOL)isLegacyLEDs {
109106
return legacyLEDs;
110107
}
111108

112-
- (BOOL)isQuadLEDs {
113-
return quadLEDs;
114-
}
115-
116109
- (void)setNumberProperty:(CFStringRef)property value:(id)value {
117110
if (stream)
118111
[stream setProperty:property value:value];

TLRootViewController.m

Lines changed: 99 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
#include <Foundation/Foundation.h>
12
#import <objc/objc.h>
3+
#import <theos/IOSMacros.h>
24
#import <UIKit/UIColor+Private.h>
35
#import "TLRootViewController.h"
46

@@ -22,6 +24,10 @@ @interface TLRootViewController () {
2224
@property (nonatomic, strong) NSMutableArray <NSLayoutConstraint *> *lockSwitchConstraints;
2325
@property (nonatomic, strong) UILabel *lockSwitchLabel;
2426
@property (nonatomic, strong) NSMutableArray <NSLayoutConstraint *> *lockSwitchLabelConstraints;
27+
@property (nonatomic, strong) UISegmentedControl *ledCount;
28+
@property (nonatomic, strong) NSMutableArray <NSLayoutConstraint *> *ledCountConstraints;
29+
@property (nonatomic, strong) UILabel *ledCountLabel;
30+
@property (nonatomic, strong) NSMutableArray <NSLayoutConstraint *> *ledCountLabelConstraints;
2531
@end
2632

2733
@implementation TLRootViewController
@@ -38,6 +44,8 @@ @implementation TLRootViewController
3844
@synthesize lockSwitchConstraints = _lockSwitchConstraints;
3945
@synthesize lockSwitchLabel = _lockSwitchLabel;
4046
@synthesize lockSwitchLabelConstraints = _lockSwitchLabelConstraints;
47+
@synthesize ledCount = _ledCount;
48+
@synthesize ledCountConstraints = _ledCountConstraints;
4149

4250
- (instancetype)init {
4351
self = [super init];
@@ -62,9 +70,13 @@ - (void)releaseStream {
6270
[_deviceManager releaseStream];
6371
}
6472

73+
- (BOOL)isQuadLEDs {
74+
return [[NSUserDefaults standardUserDefaults] boolForKey:@"TLQuadLEDs"];
75+
}
76+
6577
- (void)handleShortcutAction:(NSString *)shortcutType {
6678
BOOL legacy = [_deviceManager isLegacyLEDs];
67-
BOOL quad = [_deviceManager isQuadLEDs];
79+
BOOL quad = [self isQuadLEDs];
6880
if ([shortcutType isEqualToString:@"com.ps.TrollLEDs.AmberOn"]) {
6981
if (legacy) {
7082
LEDLevel = 100;
@@ -152,31 +164,16 @@ - (NSString *)switchLabel {
152164
return locked ? @"On: Only TrollLEDs can control the LEDs" : @"Off: Release the LEDs to other apps (this may take few seconds)";
153165
}
154166

155-
- (void)viewDidLoad {
156-
[super viewDidLoad];
157-
158-
NSString *currentError = _deviceManager.currentError;
159-
if (currentError) {
160-
[self printError:currentError];
161-
return;
162-
}
163-
164-
BOOL isLegacyLEDs = [_deviceManager isLegacyLEDs];
165-
167+
- (void)configureTableView {
166168
UITableView *tableView = (UITableView *)self.view;
167169
tableView.scrollEnabled = NO;
168170
tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
169171
tableView.backgroundColor = [UIColor blackColor];
172+
}
170173

171-
_sliders = [[NSMutableArray alloc] init];
172-
_sliderConstraints = [[NSMutableArray alloc] init];
173-
_sliderLabels = [[NSMutableArray alloc] init];
174-
_sliderLabelConstraints = [[NSMutableArray alloc] init];
175-
_sliderValueLabels = [[NSMutableArray alloc] init];
176-
_sliderValueLabelConstraints = [[NSMutableArray alloc] init];
174+
- (void)configureLockSwitch {
177175
_lockSwitchConstraints = [[NSMutableArray alloc] init];
178176
_lockSwitchLabelConstraints = [[NSMutableArray alloc] init];
179-
int sliderCount = isLegacyLEDs ? 2 : 4;
180177

181178
_lockSwitch = [[UISwitch alloc] init];
182179
_lockSwitch.translatesAutoresizingMaskIntoConstraints = NO;
@@ -194,14 +191,44 @@ - (void)viewDidLoad {
194191
_lockSwitchLabel.font = [UIFont systemFontOfSize:14];
195192

196193
[self.view addSubview:_lockSwitchLabel];
194+
}
195+
196+
- (void)configureLEDCount {
197+
_ledCountConstraints = [[NSMutableArray alloc] init];
198+
_ledCountLabelConstraints = [[NSMutableArray alloc] init];
199+
200+
_ledCount = [[UISegmentedControl alloc] initWithItems:@[@"Dual", @"Quad"]];
201+
_ledCount.translatesAutoresizingMaskIntoConstraints = NO;
202+
_ledCount.selectedSegmentIndex = [self isQuadLEDs] ? 1 : 0;
203+
[_ledCount addTarget:self action:@selector(ledCountChanged:) forControlEvents:UIControlEventValueChanged];
204+
205+
[self.view addSubview:_ledCount];
206+
207+
_ledCountLabel = [[UILabel alloc] init];
208+
_ledCountLabel.translatesAutoresizingMaskIntoConstraints = NO;
209+
_ledCountLabel.text = @"Physical LED Count";
210+
_ledCountLabel.textColor = [UIColor systemGrayColor];
211+
_ledCountLabel.textAlignment = NSTextAlignmentCenter;
212+
_ledCountLabel.font = [UIFont systemFontOfSize:14];
213+
214+
[self.view addSubview:_ledCountLabel];
215+
}
216+
217+
- (void)configureLEDSliders:(int)sliderCount maximumValue:(int)maximumValue {
218+
_sliders = [[NSMutableArray alloc] init];
219+
_sliderConstraints = [[NSMutableArray alloc] init];
220+
_sliderLabels = [[NSMutableArray alloc] init];
221+
_sliderLabelConstraints = [[NSMutableArray alloc] init];
222+
_sliderValueLabels = [[NSMutableArray alloc] init];
223+
_sliderValueLabelConstraints = [[NSMutableArray alloc] init];
197224

198225
for (NSInteger i = 0; i < sliderCount; i++) {
199226
UIColor *color = [self color:i];
200227

201228
UISlider *slider = [[UISlider alloc] init];
202229
slider.translatesAutoresizingMaskIntoConstraints = NO;
203230
slider.minimumValue = 0;
204-
slider.maximumValue = isLegacyLEDs ? 100 : 255;
231+
slider.maximumValue = maximumValue;
205232
slider.value = 0;
206233
slider.minimumTrackTintColor = color;
207234
slider.transform = CGAffineTransformMakeRotation(-M_PI_2);
@@ -242,6 +269,25 @@ - (void)viewDidLoad {
242269
[self.view addSubview:valueLabel];
243270
[_sliderValueLabels addObject:valueLabel];
244271
}
272+
}
273+
274+
- (void)viewDidLoad {
275+
[super viewDidLoad];
276+
277+
NSString *currentError = _deviceManager.currentError;
278+
if (currentError) {
279+
[self printError:currentError];
280+
return;
281+
}
282+
283+
BOOL isLegacyLEDs = [_deviceManager isLegacyLEDs];
284+
int sliderCount = isLegacyLEDs ? 2 : 4;
285+
286+
[self configureTableView];
287+
[self configureLockSwitch];
288+
if (!isLegacyLEDs)
289+
[self configureLEDCount];
290+
[self configureLEDSliders:sliderCount maximumValue:isLegacyLEDs ? 100 : 255];
245291

246292
if (_shortcutAction) {
247293
[self handleShortcutAction:_shortcutAction];
@@ -252,36 +298,56 @@ - (void)viewDidLoad {
252298
- (void)viewWillLayoutSubviews {
253299
[super viewWillLayoutSubviews];
254300

301+
BOOL isLegacyLEDs = [_deviceManager isLegacyLEDs];
302+
255303
[NSLayoutConstraint deactivateConstraints:_sliderConstraints];
256304
[NSLayoutConstraint deactivateConstraints:_sliderLabelConstraints];
257305
[NSLayoutConstraint deactivateConstraints:_sliderValueLabelConstraints];
258306
[NSLayoutConstraint deactivateConstraints:_lockSwitchConstraints];
259307
[NSLayoutConstraint deactivateConstraints:_lockSwitchLabelConstraints];
308+
260309
[_sliderConstraints removeAllObjects];
261310
[_sliderLabelConstraints removeAllObjects];
262311
[_sliderValueLabelConstraints removeAllObjects];
263312
[_lockSwitchConstraints removeAllObjects];
264313
[_lockSwitchLabelConstraints removeAllObjects];
265314

266-
UISwitch *lockSwitch = _lockSwitch;
315+
if (!isLegacyLEDs) {
316+
[NSLayoutConstraint deactivateConstraints:_ledCountConstraints];
317+
[NSLayoutConstraint deactivateConstraints:_ledCountLabelConstraints];
318+
[_ledCountConstraints removeAllObjects];
319+
[_ledCountLabelConstraints removeAllObjects];
320+
}
267321

268-
NSLayoutConstraint *lockSwitchCenterX = [lockSwitch.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor];
269-
NSLayoutConstraint *lockSwitchTop = [lockSwitch.topAnchor constraintEqualToAnchor:self.view.topAnchor constant:20];
322+
NSLayoutConstraint *lockSwitchCenterX = [_lockSwitch.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor];
323+
NSLayoutConstraint *lockSwitchTop = [_lockSwitch.topAnchor constraintEqualToAnchor:self.view.topAnchor constant:20];
270324

271325
[_lockSwitchConstraints addObjectsFromArray:@[lockSwitchCenterX, lockSwitchTop]];
272326
[NSLayoutConstraint activateConstraints:_lockSwitchConstraints];
273327

274-
UILabel *lockSwitchLabel = _lockSwitchLabel;
275-
276-
NSLayoutConstraint *lockSwitchLabelCenterX = [lockSwitchLabel.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor];
277-
NSLayoutConstraint *lockSwitchLabelTop = [lockSwitchLabel.topAnchor constraintEqualToAnchor:lockSwitch.bottomAnchor constant:10];
278-
NSLayoutConstraint *lockSwitchLabelWidth = [lockSwitchLabel.widthAnchor constraintEqualToAnchor:self.view.widthAnchor multiplier:0.9];
328+
NSLayoutConstraint *lockSwitchLabelCenterX = [_lockSwitchLabel.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor];
329+
NSLayoutConstraint *lockSwitchLabelTop = [_lockSwitchLabel.topAnchor constraintEqualToAnchor:_lockSwitch.bottomAnchor constant:10];
330+
NSLayoutConstraint *lockSwitchLabelWidth = [_lockSwitchLabel.widthAnchor constraintEqualToAnchor:self.view.widthAnchor multiplier:0.9];
279331

280332
[_lockSwitchLabelConstraints addObjectsFromArray:@[lockSwitchLabelCenterX, lockSwitchLabelTop, lockSwitchLabelWidth]];
281333
[NSLayoutConstraint activateConstraints:_lockSwitchLabelConstraints];
282334

335+
if (!isLegacyLEDs) {
336+
NSLayoutConstraint *ledCountCenterX = [_ledCount.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor];
337+
NSLayoutConstraint *ledCountBottom = [_ledCount.bottomAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.bottomAnchor constant:-20];
338+
339+
[_ledCountConstraints addObjectsFromArray:@[ledCountCenterX, ledCountBottom]];
340+
[NSLayoutConstraint activateConstraints:_ledCountConstraints];
341+
342+
NSLayoutConstraint *ledCountLabelCenterX = [_ledCountLabel.centerXAnchor constraintEqualToAnchor:self.view.centerXAnchor];
343+
NSLayoutConstraint *ledCountLabelBottom = [_ledCountLabel.bottomAnchor constraintEqualToAnchor:_ledCount.topAnchor constant:-10];
344+
345+
[_ledCountLabelConstraints addObjectsFromArray:@[ledCountLabelCenterX, ledCountLabelBottom]];
346+
[NSLayoutConstraint activateConstraints:_ledCountLabelConstraints];
347+
}
348+
283349
CGFloat sliderWidth = 30.0;
284-
CGFloat sliderHeight = self.view.bounds.size.height * 0.4;
350+
CGFloat sliderHeight = self.view.bounds.size.height * (IS_IPAD || isLegacyLEDs ? 0.4 : 0.3);
285351
CGFloat totalSlidersWidth = _sliders.count * sliderWidth;
286352
CGFloat spacing = (self.view.bounds.size.width - totalSlidersWidth) / (_sliders.count + 1);
287353

@@ -315,6 +381,10 @@ - (void)viewWillLayoutSubviews {
315381
[NSLayoutConstraint activateConstraints:_sliderValueLabelConstraints];
316382
}
317383

384+
- (void)ledCountChanged:(UISegmentedControl *)sender {
385+
[[NSUserDefaults standardUserDefaults] setBool:sender.selectedSegmentIndex == 1 forKey:@"TLQuadLEDs"];
386+
}
387+
318388
- (void)sliderValueTapped:(UITapGestureRecognizer *)sender {
319389
if (!locked) return;
320390
UILabel *label = (UILabel *)sender.view;

0 commit comments

Comments
 (0)