Enable calculator rewriter as suggestion for mobile.

BUG=none
TEST=unittest
diff --git a/src/mozc_version_template.txt b/src/mozc_version_template.txt
index 7556748..44ba72d 100644
--- a/src/mozc_version_template.txt
+++ b/src/mozc_version_template.txt
@@ -1,6 +1,6 @@
 MAJOR=2
 MINOR=17
-BUILD=2080
+BUILD=2081
 REVISION=102
 # NACL_DICTIONARY_VERSION is the target version of the system dictionary to be
 # downloaded by NaCl Mozc.
diff --git a/src/rewriter/calculator/calculator.cc b/src/rewriter/calculator/calculator.cc
index d51347a..15f687c 100644
--- a/src/rewriter/calculator/calculator.cc
+++ b/src/rewriter/calculator/calculator.cc
@@ -111,6 +111,10 @@
 // TODO(tok): Add more number of operators.
 bool CalculatorImpl::CalculateString(const string &key, string *result) const {
   DCHECK(result);
+  if (key.empty()) {
+    LOG(ERROR) << "Key is empty.";
+    return false;
+  }
   string normalized_key;
   Util::FullWidthAsciiToHalfWidthAscii(key, &normalized_key);
 
diff --git a/src/rewriter/calculator_rewriter.cc b/src/rewriter/calculator_rewriter.cc
index 78cfd06..eec4896 100644
--- a/src/rewriter/calculator_rewriter.cc
+++ b/src/rewriter/calculator_rewriter.cc
@@ -40,6 +40,7 @@
 #include "converter/converter_interface.h"
 #include "converter/segments.h"
 #include "rewriter/calculator/calculator_interface.h"
+#include "session/commands.pb.h"
 
 namespace mozc {
 
@@ -51,6 +52,13 @@
 
 CalculatorRewriter::~CalculatorRewriter() {}
 
+int CalculatorRewriter::capability(const ConversionRequest &request) const {
+  if (request.request().mixed_conversion()) {
+    return RewriterInterface::ALL;
+  }
+  return RewriterInterface::CONVERSION;
+}
+
 // Rewrites candidates when conversion segments of |segments| represents an
 // expression that can be calculated. In such case, if |segments| consists
 // of multiple segments, it merges them by calling ConverterInterface::
@@ -75,6 +83,9 @@
   if (segments_size == 1) {
     const string &key = segments->conversion_segment(0).key();
     string result;
+    if (key.empty()) {
+      return false;
+    }
     if (!calculator->CalculateString(key, &result)) {
       return false;
     }
@@ -156,9 +167,8 @@
     candidate->content_key = base_candidate.content_key;
     candidate->attributes |= Segment::Candidate::NO_VARIANTS_EXPANSION;
     candidate->attributes |= Segment::Candidate::NO_LEARNING;
-    // description "[expression] の計算結果"
-    candidate->description = expression +
-        " \xE3\x81\xAE\xE8\xA8\x88\xE7\xAE\x97\xE7\xB5\x90\xE6\x9E\x9C";
+    // "計算結果"
+    candidate->description = "\xE8\xA8\x88\xE7\xAE\x97\xE7\xB5\x90\xE6\x9E\x9C";
 
     if (n == 0) {   // without expression
       candidate->value = value;
diff --git a/src/rewriter/calculator_rewriter.h b/src/rewriter/calculator_rewriter.h
index 9d0fb45..aa13151 100644
--- a/src/rewriter/calculator_rewriter.h
+++ b/src/rewriter/calculator_rewriter.h
@@ -49,6 +49,8 @@
   explicit CalculatorRewriter(const ConverterInterface *parent_converter);
   virtual ~CalculatorRewriter();
 
+  virtual int capability(const ConversionRequest &request) const;
+
   virtual bool Rewrite(const ConversionRequest &request,
                        Segments *segments) const;
 
diff --git a/src/rewriter/calculator_rewriter_test.cc b/src/rewriter/calculator_rewriter_test.cc
index 41233ea..a63e483 100644
--- a/src/rewriter/calculator_rewriter_test.cc
+++ b/src/rewriter/calculator_rewriter_test.cc
@@ -32,6 +32,7 @@
 #include <string>
 
 #include "base/logging.h"
+#include "base/scoped_ptr.h"
 #include "base/system_util.h"
 #include "config/config.pb.h"
 #include "config/config_handler.h"
@@ -43,6 +44,7 @@
 #include "engine/mock_data_engine_factory.h"
 #include "rewriter/calculator/calculator_interface.h"
 #include "rewriter/calculator/calculator_mock.h"
+#include "session/commands.pb.h"
 #include "testing/base/public/gunit.h"
 
 DECLARE_string(test_tmpdir);
@@ -68,13 +70,12 @@
   AddSegment(key, value, segments);
 }
 
-// "の計算結果"
-const char kPartOfCalculationDescription[] =
-    "\xE3\x81\xAE\xE8\xA8\x88\xE7\xAE\x97\xE7\xB5\x90\xE6\x9E\x9C";
+// "計算結果"
+const char kCalculationDescription[] =
+    "\xE8\xA8\x88\xE7\xAE\x97\xE7\xB5\x90\xE6\x9E\x9C";
 
 bool ContainsCalculatedResult(const Segment::Candidate &candidate) {
-  return candidate.description.find(kPartOfCalculationDescription) !=
-      string::npos;
+  return candidate.description.find(kCalculationDescription) != string::npos;
 }
 
 // If the segment has a candidate which was inserted by CalculatorRewriter,
@@ -83,14 +84,13 @@
   CHECK_EQ(segments.segments_size(), 1);
   for (size_t i = 0; i < segments.segment(0).candidates_size(); ++i) {
     const Segment::Candidate &candidate = segments.segment(0).candidate(i);
-    // Description includes "の計算結果"
     if (ContainsCalculatedResult(candidate)) {
       return i;
     }
   }
   return -1;
 }
-}  // anonymous namespace
+}  // namespace
 
 class CalculatorRewriterTest : public testing::Test {
  protected:
@@ -157,9 +157,8 @@
     EXPECT_EQ(candidate.content_value, "value");
     EXPECT_EQ(candidate.content_key, "key");
     EXPECT_NE(0, candidate.attributes & Segment::Candidate::NO_LEARNING);
-    // Description should be "key の計算結果"
-    EXPECT_EQ(candidate.description, "key " +
-              string(kPartOfCalculationDescription));
+    // Description should be "計算結果"
+    EXPECT_EQ(candidate.description, kCalculationDescription);
   }
 }
 
