הגדרת גישה מרחוק

ב-Android 14 נוספה התכונה החדשה של גישה מרחוק, שמאפשרת לשותפים להפעיל מרחוק את Android ברכב כדי לבצע משימות ספציפיות. לדוגמה, כדי להפעיל את מצב מוסך במהלך הלילה כדי להחיל עדכוני תוכנה. כדי לבצע את תהליך העבודה מקצה לקצה, נדרשים כמה רכיבים שאינם של Android. מערכת Android לא מגדירה או מספקת אמצעים להטמעה של רכיבים שאינם Android (האחריות הזו שייכת לכם).

מידע נוסף זמין בקטעים הבאים:

ארכיטקטורה

התוכן הבא מבוסס על הארכיטקטורה לדוגמה הבאה, שהיא היפותטית ועשויה שלא לשקף את הארכיטקטורה בפועל. יצרני ציוד מקורי צריכים להתאים את ההטמעה בפועל לארכיטקטורות של הרכבים והשרתים שלהם.

תמונה

איור 1. דוגמה לארכיטקטורה.

הארכיטקטורה לדוגמה מורכבת מהרכיבים הבאים של חומרה:

רכיב חומרה תיאור
מעבד אפליקציות מעבד Android. יכול להיות שמערכת Android תפעל בזיכרון וירטואלי (VM) (לא בחומרה בפועל) במעבד הזה.
מעבד מידע לרכב מעבד שאחראי על בקרת הכוח של מעבד האפליקציה.
יחידת בקרה של טלמטריה (TCU) המעבד ברכב תמיד יכול לקבל הודעות מרחוק מהענן. ההנחה היא ש-TCU תמיד פועל או במצב עם צריכת חשמל נמוכה. משתמשים בהודעות מרחוק כדי להעיר את TCU.
שרת ההשכמה שרת מרוחק שפועל בענן ואחראי על התקשורת עם ה-TCU ברכב כדי להנפיק פקודות הפעלה.
שרת משימות מרוחק שרת המשימות מרחוק פועל בענן, יוצר אינטראקציה עם אנשים ומנהל משימות מרחוק.

הארכיטקטורה לדוגמה מורכבת מרכיבי התוכנה הבאים, שכולם פועלים ב-Android:

רכיב תוכנה ב-Android תיאור
שירות רכב שירות מסגרת של AAOS שמספק ממשקי API לגישה מרחוק.
לקוח משימות מרחוק סוג של Service שנכתב על ידי הספק, שמבצע משימות מרחוק. מערכת Android אחת יכולה להריץ כמה לקוחות של משימות מרוחקות.
HAL לגישה מרחוק חובה להטמיע את האפשרות הזו כדי לגשת מרחוק.
שכבת הפשטה לתקשורת בין AAOS לבין רכיב שאינו Android, כמו TCU.

הרכיבים של תוכנות שאינן Android מתוארים בהמשך:

רכיב תוכנה שאינו Android תיאור
לקוח השכמה תוכנה שפועלת ב-TCU ושומרת על חיבור ארוך טווח לשרת ההפעלה. השירות גם שומר על חיבור עם HAL של גישה מרחוק כדי לבצע משימות מרחוק לשירות הרכב.
הטמעה של שרת השכמה שרת שמתקשר עם לקוח ההתעוררות שפועל ב-TCU. יכולה לשלוח בקשות להפעלה ללקוח ההפעלה.
הטמעה של שרת משימות מרוחק שרת שמנהל משימות מרחוק. המשתמשים יוצרים אינטראקציה עם השרת הזה כדי להקצות משימות מרחוק ולעקוב אחריהן.

זרימת עבודה

בקטע הזה מפורטים השלבים בתהליך עבודה לדוגמה.

תהליך עבודה לדוגמה

