aboutsummaryrefslogtreecommitdiff
path: root/Foundation
diff options
context:
space:
mode:
authorGravatar dmaclach <dmaclach@gmail.com>2019-01-03 08:22:28 -0800
committerGravatar GitHub <noreply@github.com>2019-01-03 08:22:28 -0800
commit1057c99ca375a6b53ca079cede47fe2e9dce4d8b (patch)
treec4dec2f1575c27eba1121b4f7e54187e2ecb15be /Foundation
parentf18111ecb67a4a33f2f4d91705d032dcf00b76f5 (diff)
Add GTMTimeUtils (#229)
Utilities for relatively common desire to know the launch time of an app, or the boot time of a device.
Diffstat (limited to 'Foundation')
-rw-r--r--Foundation/GTMTimeUtils.h35
-rw-r--r--Foundation/GTMTimeUtils.m72
-rw-r--r--Foundation/GTMTimeUtilsTest.m45
3 files changed, 152 insertions, 0 deletions
diff --git a/Foundation/GTMTimeUtils.h b/Foundation/GTMTimeUtils.h
new file mode 100644
index 0000000..9b49532
--- /dev/null
+++ b/Foundation/GTMTimeUtils.h
@@ -0,0 +1,35 @@
+//
+// GTMTimeUtils.h
+//
+// Copyright 2018 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+//
+
+#import <Foundation/Foundation.h>
+
+// Return the date that the app was launched.
+NSDate *GTMAppLaunchDate(void);
+
+// Return the date that the device was started. Note on the simulator that this
+// returns the date that the computer was started, not the simulator.
+NSDate *GTMBootDate(void);
+
+// Convert a timeval to NSTimeInterval.
+NSTimeInterval GTMTimeValToNSTimeInterval(struct timeval time);
+
+// Timeval versions of the functions above if timevals are a more useful
+// structure to work with.
+struct timeval GTMBootTimeRelativeTo1970(void);
+struct timeval GTMAppLaunchTimeRelativeTo1970(void);
+
diff --git a/Foundation/GTMTimeUtils.m b/Foundation/GTMTimeUtils.m
new file mode 100644
index 0000000..2b551e4
--- /dev/null
+++ b/Foundation/GTMTimeUtils.m
@@ -0,0 +1,72 @@
+//
+// GTMTimeUtils.m
+//
+// Copyright 2018 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+//
+
+#import "GTMTimeUtils.h"
+
+#include <sys/sysctl.h>
+
+#import "GTMDefines.h"
+
+NSTimeInterval GTMTimeValToNSTimeInterval(struct timeval time) {
+ return time.tv_sec + (time.tv_usec / (double)USEC_PER_SEC);
+}
+
+struct timeval GTMBootTimeRelativeTo1970(void) {
+ struct timeval bootTime = { 0, 0 };
+ int mib[2] = { CTL_KERN, KERN_BOOTTIME };
+ size_t bootTimeSize = sizeof(bootTime);
+ if (sysctl(mib, 2, &bootTime, &bootTimeSize, NULL, 0) != 0) {
+ _GTMDevAssert(errno == 0, @"sysctl error - %d", errno);
+ struct timeval invalid = { 0, 0 };
+ return invalid;
+ }
+ return bootTime;
+}
+
+struct timeval GTMAppLaunchTimeRelativeTo1970(void) {
+ id_t pid = getpid();
+ int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, (int)pid };
+ const size_t mibSize = sizeof(mib) / sizeof(mib[0]);
+ size_t infoSize = 0;
+
+ // Get initial size of KERN_PROC data structure.
+ if (sysctl(mib, mibSize, NULL, &infoSize, NULL, 0) != 0) {
+ _GTMDevAssert(errno == 0, @"sysctl error - %d", errno);
+ struct timeval invalid = { 0, 0 };
+ return invalid;
+ }
+ struct kinfo_proc info;
+ if (sysctl(mib, mibSize, &info, &infoSize, NULL, 0) != 0) {
+ _GTMDevAssert(errno == 0, @"sysctl error - %d", errno);
+ struct timeval invalid = { 0, 0 };
+ return invalid;
+ }
+ return info.kp_proc.p_starttime;
+}
+
+NSDate *GTMAppLaunchDate() {
+ NSTimeInterval ti =
+ GTMTimeValToNSTimeInterval(GTMAppLaunchTimeRelativeTo1970());
+ return [NSDate dateWithTimeIntervalSince1970:ti];
+}
+
+NSDate *GTMBootDate() {
+ NSTimeInterval ti =
+ GTMTimeValToNSTimeInterval(GTMBootTimeRelativeTo1970());
+ return [NSDate dateWithTimeIntervalSince1970:ti];
+}
diff --git a/Foundation/GTMTimeUtilsTest.m b/Foundation/GTMTimeUtilsTest.m
new file mode 100644
index 0000000..471cad0
--- /dev/null
+++ b/Foundation/GTMTimeUtilsTest.m
@@ -0,0 +1,45 @@
+//
+// GTMTimeUtilsTest.m
+//
+// Copyright 2018 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+//
+
+#import "GTMSenTestCase.h"
+#import "GTMTimeUtils.h"
+
+@interface GTMTimeUtilsTest : GTMTestCase
+@end
+
+@implementation GTMTimeUtilsTest
+
+- (void)testAppLaunchDate {
+ // Basic test to verify that "now" is after appLaunch.
+ NSDate *now = [NSDate date];
+ NSDate *appLaunch = GTMAppLaunchDate();
+
+ XCTAssertEqual([now compare:appLaunch], NSOrderedDescending,
+ @"now: %@ appLaunch: %@", now, appLaunch);
+}
+
+- (void)testBootDate {
+ // Basic test to verify that appLaunch occurred after boot.
+ NSDate *appLaunch = GTMAppLaunchDate();
+ NSDate *boot = GTMBootDate();
+
+ XCTAssertEqual([appLaunch compare:boot], NSOrderedDescending,
+ @"appLaunch: %@ boot: %@", appLaunch, boot);
+}
+
+@end