// 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/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_method_swizzle.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:));

  // 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).
  gOriginalInitIMP = ObjcEvilDoers::SwizzleImplementedInstanceMethods(
      [NSException class],
      @selector(initWithName:reason:userInfo:),
      @selector(crInitWithName:reason:userInfo:));
}

}  // 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();
    for (TabContentsIterator it; !it.done(); it.Next()) {
      if (content::WebContents* contents = *it)
        if (content::RenderViewHost* rvh = contents->GetRenderViewHost())
          rvh->EnableFullAccessibilityMode();
    }
  }
  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
