सिस्टम ऐप्लिकेशन में ViewCapture

ViewCapture एक सॉफ़्टवेयर टूल है. यह उन विंडो से जुड़ी व्यू प्रॉपर्टी (जैसे कि जगह, साइज़, स्केल, और विज़िबिलिटी) को कैप्चर करता है जिनसे यह जुड़ा होता है. ViewCapture, किसी विंडो में अलग-अलग व्यू और उनकी प्रॉपर्टी के बारे में जानकारी इकट्ठा करता है. इससे आपको यह पता चलता है कि किसी खास समय पर उपयोगकर्ता अनुभव कैसा था. साथ ही, समय के साथ हुए बदलावों को ट्रैक किया जा सकता है.

स्क्रीन रिकॉर्डिंग से, किसी खास समय पर व्यू की स्थिति को विज़ुअलाइज़ किया जा सकता है. साथ ही, यह भी दिखाया जा सकता है कि इसमें कैसे बदलाव होता है. हालांकि, इसके लिए सीपीयू के ज़्यादा संसाधनों की ज़रूरत होती है. साथ ही, इससे परफ़ॉर्मेंस पर असर पड़ सकता है. ViewCapture टूल का इस्तेमाल करने से, डिवाइस के संसाधनों पर कम असर पड़ता है. साथ ही, इसे ज़्यादा बार चालू किया जा सकता है. इसके अलावा, ViewCapture, व्यू लेवल पर विज़ुअलाइज़ेशन को फ़्रेम दर फ़्रेम दिखाता है. इससे स्क्रीन रिकॉर्डिंग की तुलना में, किसी खास समय पर व्यू की स्थिति की जांच करना ज़्यादा आसान हो जाता है.

इस पेज पर, सिस्टम ऐप्लिकेशन में ViewCapture को शामिल करने का तरीका बताया गया है.

इस्तेमाल करें

ViewCapture.java, onDrawListener के इंस्टेंस को लागू करता है. साथ ही, ड्रॉइंग प्रोसेस के दौरान ViewCapture ट्रेस इकट्ठा करता है. हर फ़्रेम को फिर से रेंडर करने पर, व्यू ट्री हैरारकी का ट्रैवर्सल ट्रिगर होता है. यह विंडो के रूट व्यू से शुरू होता है. ViewCapture, सार्वजनिक View.java getter तरीकों का इस्तेमाल करके, वैल्यू को फ़ेच और कॉपी करता है. ऐसा वह बैकग्राउंड थ्रेड में करता है, ताकि परफ़ॉर्मेंस को बेहतर बनाया जा सके. ViewCapture को लागू करने से, इस प्रोसेस को ऑप्टिमाइज़ किया जाता है. इसके लिए, captureViewTree का इस्तेमाल करके यह जांच की जाती है कि कोई व्यू डर्टी है या अमान्य है. इससे पूरी व्यू हैरारकी को ट्रैवर्स करने से बचा जा सकता है. captureViewTree सिर्फ़ सिस्टम ऐप्लिकेशन के लिए उपलब्ध है. यह UnsupportedAppUsage API का हिस्सा है. इस एपीआई का इस्तेमाल, टारगेट एसडीके वर्शन के आधार पर ऐप्लिकेशन के लिए सीमित है.

सीमाएं

इस सेक्शन में, ViewCapture की परफ़ॉर्मेंस और मेमोरी से जुड़ी सीमाओं के बारे में बताया गया है.

परफ़ॉर्मेंस

ViewCapture की परफ़ॉर्मेंस के लिए, मुख्य थ्रेड का औसत ओवरहेड 195 μs है. हालांकि, सबसे खराब स्थिति में इसमें करीब 5 मि॰से॰ लग सकते हैं. Perfetto ट्रेस में vc#onDraw स्लाइस देखें.

ऊपरी खर्च मुख्य रूप से इन कार्रवाइयों की वजह से होते हैं:

  1. हैरारकी को पार करने में 50 μs लगते हैं. भले ही, इसे कम कर दिया गया हो.
  2. व्यू प्रॉपर्टी की कॉपी सेव करने के लिए, फ़्रीलिस्ट ऐलोकेटर से ऑब्जेक्ट पाने में 20 माइक्रोसेकंड लगते हैं.
  3. getter फ़ंक्शन के ज़रिए हर प्रॉपर्टी वैल्यू को फ़ेच करने से, हर व्यू के लिए कई अतिरिक्त फ़ंक्शन कॉल होते हैं. इसमें 110 μs का समय लगता है.

इसलिए, हमेशा चालू रहने वाली ट्रेसिंग (एओटी) में ViewCapture को चालू करने से, सिस्टम की परफ़ॉर्मेंस पर बुरा असर पड़ता है और जंक की समस्या होती है. परफ़ॉर्मेंस और मेमोरी से जुड़ी इन सीमाओं की वजह से, यह तरीका एओटी के लिए तैयार नहीं है. हमारा सुझाव है कि ViewCapture का इस्तेमाल सिर्फ़ लैब और लोकल डीबगिंग के लिए करें.

मेमोरी

ViewCapture ट्रेस के लिए Perfetto का तरीका, एक ही रिंग बफ़र का इस्तेमाल करता है. इसमें मेमोरी का इस्तेमाल पहले से तय होता है, ताकि मेमोरी का ज़्यादा इस्तेमाल न हो. इस तरीके से, हर विंडो के लिए अलग-अलग रिंग बफ़र का इस्तेमाल नहीं किया जाता. इसलिए, इससे ज़्यादा मेमोरी खर्च नहीं होती. हालांकि, इससे हर फ़्रेम के लिए, Perfetto में हर स्थिति के लिए पूरे व्यू हायरार्की को सेव करने की समस्या हल नहीं होती. NexusLauncher जैसी किसी एक विंडो को रिकॉर्ड करने पर, 10 एमबी के बफ़र में 30 सेकंड से ज़्यादा का ViewCapture डेटा जनरेट हो सकता है. सिस्टम यूज़र इंटरफ़ेस (यूआई) से 30 से ज़्यादा विंडो कैप्चर करने के लिए, बड़े बफ़र या रिकॉर्डिंग के समय को काफ़ी कम करने की ज़रूरत होती है.

निर्देश

सिस्टम ऐप्लिकेशन में ViewCapture को शामिल करने के लिए, इन निर्देशों का पालन करें:

  1. लॉन्चर कोड में दिखाए गए तरीके से, अपनी Android.bp फ़ाइल में डिपेंडेंसी जोड़ें.

    android_library {
        name: "YourLib",
        static_libs: [
              ...
            "//frameworks/libs/systemui:view_capture",
              ...
        ],
        platform_apis: true,
        privileged: true,
    }
    
  2. अपनी विंडो बनाते समय, ViewCapture इंस्टेंस बनाएं. उदाहरण के लिए:

    • पहला उदाहरण:

      private SafeCloseable mViewCapture;
      
      @Override
      protected void onCreate(Bundle savedInstanceState) {
        ...
        mViewCapture = ViewCaptureFactory.getInstance(this).startCapture(getWindow());
      }
      
    • दूसरा उदाहरण:

      private SafeCloseable mViewCapture;
      
      @Override
      protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        if (enableViewCaptureTracing()) {
            mViewCaptureCloseable = ViewCaptureFactory.getInstance(getContext())
              .startCapture(getRootView(), ".NotificationShadeWindowView");
        }
        ...
      }
      
  3. अपनी विंडो को बंद करते समय, ViewCapture इंस्टेंस को बंद करें. इसके लिए, यहां दिए गए उदाहरण देखें: