खोज को ट्रेस करना

Winscope Perfetto ट्रेस में खास स्थितियां ढूंढने के लिए, SQL का इस्तेमाल करें. क्वेरी चलाने और टेबल में दिए गए नतीजों को विज़ुअलाइज़ करने के लिए, Winscope यूज़र इंटरफ़ेस (यूआई) में मौजूद ग्लोबल खोज व्यूअर का इस्तेमाल करें:

सर्च व्यूअर टैब

पहली इमेज. व्यूअर टैब खोजें.

खोज व्यूअर की मदद से, Perfetto ट्रेस पर कस्टम एसक्यूएल क्वेरी लिखी और चलाई जा सकती हैं. साथ ही, हाल ही की और सेव की गई क्वेरी को ऐक्सेस किया जा सकता है. Winscope, SurfaceFlinger, लेन-देन, ट्रांज़िशन, और ViewCapture ट्रेस खोजने में मदद करने के लिए, खास SQL व्यू उपलब्ध कराता है.

सभी व्यू के लिए, इन तरीकों का इस्तेमाल करें:

  • property और flat_property कॉलम के लिए:

    • प्रॉपर्टी के नाम, स्नेक केस में होते हैं. उदाहरण के लिए, visible_region from LayerProto.
    • डॉट नोटेशन, नेस्ट की गई प्रॉपर्टी को दिखाता है. उदाहरण के लिए, visible_region.rect.

    • property में दोहराए गए फ़ील्ड को स्क्वेयर ब्रैकेट से अलग किया जाता है:

      उदाहरण के लिए, दोहराए गए फ़ील्ड visible_region.rect के दो इंस्टेंस में, top फ़ील्ड को visible_region.rect[0].top और visible_region.rect[1].top के तौर पर दिखाया गया है.

    • flat_property में दोहराए गए फ़ील्ड में अंतर नहीं किया जा सकता:

      उदाहरण के लिए, दोहराए गए फ़ील्ड visible_region.rect के दो इंस्टेंस में, top फ़ील्ड को दोनों इंस्टेंस में visible_region.rect.top के तौर पर दिखाया गया है.

  • value और previous_value कॉलम के लिए, बूलियन वैल्यू को 0 (False) या 1 (True) से दिखाया जाता है.

Winscope, इन व्यू को बनाता है. इसके लिए, वह ट्रेस से जुड़ी टेबल के डेटा को Perfetto args टेबल के साथ जोड़ता है. इन टेबल से सीधे तौर पर क्वेरी की जा सकती है. args टेबल में, key, flat_key, और display_value कॉलम, व्यू कॉलम property, flat_property, और value के बराबर होते हैं.

args टेबल:

कॉलम ब्यौरा
arg_set_id इस कुकी का इस्तेमाल, आर्ग्युमेंट के सेट को जोड़ने के लिए किया जाता है
flat_key प्रोटो मैसेज से प्रॉपर्टी का नाम. इसमें दोहराए गए फ़ील्ड शामिल नहीं हैं
key प्रोटो मैसेज से प्रॉपर्टी का नाम, जिसमें दोहराए गए फ़ील्ड शामिल हैं
value_type प्रॉपर्टी वैल्यू का टाइप
int_value अगर वैल्यू टाइप पूर्णांक है, तो प्रॉपर्टी की वैल्यू
string_value अगर वैल्यू टाइप एक स्ट्रिंग है, तो प्रॉपर्टी की वैल्यू
real_value अगर वैल्यू टाइप 'वास्तविक' है, तो प्रॉपर्टी की वैल्यू
display_value प्रॉपर्टी की वैल्यू को स्ट्रिंग में बदला गया

SurfaceFlinger के एसक्यूएल व्यू

SurfaceFlinger प्रोटो डेटा इन फ़ॉर्मैट का इस्तेमाल करता है:

  • लेयर का डेटा, LayerProto फ़ॉर्मैट में है.

  • हायरार्की रूट का डेटा, LayersSnapshotProto फ़ॉर्मैट में है.

लेयर का डेटा खोजने के लिए, sf_layer_search व्यू का इस्तेमाल करें. इस व्यू में ये कॉलम शामिल हैं:

कॉलम ब्यौरा
state_id उस एंट्री का लाइन आईडी जिससे लेयर जुड़ी है
ts उस एंट्री का टाइमस्टैंप जिससे लेयर जुड़ी है
layer_id लेयर आईडी
parent_id पैरंट लेयर का आईडी
layer_name लेयर का नाम
is_visible लेयर किसको दिखे
property दोहराए गए फ़ील्ड के लिए प्रॉपर्टी का नाम
flat_property प्रॉपर्टी का नाम, दोहराए गए फ़ील्ड के लिए नहीं है
value स्ट्रिंग फ़ॉर्मैट में प्रॉपर्टी की वैल्यू
previous_value स्ट्रिंग फ़ॉर्मैट में, पिछली एंट्री से प्रॉपर्टी वैल्यू

हैरारकी के रूट डेटा को खोजने के लिए, sf_hierarchy_root_search व्यू का इस्तेमाल करें. इस व्यू में ये कॉलम शामिल हैं:

कॉलम ब्यौरा
state_id एंट्री का लाइन आईडी
ts एंट्री का टाइमस्टैंप
property दोहराए गए फ़ील्ड के लिए प्रॉपर्टी का नाम
flat_property प्रॉपर्टी का नाम, दोहराए गए फ़ील्ड के लिए नहीं है
value स्ट्रिंग फ़ॉर्मैट में प्रॉपर्टी की वैल्यू
previous_value स्ट्रिंग फ़ॉर्मैट में, पिछली एंट्री से प्रॉपर्टी वैल्यू

क्वेरी के उदाहरण

  • उन सभी फ़्रेम को ढूंढें जिनमें IME लेयर दिख रही है:

    SELECT DISTINCT ts, layer_id, layer_name FROM sf_layer_search
      WHERE layer_name like 'IME%'
      AND is_visible=1
    
  • उन सभी फ़्रेम को ढूंढें जिनमें IME लेयर की स्क्रीन बाउंड्री मान्य है:

    SELECT ts, value, previous_value FROM sf_layer_search
      WHERE layer_name like 'IME%'
      AND property='screen_bounds.bottom'
      AND value<='24000'
    
  • उन सभी फ़्रेम को ढूंढें जिनमें Taskbar लेयर color.a (अल्फ़ा) बदलती है:

    SELECT ts, value, previous_value FROM sf_layer_search
      WHERE layer_name like 'Taskbar%'
      AND property='color.a'
      AND value!=previous_value
    
  • उन सभी फ़्रेम को ढूंढें जिनमें Wallpaper की बॉटम बाउंड्री 2400 से कम या इसके बराबर है:

    SELECT ts, value, previous_value FROM sf_layer_search
      WHERE layer_name LIKE 'Wallpaper%'
      AND property='bounds.bottom'
      AND cast_int!(value) <= 2400
    
  • डिस्प्ले के लिए, मान्य लेयर स्टैक वाली सभी प्रॉपर्टी की सूची बनाएं:

    SELECT STATE.* FROM sf_hierarchy_root_search STATE_WITH_DISPLAY_ON
    INNER JOIN sf_hierarchy_root_search STATE
      ON STATE.state_id = STATE_WITH_DISPLAY_ON.state_id
      AND STATE_WITH_DISPLAY_ON.flat_property='displays.layer_stack'
      AND STATE_WITH_DISPLAY_ON.value!='4294967295'
      AND STATE.property LIKE CONCAT(
        SUBSTRING(
            STATE_WITH_DISPLAY_ON.property,
            0,
            instr(STATE_WITH_DISPLAY_ON.property, ']')
        ),
        '%'
      )
    
  • उन सभी फ़्रेम को ढूंढो जिनमें पीछे जाने के लिए स्वाइप करने का जेस्चर दिख रहा है

    SELECT DISTINCT STATE.ts FROM sf_layer_search STATE
      WHERE STATE.layer_name LIKE 'EdgeBackGestureHandler%'
    

डेटा टेबल

SurfaceFlinger व्यू, यहां दी गई टेबल का इस्तेमाल करके बनाए जाते हैं.

surfaceflinger_layers_snapshot:

कॉलम ब्यौरा
id लाइन की एंट्री के लिए आईडी
ts एंट्री का टाइमस्टैंप
arg_set_id इस एंट्री के साथ args टेबल की पंक्तियों को जोड़ने के लिए इस्तेमाल किया गया आईडी