תהליך עבודה מפורט יכול להיראות כך:

  1. המשתמש מחנה את הרכב במוסך.

  2. השותף מנסה לעדכן את הרכב במהלך הלילה, כשסביר להניח שלא יהיו אינטראקציות עם הרכב.

  3. שרת הענן של השותף שולח לרכב משימה מרחוק של מערכת העדכון. באופן ספציפי, יחידת הבקרה הטלמטית (TCU).

  4. ה-TCU של הרכב מוציא את יחידת הבקרה האלקטרונית של Android (ECU) ושירות OEM (יצרן ציוד מקורי) מפעיל את מצב החניה.

  5. Android מפעיל את מצב Garage כדי להוריד ולהתקין עדכונים דרך Google Play.

  6. אחרי החלת העדכון, Android מסמנת את המשימה כ'הושלמה' ומפסיקה את החיבור או מגיע לתקופת זמן קצובה שצוינה.

תהליך עבודה מפורט

יש שני שלבים חשובים שנדרשים כדי לקבל גישה מרחוק. האפשרות הראשונה היא רישום הלקוח, כלומר קישור של משתמש ספציפי ללקוח משימות ספציפי מרחוק שפועל ברכב ספציפי. השני הוא שליחת משימה, כלומר העברת המשימה מרחוק של משתמש ספציפי ללקוח המשימות הספציפי מרחוק שפועל ברכב הספציפי.

רישום לקוח

כדי להשתמש בתכונה של גישה מרחוק, המשתמש צריך לפתוח את אפליקציית הלקוח של המשימות מרחוק לפחות פעם אחת ולהשלים את תהליך הרישום של הלקוח (טקסט מודגש מציין משימות שהופעלה בהן AAOS):

  1. עם ההפעלה, שירות Car Service מקבל את פרטי הרכב מה-HAL של הגישה מרחוק.

  2. בעת האתחול, Car Service מפעיל את כל הלקוחות של המשימות המרוחקות על סמך מסנן כוונת רכישה והרשאה.

  3. כשלקוח המשימות מרחוק מופעל, הוא מתעדכן ב-Car Service.

  4. Car Service מודיע ללקוח המשימה מרחוק על פרטי הרישום, כולל מזהה הרכב ומספר הלקוח. מזהה הלקוח הוא ייחודי ומוקצה על ידי שירות הרכב ללקוח הזה. המזהה הזה יהיה ייחודי לכל לקוחות המשימות מרחוק באותו רכב.

  5. המשתמש מתחבר לשרת המשימות המרוחק באמצעות לקוח המשימות המרוחק ומפעילים את תכונת הגישה מרחוק לרכב הזה. בשלב הזה בדרך כלל מתבצע אימות דרך שרת המשימות המרוחק.

  6. לקוח המשימות מרחוק מעלה את פרטי המשתמש, יחד עם מזהה הרכב ומזהה הלקוח, לשרת המשימות מרחוק ומבקש ממנו לקשר את המשתמש ללקוח הספציפי הזה ולרכב הספציפי הזה.

    לחלופין, השלב הזה עשוי לכלול אימות דו-שלבי נוסף מהמשתמש.

    שרת המשימות המרוחק צריך לאמת שמזהה הרכב שצוין בבקשה תואם למזהה הרכב של השולח. אפשר לעשות זאת באמצעות אימות הרכב.

אלא אם מתבצע איפוס להגדרות המקוריות, תהליך רישום הלקוח נדרש פעם אחת לכל משתמש לכל רכב. מזהה הלקוח מאוחסן באופן מקומי בשירות הרכב, והוא לא משתנה לאותו לקוח.

תמונה

איור 2. רושמים לקוח.

ביטול הרישום של לקוח

משתמש יכול לבטל את הקישור של הרכב לחשבון שלו מהרכב או משרת המשימות המרוחק:

  • ברכב, המשתמשים יכולים לפתוח את אפליקציית הלקוח של המשימות מרחוק ולשלוח בקשה לבטל את הקישור כדי לבטל את הקישור של הרכב הזה לחשבונות המשתמשים המקושרים הקודמים.

  • בשרת המשימות המרוחק, המשתמשים יכולים להתחבר לחשבון שלהם ולבטל את הקישור של רכב מקושר בעבר לחשבון הזה.

אם המשתמש ינתק את הרכב מהחשבון שלו, שרת המשימות המרוחק צריך להסיר את המיפוי המאוחסן של המשתמש הספציפי.

מסירת משימות

