blob: 9f759ab27ee0ee2f0c3885003c145d3488d8e7ec [file] [log] [blame]
Honglin Yu0c4760a2020-04-18 20:53:31 +10001// Copyright 2020 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef ML_HANDWRITING_H_
6#define ML_HANDWRITING_H_
7
8#include <base/no_destructor.h>
9#include <base/optional.h>
10#include <base/scoped_native_library.h>
11#include <chromeos/libhandwriting/interface.h>
12
13#include "chrome/knowledge/handwriting/interface.pb.h"
14
15namespace ml {
16// A singleton proxy class for the handwriting DSO.
17// Usage:
18// auto* const hwr_library = HandwritingLibrary::GetInstance();
19// if (hwr_library->GetStatus() == HandwritingLibrary::kOk) {
20// // Do the real handwriting here.
21// recognizer = hwr_library->CreateHandwritingRecognizer();
22// ...
23// } else {
24// // Otherwise, use HandwritingLibrary::GetStatus() to get the error type.
25// // Maybe return "not installed".
26// ...
27// }
28class HandwritingLibrary {
29 public:
Honglin Yu0c4760a2020-04-18 20:53:31 +100030 enum class Status {
31 kOk = 0,
32 kUninitialized = 1,
33 kLoadLibraryFailed = 2,
charleszhao17777f92020-04-23 12:53:11 +100034 kFunctionLookupFailed = 3,
35 kNotSupported = 4,
Honglin Yu0c4760a2020-04-18 20:53:31 +100036 };
37
38 ~HandwritingLibrary() = default;
39
40 static HandwritingLibrary* GetInstance();
41
42 // Get whether the library is successfully initialized.
Andrew Moylan79b34a42020-07-08 11:13:11 +100043 // Initially, the status is `Status::kUninitialized` (this value should never
Honglin Yu0c4760a2020-04-18 20:53:31 +100044 // be returned).
Andrew Moylan79b34a42020-07-08 11:13:11 +100045 // If libhandwriting.so can not be loaded, return `kLoadLibraryFailed`. This
Honglin Yu0c4760a2020-04-18 20:53:31 +100046 // usually means on-device handwriting is not supported.
47 // If the functions can not be successfully looked up, return
Andrew Moylan79b34a42020-07-08 11:13:11 +100048 // `kFunctionLookupFailed`.
49 // Return `Status::kOk` if everything works fine.
Honglin Yu0c4760a2020-04-18 20:53:31 +100050 Status GetStatus() const;
51
52 // The following public member functions define the interface functions of
Andrew Moylan79b34a42020-07-08 11:13:11 +100053 // the libhandwriting.so library. Function `InitHandwritingRecognizerLibrary`
54 // and `DeleteHandwritingResultData` do not need interfaces because the client
Honglin Yu0c4760a2020-04-18 20:53:31 +100055 // won't call it.
56
57 // Creates and returns a handwriting recognizer which is needed for using the
58 // other interface. The memory is owned by the user and should be deleted
Andrew Moylan79b34a42020-07-08 11:13:11 +100059 // using `DestroyHandwritingRecognizer` after usage.
Honglin Yu0c4760a2020-04-18 20:53:31 +100060 HandwritingRecognizer CreateHandwritingRecognizer() const;
61 // Load the models and other configuration files with options.
Andrew Moylan79b34a42020-07-08 11:13:11 +100062 // `model_path` stores the paths to the data files of the model (machine
Honglin Yu0c4760a2020-04-18 20:53:31 +100063 // learning models, configurations etc.). Please see the unit test for
64 // examples.
65 // Returns true if HandwritingRecognizer is correctly loaded and
66 // initialized. Returns false otherwise.
67 bool LoadHandwritingRecognizer(
68 HandwritingRecognizer recognizer,
69 const chrome_knowledge::HandwritingRecognizerOptions& options,
70 const chrome_knowledge::HandwritingRecognizerModelPaths& model_path)
71 const;
Andrew Moylan79b34a42020-07-08 11:13:11 +100072 // Sends the specified `request` to `recognizer`, if succeeds, `result` (which
Honglin Yu0c4760a2020-04-18 20:53:31 +100073 // should not be null) is populated with the recognition result.
74 // Returns true if succeeds, otherwise returns false.
75 bool RecognizeHandwriting(
76 HandwritingRecognizer recognizer,
77 const chrome_knowledge::HandwritingRecognizerRequest& request,
78 chrome_knowledge::HandwritingRecognizerResult* result) const;
79 // Destroys the handwriting recognizer created by
Andrew Moylan79b34a42020-07-08 11:13:11 +100080 // `CreateHandwritingRecognizer`. Must be called if the handwriting recognizer
Honglin Yu0c4760a2020-04-18 20:53:31 +100081 // will not be used anymore, otherwise there will be memory leak.
82 void DestroyHandwritingRecognizer(HandwritingRecognizer recognizer) const;
83
84 private:
85 friend class base::NoDestructor<HandwritingLibrary>;
86
87 // Initialize the handwriting library.
88 HandwritingLibrary();
89
90 base::Optional<base::ScopedNativeLibrary> library_;
91 Status status_;
92
93 // Store the interface function pointers.
94 // TODO(honglinyu) as pointed out by cjmcdonald@, we should group the pointers
Andrew Moylan79b34a42020-07-08 11:13:11 +100095 // into a single `HandwritingInterface` struct and make it optional, i.e.,
Honglin Yu0c4760a2020-04-18 20:53:31 +100096 // declaring something like |base::Optional<HandwritingInterface> interface_|.
97 CreateHandwritingRecognizerFn create_handwriting_recognizer_;
98 LoadHandwritingRecognizerFn load_handwriting_recognizer_;
99 RecognizeHandwritingFn recognize_handwriting_;
100 DeleteHandwritingResultDataFn delete_handwriting_result_data_;
101 DestroyHandwritingRecognizerFn destroy_handwriting_recognizer_;
102
103 DISALLOW_COPY_AND_ASSIGN(HandwritingLibrary);
104};
105
106} // namespace ml
107
108#endif // ML_HANDWRITING_H_