ডিসপ্লে-নির্দিষ্ট এইসব জায়গায় করা আপডেট নিচে দেওয়া হল:
- অ্যাক্টিভিটি ও ডিসপ্লে ছোট-বড় করা
- ডিসপ্লে সাইজ ও অ্যাস্পেক্ট রেশিও
- ডিসপ্লে সংক্রান্ত নীতি
- ডিসপ্লে উইন্ডো সেটিংস
- স্ট্যাটিক ডিসপ্লে আইডেন্টিফায়ার
- দুটির বেশি ডিসপ্লে ব্যবহার করা
- ডিসপ্লে-প্রতি ফোকাস
অ্যাক্টিভিটি ও ডিসপ্লের সাইজ পরিবর্তন করা
কোনও অ্যাপ যে মাল্টি-উইন্ডো মোড বা সাইজ পরিবর্তন করার সুবিধা নাও দিতে পারে তা বোঝাতে,
অ্যাক্টিভিটি resizeableActivity=false অ্যাট্রিবিউট ব্যবহার করে। অ্যাক্টিভিটি ছোট বড় করার সময় অ্যাপে যেসব সাধারণ
সমস্যা দেখা যায়, তার মধ্যে রয়েছে:
- অ্যাপ বা অন্য কোনও নন-ভিজ্যুয়াল কম্পোনেন্টের থেকে অ্যাক্টিভিটির আলাদা কনফিগারেশন থাকতে পারে। অ্যাপের কনটেক্সট থেকে ডিসপ্লে মেট্রিক রিড করা একটি সাধারণ ভুল। যে অ্যাক্টিভিটি দেখানো হচ্ছে, সেটির দৃশ্যমান অংশের মেট্রিক্সের সাথে ফেরত পাওয়া ভ্যালু অ্যাডজাস্ট করা হবে না।
- কোনও অ্যাক্টিভিটি রিসাইজ করার বিষয়টি ম্যানেজ করতে না পারলে, সেটি ক্র্যাশ করতে পারে, বিকৃত UI দেখাতে পারে, অথবা ইনস্ট্যান্স স্টেট সেভ না করে রিলঞ্চ করার কারণে স্টেট হারিয়ে ফেলতে পারে।
- কোনও অ্যাপ অ্যাবসলিউট ইনপুট কোঅর্ডিনেট (উইন্ডোর পজিশনের তুলনায় রিলেটিভের পরিবর্তে) ব্যবহার করার চেষ্টা করতে পারে, যা মাল্টি-উইন্ডোতে ইনপুট ভেঙে দিতে পারে।
Android 7 (এবং এর পরবর্তী যেকোনও ভার্সনে), কোনও অ্যাপকে
resizeableActivity=false সবসময় ফুল-স্ক্রিন মোডে চালানোর জন্য সেট করা যেতে পারে। এই
ক্ষেত্রে, প্ল্যাটফর্মটি স্প্লিট স্ক্রিনে রিসাইজ করা যায় না এমন অ্যাক্টিভিটি
প্রতিরোধ করে। ব্যবহারকারী যদি স্প্লিট-স্ক্রিন মোডে থাকাকালীন লঞ্চার থেকে এমন কোনও অ্যাক্টিভিটি শুরু করার চেষ্টা করেন যা ছোট বড় করা যায় না, তাহলে প্ল্যাটফর্মটি স্প্লিট-স্ক্রিন মোড থেকে বেরিয়ে আসে এবং
ফুল-স্ক্রিন মোডে ছোট বড় করা যায় না এমন অ্যাক্টিভিটি লঞ্চ করে।
যেসব অ্যাপ ম্যানিফেস্টে এই অ্যাট্রিবিউটকে স্পষ্টভাবে false হিসেবে সেট করে, সেগুলিকে অবশ্যই মাল্টি-উইন্ডো মোডে লঞ্চ করা যাবে না, যতক্ষণ না মানানসই
মোড প্রয়োগ করা হয়:
- প্রসেসে একই কনফিগারেশন প্রয়োগ করা হয়, যার মধ্যে সব অ্যাক্টিভিটি ও নন-অ্যাক্টিভিটি কম্পোনেন্ট থাকে।
- প্রয়োগ করা কনফিগারেশন অ্যাপ-মানানসই ডিসপ্লের জন্য CDD সংক্রান্ত প্রয়োজনীয়তা পূরণ করে।
Android 10-এ, প্ল্যাটফর্ম এখনও ছোট বড় করা যায় না এমন অ্যাক্টিভিটিগুলিকে বিভক্ত-স্ক্রীন মোডে যেতে বাধা দেয়, তবে অ্যাক্টিভিটি যদি একটি নির্দিষ্ট ওরিয়েন্টেশন বা অ্যাস্পেক্ট রেশিও ঘোষণা করে থাকে তবে সেগুলি সাময়িকভাবে স্কেল করা যেতে পারে। তা না হলে, Android 9 ও তার আগের ভার্সনের মতো অ্যাক্টিভিটি রিসাইজ করে পুরো স্ক্রিন ভর্তি করে দেওয়া হয়।
ডিফল্ট প্রয়োগের ক্ষেত্রে নিম্নলিখিত নীতি প্রযোজ্য হয়:
android:resizeableActivity অ্যাট্রিবিউট ব্যবহার করে কোনও অ্যাক্টিভিটিকে মাল্টি-উইন্ডোর সাথে ইনকম্প্যাটিবল হিসেবে ঘোষণা করা হলে এবং সেই
অ্যাক্টিভিটি নিচে বর্ণিত শর্তগুলির মধ্যে একটি পূরণ করলে, প্রয়োগ করা
স্ক্রিন কনফিগারেশন অবশ্যই পরিবর্তন করতে হবে। সেক্ষেত্রে, অ্যাক্টিভিটি ও প্রসেসকে
মূল কনফিগারেশনের সাথে সেভ করা হয় এবং আপডেট করা স্ক্রিন কনফিগারেশন ব্যবহার করার জন্য
অ্যাপ প্রসেস আবার লঞ্চ করার সুবিধা ব্যবহারকারীকে দেওয়া হয়।
android:screenOrientation-এর অ্যাপ্লিকেশন ব্যবহার করে ওরিয়েন্টেশন ফিক্স করা হয়েছে- টার্গেট API লেভেল অনুসারে অ্যাপে ডিফল্ট সর্বাধিক বা সর্বনিম্ন অ্যাস্পেক্ট রেশিও আছে অথবা অ্যাপ স্পষ্টভাবে অ্যাস্পেক্ট রেশিও ঘোষণা করে
এই ছবিতে একটি অ্যাক্টিভিটি দেখানো হয়েছে যার সাইজ পরিবর্তন করা যায় না এবং যার অ্যাস্পেক্ট রেশিও উল্লেখ করা আছে। ডিভাইস ফোল্ড করলে, উইন্ডোটি উপযুক্ত লেটারবক্সিং ব্যবহার করে অ্যাস্পেক্ট রেশিও বজায় রেখে সেটি জায়গার সাথে মানানসই করার জন্য স্কেল করা হয়। এছাড়াও, অ্যাক্টিভিটির ডিসপ্লে এরিয়া পরিবর্তন করা হলে, ব্যবহারকারীকে প্রতিবারই অ্যাক্টিভিটি রিস্টার্ট করার বিকল্প দেওয়া হয়।
ডিভাইস আনফোল্ড করার সময়, অ্যাক্টিভিটির কনফিগারেশন, সাইজ ও অ্যাস্পেক্ট রেশিও পরিবর্তন হয় না, তবে অ্যাক্টিভিটি রিস্টার্ট করার বিকল্প দেখানো হয়।
resizeableActivity সেট করা না থাকলে (অথবা এটি
true হিসেবে সেট করা থাকলে), অ্যাপটি সম্পূর্ণভাবে রিসাইজ করার সুবিধা দেয়।
প্রয়োগ
ফিক্সড ওরিয়েন্টেশন বা অ্যাস্পেক্ট রেশিও সহ ছোট বড় করা যায় না এমন অ্যাক্টিভিটিকে
কোডে সাইজ কম্প্যাটিবিলিটি মোড (SCM) বলা হয়। এই শর্তটি
ActivityRecord#shouldUseSizeCompatMode()-এ উল্লেখ করা আছে। কোনও SCM অ্যাক্টিভিটি
লঞ্চ করা হলে, স্ক্রিন-সম্পর্কিত কনফিগারেশন (যেমন, সাইজ বা ডেনসিটি) অনুরোধ করা ওভাররাইড কনফিগারেশনে
ফিক্স করা হয়, তাই অ্যাক্টিভিটি আর বর্তমান ডিসপ্লে কনফিগারেশনের
উপর নির্ভরশীল থাকে না।
SCM অ্যাক্টিভিটি পুরো স্ক্রিন জুড়ে দেখাতে না পারলে, এটি উপরে অ্যালাইন করা হয় এবং
অনুভূমিকভাবে মাঝখানে দেখানো হয়। অ্যাক্টিভিটির সীমা
AppWindowToken#calculateCompatBoundsTransformation() দ্বারা গণনা করা হয়।
কোনও SCM অ্যাক্টিভিটি তার
কন্টেনারের থেকে আলাদা স্ক্রিন কনফিগারেশন ব্যবহার করলে (যেমন, ডিসপ্লের সাইজ পরিবর্তন করা হলে বা অ্যাক্টিভিটি অন্য
ডিসপ্লেতে সরানো হলে), ActivityRecord#inSizeCompatMode() true হয় এবং
SizeCompatModeActivityController (সিস্টেম UI-তে) প্রসেস রিস্টার্ট করার বোতাম দেখানোর জন্য
কলব্যাক পায়।
ডিসপ্লে সাইজ ও অ্যাস্পেক্ট রেশিও
Android 10, নতুন অ্যাস্পেক্ট রেশিওর জন্য সহায়তা প্রদান করে
১:১ রেশিও থেকে শুরু করে লম্বা ও সরু স্ক্রিনের হাই রেশিও পর্যন্ত। অ্যাপ ApplicationInfo#maxAspectRatio
এবং স্ক্রিনের ApplicationInfo#minAspectRatio
সংজ্ঞায়িত করতে পারে যা এটি
ম্যানেজ করতে পারে।

