-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathhandwriting.h
146 lines (124 loc) · 5.82 KB
/
handwriting.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// Copyright 2020 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ML_HANDWRITING_H_
#define ML_HANDWRITING_H_
#include <string>
#include <base/no_destructor.h>
#include <base/optional.h>
#include <base/scoped_native_library.h>
#include <chromeos/libhandwriting/handwriting_interface.h>
#include "chrome/knowledge/handwriting/handwriting_interface.pb.h"
#include "ml/mojom/handwriting_recognizer.mojom.h"
#include "ml/util.h"
namespace ml {
// A singleton proxy class for the handwriting DSO.
// Usage:
// auto* const hwr_library = HandwritingLibrary::GetInstance();
// if (hwr_library->GetStatus() == HandwritingLibrary::kOk) {
// // Do the real handwriting here.
// recognizer = hwr_library->CreateHandwritingRecognizer();
// ...
// } else {
// // Otherwise, use HandwritingLibrary::GetStatus() to get the error type.
// // Maybe return "not installed".
// ...
// }
class HandwritingLibrary {
public:
enum class Status {
kOk = 0,
kUninitialized = 1,
kLoadLibraryFailed = 2,
kFunctionLookupFailed = 3,
kNotSupported = 4,
};
// Default handwriting model directory on rootfs.
static constexpr char kHandwritingDefaultModelDir[] =
"/opt/google/chrome/ml_models/handwriting";
~HandwritingLibrary() = default;
// Returns whether HandwritingLibrary is supported.
static constexpr bool IsHandwritingLibrarySupported() {
return (IsUseLibHandwritingEnabled() || IsUseLibHandwritingDlcEnabled()) &&
!IsAsan();
}
// Returns whether HandwritingLibrary is supported for unit tests.
static constexpr bool IsHandwritingLibraryUnitTestSupported() {
return IsUseLibHandwritingEnabled() && !IsAsan();
}
// Returns bool of use.ondevice_handwriting.
static constexpr bool IsUseLibHandwritingEnabled() {
return USE_ONDEVICE_HANDWRITING;
}
// Returns bool of use.ondevice_handwriting_dlc.
static constexpr bool IsUseLibHandwritingDlcEnabled() {
return USE_ONDEVICE_HANDWRITING_DLC;
}
// Gets the singleton HandwritingLibrary. The singleton is initialized with
// `model_path` on the first call to GetInstance; for the rest of the calls,
// the `model_path` is ignored, and the existing singleton is returned.
// The `model_path` should be either a path on rootfs or a path returned by
// DlcService.
static HandwritingLibrary* GetInstance(
const std::string& model_path = kHandwritingDefaultModelDir);
// Get whether the library is successfully initialized.
// Initially, the status is `Status::kUninitialized` (this value should never
// be returned).
// If libhandwriting.so can not be loaded, return `kLoadLibraryFailed`. This
// usually means on-device handwriting is not supported.
// If the functions can not be successfully looked up, return
// `kFunctionLookupFailed`.
// Return `Status::kOk` if everything works fine.
Status GetStatus() const;
// The following public member functions define the interface functions of
// the libhandwriting.so library. Function `InitHandwritingRecognizerLibrary`
// and `DeleteHandwritingResultData` do not need interfaces because the client
// won't call it.
// Creates and returns a handwriting recognizer which is needed for using the
// other interface. The memory is owned by the user and should be deleted
// using `DestroyHandwritingRecognizer` after usage.
HandwritingRecognizer CreateHandwritingRecognizer() const;
// Load the models with `spec` stores the language, the path to the data files
// of the model (machine learning models, configurations etc.).
// Returns true if HandwritingRecognizer is correctly loaded and
// initialized. Returns false otherwise.
bool LoadHandwritingRecognizer(
HandwritingRecognizer recognizer,
chromeos::machine_learning::mojom::HandwritingRecognizerSpecPtr spec)
const;
// Sends the specified `request` to `recognizer`, if succeeds, `result` (which
// should not be null) is populated with the recognition result.
// Returns true if succeeds, otherwise returns false.
bool RecognizeHandwriting(
HandwritingRecognizer recognizer,
const chrome_knowledge::HandwritingRecognizerRequest& request,
chrome_knowledge::HandwritingRecognizerResult* result) const;
// Destroys the handwriting recognizer created by
// `CreateHandwritingRecognizer`. Must be called if the handwriting recognizer
// will not be used anymore, otherwise there will be memory leak.
void DestroyHandwritingRecognizer(HandwritingRecognizer recognizer) const;
private:
friend class base::NoDestructor<HandwritingLibrary>;
FRIEND_TEST(HandwritingLibraryTest, CanLoadLibrary);
// Initialize the handwriting library.
explicit HandwritingLibrary(const std::string& root_path);
HandwritingLibrary(const HandwritingLibrary&) = delete;
HandwritingLibrary& operator=(const HandwritingLibrary&) = delete;
// Currently HandwritingLibrary is supported only when the "sanitizer" is not
// enabled (see https://crbug.com/1082632).
static constexpr bool IsAsan() { return __has_feature(address_sanitizer); }
base::Optional<base::ScopedNativeLibrary> library_;
Status status_;
const base::FilePath model_path_;
// Store the interface function pointers.
// TODO(honglinyu) as pointed out by cjmcdonald@, we should group the pointers
// into a single `HandwritingInterface` struct and make it optional, i.e.,
// declaring something like |base::Optional<HandwritingInterface> interface_|.
CreateHandwritingRecognizerFn create_handwriting_recognizer_;
LoadHandwritingRecognizerFn load_handwriting_recognizer_;
RecognizeHandwritingFn recognize_handwriting_;
DeleteHandwritingResultDataFn delete_handwriting_result_data_;
DestroyHandwritingRecognizerFn destroy_handwriting_recognizer_;
};
} // namespace ml
#endif // ML_HANDWRITING_H_