// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#import "chrome/browser/chrome_browser_application_mac.h"

#import "base/auto_reset.h"
#include "base/debug/crash_logging.h"
#include "base/debug/stack_trace.h"
#import "base/logging.h"
#import "base/mac/scoped_nsexception_enabler.h"
#import "base/mac/scoped_nsobject.h"
#import "base/mac/scoped_objc_class_swizzler.h"
#import "base/metrics/histogram.h"
#include "base/strings/stringprintf.h"
#import "base/strings/sys_string_conversions.h"
#import "chrome/browser/app_controller_mac.h"
#include "chrome/browser/ui/tab_contents/tab_contents_iterator.h"
#include "chrome/common/crash_keys.h"
#import "chrome/common/mac/objc_zombie.h"
#include "content/public/browser/browser_accessibility_state.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"

namespace {

// Tracking for cases being hit by -crInitWithName:reason:userInfo:.
enum ExceptionEventType {
  EXCEPTION_ACCESSIBILITY = 0,
  EXCEPTION_MENU_ITEM_BOUNDS_CHECK,
  EXCEPTION_VIEW_NOT_IN_WINDOW,
  EXCEPTION_NSURL_INIT_NIL,
  EXCEPTION_NSDATADETECTOR_NIL_STRING,

  // Always keep this at the end.
  EXCEPTION_MAX,
};

void RecordExceptionEvent(ExceptionEventType event_type) {
  UMA_HISTOGRAM_ENUMERATION("OSX.ExceptionHandlerEvents",
                            event_type, EXCEPTION_MAX);
}

}  // namespace

// The implementation of NSExceptions break various assumptions in the
// Chrome code.  This category defines a replacement for
// -initWithName:reason:userInfo: for purposes of forcing a break in
// the debugger when an exception is raised.  -raise sounds more
// obvious to intercept, but it doesn't catch the original throw
// because the objc runtime doesn't use it.
@interface NSException (CrNSExceptionSwizzle)
- (id)crInitWithName:(NSString*)aName
              reason:(NSString*)aReason
            userInfo:(NSDictionary*)someUserInfo;
@end

static IMP gOriginalInitIMP = NULL;