בענן:

  1. משתמש משתמש בשרת המשימות המרוחק כדי לשלוח משימה מרחוק לרכב ספציפי.

  2. שרת המשימות המרוחק ממפה את מזהה המשתמש למזהה הרכב ולמזהה הלקוח. הפעולה הזו שולחת את נתוני המשימה, מזהה הרכב ומזהה הלקוח לשרת של הוצאת המצב ממצב שינה.

  3. שרת ההתעוררות מאתר את ה-TCU הספציפי למזהה הרכב (בהנחה שה-TCU כבר רשום) ושולח את נתוני המשימה ומזהה הלקוח ל-TCU.

ברכב (טקסט מודגש מציין משימות שמבוצעות על ידי AAOS):

  1. TCU מקבל משימות מרחוק משרת מרוחק.

  2. אם מעבד האפליקציות (AP) שפועל ב-AAOS כבוי, ה-TCU משתמש במעבד הרכב (VP) כדי להעיר את ה-AP.

  3. שירות הרכב מקבל משימות מ-TCU.

  4. Car Service מחלק משימות ללקוח המשימות הרחוק המתאים.

  5. הלקוח של המשימה מרחוק מקבל ומבצע את המשימה.

    (אופציונלי) לקוח המשימות המרוחק יוצר קשר עם שרת המשימות כדי לקבל פרטים נוספים על המשימה ומבצע אותה.

  6. (אופציונלי) שירות לקוח של משימה מרחוק מדווח על תוצאת המשימה לשרת המשימות.

  7. לקוח המשימות מרחוק מודיע ל-Car Service כשהמשימה הושלמה.

  8. אם צריך, שירות הרכב משחזר את מצב החשמל ברכב.

תמונה

איור 3. מסירת משימות.

כתיבת לקוח משימה מרוחקת

CarRemoteAccessManager מספק את ה-API לתכונות הגישה מרחוק. למידע נוסף, ראו CarremoteAccessManager. לקוח של משימות מרחוק הוא שירות ל-Android שמבצע משימות מרחוק ומשתמש ב-CarRemoteAccessManager. לשם כך נדרשים PERMISSION_USE_REMOTE_ACCESS ו-PERMISSION_CONTROL_REMOTE_ACCESS, וצריך להצהיר על מסנן כוונה ל-RemoteTaskClientService, למשל:

<service android:name=".remoteaccess.RemoteTaskClientService"
         android:directBootAware="true"
         android:exported="true">
    <intent-filter>
       <action android:name="android.car.remoteaccess.RemoteTaskClientService" />
    </intent-filter>
</service>

לקוח של משימה מרוחקת צריך לרשום את עצמו ב-Car Service במהלך היצירה:

public final class RemoteTaskClientService extends Service {
    @Override
    public void onCreate() {
        // mCar = Car.createCar()...
        mRemoteAccessManager = (CarRemoteAccessManager)
            mcar.getCarManager(Car.CAR_REMOTE_ACCESS_SERVICE);
        if (mRemoteAccessManager == null) {
            // Remote access feature is not supported.
            return;
        }
        mRemoteAccessManager.setRemoteTaskClient(executor, mRemoteTaskClient);
    }
}

היא צריכה לשנות את הפונקציה onBind כדי להחזיר null.

@Override
public IBinder onBind(Intent intent) {
    return null;
}

שירות הרכב מנהל את מחזור החיים שלו. Car Service מתחבר לשירות הזה במהלך ההפעלה וכאשר מגיעת משימה מרחוק. השירות 'Car Service' יתנתק מהשירות הזה כשהמשימה תושלם. למידע נוסף, קראו את המאמר ניהול מחזור החיים של שירות.

לקוח המשימות המרוחק פועל בתור משתמש המערכת, ולכן אין לו גישה לנתונים ספציפיים למשתמש.

בדוגמה הבאה תוכלו לראות איך מטפלים בקריאות חוזרות (callback) שנרשמו:

private final class RemoteTaskClient
    implements CarRemoteAccessManager.RemoteTaskClientCallback {
    @Override
    public void onRegistrationUpdated(
        RemoteTaskClientRegistrationInfo info) {
        // Register to remote task server using info.
    }
    @Override
    public void onRemoteTaskRequested(String taskId,
        byte[] data, int remainingTimeSec) {
        // Parses the data and execute the task.
        // Report task result to remote task server.
        mRemoteAccessManager.reportRemoteTaskDone(taskId);
    }
    @Override
    public void onShutdownStarting(CompleteableRemoteTaskFuture future) {
        // Stop the executing task.
        // Clear the pending task queue.
        future.complete();
    }
}

