প্রদর্শন সমর্থন

এই ডিসপ্লে-নির্দিষ্ট ক্ষেত্রগুলিতে করা আপডেটগুলি নীচে সরবরাহ করা হয়েছে:

কার্যকলাপ এবং প্রদর্শনের আকার পরিবর্তন করুন

একটি অ্যাপ মাল্টি-উইন্ডো মোড বা আকার পরিবর্তন করতে পারে না তা নির্দেশ করার জন্য, কার্যকলাপগুলি 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 সংজ্ঞায়িত করতে পারে যা তারা পরিচালনা করতে সক্ষম।

Android 10-এ অ্যাপের অনুপাত

চিত্র 1. Android 10-এ সমর্থিত অ্যাপ অনুপাতের উদাহরণ

ডিভাইস বাস্তবায়নে সেকেন্ডারি ডিসপ্লে থাকতে পারে যার আকার এবং রেজোলিউশন অ্যান্ড্রয়েড 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 এ সরানো হয়েছে।

,

এই ডিসপ্লে-নির্দিষ্ট ক্ষেত্রগুলিতে করা আপডেটগুলি নীচে সরবরাহ করা হয়েছে:

কার্যকলাপ এবং প্রদর্শনের আকার পরিবর্তন করুন

একটি অ্যাপ মাল্টি-উইন্ডো মোড বা আকার পরিবর্তন করতে পারে না তা নির্দেশ করার জন্য, কার্যকলাপগুলি 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 সংজ্ঞায়িত করতে পারে যা তারা পরিচালনা করতে সক্ষম।

Android 10-এ অ্যাপের অনুপাত

চিত্র 1. Android 10-এ সমর্থিত অ্যাপ অনুপাতের উদাহরণ

ডিভাইস বাস্তবায়নে সেকেন্ডারি ডিসপ্লে থাকতে পারে যার আকার এবং রেজোলিউশন অ্যান্ড্রয়েড 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-ক্রমের উচ্চতর উইন্ডোতে ফোকাস প্রদান করে। এই বিধিনিষেধটি অ্যান্ড্রয়েড 10 লক্ষ্য করে এমন অ্যাপ্লিকেশনগুলির জন্য সরানো হয়েছে, যেখানে এটি আশা করা যায় যে তারা একই সাথে একাধিক উইন্ডোজকে সমর্থন করতে পারে।

বাস্তবায়ন

WindowManagerService#mPerDisplayFocusEnabled এই বৈশিষ্ট্যের প্রাপ্যতা নিয়ন্ত্রণ করে। ActivityManager , ActivityDisplay#getFocusedStack() এখন একটি ভেরিয়েবলে গ্লোবাল ট্র্যাকিংয়ের পরিবর্তে ব্যবহৃত হয়। ActivityDisplay#getFocusedStack() মানটি ক্যাচ করার পরিবর্তে জেড-অর্ডারের উপর ভিত্তি করে ফোকাস নির্ধারণ করে। এটি এমন যে কেবলমাত্র একটি উত্স, উইন্ডো ম্যানেজার, ক্রিয়াকলাপগুলির জেড-অর্ডার ট্র্যাক করতে হবে।

ActivityStackSupervisor#getTopDisplayFocusedStack() যখন সিস্টেমের শীর্ষতম ফোকাসযুক্ত স্ট্যাকটি সনাক্ত করতে হবে তখন সেই ক্ষেত্রে একই ধরণের পদ্ধতি গ্রহণ করে। স্ট্যাকগুলি শীর্ষ থেকে নীচে পর্যন্ত ট্র্যাভার করা হয়, প্রথম যোগ্য স্ট্যাকের জন্য অনুসন্ধান করে।

InputDispatcher এখন একাধিক ফোকাসযুক্ত উইন্ডোজ থাকতে পারে (প্রতি ডিসপ্লে একটি)। যদি কোনও ইনপুট ইভেন্টটি প্রদর্শিত হয় তবে এটি সংশ্লিষ্ট ডিসপ্লেতে ফোকাসযুক্ত উইন্ডোতে প্রেরণ করা হয়। অন্যথায়, এটি ফোকাসড ডিসপ্লেতে ফোকাসযুক্ত উইন্ডোতে প্রেরণ করা হয়েছে, যা ব্যবহারকারীটি সম্প্রতি সর্বাধিক ইন্টারঅ্যাক্ট করে এমন প্রদর্শন।

InputDispatcher::mFocusedWindowHandlesByDisplay এবং InputDispatcher::setFocusedDisplay() । ফোকাসযুক্ত অ্যাপ্লিকেশনগুলি NativeInputManager::setFocusedApplication() এর মাধ্যমে ইনপুট ম্যানেজার সার্ভিসে পৃথকভাবে আপডেট করা হয়।

WindowManager , ফোকাসযুক্ত উইন্ডোগুলিও আলাদাভাবে ট্র্যাক করা হয়। DisplayContent#mCurrentFocus এবং DisplayContent#mFocusedApp এবং সম্পর্কিত ব্যবহারগুলি দেখুন। সম্পর্কিত ফোকাস ট্র্যাকিং এবং আপডেট করার পদ্ধতিগুলি WindowManagerService থেকে DisplayContent স্থানান্তরিত করা হয়েছে।

,

এই প্রদর্শন-নির্দিষ্ট ক্ষেত্রগুলিতে করা আপডেটগুলি নীচে সরবরাহ করা হয়েছে:

ক্রিয়াকলাপ এবং প্রদর্শনগুলি পুনরায় আকার দিন

কোনও অ্যাপ্লিকেশন মাল্টি-উইন্ডো মোড বা পুনরায় আকার দেওয়ার পক্ষে সমর্থন করতে পারে না তা নির্দেশ করতে, ক্রিয়াকলাপগুলি resizeableActivity=false বৈশিষ্ট্য ব্যবহার করে। ক্রিয়াকলাপগুলি পুনরায় আকার দেওয়ার সময় অ্যাপ্লিকেশনগুলির দ্বারা সম্মুখীন সাধারণ বিষয়গুলির মধ্যে রয়েছে:

  • কোনও ক্রিয়াকলাপের অ্যাপ্লিকেশন বা অন্য কোনও অ-ভিজ্যুয়াল উপাদান থেকে আলাদা কনফিগারেশন থাকতে পারে। একটি সাধারণ ভুল হ'ল অ্যাপ প্রসঙ্গ থেকে ডিসপ্লে মেট্রিকগুলি পড়া। ফিরে আসা মানগুলি দৃশ্যমান অঞ্চল মেট্রিকগুলিতে সামঞ্জস্য করা হবে না যেখানে কোনও ক্রিয়াকলাপ প্রদর্শিত হয়।
  • কোনও ক্রিয়াকলাপ রেসাইজিং এবং ক্র্যাশ পরিচালনা করতে পারে না, কোনও বিকৃত ইউআই প্রদর্শন করতে পারে না, বা দৃষ্টান্তের অবস্থা সংরক্ষণ না করে পুনরায় চালু হওয়ার কারণে রাষ্ট্র হারাতে পারে না।
  • একটি অ্যাপ্লিকেশন পরম ইনপুট স্থানাঙ্কগুলি (উইন্ডো অবস্থানের সাথে সম্পর্কিতদের পরিবর্তে) ব্যবহার করার চেষ্টা করতে পারে, যা মাল্টি-উইন্ডোতে ইনপুটটি ভেঙে দিতে পারে।

অ্যান্ড্রয়েড 7 (এবং উচ্চতর) এ, একটি অ্যাপ্লিকেশন সর্বদা পূর্ণ স্ক্রিন মোডে চালানোর জন্য resizeableActivity=false সেট করা যেতে পারে। এই ক্ষেত্রে, প্ল্যাটফর্মটি অস্তিত্বহীন ক্রিয়াকলাপগুলিকে বিভক্ত স্ক্রিনে যেতে বাধা দেয়। যদি ব্যবহারকারী ইতিমধ্যে স্প্লিট-স্ক্রিন মোডে থাকাকালীন লঞ্চার থেকে কোনও অ-আবিষ্কারযোগ্য ক্রিয়াকলাপের আহ্বান করার চেষ্টা করে তবে প্ল্যাটফর্মটি স্প্লিট-স্ক্রিন মোড থেকে বেরিয়ে আসে এবং পূর্ণ-স্ক্রিন মোডে অ-উদ্ভূত ক্রিয়াকলাপ চালু করে।