@implementation NSException (CrNSExceptionSwizzle)
- (id)crInitWithName:(NSString*)aName
              reason:(NSString*)aReason
            userInfo:(NSDictionary*)someUserInfo {
  // Method only called when swizzled.
  DCHECK(_cmd == @selector(initWithName:reason:userInfo:));
  DCHECK(gOriginalInitIMP);

  // Parts of Cocoa rely on creating and throwing exceptions. These are not
  // worth bugging-out over. It is very important that there be zero chance that
  // any Chromium code is on the stack; these must be created by Apple code and
  // then immediately consumed by Apple code.
  static NSString* const kAcceptableNSExceptionNames[] = {
    // If an object does not support an accessibility attribute, this will
    // get thrown.
    NSAccessibilityException,
  };

  BOOL found = NO;
  for (size_t i = 0; i < arraysize(kAcceptableNSExceptionNames); ++i) {
    if (aName == kAcceptableNSExceptionNames[i]) {
      found = YES;
      RecordExceptionEvent(EXCEPTION_ACCESSIBILITY);
      break;
    }
  }

  if (!found) {
    // Update breakpad with the exception info.
    std::string value = base::StringPrintf("%s reason %s",
        [aName UTF8String], [aReason UTF8String]);
    base::debug::SetCrashKeyValue(crash_keys::mac::kNSException, value);
    base::debug::SetCrashKeyToStackTrace(crash_keys::mac::kNSExceptionTrace,
                                         base::debug::StackTrace());

    // Force crash for selected exceptions to generate crash dumps.
    BOOL fatal = NO;
    if (aName == NSInternalInconsistencyException) {
      NSString* const kNSMenuItemArrayBoundsCheck =
          @"Invalid parameter not satisfying: (index >= 0) && "
          @"(index < [_itemArray count])";
      if ([aReason isEqualToString:kNSMenuItemArrayBoundsCheck]) {
        RecordExceptionEvent(EXCEPTION_MENU_ITEM_BOUNDS_CHECK);
        fatal = YES;
      }

      NSString* const kNoWindowCheck = @"View is not in any window";
      if ([aReason isEqualToString:kNoWindowCheck]) {
        RecordExceptionEvent(EXCEPTION_VIEW_NOT_IN_WINDOW);
        fatal = YES;
      }
    }

    // Mostly "unrecognized selector sent to (instance|class)".  A
    // very small number of things like inappropriate nil being passed.
    if (aName == NSInvalidArgumentException) {
      fatal = YES;

      // TODO(shess): http://crbug.com/85463 throws this exception
      // from ImageKit.  Our code is not on the stack, so it needs to
      // be whitelisted for now.
      NSString* const kNSURLInitNilCheck =
          @"*** -[NSURL initFileURLWithPath:isDirectory:]: "
          @"nil string parameter";
      if ([aReason isEqualToString:kNSURLInitNilCheck]) {
        RecordExceptionEvent(EXCEPTION_NSURL_INIT_NIL);
        fatal = NO;
      }

      // TODO(shess): <http://crbug.com/316759> OSX 10.9 is failing
      // trying to extract structure from a string.
      NSString* const kNSDataDetectorNilCheck =
          @"*** -[NSDataDetector enumerateMatchesInString:"
          @"options:range:usingBlock:]: nil argument";
      if ([aReason isEqualToString:kNSDataDetectorNilCheck]) {
        RecordExceptionEvent(EXCEPTION_NSDATADETECTOR_NIL_STRING);
        fatal = NO;
      }
    }

    // Dear reader: Something you just did provoked an NSException.
    // NSException is implemented in terms of setjmp()/longjmp(),
    // which does poor things when combined with C++ scoping
    // (destructors are skipped).  Chrome should be NSException-free,
    // please check your backtrace and see if you can't file a bug
    // with a repro case.
    const bool allow = base::mac::GetNSExceptionsAllowed();
    if (fatal && !allow) {
      LOG(FATAL) << "Someone is trying to raise an exception!  "
                 << value;
    } else {
      // Make sure that developers see when their code throws
      // exceptions.
      DCHECK(allow) << "Someone is trying to raise an exception!  "
                    << value;
    }
  }

  // Forward to the original version.
  return gOriginalInitIMP(self, _cmd, aName, aReason, someUserInfo);
}
@end

namespace chrome_browser_application_mac {

// Maximum number of known named exceptions we'll support.  There is
// no central registration, but I only find about 75 possibilities in
// the system frameworks, and many of them are probably not
// interesting to track in aggregate (those relating to distributed
// objects, for instance).
const size_t kKnownNSExceptionCount = 25;

const size_t kUnknownNSException = kKnownNSExceptionCount;

size_t BinForException(NSException* exception) {
  // A list of common known exceptions.  The list position will
  // determine where they live in the histogram, so never move them
  // around, only add to the end.
  static NSString* const kKnownNSExceptionNames[] = {
    // Grab-bag exception, not very common.  CFArray (or other
    // container) mutated while being enumerated is one case seen in
    // production.
    NSGenericException,

    // Out-of-range on NSString or NSArray.  Quite common.
    NSRangeException,

    // Invalid arg to method, unrecognized selector.  Quite common.
    NSInvalidArgumentException,

    // malloc() returned null in object creation, I think.  Turns out
    // to be very uncommon in production, because of the OOM killer.
    NSMallocException,

    // This contains things like windowserver errors, trying to draw
    // views which aren't in windows, unable to read nib files.  By
    // far the most common exception seen on the crash server.
    NSInternalInconsistencyException,

    nil
  };

  // Make sure our array hasn't outgrown our abilities to track it.
  DCHECK_LE(arraysize(kKnownNSExceptionNames), kKnownNSExceptionCount);

  NSString* name = [exception name];
  for (int i = 0; kKnownNSExceptionNames[i]; ++i) {
    if (name == kKnownNSExceptionNames[i]) {
      return i;
    }
  }
  return kUnknownNSException;
}

void RecordExceptionWithUma(NSException* exception) {
  UMA_HISTOGRAM_ENUMERATION("OSX.NSException",
      BinForException(exception), kUnknownNSException);
}

void RegisterBrowserCrApp() {
  [BrowserCrApplication sharedApplication];
};

void Terminate() {
  [NSApp terminate:nil];
}

void CancelTerminate() {
  [NSApp cancelTerminate:nil];
}

}  // namespace chrome_browser_application_mac