הטמעה של הספק

התכונה של גישה מרחוק היא אופציונלית ומושבתת כברירת מחדל. כדי להפעיל את התכונה, מוסיפים קובץ RRO כמו זה:

// res/xml/overlays.xml
<?xml version="1.0" encoding="utf-8"?>
<overlay>
    <item target="array/config_allowed_optional_car_features" value="@array/config_allowed_optional_car_features" />
</overlay>

// res/values/config.xml
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
    <string-array translatable="false" name="config_allowed_optional_car_features">
        <item>car_remote_access_service</item>
    </string-array>
</resources>

// Android.bp
runtime_resource_overlay {
    name: "RemoteAccessOverlay",
    resource_dirs: ["res"],
    manifest: "AndroidManifest.xml",
    sdk_version: "current",
    product_specific: true
}

אפשר גם להשתמש בפקודת adb הבאה ב-userdebug/eng build:

adb shell cmd car_service enable-feature car_remote_access_service

דרישות ב-Android

HAL של גישה מרחוק

שכבת ההפשטה של חומרת הגישה מרחוק (HAL) היא שכבת הפשטה שהוטמעה על ידי הספק לתקשורת בין AAOS לבין יחידת בקרה אלקטרונית אחרת (למשל, TCU). חובה להשתמש בתכונה 'גישה מרחוק'. אין צורך להטמיע אותו אם לא מטמיעים את תכונת הגישה מרחוק.

הממשק מוגדר בקובץ IRemoteAccess.aidl וכולל את השיטות הבאות:

דרגה תיאור
String getVehicleId() מקבל מזהה רכב ייחודי שאפשר לזהות בשרת ההתעוררות.
String getWakeupServiceName() הפונקציה מקבלת את השם של שרת ההפעלה מרחוק.
String getProcessorId() מקבל מזהה מעבד ייחודי שאפשר לזהות על ידי העירת הלקוח.
void setRemoteTaskCallback(IRemoteTaskCallback callback)

הגדרת קריאה חוזרת (callback) שתתבצע כשמתבצעת בקשה לביצוע משימה מרחוק.

void clearRemoteTaskCallback() מחיקת קריאה חוזרת (callback) של משימה מרחוק שהוגדרה קודם.
void notifyApStateChange(in ApState state)

הבדיקה מזהה אם מעבד האפליקציה מוכן לקבל משימות מרחוק.

ממשק הקריאה החוזרת מוגדר ב-IRemoteTaskCallback.aid.

דרגה תיאור
oneway void onRemoteTaskRequested(String clientId, in byte[] data)

קריאה חוזרת (callback) שנקראת כשמתבצעת בקשה לביצוע משימה מרחוק.

הטמעת העזרה עם TCU חיצוני. ההטמעה משתמשת בזרם קריאה לטווח ארוך כדי לקבל משימות מרחוק, ותומכת בפקודה debug הבאה:

dumpsys android.hardware.automotive.remoteaccess.IRemoteAccess/default

Vehicle HAL

כדי לתמוך בתכונה 'גישה מרחוק', VHAL צריך לתמוך במאפיינים הבאים:

דרגה תיאור
SHUTDOWN_REQUEST בקשה להשבתת יחידת הראש.
VEHICLE_IN_USE
  • זיהוי אם הרכב נמצא בשימוש.
  • אחרי שהמשתמש מבטל את נעילת הרכב או כשהמשתמש מתקרב לרכב. הוא צריך להיות true.
  • משך זמן ספציפי אחרי שהמשתמש מכבה את הרכב או אחרי שהוא נועל את הרכב. הערך צריך להיות false.
  • כשהערך הוא true, מערכת AAOS לא מנסה לכבות את הרכב כשהמשימה מרחוק מסתיימת.

מידע נוסף זמין במאמר מאפייני מערכת נתמכים.

מצב שקט

התכונה 'גישה מרחוק' חייבת לתמוך במצב שקט כדי שהרכב יוכל להפעיל את המנוע במצב שקט כדי לבצע משימות מרחוק כשאין משתמש. במצב שקט, מכשיר AAOS מופעל עם המסך והאודיו מושבתים.

