DEV Community

lyc233333
lyc233333

Posted on

Hongmeng IME Kit Advanced Development: Shared Sandbox and Cross-Process Data Transmission πŸš€

The shared sandbox mechanism of Hongmeng input method makes cross-process data sharing safe and efficient.This article analyzes sandbox configuration and core data transmission logic, and attaches practical code to help you realize advanced functions such as cloud synchronization~

1. Shared sandbox: a "safety safe" for cross-process communication πŸ“¦

Core Concept

  • Sandbox Isolation: Each application has an independent sandbox by default (/data/el2/user/0/package/). Shared sandboxes are accessed across processes through data-group
  • Permission Control: Only processes within the same data-group can be read and written, and must be declared in module.json5
  • Data encryption: Supports AES-256 encrypted storage to prevent data leakage

Application Scenario

Scenario Implementation method
Input method β†’ ​​Main application synchronizes theme Sandbox stores theme configuration files, and the main application updates the UI after reading
Cross-device vocabulary synchronization Sandbox data is synchronized across devices through HMS Core cloud service
Extended function data interaction Voice input module recognition results are written to the sandbox, and input method is read

2. Sandbox configuration: open the "data tunnel" between processes πŸ”‘

1. Declare the shared group ID (module.json5)

{  
  "module": {  
    "extensionAbilities": [  
      {  
        "name": ".InputMethodService",  
"data-group-ids": ["ime_share_group"] // Input method extension group ID
      }  
    ],  
    "abilities": [  
      {  
        "name": ".MainAbility",  
"data-group-ids": ["ime_share_group"] // The main application group ID must be consistent
      }  
    ]  
  }  
}  
Enter fullscreen mode Exit fullscreen mode

2. Get the sandbox path

// Get in the input method extension
const shareDir = this.context.getGroupDir('ime_share_group');  
// The paths in the main application are consistent
Enter fullscreen mode Exit fullscreen mode

3. Example directory structure

ime_share_group/  
β”œβ”€ config/ # configuration file (theme, thesaurus)
β”‚  β”œβ”€ theme.json  
β”‚  └─ user_dict.txt  
β”œβ”€ cache/ # Temporary data (voice cache, clipboard)
└─ logs/ # debug log
Enter fullscreen mode Exit fullscreen mode

3. Data transmission: file operation and serialization skillsπŸ“„

1. Write data (example: save user vocabulary)

import fs from '@ohos.file.fs';  

async function saveUserDictionary(words: string[]) {  
  const filePath = `${shareDir}/config/user_dict.txt`;  
  const content = words.join('\n');  
  await fs.writeFile(filePath, content, { encoding: 'utf8' });  
}  
Enter fullscreen mode Exit fullscreen mode

2. Read data (Example: Loading topic configuration)

async function loadThemeConfig() {  
  const filePath = `${shareDir}/config/theme.json`;  
  try {  
    const content = await fs.readFile(filePath, { encoding: 'utf8' });  
    return JSON.parse(content) as ThemeConfig;  
  } catch (error) {  
return defaultTheme; //Return to default configuration if read failed
  }  
}  
Enter fullscreen mode Exit fullscreen mode

3. Binary data processing (example: cache voice files)

async function cacheVoiceData(voiceBuffer: ArrayBuffer) {  
  const filePath = `${shareDir}/cache/voice_${Date.now()}.bin`;  
  const fd = await fs.open(filePath, fs.OpenMode.CREATE | fs.OpenMode.WRITE);  
  await fs.writeSync(fd, new Uint8Array(voiceBuffer));  
  await fs.close(fd);  
}  
Enter fullscreen mode Exit fullscreen mode

4. Security Strengthening: Prevent data abuse πŸ›‘οΈ

1. Permission verification

// Verify the caller's identity when data is read
function checkCallerPermission() {  
  const callerBundle = AbilityFeatureManager.getCurrentAbilityInfo().bundleName;  
  if (callerBundle !== 'com.example.ime.main') {  
throw new Error('No permission to access the shared sandbox');
  }  
}  
Enter fullscreen mode Exit fullscreen mode

2. Encrypted storage

import { crypto } from '@ohos.security';  

// Encryption during writing
async function encryptAndSave(data: string, key: string) {  
  const cipherText = await crypto.encrypt(data, key, 'AES/CBC/PKCS7Padding');  
  await fs.writeFile(`${shareDir}/secure_data.dat`, cipherText);  
}  

// Decryption during reading
async function decryptAndLoad(key: string) {  
  const cipherText = await fs.readFile(`${shareDir}/secure_data.dat`);  
  return crypto.decrypt(cipherText, key, 'AES/CBC/PKCS7Padding');  
}  
Enter fullscreen mode Exit fullscreen mode

3. Data Cleaning Strategy

// Clean out expired cache regularly (such as voice files 7 days ago)
async function cleanOldCache() {  
  const files = await fs.readdir(`${shareDir}/cache`);  
  files.forEach(file => {  
    const mtime = fs.statSync(`${shareDir}/cache/${file}`).mtime;  
    if (Date.now() - mtime > 7 * 24 * 3600 * 1000) {  
      fs.unlinkSync(`${shareDir}/cache/${file}`);  
    }  
  });  
}  
Enter fullscreen mode Exit fullscreen mode

5. Practical scenario: Cross-process theme synchronizationπŸ’…

1. Main application setting theme

// Save theme configuration in the main application
async function setTheme(theme: Theme) {  
  const config = { themeColor: theme.color, fontSize: theme.size };  
  await saveUserConfig('theme.json', config);  
// Notify input method to update topic
  this.context.startAbility({  
    bundleName: 'com.example.ime',  
    abilityName: 'InputMethodService',  
    action: 'update_theme'  
  });  
}  
Enter fullscreen mode Exit fullscreen mode

2. Input method to monitor topic changes

// Receive topic update messages in the input method service
onRequest(want: Want) {  
  if (want.action === 'update_theme') {  
    this.loadThemeConfig().then(theme => {  
this.updateKeyboardStyle(theme); // Re-render the keyboard style
    });  
  }  
}  
Enter fullscreen mode Exit fullscreen mode

3. Theme style update

function updateKeyboardStyle(theme: ThemeConfig) {  
  this.panel.setUiContent(() => {  
    Column() {  
Grid() { /* Use theme.color as background color */ }
    }.backgroundColor(theme.themeColor);  
  });  
}  
Enter fullscreen mode Exit fullscreen mode

6. Performance optimization: Make data interaction more efficient

1. Memory Mapping (MMAP)

// Use memory mapping to improve speed when reading large files
const fd = await fs.open(filePath, fs.OpenMode.READ);  
const mmap = await fs.mmap(fd, 0, fs.MMAP_ACCESS_MODE.MMAP_ACCESS_READ);  
const content = new TextDecoder().decode(mmap);  
fs.munmap(mmap);  
Enter fullscreen mode Exit fullscreen mode

2. Incremental update

// Only the difference is written when the lexicon is updated
async function updateDictionaryDiff(newWords: string[]) {  
  const oldWords = await loadUserDictionary();  
  const diff = newWords.filter(word => !oldWords.includes(word));  
  await fs.appendFile(`${shareDir}/config/user_dict.txt`, diff.join('\n'));  
}  
Enter fullscreen mode Exit fullscreen mode

Summary: The "three elements" of shared sandbox development

  1. Configuration first: Ensure that the main application is consistent with the data-group extended by the input method
  2. Security first: Sensitive data encrypted storage, strictly verify access permissions
  3. Efficiency priority: Use MMAP for large files, and update incremental data differentials

Top comments (0)