এই ডিসপ্লে-নির্দিষ্ট ক্ষেত্রগুলিতে করা আপডেটগুলি নীচে সরবরাহ করা হয়েছে:
- ক্রিয়াকলাপ এবং প্রদর্শনের আকার পরিবর্তন করুন
- ডিসপ্লে মাপ এবং আকৃতির অনুপাত
- প্রদর্শন নীতি
- উইন্ডো সেটিংস প্রদর্শন করুন
- স্ট্যাটিক ডিসপ্লে শনাক্তকারী
- দুইটির বেশি ডিসপ্লে ব্যবহার করা
- প্রতি-ডিসপ্লে ফোকাস
কার্যকলাপ এবং প্রদর্শনের আকার পরিবর্তন করুন
একটি অ্যাপ মাল্টি-উইন্ডো মোড বা আকার পরিবর্তন করতে পারে না তা নির্দেশ করার জন্য, কার্যকলাপগুলি resizeableActivity=false
অ্যাট্রিবিউট ব্যবহার করে। অ্যাপ্লিকেশানগুলির দ্বারা ক্রিয়াকলাপগুলির আকার পরিবর্তন করার সময় সাধারণ সমস্যাগুলির মধ্যে রয়েছে:
- একটি অ্যাক্টিভিটি অ্যাপ বা অন্য অ-ভিজ্যুয়াল উপাদান থেকে একটি ভিন্ন কনফিগারেশন থাকতে পারে। অ্যাপের প্রসঙ্গ থেকে ডিসপ্লে মেট্রিক্স পড়া একটি সাধারণ ভুল। প্রত্যাবর্তিত মানগুলি দৃশ্যমান এলাকার মেট্রিক্সের সাথে সামঞ্জস্য করা হবে না যেখানে একটি কার্যকলাপ প্রদর্শিত হয়৷
- একটি ক্রিয়াকলাপ আকার পরিবর্তন এবং ক্র্যাশ পরিচালনা করতে পারে না, একটি বিকৃত UI প্রদর্শন করতে পারে, বা দৃষ্টান্তের অবস্থা সংরক্ষণ না করে পুনরায় লঞ্চ করার কারণে অবস্থা হারাতে পারে।
- একটি অ্যাপ পরম ইনপুট স্থানাঙ্ক ব্যবহার করার চেষ্টা করতে পারে (উইন্ডো অবস্থানের সাথে সম্পর্কিত সেগুলির পরিবর্তে), যা মাল্টি-উইন্ডোতে ইনপুটটি ভেঙে দিতে পারে।
অ্যান্ড্রয়েড 7 (এবং উচ্চতর), একটি অ্যাপকে সর্বদা ফুল স্ক্রিন মোডে চালানোর জন্য resizeableActivity=false
সেট করা যেতে পারে। এই ক্ষেত্রে, প্ল্যাটফর্মটি স্প্লিট স্ক্রিনে যাওয়া থেকে অ-আকারযোগ্য ক্রিয়াকলাপগুলিকে বাধা দেয়। যদি ব্যবহারকারী ইতিমধ্যেই একটি স্প্লিট-স্ক্রিন মোডে থাকা অবস্থায় লঞ্চার থেকে একটি অ-আকারযোগ্য ক্রিয়াকলাপ শুরু করার চেষ্টা করে, প্ল্যাটফর্মটি স্প্লিট-স্ক্রিন মোড থেকে বেরিয়ে আসে এবং পূর্ণ-স্ক্রীন মোডে অ-আকারযোগ্য কার্যকলাপ চালু করে।
যে অ্যাপগুলি স্পষ্টভাবে ম্যানিফেস্টে এই অ্যাট্রিবিউটটিকে false
সেট করে সেগুলি মাল্টি-উইন্ডো মোডে লঞ্চ করা উচিত নয়, যদি না সামঞ্জস্য মোড প্রয়োগ করা হয়:
- একই কনফিগারেশন প্রক্রিয়াটিতে প্রয়োগ করা হয়, যাতে সমস্ত ক্রিয়াকলাপ এবং নন-অ্যাক্টিভিটি উপাদান রয়েছে।
- প্রয়োগকৃত কনফিগারেশন অ্যাপ-সামঞ্জস্যপূর্ণ প্রদর্শনের জন্য CDD প্রয়োজনীয়তা পূরণ করে।
অ্যান্ড্রয়েড 10-এ, প্ল্যাটফর্মটি এখনও অ-আকারযোগ্য ক্রিয়াকলাপগুলিকে স্প্লিট-স্ক্রিন মোডে যেতে বাধা দেয়, তবে যদি কার্যকলাপটি একটি নির্দিষ্ট অভিযোজন বা দিক অনুপাত ঘোষণা করে থাকে তবে সেগুলি সাময়িকভাবে স্কেল করা যেতে পারে। যদি তা না হয়, তাহলে অ্যানড্রয়েড 9 এবং তার নিচের স্ক্রিনগুলির মতো পুরো স্ক্রিনটি পূরণ করার জন্য অ্যাক্টিভিটির আকার পরিবর্তন করা হয়।
ডিফল্ট বাস্তবায়ন নিম্নলিখিত নীতি প্রয়োগ করে:
android:resizeableActivity
অ্যাট্রিবিউট ব্যবহারের মাধ্যমে যখন কোনো অ্যাক্টিভিটি মাল্টি-উইন্ডোর সাথে বেমানান বলে ঘোষণা করা হয় এবং যখন সেই অ্যাক্টিভিটি নিচে বর্ণিত শর্তগুলির একটি পূরণ করে, তখন যখন প্রয়োগ করা স্ক্রিন কনফিগারেশন পরিবর্তন করতে হবে, তখন অ্যাক্টিভিটি এবং প্রক্রিয়াটি মূল কনফিগারেশনের সাথে সংরক্ষিত হয়। এবং ব্যবহারকারীকে আপডেট করা স্ক্রিন কনফিগারেশন ব্যবহার করার জন্য অ্যাপ প্রক্রিয়াটি পুনরায় চালু করার জন্য একটি সামর্থ্য প্রদান করা হয়।
-
android:screenOrientation
অ্যাপ্লিকেশনের মাধ্যমে স্থির অভিযোজন - এপিআই লেভেলকে টার্গেট করে অ্যাপে ডিফল্ট সর্বোচ্চ বা ন্যূনতম আকৃতির অনুপাত রয়েছে বা আকৃতির অনুপাত স্পষ্টভাবে ঘোষণা করে
এই চিত্রটি একটি ঘোষিত আকৃতির অনুপাত সহ একটি অ-আকারযোগ্য কার্যকলাপ প্রদর্শন করে৷ ডিভাইসটি ভাঁজ করার সময়, উপযুক্ত লেটারবক্সিং ব্যবহার করে দৃষ্টিভঙ্গি অনুপাত বজায় রেখে এলাকাটি ফিট করার জন্য উইন্ডোটি ছোট করা হয়। উপরন্তু, প্রতিবার ক্রিয়াকলাপের জন্য ডিসপ্লে এরিয়া পরিবর্তন করার সময় ব্যবহারকারীকে একটি রিস্টার্ট অ্যাক্টিভিটি বিকল্প প্রদান করা হয়।
ডিভাইসটি উন্মোচন করার সময়, ক্রিয়াকলাপের কনফিগারেশন, আকার এবং আকৃতির অনুপাত পরিবর্তন হয় না, তবে কার্যকলাপটি পুনরায় চালু করার বিকল্পটি প্রদর্শিত হয়।
যখন resizeableActivity
সেট করা হয় না (অথবা এটি true
সেট করা হয়), অ্যাপটি সম্পূর্ণরূপে আকার পরিবর্তনকে সমর্থন করে।
বাস্তবায়ন
স্থির অভিযোজন বা আকৃতির অনুপাত সহ একটি অ-আবর্তনযোগ্য কার্যকলাপকে কোডে আকার সামঞ্জস্য মোড (SCM) বলা হয়। শর্তটি ActivityRecord#shouldUseSizeCompatMode()
এ সংজ্ঞায়িত করা হয়েছে। যখন একটি SCM কার্যকলাপ চালু করা হয়, স্ক্রীন-সম্পর্কিত কনফিগারেশন (যেমন আকার বা ঘনত্ব) অনুরোধ করা ওভাররাইড কনফিগারেশনে স্থির করা হয়, তাই কার্যকলাপটি আর বর্তমান প্রদর্শন কনফিগারেশনের উপর নির্ভর করে না।
যদি SCM অ্যাক্টিভিটি পুরো স্ক্রিনটি পূরণ করতে না পারে, তাহলে এটি শীর্ষ সারিবদ্ধ এবং অনুভূমিকভাবে কেন্দ্রীভূত হয়। কার্যকলাপের সীমা AppWindowToken#calculateCompatBoundsTransformation()
দ্বারা গণনা করা হয়।
যখন একটি SCM অ্যাক্টিভিটি তার কন্টেইনার থেকে আলাদা স্ক্রিন কনফিগারেশন ব্যবহার করে (উদাহরণস্বরূপ, ডিসপ্লেটির আকার পরিবর্তন করা হয়, বা কার্যকলাপ অন্য ডিসপ্লেতে সরানো হয়), ActivityRecord#inSizeCompatMode()
সত্য হয় এবং SizeCompatModeActivityController
(সিস্টেম UI-তে) প্রক্রিয়াটি দেখানোর জন্য কলব্যাক গ্রহণ করে রিস্টার্ট বোতাম।
ডিসপ্লে মাপ এবং আকৃতির অনুপাত
Android 10 দীর্ঘ এবং পাতলা স্ক্রিনের উচ্চ অনুপাত থেকে 1:1 অনুপাতের নতুন অনুপাতের জন্য সমর্থন প্রদান করে। অ্যাপগুলি স্ক্রীনের ApplicationInfo#maxAspectRatio
এবং ApplicationInfo#minAspectRatio
সংজ্ঞায়িত করতে পারে যা তারা পরিচালনা করতে সক্ষম।
চিত্র 1. Android 10-এ সমর্থিত অ্যাপ অনুপাতের উদাহরণ
ডিভাইস বাস্তবায়নে Android 9 এর প্রয়োজনের চেয়ে ছোট আকার এবং রেজোলিউশন সহ সেকেন্ডারি ডিসপ্লে থাকতে পারে এবং কম (সর্বনিম্ন 2.5 ইঞ্চি প্রস্থ বা উচ্চতা, সর্বনিম্ন 320 ডিপি smallestScreenWidth
জন্য), তবে শুধুমাত্র এই ছোট ডিসপ্লেগুলিকে সমর্থন করার জন্য বেছে নেওয়া কার্যকলাপগুলি হতে পারে সেখানে স্থাপন করা হয়।
লক্ষ্য প্রদর্শনের আকারের চেয়ে ছোট বা সমান একটি ন্যূনতম সমর্থিত আকার ঘোষণা করে অ্যাপগুলি নির্বাচন করতে পারে৷ এটি করতে AndroidManifest-এ android:minHeight
এবং android:minWidth
কার্যকলাপ লেআউট বৈশিষ্ট্যগুলি ব্যবহার করুন৷
প্রদর্শন নীতি
অ্যান্ড্রয়েড 10 PhoneWindowManager
ডিফল্ট WindowManagerPolicy
ইমপ্লিমেন্টেশন থেকে ডিসপ্লে প্রতি ক্লাসে নির্দিষ্ট ডিসপ্লে নীতিগুলিকে আলাদা করে এবং সরিয়ে দেয়, যেমন:
- প্রদর্শনের অবস্থা এবং ঘূর্ণন
- কিছু কী এবং মোশন ইভেন্ট ট্র্যাকিং
- সিস্টেম UI এবং সজ্জা উইন্ডো
অ্যান্ড্রয়েড 9 (এবং নিম্নতর) তে, PhoneWindowManager
ক্লাস ডিসপ্লে নীতি, অবস্থা এবং সেটিংস, ঘূর্ণন, সজ্জা উইন্ডো ফ্রেম ট্র্যাকিং এবং আরও অনেক কিছু পরিচালনা করে। অ্যান্ড্রয়েড 10 এর বেশিরভাগই DisplayPolicy
ক্লাসে নিয়ে যায়, রোটেশন ট্র্যাকিং বাদে, যা DisplayRotation
সরানো হয়েছে।
উইন্ডো সেটিংস প্রদর্শন করুন
অ্যান্ড্রয়েড 10-এ, কনফিগারযোগ্য প্রতি-ডিসপ্লে উইন্ডো সেটিংটি অন্তর্ভুক্ত করার জন্য প্রসারিত করা হয়েছে:
- ডিফল্ট প্রদর্শন উইন্ডো মোড
- ওভারস্ক্যান মান
- ব্যবহারকারীর ঘূর্ণন এবং ঘূর্ণন মোড
- জোরপূর্বক আকার, ঘনত্ব, এবং স্কেলিং মোড
- বিষয়বস্তু অপসারণ মোড (যখন প্রদর্শন সরানো হয়)
- সিস্টেম সজ্জা এবং IME জন্য সমর্থন
DisplayWindowSettings
ক্লাসে এই বিকল্পগুলির জন্য সেটিংস রয়েছে। প্রতিবার সেটিং পরিবর্তন করার সময় display_settings.xml
এ /data
পার্টিশনে ডিস্কে এগুলি বজায় থাকে। বিস্তারিত জানার জন্য, DisplayWindowSettings.AtomicFileStorage
এবং DisplayWindowSettings#writeSettings()
দেখুন। ডিভাইস নির্মাতারা তাদের ডিভাইস কনফিগারেশনের জন্য display_settings.xml
এ ডিফল্ট মান প্রদান করতে পারে। যাইহোক, যেহেতু ফাইলটি /data
এ সংরক্ষিত আছে, তাই মুছে ফেলা হলে ফাইলটি পুনরুদ্ধার করার জন্য অতিরিক্ত যুক্তির প্রয়োজন হতে পারে।
ডিফল্টরূপে, Android 10 সেটিংস বজায় রাখার সময় একটি প্রদর্শনের জন্য একটি শনাক্তকারী হিসাবে DisplayInfo#uniqueId
ব্যবহার করে। uniqueId
সমস্ত প্রদর্শনের জন্য পপুলেট করা উচিত। উপরন্তু, এটি শারীরিক এবং নেটওয়ার্ক প্রদর্শনের জন্য স্থিতিশীল। শনাক্তকারী হিসাবে একটি শারীরিক প্রদর্শনের পোর্ট ব্যবহার করাও সম্ভব, যা DisplayWindowSettings#mIdentifier
এ সেট করা যেতে পারে। প্রতিটি লেখার উপর, সমস্ত সেটিংস লেখা থাকে তাই স্টোরেজের প্রদর্শন এন্ট্রির জন্য ব্যবহৃত কী আপডেট করা নিরাপদ। বিস্তারিত জানার জন্য, স্ট্যাটিক ডিসপ্লে শনাক্তকারী দেখুন।
ঐতিহাসিক কারণে /data
ডিরেক্টরিতে সেটিংস টিকে থাকে। মূলত, তারা ব্যবহারকারী-সেট সেটিংস, যেমন ডিসপ্লে রোটেশন বজায় রাখতে ব্যবহার করা হয়েছিল।
স্ট্যাটিক ডিসপ্লে শনাক্তকারী
অ্যান্ড্রয়েড 9 (এবং নিম্ন) ফ্রেমওয়ার্কের প্রদর্শনের জন্য স্থিতিশীল শনাক্তকারী প্রদান করেনি। যখন সিস্টেমে একটি ডিসপ্লে যোগ করা হয়, তখন একটি স্ট্যাটিক কাউন্টার বৃদ্ধি করে সেই ডিসপ্লের জন্য Display#mDisplayId
বা DisplayInfo#displayId
তৈরি করা হয়। যদি সিস্টেম একই ডিসপ্লে যোগ করে এবং সরিয়ে দেয়, তাহলে একটি ভিন্ন আইডি ফলাফল হবে।
যদি একটি ডিভাইসে বুট থেকে একাধিক ডিসপ্লে উপলব্ধ থাকে, তবে সময়ের উপর নির্ভর করে প্রদর্শনগুলিকে বিভিন্ন শনাক্তকারী বরাদ্দ করা যেতে পারে। যদিও অ্যান্ড্রয়েড 9 (এবং পূর্ববর্তী) DisplayInfo#uniqueId
অন্তর্ভুক্ত করে, এতে ডিসপ্লেগুলির মধ্যে পার্থক্য করার জন্য যথেষ্ট তথ্য ছিল না কারণ শারীরিক প্রদর্শনগুলিকে local:0
বা local:1
হিসাবে চিহ্নিত করা হয়েছিল, অন্তর্নির্মিত এবং বাহ্যিক প্রদর্শনের প্রতিনিধিত্ব করতে।
Android 10 একটি স্থিতিশীল শনাক্তকারী যোগ করতে এবং স্থানীয়, নেটওয়ার্ক এবং ভার্চুয়াল প্রদর্শনের মধ্যে পার্থক্য করতে DisplayInfo#uniqueId
পরিবর্তন করে।
প্রদর্শনের ধরন | বিন্যাস |
---|---|
স্থানীয় | local:<stable-id> |
নেটওয়ার্ক | network:<mac-address> |
ভার্চুয়াল | virtual:<package-name-and-name> |
uniqueId
এর আপডেট ছাড়াও, DisplayInfo.address
DisplayAddress
রয়েছে, একটি ডিসপ্লে শনাক্তকারী যা রিবুট জুড়ে স্থিতিশীল। Android 10-এ, DisplayAddress
ফিজিক্যাল এবং নেটওয়ার্ক ডিসপ্লে সমর্থন করে। DisplayAddress.Physical
একটি স্থিতিশীল ডিসপ্লে আইডি রয়েছে ( uniqueId
মতো) এবং DisplayAddress#fromPhysicalDisplayId()
দিয়ে তৈরি করা যেতে পারে।
Android 10 পোর্টের তথ্য পেতে একটি সুবিধাজনক পদ্ধতিও প্রদান করে ( Physical#getPort()
)। এই পদ্ধতিটি স্থিরভাবে ডিসপ্লে সনাক্ত করতে ফ্রেমওয়ার্কের মধ্যে ব্যবহার করা যেতে পারে। উদাহরণস্বরূপ, এটি DisplayWindowSettings
এ ব্যবহৃত হয়)। DisplayAddress.Network
MAC ঠিকানা থাকে এবং DisplayAddress#fromMacAddress()
দিয়ে তৈরি করা যায়।
এই সংযোজনগুলি ডিভাইস নির্মাতাদের স্ট্যাটিক মাল্টি-ডিসপ্লে সেট-আপে ডিসপ্লে শনাক্ত করতে এবং স্ট্যাটিক ডিসপ্লে আইডেন্টিফায়ার ব্যবহার করে বিভিন্ন সিস্টেম সেটিংস এবং বৈশিষ্ট্যগুলি কনফিগার করতে দেয়, যেমন ফিজিক্যাল ডিসপ্লেগুলির জন্য পোর্ট। এই পদ্ধতিগুলি লুকানো এবং শুধুমাত্র system_server
মধ্যে ব্যবহার করার উদ্দেশ্যে।
একটি HWC ডিসপ্লে আইডি দেওয়া (যা অস্বচ্ছ হতে পারে এবং সবসময় স্থিতিশীল নয়), এই পদ্ধতিটি (প্ল্যাটফর্ম-নির্দিষ্ট) 8-বিট পোর্ট নম্বর প্রদান করে যা ডিসপ্লে আউটপুটের জন্য একটি ফিজিক্যাল কানেক্টর, সেইসাথে ডিসপ্লের EDID ব্লবকে চিহ্নিত করে। সারফেসফ্লিংগার ফ্রেমওয়ার্কের সাথে উন্মুক্ত স্থিতিশীল 64-বিট ডিসপ্লে আইডি তৈরি করতে EDID থেকে নির্মাতা বা মডেলের তথ্য বের করে। যদি এই পদ্ধতিটি সমর্থিত না হয় বা ত্রুটিগুলি আউট হয়, তাহলে SurfaceFlinger লিগ্যাসি MD মোডে ফিরে আসে, যেখানে DisplayInfo#address
null এবং DisplayInfo#uniqueId
হার্ড-কোডেড, যেমন উপরে বর্ণিত হয়েছে।
এই বৈশিষ্ট্যটি সমর্থিত তা যাচাই করতে, চালান:
$ dumpsys SurfaceFlinger --display-id # Example output. Display 21691504607621632 (HWC display 0): port=0 pnpId=SHP displayName="LQ123P1JX32" Display 9834494747159041 (HWC display 2): port=1 pnpId=HWP displayName="HP Z24i" Display 1886279400700944 (HWC display 1): port=2 pnpId=AUS displayName="ASUS MB16AP"
দুটির বেশি ডিসপ্লে ব্যবহার করুন
অ্যান্ড্রয়েড 9 (এবং নিম্নতর), সারফেসফ্লিংগার এবং DisplayManagerService
হার্ড-কোডেড আইডি 0 এবং 1 সহ সর্বাধিক দুটি শারীরিক প্রদর্শনের অস্তিত্ব ধরে নিয়েছে।
অ্যান্ড্রয়েড 10 দিয়ে শুরু করে, সারফেসফ্লিঙ্গার একটি হার্ডওয়্যার কম্পোজার (HWC) API স্থিতিশীল ডিসপ্লে আইডি তৈরি করতে পারে, যা এটিকে একটি নির্বিচারে শারীরিক প্রদর্শন পরিচালনা করতে সক্ষম করে। আরও জানতে, স্ট্যাটিক ডিসপ্লে শনাক্তকারী দেখুন।
কাঠামোটি SurfaceControl#getPhysicalDisplayToken
মাধ্যমে SurfaceControl#getPhysicalDisplayIds
বা একটি DisplayEventReceiver
হটপ্লাগ ইভেন্ট থেকে 64-বিট ডিসপ্লে আইডি পাওয়ার পরে একটি ফিজিক্যাল ডিসপ্লের জন্য IBinder
টোকেন দেখতে পারে।
অ্যান্ড্রয়েড 10 (এবং নিম্নতর) এ, প্রাথমিক অভ্যন্তরীণ ডিসপ্লে হল TYPE_INTERNAL
এবং সমস্ত সেকেন্ডারি ডিসপ্লেগুলি সংযোগের প্রকার নির্বিশেষে TYPE_EXTERNAL
হিসাবে পতাকাঙ্কিত। অতএব, অতিরিক্ত অভ্যন্তরীণ প্রদর্শনগুলি বহিরাগত হিসাবে বিবেচিত হয়। একটি সমাধান হিসাবে, ডিভাইস-নির্দিষ্ট কোড DisplayAddress.Physical#getPort
সম্পর্কে অনুমান করতে পারে যদি HWC পরিচিত হয় এবং পোর্ট বরাদ্দের যুক্তি অনুমানযোগ্য হয়।
এই সীমাবদ্ধতা Android 11 (এবং উচ্চতর) এ সরানো হয়েছে।
- অ্যান্ড্রয়েড 11-এ, বুটের সময় রিপোর্ট করা প্রথম ডিসপ্লে হল প্রাথমিক ডিসপ্লে। সংযোগের ধরন (অভ্যন্তরীণ বনাম বাহ্যিক) অপ্রাসঙ্গিক। যাইহোক, এটি সত্য যে প্রাথমিক প্রদর্শনটি সংযোগ বিচ্ছিন্ন করা যাবে না এবং অনুসরণ করে যে এটি অবশ্যই একটি অভ্যন্তরীণ প্রদর্শন হতে হবে। মনে রাখবেন কিছু ভাঁজযোগ্য ফোনে একাধিক অভ্যন্তরীণ ডিসপ্লে থাকে।
- সেকেন্ডারি ডিসপ্লেগুলিকে সঠিকভাবে
Display.TYPE_INTERNAL
বাDisplay.TYPE_EXTERNAL
(পূর্বে যথাক্রমেDisplay.TYPE_BUILT_IN
এবংDisplay.TYPE_HDMI
নামে পরিচিত) হিসাবে শ্রেণীবদ্ধ করা হয়েছে তাদের সংযোগের প্রকারের উপর নির্ভর করে।
বাস্তবায়ন
অ্যান্ড্রয়েড 9 এবং তার চেয়ে কম সময়ে, ডিসপ্লেগুলিকে 32-বিট আইডি দ্বারা চিহ্নিত করা হয়, যেখানে 0 হল অভ্যন্তরীণ ডিসপ্লে, 1 হল বাহ্যিক ডিসপ্লে, [2, INT32_MAX]
হল HWC ভার্চুয়াল ডিসপ্লে, এবং -1 একটি অবৈধ ডিসপ্লে বা একটি নন-HWC প্রতিনিধিত্ব করে ভার্চুয়াল প্রদর্শন।
অ্যান্ড্রয়েড 10 দিয়ে শুরু করে, ডিসপ্লেগুলিকে স্থিতিশীল এবং অবিরাম আইডি দেওয়া হয়, যা সারফেসফ্লিংগার এবং DisplayManagerService
দুটির বেশি ডিসপ্লে ট্র্যাক করতে এবং পূর্বে দেখা ডিসপ্লেগুলিকে চিনতে দেয়৷ যদি HWC IComposerClient.getDisplayIdentificationData
সমর্থন করে এবং ডিসপ্লে আইডেন্টিফিকেশন ডেটা প্রদান করে, SurfaceFlinger EDID স্ট্রাকচার পার্স করে এবং ফিজিক্যাল এবং HWC ভার্চুয়াল ডিসপ্লের জন্য স্থিতিশীল 64-বিট ডিসপ্লে আইডি বরাদ্দ করে। আইডিগুলি একটি বিকল্প প্রকার ব্যবহার করে প্রকাশ করা হয়, যেখানে নাল মানটি একটি অবৈধ প্রদর্শন বা অ-HWC ভার্চুয়াল প্রদর্শনকে উপস্থাপন করে। HWC সমর্থন ছাড়া, SurfaceFlinger সর্বাধিক দুটি শারীরিক প্রদর্শনের সাথে উত্তরাধিকারী আচরণে ফিরে আসে।
প্রতি-ডিসপ্লে ফোকাস
একাধিক ইনপুট উত্স সমর্থন করতে যা একই সময়ে পৃথক প্রদর্শনকে লক্ষ্য করে, Android 10 একাধিক ফোকাসযুক্ত উইন্ডো সমর্থন করার জন্য কনফিগার করা যেতে পারে, প্রতি-ডিসপ্লেতে সর্বাধিক একটি। এটি শুধুমাত্র বিশেষ ধরনের ডিভাইসের জন্য উদ্দিষ্ট যখন একাধিক ব্যবহারকারী একই ডিভাইসের সাথে একই সময়ে ইন্টারঅ্যাক্ট করে এবং বিভিন্ন ইনপুট পদ্ধতি বা ডিভাইস ব্যবহার করে, যেমন Android Automotive।
এটি দৃঢ়ভাবে সুপারিশ করা হয় যে মাল্টি-স্ক্রীন ডিভাইস বা ডেস্কটপের মতো অভিজ্ঞতার জন্য ব্যবহার করা সহ নিয়মিত ডিভাইসগুলির জন্য এই বৈশিষ্ট্যটি সক্ষম করা যাবে না । এটি প্রাথমিকভাবে একটি নিরাপত্তা উদ্বেগের কারণে যা ব্যবহারকারীদের মনে হতে পারে কোন উইন্ডোতে ইনপুট ফোকাস আছে।
কল্পনা করুন যে ব্যবহারকারী একটি পাঠ্য ইনপুট ক্ষেত্রে সুরক্ষিত তথ্য প্রবেশ করান, সম্ভবত একটি ব্যাঙ্কিং অ্যাপে লগ ইন করছেন বা সংবেদনশীল তথ্য রয়েছে এমন পাঠ্য প্রবেশ করান৷ একটি দূষিত অ্যাপ একটি ভার্চুয়াল অফ-স্ক্রিন ডিসপ্লে তৈরি করতে পারে যার সাহায্যে একটি পাঠ্য ইনপুট ক্ষেত্র সহ একটি কার্যকলাপ চালানো যায়৷ বৈধ এবং দূষিত ক্রিয়াকলাপের ফোকাস থাকে এবং উভয়ই একটি সক্রিয় ইনপুট সূচক (ব্লিঙ্কিং কার্সার) প্রদর্শন করে।
যাইহোক, যেহেতু একটি কীবোর্ড (হার্ডওয়্যার বা সফ্টওয়্যার) থেকে ইনপুট শুধুমাত্র শীর্ষস্থানীয় কার্যকলাপে প্রবেশ করা হয় (যে অ্যাপটি সম্প্রতি চালু হয়েছে), একটি লুকানো ভার্চুয়াল ডিসপ্লে তৈরি করে, একটি দূষিত অ্যাপ ব্যবহারকারীর ইনপুট দখল করতে পারে, এমনকি একটি সফ্টওয়্যার কীবোর্ড ব্যবহার করার সময়ও। প্রাথমিক ডিভাইস প্রদর্শনে।
প্রতি-ডিসপ্লে ফোকাস সেট করতে com.android.internal.R.bool.config_perDisplayFocusEnabled
ব্যবহার করুন।
সামঞ্জস্য
সমস্যা: অ্যান্ড্রয়েড 9 এবং তার চেয়ে কম সময়ে, সিস্টেমের সর্বাধিক একটি উইন্ডোতে ফোকাস থাকে৷
সমাধান: বিরল ক্ষেত্রে যখন একই প্রক্রিয়া থেকে দুটি উইন্ডো ফোকাস করা হবে, সিস্টেমটি শুধুমাত্র Z-ক্রমের উচ্চতর উইন্ডোতে ফোকাস প্রদান করে। এই বিধিনিষেধটি এমন অ্যাপগুলির জন্য সরানো হয়েছে যেগুলি Android 10 কে লক্ষ্য করে, সেই সময়ে এটি প্রত্যাশিত যে তারা একসাথে একাধিক উইন্ডোতে ফোকাস করা সমর্থন করতে পারে৷
বাস্তবায়ন
WindowManagerService#mPerDisplayFocusEnabled
এই বৈশিষ্ট্যের উপলব্ধতা নিয়ন্ত্রণ করে। ActivityManager
এ, ActivityDisplay#getFocusedStack()
এখন একটি ভেরিয়েবলে গ্লোবাল ট্র্যাকিংয়ের পরিবর্তে ব্যবহার করা হয়। ActivityDisplay#getFocusedStack()
মান ক্যাশে করার পরিবর্তে Z-অর্ডারের উপর ভিত্তি করে ফোকাস নির্ধারণ করে। এটি যাতে শুধুমাত্র একটি উৎস, WindowManager-এর কার্যক্রমের Z-ক্রম ট্র্যাক করা প্রয়োজন।
ActivityStackSupervisor#getTopDisplayFocusedStack()
সেই সব ক্ষেত্রে একই ধরনের পদ্ধতি গ্রহণ করে যখন সিস্টেমে সবচেয়ে বেশি ফোকাস করা স্ট্যাক চিহ্নিত করা আবশ্যক। স্ট্যাকগুলি প্রথম যোগ্য স্ট্যাকের জন্য অনুসন্ধান করে, উপরে থেকে নীচের দিকে যাত্রা করা হয়।
InputDispatcher
এখন একাধিক ফোকাস করা উইন্ডো থাকতে পারে (প্রতি প্রদর্শনে একটি)। যদি একটি ইনপুট ইভেন্ট ডিসপ্লে-নির্দিষ্ট হয়, তাহলে সেটি সংশ্লিষ্ট ডিসপ্লেতে ফোকাস করা উইন্ডোতে পাঠানো হয়। অন্যথায়, এটি ফোকাস করা ডিসপ্লেতে ফোকাস করা উইন্ডোতে পাঠানো হয়, যেটি হল সেই ডিসপ্লে যার সাথে ব্যবহারকারী সম্প্রতি ইন্টারঅ্যাক্ট করেছেন।
InputDispatcher::mFocusedWindowHandlesByDisplay
এবং InputDispatcher::setFocusedDisplay()
দেখুন। NativeInputManager::setFocusedApplication()
এর মাধ্যমে InputManagerService-এ ফোকাস করা অ্যাপগুলিও আলাদাভাবে আপডেট করা হয়।
WindowManager
এ, ফোকাস করা উইন্ডোগুলিও আলাদাভাবে ট্র্যাক করা হয়। DisplayContent#mCurrentFocus
এবং DisplayContent#mFocusedApp
এবং সংশ্লিষ্ট ব্যবহারগুলি দেখুন। সম্পর্কিত ফোকাস ট্র্যাকিং এবং আপডেট করার পদ্ধতি WindowManagerService
থেকে DisplayContent
এ সরানো হয়েছে।