מצב השקט נשלט באמצעות שני קבצים של ליבה של Linux‏ sysfs.

דרגה תיאור
/sys/kernel/silent_boot/pm_silentmode_kernel_state

מייצג את המצב השקט הנוכחי.

/sys/kernel/silent_boot/pm_silentmode_hw_state

מייצג את אות החומרה להגדרת מצב שקט חדש.

מעבד הרכב שולח אות חומרה ל-Android SoC כדי להפעיל או להשבית את המצב השקט. האות (0 או 1) נכתב ב-/sys/kernel/silent_boot/pm_silentmode_hw_state. לאחר מכן, מסגרת AAOS מעדכנת את הערך של /sys/kernel/silent_boot/pm_silentmode_kernel_state בהתאם, והוא מייצג את מצב ההשתקה הנוכחי. המודולים של AAOS בודקים את הערך של /sys/kernel/silent_boot/pm_silentmode_kernel_state כדי לדעת אם המערכת במצב שקט או לא.

כשמתקבלת משימה מרחוק ו-AAOS מופעל, מעבד הרכב מגדיר את המצב השקט ומפעיל את AAOS כך שהמערכת תופעל עם המסך או השמע מושבתים.

רכיבים ברכב שלא מבוססים על Android

מעבד מידע לרכב

מעבד הרכב הוא מעבד ברכב שיכול לשלוט במתח של מעבד האפליקציה שפועל ב-Android. בארכיטקטורה לדוגמה, ה-TCU מעיר את מעבד האפליקציות על ידי שליחת אות למעבד הרכב.

רכיבים ברכב שאינם של Android

ה-TCU ברכב תמיד יכול לקבל הודעות מרחוק.

לקוח ההפעלה פועל ב-TCU כדי להבטיח חיבור ארוך טווח לשרת ההפעלה מרחוק.

AAOS שפועל ב-AP יכול לתקשר עם הלקוח במצב שינה שפועל ב-TCU באמצעות HAL של גישה מרחוק.

תמונה

איור 4. TCU (לקוח ההשכמה).

רכיבים בענן

שרת ההשכמה

שרת היציאה ממצב שינה מתקשר עם הלקוח ליציאה ממצב שינה ב-TCU כדי:

  • שמירה על חיבור ארוך טווח ל-TCU של הרכב.
  • חיפוש TCU ספציפי על סמך מזהה רכב.
  • דיווח על סטטוס הרכב. לדוגמה, אונליין או אופליין, או מועד החיבור האחרון לשרת המשימות המרוחק.

בהטמעה בפועל, אפשר למזג שרת התעוררות עם שרת משימות מרוחק.

שרת משימות מרוחק

המשימות המרוחקות האלה מנוהלות על ידי שרת המשימות המרוחק.

  • המשתמש יוצר אינטראקציה עם השרת כדי להתחיל משימות חדשות מרחוק ולעקוב אחרי משימות מרחוק.

  • נעשה שימוש בשרת ההתעוררות המרוחק כדי להוציא את מעבד האפליקציות ממצב שינה ברכבים.

  • מתקשר עם לקוח המשימות מרחוק שפועל ברכב.

  • שמירת פרטי הרישום של הלקוח. כך אפשר לשייך משתמש ספציפי ללקוח משימות ספציפי מרחוק ברכב ספציפי.

בדרך כלל, נתוני המשימה שנשלחים דרך שרת המשימות המרוחק לשרת ההתעוררות, ל-TCU של הרכב ולבסוף ללקוח המשימות המרוחק, הם פשוט מזהה משימה. לקוח המשימה מרחוק משתמש במזהה המשימה כדי לאחזר את המידע המפורט משרת המשימות המרוחק.

דרישות לגבי פרטיות ואבטחה

משימה תנאי דרישה
TCU (לקוח ההשכמה) MUST
  • אימות שרת ההתעוררות.
  • אמון בקוד.
שרת השכמה MUST
  • מתירים רק לשרתים מרוחקים של משימות שברשימת ההיתרים להתחבר.
  • מבצעים אימות של לקוח ההתעוררות.
  • שולחים את הודעת ההשכמה רק לרכב היעד.