surfaceflinger_layer:

कॉलम ब्यौरा
id लेयर के लिए लाइन आईडी
snapshot_id surfaceflinger_layers_snapshot में मौजूद उस एंट्री का लाइन आईडी जिससे लेयर जुड़ी है
arg_set_id इस लेयर के साथ args टेबल की पंक्तियों को जोड़ने के लिए इस्तेमाल किया गया आईडी

लेन-देन की एसक्यूएल व्यू

लेन-देन का प्रोटो डेटा, TransactionTraceEntry फ़ॉर्मैट का इस्तेमाल करता है.

लेन-देन के ट्रेस डेटा को खोजने के लिए, transactions_search व्यू का इस्तेमाल करें. इस व्यू में ये कॉलम शामिल हैं:

कॉलम ब्यौरा
state_id उस एंट्री का लाइन आईडी जिससे प्रोटो प्रॉपर्टी जुड़ी है
ts उस एंट्री का टाइमस्टैंप जिससे प्रोटो प्रॉपर्टी जुड़ी है
transaction_id अगर उपलब्ध हो, तो लेन-देन आईडी
property दोहराए गए फ़ील्ड के लिए प्रॉपर्टी का नाम
flat_property प्रॉपर्टी का नाम, दोहराए गए फ़ील्ड के लिए नहीं है
value स्ट्रिंग फ़ॉर्मैट में प्रॉपर्टी की वैल्यू

क्वेरी के उदाहरण

  • उस फ़्रेम को ढूंढें जहां लेन-देन लागू किया गया था, ताकि लेयर x की पोज़िशन को -54.0 पर बदला जा सके:

    SELECT ts, transaction_id, value FROM transactions_search
      WHERE flat_property='transactions.layer_changes.x'
      AND value='-54.0'
    
  • वह फ़्रेम ढूंढें जिसमें ImeContainer लेयर जोड़ी गई थी:

    SELECT ts FROM transactions_search
      WHERE flat_property='added_layers.name'
      AND value='ImeContainer'
    

डेटा टेबल

लेन-देन की एसक्यूएल व्यू टेबल, इन टेबल का इस्तेमाल करके बनाई जाती है.

surfaceflinger_transactions:

कॉलम ब्यौरा
id लाइन की एंट्री के लिए आईडी
ts एंट्री का टाइमस्टैंप
arg_set_id इस एंट्री के साथ args टेबल की पंक्तियों को जोड़ने के लिए इस्तेमाल किया गया आईडी
vsync_id इस एंट्री में मौजूद सभी लेन-देन से जुड़ा VSync आईडी

android_surfaceflinger_transaction:

कॉलम ब्यौरा
id लेन-देन के लिए लाइन आईडी
snapshot_id surfaceflinger_transactions में मौजूद उस एंट्री का लाइन आईडी जिससे लेन-देन जुड़ा है
arg_set_id इस लेन-देन के साथ args टेबल की पंक्तियों को जोड़ने के लिए इस्तेमाल किया गया आईडी
transaction_id प्रोटो मैसेज से लिया गया लेन-देन आईडी
pid प्रोटो मैसेज से लिया गया लेन-देन का पीआईडी
uid प्रोटो मैसेज से लिया गया लेन-देन यूआईडी
layer_id अगर लागू हो, तो लेन-देन से जुड़ी लेयर का आईडी
display_id अगर लागू हो, तो लेन-देन से जुड़े डिसप्ले का आईडी
flags_id इस आईडी का इस्तेमाल, android_surfaceflinger_transaction_flag से जुड़े फ़्लैग वापस पाने के लिए किया जाता है
transaction_type लेन-देन का टाइप

android_surfaceflinger_transaction_flag:

कॉलम ब्यौरा
flags_id यह android_surfaceflinger_transaction में मौजूद किसी लाइन की वैल्यू से मेल खाता है
flag अनुवाद की गई फ़्लैग स्ट्रिंग