অ্যাপ্লিকেশনগুলি যেগুলি স্পষ্টভাবে এই বৈশিষ্ট্যটিকে ম্যানিফেস্টে false হিসাবে সেট করে তা অবশ্যই মাল্টি-উইন্ডো মোডে চালু করা উচিত নয়, যদি না সামঞ্জস্যতা মোডটি প্রয়োগ করা হয়:

  • একই কনফিগারেশন প্রক্রিয়াটিতে প্রয়োগ করা হয়, এতে সমস্ত ক্রিয়াকলাপ এবং অ-ক্রিয়াকলাপের উপাদান রয়েছে।
  • প্রয়োগিত কনফিগারেশন অ্যাপ্লিকেশন-সামঞ্জস্যপূর্ণ প্রদর্শনগুলির জন্য সিডিডি প্রয়োজনীয়তা পূরণ করে।

অ্যান্ড্রয়েড 10-এ, প্ল্যাটফর্মটি এখনও অ-উদ্ভূত ক্রিয়াকলাপগুলিকে স্প্লিট-স্ক্রিন মোডে যেতে বাধা দেয়, তবে ক্রিয়াকলাপটি যদি একটি নির্দিষ্ট ওরিয়েন্টেশন বা দিক অনুপাত ঘোষণা করে থাকে তবে এগুলি সাময়িকভাবে স্কেল করা যেতে পারে। যদি তা না হয় তবে ক্রিয়াকলাপটি অ্যান্ড্রয়েড 9 এবং নিম্নের মতো পুরো স্ক্রিনটি পূরণ করতে পুনরায় আকার দেয়।

ডিফল্ট বাস্তবায়ন নিম্নলিখিত নীতি প্রয়োগ করে:

যখন কোনও ক্রিয়াকলাপ android:resizeableActivity বৈশিষ্ট্য এবং যখন সেই ক্রিয়াকলাপটি নীচে বর্ণিত শর্তগুলির মধ্যে একটি পূরণ করে, তখন প্রয়োগিত স্ক্রিন কনফিগারেশনটি অবশ্যই পরিবর্তন করতে হবে, তখন ক্রিয়াকলাপ এবং প্রক্রিয়াটি মূল কনফিগারেশন দিয়ে সংরক্ষণ করা হয় এবং ব্যবহারকারীকে আপডেট হওয়া স্ক্রিন কনফিগারেশনটি ব্যবহার করার জন্য অ্যাপ্লিকেশন প্রক্রিয়াটি সরবরাহ করা হয়।

  • android:screenOrientation
  • অ্যাপ্লিকেশনটি এপিআই স্তরকে লক্ষ্য করে সর্বাধিক বা ন্যূনতম দিক অনুপাতের ডিফল্ট রয়েছে বা দিক অনুপাতটি স্পষ্টভাবে ঘোষণা করে

এই চিত্রটি একটি ঘোষিত দিক অনুপাতের সাথে একটি অ-আবিষ্কারযোগ্য ক্রিয়াকলাপ প্রদর্শন করে। ডিভাইসটি ভাঁজ করার সময়, উপযুক্ত লেটারবক্সিং ব্যবহার করে দিক অনুপাতটি বজায় রেখে উইন্ডোটি ফিট করার জন্য উইন্ডোটি ছোট করে দেওয়া হয়। এছাড়াও, ক্রিয়াকলাপের জন্য ডিসপ্লে অঞ্চলটি পরিবর্তন করা হলে প্রতিবার ব্যবহারকারীকে একটি পুনঃসূচনা ক্রিয়াকলাপ বিকল্প সরবরাহ করা হয়।

ডিভাইসটি উন্মোচন করার সময়, ক্রিয়াকলাপের কনফিগারেশন, আকার এবং দিক অনুপাত পরিবর্তন হয় না, তবে ক্রিয়াকলাপটি পুনরায় চালু করার বিকল্পটি প্রদর্শিত হয়।

যখন resizeableActivity সেট করা হয় না (বা এটি true সেট করা থাকে), অ্যাপ্লিকেশনটি সম্পূর্ণরূপে পুনরায় আকার দেওয়ার পক্ষে সমর্থন করে।

বাস্তবায়ন

স্থির ওরিয়েন্টেশন বা দিক অনুপাত সহ একটি অ-সম্ভাব্য ক্রিয়াকলাপকে কোডে আকার সামঞ্জস্যতা মোড (এসসিএম) বলা হয়। শর্তটি ActivityRecord#shouldUseSizeCompatMode() যখন কোনও এসসিএম ক্রিয়াকলাপ চালু করা হয়, স্ক্রিন-সম্পর্কিত কনফিগারেশন (যেমন আকার বা ঘনত্ব) অনুরোধ করা ওভাররাইড কনফিগারেশনে স্থির করা হয়, সুতরাং ক্রিয়াকলাপটি আর বর্তমান প্রদর্শন কনফিগারেশনের উপর নির্ভর করে না।

যদি এসসিএম ক্রিয়াকলাপ পুরো স্ক্রিনটি পূরণ করতে না পারে তবে এটি শীর্ষে সারিবদ্ধ এবং অনুভূমিকভাবে কেন্দ্রিক। ক্রিয়াকলাপের সীমাগুলি AppWindowToken#calculateCompatBoundsTransformation() দ্বারা গণনা করা হয়।

যখন কোনও এসসিএম ক্রিয়াকলাপ তার ধারকটির চেয়ে আলাদা স্ক্রিন কনফিগারেশন ব্যবহার করে (উদাহরণস্বরূপ, প্রদর্শনটি পুনরায় আকার দেওয়া হয়, বা ক্রিয়াকলাপটি অন্য ডিসপ্লেতে স্থানান্তরিত হয়), ActivityRecord#inSizeCompatMode() সত্য এবং SizeCompatModeActivityController (সিস্টেম ইউআইতে) প্রক্রিয়া পুনঃস্থাপন বোতামটি দেখানোর জন্য কলব্যাকটি গ্রহণ করে।

আকার এবং দিক অনুপাত প্রদর্শন করুন

অ্যান্ড্রয়েড 10 দীর্ঘ এবং পাতলা পর্দার উচ্চ অনুপাত থেকে 1: 1 অনুপাত পর্যন্ত নতুন দিক অনুপাতের জন্য সমর্থন সরবরাহ করে। অ্যাপ্লিকেশনগুলি ApplicationInfo#maxAspectRatio এবং ApplicationInfo#minAspectRatio স্ক্রিনের যে তারা পরিচালনা করতে সক্ষম তা সংজ্ঞায়িত করতে পারে।

অ্যান্ড্রয়েড 10 এ অ্যাপ্লিকেশন অনুপাত

চিত্র 1। উদাহরণ অ্যাপ্লিকেশন অনুপাত অ্যান্ড্রয়েড 10 এ সমর্থিত

ডিভাইস বাস্তবায়নের জন্য অ্যান্ড্রয়েড 9, এবং নিম্ন (ন্যূনতম 2.5 ইঞ্চি প্রস্থ বা উচ্চতা, ন্যূনতম 320 ডিপি smallestScreenWidth জন্য ন্যূনতম 320 ডিপি) এর চেয়ে ছোট আকার এবং রেজোলিউশনগুলির সাথে গৌণ প্রদর্শন থাকতে পারে, তবে কেবলমাত্র এই ছোট্ট প্রদর্শনগুলি সমর্থন করার জন্য যে ক্রিয়াকলাপগুলি বেছে নেওয়া যায় সেখানে রাখা যেতে পারে।

অ্যাপ্লিকেশনগুলি ন্যূনতম সমর্থিত আকার ঘোষণা করে বেছে নিতে পারে যা লক্ষ্য প্রদর্শন আকারের চেয়ে ছোট বা সমান। android:minHeight এবং android:minWidth ক্রিয়াকলাপের বিন্যাসের বৈশিষ্ট্যগুলি।

নীতি প্রদর্শন

অ্যান্ড্রয়েড 10 পৃথক করে এবং PhoneWindowManager ডিফল্ট WindowManagerPolicy বাস্তবায়ন থেকে প্রতি-প্রদর্শনী ক্লাসগুলিতে নির্দিষ্ট প্রদর্শন নীতিগুলি সরিয়ে দেয় এবং সরিয়ে দেয়: যেমন:

  • রাষ্ট্র এবং ঘূর্ণন প্রদর্শন করুন
  • কিছু কী এবং গতি ইভেন্ট ট্র্যাকিং
  • সিস্টেম ইউআই এবং সজ্জা উইন্ডোজ