@@ -230,8 +229,7 @@
       "\xEF\xBC\x93\xEF\xBC\x8B\xEF\xBC\x96\xEF\xBC\xBE\xE2\x88\x92"
       "\xEF\xBC\x91\xEF\xBC\x8A\xEF\xBC\x99\xEF\xBC\x9D";
   // Expected description
-  const string description =
-      "5/(8/4)-7%3+6^-1*9= " + string(kPartOfCalculationDescription);
+  const string description = kCalculationDescription;
 
   // Pretend kExpression is calculated to "3"
   calculator_mock().SetCalculatePair(kExpression, "3", true);
@@ -286,4 +284,41 @@
     EXPECT_FALSE(calculator_rewriter->Rewrite(request, &segments));
   }
 }
+
+TEST_F(CalculatorRewriterTest, MobileEnvironmentTest) {
+  commands::Request input;
+  scoped_ptr<EngineInterface> engine_(MockDataEngineFactory::Create());
+  scoped_ptr<CalculatorRewriter> rewriter(
+      new CalculatorRewriter(engine_->GetConverter()));
+
+  {
+    input.set_mixed_conversion(true);
+    const ConversionRequest request(NULL, &input);
+    EXPECT_EQ(RewriterInterface::ALL, rewriter->capability(request));
+  }
+
+  {
+    input.set_mixed_conversion(false);
+    const ConversionRequest request(NULL, &input);
+    EXPECT_EQ(RewriterInterface::CONVERSION, rewriter->capability(request));
+  }
+}
+
+TEST_F(CalculatorRewriterTest, EmptyKeyTest) {
+  config::Config config;
+  config::ConfigHandler::GetDefaultConfig(&config);
+
+  const ConversionRequest request;
+  scoped_ptr<EngineInterface> engine_(MockDataEngineFactory::Create());
+  scoped_ptr<CalculatorRewriter> calculator_rewriter(
+      new CalculatorRewriter(engine_->GetConverter()));
+  {
+    Segments segments;
+    AddSegment("", "1", &segments);
+    config.set_use_calculator(true);
+    config::ConfigHandler::SetConfig(config);
+    EXPECT_FALSE(calculator_rewriter->Rewrite(request, &segments));
+  }
+}
+
 }  // namespace mozc