Steven
Steven7 मिनट पढ़ें

आपका Mac ऐप माइक्रोफ़ोन एक्सेस देता है — फिर हर बार खुलने पर उसे भूल जाता है

GeekBye ने माइक्रोफ़ोन की अनुमति माँगी, आपने दे दी, और यह चल गया। अगली बार खोलने पर: गायब। और ऐप System Settings → Microphone में कभी दिखा ही नहीं। गुनहगार एक macOS सुरक्षा फ़ीचर था जो चुपचाप ऐप को एक ऐसे पाथ से चला रहा था जो गायब हो जाता है — यहाँ पूरी जाँच और वह एक-प्रॉम्प्ट वाला फ़िक्स है।

macOS
अनुमतियाँ
इंजीनियरिंग
GeekBye रिलीज़
आपका Mac ऐप माइक्रोफ़ोन एक्सेस देता है — फिर हर बार खुलने पर उसे भूल जाता है

यहाँ एक ऐसा बग है जो आपको अपनी ही आँखों पर शक करा दे। आप GeekBye इंस्टॉल करते हैं, यह माइक्रोफ़ोन एक्सेस माँगता है, आप Allow पर क्लिक करते हैं, और ट्रांसक्रिप्शन चल जाती है। बढ़िया। आप इसे बंद करते हैं, अगली सुबह फिर खोलते हैं — और यह माइक्रोफ़ोन एक्सेस फिर से माँगता है। आप इसे हाथ से ठीक करने के लिए System Settings → Privacy & Security → Microphone में जाकर देखते हैं, और GeekBye उस लिस्ट में है ही नहीं। न डिनाइड। न अलाउड। बस गैरहाज़िर, मानो उसने कभी माँगा ही न हो।

हर अलग-अलग हिस्सा सही दिखता था। प्रॉम्प्ट असली था। अनुमति उस पल में काम करती थी। ऐप सही यूज़ेज स्ट्रिंग्स के साथ ठीक से साइन्ड और नोटराइज़्ड था। फिर भी अनुमति हर बार खुलने पर हवा हो जाती थी। GeekBye v2.0.6 ने इसे ठीक किया — और मूल कारण उन सबसे चालाक चीज़ों में से एक है जो macOS आपकी हिफ़ाज़त के लिए करता है।

वह फ़ीचर जो ऐप को खुद उससे ही छिपा रहा था

गुनहगार है macOS App Translocation, एक Gatekeeper सुरक्षा फ़ीचर। जब आप कोई ऐप डाउनलोड करके सीधे DMG से या अपने ~/Downloads फ़ोल्डर से चलाते हैं — कहीं भी जहाँ वह अभी भी "क्वारंटीन" में है — तो macOS असल में उसे वहाँ से नहीं चलाता जहाँ आप उसे देखते हैं। यह चुपके से उसे एक रैंडमाइज़्ड, रीड-ओनली पाथ पर, /private/var/folders/.../AppTranslocation/… के गहरे अंदर कॉपी कर देता है और उसी कॉपी को चलाता है। यह एक अच्छा बचाव है: यह किसी नुकसानदेह डाउनलोड को अपने बगल की फ़ाइलों से छेड़छाड़ करने से रोकता है।

पर टकराव यहाँ है। macOS का अनुमति सिस्टम (TCC — वह चीज़ जो नज़र रखती है कि आपके माइक, कैमरा, स्क्रीन को कौन इस्तेमाल कर सकता है) एक ऐप को उसके पाथ और कोड आइडेंटिटी से पहचानता है। जब ऐप ट्रांसलोकेट होता है, वह पाथ रैंडम और अस्थायी होता है। तो जब आप माइक्रोफ़ोन एक्सेस देते हैं, macOS ईमानदारी से अनुमति दर्ज कर लेता है — पर एक ऐसे पाथ के ख़िलाफ़ जो अगली बार खुलने पर मौजूद ही नहीं होगा। ऐप फिर खोलिए, macOS उसे एक अलग रैंडम पाथ पर ट्रांसलोकेट करता है, एक ऐसा ऐप देखता है जिसका उसके पास कोई रिकॉर्ड नहीं है, और फिर से पूछता है। और चूँकि वह भूतिया पाथ कभी एक स्थिर जगह नहीं होता, ऐप को System Settings → Microphone में कभी एक स्थायी पंक्ति नहीं मिलती।

ऐप एक भूत को अनुमति दे रहा था।

यही वजह है कि सिर्फ़ कुछ लोग इससे टकराते थे। अगर GeekBye की आपकी कॉपी पहले से /Applications में थी — क्योंकि आपने उसे वहाँ खींचकर रखा, या क्योंकि वह ऑटो-अपडेट के जरिए वहाँ पहुँची — तो कोई क्वारंटीन नहीं, कोई ट्रांसलोकेशन नहीं, एक स्थिर पाथ, और सब कुछ पूरी तरह टिका रहता है। यह बग हमारे लिए और पहली इंस्टॉल के आगे बढ़ चुके हर किसी के लिए अदृश्य था, और यही वह किस्म का बग है जो सबसे लंबा टिकता है।