অ্যান্ড্রয়েড 9 (এবং নিম্ন) এ, PhoneWindowManager শ্রেণি প্রদর্শন নীতি, রাজ্য এবং সেটিংস, ঘূর্ণন, সজ্জা উইন্ডো ফ্রেম ট্র্যাকিং এবং আরও অনেক কিছু পরিচালনা করেছে। অ্যান্ড্রয়েড 10 এর বেশিরভাগটি রোটেশন ট্র্যাকিং ব্যতীত DisplayPolicy ক্লাসে স্থানান্তরিত করে, যা DisplayRotation স্থানান্তরিত হয়েছে।

উইন্ডো সেটিংস প্রদর্শন করুন

অ্যান্ড্রয়েড 10-এ, কনফিগারযোগ্য প্রতি-ডিসপ্লে উইন্ডোইং সেটিংসটি অন্তর্ভুক্ত করার জন্য প্রসারিত করা হয়েছে:

  • ডিফল্ট ডিসপ্লে উইন্ডোয়িং মোড
  • ওভারস্ক্যান মান
  • ব্যবহারকারী ঘূর্ণন এবং ঘূর্ণন মোড
  • জোর করে আকার, ঘনত্ব এবং স্কেলিং মোড
  • সামগ্রী অপসারণ মোড (যখন প্রদর্শন সরানো হয়)
  • সিস্টেম সজ্জা এবং ime জন্য সমর্থন

DisplayWindowSettings শ্রেণিতে এই বিকল্পগুলির জন্য সেটিংস রয়েছে। তারা display_settings.xml এ ডিস্ক /data পার্টিশনে অবিরত থাকে যখন কোনও সেটিংস পরিবর্তন করা হয়। বিশদগুলির জন্য, DisplayWindowSettings.AtomicFileStorage এবং DisplayWindowSettings#writeSettings() দেখুন। ডিভাইস নির্মাতারা তাদের ডিভাইস কনফিগারেশনের জন্য display_settings.xml -তে ডিফল্ট মান সরবরাহ করতে পারে। তবে, ফাইলটি /data সঞ্চিত থাকায়, কোনও মুছা দ্বারা মুছে ফেলা হলে ফাইলটি পুনরুদ্ধার করতে অতিরিক্ত যুক্তির প্রয়োজন হতে পারে।

ডিফল্টরূপে, অ্যান্ড্রয়েড 10 সেটিংস বজায় রাখার সময় DisplayInfo#uniqueId ডিসপ্লেটির সনাক্তকারী হিসাবে ব্যবহার করে। সমস্ত প্রদর্শনের জন্য uniqueId পপুলেশন করা উচিত। এছাড়াও, এটি শারীরিক এবং নেটওয়ার্ক প্রদর্শনের জন্য স্থিতিশীল। এটি সনাক্তকারী হিসাবে কোনও শারীরিক প্রদর্শনের বন্দরটি ব্যবহার করাও সম্ভব, যা DisplayWindowSettings#mIdentifier সেট করা যেতে পারে। প্রতিটি লেখার পরে, সমস্ত সেটিংস লেখা হয় তাই স্টোরেজে ডিসপ্লে এন্ট্রি করার জন্য ব্যবহৃত কীটি আপডেট করা নিরাপদ। বিশদগুলির জন্য, স্ট্যাটিক ডিসপ্লে সনাক্তকারী দেখুন।

Historical তিহাসিক কারণে সেটিংস /data ডিরেক্টরিতে অবিচল থাকে। মূলত, এগুলি ব্যবহারকারী-সেট সেটিংস যেমন ডিসপ্লে রোটেশন ধরে রাখতে ব্যবহৃত হয়েছিল।

স্ট্যাটিক ডিসপ্লে সনাক্তকারী

অ্যান্ড্রয়েড 9 (এবং নিম্ন) ফ্রেমওয়ার্কে প্রদর্শনের জন্য স্থিতিশীল সনাক্তকারী সরবরাহ করে না। সিস্টেমে যখন কোনও ডিসপ্লে যুক্ত করা হয়েছিল, তখন স্ট্যাটিক কাউন্টারকে বাড়িয়ে এই ডিসপ্লেটির জন্য Display#mDisplayId বা DisplayInfo#displayId তৈরি করা হয়েছিল। যদি সিস্টেমটি একই প্রদর্শনটি যুক্ত করে এবং সরানো হয় তবে একটি আলাদা আইডি ফলাফল।

যদি কোনও ডিভাইসে বুট থেকে একাধিক ডিসপ্লে উপলব্ধ থাকে তবে সময়গুলির উপর নির্ভর করে প্রদর্শনগুলি বিভিন্ন আইডেন্টিফায়ার বরাদ্দ করা যেতে পারে। যদিও অ্যান্ড্রয়েড 9 (এবং এর আগে) DisplayInfo#uniqueId অন্তর্ভুক্ত করেছে, এতে প্রদর্শনগুলির মধ্যে পার্থক্য করার জন্য পর্যাপ্ত তথ্য নেই কারণ শারীরিক প্রদর্শনগুলি local:0 বা local:1 হিসাবে চিহ্নিত করা হয়েছিল, অন্তর্নির্মিত এবং বাহ্যিক প্রদর্শনকে উপস্থাপন করতে।

একটি স্থিতিশীল সনাক্তকারী যুক্ত করতে এবং স্থানীয়, নেটওয়ার্ক এবং ভার্চুয়াল ডিসপ্লেগুলির মধ্যে পার্থক্য করতে অ্যান্ড্রয়েড 10 পরিবর্তনগুলি DisplayInfo#uniqueId পরিবর্তন করে।

প্রদর্শনের ধরন বিন্যাস
স্থানীয়
local:<stable-id>
নেটওয়ার্ক
network:<mac-address>
ভার্চুয়াল
virtual:<package-name-and-name>

uniqueId আপডেট করার পাশাপাশি, DisplayInfo.address DisplayAddress রয়েছে, একটি ডিসপ্লে আইডেন্টিফায়ার যা রিবুটগুলি জুড়ে স্থিতিশীল। অ্যান্ড্রয়েড 10 -এ, DisplayAddress শারীরিক এবং নেটওয়ার্ক প্রদর্শনগুলিকে সমর্থন করে। DisplayAddress.Physical একটি স্থিতিশীল ডিসপ্লে আইডি রয়েছে ( uniqueId মতো) এবং DisplayAddress#fromPhysicalDisplayId() দিয়ে তৈরি করা যেতে পারে।