namespace {

void SwizzleInit() {
  // Do-nothing wrapper so that we can arrange to only swizzle
  // -[NSException raise] when DCHECK() is turned on (as opposed to
  // replicating the preprocess logic which turns DCHECK() on).
  CR_DEFINE_STATIC_LOCAL(base::mac::ScopedObjCClassSwizzler,
                         swizzle_exception,
                         ([NSException class],
                          @selector(initWithName:reason:userInfo:),
                          @selector(crInitWithName:reason:userInfo:)));
  gOriginalInitIMP = swizzle_exception.GetOriginalImplementation();
}

}  // namespace

// These methods are being exposed for the purposes of overriding.
// Used to determine when a Panel window can become the key window.
@interface NSApplication (PanelsCanBecomeKey)
- (void)_cycleWindowsReversed:(BOOL)arg1;
- (id)_removeWindow:(NSWindow*)window;
- (id)_setKeyWindow:(NSWindow*)window;
@end

@interface BrowserCrApplication (PrivateInternal)

// This must be called under the protection of previousKeyWindowsLock_.
- (void)removePreviousKeyWindow:(NSWindow*)window;

@end

@implementation BrowserCrApplication

+ (void)initialize {
  // Turn all deallocated Objective-C objects into zombies, keeping
  // the most recent 10,000 of them on the treadmill.
  ObjcEvilDoers::ZombieEnable(true, 10000);
}

- (id)init {
  SwizzleInit();
  self = [super init];

  // Sanity check to alert if overridden methods are not supported.
  DCHECK([NSApplication
      instancesRespondToSelector:@selector(_cycleWindowsReversed:)]);
  DCHECK([NSApplication
      instancesRespondToSelector:@selector(_removeWindow:)]);
  DCHECK([NSApplication
      instancesRespondToSelector:@selector(_setKeyWindow:)]);

  return self;
}

// Initialize NSApplication using the custom subclass.  Check whether NSApp
// was already initialized using another class, because that would break
// some things.
+ (NSApplication*)sharedApplication {
  NSApplication* app = [super sharedApplication];

  // +sharedApplication initializes the global NSApp, so if a specific
  // NSApplication subclass is requested, require that to be the one
  // delivered.  The practical effect is to require a consistent NSApp
  // across the executable.
  CHECK([NSApp isKindOfClass:self])
      << "NSApp must be of type " << [[self className] UTF8String]
      << ", not " << [[NSApp className] UTF8String];

  // If the message loop was initialized before NSApp is setup, the
  // message pump will be setup incorrectly.  Failing this implies
  // that RegisterBrowserCrApp() should be called earlier.
  CHECK(base::MessagePumpMac::UsingCrApp())
      << "MessagePumpMac::Create() is using the wrong pump implementation"
      << " for " << [[self className] UTF8String];

  return app;
}

