Merge "Properly handle cancel event in GlowPadView" into jb-mr1-dev
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index caabfbf..c324da92 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -1694,7 +1694,8 @@
@Override
public Context createPackageContext(String packageName, int flags)
throws NameNotFoundException {
- return createPackageContextAsUser(packageName, flags, Process.myUserHandle());
+ return createPackageContextAsUser(packageName, flags,
+ mUser != null ? mUser : Process.myUserHandle());
}
@Override
diff --git a/core/java/android/app/SearchableInfo.java b/core/java/android/app/SearchableInfo.java
index 5482f60..922ebdd 100644
--- a/core/java/android/app/SearchableInfo.java
+++ b/core/java/android/app/SearchableInfo.java
@@ -24,10 +24,12 @@
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ProviderInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
import android.os.Parcel;
import android.os.Parcelable;
+import android.os.UserHandle;
import android.text.InputType;
import android.util.AttributeSet;
import android.util.Log;
@@ -510,16 +512,25 @@
*
* @hide For use by SearchManagerService.
*/
- public static SearchableInfo getActivityMetaData(Context context, ActivityInfo activityInfo) {
+ public static SearchableInfo getActivityMetaData(Context context, ActivityInfo activityInfo,
+ int userId) {
+ Context userContext = null;
+ try {
+ userContext = context.createPackageContextAsUser("system", 0,
+ new UserHandle(userId));
+ } catch (NameNotFoundException nnfe) {
+ Log.e(LOG_TAG, "Couldn't create package context for user " + userId);
+ return null;
+ }
// for each component, try to find metadata
XmlResourceParser xml =
- activityInfo.loadXmlMetaData(context.getPackageManager(), MD_LABEL_SEARCHABLE);
+ activityInfo.loadXmlMetaData(userContext.getPackageManager(), MD_LABEL_SEARCHABLE);
if (xml == null) {
return null;
}
ComponentName cName = new ComponentName(activityInfo.packageName, activityInfo.name);
- SearchableInfo searchable = getActivityMetaData(context, xml, cName);
+ SearchableInfo searchable = getActivityMetaData(userContext, xml, cName);
xml.close();
if (DBG) {
diff --git a/core/java/android/content/pm/PackageItemInfo.java b/core/java/android/content/pm/PackageItemInfo.java
index d73aaf6..a67326e 100644
--- a/core/java/android/content/pm/PackageItemInfo.java
+++ b/core/java/android/content/pm/PackageItemInfo.java
@@ -218,7 +218,7 @@
}
return null;
}
-
+
protected void dumpFront(Printer pw, String prefix) {
if (name != null) {
pw.println(prefix + "name=" + name);
diff --git a/core/java/android/server/search/SearchManagerService.java b/core/java/android/server/search/SearchManagerService.java
index bc3efdd..de4dd88 100644
--- a/core/java/android/server/search/SearchManagerService.java
+++ b/core/java/android/server/search/SearchManagerService.java
@@ -17,6 +17,7 @@
package android.server.search;
import com.android.internal.content.PackageMonitor;
+import com.android.internal.util.IndentingPrintWriter;
import android.app.ActivityManager;
import android.app.ActivityManagerNative;
@@ -44,6 +45,8 @@
import android.util.Slog;
import android.util.SparseArray;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
import java.util.List;
/**
@@ -59,9 +62,7 @@
private final Context mContext;
// This field is initialized lazily in getSearchables(), and then never modified.
- private SparseArray<Searchables> mSearchables;
-
- private ContentObserver mGlobalSearchObserver;
+ private final SparseArray<Searchables> mSearchables = new SparseArray<Searchables>();
/**
* Initializes the Search Manager service in the provided system context.
@@ -73,29 +74,39 @@
mContext = context;
mContext.registerReceiver(new BootCompletedReceiver(),
new IntentFilter(Intent.ACTION_BOOT_COMPLETED));
- mGlobalSearchObserver = new GlobalSearchProviderObserver(
- mContext.getContentResolver());
+ mContext.registerReceiver(new UserReceiver(),
+ new IntentFilter(Intent.ACTION_USER_REMOVED));
+ new MyPackageMonitor().register(context, null, UserHandle.ALL, true);
}
- private synchronized Searchables getSearchables(int userId) {
- if (mSearchables == null) {
- new MyPackageMonitor().register(mContext, null, true);
- mSearchables = new SparseArray<Searchables>();
- }
- Searchables searchables = mSearchables.get(userId);
-
+ private Searchables getSearchables(int userId) {
long origId = Binder.clearCallingIdentity();
- boolean userExists = ((UserManager) mContext.getSystemService(Context.USER_SERVICE))
- .getUserInfo(userId) != null;
- Binder.restoreCallingIdentity(origId);
-
- if (searchables == null && userExists) {
- Log.i(TAG, "Building list of searchable activities for userId=" + userId);
- searchables = new Searchables(mContext, userId);
- searchables.buildSearchableList();
- mSearchables.append(userId, searchables);
+ try {
+ boolean userExists = ((UserManager) mContext.getSystemService(Context.USER_SERVICE))
+ .getUserInfo(userId) != null;
+ if (!userExists) return null;
+ } finally {
+ Binder.restoreCallingIdentity(origId);
}
- return searchables;
+ synchronized (mSearchables) {
+ Searchables searchables = mSearchables.get(userId);
+
+ if (searchables == null) {
+ Log.i(TAG, "Building list of searchable activities for userId=" + userId);
+ searchables = new Searchables(mContext, userId);
+ searchables.buildSearchableList();
+ mSearchables.append(userId, searchables);
+ }
+ return searchables;
+ }
+ }
+
+ private void onUserRemoved(int userId) {
+ if (userId != UserHandle.USER_OWNER) {
+ synchronized (mSearchables) {
+ mSearchables.remove(userId);
+ }
+ }
}
/**
@@ -115,6 +126,13 @@
}
}
+ private final class UserReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ onUserRemoved(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_OWNER));
+ }
+ }
+
/**
* Refreshes the "searchables" list when packages are added/removed.
*/
@@ -131,16 +149,20 @@
}
private void updateSearchables() {
- synchronized (SearchManagerService.this) {
+ final int changingUserId = getChangingUserId();
+ synchronized (mSearchables) {
// Update list of searchable activities
for (int i = 0; i < mSearchables.size(); i++) {
- getSearchables(mSearchables.keyAt(i)).buildSearchableList();
+ if (changingUserId == mSearchables.keyAt(i)) {
+ getSearchables(mSearchables.keyAt(i)).buildSearchableList();
+ break;
+ }
}
}
// Inform all listeners that the list of searchables has been updated.
Intent intent = new Intent(SearchManager.INTENT_ACTION_SEARCHABLES_CHANGED);
intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
- mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
+ mContext.sendBroadcastAsUser(intent, new UserHandle(changingUserId));
}
}
@@ -158,7 +180,7 @@
@Override
public void onChange(boolean selfChange) {
- synchronized (SearchManagerService.this) {
+ synchronized (mSearchables) {
for (int i = 0; i < mSearchables.size(); i++) {
getSearchables(mSearchables.keyAt(i)).buildSearchableList();
}
@@ -258,4 +280,17 @@
}
return null;
}
+
+ @Override
+ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
+ synchronized (mSearchables) {
+ for (int i = 0; i < mSearchables.size(); i++) {
+ ipw.print("\nUser: "); ipw.println(mSearchables.keyAt(i));
+ ipw.increaseIndent();
+ mSearchables.valueAt(i).dump(fd, ipw, args);
+ ipw.decreaseIndent();
+ }
+ }
+ }
}
diff --git a/core/java/android/server/search/Searchables.java b/core/java/android/server/search/Searchables.java
index 30ca340..a0095d6 100644
--- a/core/java/android/server/search/Searchables.java
+++ b/core/java/android/server/search/Searchables.java
@@ -34,6 +34,8 @@
import android.text.TextUtils;
import android.util.Log;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@@ -210,59 +212,64 @@
// Use intent resolver to generate list of ACTION_SEARCH & ACTION_WEB_SEARCH receivers.
List<ResolveInfo> searchList;
final Intent intent = new Intent(Intent.ACTION_SEARCH);
-
- searchList = queryIntentActivities(intent, PackageManager.GET_META_DATA);
- List<ResolveInfo> webSearchInfoList;
- final Intent webSearchIntent = new Intent(Intent.ACTION_WEB_SEARCH);
- webSearchInfoList = queryIntentActivities(webSearchIntent, PackageManager.GET_META_DATA);
+ long ident = Binder.clearCallingIdentity();
+ try {
+ searchList = queryIntentActivities(intent, PackageManager.GET_META_DATA);
- // analyze each one, generate a Searchables record, and record
- if (searchList != null || webSearchInfoList != null) {
- int search_count = (searchList == null ? 0 : searchList.size());
- int web_search_count = (webSearchInfoList == null ? 0 : webSearchInfoList.size());
- int count = search_count + web_search_count;
- long token = Binder.clearCallingIdentity();
- for (int ii = 0; ii < count; ii++) {
- // for each component, try to find metadata
- ResolveInfo info = (ii < search_count)
- ? searchList.get(ii)
- : webSearchInfoList.get(ii - search_count);
- ActivityInfo ai = info.activityInfo;
- // Check first to avoid duplicate entries.
- if (newSearchablesMap.get(new ComponentName(ai.packageName, ai.name)) == null) {
- SearchableInfo searchable = SearchableInfo.getActivityMetaData(mContext, ai);
- if (searchable != null) {
- newSearchablesList.add(searchable);
- newSearchablesMap.put(searchable.getSearchActivity(), searchable);
- if (searchable.shouldIncludeInGlobalSearch()) {
- newSearchablesInGlobalSearchList.add(searchable);
+ List<ResolveInfo> webSearchInfoList;
+ final Intent webSearchIntent = new Intent(Intent.ACTION_WEB_SEARCH);
+ webSearchInfoList = queryIntentActivities(webSearchIntent, PackageManager.GET_META_DATA);
+
+ // analyze each one, generate a Searchables record, and record
+ if (searchList != null || webSearchInfoList != null) {
+ int search_count = (searchList == null ? 0 : searchList.size());
+ int web_search_count = (webSearchInfoList == null ? 0 : webSearchInfoList.size());
+ int count = search_count + web_search_count;
+ for (int ii = 0; ii < count; ii++) {
+ // for each component, try to find metadata
+ ResolveInfo info = (ii < search_count)
+ ? searchList.get(ii)
+ : webSearchInfoList.get(ii - search_count);
+ ActivityInfo ai = info.activityInfo;
+ // Check first to avoid duplicate entries.
+ if (newSearchablesMap.get(new ComponentName(ai.packageName, ai.name)) == null) {
+ SearchableInfo searchable = SearchableInfo.getActivityMetaData(mContext, ai,
+ mUserId);
+ if (searchable != null) {
+ newSearchablesList.add(searchable);
+ newSearchablesMap.put(searchable.getSearchActivity(), searchable);
+ if (searchable.shouldIncludeInGlobalSearch()) {
+ newSearchablesInGlobalSearchList.add(searchable);
+ }
}
}
}
}
- Binder.restoreCallingIdentity(token);
- }
- List<ResolveInfo> newGlobalSearchActivities = findGlobalSearchActivities();
+ List<ResolveInfo> newGlobalSearchActivities = findGlobalSearchActivities();
- // Find the global search activity
- ComponentName newGlobalSearchActivity = findGlobalSearchActivity(
- newGlobalSearchActivities);
+ // Find the global search activity
+ ComponentName newGlobalSearchActivity = findGlobalSearchActivity(
+ newGlobalSearchActivities);
- // Find the web search activity
- ComponentName newWebSearchActivity = findWebSearchActivity(newGlobalSearchActivity);
+ // Find the web search activity
+ ComponentName newWebSearchActivity = findWebSearchActivity(newGlobalSearchActivity);
- // Store a consistent set of new values
- synchronized (this) {
- mSearchablesMap = newSearchablesMap;
- mSearchablesList = newSearchablesList;
- mSearchablesInGlobalSearchList = newSearchablesInGlobalSearchList;
- mGlobalSearchActivities = newGlobalSearchActivities;
- mCurrentGlobalSearchActivity = newGlobalSearchActivity;
- mWebSearchActivity = newWebSearchActivity;
+ // Store a consistent set of new values
+ synchronized (this) {
+ mSearchablesMap = newSearchablesMap;
+ mSearchablesList = newSearchablesList;
+ mSearchablesInGlobalSearchList = newSearchablesInGlobalSearchList;
+ mGlobalSearchActivities = newGlobalSearchActivities;
+ mCurrentGlobalSearchActivity = newGlobalSearchActivity;
+ mWebSearchActivity = newWebSearchActivity;
+ }
+ } finally {
+ Binder.restoreCallingIdentity(ident);
}
}
+
/**
* Returns a sorted list of installed search providers as per
* the following heuristics:
@@ -443,4 +450,15 @@
public synchronized ComponentName getWebSearchActivity() {
return mWebSearchActivity;
}
+
+ void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ pw.println("Searchable authorities:");
+ synchronized (this) {
+ if (mSearchablesList != null) {
+ for (SearchableInfo info: mSearchablesList) {
+ pw.print(" "); pw.println(info.getSuggestAuthority());
+ }
+ }
+ }
+ }
}
diff --git a/core/java/android/text/Html.java b/core/java/android/text/Html.java
index 35e2e4a..1aab911 100644
--- a/core/java/android/text/Html.java
+++ b/core/java/android/text/Html.java
@@ -221,10 +221,10 @@
false /* no info */);
switch(paraDir) {
case Layout.DIR_RIGHT_TO_LEFT:
- return "<p dir=rtl>";
+ return "<p dir=\"rtl\">";
case Layout.DIR_LEFT_TO_RIGHT:
default:
- return "<p dir=ltr>";
+ return "<p dir=\"ltr\">";
}
}
diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java
index a9b6e09..230f426 100644
--- a/core/java/android/view/TextureView.java
+++ b/core/java/android/view/TextureView.java
@@ -224,6 +224,8 @@
private void destroySurface() {
if (mLayer != null) {
mSurface.detachFromGLContext();
+ // SurfaceTexture owns the texture name and detachFromGLContext
+ // should have deleted it
mLayer.clearStorage();
boolean shouldRelease = true;
@@ -291,6 +293,9 @@
*/
@Override
public final void draw(Canvas canvas) {
+ // NOTE: Maintain this carefully (see View.java)
+ mPrivateFlags = (mPrivateFlags & ~PFLAG_DIRTY_MASK) | PFLAG_DRAWN;
+
applyUpdate();
applyTransformMatrix();
}
@@ -335,6 +340,10 @@
@Override
HardwareLayer getHardwareLayer() {
+ // NOTE: Maintain these two lines very carefully (see View.java)
+ mPrivateFlags |= PFLAG_DRAWN | PFLAG_DRAWING_CACHE_VALID;
+ mPrivateFlags &= ~PFLAG_DIRTY_MASK;
+
if (mLayer == null) {
if (mAttachInfo == null || mAttachInfo.mHardwareRenderer == null) {
return null;
@@ -773,6 +782,7 @@
* Invoked when the specified {@link SurfaceTexture} is about to be destroyed.
* If returns true, no rendering should happen inside the surface texture after this method
* is invoked. If returns false, the client needs to call {@link SurfaceTexture#release()}.
+ * Most applications should return true.
*
* @param surface The surface about to be destroyed
*/
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 9eb0b0f..235416e 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -1103,15 +1103,12 @@
<string name="sms_control_yes" msgid="3663725993855816807">"Разрешаване"</string>
<string name="sms_control_no" msgid="625438561395534982">"Отказване"</string>
<string name="sms_short_code_confirm_message" msgid="1645436466285310855">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> иска да изпрати съобщение до <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>."</string>
- <!-- no translation found for sms_short_code_details (3492025719868078457) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_details (5523826349105123687) -->
- <skip />
+ <string name="sms_short_code_details" msgid="3492025719868078457">"Това "<font fgcolor="#ffffb060">"може да доведе до таксуване"</font>" на мобилната ви сметка."</string>
+ <string name="sms_premium_short_code_details" msgid="5523826349105123687"><font fgcolor="#ffffb060">"Това ще доведе до таксуване на мобилната ви сметка."</font></string>
<string name="sms_short_code_confirm_allow" msgid="4458878637111023413">"Изпращане"</string>
<string name="sms_short_code_confirm_deny" msgid="2927389840209170706">"Отказ"</string>
<string name="sms_short_code_remember_choice" msgid="5289538592272218136">"Изборът ми да се запомни"</string>
- <!-- no translation found for sms_short_code_remember_undo_instruction (4960944133052287484) -->
- <skip />
+ <string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"Можете да промените това по-късно в „Настройки“ > „Приложения“"</string>
<string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"Винаги да се разрешава"</string>
<string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"Никога да не се разрешава"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"SIM картата е премахната"</string>
@@ -1371,20 +1368,15 @@
<string name="default_audio_route_name" product="default" msgid="4239291273420140123">"Телефон"</string>
<string name="default_audio_route_name_headphones" msgid="8119971843803439110">"Слушалки"</string>
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Докинг станц.: Високогов."</string>
- <!-- no translation found for default_media_route_name_hdmi (2450970399023478055) -->
- <skip />
+ <string name="default_media_route_name_hdmi" msgid="2450970399023478055">"HDMI"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Система"</string>
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Звук през Bluetooth"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Готово"</string>
<string name="media_route_button_content_description" msgid="5758553567065145276">"Изходяща мултимедия"</string>
- <!-- no translation found for media_route_status_scanning (7279908761758293783) -->
- <skip />
- <!-- no translation found for media_route_status_connecting (6422571716007825440) -->
- <skip />
- <!-- no translation found for media_route_status_available (6983258067194649391) -->
- <skip />
- <!-- no translation found for media_route_status_not_available (6739899962681886401) -->
- <skip />
+ <string name="media_route_status_scanning" msgid="7279908761758293783">"Сканира се..."</string>
+ <string name="media_route_status_connecting" msgid="6422571716007825440">"Установява се връзка..."</string>
+ <string name="media_route_status_available" msgid="6983258067194649391">"Налице"</string>
+ <string name="media_route_status_not_available" msgid="6739899962681886401">"Не е налице"</string>
<string name="display_manager_built_in_display_name" msgid="2583134294292563941">"Вграден екран"</string>
<string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"Екран „HDMI“"</string>
<string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Наслагване №<xliff:g id="ID">%1$d</xliff:g>"</string>
@@ -1399,21 +1391,15 @@
<string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Въведете ПИН кода за SIM картата"</string>
<string name="kg_pin_instructions" msgid="2377242233495111557">"Въведете ПИН код"</string>
<string name="kg_password_instructions" msgid="5753646556186936819">"Въведете паролата"</string>
- <!-- no translation found for kg_puk_enter_puk_hint (453227143861735537) -->
- <skip />
- <!-- no translation found for kg_puk_enter_pin_hint (7871604527429602024) -->
- <skip />
- <!-- no translation found for kg_enter_confirm_pin_hint (325676184762529976) -->
- <skip />
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM картата вече е деактивирана. Въведете PUK кода, за да продължите. Свържете се с оператора за подробности."</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Въведете желания ПИН код"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Потвърдете желания ПИН код"</string>
<string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM картата се отключва…"</string>
<string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Неправилен ПИН код."</string>
<string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Въведете ПИН код с четири до осем цифри."</string>
- <!-- no translation found for kg_invalid_sim_puk_hint (7553388325654369575) -->
- <skip />
- <!-- no translation found for kg_invalid_puk (3638289409676051243) -->
- <skip />
- <!-- no translation found for kg_invalid_confirm_pin_hint (7003469261464593516) -->
- <skip />
+ <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK кодът трябва да е с 8 или повече цифри."</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"Въведете отново правилния PUK код. Многократните опити ще деактивират за постоянно SIM картата."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"ПИН кодовете не съвпадат"</string>
<string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Опитите за фигурата са твърде много"</string>
<string name="kg_login_instructions" msgid="1100551261265506448">"За да отключите, влезте с профила си в Google."</string>
<string name="kg_login_username_hint" msgid="5718534272070920364">"Потребителско име (имейл)"</string>
@@ -1421,8 +1407,7 @@
<string name="kg_login_submit_button" msgid="5355904582674054702">"Вход"</string>
<string name="kg_login_invalid_input" msgid="5754664119319872197">"Невалидно потребителско име или парола."</string>
<string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Забравили сте потребителското име или паролата си?"\n"Посетете "<b>"google.com/accounts/recovery"</b>"."</string>
- <!-- no translation found for kg_login_checking_password (5316091912653672681) -->
- <skip />
+ <string name="kg_login_checking_password" msgid="5316091912653672681">"SIM картата се отключва…"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Въведохте неправилно ПИН кода си <xliff:g id="NUMBER_0">%d</xliff:g> пъти. "\n\n"Опитайте отново след <xliff:g id="NUMBER_1">%d</xliff:g> секунди."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Въведохте неправилно паролата си <xliff:g id="NUMBER_0">%d</xliff:g> пъти. "\n\n"Опитайте отново след <xliff:g id="NUMBER_1">%d</xliff:g> секунди."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Начертахте неправилно фигурата си за отключване <xliff:g id="NUMBER_0">%d</xliff:g> пъти. "\n\n"Опитайте отново след <xliff:g id="NUMBER_1">%d</xliff:g> секунди."</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 8bd9a46..103aded 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -810,14 +810,10 @@
<string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Corak dipadamkan"</string>
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Sel ditambahkan"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Corak siap"</string>
- <!-- no translation found for keyguard_accessibility_widget_changed (5678624624681400191) -->
- <skip />
- <!-- no translation found for keyguard_accessibility_user_selector (1226798370913698896) -->
- <skip />
- <!-- no translation found for keyguard_accessibility_status (8008264603935930611) -->
- <skip />
- <!-- no translation found for keygaurd_accessibility_media_controls (262209654292161806) -->
- <skip />
+ <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d dari %3$d."</string>
+ <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Pemilih pengguna"</string>
+ <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Status"</string>
+ <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Kawalan media"</string>
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
@@ -1107,15 +1103,12 @@
<string name="sms_control_yes" msgid="3663725993855816807">"Benarkan"</string>
<string name="sms_control_no" msgid="625438561395534982">"Nafikan"</string>
<string name="sms_short_code_confirm_message" msgid="1645436466285310855">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ingin menghantar mesej kepada <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>."</string>
- <!-- no translation found for sms_short_code_details (3492025719868078457) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_details (5523826349105123687) -->
- <skip />
+ <string name="sms_short_code_details" msgid="3492025719868078457"><font fgcolor="#ffffb060">"ini boleh menyebabkan caj dikenakan"</font>" kepada akaun mudah alih anda."</string>
+ <string name="sms_premium_short_code_details" msgid="5523826349105123687"><font fgcolor="#ffffb060">"Ini akan menyebabkan caj dikenakan kepada akaun mudah alih anda."</font></string>
<string name="sms_short_code_confirm_allow" msgid="4458878637111023413">"Hantar"</string>
<string name="sms_short_code_confirm_deny" msgid="2927389840209170706">"Batal"</string>
<string name="sms_short_code_remember_choice" msgid="5289538592272218136">"Ingat pilihan saya"</string>
- <!-- no translation found for sms_short_code_remember_undo_instruction (4960944133052287484) -->
- <skip />
+ <string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"Anda boleh menukar ini nanti dalam Tetapan > Apl"</string>
<string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"Sentiasa Benarkan"</string>
<string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"Jangan Benarkan"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"Kad SIM dikeluarkan"</string>
@@ -1375,20 +1368,15 @@
<string name="default_audio_route_name" product="default" msgid="4239291273420140123">"Telefon"</string>
<string name="default_audio_route_name_headphones" msgid="8119971843803439110">"Fon kepala"</string>
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Pembesar suara dok"</string>
- <!-- no translation found for default_media_route_name_hdmi (2450970399023478055) -->
- <skip />
+ <string name="default_media_route_name_hdmi" msgid="2450970399023478055">"HDMI"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistem"</string>
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Audio Bluetooth"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Selesai"</string>
<string name="media_route_button_content_description" msgid="5758553567065145276">"Output media"</string>
- <!-- no translation found for media_route_status_scanning (7279908761758293783) -->
- <skip />
- <!-- no translation found for media_route_status_connecting (6422571716007825440) -->
- <skip />
- <!-- no translation found for media_route_status_available (6983258067194649391) -->
- <skip />
- <!-- no translation found for media_route_status_not_available (6739899962681886401) -->
- <skip />
+ <string name="media_route_status_scanning" msgid="7279908761758293783">"Mengimbas…"</string>
+ <string name="media_route_status_connecting" msgid="6422571716007825440">"Menyambung..."</string>
+ <string name="media_route_status_available" msgid="6983258067194649391">"Tersedia"</string>
+ <string name="media_route_status_not_available" msgid="6739899962681886401">"Tidak tersedia"</string>
<string name="display_manager_built_in_display_name" msgid="2583134294292563941">"Skrin Terbina Dalam"</string>
<string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"Skrin HDMI"</string>
<string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Tindih #<xliff:g id="ID">%1$d</xliff:g>"</string>
@@ -1403,21 +1391,15 @@
<string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Masukkan PIN SIM"</string>
<string name="kg_pin_instructions" msgid="2377242233495111557">"Masukkan PIN"</string>
<string name="kg_password_instructions" msgid="5753646556186936819">"Masukkan Kata Laluan"</string>
- <!-- no translation found for kg_puk_enter_puk_hint (453227143861735537) -->
- <skip />
- <!-- no translation found for kg_puk_enter_pin_hint (7871604527429602024) -->
- <skip />
- <!-- no translation found for kg_enter_confirm_pin_hint (325676184762529976) -->
- <skip />
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM kini dilumpuhkan. Masukkan kod PUK untuk meneruskan. Hubungi pembawa untuk butiran."</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Masukkan kod PIN yang diingini"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Sahkan kod PIN yang diingini"</string>
<string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Membuka kunci kad SIM..."</string>
<string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Kod PIN salah."</string>
<string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Taipkan PIN yang mengandungi 4 hingga 8 nombor."</string>
- <!-- no translation found for kg_invalid_sim_puk_hint (7553388325654369575) -->
- <skip />
- <!-- no translation found for kg_invalid_puk (3638289409676051243) -->
- <skip />
- <!-- no translation found for kg_invalid_confirm_pin_hint (7003469261464593516) -->
- <skip />
+ <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"Kod PUK mestilah 8 nombor atau lebih."</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"Masukkan semula kod PIN yang betul. Percubaan berulang akan melumpuhkan SIM secara kekal."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Kod PIN tidak sepadan"</string>
<string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Terlalu banyak percubaan melukis corak"</string>
<string name="kg_login_instructions" msgid="1100551261265506448">"Untuk membuka kunci, log masuk dengan akaun Google anda."</string>
<string name="kg_login_username_hint" msgid="5718534272070920364">"Nama Pengguna (E-mel)"</string>
@@ -1425,8 +1407,7 @@
<string name="kg_login_submit_button" msgid="5355904582674054702">"Log masuk"</string>
<string name="kg_login_invalid_input" msgid="5754664119319872197">"Nama pengguna atau kata laluan tidak sah."</string>
<string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Lupa nama pengguna atau kata laluan anda?"\n"Lawati"<b>"google.com/accounts/recovery"</b>"."</string>
- <!-- no translation found for kg_login_checking_password (5316091912653672681) -->
- <skip />
+ <string name="kg_login_checking_password" msgid="5316091912653672681">"Membuka kunci SIM..."</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Anda telah menaip PIN anda secara salah sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. "\n\n"Cuba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> saat."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Anda telah menaip kata laluan anda secara salah sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. "\n\n"Cuba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> saat."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Anda telah tersilap melukis corak buka kunci anda sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. "\n\n"Cuba lagi dalam <xliff:g id="NUMBER_1">%d</xliff:g> saat."</string>
@@ -1437,11 +1418,8 @@
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Anda telah tersilap melukis corak buka kunci sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, anda akan diminta membuka kunci tablet anda menggunakan log masuk Google anda."\n\n" Cuba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> saat."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Anda telah tersilap lukis corak buka kunci sebanyak <xliff:g id="NUMBER_0">%d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%d</xliff:g> lagi percubaan yang tidak berjaya, anda akan diminta membuka kunci telefon anda menggunakan log masuk Google anda."\n\n" Cuba lagi dalam <xliff:g id="NUMBER_2">%d</xliff:g> saat."</string>
<string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Tingkatkan kelantangan di atas tahap selamat?"\n"Mendengar pada kelantangan tinggi untuk tempoh yang panjang boleh merosakkan pendengaran anda."</string>
- <!-- no translation found for continue_to_enable_accessibility (2184747411804432885) -->
- <skip />
+ <string name="continue_to_enable_accessibility" msgid="2184747411804432885">"Teruskan menahan dengan dua jari anda untuk mendayakan kebolehcapaian."</string>
<string name="accessibility_enabled" msgid="1381972048564547685">"Kebolehcapaian didayakan."</string>
- <!-- no translation found for enable_accessibility_canceled (3833923257966635673) -->
- <skip />
- <!-- no translation found for user_switched (3768006783166984410) -->
- <skip />
+ <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Kebolehcapaian dibatalkan."</string>
+ <string name="user_switched" msgid="3768006783166984410">"Pengguna semasa <xliff:g id="NAME">%1$s</xliff:g>."</string>
</resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index b2f9595..f780443 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -1103,15 +1103,12 @@
<string name="sms_control_yes" msgid="3663725993855816807">"Tillat"</string>
<string name="sms_control_no" msgid="625438561395534982">"Sperr"</string>
<string name="sms_short_code_confirm_message" msgid="1645436466285310855">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ønsker å sende en melding til <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>."</string>
- <!-- no translation found for sms_short_code_details (3492025719868078457) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_details (5523826349105123687) -->
- <skip />
+ <string name="sms_short_code_details" msgid="3492025719868078457">"Dette "<font fgcolor="#ffffb060">"kan føre til belastninger"</font>" på mobilkontoen din."</string>
+ <string name="sms_premium_short_code_details" msgid="5523826349105123687"><font fgcolor="#ffffb060">"Dette kommer til å føre til belastninger på mobilkontoen din."</font></string>
<string name="sms_short_code_confirm_allow" msgid="4458878637111023413">"Send"</string>
<string name="sms_short_code_confirm_deny" msgid="2927389840209170706">"Avbryt"</string>
<string name="sms_short_code_remember_choice" msgid="5289538592272218136">"Husk valget mitt"</string>
- <!-- no translation found for sms_short_code_remember_undo_instruction (4960944133052287484) -->
- <skip />
+ <string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"Du kan endre dette senere i Innstillinger > Apper"</string>
<string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"Alltid tillat"</string>
<string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"Aldri tillat"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"SIM-kort er fjernet"</string>
@@ -1371,20 +1368,15 @@
<string name="default_audio_route_name" product="default" msgid="4239291273420140123">"Telefon"</string>
<string name="default_audio_route_name_headphones" msgid="8119971843803439110">"Hodetelefoner"</string>
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Dokkhøyttalere"</string>
- <!-- no translation found for default_media_route_name_hdmi (2450970399023478055) -->
- <skip />
+ <string name="default_media_route_name_hdmi" msgid="2450970399023478055">"HDMI"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"System"</string>
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth-lyd"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Fullført"</string>
<string name="media_route_button_content_description" msgid="5758553567065145276">"Medieutgang"</string>
- <!-- no translation found for media_route_status_scanning (7279908761758293783) -->
- <skip />
- <!-- no translation found for media_route_status_connecting (6422571716007825440) -->
- <skip />
- <!-- no translation found for media_route_status_available (6983258067194649391) -->
- <skip />
- <!-- no translation found for media_route_status_not_available (6739899962681886401) -->
- <skip />
+ <string name="media_route_status_scanning" msgid="7279908761758293783">"Skanner ..."</string>
+ <string name="media_route_status_connecting" msgid="6422571716007825440">"Kobler til ..."</string>
+ <string name="media_route_status_available" msgid="6983258067194649391">"Tilgjengelig"</string>
+ <string name="media_route_status_not_available" msgid="6739899962681886401">"Ikke tilgjengelig"</string>
<string name="display_manager_built_in_display_name" msgid="2583134294292563941">"Innebygd skjerm"</string>
<string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"HDMI-skjerm"</string>
<string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Overlegg #<xliff:g id="ID">%1$d</xliff:g>"</string>
@@ -1399,21 +1391,15 @@
<string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Skriv inn PIN-koden for SIM-kortet"</string>
<string name="kg_pin_instructions" msgid="2377242233495111557">"Skriv inn PIN-koden"</string>
<string name="kg_password_instructions" msgid="5753646556186936819">"Skriv inn passordet"</string>
- <!-- no translation found for kg_puk_enter_puk_hint (453227143861735537) -->
- <skip />
- <!-- no translation found for kg_puk_enter_pin_hint (7871604527429602024) -->
- <skip />
- <!-- no translation found for kg_enter_confirm_pin_hint (325676184762529976) -->
- <skip />
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM-kortet er nå deaktivert. Skriv inn PUK-koden for å fortsette. Ta kontakt med operatøren for mer informasjon."</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Tast inn ønsket PIN-kode"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Bekreft ønsket PIN-kode"</string>
<string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Låser opp SIM-kortet ..."</string>
<string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Feil PIN-kode."</string>
<string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Skriv inn en PIN-kode på fire til åtte sifre."</string>
- <!-- no translation found for kg_invalid_sim_puk_hint (7553388325654369575) -->
- <skip />
- <!-- no translation found for kg_invalid_puk (3638289409676051243) -->
- <skip />
- <!-- no translation found for kg_invalid_confirm_pin_hint (7003469261464593516) -->
- <skip />
+ <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"PUK-koden skal være på åtte eller flere siffer."</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"Skriv inn den korrekte PUK-koden på nytt. Gjentatte forsøk kommer til å deaktivere SIM-kortet."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN-kodene stemmer ikke overens"</string>
<string name="kg_login_too_many_attempts" msgid="6486842094005698475">"For mange forsøk på tegning av mønster"</string>
<string name="kg_login_instructions" msgid="1100551261265506448">"Logg deg på med Google-kontoen din for å låse opp."</string>
<string name="kg_login_username_hint" msgid="5718534272070920364">"Brukernavn (e-postadresse)"</string>
@@ -1421,8 +1407,7 @@
<string name="kg_login_submit_button" msgid="5355904582674054702">"Logg på"</string>
<string name="kg_login_invalid_input" msgid="5754664119319872197">"Ugyldig brukernavn eller passord."</string>
<string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Har du glemt brukernavnet eller passordet?"\n"Gå til "<b>"google.com/accounts/recovery"</b>"."</string>
- <!-- no translation found for kg_login_checking_password (5316091912653672681) -->
- <skip />
+ <string name="kg_login_checking_password" msgid="5316091912653672681">"Låser opp SIM-kortet ..."</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Du har oppgitt feil PIN-kode <xliff:g id="NUMBER_0">%d</xliff:g> ganger. "\n\n"Prøv på nytt om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Du har tastet inn passordet ditt feil <xliff:g id="NUMBER_0">%d</xliff:g> ganger. "\n\n"Prøv på nytt om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Du har tegnet opplåsningsmønsteret ditt feil <xliff:g id="NUMBER_0">%d</xliff:g> ganger. "\n\n"Prøv på nytt om <xliff:g id="NUMBER_1">%d</xliff:g> sekunder."</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index d0d26a1..e95ed6d 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -810,14 +810,10 @@
<string name="lockscreen_access_pattern_cleared" msgid="5583479721001639579">"Padrão apagado"</string>
<string name="lockscreen_access_pattern_cell_added" msgid="6756031208359292487">"Célula adicionada"</string>
<string name="lockscreen_access_pattern_detected" msgid="4988730895554057058">"Padrão concluído"</string>
- <!-- no translation found for keyguard_accessibility_widget_changed (5678624624681400191) -->
- <skip />
- <!-- no translation found for keyguard_accessibility_user_selector (1226798370913698896) -->
- <skip />
- <!-- no translation found for keyguard_accessibility_status (8008264603935930611) -->
- <skip />
- <!-- no translation found for keygaurd_accessibility_media_controls (262209654292161806) -->
- <skip />
+ <string name="keyguard_accessibility_widget_changed" msgid="5678624624681400191">"%1$s. Widget %2$d de %3$d."</string>
+ <string name="keyguard_accessibility_user_selector" msgid="1226798370913698896">"Seletor de usuários"</string>
+ <string name="keyguard_accessibility_status" msgid="8008264603935930611">"Status"</string>
+ <string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"Controles de mídia"</string>
<string name="password_keyboard_label_symbol_key" msgid="992280756256536042">"?123"</string>
<string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
<string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
@@ -1422,11 +1418,8 @@
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas incorretas, será solicitado que você use o login do Google para desbloquear seu tablet."\n\n" Tente novamente em <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Você desenhou sua sequência de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas incorretas, será solicitado que você use o login do Google para desbloquear."\n\n" Tente novamente em <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
<string name="safe_media_volume_warning" product="default" msgid="7382971871993371648">"Aumentar o volume acima do nível seguro?"\n"A audição em volume elevado por períodos longos pode prejudicar sua audição."</string>
- <!-- no translation found for continue_to_enable_accessibility (2184747411804432885) -->
- <skip />
+ <string name="continue_to_enable_accessibility" msgid="2184747411804432885">"Mantenha pressionado com dois dedos para ativar a acessibilidade."</string>
<string name="accessibility_enabled" msgid="1381972048564547685">"Acessibilidade ativada."</string>
- <!-- no translation found for enable_accessibility_canceled (3833923257966635673) -->
- <skip />
- <!-- no translation found for user_switched (3768006783166984410) -->
- <skip />
+ <string name="enable_accessibility_canceled" msgid="3833923257966635673">"Acessibilidade cancelada."</string>
+ <string name="user_switched" msgid="3768006783166984410">"Usuário atual <xliff:g id="NAME">%1$s</xliff:g>."</string>
</resources>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 7825e7d..6e6671b 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -1103,15 +1103,12 @@
<string name="sms_control_yes" msgid="3663725993855816807">"Permiteţi"</string>
<string name="sms_control_no" msgid="625438561395534982">"Refuzaţi"</string>
<string name="sms_short_code_confirm_message" msgid="1645436466285310855">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> intenţionează să trimită un mesaj la <b><xliff:g id="DEST_ADDRESS">%2$s</xliff:g></b>."</string>
- <!-- no translation found for sms_short_code_details (3492025719868078457) -->
- <skip />
- <!-- no translation found for sms_premium_short_code_details (5523826349105123687) -->
- <skip />
+ <string name="sms_short_code_details" msgid="3492025719868078457">"Aceasta "<font fgcolor="#ffffb060">"poate genera costuri"</font>" în contul dvs. mobil."</string>
+ <string name="sms_premium_short_code_details" msgid="5523826349105123687"><font fgcolor="#ffffb060">"Aceasta va genera costuri în contul dvs. mobil."</font></string>
<string name="sms_short_code_confirm_allow" msgid="4458878637111023413">"Trimiteţi"</string>
<string name="sms_short_code_confirm_deny" msgid="2927389840209170706">"Anulaţi"</string>
<string name="sms_short_code_remember_choice" msgid="5289538592272218136">"Doresc să se reţină opţiunea"</string>
- <!-- no translation found for sms_short_code_remember_undo_instruction (4960944133052287484) -->
- <skip />
+ <string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"Puteţi modifica ulterior în Setări > Aplicaţii"</string>
<string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"Permiteţi întotdeauna"</string>
<string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"Nu permiteţi niciodată"</string>
<string name="sim_removed_title" msgid="6227712319223226185">"Card SIM eliminat"</string>
@@ -1371,20 +1368,15 @@
<string name="default_audio_route_name" product="default" msgid="4239291273420140123">"Telefon"</string>
<string name="default_audio_route_name_headphones" msgid="8119971843803439110">"Căşti"</string>
<string name="default_audio_route_name_dock_speakers" msgid="6240602982276591864">"Difuz. dispozit. andocare"</string>
- <!-- no translation found for default_media_route_name_hdmi (2450970399023478055) -->
- <skip />
+ <string name="default_media_route_name_hdmi" msgid="2450970399023478055">"HDMI"</string>
<string name="default_audio_route_category_name" msgid="3722811174003886946">"Sistem"</string>
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Audio Bluetooth"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Terminat"</string>
<string name="media_route_button_content_description" msgid="5758553567065145276">"Rezultate media"</string>
- <!-- no translation found for media_route_status_scanning (7279908761758293783) -->
- <skip />
- <!-- no translation found for media_route_status_connecting (6422571716007825440) -->
- <skip />
- <!-- no translation found for media_route_status_available (6983258067194649391) -->
- <skip />
- <!-- no translation found for media_route_status_not_available (6739899962681886401) -->
- <skip />
+ <string name="media_route_status_scanning" msgid="7279908761758293783">"Se scanează..."</string>
+ <string name="media_route_status_connecting" msgid="6422571716007825440">"Se conectează..."</string>
+ <string name="media_route_status_available" msgid="6983258067194649391">"Disponibilă"</string>
+ <string name="media_route_status_not_available" msgid="6739899962681886401">"Indisponibilă"</string>
<string name="display_manager_built_in_display_name" msgid="2583134294292563941">"Ecran încorporat"</string>
<string name="display_manager_hdmi_display_name" msgid="1555264559227470109">"Ecran HDMI"</string>
<string name="display_manager_overlay_display_name" msgid="5142365982271620716">"Suprapunerea <xliff:g id="ID">%1$d</xliff:g>"</string>
@@ -1399,21 +1391,15 @@
<string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Introduceţi codul PIN al cardului SIM"</string>
<string name="kg_pin_instructions" msgid="2377242233495111557">"Introduceţi codul PIN"</string>
<string name="kg_password_instructions" msgid="5753646556186936819">"Introduceţi parola"</string>
- <!-- no translation found for kg_puk_enter_puk_hint (453227143861735537) -->
- <skip />
- <!-- no translation found for kg_puk_enter_pin_hint (7871604527429602024) -->
- <skip />
- <!-- no translation found for kg_enter_confirm_pin_hint (325676184762529976) -->
- <skip />
+ <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"Cardul SIM este acum dezactivat. Introduceţi codul PUK pentru a continua. Contactaţi operatorul pentru mai multe detalii."</string>
+ <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Introduceţi codul PIN dorit"</string>
+ <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Confirmaţi codul PIN dorit"</string>
<string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Se deblochează cardul SIM..."</string>
<string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Cod PIN incorect."</string>
<string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Introduceţi un cod PIN format din 4 până la 8 cifre."</string>
- <!-- no translation found for kg_invalid_sim_puk_hint (7553388325654369575) -->
- <skip />
- <!-- no translation found for kg_invalid_puk (3638289409676051243) -->
- <skip />
- <!-- no translation found for kg_invalid_confirm_pin_hint (7003469261464593516) -->
- <skip />
+ <string name="kg_invalid_sim_puk_hint" msgid="7553388325654369575">"Codul PUK trebuie să aibă minimum 8 cifre."</string>
+ <string name="kg_invalid_puk" msgid="3638289409676051243">"Reintroduceţi codul PUK corect. Încercările repetate vor dezactiva definitiv cardul SIM."</string>
+ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Codurile PIN nu coincid"</string>
<string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Prea multe încercări de desenare a modelului"</string>
<string name="kg_login_instructions" msgid="1100551261265506448">"Pentru a debloca, conectaţi-vă cu Contul dvs. Google."</string>
<string name="kg_login_username_hint" msgid="5718534272070920364">"Nume de utilizator (e-mail)"</string>
@@ -1421,8 +1407,7 @@
<string name="kg_login_submit_button" msgid="5355904582674054702">"Conectaţi-vă"</string>
<string name="kg_login_invalid_input" msgid="5754664119319872197">"Nume de utilizator sau parolă nevalide."</string>
<string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Aţi uitat numele de utilizator sau parola?"\n"Accesaţi "<b>"google.com/accounts/recovery"</b>"."</string>
- <!-- no translation found for kg_login_checking_password (5316091912653672681) -->
- <skip />
+ <string name="kg_login_checking_password" msgid="5316091912653672681">"Se deblochează cardul SIM…"</string>
<string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"Aţi introdus incorect codul PIN de <xliff:g id="NUMBER_0">%d</xliff:g> ori."\n\n"Încercaţi din nou peste <xliff:g id="NUMBER_1">%d</xliff:g> (de) secunde."</string>
<string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"Aţi introdus incorect parola de <xliff:g id="NUMBER_0">%d</xliff:g> ori. "\n\n"Încercaţi din nou peste <xliff:g id="NUMBER_1">%d</xliff:g> (de) secunde."</string>
<string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"Aţi desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%d</xliff:g> ori. "\n\n"Încercaţi din nou peste <xliff:g id="NUMBER_1">%d</xliff:g> (de) secunde."</string>
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index 7853ae4..d18a5b0 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -418,6 +418,7 @@
if (!scissorEnabled) {
glEnable(GL_SCISSOR_TEST);
scissorEnabled = true;
+ resetScissor();
return true;
}
return false;
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 7c23e4b..cc536f2 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -2076,7 +2076,7 @@
setupDrawShader();
setupDrawBlending(isAA, mode);
setupDrawProgram();
- setupDrawModelViewIdentity();
+ setupDrawModelViewIdentity(true);
setupDrawColorUniforms();
setupDrawColorFilterUniforms();
setupDrawShaderIdentityUniforms();
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index b334bb3..7d17391 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -1750,6 +1750,10 @@
}
}
+ // apply new ringer mode before checking volume for alias streams so that streams
+ // muted by ringer mode have the correct volume
+ setRingerModeInt(getRingerMode(), false);
+
checkAllAliasStreamVolumes();
synchronized (mSafeMediaVolumeState) {
@@ -1757,9 +1761,6 @@
enforceSafeMediaVolume();
}
}
-
- // apply new ringer mode
- setRingerModeInt(getRingerMode(), false);
}
/** @see AudioManager#setSpeakerphoneOn() */
@@ -2575,9 +2576,10 @@
AudioSystem.initStreamVolume(streamType, 0, mIndexMax);
mIndexMax *= 10;
- readSettings();
-
+ // mDeathHandlers must be created before calling readSettings()
mDeathHandlers = new ArrayList<VolumeDeathHandler>();
+
+ readSettings();
}
public String getSettingNameForDevice(boolean lastAudible, int device) {
@@ -2597,7 +2599,9 @@
// do not read system stream volume from settings: this stream is always aliased
// to another stream type and its volume is never persisted. Values in settings can
// only be stale values
- if ((mStreamType == AudioSystem.STREAM_SYSTEM) ||
+ // on first call to readSettings() at init time, muteCount() is always 0 so we will
+ // always create entries for default device
+ if ((muteCount() == 0) && (mStreamType == AudioSystem.STREAM_SYSTEM) ||
(mStreamType == AudioSystem.STREAM_SYSTEM_ENFORCED)) {
mLastAudibleIndex.put(AudioSystem.DEVICE_OUT_DEFAULT,
10 * AudioManager.DEFAULT_STREAM_VOLUME[mStreamType]);
@@ -2613,6 +2617,14 @@
}
remainingDevices &= ~device;
+ // ignore settings for fixed volume devices: volume should always be at max
+ if ((muteCount() == 0) &&
+ (mStreamVolumeAlias[mStreamType] == AudioSystem.STREAM_MUSIC) &&
+ ((device & mFixedVolumeDevices) != 0)) {
+ mIndex.put(device, mIndexMax);
+ mLastAudibleIndex.put(device, mIndexMax);
+ continue;
+ }
// retrieve current volume for device
String name = getSettingNameForDevice(false /* lastAudible */, device);
// if no volume stored for current stream and device, use default volume if default
@@ -2798,7 +2810,12 @@
int device = ((Integer)entry.getKey()).intValue();
int index = ((Integer)entry.getValue()).intValue();
index = rescaleIndex(index, srcStream.getStreamType(), mStreamType);
- setIndex(index, device, lastAudible);
+
+ if (lastAudible) {
+ setLastAudibleIndex(index, device);
+ } else {
+ setIndex(index, device, false /* lastAudible */);
+ }
}
}
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index cdf30b3..64b660f 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -205,7 +205,7 @@
<activity android:name=".Somnambulator"
android:label="@string/start_dreams"
- android:icon="@mipmap/ic_dreams"
+ android:icon="@mipmap/ic_launcher_dreams"
android:theme="@android:style/Theme.Wallpaper.NoTitleBar"
android:exported="true"
android:excludeFromRecents="true"
diff --git a/packages/SystemUI/res/mipmap-hdpi/ic_launcher_dreams.png b/packages/SystemUI/res/mipmap-hdpi/ic_launcher_dreams.png
new file mode 100644
index 0000000..a335d6d
--- /dev/null
+++ b/packages/SystemUI/res/mipmap-hdpi/ic_launcher_dreams.png
Binary files differ
diff --git a/packages/SystemUI/res/mipmap-mdpi/ic_launcher_dreams.png b/packages/SystemUI/res/mipmap-mdpi/ic_launcher_dreams.png
new file mode 100644
index 0000000..ef2e27b
--- /dev/null
+++ b/packages/SystemUI/res/mipmap-mdpi/ic_launcher_dreams.png
Binary files differ
diff --git a/packages/SystemUI/res/mipmap-xhdpi/ic_launcher_dreams.png b/packages/SystemUI/res/mipmap-xhdpi/ic_launcher_dreams.png
new file mode 100644
index 0000000..7b42cb4
--- /dev/null
+++ b/packages/SystemUI/res/mipmap-xhdpi/ic_launcher_dreams.png
Binary files differ
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 7060d0d..7c4e690 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -154,7 +154,7 @@
<string name="start_dreams" msgid="6170089063982549905">"Ruhezustand ein"</string>
<string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
<string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"Flugmodus"</string>
- <string name="quick_settings_battery_charging_label" msgid="490074774465309209">"Akku wird aufgeladen (<xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>)"</string>
+ <string name="quick_settings_battery_charging_label" msgid="490074774465309209">"Lädt, <xliff:g id="NUMBER">%d</xliff:g> <xliff:g id="PERCENT">%%</xliff:g>"</string>
<string name="quick_settings_battery_charged_label" msgid="8865413079414246081">"Aufgeladen"</string>
<string name="quick_settings_bluetooth_label" msgid="6304190285170721401">"Bluetooth"</string>
<string name="quick_settings_bluetooth_multiple_devices_label" msgid="3912245565613684735">"Bluetooth (<xliff:g id="NUMBER">%d</xliff:g> Geräte)"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 425a09f..4433d86 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -161,7 +161,7 @@
<string name="quick_settings_bluetooth_off_label" msgid="8159652146149219937">"Bluetooth désactivé"</string>
<string name="quick_settings_brightness_label" msgid="6968372297018755815">"Luminosité"</string>
<string name="quick_settings_rotation_unlocked_label" msgid="336054930362580584">"Rotation auto."</string>
- <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Rotation verrouillée"</string>
+ <string name="quick_settings_rotation_locked_label" msgid="8058646447242565486">"Rotation bloquée"</string>
<string name="quick_settings_ime_label" msgid="7073463064369468429">"Mode de saisie"</string>
<string name="quick_settings_location_label" msgid="3292451598267467545">"Utilisation des données de localisation"</string>
<string name="quick_settings_media_device_label" msgid="1302906836372603762">"Appareil multimédia"</string>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 6561115..206df86 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -149,8 +149,7 @@
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Skrin dikunci dalam orientasi landskap."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Skrin dikunci dalam orientasi potret."</string>
<string name="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
- <!-- no translation found for start_dreams (6170089063982549905) -->
- <skip />
+ <string name="start_dreams" msgid="6170089063982549905">"Tidur Sekarang"</string>
<string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
<string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"Mod kapal terbang"</string>
<string name="quick_settings_battery_charging_label" msgid="490074774465309209">"Mengecas, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 445acbf..b4b725e 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -151,8 +151,7 @@
<string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"A tela está bloqueada na orientação paisagem."</string>
<string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"A tela está bloqueada na orientação retrato."</string>
<string name="jelly_bean_dream_name" msgid="5992026543636816792">"BeanFlinger"</string>
- <!-- no translation found for start_dreams (6170089063982549905) -->
- <skip />
+ <string name="start_dreams" msgid="6170089063982549905">"Suspender"</string>
<string name="ethernet_label" msgid="7967563676324087464">"Ethernet"</string>
<string name="quick_settings_airplane_mode_label" msgid="5510520633448831350">"Modo para avião"</string>
<string name="quick_settings_battery_charging_label" msgid="490074774465309209">"Carregando, <xliff:g id="NUMBER">%d</xliff:g><xliff:g id="PERCENT">%%</xliff:g>"</string>
diff --git a/packages/SystemUI/src/com/android/systemui/Somnambulator.java b/packages/SystemUI/src/com/android/systemui/Somnambulator.java
index 011bf9c..9356ff2 100644
--- a/packages/SystemUI/src/com/android/systemui/Somnambulator.java
+++ b/packages/SystemUI/src/com/android/systemui/Somnambulator.java
@@ -58,7 +58,7 @@
| Intent.FLAG_ACTIVITY_NEW_TASK);
Intent resultIntent = new Intent();
resultIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE,
- Intent.ShortcutIconResource.fromContext(this, R.mipmap.ic_dreams));
+ Intent.ShortcutIconResource.fromContext(this, R.mipmap.ic_launcher_dreams));
resultIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
resultIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, getString(R.string.start_dreams));
setResult(RESULT_OK, resultIntent);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index 0c9683d..b3cf854 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -281,22 +281,32 @@
mHandleView.setPressed(false);
mBar.onTrackingStopped(PanelView.this);
trackMovement(event);
- mVelocityTracker.computeCurrentVelocity(1000);
- float yVel = mVelocityTracker.getYVelocity();
- boolean negative = yVel < 0;
+ float vel = 0, yVel = 0, xVel = 0;
+ boolean negative = false;
- float xVel = mVelocityTracker.getXVelocity();
- if (xVel < 0) {
- xVel = -xVel;
- }
- if (xVel > mFlingGestureMaxXVelocityPx) {
- xVel = mFlingGestureMaxXVelocityPx; // limit how much we care about the x axis
- }
+ if (mVelocityTracker != null) {
+ // the velocitytracker might be null if we got a bad input stream
+ mVelocityTracker.computeCurrentVelocity(1000);
- float vel = (float)Math.hypot(yVel, xVel);
- if (vel > mFlingGestureMaxOutputVelocityPx) {
- vel = mFlingGestureMaxOutputVelocityPx;
+ yVel = mVelocityTracker.getYVelocity();
+ negative = yVel < 0;
+
+ xVel = mVelocityTracker.getXVelocity();
+ if (xVel < 0) {
+ xVel = -xVel;
+ }
+ if (xVel > mFlingGestureMaxXVelocityPx) {
+ xVel = mFlingGestureMaxXVelocityPx; // limit how much we care about the x axis
+ }
+
+ vel = (float)Math.hypot(yVel, xVel);
+ if (vel > mFlingGestureMaxOutputVelocityPx) {
+ vel = mFlingGestureMaxOutputVelocityPx;
+ }
+
+ mVelocityTracker.recycle();
+ mVelocityTracker = null;
}
// if you've barely moved your finger, we treat the velocity as 0
@@ -321,9 +331,6 @@
fling(vel, true);
- mVelocityTracker.recycle();
- mVelocityTracker = null;
-
break;
}
return true;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 0161f1d..f171662 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -1376,14 +1376,20 @@
}
public void showCling() {
+ // lazily inflate this to accommodate orientation change
+ final ViewStub stub = (ViewStub) mStatusBarWindow.findViewById(R.id.status_bar_cling_stub);
+ if (stub == null) {
+ mClingShown = true;
+ return; // no clings on this device
+ }
+
mSuppressStatusBarDrags = true;
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
- // lazily inflate this to accommodate orientation change
- ViewStub stub = (ViewStub) mStatusBarWindow.findViewById(R.id.status_bar_cling_stub);
mCling = (ViewGroup) stub.inflate();
+
mCling.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
index f981eeb..2e298d1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
@@ -207,6 +207,11 @@
Profile.CONTENT_URI, new String[] {Phone._ID, Phone.DISPLAY_NAME},
null, null, null);
+ if (cursor == null) {
+ // Info not available. Should become available later.
+ return new Pair<String, BitmapDrawable>(null, null);
+ }
+
String name = null;
try {
if (cursor.moveToFirst()) {
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index e4ca8d8..3351e61 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -2925,14 +2925,14 @@
mNoDreamEnterAnim = true;
}
if (((attrs.type >= FIRST_APPLICATION_WINDOW && attrs.type <= LAST_APPLICATION_WINDOW)
- || attrs.type == TYPE_DREAM)
+ || (attrs.type == TYPE_DREAM && win.isVisibleLw()))
&& attrs.x == 0 && attrs.y == 0
&& attrs.width == WindowManager.LayoutParams.MATCH_PARENT
&& attrs.height == WindowManager.LayoutParams.MATCH_PARENT) {
if (DEBUG_LAYOUT) Log.v(TAG, "Fullscreen window: " + win);
mTopFullscreenOpaqueWindowState = win;
if (attrs.type == TYPE_DREAM) {
- mNoDreamEnterAnim = true;
+ mForceStatusBarFromKeyguard = true;
}
if ((attrs.flags & FLAG_SHOW_WHEN_LOCKED) != 0) {
if (DEBUG_LAYOUT) Log.v(TAG, "Setting mHideLockScreen to true by win " + win);
diff --git a/services/java/com/android/server/am/AppErrorDialog.java b/services/java/com/android/server/am/AppErrorDialog.java
index a9c77fc9..ffa1e92 100644
--- a/services/java/com/android/server/am/AppErrorDialog.java
+++ b/services/java/com/android/server/am/AppErrorDialog.java
@@ -75,6 +75,7 @@
getWindow().addFlags(FLAG_SYSTEM_ERROR);
WindowManager.LayoutParams attrs = getWindow().getAttributes();
attrs.setTitle("Application Error: " + app.info.processName);
+ attrs.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
getWindow().setAttributes(attrs);
if (app.persistent) {
getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
diff --git a/services/java/com/android/server/am/AppNotRespondingDialog.java b/services/java/com/android/server/am/AppNotRespondingDialog.java
index 58e533b..af61c9b 100644
--- a/services/java/com/android/server/am/AppNotRespondingDialog.java
+++ b/services/java/com/android/server/am/AppNotRespondingDialog.java
@@ -97,6 +97,7 @@
getWindow().addFlags(FLAG_SYSTEM_ERROR);
WindowManager.LayoutParams attrs = getWindow().getAttributes();
attrs.setTitle("Application Not Responding: " + app.info.processName);
+ attrs.privateFlags = WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
getWindow().setAttributes(attrs);
}
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 0f3dc92..0600f5c 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -1300,27 +1300,6 @@
? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL)
: 0));
- // Verify that all of the preferred activity components actually
- // exist. It is possible for applications to be updated and at
- // that point remove a previously declared activity component that
- // had been set as a preferred activity. We try to clean this up
- // the next time we encounter that preferred activity, but it is
- // possible for the user flow to never be able to return to that
- // situation so here we do a sanity check to make sure we haven't
- // left any junk around.
- ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
- for (PreferredActivity pa : mSettings.mPreferredActivities.filterSet()) {
- if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
- removed.add(pa);
- }
- }
- for (int i=0; i<removed.size(); i++) {
- PreferredActivity pa = removed.get(i);
- Slog.w(TAG, "Removing dangling preferred activity: "
- + pa.mPref.mComponent);
- mSettings.mPreferredActivities.removeFilter(pa);
- }
-
// can downgrade to reader
mSettings.writeLPr();
@@ -2504,9 +2483,11 @@
intent = intent.getSelector();
}
if (DEBUG_PREFERRED) intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
- List<PreferredActivity> prefs =
- mSettings.mPreferredActivities.queryIntent(intent, resolvedType,
- (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
+ PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
+ List<PreferredActivity> prefs = pir != null
+ ? pir.queryIntent(intent, resolvedType,
+ (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId)
+ : null;
if (prefs != null && prefs.size() > 0) {
// First figure out how good the original match set is.
// We will only allow preferred activities that came
@@ -2537,9 +2518,6 @@
final int M = prefs.size();
for (int i=0; i<M; i++) {
final PreferredActivity pa = prefs.get(i);
- if (pa.mUserId != userId) {
- continue;
- }
if (pa.mPref.mMatch != match) {
continue;
}
@@ -2560,7 +2538,7 @@
// it from the preferred activities list, and skip it.
Slog.w(TAG, "Removing dangling preferred activity: "
+ pa.mPref.mComponent);
- mSettings.mPreferredActivities.removeFilter(pa);
+ pir.removeFilter(pa);
continue;
}
for (int j=0; j<N; j++) {
@@ -2580,7 +2558,7 @@
if (!pa.mPref.sameSet(query, priority)) {
Slog.i(TAG, "Result set changed, dropping preferred activity for "
+ intent + " type " + resolvedType);
- mSettings.mPreferredActivities.removeFilter(pa);
+ pir.removeFilter(pa);
return null;
}
@@ -8682,9 +8660,9 @@
Slog.i(TAG, "Adding preferred activity " + activity + " for user " + userId + " :");
filter.dump(new LogPrinter(Log.INFO, TAG), " ");
- mSettings.mPreferredActivities.addFilter(
- new PreferredActivity(filter, match, set, activity, userId));
- scheduleWriteSettingsLocked();
+ mSettings.editPreferredActivitiesLPw(userId).addFilter(
+ new PreferredActivity(filter, match, set, activity));
+ mSettings.writePackageRestrictionsLPr(userId);
}
}
@@ -8722,25 +8700,27 @@
final int callingUserId = UserHandle.getCallingUserId();
ArrayList<PreferredActivity> removed = null;
- Iterator<PreferredActivity> it = mSettings.mPreferredActivities.filterIterator();
- String action = filter.getAction(0);
- String category = filter.getCategory(0);
- while (it.hasNext()) {
- PreferredActivity pa = it.next();
- if (pa.mUserId != callingUserId) continue;
- if (pa.getAction(0).equals(action) && pa.getCategory(0).equals(category)) {
- if (removed == null) {
- removed = new ArrayList<PreferredActivity>();
+ PreferredIntentResolver pir = mSettings.mPreferredActivities.get(callingUserId);
+ if (pir != null) {
+ Iterator<PreferredActivity> it = pir.filterIterator();
+ String action = filter.getAction(0);
+ String category = filter.getCategory(0);
+ while (it.hasNext()) {
+ PreferredActivity pa = it.next();
+ if (pa.getAction(0).equals(action) && pa.getCategory(0).equals(category)) {
+ if (removed == null) {
+ removed = new ArrayList<PreferredActivity>();
+ }
+ removed.add(pa);
+ Log.i(TAG, "Removing preferred activity " + pa.mPref.mComponent + ":");
+ filter.dump(new LogPrinter(Log.INFO, TAG), " ");
}
- removed.add(pa);
- Log.i(TAG, "Removing preferred activity " + pa.mPref.mComponent + ":");
- filter.dump(new LogPrinter(Log.INFO, TAG), " ");
}
- }
- if (removed != null) {
- for (int i=0; i<removed.size(); i++) {
- PreferredActivity pa = removed.get(i);
- mSettings.mPreferredActivities.removeFilter(pa);
+ if (removed != null) {
+ for (int i=0; i<removed.size(); i++) {
+ PreferredActivity pa = removed.get(i);
+ pir.removeFilter(pa);
+ }
}
}
addPreferredActivity(filter, match, set, activity, callingUserId);
@@ -8776,27 +8756,33 @@
/** This method takes a specific user id as well as UserHandle.USER_ALL. */
boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
ArrayList<PreferredActivity> removed = null;
- Iterator<PreferredActivity> it = mSettings.mPreferredActivities.filterIterator();
- while (it.hasNext()) {
- PreferredActivity pa = it.next();
- if (userId != UserHandle.USER_ALL && pa.mUserId != userId) {
+ boolean changed = false;
+ for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
+ final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
+ PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
+ if (userId != UserHandle.USER_ALL && userId != thisUserId) {
continue;
}
- if (pa.mPref.mComponent.getPackageName().equals(packageName)) {
- if (removed == null) {
- removed = new ArrayList<PreferredActivity>();
+ Iterator<PreferredActivity> it = pir.filterIterator();
+ while (it.hasNext()) {
+ PreferredActivity pa = it.next();
+ if (pa.mPref.mComponent.getPackageName().equals(packageName)) {
+ if (removed == null) {
+ removed = new ArrayList<PreferredActivity>();
+ }
+ removed.add(pa);
}
- removed.add(pa);
+ }
+ if (removed != null) {
+ for (int j=0; j<removed.size(); j++) {
+ PreferredActivity pa = removed.get(j);
+ pir.removeFilter(pa);
+ }
+ changed = true;
+ mSettings.writePackageRestrictionsLPr(thisUserId);
}
}
- if (removed != null) {
- for (int i=0; i<removed.size(); i++) {
- PreferredActivity pa = removed.get(i);
- mSettings.mPreferredActivities.removeFilter(pa);
- }
- return true;
- }
- return false;
+ return changed;
}
public int getPreferredActivities(List<IntentFilter> outFilters,
@@ -8806,19 +8792,19 @@
final int userId = UserHandle.getCallingUserId();
// reader
synchronized (mPackages) {
- final Iterator<PreferredActivity> it = mSettings.mPreferredActivities.filterIterator();
- while (it.hasNext()) {
- final PreferredActivity pa = it.next();
- if (pa.mUserId != userId) {
- continue;
- }
- if (packageName == null
- || pa.mPref.mComponent.getPackageName().equals(packageName)) {
- if (outFilters != null) {
- outFilters.add(new IntentFilter(pa));
- }
- if (outActivities != null) {
- outActivities.add(pa.mPref.mComponent);
+ PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
+ if (pir != null) {
+ final Iterator<PreferredActivity> it = pir.filterIterator();
+ while (it.hasNext()) {
+ final PreferredActivity pa = it.next();
+ if (packageName == null
+ || pa.mPref.mComponent.getPackageName().equals(packageName)) {
+ if (outFilters != null) {
+ outFilters.add(new IntentFilter(pa));
+ }
+ if (outActivities != null) {
+ outActivities.add(pa.mPref.mComponent);
+ }
}
}
}
@@ -9041,6 +9027,39 @@
if (DEBUG_SETTINGS) {
Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
}
+
+ synchronized (mPackages) {
+ // Verify that all of the preferred activity components actually
+ // exist. It is possible for applications to be updated and at
+ // that point remove a previously declared activity component that
+ // had been set as a preferred activity. We try to clean this up
+ // the next time we encounter that preferred activity, but it is
+ // possible for the user flow to never be able to return to that
+ // situation so here we do a sanity check to make sure we haven't
+ // left any junk around.
+ ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
+ for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
+ PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
+ removed.clear();
+ for (PreferredActivity pa : pir.filterSet()) {
+ if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
+ removed.add(pa);
+ }
+ }
+ if (removed.size() > 0) {
+ for (int j=0; j<removed.size(); j++) {
+ PreferredActivity pa = removed.get(i);
+ RuntimeException here = new RuntimeException("here");
+ here.fillInStackTrace();
+ Slog.w(TAG, "Removing dangling preferred activity: "
+ + pa.mPref.mComponent, here);
+ pir.removeFilter(pa);
+ }
+ mSettings.writePackageRestrictionsLPr(
+ mSettings.mPreferredActivities.keyAt(i));
+ }
+ }
+ }
}
public boolean isSafeMode() {
@@ -9281,11 +9300,16 @@
}
if (dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
- if (mSettings.mPreferredActivities.dump(pw,
- dumpState.getTitlePrinted() ? "\nPreferred Activities:"
- : "Preferred Activities:", " ",
- packageName, dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
- dumpState.setTitlePrinted(true);
+ for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
+ PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
+ int user = mSettings.mPreferredActivities.keyAt(i);
+ if (pir.dump(pw,
+ dumpState.getTitlePrinted()
+ ? "\nPreferred Activities User " + user + ":"
+ : "Preferred Activities User " + user + ":", " ",
+ packageName, dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS))) {
+ dumpState.setTitlePrinted(true);
+ }
}
}
@@ -9299,7 +9323,7 @@
serializer.startDocument(null, true);
serializer.setFeature(
"http://xmlpull.org/v1/doc/features.html#indent-output", true);
- mSettings.writePreferredActivitiesLPr(serializer);
+ mSettings.writePreferredActivitiesLPr(serializer, 0);
serializer.endDocument();
serializer.flush();
} catch (IllegalArgumentException e) {
@@ -10045,11 +10069,6 @@
/** Called by UserManagerService */
void cleanUpUserLILPw(int userHandle) {
- // Disable all the packages for the user first
- Set<Entry<String, PackageSetting>> entries = mSettings.mPackages.entrySet();
- for (Entry<String, PackageSetting> entry : entries) {
- entry.getValue().removeUser(userHandle);
- }
if (mDirtyUsers.remove(userHandle));
mSettings.removeUserLPr(userHandle);
if (mInstaller != null) {
@@ -10063,17 +10082,7 @@
/** Called by UserManagerService */
void createNewUserLILPw(int userHandle, File path) {
if (mInstaller != null) {
- path.mkdir();
- FileUtils.setPermissions(path.toString(), FileUtils.S_IRWXU | FileUtils.S_IRWXG
- | FileUtils.S_IXOTH, -1, -1);
- for (PackageSetting ps : mSettings.mPackages.values()) {
- // Only system apps are initially installed.
- ps.setInstalled((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) != 0, userHandle);
- // Need to create a data directory for all apps under this user.
- mInstaller.createUserData(ps.name,
- UserHandle.getUid(userHandle, ps.appId), userHandle);
- }
- mSettings.writePackageRestrictionsLPr(userHandle);
+ mSettings.createNewUserLILPw(mInstaller, userHandle, path);
}
}
diff --git a/services/java/com/android/server/pm/PreferredActivity.java b/services/java/com/android/server/pm/PreferredActivity.java
index 5539e84..dbf56ef 100644
--- a/services/java/com/android/server/pm/PreferredActivity.java
+++ b/services/java/com/android/server/pm/PreferredActivity.java
@@ -36,32 +36,17 @@
static final String ATTR_USER_ID = "userId";
final PreferredComponent mPref;
- final int mUserId;
PreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity) {
- this(filter, match, set, activity, 0);
- }
-
- PreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity,
- int userId) {
super(filter);
- mUserId = userId;
mPref = new PreferredComponent(this, match, set, activity);
}
PreferredActivity(XmlPullParser parser) throws XmlPullParserException, IOException {
- String userIdString = parser.getAttributeValue(null, ATTR_USER_ID);
- if (userIdString != null && userIdString.length() > 0) {
- mUserId = Integer.parseInt(userIdString);
- } else {
- // Old format with no userId specified - assume primary user
- mUserId = 0;
- }
mPref = new PreferredComponent(this, parser);
}
public void writeToXml(XmlSerializer serializer) throws IOException {
- serializer.attribute(null, ATTR_USER_ID, Integer.toString(mUserId));
mPref.writeToXml(serializer);
serializer.startTag(null, "filter");
super.writeToXml(serializer);
diff --git a/services/java/com/android/server/pm/PreferredIntentResolver.java b/services/java/com/android/server/pm/PreferredIntentResolver.java
new file mode 100644
index 0000000..3f1e50c
--- /dev/null
+++ b/services/java/com/android/server/pm/PreferredIntentResolver.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.pm;
+
+import java.io.PrintWriter;
+
+import com.android.server.IntentResolver;
+
+public class PreferredIntentResolver
+ extends IntentResolver<PreferredActivity, PreferredActivity> {
+ @Override
+ protected PreferredActivity[] newArray(int size) {
+ return new PreferredActivity[size];
+ }
+ @Override
+ protected String packageForFilter(PreferredActivity filter) {
+ return filter.mPref.mComponent.getPackageName();
+ }
+ @Override
+ protected void dumpFilter(PrintWriter out, String prefix,
+ PreferredActivity filter) {
+ filter.mPref.dump(out, prefix, filter);
+ }
+}
diff --git a/services/java/com/android/server/pm/Settings.java b/services/java/com/android/server/pm/Settings.java
index bdf5044..3a54514 100644
--- a/services/java/com/android/server/pm/Settings.java
+++ b/services/java/com/android/server/pm/Settings.java
@@ -70,6 +70,8 @@
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Set;
+import java.util.Map.Entry;
import libcore.io.IoUtils;
@@ -123,22 +125,9 @@
// The user's preferred activities associated with particular intent
// filters.
- final IntentResolver<PreferredActivity, PreferredActivity> mPreferredActivities =
- new IntentResolver<PreferredActivity, PreferredActivity>() {
- @Override
- protected PreferredActivity[] newArray(int size) {
- return new PreferredActivity[size];
- }
- @Override
- protected String packageForFilter(PreferredActivity filter) {
- return filter.mPref.mComponent.getPackageName();
- }
- @Override
- protected void dumpFilter(PrintWriter out, String prefix,
- PreferredActivity filter) {
- filter.mPref.dump(out, prefix, filter);
- }
- };
+ final SparseArray<PreferredIntentResolver> mPreferredActivities =
+ new SparseArray<PreferredIntentResolver>();
+
final HashMap<String, SharedUserSetting> mSharedUsers =
new HashMap<String, SharedUserSetting>();
private final ArrayList<Object> mUserIds = new ArrayList<Object>();
@@ -745,6 +734,15 @@
}
}
+ PreferredIntentResolver editPreferredActivitiesLPw(int userId) {
+ PreferredIntentResolver pir = mPreferredActivities.get(userId);
+ if (pir == null) {
+ pir = new PreferredIntentResolver();
+ mPreferredActivities.put(userId, pir);
+ }
+ return pir;
+ }
+
private File getUserPackagesStateFile(int userId) {
return new File(Environment.getUserSystemDirectory(userId), "package-restrictions.xml");
}
@@ -775,6 +773,35 @@
}
}
+ private void readPreferredActivitiesLPw(XmlPullParser parser, int userId)
+ throws XmlPullParserException, IOException {
+ int outerDepth = parser.getDepth();
+ int type;
+ while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+ && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
+ if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+ continue;
+ }
+
+ String tagName = parser.getName();
+ if (tagName.equals(TAG_ITEM)) {
+ PreferredActivity pa = new PreferredActivity(parser);
+ if (pa.mPref.getParseError() == null) {
+ editPreferredActivitiesLPw(userId).addFilter(pa);
+ } else {
+ PackageManagerService.reportSettingsProblem(Log.WARN,
+ "Error in package manager settings: <preferred-activity> "
+ + pa.mPref.getParseError() + " at "
+ + parser.getPositionDescription());
+ }
+ } else {
+ PackageManagerService.reportSettingsProblem(Log.WARN,
+ "Unknown element under <preferred-activities>: " + parser.getName());
+ XmlUtils.skipCurrentTag(parser);
+ }
+ }
+ }
+
void readPackageRestrictionsLPr(int userId) {
if (DEBUG_MU) {
Log.i(TAG, "Reading package restrictions for user=" + userId);
@@ -893,6 +920,8 @@
ps.setUserState(userId, enabled, installed, stopped, notLaunched,
enabledComponents, disabledComponents);
+ } else if (tagName.equals("preferred-activities")) {
+ readPreferredActivitiesLPw(parser, userId);
} else {
Slog.w(PackageManagerService.TAG, "Unknown element under <stopped-packages>: "
+ parser.getName());
@@ -942,6 +971,20 @@
return components;
}
+ void writePreferredActivitiesLPr(XmlSerializer serializer, int userId)
+ throws IllegalArgumentException, IllegalStateException, IOException {
+ serializer.startTag(null, "preferred-activities");
+ PreferredIntentResolver pir = mPreferredActivities.get(userId);
+ if (pir != null) {
+ for (final PreferredActivity pa : pir.filterSet()) {
+ serializer.startTag(null, TAG_ITEM);
+ pa.writeToXml(serializer);
+ serializer.endTag(null, TAG_ITEM);
+ }
+ }
+ serializer.endTag(null, "preferred-activities");
+ }
+
void writePackageRestrictionsLPr(int userId) {
if (DEBUG_MU) {
Log.i(TAG, "Writing package restrictions for user=" + userId);
@@ -1028,6 +1071,8 @@
}
}
+ writePreferredActivitiesLPr(serializer, userId);
+
serializer.endTag(null, TAG_PACKAGE_RESTRICTIONS);
serializer.endDocument();
@@ -1237,8 +1282,6 @@
writeDisabledSysPackageLPr(serializer, pkg);
}
- writePreferredActivitiesLPr(serializer);
-
for (final SharedUserSetting usr : mSharedUsers.values()) {
serializer.startTag(null, "shared-user");
serializer.attribute(null, ATTR_NAME, usr.name);
@@ -1366,17 +1409,6 @@
//Debug.stopMethodTracing();
}
- void writePreferredActivitiesLPr(XmlSerializer serializer)
- throws IllegalArgumentException, IllegalStateException, IOException {
- serializer.startTag(null, "preferred-activities");
- for (final PreferredActivity pa : mPreferredActivities.filterSet()) {
- serializer.startTag(null, TAG_ITEM);
- pa.writeToXml(serializer);
- serializer.endTag(null, TAG_ITEM);
- }
- serializer.endTag(null, "preferred-activities");
- }
-
void writeDisabledSysPackageLPr(XmlSerializer serializer, final PackageSetting pkg)
throws java.io.IOException {
serializer.startTag(null, "updated-package");
@@ -1554,7 +1586,7 @@
mReadMessages.append("No settings file found\n");
PackageManagerService.reportSettingsProblem(Log.INFO,
"No settings file; creating initial state");
- readDefaultPreferredAppsLPw();
+ readDefaultPreferredAppsLPw(0);
return false;
}
str = new FileInputStream(mSettingsFilename);
@@ -1596,7 +1628,9 @@
} else if (tagName.equals("preferred-packages")) {
// no longer used.
} else if (tagName.equals("preferred-activities")) {
- readPreferredActivitiesLPw(parser);
+ // Upgrading from old single-user implementation;
+ // these are the preferred activities for user 0.
+ readPreferredActivitiesLPw(parser, 0);
} else if (tagName.equals("updated-package")) {
readDisabledSysPackageLPw(parser);
} else if (tagName.equals("cleaning-package")) {
@@ -1733,7 +1767,7 @@
return true;
}
- private void readDefaultPreferredAppsLPw() {
+ private void readDefaultPreferredAppsLPw(int userId) {
// Read preferred apps from .../etc/preferred-apps directory.
File preferredDir = new File(Environment.getRootDirectory(), "etc/preferred-apps");
if (!preferredDir.exists() || !preferredDir.isDirectory()) {
@@ -1776,7 +1810,7 @@
+ " does not start with 'preferred-activities'");
continue;
}
- readPreferredActivitiesLPw(parser);
+ readPreferredActivitiesLPw(parser, userId);
} catch (XmlPullParserException e) {
Slog.w(TAG, "Error reading apps file " + f, e);
} catch (IOException e) {
@@ -2291,36 +2325,27 @@
}
}
- private void readPreferredActivitiesLPw(XmlPullParser parser) throws XmlPullParserException,
- IOException {
- int outerDepth = parser.getDepth();
- int type;
- while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
- && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
- if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
- continue;
- }
-
- String tagName = parser.getName();
- if (tagName.equals(TAG_ITEM)) {
- PreferredActivity pa = new PreferredActivity(parser);
- if (pa.mPref.getParseError() == null) {
- mPreferredActivities.addFilter(pa);
- } else {
- PackageManagerService.reportSettingsProblem(Log.WARN,
- "Error in package manager settings: <preferred-activity> "
- + pa.mPref.getParseError() + " at "
- + parser.getPositionDescription());
- }
- } else {
- PackageManagerService.reportSettingsProblem(Log.WARN,
- "Unknown element under <preferred-activities>: " + parser.getName());
- XmlUtils.skipCurrentTag(parser);
- }
+ void createNewUserLILPw(Installer installer, int userHandle, File path) {
+ path.mkdir();
+ FileUtils.setPermissions(path.toString(), FileUtils.S_IRWXU | FileUtils.S_IRWXG
+ | FileUtils.S_IXOTH, -1, -1);
+ for (PackageSetting ps : mPackages.values()) {
+ // Only system apps are initially installed.
+ ps.setInstalled((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) != 0, userHandle);
+ // Need to create a data directory for all apps under this user.
+ installer.createUserData(ps.name,
+ UserHandle.getUid(userHandle, ps.appId), userHandle);
}
+ readDefaultPreferredAppsLPw(userHandle);
+ writePackageRestrictionsLPr(userHandle);
}
void removeUserLPr(int userId) {
+ Set<Entry<String, PackageSetting>> entries = mPackages.entrySet();
+ for (Entry<String, PackageSetting> entry : entries) {
+ entry.getValue().removeUser(userId);
+ }
+ mPreferredActivities.remove(userId);
File file = getUserPackagesStateFile(userId);
file.delete();
file = getUserPackagesStateBackupFile(userId);
diff --git a/services/java/com/android/server/power/DisplayPowerController.java b/services/java/com/android/server/power/DisplayPowerController.java
index a1c1fa6..25d2944 100644
--- a/services/java/com/android/server/power/DisplayPowerController.java
+++ b/services/java/com/android/server/power/DisplayPowerController.java
@@ -271,6 +271,12 @@
// When the screen turns on again, we report user activity to the power manager.
private boolean mScreenOffBecauseOfProximity;
+ // True if the screen on is being blocked.
+ private boolean mScreenOnWasBlocked;
+
+ // The elapsed real time when the screen on was blocked.
+ private long mScreenOnBlockStartRealTime;
+
// Set to true if the light sensor is enabled.
private boolean mLightSensorEnabled;
@@ -513,7 +519,7 @@
final Executor executor = AsyncTask.THREAD_POOL_EXECUTOR;
Display display = mDisplayManager.getDisplay(Display.DEFAULT_DISPLAY);
mPowerState = new DisplayPowerState(
- mElectronBeamAnimatesBacklightConfig ? null : new ElectronBeam(display),
+ new ElectronBeam(display),
new PhotonicModulator(executor,
mLights.getLight(LightsService.LIGHT_ID_BACKLIGHT),
mSuspendBlocker));
@@ -553,7 +559,6 @@
final boolean mustNotify;
boolean mustInitialize = false;
boolean updateAutoBrightness = mTwilightChanged;
- boolean screenOnWasBlocked = false;
mTwilightChanged = false;
synchronized (mLock) {
@@ -662,18 +667,24 @@
// It is relatively short but if we cancel it and switch to the
// on animation immediately then the results are pretty ugly.
if (!mElectronBeamOffAnimator.isStarted()) {
- if (mPowerRequest.blockScreenOn && !mPowerState.isScreenOn()) {
- if (DEBUG) {
- Slog.d(TAG, "Blocked screen on while screen currently off.");
- }
- screenOnWasBlocked = true;
+ // Turn the screen on. The contents of the screen may not yet
+ // be visible if the electron beam has not been dismissed because
+ // its last frame of animation is solid black.
+ setScreenOn(true);
+
+ if (mPowerRequest.blockScreenOn
+ && mPowerState.getElectronBeamLevel() == 0.0f) {
+ blockScreenOn();
} else {
- setScreenOn(true);
+ unblockScreenOn();
if (USE_ELECTRON_BEAM_ON_ANIMATION) {
if (!mElectronBeamOnAnimator.isStarted()) {
if (mPowerState.getElectronBeamLevel() == 1.0f) {
mPowerState.dismissElectronBeam();
- } else if (mPowerState.prepareElectronBeam(true)) {
+ } else if (mPowerState.prepareElectronBeam(
+ mElectronBeamAnimatesBacklightConfig ?
+ ElectronBeam.MODE_BLANK :
+ ElectronBeam.MODE_WARM_UP)) {
mElectronBeamOnAnimator.start();
} else {
mElectronBeamOnAnimator.end();
@@ -684,22 +695,6 @@
mPowerState.dismissElectronBeam();
}
}
- } else {
- // FIXME: If the electron beam off animation is playing then we have a bit
- // of a problem. The window manager policy would only have requested
- // to block screen on if it was about to start preparing the keyguard.
- // It's already too late to do anything about that. Ideally we would
- // let the animation play out first but that would require making
- // some pretty deep changes to the power manager and we don't have
- // time just now. For now, short-circuit the animation and get ready.
- if (mPowerRequest.blockScreenOn) {
- if (DEBUG) {
- Slog.d(TAG, "Blocked screen on while screen off animation running.");
- }
- screenOnWasBlocked = true;
- setScreenOn(false);
- mElectronBeamOffAnimator.end();
- }
}
} else {
// Want screen off.
@@ -708,7 +703,10 @@
if (!mElectronBeamOffAnimator.isStarted()) {
if (mPowerState.getElectronBeamLevel() == 0.0f) {
setScreenOn(false);
- } else if (mPowerState.prepareElectronBeam(false)
+ } else if (mPowerState.prepareElectronBeam(
+ mElectronBeamAnimatesBacklightConfig ?
+ ElectronBeam.MODE_BLANK :
+ ElectronBeam.MODE_COOL_DOWN)
&& mPowerState.isScreenOn()) {
mElectronBeamOffAnimator.start();
} else {
@@ -723,7 +721,7 @@
// We mostly care about the screen state here, ignoring brightness changes
// which will be handled asynchronously.
if (mustNotify
- && !screenOnWasBlocked
+ && !mScreenOnWasBlocked
&& !mElectronBeamOnAnimator.isStarted()
&& !mElectronBeamOffAnimator.isStarted()
&& mPowerState.waitUntilClean(mCleanListener)) {
@@ -740,6 +738,26 @@
}
}
+ private void blockScreenOn() {
+ if (!mScreenOnWasBlocked) {
+ mScreenOnWasBlocked = true;
+ if (DEBUG) {
+ Slog.d(TAG, "Blocked screen on.");
+ mScreenOnBlockStartRealTime = SystemClock.elapsedRealtime();
+ }
+ }
+ }
+
+ private void unblockScreenOn() {
+ if (mScreenOnWasBlocked) {
+ mScreenOnWasBlocked = false;
+ if (DEBUG) {
+ Slog.d(TAG, "Unblocked screen on after " +
+ (SystemClock.elapsedRealtime() - mScreenOnBlockStartRealTime) + " ms");
+ }
+ }
+ }
+
private void setScreenOn(boolean on) {
if (!mPowerState.isScreenOn() == on) {
mPowerState.setScreenOn(on);
diff --git a/services/java/com/android/server/power/DisplayPowerRequest.java b/services/java/com/android/server/power/DisplayPowerRequest.java
index 5f94414..22f17d7 100644
--- a/services/java/com/android/server/power/DisplayPowerRequest.java
+++ b/services/java/com/android/server/power/DisplayPowerRequest.java
@@ -52,11 +52,14 @@
// If true, enables automatic brightness control.
public boolean useAutoBrightness;
- // If true, prevents the screen from turning on if it is currently off.
- // The display does not enter a "ready" state if this flag is true and the screen
- // is off and is being prevented from turning on. The window manager policy blocks
- // screen on while it prepares the keyguard to prevent the user from seeing
- // intermediate updates.
+ // If true, prevents the screen from completely turning on if it is currently off.
+ // The display does not enter a "ready" state if this flag is true and screen on is
+ // blocked. The window manager policy blocks screen on while it prepares the keyguard to
+ // prevent the user from seeing intermediate updates.
+ //
+ // Technically, we may not block the screen itself from turning on (because that introduces
+ // extra unnecessary latency) but we do prevent content on screen from becoming
+ // visible to the user.
public boolean blockScreenOn;
public DisplayPowerRequest() {
diff --git a/services/java/com/android/server/power/DisplayPowerState.java b/services/java/com/android/server/power/DisplayPowerState.java
index dba45b3..f6ce7a7 100644
--- a/services/java/com/android/server/power/DisplayPowerState.java
+++ b/services/java/com/android/server/power/DisplayPowerState.java
@@ -50,7 +50,7 @@
private static final int DIRTY_BRIGHTNESS = 1 << 2;
private final Choreographer mChoreographer;
- private final ElectronBeam mElectronBeam; // may be null if only animating backlights
+ private final ElectronBeam mElectronBeam;
private final PhotonicModulator mScreenBrightnessModulator;
private int mDirty;
@@ -130,26 +130,19 @@
* This method should be called before starting an animation because it
* can take a fair amount of time to prepare the electron beam surface.
*
- * @param warmUp True if the electron beam should start warming up.
+ * @param mode The electron beam animation mode to prepare.
* @return True if the electron beam was prepared.
*/
- public boolean prepareElectronBeam(boolean warmUp) {
- if (mElectronBeam != null) {
- boolean success = mElectronBeam.prepare(warmUp);
- invalidate(DIRTY_ELECTRON_BEAM);
- return success;
- } else {
- return true;
- }
+ public boolean prepareElectronBeam(int mode) {
+ invalidate(DIRTY_ELECTRON_BEAM);
+ return mElectronBeam.prepare(mode);
}
/**
* Dismisses the electron beam surface.
*/
public void dismissElectronBeam() {
- if (mElectronBeam != null) {
- mElectronBeam.dismiss();
- }
+ mElectronBeam.dismiss();
}
/**
@@ -230,9 +223,7 @@
pw.println(" mScreenBrightness=" + mScreenBrightness);
pw.println(" mElectronBeamLevel=" + mElectronBeamLevel);
- if (mElectronBeam != null) {
- mElectronBeam.dump(pw);
- }
+ mElectronBeam.dump(pw);
}
private void invalidate(int dirty) {
@@ -251,7 +242,7 @@
PowerManagerService.nativeSetScreenState(false);
}
- if ((mDirty & DIRTY_ELECTRON_BEAM) != 0 && mElectronBeam != null) {
+ if ((mDirty & DIRTY_ELECTRON_BEAM) != 0) {
mElectronBeam.draw(mElectronBeamLevel);
}
diff --git a/services/java/com/android/server/power/ElectronBeam.java b/services/java/com/android/server/power/ElectronBeam.java
index 0c68997..8c242f7 100644
--- a/services/java/com/android/server/power/ElectronBeam.java
+++ b/services/java/com/android/server/power/ElectronBeam.java
@@ -26,7 +26,6 @@
import android.opengl.GLES10;
import android.opengl.GLUtils;
import android.os.Looper;
-import android.os.Process;
import android.util.FloatMath;
import android.util.Slog;
import android.view.Display;
@@ -41,12 +40,13 @@
/**
* Bzzzoooop! *crackle*
- *
+ * <p>
* Animates a screen transition from on to off or off to on by applying
* some GL transformations to a screenshot.
- *
+ * </p><p>
* This component must only be created or accessed by the {@link Looper} thread
* that belongs to the {@link DisplayPowerController}.
+ * </p>
*/
final class ElectronBeam {
private static final String TAG = "ElectronBeam";
@@ -65,7 +65,7 @@
// Set to true when the animation context has been fully prepared.
private boolean mPrepared;
- private boolean mWarmUp;
+ private int mMode;
private final Display mDisplay;
private final DisplayInfo mDisplayInfo = new DisplayInfo();
@@ -90,6 +90,10 @@
private final FloatBuffer mVertexBuffer = createNativeFloatBuffer(8);
private final FloatBuffer mTexCoordBuffer = createNativeFloatBuffer(8);
+ public static final int MODE_WARM_UP = 0;
+ public static final int MODE_COOL_DOWN = 1;
+ public static final int MODE_BLANK = 2;
+
public ElectronBeam(Display display) {
mDisplay = display;
}
@@ -98,16 +102,15 @@
* Warms up the electron beam in preparation for turning on or off.
* This method prepares a GL context, and captures a screen shot.
*
- * @param warmUp True if the electron beam is about to be turned on, false if
- * it is about to be turned off.
+ * @param mode The desired mode for the upcoming animation.
* @return True if the electron beam is ready, false if it is uncontrollable.
*/
- public boolean prepare(boolean warmUp) {
+ public boolean prepare(int mode) {
if (DEBUG) {
- Slog.d(TAG, "prepare: warmUp=" + warmUp);
+ Slog.d(TAG, "prepare: mode=" + mode);
}
- mWarmUp = warmUp;
+ mMode = mode;
// Get the display size and adjust it for rotation.
mDisplay.getDisplayInfo(mDisplayInfo);
@@ -123,17 +126,28 @@
}
// Prepare the surface for drawing.
- if (!createEglContext()
- || !createEglSurface()
- || !captureScreenshotTextureAndSetViewport()) {
+ if (!tryPrepare()) {
dismiss();
return false;
}
+ // Done.
mPrepared = true;
return true;
}
+ private boolean tryPrepare() {
+ if (createSurface()) {
+ if (mMode == MODE_BLANK) {
+ return true;
+ }
+ return createEglContext()
+ && createEglSurface()
+ && captureScreenshotTextureAndSetViewport();
+ }
+ return false;
+ }
+
/**
* Dismisses the electron beam animation surface and cleans up.
*
@@ -148,6 +162,7 @@
destroyScreenshotTexture();
destroyEglSurface();
+ destroySurface();
mPrepared = false;
}
@@ -163,6 +178,14 @@
Slog.d(TAG, "drawFrame: level=" + level);
}
+ if (!mPrepared) {
+ return false;
+ }
+
+ if (mMode == MODE_BLANK) {
+ return showSurface(1.0f - level);
+ }
+
if (!attachEglContext()) {
return false;
}
@@ -185,8 +208,7 @@
} finally {
detachEglContext();
}
-
- return showEglSurface();
+ return showSurface(1.0f);
}
/**
@@ -217,7 +239,7 @@
// bind texture and set blending for drawing planes
GLES10.glBindTexture(GLES10.GL_TEXTURE_2D, mTexNames[0]);
GLES10.glTexEnvx(GLES10.GL_TEXTURE_ENV, GLES10.GL_TEXTURE_ENV_MODE,
- mWarmUp ? GLES10.GL_MODULATE : GLES10.GL_REPLACE);
+ mMode == MODE_WARM_UP ? GLES10.GL_MODULATE : GLES10.GL_REPLACE);
GLES10.glTexParameterx(GLES10.GL_TEXTURE_2D,
GLES10.GL_TEXTURE_MAG_FILTER, GLES10.GL_LINEAR);
GLES10.glTexParameterx(GLES10.GL_TEXTURE_2D,
@@ -251,7 +273,7 @@
GLES10.glColorMask(true, true, true, true);
// draw the white highlight (we use the last vertices)
- if (!mWarmUp) {
+ if (mMode == MODE_COOL_DOWN) {
GLES10.glColor4f(ag, ag, ag, 1.0f);
GLES10.glDrawArrays(GLES10.GL_TRIANGLE_FAN, 0, 4);
}
@@ -472,7 +494,7 @@
}
}*/
- private boolean createEglSurface() {
+ private boolean createSurface() {
if (mSurfaceSession == null) {
mSurfaceSession = new SurfaceSession();
}
@@ -481,9 +503,15 @@
try {
if (mSurface == null) {
try {
+ int flags;
+ if (mMode == MODE_BLANK) {
+ flags = Surface.FX_SURFACE_DIM | Surface.HIDDEN;
+ } else {
+ flags = Surface.OPAQUE | Surface.HIDDEN;
+ }
mSurface = new Surface(mSurfaceSession,
"ElectronBeam", mDisplayWidth, mDisplayHeight,
- PixelFormat.OPAQUE, Surface.OPAQUE | Surface.HIDDEN);
+ PixelFormat.OPAQUE, flags);
} catch (Surface.OutOfResourcesException ex) {
Slog.e(TAG, "Unable to create surface.", ex);
return false;
@@ -514,7 +542,10 @@
} finally {
Surface.closeTransaction();
}
+ return true;
+ }
+ private boolean createEglSurface() {
if (mEglSurface == null) {
int[] eglSurfaceAttribList = new int[] {
EGL14.EGL_NONE
@@ -536,7 +567,9 @@
}
mEglSurface = null;
}
+ }
+ private void destroySurface() {
if (mSurface != null) {
Surface.openTransaction();
try {
@@ -549,11 +582,12 @@
}
}
- private boolean showEglSurface() {
+ private boolean showSurface(float alpha) {
if (!mSurfaceVisible) {
Surface.openTransaction();
try {
mSurface.setLayer(ELECTRON_BEAM_LAYER);
+ mSurface.setAlpha(alpha);
mSurface.show();
} finally {
Surface.closeTransaction();
@@ -643,7 +677,7 @@
pw.println();
pw.println("Electron Beam State:");
pw.println(" mPrepared=" + mPrepared);
- pw.println(" mWarmUp=" + mWarmUp);
+ pw.println(" mMode=" + mMode);
pw.println(" mDisplayLayerStack=" + mDisplayLayerStack);
pw.println(" mDisplayRotation=" + mDisplayRotation);
pw.println(" mDisplayWidth=" + mDisplayWidth);
diff --git a/services/java/com/android/server/power/ScreenOnBlocker.java b/services/java/com/android/server/power/ScreenOnBlocker.java
index 2bf0bcf..dbbbc6d 100644
--- a/services/java/com/android/server/power/ScreenOnBlocker.java
+++ b/services/java/com/android/server/power/ScreenOnBlocker.java
@@ -18,7 +18,7 @@
/**
* Low-level screen on blocker mechanism which is used to keep the screen off
- * until the window manager is ready to show new content.
+ * or the contents of the screen hidden until the window manager is ready to show new content.
*/
interface ScreenOnBlocker {
/**
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 4df1d71..0db9f19 100755
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -1210,12 +1210,9 @@
final WindowState curTarget = mInputMethodTarget;
if (curTarget != null && w != null
&& curTarget.isDisplayedLw()
- && curTarget.mExiting) {
- if (curTarget.mWinAnimator.mAnimLayer > w.mWinAnimator.mAnimLayer) {
- w = curTarget;
- i = windows.indexOf(w);
- if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Current target higher, switching to: " + w);
- }
+ && (curTarget.mWinAnimator.mAnimLayer > w.mWinAnimator.mAnimLayer)) {
+ if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Current target higher, not changing");
+ return windows.indexOf(curTarget) + 1;
}
if (DEBUG_INPUT_METHOD) Slog.v(TAG, "Desired input method target="
@@ -4184,6 +4181,7 @@
}
}
+ @Override
public void setAppStartingWindow(IBinder token, String pkg,
int theme, CompatibilityInfo compatInfo,
CharSequence nonLocalizedLabel, int labelRes, int icon,
diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java
index dee66a6..23892f6 100644
--- a/services/java/com/android/server/wm/WindowState.java
+++ b/services/java/com/android/server/wm/WindowState.java
@@ -788,18 +788,21 @@
* Like isOnScreen, but returns false if the surface hasn't yet
* been drawn.
*/
+ @Override
public boolean isDisplayedLw() {
final AppWindowToken atoken = mAppToken;
return isDrawnLw() && mPolicyVisibility
&& ((!mAttachedHidden &&
(atoken == null || !atoken.hiddenRequested))
- || mWinAnimator.mAnimating);
+ || mWinAnimator.mAnimating
+ || (atoken != null && atoken.mAppAnimator.animation != null));
}
/**
* Return true if this window (or a window it is attached to, but not
* considering its app token) is currently animating.
*/
+ @Override
public boolean isAnimatingLw() {
return mWinAnimator.mAnimation != null;
}