לקוח משימות מרחוק MUST
  • אימות המשתמש בזמן ההרשמה.
  • מאמתים את שרת המשימות המרוחק.
  • לעמוד בכל דרישות האבטחה לשירות ל-Android. לדוגמה, הרשאות מוגבלות.
שרת משימות מרוחק MUST
  • צריך לאמת את שרת ההתעוררות.
  • לספק אימות רכב. כלומר, צריך לאמת שמספר הרכב שצוין בבקשה תואם למספר הרכב של השולח. אם אי אפשר לבצע אימות של הרכב, צריך להשתמש באמצעים אחרים כדי לאמת שהמשתמש הוא הבעלים הנוכחי של הרכב.
  • אימות הזהות של המשתמש.
  • לעמוד בכל דרישות האבטחה לשרת שמטפל במידע על המשתמשים.

איפוס להגדרות המקוריות והעברת הבעלות

אם משתמש מבצע איפוס להגדרות המקוריות, המערכת מאפסת את מספר הלקוח ששמור בשירות הרכב. עם זאת, השרתים (שרת משימות מרוחקות ושרת יציאה ממצב שינה מרחוק) לא מקבלים הודעה על כך. השרתים שומרים מיפוי של מזהה הלקוח שפג התוקף שלו לרכב. כתוצאה מכך, אם המשתמש מתחיל משימה חדשה מרחוק ברכב, המערכת משתמשת במזהה הלקוח שפג התוקף שלו. הרכב מתעורר, אבל לא ניתן להריץ את המשימה מרחוק כי למזהה הלקוח של המשימה מרחוק יש מזהה לקוח שונה שלא תואם.

המאמר הבא מתאר אחת מהאפשרויות ליישום איפוס להגדרות המקוריות.

כשמשתמש מבצע איפוס להגדרות המקוריות, הספק מבקש מהמשתמש להתחבר לשרת המשימות המרוחק ולבטל את הקישור של הרכב לחשבון שלו, אם המשתמש קישר בעבר את הרכב. אין ערובה לכך שהמכשיר יהיה עם גישה לרשת במהלך האיפוס להגדרות המקוריות. לכן, יכול להיות שלא תהיה אפשרות לשלוח את בקשת ביטול הקישור מהמכשיר בזמן האיפוס להגדרות המקוריות.

כשמעבירים את הבעלות על הרכב, צריך לבצע פעולות מסוימות כדי לוודא שהבעלים הקודמים לא יוכלו יותר לבצע משימות מרחוק לרכב. לדוגמה, יכול להיות שהבעלים החדש יתבקש:

  • לבצע איפוס להגדרות המקוריות. כך מוודאים שמזהה הלקוח ייווצר מחדש. אחרי השלב הזה, הבעלים הקודם עדיין יוכל להעיר את הרכב, אבל לא יוכל יותר לבצע משימות מרחוק.

  • פותחים את אפליקציית הלקוח של המשימות מרחוק ופועלים לפי התהליך של ביטול הרישום של לקוח כדי לבטל את הקישור של הרכב לחשבון של הבעלים הקודם. הבעלים החדש יכול לפעול לפי התהליך של רישום לקוח כדי לקשר את הרכב לחשבון שלו ולהחליף את החשבון הקודם שמקושר לרכב.

  • הבעלים החדשים יכולים להשתמש בתהליך רישום לקוח כדי לקשר את הרכב לחשבון שלו ולהחליף את החשבון הקודם שקושר.

בדיקת לקוח המשימות מרחוק

אנחנו מספקים את ספריית העזר לגישה מרחוק עם HAL default כדי לבדוק לקוחות עם משימות מרחוק. אפשר להשתמש בפקודה הבאה debug כדי להחדיר משימה מזויפת מרחוק ל-HAL, שמועברת ללקוח המשימה המרוחקת אם מספקים את מזהה הלקוח הנכון. כדי לקבל את מזהה הלקוח, אפשר לרשום את פרטי הרישום בהטמעת הלקוח של המשימה מרחוק.

adb root && adb shell dumpsys android.hardware.automotive.remoteaccess.IRemoteAccess/default --inject-task [clientID] [taskData]