////////////////////////////////////////////////////////////////////////////////
// HISTORICAL COMMENT (by viettrungluu, from
// http://codereview.chromium.org/1520006 with mild editing):
//
// A quick summary of the state of things (before the changes to shutdown):
//
// Currently, we are totally hosed (put in a bad state in which Cmd-W does the
// wrong thing, and which will probably eventually lead to a crash) if we begin
// quitting but termination is aborted for some reason.
//
// I currently know of two ways in which termination can be aborted:
// (1) Common case: a window has an onbeforeunload handler which pops up a
//     "leave web page" dialog, and the user answers "no, don't leave".
// (2) Uncommon case: popups are enabled (in Content Settings, i.e., the popup
//     blocker is disabled), and some nasty web page pops up a new window on
//     closure.
//
// I don't know of other ways in which termination can be aborted, but they may
// exist (or may be added in the future, for that matter).
//
// My CL [see above] does the following:
// a. Should prevent being put in a bad state (which breaks Cmd-W and leads to
//    crash) under all circumstances.
// b. Should completely handle (1) properly.
// c. Doesn't (yet) handle (2) properly and puts it in a weird state (but not
//    that bad).
// d. Any other ways of aborting termination would put it in that weird state.
//
// c. can be fixed by having the global flag reset on browser creation or
// similar (and doing so might also fix some possible d.'s as well). I haven't
// done this yet since I haven't thought about it carefully and since it's a
// corner case.
//
// The weird state: a state in which closing the last window quits the browser.
// This might be a bit annoying, but it's not dangerous in any way.
////////////////////////////////////////////////////////////////////////////////

// |-terminate:| is the entry point for orderly "quit" operations in Cocoa. This
// includes the application menu's quit menu item and keyboard equivalent, the
// application's dock icon menu's quit menu item, "quit" (not "force quit") in
// the Activity Monitor, and quits triggered by user logout and system restart
// and shutdown.
//
// The default |-terminate:| implementation ends the process by calling exit(),
// and thus never leaves the main run loop. This is unsuitable for Chrome since
// Chrome depends on leaving the main run loop to perform an orderly shutdown.
// We support the normal |-terminate:| interface by overriding the default
// implementation. Our implementation, which is very specific to the needs of
// Chrome, works by asking the application delegate to terminate using its
// |-tryToTerminateApplication:| method.
//
// |-tryToTerminateApplication:| differs from the standard
// |-applicationShouldTerminate:| in that no special event loop is run in the
// case that immediate termination is not possible (e.g., if dialog boxes
// allowing the user to cancel have to be shown). Instead, this method sets a
// flag and tries to close all browsers. This flag causes the closure of the
// final browser window to begin actual tear-down of the application.
// Termination is cancelled by resetting this flag. The standard
// |-applicationShouldTerminate:| is not supported, and code paths leading to it
// must be redirected.
//
// When the last browser has been destroyed, the BrowserList calls
// chrome::OnAppExiting(), which is the point of no return. That will cause
// the NSApplicationWillTerminateNotification to be posted, which ends the
// NSApplication event loop, so final post- MessageLoop::Run() work is done
// before exiting.
- (void)terminate:(id)sender {
  AppController* appController = static_cast<AppController*>([NSApp delegate]);
  [appController tryToTerminateApplication:self];
  // Return, don't exit. The application is responsible for exiting on its own.
}

- (void)cancelTerminate:(id)sender {
  AppController* appController = static_cast<AppController*>([NSApp delegate]);
  [appController stopTryingToTerminateApplication:self];
}

