fix(ans): fix cross-SO singleton issue by adding AnsNotification::GetInstance()
Created-by: cheerful_ricky
Commit-by: CheerfulRicky
Merged-by: openharmony_ci
Description: ## Problem
`DelayedSingleton<AnsNotification>::GetInstance()` returns different singleton objects in different shared libraries because the template's static members (`instance_`, `mutex_`) have vague linkage (COMDAT) and are hidden per-SO by `-fvisibility=hidden` + version scripts.
## Solution
1. **Add `AnsNotification::GetInstance()`** using function-local static (C++11 thread-safe, defined out-of-line in `ans_notification.cpp` within `libans_innerkits`, symbol exported via `*Ans*` in `.map`)
2. **Replace ALL callers** (NAPI/ANI/Tools/Tests/CJ FFI) from `DelayedSingleton<AnsNotification>::GetInstance()` to `AnsNotification::GetInstance()`
3. **Clean up** `#include singleton.h` from files that no longer use `DelayedSingleton` (kept in `ans_manager_death_recipient.h` and `pixelmap_cache_manager.h` which still use `DelayedSingleton` as base class)
## Why it works
The function-local static in `ans_notification.cpp` lives in `libans_innerkits.so`'s data segment. `AnsNotification::GetInstance()` is a non-inline member function compiled only in `libans_innerkits.so` and exported via `*Ans*` pattern in `libans_innerkits.map`. All SOs call this exported function through dynamic linking, sharing the single instance.
## Verification
Syntax-checked key files with exact ninja build flags: `ans_notification.cpp`, `notification_helper.cpp`, `ans_manager_death_recipient.cpp`, `napi_cancel.cpp`, `ani_cance.cpp`, `notification_manager_impl.cpp` (CJ FFI), `notification_shell_command.cpp` (Tools) — all passed.
Co-Authored-By: Agent
See merge request: openharmony/notification_distributed_notification_service!4960
DelayedSingleton<AnsNotification>::GetInstance() returns different
singleton objects in different shared libraries because the template's
static members (instance_, mutex_) have vague linkage (COMDAT) and are
hidden per-SO by -fvisibility=hidden + version scripts.
Solution:
1. Add AnsNotification::GetInstance() using function-local static
(C++11 thread-safe, defined out-of-line in ans_notification.cpp
within libans_innerkits, symbol exported via *Ans* in .map)
2. Replace ALL callers (NAPI/ANI/Tools/Tests/CJ FFI) from
DelayedSingleton<AnsNotification>::GetInstance() to
AnsNotification::GetInstance()
3. Fix singleton.h include hygiene:
- Add #include singleton.h to 34 files that use Singleton<>,
DelayedSingleton<>, DECLARE_SINGLETON etc. but relied on
transitive includes
- Add #include nocopyable.h to 7 files that use
DISALLOW_COPY_AND_MOVE but relied on transitive includes
- Remove #include singleton.h from 70 files that no longer use
any singleton.h symbols after the DelayedSingleton replacement
The function-local static in ans_notification.cpp lives in
libans_innerkits.so's data segment. AnsNotification::GetInstance() is
a non-inline member function compiled only in libans_innerkits.so and
exported via *Ans* pattern in libans_innerkits.map. All SOs call this
exported function through dynamic linking, sharing the single instance.
Co-Authored-By: Agent
Signed-off-by: CheerfulRicky <yuegang7@h-partners.com>
Change-Id: I1089cfa5bb010daf37c68333a1e71c55fc1f16f3
Add comprehensive null pointer validation across frameworks and services
layers (notification_request, subscriber_image_util, napi converters,
geofence service, live view service, preferences, subscriber manager, etc.)
to prevent null-dereference crashes, and add unit tests covering the new
null-check branches.
Co-Authored-By: Agent
Signed-off-by: stepend98 <yangjun273@huawei.com>
Change-Id: I62f9e3a450dbdbbcf7b0657c7187c6f7709b01df
Check return values of napi_create_async_work and napi_queue_async_work_with_qos, properly clean up callback references, async work objects and asynccallbackinfo on failure paths. Use unique_ptr for exception safety in FromJson, fix null deref in ANI CheckCompleteEnvironment, dlclose handle in ExtensionWrapper destructor, and destroy timers in ExtensionServiceConnection destructor.
Co-Authored-By: Agent
Signed-off-by: stepend98 <yangjun273@huawei.com>
Change-Id: I9f681bba5677db209f6f3691d19f78623699dbb3
Critical fix: libnotification_subscriber_extension_ani.map exported
ANI_Constructor (non-existent) instead of
OHOS_STS_NotificationSubscriberExtension_Creation which is the dlsym
symbol expected by NotificationSubscriberExtensionModuleLoader. Added
the missing extern "C" factory function in sts_notification_subscriber_extension.cpp.
Other fixes:
- Remove dead napi_module exports from NAPI module maps (the actual
variable is _module; registration works via __attribute__((constructor)))
- Add vtable/typeinfo/VTT export patterns to module .so maps for CFI
cross-dso virtual call safety on IPC callback classes
- Clean up redundant patterns in common library maps (*Common*,
*NotificationManagerSts*, *NotificationSubScribeSts*, *ReminderAgentNapi*)
- Remove orphaned libnotification_subscriber_extension.map (not referenced
in BUILD.gn)
Co-Authored-By: Agent
Signed-off-by: CheerfulRicky <yuegang7@h-partners.com>
Change-Id: I6ba01c5568862e5827d56efe5cbacfd593069c50
- Fix NAPI memory leaks by deleting callback references on error paths
- Add null pointer checks for context and bundle option objects
- Add bounds validation for Parcel vector sizes against MAX_PARCELABLE_VECTOR_NUM
- Add is_discarded() checks before JSON parse result usage
- Fix uninitialized member variables in constructors
- Fix timer id type from int32_t to uint64_t
- Fix log format placeholder and return empty string instead of nullptr
Co-Authored-By: Agent
Signed-off-by: stepend98 <yangjun273@huawei.com>
Change-Id: I980acf6c5aaed0e4ee31de14f246d95fae2d2c65
Phase 1 of ROM size optimization (target: 30% reduction, baseline 7963KB).
All changes are limited to BUILD.gn/.gni/.map files, no .cpp/.h modifications.
Key changes:
- Add notification_size_opt_cflags/ldflags public variables in notification.gni
- Add -fno-rtti/-flto/-Bsymbolic/-fno-exceptions config to all production targets
- Extract ANI sts_*.cpp (21 files) to ohos_shared_library notification_ani_common
- Extract NAPI common*.cpp (12 files) to ohos_shared_library notification_napi_common
- Tighten libans_innerkits.map from global:* to class-name-based export
- Add version_script to 6 NAPI .so (export only napi_module)
- Add version_script to 4 ANI .so (export only ANI_Constructor)
- Feature-gate priority_notification/clone/geofence source files
- Add distributed_notification_service_feature_clone flag
Expected benefit: 500-1100KB reduction.
Co-Authored-By: Agent
Signed-off-by: CheerfulRicky <yuegang7@h-partners.com>
Change-Id: I029559a06708665662b1d2f9b7f66dcae53ee96f
Signed-off-by: CheerfulRicky <yuegang7@h-partners.com>
1. Empty DB query result now returns an empty Map instead of null in the
NAPI callback; DB query failure still reports an error. The service/DB
layers already distinguished empty (ERR_OK) from failure; this fixes
the NAPI layer that overwrote the empty Map with null, which violated
the declared Promise<Map<BundleOption, boolean>> return type.
2. BundleOption.uid is optional; when not filled (uid<=0), the batch path
now resolves the uid via GenerateValidBundleOption (same as the single
path) before querying the DB, so the correct slot key and userId are
used. Unresolvable bundles are skipped and ERR_OK with partial results
is returned.
Add unit tests for uid-not-filled skip and partial-result scenarios.
Co-Authored-By: Agent
Signed-off-by: CheerfulRicky <yuegang7@h-partners.com>
Change-Id: I305f17443ebfa38eb6ead89ecbe9e42622e0da08
Add isNotificationSlotEnabledByBundles batch slot query API to query
multiple bundles' slot enabled state in a single IPC call, avoiding the
performance degradation caused by LRU cache misses in the single-query
path. Optimize getAllNotificationEnabledBundles to only query
_enabledNotification keys (filtered by VALUE IN ('1','3')) and parse
bundleName/uid from the key, reducing I/O by ~66%.
- Add IDL method GetEnabledForBundleSlots with OrderedMap output
- Add full-stack implementation: server, DB, client, helper, NAPI, ANI
- Unify single query path to bypass LRU cache via batch query internally
- Add QueryDataInKeys batched IN query and QueryEnabledBundles in RDB layer
- Add unit tests for server, DB layer, and RDB batch query
- Add performance test (300-bundle batch query < 30ms target)
Signed-off-by: CheerfulRicky <yuegang7@h-partners.com>
Co-Authored-By: Agent
Change-Id: I59ed3041c14b33a2fbe69517d6b366597f03b11b
Error code layering refactor moved SubscribeNotificationV26 call before
SetEnableClassification and SetNeedSilentReplayOnSubscribe, causing these
fields to be unset during subscription. Restore the original order: set
all subscribeInfo fields first, then call SubscribeNotificationV26.
Signed-off-by: CheerfulRicky <yuegang7@h-partners.com>
Co-Authored-By: Agent
Change-Id: Ia7c97753fa320567ea1ea67acf5e08efea66f145