फ़िक्स: ऐप को एक असली घर दो

चूँकि पूरी समस्या एक अस्थिर पाथ है, फ़िक्स यह है कि ऐप को एक स्थिर पाथ पर पहुँचाया जाए। v2.0.6 पहचानता है कि GeekBye कब ट्रांसलोकेटेड चल रहा है (या बस /Applications के बाहर से चल रहा है) और एक-क्लिक वाला "Move to Applications" पेश करता है — macOS के उस रीलोकेशन कॉल का इस्तेमाल करके जो बंडल को /Applications में कॉपी करके वहीं से दोबारा लॉन्च करता है। उस पल के बाद ऐप की एक तयशुदा पहचान होती है: माइक्रोफ़ोन अनुमति टिकती है, स्क्रीन रिकॉर्डिंग टिकती है, और GeekBye आख़िरकार System Settings में वहीं दिखता है जहाँ आप उम्मीद करते हैं।

प्रॉम्प्ट इस बारे में शालीन है। यह Move to Applications, Not Now, और Don't Ask Again पेश करता है — और यह आख़िरी चुनाव याद रखता है, ताकि ऐप कभी उस किसी को तंग न करे जिसके पास इसे कहीं और से चलाने की सोची-समझी वजह है। प्रॉम्प्ट को दिखाया जाए या नहीं — इसका फ़ैसला छोटे, शुद्ध फ़ंक्शनों में अलग किया गया है (क्या यह बिल्ड ट्रांसलोकेटेड है? क्या यह /Applications के बाहर है? क्या यूज़र ने इसे दबा दिया?) ताकि इस लॉजिक की यूनिट-टेस्टिंग बिना किसी असली नोटराइज़्ड बिल्ड को असली क्वारंटीन किए हुए वॉल्यूम पर लॉन्च किए हो सके।

इसी रिलीज़ ने अनुमति के अनुभव को भी सरल किया। GeekBye पहले एक कस्टम, ख़ास इन-ऐप अनुमति विंडो खोलता था — कुछ सौ लाइनों की UI जो उस चीज़ को दोहराने की कोशिश करती थी जो OS पहले से अच्छे से करता है। v2.0.6 ने उसे हटा दिया और नेटिव macOS अनुमति प्रॉम्प्ट पर भरोसा किया, जिसके साथ एक शांत, बिना रुकावट वाला बैनर है जो तभी दिखता है जब कोई ज़रूरी अनुमति सच में गायब हो। कम कोड, और वह व्यवहार जिसे यूज़र पहले से पहचानते हैं क्योंकि बाक़ी हर Mac ऐप इसी तरह काम करता है।

जिस बात पर मुझे सबसे ज़्यादा गर्व है: मानने से पहले हमने इसे साबित किया

ट्रांसलोकेशन का अंदाज़ा लगाकर एक फ़िक्स शिप कर देना आसान होता। इसके बजाय, रिलीज़ ने पहले एक स्टार्टअप डायग्नॉस्टिक शिप किया: लॉन्च पर, GeekBye अब अपना ही एग्ज़िक्यूटेबल पाथ रिपोर्ट करता है और यह कि वह ट्रांसलोकेटेड है या नहीं, /Applications के अंदर है या नहीं, और मौजूदा माइक्रोफ़ोन व स्क्रीन अनुमति की स्थिति। उस टेलीमेट्री ने एक संभावित थ्योरी को एक पुष्ट थ्योरी में बदल दिया — प्रोडक्शन डेटा ने दिखाया कि प्रभावित सेशन असल में /Applications के बाहर ट्रांसलोकेटेड पाथ से ही चल रहे थे, बिलकुल जैसा अनुमान था।

वह क्रम मायने रखता है। "प्रॉम्प्ट आता है पर अनुमति टिकती नहीं" के कई संभावित स्पष्टीकरण हैं — कोई साइनिंग समस्या, कोई गायब यूज़ेज स्ट्रिंग, कोई एंटाइटलमेंट का मसला, कोई TCC डेटाबेस की गड़बड़ी। हमने API-स्तर के कारणों को ख़ारिज किया (रिक्वेस्ट पाथ साफ़-साफ़ सही था), फिर असल दुनिया के डेटा को आइडेंटिटी/पाथ लेयर की ओर इशारा करने दिया, बजाय इसके कि एक उम्मीद भरा फ़िक्स शिप करके यह आस लगाते कि सपोर्ट टिकट रुक जाएँ।