लेन-देन के टाइप के आधार पर, अलग-अलग प्रोटो मैसेज फ़ॉर्मैट से, args टेबल में अलग-अलग लेन-देन जोड़े जाते हैं:

  • LAYER_ADDED: LayerCreationArgs फ़ॉर्मैट
  • LAYER_CHANGED: LayerState फ़ॉर्मैट
  • DISPLAY_ADDED: DisplayState फ़ॉर्मैट
  • DISPLAY_CHANGED: DisplayState फ़ॉर्मैट
  • LAYER_DESTROYED: कोई आर्ग्युमेंट नहीं
  • LAYER_HANDLE_DESTROYED: कोई आर्ग्युमेंट नहीं
  • DISPLAY_REMOVED: कोई आर्ग्युमेंट नहीं
  • NOOP: कोई आर्ग्युमेंट नहीं

ट्रांज़िशन का एसक्यूएल व्यू

ट्रांज़िशन प्रोटो डेटा, ShellTransition फ़ॉर्मैट का इस्तेमाल करता है.

ट्रांज़िशन का डेटा खोजने के लिए, transitions_search व्यू का इस्तेमाल करें. इस व्यू में ये कॉलम शामिल हैं:

कॉलम ब्यौरा
ts डिस्पैच करने का समय; अगर उपलब्ध है, तो भेजने के समय पर वापस आ जाता है. अगर उपलब्ध नहीं है, तो 0
transition_id प्रोटो मैसेज से लिया गया ट्रांज़िशन आईडी
property दोहराए गए फ़ील्ड के लिए प्रॉपर्टी का नाम
flat_property प्रॉपर्टी का नाम, दोहराए गए फ़ील्ड के लिए नहीं है
value प्रोटो मैसेज से लिया गया लेन-देन यूआईडी

क्वेरी के उदाहरण

DefaultMixedHandler से मैनेज किए गए ट्रांज़िशन की प्रॉपर्टी ढूंढें:

  SELECT
    PROPS.ts,
    PROPS.transition_id,
    PROPS.property,
    PROPS.value
  FROM transitions_search HANDLER_MATCH
  INNER JOIN transitions_search PROPS
    ON HANDLER_MATCH.transition_id = PROPS.transition_id
  WHERE HANDLER_MATCH.property = 'handler'
    AND HANDLER_MATCH.value LIKE "%DefaultMixedHandler"
  ORDER BY PROPS.transition_id, PROPS.property

डेटा टेबल

ट्रांज़िशन व्यू, इन टेबल का इस्तेमाल करके बनाया जाता है.

window_manager_shell_transitions:

कॉलम ब्यौरा
id ट्रांज़िशन के लिए लाइन आईडी
ts डिस्पैच करने का समय; अगर उपलब्ध है, तो भेजने के समय पर वापस आ जाता है. अगर उपलब्ध नहीं है, तो 0
transition_id प्रोटो मैसेज से लिया गया ट्रांज़िशन आईडी
arg_set_id इस ट्रांज़िशन के साथ args टेबल की पंक्तियों को जोड़ने के लिए इस्तेमाल किया गया आईडी
transition_type प्रोटो मैसेज से लिया गया ट्रांज़िशन टाइप
send_time_ns प्रोटो मैसेज से ट्रांज़िशन भेजने का समय
dispatch_time_ns ट्रांज़िशन डिस्पैच करने में लगने वाला समय, प्रोटो मैसेज से लिया गया है
duration_ns अगर शुरू और खत्म होने का समय उपलब्ध है, तो ट्रांज़िशन की अवधि
handler ट्रांज़िशन हैंडलर: window_manager_shell_transition_handlers से अनुवाद वापस पाएं
status ट्रांज़िशन का स्टेटस: played, merged या aborted
flags ट्रांज़िशन फ़्लैग, प्रोटो मैसेज से लिए गए हैं

window_manager_shell_transition_handlers:

कॉलम ब्यौरा
handler_id window_manager_shell_transitions की handler कॉलम में मौजूद वैल्यू से मेल खाने वाला आईडी
handler_name स्ट्रिंग का अनुवाद

android_window_manager_shell_transition_participants:

कॉलम ब्यौरा
transition_id ट्रांज़िशन आईडी, रॉ प्रोटो मैसेज से लिया गया है
layer_id SurfaceFlinger लेयर में हिस्सा लेने वाले व्यक्ति का आईडी
window_id WindowManager कंटेनर में हिस्सा लेने वाले व्यक्ति का आईडी

ViewCapture SQL व्यू