অ্যান্ড্রয়েড 10 পোর্টের তথ্য ( Physical#getPort() ) পাওয়ার জন্য একটি সুবিধাজনক পদ্ধতিও সরবরাহ করে। এই পদ্ধতিটি ফ্রেমওয়ার্কে স্থিতিশীলভাবে প্রদর্শনগুলি সনাক্ত করতে ব্যবহার করা যেতে পারে। উদাহরণস্বরূপ, এটি DisplayWindowSettings ব্যবহৃত হয়)। DisplayAddress.Network ম্যাক ঠিকানা রয়েছে এবং DisplayAddress#fromMacAddress() দিয়ে তৈরি করা যেতে পারে।

এই সংযোজনগুলি ডিভাইস নির্মাতাদের স্ট্যাটিক মাল্টি-ডিসপ্লে সেট-আপগুলিতে প্রদর্শনগুলি সনাক্ত করতে এবং বিভিন্ন সিস্টেম সেটিংস এবং স্ট্যাটিক ডিসপ্লে আইডেন্টিফায়ার ব্যবহার করে বৈশিষ্ট্যগুলি যেমন শারীরিক ডিসপ্লেগুলির জন্য পোর্টগুলি কনফিগার করতে দেয়। এই পদ্ধতিগুলি লুকানো থাকে এবং কেবল system_server মধ্যে ব্যবহার করার উদ্দেশ্যে করা হয়।

একটি এইচডাব্লুসি ডিসপ্লে আইডি দেওয়া (যা অস্বচ্ছ হতে পারে এবং সর্বদা স্থিতিশীল নয়) দেওয়া হয়, এই পদ্ধতিটি (প্ল্যাটফর্ম-নির্দিষ্ট) 8-বিট পোর্ট নম্বরটি দেয় যা ডিসপ্লে আউটপুটটির জন্য কোনও শারীরিক সংযোগকারীকে চিহ্নিত করে, পাশাপাশি ডিসপ্লেটির ইডিআইডি ব্লব। ফ্রেমওয়ার্কের সংস্পর্শে থাকা স্থিতিশীল 64-বিট ডিসপ্লে আইডি তৈরি করতে EDID থেকে সারফেসফ্লিংগার প্রস্তুতকারক বা মডেল তথ্যগুলি নিষ্কাশন করে। যদি এই পদ্ধতিটি সমর্থিত না হয় বা ত্রুটিগুলি আউট না করে থাকে তবে সারফেসফ্লিংগার লিগ্যাসি এমডি মোডে ফিরে আসে, যেখানে 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"

দু'জনেরও বেশি প্রদর্শন ব্যবহার করুন

অ্যান্ড্রয়েড 9 (এবং নিম্ন) এ, সারফেসফ্লিংগার এবং DisplayManagerService হার্ড-কোডেড আইডি 0 এবং 1 সহ সর্বাধিক দুটি শারীরিক ডিসপ্লেগুলির অস্তিত্ব ধরে নিয়েছিল।

অ্যান্ড্রয়েড 10 দিয়ে শুরু করে, সারফেসফ্লিংগার স্থিতিশীল ডিসপ্লে আইডি তৈরি করতে একটি হার্ডওয়্যার সুরকার (এইচডাব্লুসি) এপিআই উপার্জন করতে পারে, যা এটি শারীরিক প্রদর্শনগুলির একটি স্বেচ্ছাসেবী সংখ্যা পরিচালনা করতে সক্ষম করে। আরও জানতে, স্ট্যাটিক ডিসপ্লে সনাক্তকারী দেখুন।

কাঠামোটি SurfaceControl#getPhysicalDisplayToken মাধ্যমে শারীরিক প্রদর্শনের জন্য IBinder টোকেনটি সন্ধান করতে পারে SurfaceControl#getPhysicalDisplayIds থেকে বা DisplayEventReceiver হটপ্লাগ ইভেন্ট থেকে 64-বিট ডিসপ্লে আইডি পাওয়ার পরে।

অ্যান্ড্রয়েড 10 (এবং নিম্ন) এ, প্রাথমিক অভ্যন্তরীণ প্রদর্শনটি TYPE_INTERNAL এবং সমস্ত মাধ্যমিক প্রদর্শনগুলি সংযোগের ধরণ নির্বিশেষে TYPE_EXTERNAL হিসাবে পতাকাঙ্কিত করা হয়। অতএব, অতিরিক্ত অভ্যন্তরীণ প্রদর্শনগুলি বাহ্যিক হিসাবে বিবেচিত হয়। কার্যকারিতা হিসাবে, ডিভাইস-নির্দিষ্ট কোডটি DisplayAddress.Physical#getPort সম্পর্কে অনুমান করতে পারে H এইচডাব্লুসিটি জানা থাকলে এবং পোর্ট বরাদ্দ যুক্তিটি অনুমানযোগ্য হয়।

এই সীমাবদ্ধতা অ্যান্ড্রয়েড 11 (এবং উচ্চতর) এ সরানো হয়েছে।

  • অ্যান্ড্রয়েড 11 -এ, বুট চলাকালীন রিপোর্ট করা প্রথম প্রদর্শনটি প্রাথমিক প্রদর্শন। সংযোগের ধরণ (অভ্যন্তরীণ বনাম বাহ্যিক) অপ্রাসঙ্গিক। যাইহোক, এটি সত্য থেকে যায় যে প্রাথমিক প্রদর্শনটি সংযোগ বিচ্ছিন্ন করা যায় না এবং অনুসরণ করে যে এটি অবশ্যই অনুশীলনে একটি অভ্যন্তরীণ প্রদর্শন হতে হবে। নোট করুন যে কিছু ফোল্ডেবল ফোনে একাধিক অভ্যন্তরীণ প্রদর্শন রয়েছে।
  • মাধ্যমিক Display.TYPE_EXTERNAL তাদের সংযোগের Display.TYPE_BUILT_IN Display.TYPE_HDMI নির্ভর করে যথাক্রমে Display.TYPE_INTERNAL

বাস্তবায়ন

অ্যান্ড্রয়েড 9 এবং নিম্নে, প্রদর্শনগুলি 32-বিট আইডি দ্বারা চিহ্নিত করা হয়, যেখানে 0 টি অভ্যন্তরীণ প্রদর্শন, 1 বাহ্যিক প্রদর্শন, [2, INT32_MAX] এইচডাব্লুসি ভার্চুয়াল ডিসপ্লে এবং -1 একটি অবৈধ প্রদর্শন বা একটি নন-এইচডাব্লুসি ভার্চুয়াল ডিসপ্লে উপস্থাপন করে।

অ্যান্ড্রয়েড 10 দিয়ে শুরু করে, ডিসপ্লেগুলি স্থিতিশীল এবং অবিরাম আইডি দেওয়া হয়, যা সারফেসফ্লিংগার এবং DisplayManagerService আরও দুটি প্রদর্শন ট্র্যাক করতে এবং পূর্বে দেখা প্রদর্শনগুলি সনাক্ত করতে দেয়। যদি এইচডব্লিউসি IComposerClient.getDisplayIdentificationData সমর্থন করে এবং প্রদর্শন সনাক্তকরণের ডেটা সরবরাহ করে, সারফেসফ্লিংগার ইডিআইডি কাঠামোটি পার্স করে এবং শারীরিক এবং এইচডাব্লুসি ভার্চুয়াল ডিসপ্লেগুলির জন্য স্থিতিশীল 64-বিট ডিসপ্লে আইডি বরাদ্দ করে। আইডিগুলি একটি বিকল্প প্রকার ব্যবহার করে প্রকাশ করা হয়, যেখানে নাল মানটি একটি অবৈধ প্রদর্শন বা নন-এইচডাব্লুসি ভার্চুয়াল ডিসপ্লে উপস্থাপন করে। এইচডব্লিউসি সমর্থন ব্যতীত, সারফেসফ্লিংগার সর্বাধিক দুটি শারীরিক ডিসপ্লে দিয়ে উত্তরাধিকার আচরণে ফিরে আসে।

প্রতি প্রদর্শন ফোকাস

একই সময়ে পৃথক প্রদর্শনগুলি লক্ষ্য করে এমন বেশ কয়েকটি ইনপুট উত্সকে সমর্থন করার জন্য, অ্যান্ড্রয়েড 10 একাধিক ফোকাসযুক্ত উইন্ডোগুলিকে সমর্থন করার জন্য কনফিগার করা যেতে পারে, প্রতি প্রদর্শনীতে বেশিরভাগ ক্ষেত্রে। এটি কেবলমাত্র বিশেষ ধরণের ডিভাইসের জন্য উদ্দেশ্যযুক্ত যখন একাধিক ব্যবহারকারী একই সময়ে একই ডিভাইসের সাথে যোগাযোগ করে এবং অ্যান্ড্রয়েড অটোমোটিভের মতো বিভিন্ন ইনপুট পদ্ধতি বা ডিভাইস ব্যবহার করে।

এটি দৃ strongly ়ভাবে সুপারিশ করা হয় যে এই বৈশিষ্ট্যটি নিয়মিত ডিভাইসগুলির জন্য মাল্টি-স্ক্রিন ডিভাইসগুলি বা ডেস্কটপের মতো অভিজ্ঞতার জন্য ব্যবহৃত ব্যবহার সহ সক্ষম করা উচিত নয় । এটি মূলত একটি সুরক্ষা উদ্বেগের কারণে যা ব্যবহারকারীদের কোন উইন্ডোতে ইনপুট ফোকাস রয়েছে তা অবাক করে দিতে পারে।

ব্যবহারকারী যিনি কোনও পাঠ্য ইনপুট ক্ষেত্রে সুরক্ষিত তথ্য প্রবেশ করেন তার কল্পনা করুন, সম্ভবত কোনও ব্যাংকিং অ্যাপে লগ ইন করছেন বা সংবেদনশীল তথ্য রয়েছে এমন পাঠ্য প্রবেশ করুন। একটি দূষিত অ্যাপ্লিকেশন একটি পাঠ্য ইনপুট ক্ষেত্রের সাথে কোনও ক্রিয়াকলাপ সম্পাদন করার জন্য ভার্চুয়াল অফ-স্ক্রিন প্রদর্শন তৈরি করতে পারে। বৈধ এবং দূষিত ক্রিয়াকলাপগুলির ফোকাস রয়েছে এবং উভয়ই একটি সক্রিয় ইনপুট সূচক (জ্বলজ্বলে কার্সার) প্রদর্শন করে।

তবে, যেহেতু কোনও কীবোর্ড (হার্ডওয়্যার বা সফ্টওয়্যার) থেকে ইনপুটটি কেবলমাত্র শীর্ষস্থানীয় ক্রিয়াকলাপে প্রবেশ করা হয়েছে (যে অ্যাপটি সর্বাধিক সম্প্রতি চালু হয়েছিল), একটি লুকানো ভার্চুয়াল ডিসপ্লে তৈরি করে, একটি দূষিত অ্যাপ্লিকেশন প্রাথমিক ডিভাইস ডিসপ্লেতে একটি সফ্টওয়্যার কীবোর্ড ব্যবহার করার পরেও ব্যবহারকারী ইনপুটটি ধরতে পারে।

com.android.internal.R.bool.config_perDisplayFocusEnabled প্রতি প্রদর্শন ফোকাস সেট করতে ব্যবহার করুন।

সামঞ্জস্য

ইস্যু: অ্যান্ড্রয়েড 9 এবং নিম্নে, সিস্টেমের বেশিরভাগ উইন্ডোতে একবারে ফোকাস রয়েছে।

সমাধান: বিরল ক্ষেত্রে যখন একই প্রক্রিয়া থেকে দুটি উইন্ডো ফোকাস করা হবে, সিস্টেমটি কেবল জেড-অর্ডারে উচ্চতর উইন্ডোতে ফোকাস সরবরাহ করে। এই বিধিনিষেধটি অ্যান্ড্রয়েড 10 লক্ষ্য করে এমন অ্যাপ্লিকেশনগুলির জন্য সরানো হয়েছে, যেখানে এটি আশা করা যায় যে তারা একই সাথে একাধিক উইন্ডোজকে সমর্থন করতে পারে।

বাস্তবায়ন

WindowManagerService#mPerDisplayFocusEnabled এই বৈশিষ্ট্যের প্রাপ্যতা নিয়ন্ত্রণ করে। ActivityManager , ActivityDisplay#getFocusedStack() এখন একটি ভেরিয়েবলে গ্লোবাল ট্র্যাকিংয়ের পরিবর্তে ব্যবহৃত হয়। ActivityDisplay#getFocusedStack() মানটি ক্যাচ করার পরিবর্তে জেড-অর্ডারের উপর ভিত্তি করে ফোকাস নির্ধারণ করে। এটি এমন যে কেবলমাত্র একটি উত্স, উইন্ডো ম্যানেজার, ক্রিয়াকলাপগুলির জেড-অর্ডার ট্র্যাক করতে হবে।

ActivityStackSupervisor#getTopDisplayFocusedStack() যখন সিস্টেমের শীর্ষতম ফোকাসযুক্ত স্ট্যাকটি সনাক্ত করতে হবে তখন সেই ক্ষেত্রে একই ধরণের পদ্ধতি গ্রহণ করে। স্ট্যাকগুলি শীর্ষ থেকে নীচে পর্যন্ত ট্র্যাভার করা হয়, প্রথম যোগ্য স্ট্যাকের জন্য অনুসন্ধান করে।

InputDispatcher এখন একাধিক ফোকাসযুক্ত উইন্ডোজ থাকতে পারে (প্রতি ডিসপ্লে একটি)। যদি কোনও ইনপুট ইভেন্টটি প্রদর্শিত হয় তবে এটি সংশ্লিষ্ট ডিসপ্লেতে ফোকাসযুক্ত উইন্ডোতে প্রেরণ করা হয়। অন্যথায়, এটি ফোকাসড ডিসপ্লেতে ফোকাসযুক্ত উইন্ডোতে প্রেরণ করা হয়েছে, যা ব্যবহারকারীটি সম্প্রতি সর্বাধিক ইন্টারঅ্যাক্ট করে এমন প্রদর্শন।

InputDispatcher::mFocusedWindowHandlesByDisplay এবং InputDispatcher::setFocusedDisplay() । ফোকাসযুক্ত অ্যাপ্লিকেশনগুলি NativeInputManager::setFocusedApplication() এর মাধ্যমে ইনপুট ম্যানেজার সার্ভিসে পৃথকভাবে আপডেট করা হয়।

WindowManager , ফোকাসযুক্ত উইন্ডোগুলিও আলাদাভাবে ট্র্যাক করা হয়। DisplayContent#mCurrentFocus এবং DisplayContent#mFocusedApp এবং সম্পর্কিত ব্যবহারগুলি দেখুন। সম্পর্কিত ফোকাস ট্র্যাকিং এবং আপডেট করার পদ্ধতিগুলি WindowManagerService থেকে DisplayContent স্থানান্তরিত করা হয়েছে।

,

এই প্রদর্শন-নির্দিষ্ট ক্ষেত্রগুলিতে করা আপডেটগুলি নীচে সরবরাহ করা হয়েছে:

ক্রিয়াকলাপ এবং প্রদর্শনগুলি পুনরায় আকার দিন

কোনও অ্যাপ্লিকেশন মাল্টি-উইন্ডো মোড বা পুনরায় আকার দেওয়ার পক্ষে সমর্থন করতে পারে না তা নির্দেশ করতে, ক্রিয়াকলাপগুলি resizeableActivity=false বৈশিষ্ট্য ব্যবহার করে। ক্রিয়াকলাপগুলি পুনরায় আকার দেওয়ার সময় অ্যাপ্লিকেশনগুলির দ্বারা সম্মুখীন সাধারণ বিষয়গুলির মধ্যে রয়েছে:

  • কোনও ক্রিয়াকলাপের অ্যাপ্লিকেশন বা অন্য কোনও অ-ভিজ্যুয়াল উপাদান থেকে আলাদা কনফিগারেশন থাকতে পারে। একটি সাধারণ ভুল হ'ল অ্যাপ প্রসঙ্গ থেকে ডিসপ্লে মেট্রিকগুলি পড়া। ফিরে আসা মানগুলি দৃশ্যমান অঞ্চল মেট্রিকগুলিতে সামঞ্জস্য করা হবে না যেখানে কোনও ক্রিয়াকলাপ প্রদর্শিত হয়।
  • কোনও ক্রিয়াকলাপ রেসাইজিং এবং ক্র্যাশ পরিচালনা করতে পারে না, কোনও বিকৃত ইউআই প্রদর্শন করতে পারে না, বা দৃষ্টান্তের অবস্থা সংরক্ষণ না করে পুনরায় চালু হওয়ার কারণে রাষ্ট্র হারাতে পারে না।
  • একটি অ্যাপ্লিকেশন পরম ইনপুট স্থানাঙ্কগুলি (উইন্ডো অবস্থানের সাথে সম্পর্কিতদের পরিবর্তে) ব্যবহার করার চেষ্টা করতে পারে, যা মাল্টি-উইন্ডোতে ইনপুটটি ভেঙে দিতে পারে।

অ্যান্ড্রয়েড 7 (এবং উচ্চতর) এ, একটি অ্যাপ্লিকেশন সর্বদা পূর্ণ স্ক্রিন মোডে চালানোর জন্য resizeableActivity=false সেট করা যেতে পারে। এই ক্ষেত্রে, প্ল্যাটফর্মটি অস্তিত্বহীন ক্রিয়াকলাপগুলিকে বিভক্ত স্ক্রিনে যেতে বাধা দেয়। যদি ব্যবহারকারী ইতিমধ্যে স্প্লিট-স্ক্রিন মোডে থাকাকালীন লঞ্চার থেকে কোনও অ-আবিষ্কারযোগ্য ক্রিয়াকলাপের আহ্বান করার চেষ্টা করে তবে প্ল্যাটফর্মটি স্প্লিট-স্ক্রিন মোড থেকে বেরিয়ে আসে এবং পূর্ণ-স্ক্রিন মোডে অ-উদ্ভূত ক্রিয়াকলাপ চালু করে।

অ্যাপ্লিকেশনগুলি যেগুলি স্পষ্টভাবে এই বৈশিষ্ট্যটিকে ম্যানিফেস্টে false হিসাবে সেট করে তা অবশ্যই মাল্টি-উইন্ডো মোডে চালু করা উচিত নয়, যদি না সামঞ্জস্যতা মোডটি প্রয়োগ করা হয়:

  • একই কনফিগারেশন প্রক্রিয়াটিতে প্রয়োগ করা হয়, এতে সমস্ত ক্রিয়াকলাপ এবং অ-ক্রিয়াকলাপের উপাদান রয়েছে।
  • প্রয়োগিত কনফিগারেশন অ্যাপ্লিকেশন-সামঞ্জস্যপূর্ণ প্রদর্শনগুলির জন্য সিডিডি প্রয়োজনীয়তা পূরণ করে।

অ্যান্ড্রয়েড 10-এ, প্ল্যাটফর্মটি এখনও অ-উদ্ভূত ক্রিয়াকলাপগুলিকে স্প্লিট-স্ক্রিন মোডে যেতে বাধা দেয়, তবে ক্রিয়াকলাপটি যদি একটি নির্দিষ্ট ওরিয়েন্টেশন বা দিক অনুপাত ঘোষণা করে থাকে তবে এগুলি সাময়িকভাবে স্কেল করা যেতে পারে। যদি তা না হয় তবে ক্রিয়াকলাপটি অ্যান্ড্রয়েড 9 এবং নিম্নের মতো পুরো স্ক্রিনটি পূরণ করতে পুনরায় আকার দেয়।

ডিফল্ট বাস্তবায়ন নিম্নলিখিত নীতি প্রয়োগ করে:

যখন কোনও ক্রিয়াকলাপ android:resizeableActivity বৈশিষ্ট্য এবং যখন সেই ক্রিয়াকলাপটি নীচে বর্ণিত শর্তগুলির মধ্যে একটি পূরণ করে, তখন প্রয়োগিত স্ক্রিন কনফিগারেশনটি অবশ্যই পরিবর্তন করতে হবে, তখন ক্রিয়াকলাপ এবং প্রক্রিয়াটি মূল কনফিগারেশন দিয়ে সংরক্ষণ করা হয় এবং ব্যবহারকারীকে আপডেট হওয়া স্ক্রিন কনফিগারেশনটি ব্যবহার করার জন্য অ্যাপ্লিকেশন প্রক্রিয়াটি সরবরাহ করা হয়।

  • android:screenOrientation
  • অ্যাপ্লিকেশনটি এপিআই স্তরকে লক্ষ্য করে সর্বাধিক বা ন্যূনতম দিক অনুপাতের ডিফল্ট রয়েছে বা দিক অনুপাতটি স্পষ্টভাবে ঘোষণা করে

এই চিত্রটি একটি ঘোষিত দিক অনুপাতের সাথে একটি অ-আবিষ্কারযোগ্য ক্রিয়াকলাপ প্রদর্শন করে। ডিভাইসটি ভাঁজ করার সময়, উপযুক্ত লেটারবক্সিং ব্যবহার করে দিক অনুপাতটি বজায় রেখে উইন্ডোটি ফিট করার জন্য উইন্ডোটি ছোট করে দেওয়া হয়। এছাড়াও, ক্রিয়াকলাপের জন্য ডিসপ্লে অঞ্চলটি পরিবর্তন করা হলে প্রতিবার ব্যবহারকারীকে একটি পুনঃসূচনা ক্রিয়াকলাপ বিকল্প সরবরাহ করা হয়।

ডিভাইসটি উন্মোচন করার সময়, ক্রিয়াকলাপের কনফিগারেশন, আকার এবং দিক অনুপাত পরিবর্তন হয় না, তবে ক্রিয়াকলাপটি পুনরায় চালু করার বিকল্পটি প্রদর্শিত হয়।

যখন resizeableActivity সেট করা হয় না (বা এটি true সেট করা থাকে), অ্যাপ্লিকেশনটি সম্পূর্ণরূপে পুনরায় আকার দেওয়ার পক্ষে সমর্থন করে।

বাস্তবায়ন

স্থির ওরিয়েন্টেশন বা দিক অনুপাত সহ একটি অ-সম্ভাব্য ক্রিয়াকলাপকে কোডে আকার সামঞ্জস্যতা মোড (এসসিএম) বলা হয়। শর্তটি ActivityRecord#shouldUseSizeCompatMode() যখন কোনও এসসিএম ক্রিয়াকলাপ চালু করা হয়, স্ক্রিন-সম্পর্কিত কনফিগারেশন (যেমন আকার বা ঘনত্ব) অনুরোধ করা ওভাররাইড কনফিগারেশনে স্থির করা হয়, সুতরাং ক্রিয়াকলাপটি আর বর্তমান প্রদর্শন কনফিগারেশনের উপর নির্ভর করে না।

যদি এসসিএম ক্রিয়াকলাপ পুরো স্ক্রিনটি পূরণ করতে না পারে তবে এটি শীর্ষে সারিবদ্ধ এবং অনুভূমিকভাবে কেন্দ্রিক। ক্রিয়াকলাপের সীমাগুলি AppWindowToken#calculateCompatBoundsTransformation() দ্বারা গণনা করা হয়।

যখন কোনও এসসিএম ক্রিয়াকলাপ তার ধারকটির চেয়ে আলাদা স্ক্রিন কনফিগারেশন ব্যবহার করে (উদাহরণস্বরূপ, প্রদর্শনটি পুনরায় আকার দেওয়া হয়, বা ক্রিয়াকলাপটি অন্য ডিসপ্লেতে স্থানান্তরিত হয়), ActivityRecord#inSizeCompatMode() সত্য এবং SizeCompatModeActivityController (সিস্টেম ইউআইতে) প্রক্রিয়া পুনঃস্থাপন বোতামটি দেখানোর জন্য কলব্যাকটি গ্রহণ করে।

আকার এবং দিক অনুপাত প্রদর্শন করুন

অ্যান্ড্রয়েড 10 দীর্ঘ এবং পাতলা পর্দার উচ্চ অনুপাত থেকে 1: 1 অনুপাত পর্যন্ত নতুন দিক অনুপাতের জন্য সমর্থন সরবরাহ করে। অ্যাপ্লিকেশনগুলি ApplicationInfo#maxAspectRatio এবং ApplicationInfo#minAspectRatio স্ক্রিনের যে তারা পরিচালনা করতে সক্ষম তা সংজ্ঞায়িত করতে পারে।

অ্যান্ড্রয়েড 10 এ অ্যাপ্লিকেশন অনুপাত

চিত্র 1। উদাহরণ অ্যাপ্লিকেশন অনুপাত অ্যান্ড্রয়েড 10 এ সমর্থিত

ডিভাইস বাস্তবায়নের জন্য অ্যান্ড্রয়েড 9, এবং নিম্ন (ন্যূনতম 2.5 ইঞ্চি প্রস্থ বা উচ্চতা, ন্যূনতম 320 ডিপি smallestScreenWidth জন্য ন্যূনতম 320 ডিপি) এর চেয়ে ছোট আকার এবং রেজোলিউশনগুলির সাথে গৌণ প্রদর্শন থাকতে পারে, তবে কেবলমাত্র এই ছোট্ট প্রদর্শনগুলি সমর্থন করার জন্য যে ক্রিয়াকলাপগুলি বেছে নেওয়া যায় সেখানে রাখা যেতে পারে।

অ্যাপ্লিকেশনগুলি ন্যূনতম সমর্থিত আকার ঘোষণা করে বেছে নিতে পারে যা লক্ষ্য প্রদর্শন আকারের চেয়ে ছোট বা সমান। android:minHeight এবং android:minWidth ক্রিয়াকলাপের বিন্যাসের বৈশিষ্ট্যগুলি।

নীতি প্রদর্শন

অ্যান্ড্রয়েড 10 পৃথক করে এবং PhoneWindowManager ডিফল্ট WindowManagerPolicy বাস্তবায়ন থেকে প্রতি-প্রদর্শনী ক্লাসগুলিতে নির্দিষ্ট প্রদর্শন নীতিগুলি সরিয়ে দেয় এবং সরিয়ে দেয়: যেমন:

  • রাষ্ট্র এবং ঘূর্ণন প্রদর্শন করুন
  • কিছু কী এবং গতি ইভেন্ট ট্র্যাকিং
  • সিস্টেম ইউআই এবং সজ্জা উইন্ডোজ

অ্যান্ড্রয়েড 9 (এবং নিম্ন) এ, PhoneWindowManager শ্রেণি প্রদর্শন নীতি, রাজ্য এবং সেটিংস, ঘূর্ণন, সজ্জা উইন্ডো ফ্রেম ট্র্যাকিং এবং আরও অনেক কিছু পরিচালনা করেছে। অ্যান্ড্রয়েড 10 এর বেশিরভাগটি রোটেশন ট্র্যাকিং ব্যতীত DisplayPolicy ক্লাসে স্থানান্তরিত করে, যা DisplayRotation স্থানান্তরিত হয়েছে।

উইন্ডো সেটিংস প্রদর্শন করুন

অ্যান্ড্রয়েড 10-এ, কনফিগারযোগ্য প্রতি-ডিসপ্লে উইন্ডোইং সেটিংসটি অন্তর্ভুক্ত করার জন্য প্রসারিত করা হয়েছে:

  • ডিফল্ট ডিসপ্লে উইন্ডোয়িং মোড
  • ওভারস্ক্যান মান
  • ব্যবহারকারী ঘূর্ণন এবং ঘূর্ণন মোড
  • জোর করে আকার, ঘনত্ব এবং স্কেলিং মোড
  • সামগ্রী অপসারণ মোড (যখন প্রদর্শন সরানো হয়)
  • সিস্টেম সজ্জা এবং ime জন্য সমর্থন

DisplayWindowSettings শ্রেণিতে এই বিকল্পগুলির জন্য সেটিংস রয়েছে। তারা display_settings.xml এ ডিস্ক /data পার্টিশনে অবিরত থাকে যখন কোনও সেটিংস পরিবর্তন করা হয়। বিশদগুলির জন্য, DisplayWindowSettings.AtomicFileStorage এবং DisplayWindowSettings#writeSettings() দেখুন। ডিভাইস নির্মাতারা তাদের ডিভাইস কনফিগারেশনের জন্য display_settings.xml -তে ডিফল্ট মান সরবরাহ করতে পারে। তবে, ফাইলটি /data সঞ্চিত থাকায়, কোনও মুছা দ্বারা মুছে ফেলা হলে ফাইলটি পুনরুদ্ধার করতে অতিরিক্ত যুক্তির প্রয়োজন হতে পারে।

ডিফল্টরূপে, অ্যান্ড্রয়েড 10 সেটিংস বজায় রাখার সময় DisplayInfo#uniqueId ডিসপ্লেটির সনাক্তকারী হিসাবে ব্যবহার করে। সমস্ত প্রদর্শনের জন্য uniqueId পপুলেশন করা উচিত। এছাড়াও, এটি শারীরিক এবং নেটওয়ার্ক প্রদর্শনের জন্য স্থিতিশীল। এটি সনাক্তকারী হিসাবে কোনও শারীরিক প্রদর্শনের বন্দরটি ব্যবহার করাও সম্ভব, যা DisplayWindowSettings#mIdentifier সেট করা যেতে পারে। প্রতিটি লেখার পরে, সমস্ত সেটিংস লেখা হয় তাই স্টোরেজে ডিসপ্লে এন্ট্রি করার জন্য ব্যবহৃত কীটি আপডেট করা নিরাপদ। বিশদগুলির জন্য, স্ট্যাটিক ডিসপ্লে সনাক্তকারী দেখুন।

Historical তিহাসিক কারণে সেটিংস /data ডিরেক্টরিতে অবিচল থাকে। মূলত, এগুলি ব্যবহারকারী-সেট সেটিংস যেমন ডিসপ্লে রোটেশন ধরে রাখতে ব্যবহৃত হয়েছিল।

স্ট্যাটিক ডিসপ্লে সনাক্তকারী

অ্যান্ড্রয়েড 9 (এবং নিম্ন) ফ্রেমওয়ার্কে প্রদর্শনের জন্য স্থিতিশীল সনাক্তকারী সরবরাহ করে না। সিস্টেমে যখন কোনও ডিসপ্লে যুক্ত করা হয়েছিল, তখন স্ট্যাটিক কাউন্টারকে বাড়িয়ে এই ডিসপ্লেটির জন্য Display#mDisplayId বা DisplayInfo#displayId তৈরি করা হয়েছিল। যদি সিস্টেমটি একই প্রদর্শনটি যুক্ত করে এবং সরানো হয় তবে একটি আলাদা আইডি ফলাফল।

যদি কোনও ডিভাইসে বুট থেকে একাধিক ডিসপ্লে উপলব্ধ থাকে তবে সময়গুলির উপর নির্ভর করে প্রদর্শনগুলি বিভিন্ন আইডেন্টিফায়ার বরাদ্দ করা যেতে পারে। যদিও অ্যান্ড্রয়েড 9 (এবং এর আগে) DisplayInfo#uniqueId অন্তর্ভুক্ত করেছে, এতে প্রদর্শনগুলির মধ্যে পার্থক্য করার জন্য পর্যাপ্ত তথ্য নেই কারণ শারীরিক প্রদর্শনগুলি local:0 বা local:1 হিসাবে চিহ্নিত করা হয়েছিল, অন্তর্নির্মিত এবং বাহ্যিক প্রদর্শনকে উপস্থাপন করতে।

একটি স্থিতিশীল সনাক্তকারী যুক্ত করতে এবং স্থানীয়, নেটওয়ার্ক এবং ভার্চুয়াল ডিসপ্লেগুলির মধ্যে পার্থক্য করতে অ্যান্ড্রয়েড 10 পরিবর্তনগুলি DisplayInfo#uniqueId পরিবর্তন করে।

প্রদর্শনের ধরন বিন্যাস
স্থানীয়
local:<stable-id>
নেটওয়ার্ক
network:<mac-address>
ভার্চুয়াল
virtual:<package-name-and-name>

uniqueId আপডেট করার পাশাপাশি, DisplayInfo.address DisplayAddress রয়েছে, একটি ডিসপ্লে আইডেন্টিফায়ার যা রিবুটগুলি জুড়ে স্থিতিশীল। অ্যান্ড্রয়েড 10 -এ, DisplayAddress শারীরিক এবং নেটওয়ার্ক প্রদর্শনগুলিকে সমর্থন করে। DisplayAddress.Physical একটি স্থিতিশীল ডিসপ্লে আইডি রয়েছে ( uniqueId মতো) এবং DisplayAddress#fromPhysicalDisplayId() দিয়ে তৈরি করা যেতে পারে।

অ্যান্ড্রয়েড 10 পোর্টের তথ্য ( Physical#getPort() ) পাওয়ার জন্য একটি সুবিধাজনক পদ্ধতিও সরবরাহ করে। এই পদ্ধতিটি ফ্রেমওয়ার্কে স্থিতিশীলভাবে প্রদর্শনগুলি সনাক্ত করতে ব্যবহার করা যেতে পারে। উদাহরণস্বরূপ, এটি DisplayWindowSettings ব্যবহৃত হয়)। DisplayAddress.Network ম্যাক ঠিকানা রয়েছে এবং DisplayAddress#fromMacAddress() দিয়ে তৈরি করা যেতে পারে।

এই সংযোজনগুলি ডিভাইস নির্মাতাদের স্ট্যাটিক মাল্টি-ডিসপ্লে সেট-আপগুলিতে প্রদর্শনগুলি সনাক্ত করতে এবং বিভিন্ন সিস্টেম সেটিংস এবং স্ট্যাটিক ডিসপ্লে আইডেন্টিফায়ার ব্যবহার করে বৈশিষ্ট্যগুলি যেমন শারীরিক ডিসপ্লেগুলির জন্য পোর্টগুলি কনফিগার করতে দেয়। এই পদ্ধতিগুলি লুকানো থাকে এবং কেবল system_server মধ্যে ব্যবহার করার উদ্দেশ্যে করা হয়।

একটি এইচডাব্লুসি ডিসপ্লে আইডি দেওয়া (যা অস্বচ্ছ হতে পারে এবং সর্বদা স্থিতিশীল নয়) দেওয়া হয়, এই পদ্ধতিটি (প্ল্যাটফর্ম-নির্দিষ্ট) 8-বিট পোর্ট নম্বরটি দেয় যা ডিসপ্লে আউটপুটটির জন্য কোনও শারীরিক সংযোগকারীকে চিহ্নিত করে, পাশাপাশি ডিসপ্লেটির ইডিআইডি ব্লব। ফ্রেমওয়ার্কের সংস্পর্শে থাকা স্থিতিশীল 64-বিট ডিসপ্লে আইডি তৈরি করতে EDID থেকে সারফেসফ্লিংগার প্রস্তুতকারক বা মডেল তথ্যগুলি নিষ্কাশন করে। যদি এই পদ্ধতিটি সমর্থিত না হয় বা ত্রুটিগুলি আউট না করে থাকে তবে সারফেসফ্লিংগার লিগ্যাসি এমডি মোডে ফিরে আসে, যেখানে 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"

দু'জনেরও বেশি প্রদর্শন ব্যবহার করুন

অ্যান্ড্রয়েড 9 (এবং নিম্ন) এ, সারফেসফ্লিংগার এবং DisplayManagerService হার্ড-কোডেড আইডি 0 এবং 1 সহ সর্বাধিক দুটি শারীরিক ডিসপ্লেগুলির অস্তিত্ব ধরে নিয়েছিল।

অ্যান্ড্রয়েড 10 দিয়ে শুরু করে, সারফেসফ্লিংগার স্থিতিশীল ডিসপ্লে আইডি তৈরি করতে একটি হার্ডওয়্যার সুরকার (এইচডাব্লুসি) এপিআই উপার্জন করতে পারে, যা এটি শারীরিক প্রদর্শনগুলির একটি স্বেচ্ছাসেবী সংখ্যা পরিচালনা করতে সক্ষম করে। আরও জানতে, স্ট্যাটিক ডিসপ্লে সনাক্তকারী দেখুন।

কাঠামোটি SurfaceControl#getPhysicalDisplayToken মাধ্যমে শারীরিক প্রদর্শনের জন্য IBinder টোকেনটি সন্ধান করতে পারে SurfaceControl#getPhysicalDisplayIds থেকে বা DisplayEventReceiver হটপ্লাগ ইভেন্ট থেকে 64-বিট ডিসপ্লে আইডি পাওয়ার পরে।

অ্যান্ড্রয়েড 10 (এবং নিম্ন) এ, প্রাথমিক অভ্যন্তরীণ প্রদর্শনটি TYPE_INTERNAL এবং সমস্ত মাধ্যমিক প্রদর্শনগুলি সংযোগের ধরণ নির্বিশেষে TYPE_EXTERNAL হিসাবে পতাকাঙ্কিত করা হয়। অতএব, অতিরিক্ত অভ্যন্তরীণ প্রদর্শনগুলি বাহ্যিক হিসাবে বিবেচিত হয়। কার্যকারিতা হিসাবে, ডিভাইস-নির্দিষ্ট কোডটি DisplayAddress.Physical#getPort সম্পর্কে অনুমান করতে পারে H এইচডাব্লুসিটি জানা থাকলে এবং পোর্ট বরাদ্দ যুক্তিটি অনুমানযোগ্য হয়।

এই সীমাবদ্ধতা অ্যান্ড্রয়েড 11 (এবং উচ্চতর) এ সরানো হয়েছে।

  • অ্যান্ড্রয়েড 11 -এ, বুট চলাকালীন রিপোর্ট করা প্রথম প্রদর্শনটি প্রাথমিক প্রদর্শন। সংযোগের ধরণ (অভ্যন্তরীণ বনাম বাহ্যিক) অপ্রাসঙ্গিক। যাইহোক, এটি সত্য থেকে যায় যে প্রাথমিক প্রদর্শনটি সংযোগ বিচ্ছিন্ন করা যায় না এবং অনুসরণ করে যে এটি অবশ্যই অনুশীলনে একটি অভ্যন্তরীণ প্রদর্শন হতে হবে। নোট করুন যে কিছু ফোল্ডেবল ফোনে একাধিক অভ্যন্তরীণ প্রদর্শন রয়েছে।
  • মাধ্যমিক Display.TYPE_EXTERNAL তাদের সংযোগের Display.TYPE_BUILT_IN Display.TYPE_HDMI নির্ভর করে যথাক্রমে Display.TYPE_INTERNAL

বাস্তবায়ন

অ্যান্ড্রয়েড 9 এবং নিম্নে, প্রদর্শনগুলি 32-বিট আইডি দ্বারা চিহ্নিত করা হয়, যেখানে 0 টি অভ্যন্তরীণ প্রদর্শন, 1 বাহ্যিক প্রদর্শন, [2, INT32_MAX] এইচডাব্লুসি ভার্চুয়াল ডিসপ্লে এবং -1 একটি অবৈধ প্রদর্শন বা একটি নন-এইচডাব্লুসি ভার্চুয়াল ডিসপ্লে উপস্থাপন করে।

অ্যান্ড্রয়েড 10 দিয়ে শুরু করে, ডিসপ্লেগুলি স্থিতিশীল এবং অবিরাম আইডি দেওয়া হয়, যা সারফেসফ্লিংগার এবং DisplayManagerService আরও দুটি প্রদর্শন ট্র্যাক করতে এবং পূর্বে দেখা প্রদর্শনগুলি সনাক্ত করতে দেয়। যদি এইচডব্লিউসি IComposerClient.getDisplayIdentificationData সমর্থন করে এবং প্রদর্শন সনাক্তকরণের ডেটা সরবরাহ করে, সারফেসফ্লিংগার ইডিআইডি কাঠামোটি পার্স করে এবং শারীরিক এবং এইচডাব্লুসি ভার্চুয়াল ডিসপ্লেগুলির জন্য স্থিতিশীল 64-বিট ডিসপ্লে আইডি বরাদ্দ করে। আইডিগুলি একটি বিকল্প প্রকার ব্যবহার করে প্রকাশ করা হয়, যেখানে নাল মানটি একটি অবৈধ প্রদর্শন বা নন-এইচডাব্লুসি ভার্চুয়াল ডিসপ্লে উপস্থাপন করে। এইচডব্লিউসি সমর্থন ব্যতীত, সারফেসফ্লিংগার সর্বাধিক দুটি শারীরিক ডিসপ্লে দিয়ে উত্তরাধিকার আচরণে ফিরে আসে।

প্রতি প্রদর্শন ফোকাস

To support several input sources that target individual displays at the same time, Android 10 can be configured to support multiple focused windows, at most one per-display. This is intended only for special types of devices when multiple users interact with the same device at the same time and use different input methods or devices, such as Android Automotive.

It is strongly recommended that this feature not be enabled for regular devices, including multi-screen devices or those used for desktop-like experiences. This is due primarily to a security concern that may cause users to wonder which window has input focus.

Imagine the user who enters secure information into a text input field, perhaps logging in to a banking app or entering text that contains sensitive information. A malicious app could create a virtual off-screen display with which to execute an activity, also with a text input field. Legitimate and malicious activities have focus and both display an active input indicator (blinking cursor).

However, since input from a keyboard (hardware or software) is entered into the topmost activity only (that app that was most recently launched), by creating a hidden virtual display, a malicious app could grab user input, even when using a software keyboard on the primary device display.

Use com.android.internal.R.bool.config_perDisplayFocusEnabled to set per-display focus.

সামঞ্জস্য

Issue: In Android 9 and lower, at most one window in the system has focus at a time.

Solution: In the rare case when two windows from the same process would be focused, the system provides focus only to the window that's higher in the Z-order. This restriction is removed for apps that target Android 10, at which point it's expected that they can support multiple windows being focused on simultaneously.

বাস্তবায়ন

WindowManagerService#mPerDisplayFocusEnabled controls the availability of this feature. In ActivityManager , ActivityDisplay#getFocusedStack() is now used instead of global tracking in a variable. ActivityDisplay#getFocusedStack() determines focus based on Z-order instead of caching the value. This is so that only one source, WindowManager, need track the Z-order of activities.

ActivityStackSupervisor#getTopDisplayFocusedStack() takes a similar approach for those cases when the topmost focused stack in the system must be identified. The stacks are traversed from top to bottom, searching for the first eligible stack.

InputDispatcher can now have multiple focused windows (one per display). If an input event is display-specific, then it's dispatched to the focused window in the corresponding display. Otherwise, it's dispatched to the focused window in the focused display, which is the display that the user most recently interacted with.

See InputDispatcher::mFocusedWindowHandlesByDisplay and InputDispatcher::setFocusedDisplay() . Focused apps are also updated separately in InputManagerService through NativeInputManager::setFocusedApplication() .

In WindowManager , focused windows are also tracked separately. See DisplayContent#mCurrentFocus and DisplayContent#mFocusedApp and the respective uses. Related focus tracking and updating methods have been moved from WindowManagerService to DisplayContent .