तीन बातें जो यह बग सिखाता है

  1. वह अनुमति जो प्रॉम्प्ट तो करती है पर टिकती नहीं, यह एक आइडेंटिटी की समस्या है, API की नहीं। अगर रिक्वेस्ट कोड सही है और अनुमति फिर भी गायब हो जाती है, तो रिक्वेस्ट को दोबारा लिखना बंद करिए। पूछिए कि OS अनुमति को किस पाथ और कोड आइडेंटिटी से बाँध रहा है — और क्या वह पहचान हर बार खुलने पर स्थिर रहती है।
  2. डायग्नॉस्टिक को फ़िक्स के साथ (या उससे पहले) शिप करिए। कुछ ही फ़ील्ड — मैं कहाँ से चल रहा हूँ, मेरी अनुमति की स्थिति क्या है — ने एक पढ़े-लिखे अनुमान को एक सत्यापित मूल कारण में बदला और हमें ठीक-ठीक बताया कि कौन-से यूज़र प्रभावित थे। जिस सीमा पर आपको शक है, उसे पैच करने से पहले उस पर इंस्ट्रुमेंट लगाइए।
  3. जो बग डेवलपरों से छिपते हैं, वे "ग़लत" माहौल में चल रहे होते हैं। हमारा हर डेव मशीन पर /Applications में रहता था, इसलिए बग बनावटी तौर पर हमारे लिए अदृश्य था जबकि पहली बार आने वाले यूज़र पर वार कर रहा था। जब कोई रिपोर्ट दोहराई न जा सके, तो पहला सवाल यह है कि वह कहाँ चलता है, इसमें क्या अलग है, न कि क्या यूज़र से ग़लती हुई है।

GeekBye v2.0.6 ने रीलोकेशन प्रॉम्प्ट और डायग्नॉस्टिक को साथ शिप किया। जिस बड़े रिलायबिलिटी दौर में यह बैठता है, उसके लिए देखिए एक वर्शन 2 में असल में क्या लगता है (v2.0.0) और स्क्रीन रिकॉर्डिंग ग़लत मॉनिटर क्यों कैप्चर करती है (v2.0.10) — एक और बग जो सिर्फ़ एक ख़ास माहौल में सामने आया। पास वाली छोटी-छोटी बातों वाली रिलीज़ के लिए, शांत सॉफ़्टवेयर: फ़्लिकर फ़िक्स और आंसर-मोड चिप (v2.0.3 + v2.0.5)।

संबंधित लेख

एक call को एक खुले हुए app से अलग पहचानना
Steven
Steven10 मिनट पढ़ें

एक call को एक खुले हुए app से अलग पहचानना

GeekBye यह ताड़ सकता है कि आप एक video meeting में शामिल हो गए हैं और एक क्लिक में उसे record करने की पेशकश करता है। पता चलता है कि detection ही आसान वाला आधा था — एक Swift binary जो हर दस सेकंड window titles पढ़ती है। मुश्किल आधा है सटीकता: जब Zoom बस खुला हो तब न भड़कना, एक ऐसी meeting के लिए न टोकना जिसे आप पहले से record कर रहे हैं, और उस call में microphone को mute न करना जिसमें आप असल में हैं। तीन releases, और हर एक एक ऐसा guard है जिसे ख़ुद को न हराना सीखना पड़ा।

इंजीनियरिंग
macOS
डेस्कटॉप
ख़ामोशी भार-वहन कर रही थी
Steven
Steven9 मिनट पढ़ें

ख़ामोशी भार-वहन कर रही थी

GeekBye v1 की आख़िरी दो releases एक ही असहज सच्चाई के बारे में हैं: एक असली network पर real-time transcription लॉसलेस नहीं है, और ईमानदार चाल है यह दिखावा बंद करना कि वह है। v1.8.20 ने एक reconnect के दौरान हर audio chunk को गिराने से पहले उसकी एक प्रति disk पर रखी, और transcript के अंतरालों को ज़ोर से चिह्नित करना शुरू किया। v1.9.0 ने bandwidth बचाने के लिए silence भेजना बंद किया — और पाया कि वह silence ही वह ठीक-ठीक संकेत था जिससे transcriber जानता था कि एक वाक्य ख़त्म हो चुका है। चीज़ें फेंक देने की क़ीमत के बारे में दो releases।

इंजीनियरिंग
Audio
विश्वसनीयता
तीन क्रियाएँ जो Web Audio को ज़िंदा रखती हैं
Steven
Steven10 मिनट पढ़ें

तीन क्रियाएँ जो Web Audio को ज़िंदा रखती हैं

GeekBye की दो point releases, दो महीने के फ़ासले पर और दो अलग files में, हमारे audio code को उलटे छोरों से एक ही सबक़ सिखा गईं: browser के AudioContext को इस्तेमाल-कर-फेंको जैसा मानना बंद करो। एक release ने एक ऐसे context को resume() करना सीखा जिसे macOS ने record के बीचोंबीच चुपचाप suspend कर दिया था; दूसरी ने close() के बजाय suspend() करना सीखा ताकि पीठ-दर-पीठ चलती sessions Chromium की लगभग-छह-context वाली छत से टकराना बंद कर दें। resume, suspend, close — यही पूरी कहानी है।

इंजीनियरिंग
Audio
डेस्कटॉप