ViewCapture प्रोटो डेटा, View फ़ॉर्मैट का इस्तेमाल करता है.

ViewCapture का डेटा खोजने के लिए, viewcapture_search व्यू का इस्तेमाल करें. इस व्यू में ये कॉलम शामिल हैं:

कॉलम ब्यौरा
state_id उस राज्य का लाइन आईडी जिससे व्यू जुड़ा है
ts उस स्थिति का टाइमस्टैंप जिससे व्यू जुड़ा है
package_name पैकेज का नाम
window_name विंडो का नाम
class_name क्लास का नाम देखना
property दोहराए गए फ़ील्ड के लिए प्रॉपर्टी का नाम
flat_property प्रॉपर्टी का नाम, दोहराए गए फ़ील्ड के लिए नहीं है
value स्ट्रिंग फ़ॉर्मैट में प्रॉपर्टी की वैल्यू
previous_value स्ट्रिंग फ़ॉर्मैट में, पिछली स्थिति से प्रॉपर्टी की वैल्यू

क्वेरी के उदाहरण

SearchContainerView को y-दिशा में ले जाने पर, सभी राज्यों को ढूंढें:

  SELECT * FROM viewcapture_search
  WHERE class_name LIKE '%SearchContainerView'
    AND flat_property='translation_y'
    AND value!=previous_value

डेटा टेबल

ViewCapture व्यू, यहां दी गई टेबल का इस्तेमाल करके बनाया जाता है.

android_viewcapture:

कॉलम ब्यौरा
id लाइन की एंट्री के लिए आईडी
ts एंट्री का टाइमस्टैंप
arg_set_id इस एंट्री के साथ args टेबल की पंक्तियों को जोड़ने के लिए इस्तेमाल किया गया आईडी

android_viewcapture_view:

कॉलम ब्यौरा
id व्यू के लिए लाइन आईडी
snapshot_id android_viewcapture में मौजूद उस एंट्री का लाइन आईडी जिससे व्यू जुड़ा है
arg_set_id इस व्यू के साथ args टेबल की पंक्तियों को जोड़ने के लिए इस्तेमाल किया गया आईडी

ProtoLog SQL टेबल

ProtoLog का प्रोटो डेटा, ProtoLogMessage फ़ॉर्मैट का इस्तेमाल करता है. इस व्यू में ये कॉलम शामिल हैं:

कॉलम ब्यौरा
ts लॉग का टाइमस्टैंप
level लॉग लेवल
tag ग्रुप टैग को लॉग करना
message लॉग मैसेज
stacktrace स्टैकट्रेस (अगर उपलब्ध हो)
location मैसेज जनरेट करने वाले कोड की जगह

क्वेरी के उदाहरण

  • transition वाला मैसेज दिखाने वाले सभी लॉग ढूंढें:

    SELECT ts, message, location FROM protolog
      WHERE message LIKE '%transition%'
    
  • मान्य लेन-देन आईडी वाले सभी लॉग ढूंढें:

    CREATE PERFETTO VIEW valid_tx_ids AS
      SELECT DISTINCT transaction_id FROM transactions_search
      WHERE transaction_id IS NOT NULL AND transaction_id != '0';
    
    SELECT TRANS.transaction_id, message FROM valid_tx_ids TRANS
    INNER JOIN protolog LOGS
      ON LOGS.message LIKE CONCAT('%', TRANS.transaction_id, '%');
    

WindowManager का एसक्यूएल व्यू

WindowManager प्रोटो डेटा, क्रम के हिसाब से व्यवस्थित किए गए WindowManagerServiceDumpProto फ़ॉर्मैट का इस्तेमाल करता है. WindowManager कंटेनर की किसी भी प्रॉपर्टी को खोजा जा सकता है. जैसे:

WindowManager डेटा खोजने के लिए, wm_search व्यू का इस्तेमाल करें. इस व्यू में ये कॉलम शामिल हैं:

