Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Add support for using iSH on Apple Watches #842

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ You'll need these things to build the project:

Open the project in Xcode, open iSH.xcconfig, and change `ROOT_BUNDLE_IDENTIFIER` to something unique. Then click Run. There are scripts that should do everything else automatically. If you run into any problems, open an issue and I'll try to help.

If you want to deploy the project onto your own devices, you'll need a valid developer account. Sign in to your account via Xcode: Xcode -> Preferences -> Accounts. Now go to the project settings and change the value for Signing > Development Team under Build Settings to your development team. To do this a bit more automatically, change the value for one project and then change all occurances of `CK5SXRTBR7` in `iSH.xcodeproj/project.pbxproj` to your development ID for all `DevelopmentTeam` fields. Your ID will be the one not matching `CK5SXRTBR7`.

## Build command line tool for testing

To set up your environment, cd to the project and run `meson build` to create a build directory in `build`. Then cd to the build directory and run `ninja`.
Expand Down
76 changes: 75 additions & 1 deletion app/AppDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,14 @@
#import "Roots.h"
#import "TerminalViewController.h"
#import "UserPreferences.h"
#import <WatchConnectivity/WatchConnectivity.h>
#include "kernel/init.h"
#include "kernel/calls.h"
#include "fs/dyndev.h"
#include "fs/devices.h"
#include "fs/path.h"

@interface AppDelegate ()
@interface AppDelegate () <WCSessionDelegate>

@property BOOL exiting;
@property NSString *unameVersion;
Expand Down Expand Up @@ -203,6 +204,15 @@ + (int)bootError {
}

- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary<UIApplicationLaunchOptionsKey,id> *)launchOptions {
if(WCSession.isSupported){
WCSession* session = WCSession.defaultSession;
session.delegate = self;
[session activateSession];
NSLog(@"Started watch session");
} else {
NSLog(@"Watch communication not supported");
}

NSUserDefaults *defaults = NSUserDefaults.standardUserDefaults;
if ([defaults boolForKey:@"hail mary"]) {
[defaults removeObjectForKey:kPreferenceBootCommandKey];
Expand Down Expand Up @@ -289,6 +299,70 @@ - (void)applicationDidEnterBackground:(UIApplication *)application {
exit(0);
}

- (void)session:(WCSession *)session didReceiveMessage:(NSDictionary<NSString *, id> *)message replyHandler:(void(^)(NSDictionary<NSString *, id> *replyMessage))replyHandler
{
NSLog(@"Received message from watch");

if (message) {
NSString* command = [message objectForKey:@"command"];

NSLog(@"Got command: %@", command);

if (currentTerminalViewController == NULL) {
NSLog(@"No terminal view controller available");
NSDictionary* response = @{@"error" : @"The terminal view is not available"};
replyHandler(response);
} else {
NSLog(@"Sending command");
NSData *input = [command dataUsingEncoding:NSUTF8StringEncoding];
dispatch_async(dispatch_get_main_queue(), ^{
[currentTerminalViewController.sessionTerminal sendInput:input.bytes length:input.length];
});
NSDictionary* response = @{@"message" : @". .."};
replyHandler(response);
}
}
}

-(void)sessionWatchStateDidChange:(nonnull WCSession *)session
{

if(WCSession.isSupported){
WCSession* session = WCSession.defaultSession;
session.delegate = self;
[session activateSession];


if(session.reachable){
NSLog(@"session.reachable");
}

if(session.paired){
NSLog(@"watch is paired");
if(session.isWatchAppInstalled){
NSLog(@"watch app is installed");
if(session.watchDirectoryURL != nil) {
NSLog(@"watch got directory URL %@", session.watchDirectoryURL);
}
}
}


}
}

- (void)session:(nonnull WCSession *)session activationDidCompleteWithState:(WCSessionActivationState)activationState error:(nullable NSError *)error {
NSLog(@"Watch session became active with status: %ld", activationState);
}

- (void)sessionDidBecomeInactive:(nonnull WCSession *)session {
NSLog(@"Watch session became inactive");
}

- (void)sessionDidDeactivate:(nonnull WCSession *)session {
NSLog(@"Watch session became deactivated");
}

@end

NSString *const ProcessExitedNotification = @"ProcessExitedNotification";
2 changes: 1 addition & 1 deletion app/FileProvider/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>73</string>
<string>$(PRODUCT_VERSION)</string>
<key>NSExtension</key>
<dict>
<key>NSExtensionFileProviderDocumentGroup</key>
Expand Down
2 changes: 1 addition & 1 deletion app/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>73</string>
<string>$(PRODUCT_VERSION)</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
Expand Down
1 change: 1 addition & 0 deletions app/TerminalViewController.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
- (void)startNewSession;
- (void)reconnectSessionFromTerminalUUID:(NSUUID *)uuid;
@property (readonly) NSUUID *sessionTerminalUUID; // 0 means invalid
@property (nonatomic) Terminal *sessionTerminal;
@property UISceneSession *sceneSession API_AVAILABLE(ios(13.0));

@end
Expand Down
1 change: 0 additions & 1 deletion app/TerminalViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ @interface TerminalViewController () <UIGestureRecognizerDelegate>
@property (weak, nonatomic) IBOutlet UIButton *hideKeyboardButton;

@property int sessionPid;
@property (nonatomic) Terminal *sessionTerminal;
@property int sessionTerminalNumber;

@property BOOL ignoreKeyboardMotion;
Expand Down
3 changes: 3 additions & 0 deletions iSH.xcconfig
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@ ROOT_BUNDLE_IDENTIFIER = app.ish.iSH
ISH_LOG =

PRODUCT_APP_GROUP_IDENTIFIER = group.$(ROOT_BUNDLE_IDENTIFIER)

// Change this to change all versions of the app and watch app
PRODUCT_VERSION = 73
Loading