ছবি ১. Android-এ কাজ করে এমন অ্যাপের অনুপাতের উদাহরণ 10
ডিভাইস ইমপ্লিমেন্টেশনে Android 9-এর প্রয়োজনীয় সাইজ ও রেজোলিউশনের চেয়ে ছোট সাইজ ও রেজোলিউশনের
সেকেন্ডারি ডিসপ্লে থাকতে পারে এবং এর থেকে কম (ন্যূনতম ২.৫
ইঞ্চি প্রস্থ বা উচ্চতা, smallestScreenWidth-এর জন্য ন্যূনতম ৩২০ DP),
কিন্তু শুধুমাত্র সেইসব অ্যাক্টিভিটি এখানে প্লেস করা যাবে যেগুলি এই ছোট ডিসপ্লেতে কাজ করার জন্য অপ্ট-ইন করেছে।
টার্গেট ডিসপ্লে সাইজের থেকে ছোট বা সমান ন্যূনতম সাইজ ঘোষণা করে অ্যাপ অপ্ট-ইন করতে পারে। এর জন্য AndroidManifest-এ android:minHeight এবং
android:minWidth অ্যাক্টিভিটি লেআউট অ্যাট্রিবিউট
ব্যবহার করুন।
ডিসপ্লে নীতি
Android 10, নির্দিষ্ট ডিসপ্লে
পলিসিকে ডিফল্ট WindowManagerPolicy ইমপ্লিমেন্টেশন থেকে আলাদা করে
PhoneWindowManager ডিসপ্লে-পিছু ক্লাসে সরিয়ে দেয়, যেমন:
- ডিসপ্লেয়ের অবস্থা ও রোটেশন
- কিছু কী ও মোশন ইভেন্ট ট্র্যাকিং
- সিস্টেম UI ও ডেকরেশন উইন্ডো
Android 9 (এবং এর আগের যেকোনও ভার্সনে), PhoneWindowManager ক্লাস ডিসপ্লে পলিসি, স্টেট ও সেটিংস, রোটেশন, ডেকোরেশন উইন্ডো ফ্রেম
ট্র্যাকিং এবং আরও অনেক কিছু হ্যান্ডেল করে। Android 10-এ এর বেশিরভাগই
DisplayPolicy ক্লাসে সরানো হয়েছে, তবে রোটেট করা ট্র্যাক করার সুবিধা
DisplayRotation ক্লাসে সরানো হয়েছে।
ডিসপ্লে উইন্ডো সেটিংস
Android 10-এ, কনফিগার করা যায় এমন প্রতি-ডিসপ্লে উইন্ডোইং সেটিংকে আরও বড় করা হয়েছে যাতে এগুলি অন্তর্ভুক্ত করা যায়:
- ডিফল্ট ডিসপ্লে উইন্ডোইং মোড
- ওভারস্ক্যান ভ্যালু
- ব্যবহারকারী রোটেশন ও রোটেশন মোড
- বাধ্যতামূলক সাইজ, ঘনত্ব ও স্কেলিং মোড
- কন্টেন্ট সরিয়ে দেওয়ার মোড (ডিসপ্লে সরিয়ে দেওয়া হলে)
- সিস্টেম সজ্জা ও IME-এর জন্য সহায়তা
DisplayWindowSettings ক্লাসে এইসব
বিকল্পের সেটিংস থাকে। কোনও সেটিং পরিবর্তন করা হলে, সেগুলি /data পার্টিশনে
display_settings.xml ডিস্কে সেভ করা হয়। বিবরণের
জন্য, DisplayWindowSettings.AtomicFileStorage এবং
DisplayWindowSettings#writeSettings() দেখুন। ডিভাইস প্রস্তুতকারক
তাদের ডিভাইস
কনফিগারেশনের জন্য display_settings.xml-এ ডিফল্ট ভ্যালু প্রদান করতে পারেন। তবে, ফাইলটি /data-এ সেভ করা থাকার কারণে,
ওয়াইপ করার মাধ্যমে মুছে দেওয়া হলে, ফাইলটি ফিরিয়ে আনার জন্য অতিরিক্ত লজিক প্রয়োজন হতে পারে।
ডিফল্ট হিসেবে, Android 10, সেটিংস সেভ করার সময় ডিসপ্লের জন্য
DisplayInfo#uniqueId-কে
আইডেন্টিফায়ার হিসেবে ব্যবহার করে। সব ডিসপ্লের জন্য uniqueId পূরণ করতে হবে। এছাড়াও, এটি ফিজিক্যাল ও নেটওয়ার্ক ডিসপ্লের জন্য স্টেবল। এছাড়াও, শনাক্তকারী হিসেবে ফিজিক্যাল ডিসপ্লের পোর্ট ব্যবহার করা যেতে পারে, যা
DisplayWindowSettings#mIdentifier-এ সেট করা যেতে পারে।
প্রতিটি লেখার পরে, সব সেটিংস
লেখা হয়, তাই স্টোরেজে
ডিসপ্লে এন্ট্রির জন্য ব্যবহৃত কী আপডেট করা নিরাপদ। আরও বিবরণের জন্য, স্ট্যাটিক ডিসপ্লে শনাক্তকারী দেখুন।
ঐতিহাসিক কারণে /data ডিরেক্টরিতে সেটিংস সেভ করা থাকে।
মূলত, এগুলি ব্যবহারকারীর সেট করা সেটিংস, যেমন
ডিসপ্লে রোটেশন সেভ করে রাখার জন্য ব্যবহার করা হত।
স্ট্যাটিক ডিসপ্লে শনাক্তকারী
Android 9 (এবং এর আগের যেকোনও ভার্সন)
ফ্রেমওয়ার্কে ডিসপ্লের জন্য স্থিতিশীল শনাক্তকারী প্রদান করে না। সিস্টেমে কোনও ডিসপ্লে যোগ করা হলে,
Display#mDisplayId বা DisplayInfo#displayId-এর জন্য একটি স্ট্যাটিক কাউন্টার ইনক্রিমেন্ট করে
সেই ডিসপ্লে তৈরি করা হয়। সিস্টেম
একই ডিসপ্লে যোগ ও সরিয়ে দিলে, আলাদা আইডি তৈরি হয়।
কোনও ডিভাইসে বুট করার সময় একাধিক ডিসপ্লে উপলভ্য থাকলে, টাইমিংয়ের উপর নির্ভর করে ডিসপ্লেগুলিকে
আলাদা আলাদা শনাক্তকারী অ্যাসাইন করা হতে পারে। Android 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 ডিসপ্লে আইডি (যা অপেক হতে পারে এবং সবসময় স্থিতিশীল নাও হতে পারে) দেওয়া থাকলে, এই
মেথডটি (প্ল্যাটফর্ম-নির্দিষ্ট) ৮-বিট পোর্ট নম্বর রিটার্ন করে যা ডিসপ্লে আউটপুটের জন্য
ফিজিক্যাল কানেক্টরকে শনাক্ত করে, সেইসাথে ডিসপ্লের EDID ব্লবও রিটার্ন করে।
SurfaceFlinger, ফ্রেমওয়ার্কে এক্সপোজ করা স্থিতিশীল ৬৪-বিট ডিসপ্লে আইডি জেনারেট করতে
EDID থেকে প্রস্তুতকারক বা মডেল সংক্রান্ত তথ্য এক্সট্র্যাক্ট করে। এই পদ্ধতি
কাজ না করলে বা কোনও সমস্যা হলে, SurfaceFlinger পুরনো MD মোডে ফিরে যায়,
যেখানে DisplayInfo#address নাল এবং
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"
দুটির বেশি ডিসপ্লে ব্যবহার করা
Android 9 (এবং তার আগের ভার্সনে), SurfaceFlinger এবং DisplayManagerService
হার্ড-কোডেড আইডি 0 এবং 1 সহ সর্বাধিক দুটি ফিজিক্যাল ডিসপ্লের অস্তিত্ব অনুমান করে।
Android 10 থেকে শুরু করে, SurfaceFlinger স্থিতিশীল ডিসপ্লে আইডি তৈরি করতে হার্ডওয়্যার কম্পোজার (HWC) API ব্যবহার করতে পারে, যা এটিকে যেকোনও সংখ্যক ফিজিক্যাল ডিসপ্লে ম্যানেজ করতে সক্ষম করে। আরও জানতে, স্ট্যাটিক ডিসপ্লে আইডেন্টিফায়ার দেখুন।
SurfaceControl#getPhysicalDisplayIds বা DisplayEventReceiver হটপ্লাগ ইভেন্ট থেকে ৬৪-বিট ডিসপ্লে আইডি পাওয়ার পরে,
ফ্রেমওয়ার্ক SurfaceControl#getPhysicalDisplayToken-এর মাধ্যমে ফিজিক্যাল ডিসপ্লের জন্য
IBinder টোকেন খুঁজতে পারে।
Android 10 (এবং এর আগের যেকোনও ভার্সনে), প্রাথমিক ইন্টার্নাল ডিসপ্লে হল
TYPE_INTERNAL এবং কানেকশনের ধরন নির্বিশেষে সমস্ত সেকেন্ডারি ডিসপ্লেকে TYPE_EXTERNAL
হিসেবে ফ্ল্যাগ করা হয়। তাই, অতিরিক্ত ইন্টার্নাল ডিসপ্লেকে এক্সটার্নাল হিসেবে বিবেচনা করা হয়।
সমাধান হিসেবে, ডিভাইস-নির্দিষ্ট কোড
DisplayAddress.Physical#getPort-এর ব্যাপারে অনুমান করতে পারে, যদি HWC জানা থাকে এবং পোর্ট অ্যালোকেশন লজিক অনুমান করা যায়।
Android 11 (এবং এর পরের যেকোনও ভার্সনে) এই সীমাবদ্ধতা সরিয়ে দেওয়া হয়েছে।
- Android 11-এ, বুট করার সময় প্রথম যে ডিসপ্লে রিপোর্ট করা হয় সেটি হল প্রাইমারি ডিসপ্লে। কানেকশনের ধরন (ইন্টার্নাল বনাম এক্সটার্নাল) অপ্রাসঙ্গিক। তবে, এটি সত্য যে প্রাথমিক ডিসপ্লে ডিসকানেক্ট করা যাবে না এবং এর থেকে বোঝা যায় যে এটি অবশ্যই ইন্টার্নাল ডিসপ্লে হতে হবে। মনে রাখবেন, কিছু ফোল্ড করা যায় এমন ফোনে একাধিক ইন্টার্নাল ডিসপ্লে থাকে।
- সেকেন্ডারি ডিসপ্লেকে তাদের কানেকশনের ধরন অনুযায়ী
Display.TYPE_INTERNALবাDisplay.TYPE_EXTERNAL(আগে যথাক্রমেDisplay.TYPE_BUILT_INওDisplay.TYPE_HDMIনামে পরিচিত ছিল) হিসেবে সঠিকভাবে শ্রেণীবদ্ধ করা হয়েছে।
প্রয়োগ
Android 9 এবং এর আগের যেকোনও ভার্সনে, ডিসপ্লেগুলিকে ৩২-বিট আইডি দ্বারা শনাক্ত করা হয়,
যেখানে ০ হল ইন্টার্নাল ডিসপ্লে, ১ হল এক্সটার্নাল ডিসপ্লে, [2, INT32_MAX]
হল HWC ভার্চুয়াল ডিসপ্লে এবং -১ হল একটি অবৈধ ডিসপ্লে বা নন-HWC ভার্চুয়াল ডিসপ্লে।
Android 10 থেকে শুরু করে, ডিসপ্লেগুলিকে স্থিতিশীল
এবং স্থায়ী আইডি দেওয়া হয়, যা SurfaceFlinger এবং DisplayManagerService
দুটির বেশি ডিসপ্লে ট্র্যাক করতে এবং আগে দেখা ডিসপ্লে শনাক্ত করতে দেয়। HWC
IComposerClient.getDisplayIdentificationData সাপোর্ট করলে এবং ডিসপ্লে শনাক্তকরণ ডেটা প্রদান করলে, SurfaceFlinger, EDID স্ট্রাকচার পার্স করে এবং ফিজিক্যাল ও HWC ভার্চুয়াল ডিসপ্লের জন্য স্টেবল
৬৪-বিট ডিসপ্লে আইডি বরাদ্দ করে। ID-গুলি একটি বিকল্পের ধরন ব্যবহার করে প্রকাশ করা হয়, যেখানে শূন্য মান একটি ভুল ডিসপ্লে বা নন-HWC ভার্চুয়াল
ডিসপ্লেকে বোঝায়। HWC সহায়তা না থাকলে, SurfaceFlinger সর্বাধিক দুটি ফিজিক্যাল ডিসপ্লে সহ পুরনো আচরণে ফিরে আসে।
প্রতিটি ডিসপ্লেতে ফোকাস
একই সময়ে আলাদা আলাদা ডিসপ্লে টার্গেট করে এমন একাধিক ইনপুট সোর্সকে সাপোর্ট করার জন্য, Android 10-কে একাধিক ফোকাস করা উইন্ডোকে সাপোর্ট করার জন্য কনফিগার করা যেতে পারে, প্রতি ডিসপ্লেতে সর্বাধিক একটি। এটি শুধুমাত্র বিশেষ ধরনের ডিভাইসের জন্য তৈরি করা হয়েছে, যেখানে একাধিক ব্যবহারকারী একই সময়ে একই ডিভাইসের সাথে ইন্টার্যাক্ট করেন এবং বিভিন্ন ইনপুট পদ্ধতি বা ডিভাইস ব্যবহার করেন, যেমন Android Automotive।
মাল্টি-স্ক্রিন ডিভাইস বা ডেস্কটপের মতো অভিজ্ঞতা প্রদানকারী ডিভাইস সহ সাধারণ ডিভাইসের জন্য এই ফিচার চালু না করার জন্য বিশেষভাবে সাজেস্ট করা হয়। এটি মূলত নিরাপত্তা সংক্রান্ত উদ্বেগের কারণে হয়, যার ফলে ব্যবহারকারীরা কোন উইন্ডোতে ইনপুট ফোকাস আছে তা নিয়ে বিভ্রান্ত হতে পারেন।
সেইসব ব্যবহারকারীর কথা ভাবুন যারা টেক্সট ইনপুট ফিল্ডে সুরক্ষিত তথ্য লিখছেন, যেমন, হয়ত কোনও ব্যাঙ্কিং অ্যাপে লগ-ইন করছেন অথবা সংবেদনশীল তথ্য লিখছেন। ক্ষতিকর অ্যাপ ভার্চুয়াল অফ-স্ক্রিন ডিসপ্লে তৈরি করতে পারে যার মাধ্যমে অ্যাক্টিভিটি চালানো যায়, এছাড়াও টেক্সট ইনপুট ফিল্ডও থাকে। বৈধ ও ক্ষতিকর অ্যাক্টিভিটির উপর ফোকাস করা হয় এবং দু'টি ক্ষেত্রেই অ্যাক্টিভ ইনপুট ইন্ডিকেটর (মিটমিট করা কার্সর) দেখানো হয়।
তবে, কীবোর্ড (হার্ডওয়্যার বা সফ্টওয়্যার) থেকে ইনপুট শুধুমাত্র সবচেয়ে উপরের অ্যাক্টিভিটিতে (যে অ্যাপটি সবচেয়ে সম্প্রতি লঞ্চ করা হয়েছে) প্রবেশ করানো হয় বলে, একটি লুকানো ভার্চুয়াল ডিসপ্লে তৈরি করে, কোনও ক্ষতিকর অ্যাপ ব্যবহারকারীর ইনপুট চুরি করতে পারে, এমনকি প্রাইমারি ডিভাইস ডিসপ্লেতে সফ্টওয়্যার কীবোর্ড ব্যবহার করার সময়ও।
প্রতিটি ডিসপ্লের জন্য ফোকাস সেট করতে com.android.internal.R.bool.config_perDisplayFocusEnabled
ব্যবহার করুন।
মানানসই
সমস্যা: Android 9 এবং এর আগের ভার্সনে, সিস্টেমে একবারে সর্বাধিক একটি উইন্ডো ফোকাসে থাকে।
সমাধান: খুব কম ক্ষেত্রেই একই প্রসেস থেকে দুটি উইন্ডো ফোকাস করা হয়। এমন হলে, সিস্টেম শুধুমাত্র সেই উইন্ডোতেই ফোকাস করে যেটি Z-অর্ডারে উপরে আছে। যেসব অ্যাপ Android 10 বা তার পরের যেকোনও ভার্সনে চলে, সেগুলির ক্ষেত্রে এই বিধিনিষেধ তুলে নেওয়া হয়েছে। এর কারণ হল, Android 10 বা তার পরের যেকোনও ভার্সনে একই সাথে একাধিক উইন্ডো ফোকাস করা যায়।
প্রয়োগ
WindowManagerService#mPerDisplayFocusEnabled এই ফিচারের
উপলভ্যতা নিয়ন্ত্রণ করে। ActivityManager-এ,
ভেরিয়েবলে গ্লোবাল ট্র্যাকিংয়ের পরিবর্তে এখন
ActivityDisplay#getFocusedStack() ব্যবহার করা হয়। ActivityDisplay#getFocusedStack()
ভ্যালু ক্যাশে করার পরিবর্তে Z-অর্ডারের উপর ভিত্তি করে ফোকাস নির্ধারণ করে। এটি এই কারণে করা হয় যাতে
শুধুমাত্র একটি সোর্স, WindowManager-কে অ্যাক্টিভিটির Z-অর্ডার ট্র্যাক করতে হয়।
ActivityStackSupervisor#getTopDisplayFocusedStack() সেইসব ক্ষেত্রে একই ধরনের
পদ্ধতি নেয় যেখানে সিস্টেমের সবচেয়ে বেশি ফোকাস করা স্ট্যাক
অবশ্যই শনাক্ত করতে হবে। প্রথম উপযুক্ত স্ট্যাক খোঁজার জন্য
স্ট্যাকগুলি উপর থেকে নিচে পর্যন্ত সার্চ করা হয়।
InputDispatcher-এ এখন একাধিক ফোকাস করা উইন্ডো থাকতে পারে
(ডিসপ্লে প্রতি একটি)। কোনও ইনপুট ইভেন্ট ডিসপ্লে-নির্দিষ্ট হলে, এটি সংশ্লিষ্ট ডিসপ্লেতে
ফোকাস করা উইন্ডোতে পাঠানো হয়। অন্যথায়, এটি ফোকাস করা ডিসপ্লের ফোকাস করা উইন্ডোতে
পাঠানো হয়, এটি হল সেই ডিসপ্লে যার সাথে ব্যবহারকারী
অতি সম্প্রতি ইন্টার্যাক্ট করেছেন।
InputDispatcher::mFocusedWindowHandlesByDisplay এবং
InputDispatcher::setFocusedDisplay() দেখুন। এছাড়াও, ফোকাস করা অ্যাপগুলি InputManagerService-এ
NativeInputManager::setFocusedApplication()-এর মাধ্যমে
আলাদাভাবে আপডেট করা হয়।
WindowManager-এ, ফোকাস করা উইন্ডোও আলাদাভাবে ট্র্যাক করা হয়।
DisplayContent#mCurrentFocus এবং
DisplayContent#mFocusedApp ও সংশ্লিষ্ট ব্যবহার দেখুন। সম্পর্কিত ফোকাস
ট্র্যাকিং এবং আপডেট করার পদ্ধতিগুলি
WindowManagerService থেকে DisplayContent-এ সরানো হয়েছে।