- (BOOL)sendAction:(SEL)anAction to:(id)aTarget from:(id)sender {
  // The Dock menu contains an automagic section where you can select
  // amongst open windows.  If a window is closed via JavaScript while
  // the menu is up, the menu item for that window continues to exist.
  // When a window is selected this method is called with the
  // now-freed window as |aTarget|.  Short-circuit the call if
  // |aTarget| is not a valid window.
  if (anAction == @selector(_selectWindow:)) {
    // Not using -[NSArray containsObject:] because |aTarget| may be a
    // freed object.
    BOOL found = NO;
    for (NSWindow* window in [self windows]) {
      if (window == aTarget) {
        found = YES;
        break;
      }
    }
    if (!found) {
      return NO;
    }
  }

  // When a Cocoa control is wired to a freed object, we get crashers
  // in the call to |super| with no useful information in the
  // backtrace.  Attempt to add some useful information.

  // If the action is something generic like -commandDispatch:, then
  // the tag is essential.
  NSInteger tag = 0;
  if ([sender isKindOfClass:[NSControl class]]) {
    tag = [sender tag];
    if (tag == 0 || tag == -1) {
      tag = [sender selectedTag];
    }
  } else if ([sender isKindOfClass:[NSMenuItem class]]) {
    tag = [sender tag];
  }

  NSString* actionString = NSStringFromSelector(anAction);
  std::string value = base::StringPrintf("%s tag %ld sending %s to %p",
      [[sender className] UTF8String],
      static_cast<long>(tag),
      [actionString UTF8String],
      aTarget);

  base::debug::ScopedCrashKey key(crash_keys::mac::kSendAction, value);

  // Certain third-party code, such as print drivers, can still throw
  // exceptions and Chromium cannot fix them.  This provides a way to
  // work around those on a spot basis.
  bool enableNSExceptions = false;

  // http://crbug.com/80686 , an Epson printer driver.
  if (anAction == @selector(selectPDE:)) {
    enableNSExceptions = true;
  }

  // Minimize the window by keeping this close to the super call.
  scoped_ptr<base::mac::ScopedNSExceptionEnabler> enabler;
  if (enableNSExceptions)
    enabler.reset(new base::mac::ScopedNSExceptionEnabler());
  return [super sendAction:anAction to:aTarget from:sender];
}

- (BOOL)isHandlingSendEvent {
  return handlingSendEvent_;
}

- (void)setHandlingSendEvent:(BOOL)handlingSendEvent {
  handlingSendEvent_ = handlingSendEvent;
}

- (void)sendEvent:(NSEvent*)event {
  base::mac::ScopedSendingEvent sendingEventScoper;
  [super sendEvent:event];
}

// NSExceptions which are caught by the event loop are logged here.
// NSException uses setjmp/longjmp, which can be very bad for C++, so
// we attempt to track and report them.
- (void)reportException:(NSException *)anException {
  // If we throw an exception in this code, we can create an infinite
  // loop.  If we throw out of the if() without resetting
  // |reportException|, we'll stop reporting exceptions for this run.
  static BOOL reportingException = NO;
  DCHECK(!reportingException);
  if (!reportingException) {
    reportingException = YES;
    chrome_browser_application_mac::RecordExceptionWithUma(anException);

    // http://crbug.com/45928 is a bug about needing to double-close
    // windows sometimes.  One theory is that |-isHandlingSendEvent|
    // gets latched to always return |YES|.  Since scopers are used to
    // manipulate that value, that should not be possible.  One way to
    // sidestep scopers is setjmp/longjmp (see above).  The following
    // is to "fix" this while the more fundamental concern is
    // addressed elsewhere.
    [self setHandlingSendEvent:NO];

    // If |ScopedNSExceptionEnabler| is used to allow exceptions, and an
    // uncaught exception is thrown, it will throw past all of the scopers.
    // Reset the flag so that future exceptions are not masked.
    base::mac::SetNSExceptionsAllowed(false);

    // Store some human-readable information in breakpad keys in case
    // there is a crash.  Since breakpad does not provide infinite
    // storage, we track two exceptions.  The first exception thrown
    // is tracked because it may be the one which caused the system to
    // go off the rails.  The last exception thrown is tracked because
    // it may be the one most directly associated with the crash.
    static BOOL trackedFirstException = NO;

    const char* const kExceptionKey =
        trackedFirstException ? crash_keys::mac::kLastNSException
                              : crash_keys::mac::kFirstNSException;
    NSString* value = [NSString stringWithFormat:@"%@ reason %@",
                                [anException name], [anException reason]];
    base::debug::SetCrashKeyValue(kExceptionKey, [value UTF8String]);

    // Encode the callstack from point of throw.
    // TODO(shess): Our swizzle plus the 23-frame limit plus Cocoa
    // overhead may make this less than useful.  If so, perhaps skip
    // some items and/or use two keys.
    const char* const kExceptionBtKey =
        trackedFirstException ? crash_keys::mac::kLastNSExceptionTrace
                              : crash_keys::mac::kFirstNSExceptionTrace;
    NSArray* addressArray = [anException callStackReturnAddresses];
    NSUInteger addressCount = [addressArray count];
    if (addressCount) {
      // SetCrashKeyFromAddresses() only encodes 23, so that's a natural limit.
      const NSUInteger kAddressCountMax = 23;
      void* addresses[kAddressCountMax];
      if (addressCount > kAddressCountMax)
        addressCount = kAddressCountMax;

      for (NSUInteger i = 0; i < addressCount; ++i) {
        addresses[i] = reinterpret_cast<void*>(
            [[addressArray objectAtIndex:i] unsignedIntegerValue]);
      }
      base::debug::SetCrashKeyFromAddresses(
          kExceptionBtKey, addresses, static_cast<size_t>(addressCount));
    } else {
      base::debug::ClearCrashKey(kExceptionBtKey);
    }
    trackedFirstException = YES;

    reportingException = NO;
  }

  [super reportException:anException];
}

