base: Implement GetCurrentThreadPriority.

The Chrome thread priority is saved in the thread dictionary during
SetCurrentThreadPriority(). This seemed a better approach than using
thread_policy_get(), since there are 4 Chrome priorities which won't cleanly map
to thread flavors.

BUG=554651

Review URL: https://codereview.chromium.org/1620673003

Cr-Commit-Position: refs/heads/master@{#381102}
diff --git a/base/threading/platform_thread.h b/base/threading/platform_thread.h
index e62eb2b..72da93b 100644
--- a/base/threading/platform_thread.h
+++ b/base/threading/platform_thread.h
@@ -99,7 +99,7 @@
 
 // Valid values for priority of Thread::Options and SimpleThread::Options, and
 // SetCurrentThreadPriority(), listed in increasing order of importance.
-enum class ThreadPriority {
+enum class ThreadPriority : int {
   // Suitable for threads that shouldn't disrupt high priority work.
   BACKGROUND,
   // Default priority level.
diff --git a/base/threading/platform_thread_mac.mm b/base/threading/platform_thread_mac.mm
index 7ab47cb4..51f3621 100644
--- a/base/threading/platform_thread_mac.mm
+++ b/base/threading/platform_thread_mac.mm
@@ -15,6 +15,7 @@
 
 #include "base/lazy_instance.h"
 #include "base/logging.h"
+#include "base/mac/foundation_util.h"
 #include "base/mac/mach_logging.h"
 #include "base/threading/thread_id_name_manager.h"
 #include "base/tracked_objects.h"
@@ -22,6 +23,10 @@
 
 namespace base {
 
+namespace {
+NSString* const kThreadPriorityKey = @"CrThreadPriorityKey";
+}  // namespace
+
 // If Cocoa is to be used on more than one thread, it must know that the
 // application is multithreaded.  Since it's possible to enter Cocoa code
 // from threads created by pthread_thread_create, Cocoa won't necessarily
@@ -164,21 +169,41 @@
 
   switch (priority) {
     case ThreadPriority::NORMAL:
+    case ThreadPriority::BACKGROUND:
+    case ThreadPriority::DISPLAY:
+      // Add support for non-NORMAL thread priorities. https://crbug.com/554651
       SetPriorityNormal(mach_thread_id);
       break;
     case ThreadPriority::REALTIME_AUDIO:
       SetPriorityRealtimeAudio(mach_thread_id);
       break;
-    default:
-      NOTREACHED() << "Unknown priority.";
-      break;
   }
+
+  [[[NSThread currentThread] threadDictionary]
+      setObject:@(static_cast<int>(priority))
+         forKey:kThreadPriorityKey];
 }
 
 // static
 ThreadPriority PlatformThread::GetCurrentThreadPriority() {
-  NOTIMPLEMENTED();
-  return ThreadPriority::NORMAL;
+  NSNumber* priority = base::mac::ObjCCast<NSNumber>([[[NSThread currentThread]
+      threadDictionary] objectForKey:kThreadPriorityKey]);
+
+  if (!priority)
+    return ThreadPriority::NORMAL;
+
+  ThreadPriority thread_priority =
+      static_cast<ThreadPriority>(priority.intValue);
+  switch (thread_priority) {
+    case ThreadPriority::BACKGROUND:
+    case ThreadPriority::NORMAL:
+    case ThreadPriority::DISPLAY:
+    case ThreadPriority::REALTIME_AUDIO:
+      return thread_priority;
+    default:
+      NOTREACHED() << "Unknown priority.";
+      return ThreadPriority::NORMAL;
+  }
 }
 
 size_t GetDefaultThreadStackSize(const pthread_attr_t& attributes) {
diff --git a/base/threading/platform_thread_unittest.cc b/base/threading/platform_thread_unittest.cc
index 1c68ded..6738775 100644
--- a/base/threading/platform_thread_unittest.cc
+++ b/base/threading/platform_thread_unittest.cc
@@ -239,16 +239,9 @@
 
 }  // namespace
 
-#if defined(OS_MACOSX)
-// PlatformThread::GetCurrentThreadPriority() is not implemented on OS X.
-#define MAYBE_ThreadPriorityCurrentThread DISABLED_ThreadPriorityCurrentThread
-#else
-#define MAYBE_ThreadPriorityCurrentThread ThreadPriorityCurrentThread
-#endif
-
 // Test changing a created thread's priority (which has different semantics on
 // some platforms).
-TEST(PlatformThreadTest, MAYBE_ThreadPriorityCurrentThread) {
+TEST(PlatformThreadTest, ThreadPriorityCurrentThread) {
   const bool bumping_priority_allowed = IsBumpingPriorityAllowed();
   if (bumping_priority_allowed) {
     // Bump the priority in order to verify that new threads are started with
diff --git a/components/startup_metric_utils/browser/startup_metric_utils.cc b/components/startup_metric_utils/browser/startup_metric_utils.cc
index 31890eb5..3ac80bd 100644
--- a/components/startup_metric_utils/browser/startup_metric_utils.cc
+++ b/components/startup_metric_utils/browser/startup_metric_utils.cc
@@ -271,7 +271,6 @@
 
 // platform_thread_mac.mm unfortunately doesn't properly support base's
 // thread priority APIs (crbug.com/554651).
-#if !defined(OS_MACOSX)
   static bool statics_initialized = false;
 
   base::ThreadPriority previous_priority = base::ThreadPriority::NORMAL;
@@ -280,18 +279,15 @@
     base::PlatformThread::SetCurrentThreadPriority(
         base::ThreadPriority::DISPLAY);
   }
-#endif
 
   static const base::Time time_base = base::Time::Now();
   static const base::TimeTicks trace_ticks_base = base::TimeTicks::Now();
 
-#if !defined(OS_MACOSX)
   if (!statics_initialized) {
     base::PlatformThread::SetCurrentThreadPriority(previous_priority);
   }
 
   statics_initialized = true;
-#endif
 
   // Then use the TimeDelta common ground between the two units to make the
   // conversion.