कॉलम ब्यौरा
state_id उस राज्य का लाइन आईडी जहां कंटेनर मौजूद है
ts उस स्थिति का टाइमस्टैंप जिससे कंटेनर जुड़ा है
title कंटेनर का टाइटल
token कंटेनर टोकन
parent_token पैरंट कंटेनर टोकन
is_visible कंटेनर दिखने की सेटिंग
property दोहराए गए फ़ील्ड के लिए प्रॉपर्टी का नाम
flat_property प्रॉपर्टी का नाम, दोहराए गए फ़ील्ड के लिए नहीं है
value स्ट्रिंग फ़ॉर्मैट में प्रॉपर्टी की वैल्यू
previous_value स्ट्रिंग फ़ॉर्मैट में, पिछली स्थिति से प्रॉपर्टी की वैल्यू

क्वेरी के उदाहरण

  • उन सभी राज्यों का पता लगाएं जहां LauncherActivity दिखता है:

    SELECT DISTINCT ts, title, token FROM wm_search
      WHERE title like '%LauncherActivity%'
      AND is_visible=1
    
  • उन सभी राज्यों का पता लगाएं जहां Wallpaper की सतह हिल रही है:

    SELECT ts, value, previous_value FROM wm_search
      WHERE title like '%Wallpaper%'
      AND property like '%surface_position%'
      AND value != previous_value
    

डेटा टेबल

WindowManager व्यू, इन टेबल का इस्तेमाल करके बनाया जाता है.

android_windowmanager:

कॉलम ब्यौरा
id लाइन की एंट्री के लिए आईडी
ts एंट्री का टाइमस्टैंप
arg_set_id इस एंट्री के साथ args टेबल की पंक्तियों को जोड़ने के लिए इस्तेमाल किया गया आईडी

android_windowmanager_windowcontainer:

कॉलम ब्यौरा
id कंटेनर के लिए लाइन आईडी
snapshot_id android_windowmanager में मौजूद उस एंट्री का लाइन आईडी जिससे कंटेनर जुड़ा है
arg_set_id इस व्यू के साथ args टेबल की पंक्तियों को जोड़ने के लिए इस्तेमाल किया गया आईडी

क्वेरी चलाना

खोज व्यूअर की बाईं ओर मौजूद, ग्लोबल सर्च पैनल का इस्तेमाल करके, सर्च क्वेरी चलाई जा सकती हैं.

GLOBAL SEARCH पैनल के साथ पहली बार इंटरैक्ट करने पर, ट्रेस सर्च शुरू हो जाती है. साथ ही, Winscope, हेल्पर एसक्यूएल व्यू बनाता है. इसमें कुछ सेकंड लगते हैं. ट्रेस सर्च शुरू होने के दौरान, टाइमलाइन उपलब्ध नहीं होती.

क्वेरी शुरू करने के लिए, खोज बॉक्स में कोई क्वेरी लिखें. इसके बाद, इसे चलाने के लिए खोज क्वेरी चलाएं पर क्लिक करें या अपने कीबोर्ड पर Enter दबाएं.

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

सेव की गई क्वेरी ऐक्सेस करने के लिए, बाईं ओर मौजूद पैनल में सेव की गई टैब पर क्लिक करें. हाल ही में चलाई गई क्वेरी ऐक्सेस करने के लिए, हाल ही की टैब पर क्लिक करें:

खोज के नतीजे दिखाने वाले पेज का बायां पैनल

दूसरी इमेज. व्यूअर के बाईं ओर मौजूद पैनल में खोजें.

नतीजे

सभी क्वेरी, टेबल के फ़ॉर्मैट में नतीजे दिखाती हैं. इन्हें स्क्रोल किया जा सकता है. साथ ही, ये लॉग-आधारित ट्रेस व्यूअर की तरह इंटरैक्टिव होते हैं. जैसे, लेन-देन और ProtoLog:

खोज के नतीजों में दिखने वाले वीडियो

तीसरी इमेज. खोज के नतीजों को देखने वाले व्यक्ति के लिए नतीजे.

अगर नतीजे के तौर पर मिली टेबल में ts कॉलम मौजूद है, तो उस कॉलम में मौजूद वैल्यू को टाइमस्टैंप के तौर पर समझा जाता है. साथ ही, उन्हें टाइमलाइन ओवरले में एंट्री की नई लाइन के तौर पर जोड़ा जाता है. इस लाइन पर क्लिक करें और एक से दूसरी एंट्री पर जाने के लिए, लेफ़्ट और राइट ऐरो बटन का इस्तेमाल करें:

खोज की टाइमलाइन

चौथी इमेज. टाइमलाइन में खोजें.