- (void)accessibilitySetValue:(id)value forAttribute:(NSString*)attribute {
  if ([attribute isEqualToString:@"AXEnhancedUserInterface"] &&
      [value intValue] == 1) {
    content::BrowserAccessibilityState::GetInstance()->OnScreenReaderDetected();
  }
  return [super accessibilitySetValue:value forAttribute:attribute];
}

- (void)_cycleWindowsReversed:(BOOL)arg1 {
  base::AutoReset<BOOL> pin(&cyclingWindows_, YES);
  [super _cycleWindowsReversed:arg1];
}

- (BOOL)isCyclingWindows {
  return cyclingWindows_;
}

- (id)_removeWindow:(NSWindow*)window {
  {
    base::AutoLock lock(previousKeyWindowsLock_);
    [self removePreviousKeyWindow:window];
  }
  id result = [super _removeWindow:window];

  // Ensure app has a key window after a window is removed.
  // OS wants to make a panel browser window key after closing an app window
  // because panels use a higher priority window level, but panel windows may
  // refuse to become key, leaving the app with no key window. The OS does
  // not seem to consider other windows after the first window chosen refuses
  // to become key. Force consideration of other windows here.
  if ([self isActive] && [self keyWindow] == nil) {
    NSWindow* key =
        [self makeWindowsPerform:@selector(canBecomeKeyWindow) inOrder:YES];
    [key makeKeyWindow];
  }

  // Return result from the super class. It appears to be the app that
  // owns the removed window (determined via experimentation).
  return result;
}

- (id)_setKeyWindow:(NSWindow*)window {
  // |window| is nil when the current key window is being closed.
  // A separate call follows with a new value when a new key window is set.
  // Closed windows are not tracked in previousKeyWindows_.
  if (window != nil) {
    base::AutoLock lock(previousKeyWindowsLock_);
    [self removePreviousKeyWindow:window];
    NSWindow* currentKeyWindow = [self keyWindow];
    if (currentKeyWindow != nil && currentKeyWindow != window)
      previousKeyWindows_.push_back(currentKeyWindow);
  }

  return [super _setKeyWindow:window];
}

- (NSWindow*)previousKeyWindow {
  base::AutoLock lock(previousKeyWindowsLock_);
  return previousKeyWindows_.empty() ? nil : previousKeyWindows_.back();
}

- (void)removePreviousKeyWindow:(NSWindow*)window {
  previousKeyWindowsLock_.AssertAcquired();
  std::vector<NSWindow*>::iterator window_iterator =
      std::find(previousKeyWindows_.begin(),
                previousKeyWindows_.end(),
                window);
  if (window_iterator != previousKeyWindows_.end()) {
    previousKeyWindows_.erase(window_iterator);
  }
}

@end
