Merge change 3857 into donut
* changes:
Allow arrays of values for power profile data.
diff --git a/Android.mk b/Android.mk
index 0567ca6..bffd04c 100644
--- a/Android.mk
+++ b/Android.mk
@@ -119,6 +119,8 @@
core/java/android/view/IWindowSession.aidl \
core/java/android/speech/IRecognitionListener.aidl \
core/java/android/speech/IRecognitionService.aidl \
+ core/java/android/speech/tts/ITts.aidl \
+ core/java/android/speech/tts/ITtsCallback.aidl \
core/java/com/android/internal/app/IBatteryStats.aidl \
core/java/com/android/internal/app/IUsageStats.aidl \
core/java/com/android/internal/appwidget/IAppWidgetService.aidl \
@@ -148,8 +150,6 @@
telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl \
telephony/java/com/android/internal/telephony/IIccPhoneBook.aidl \
telephony/java/com/android/internal/telephony/ISms.aidl \
- tts/java/android/tts/ITtsCallback.aidl \
- tts/java/android/tts/ITts.aidl \
wifi/java/android/net/wifi/IWifiManager.aidl \
telephony/java/com/android/internal/telephony/IExtendedNetworkService.aidl \
vpn/java/android/net/vpn/IVpnService.aidl \
diff --git a/api/current.xml b/api/current.xml
index 0660d7d..cb348e1 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -46362,7 +46362,7 @@
</parameter>
<parameter name="height" type="int">
</parameter>
-<parameter name="edge" type="int">
+<parameter name="inset" type="int">
</parameter>
<parameter name="color" type="int">
</parameter>
@@ -173571,6 +173571,17 @@
deprecated="not deprecated"
visibility="public"
>
+<method name="getTag"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="setContent"
return="android.widget.TabHost.TabSpec"
abstract="false"
@@ -173638,6 +173649,19 @@
<parameter name="icon" type="android.graphics.drawable.Drawable">
</parameter>
</method>
+<method name="setIndicator"
+ return="android.widget.TabHost.TabSpec"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="view" type="android.view.View">
+</parameter>
+</method>
</class>
<class name="TabWidget"
extends="android.widget.LinearLayout"
@@ -173711,6 +173735,30 @@
<parameter name="index" type="int">
</parameter>
</method>
+<method name="getChildTabViewAt"
+ return="android.view.View"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="index" type="int">
+</parameter>
+</method>
+<method name="getTabCount"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="onFocusChange"
return="void"
abstract="false"
@@ -173739,6 +173787,32 @@
<parameter name="index" type="int">
</parameter>
</method>
+<method name="setDividerDrawable"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="drawable" type="android.graphics.drawable.Drawable">
+</parameter>
+</method>
+<method name="setDividerDrawable"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="resId" type="int">
+</parameter>
+</method>
</class>
<class name="TableLayout"
extends="android.widget.LinearLayout"
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index f3dfc5a..f10dd53 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -145,6 +145,13 @@
public static final int FLAG_ALLOW_BACKUP = 1<<10;
/**
+ * Indicates that the application supports any densities;
+ * {@hide}
+ */
+ public static final int ANY_DENSITY = -1;
+ private static final int[] ANY_DENSITIES_ARRAY = { ANY_DENSITY };
+
+ /**
* Flags associated with the application. Any combination of
* {@link #FLAG_SYSTEM}, {@link #FLAG_DEBUGGABLE}, {@link #FLAG_HAS_CODE},
* {@link #FLAG_PERSISTENT}, {@link #FLAG_FACTORY_TEST}, and
@@ -369,4 +376,14 @@
}
return null;
}
+
+ /**
+ * Disable compatibility mode
+ *
+ * @hide
+ */
+ public void disableCompatibilityMode() {
+ expandable = true;
+ supportsDensities = ANY_DENSITIES_ARRAY;
+ }
}
diff --git a/core/java/android/content/res/CompatibilityInfo.java b/core/java/android/content/res/CompatibilityInfo.java
index 19379fb..836de39 100644
--- a/core/java/android/content/res/CompatibilityInfo.java
+++ b/core/java/android/content/res/CompatibilityInfo.java
@@ -51,10 +51,17 @@
public final float mApplicationInvertedScale;
/**
- *
* A boolean flag to indicates that the application can expand over the original size.
+ * The flag is set to true if
+ * 1) Application declares its expandable in manifest file using <expandable /> or
+ * 2) The screen size is same as (320 x 480) * density.
*/
- public final boolean mExpandable;
+ public boolean mExpandable;
+
+ /**
+ * A expandable flag in the configuration.
+ */
+ public final boolean mConfiguredExpandable;
/**
* A boolean flag to tell if the application needs scaling (when mApplicationScale != 1.0f)
@@ -62,13 +69,16 @@
public final boolean mScalingRequired;
public CompatibilityInfo(ApplicationInfo appInfo) {
- // A temp workaround to fix rotation issue.
- // mExpandable = appInfo.expandable;
- mExpandable = true;
+ mExpandable = mConfiguredExpandable = appInfo.expandable;
+
float packageDensityScale = -1.0f;
if (appInfo.supportsDensities != null) {
int minDiff = Integer.MAX_VALUE;
for (int density : appInfo.supportsDensities) {
+ if (density == ApplicationInfo.ANY_DENSITY) {
+ packageDensityScale = 1.0f;
+ break;
+ }
int tmpDiff = Math.abs(DisplayMetrics.DEVICE_DENSITY - density);
if (tmpDiff == 0) {
packageDensityScale = 1.0f;
@@ -92,7 +102,7 @@
private CompatibilityInfo() {
mApplicationScale = mApplicationInvertedScale = 1.0f;
- mExpandable = true;
+ mExpandable = mConfiguredExpandable = true;
mScalingRequired = false;
}
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index 976b618..2f63820 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -88,7 +88,7 @@
PluralRules mPluralRule;
private final CompatibilityInfo mCompatibilityInfo;
-
+
private static final SparseArray<Object> EMPTY_ARRAY = new SparseArray<Object>() {
@Override
public void put(int k, Object o) {
@@ -1255,7 +1255,7 @@
return array;
}
-
+
/**
* Store the newly updated configuration.
*/
@@ -1268,7 +1268,7 @@
}
if (metrics != null) {
mMetrics.setTo(metrics);
- mMetrics.updateMetrics(mCompatibilityInfo, mConfiguration);
+ mMetrics.updateMetrics(mCompatibilityInfo, mConfiguration.orientation);
}
mMetrics.scaledDensity = mMetrics.density * mConfiguration.fontScale;
diff --git a/core/java/android/provider/Browser.java b/core/java/android/provider/Browser.java
index c597b3c..0bab2a7 100644
--- a/core/java/android/provider/Browser.java
+++ b/core/java/android/provider/Browser.java
@@ -34,6 +34,12 @@
Uri.parse("content://browser/bookmarks");
/**
+ * The inline scheme to show embedded content in a browser.
+ * @hide
+ */
+ public static final Uri INLINE_URI = Uri.parse("inline:");
+
+ /**
* The name of extra data when starting Browser with ACTION_VIEW or
* ACTION_SEARCH intent.
* <p>
@@ -53,8 +59,26 @@
* identifier.
*/
public static final String EXTRA_APPLICATION_ID =
- "com.android.browser.application_id";
+ "com.android.browser.application_id";
+ /**
+ * The content to be rendered when url's scheme is inline.
+ * @hide
+ */
+ public static final String EXTRA_INLINE_CONTENT ="com.android.browser.inline.content";
+
+ /**
+ * The encoding of the inlined content for inline scheme.
+ * @hide
+ */
+ public static final String EXTRA_INLINE_ENCODING ="com.android.browser.inline.encoding";
+
+ /**
+ * The url used when the inline content is falied to render.
+ * @hide
+ */
+ public static final String EXTRA_INLINE_FAILURL ="com.android.browser.inline.failurl";
+
/* if you change column order you must also change indices
below */
public static final String[] HISTORY_PROJECTION = new String[] {
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 5f383166..c2da593 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1025,6 +1025,14 @@
public static final String SCREEN_OFF_TIMEOUT = "screen_off_timeout";
/**
+ * If 0, the compatibility mode is off for all applications.
+ * If 1, older applications run under compatibility mode.
+ * TODO: remove this settings before code freeze (bug/1907571)
+ * @hide
+ */
+ public static final String COMPATIBILITY_MODE = "compatibility_mode";
+
+ /**
* The screen backlight brightness between 0 and 255.
*/
public static final String SCREEN_BRIGHTNESS = "screen_brightness";
@@ -2491,6 +2499,12 @@
public static final String GMAIL_BUFFER_SERVER_RESPONSE = "gmail_buffer_server_response";
/**
+ * The maximum size in bytes allowed for the provider to gzip a protocol buffer uploaded to
+ * the server.
+ */
+ public static final String GMAIL_MAX_GZIP_SIZE = "gmail_max_gzip_size_bytes";
+
+ /**
* Controls whether Gmail will discard uphill operations that repeatedly fail. Value must be
* an integer where non-zero means true. Defaults to 1.
*/
diff --git a/tts/java/android/tts/ITts.aidl b/core/java/android/speech/tts/ITts.aidl
similarity index 95%
rename from tts/java/android/tts/ITts.aidl
rename to core/java/android/speech/tts/ITts.aidl
index 3558f5a..739a8e4 100755
--- a/tts/java/android/tts/ITts.aidl
+++ b/core/java/android/speech/tts/ITts.aidl
@@ -14,9 +14,9 @@
* limitations under the License.
*/
-package android.tts;
+package android.speech.tts;
-import android.tts.ITtsCallback;
+import android.speech.tts.ITtsCallback;
import android.content.Intent;
diff --git a/tts/java/android/tts/ITtsCallback.aidl b/core/java/android/speech/tts/ITtsCallback.aidl
similarity index 96%
rename from tts/java/android/tts/ITtsCallback.aidl
rename to core/java/android/speech/tts/ITtsCallback.aidl
index 1314010..48ed73e 100755
--- a/tts/java/android/tts/ITtsCallback.aidl
+++ b/core/java/android/speech/tts/ITtsCallback.aidl
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package android.tts;
+package android.speech.tts;
/**
* AIDL for the callback from the TTS Service
diff --git a/core/java/android/speech/tts/Tts.java b/core/java/android/speech/tts/Tts.java
index 0c52910..085b030 100755
--- a/core/java/android/speech/tts/Tts.java
+++ b/core/java/android/speech/tts/Tts.java
@@ -15,8 +15,8 @@
*/
package android.speech.tts;
-import android.tts.ITts;
-import android.tts.ITtsCallback;
+import android.speech.tts.ITts;
+import android.speech.tts.ITtsCallback;
import android.content.ComponentName;
import android.content.Context;
@@ -29,7 +29,6 @@
import android.util.Log;
/**
- * @hide
*
* Synthesizes speech from text. This abstracts away the complexities of using
* the TTS service such as setting up the IBinder connection and handling
@@ -39,8 +38,10 @@
* necessary TTS apk installed, the behavior is that all calls to the TTS act as
* no-ops.
*
+ * {@hide}
*/
//FIXME #TTS# review + complete javadoc
+//FIXME RENAME TO TextToSpeech.java
public class Tts {
diff --git a/core/java/android/text/format/DateUtils.java b/core/java/android/text/format/DateUtils.java
index 9073d82..bccb3a6 100644
--- a/core/java/android/text/format/DateUtils.java
+++ b/core/java/android/text/format/DateUtils.java
@@ -147,6 +147,9 @@
public static final long HOUR_IN_MILLIS = MINUTE_IN_MILLIS * 60;
public static final long DAY_IN_MILLIS = HOUR_IN_MILLIS * 24;
public static final long WEEK_IN_MILLIS = DAY_IN_MILLIS * 7;
+ /**
+ * This constant is actually the length of 364 days, not of a year!
+ */
public static final long YEAR_IN_MILLIS = WEEK_IN_MILLIS * 52;
// The following FORMAT_* symbols are used for specifying the format of
@@ -176,6 +179,9 @@
// Date and time format strings that are constant and don't need to be
// translated.
+ /**
+ * This is not actually the preferred 24-hour date format in all locales.
+ */
public static final String HOUR_MINUTE_24 = "%H:%M";
public static final String MONTH_FORMAT = "%B";
public static final String ABBREV_MONTH_FORMAT = "%b";
@@ -1106,7 +1112,9 @@
*
* <p>
* If FORMAT_CAP_AMPM is set and 12-hour time is used, then the "AM"
- * and "PM" are capitalized.
+ * and "PM" are capitalized. You should not use this flag
+ * because in some locales these terms cannot be capitalized, and in
+ * many others it doesn't make sense to do so even though it is possible.
*
* <p>
* If FORMAT_NO_NOON is set and 12-hour time is used, then "12pm" is
@@ -1114,15 +1122,19 @@
*
* <p>
* If FORMAT_CAP_NOON is set and 12-hour time is used, then "Noon" is
- * shown instead of "noon".
+ * shown instead of "noon". You should probably not use this flag
+ * because in many locales it will not make sense to capitalize
+ * the term.
*
* <p>
* If FORMAT_NO_MIDNIGHT is set and 12-hour time is used, then "12am" is
* shown instead of "midnight".
*
* <p>
- * If FORMAT_CAP_NOON is set and 12-hour time is used, then "Midnight" is
- * shown instead of "midnight".
+ * If FORMAT_CAP_MIDNIGHT is set and 12-hour time is used, then "Midnight"
+ * is shown instead of "midnight". You should probably not use this
+ * flag because in many locales it will not make sense to capitalize
+ * the term.
*
* <p>
* If FORMAT_12HOUR is set and the time is shown, then the time is
@@ -1264,8 +1276,8 @@
use24Hour = DateFormat.is24HourFormat(context);
}
if (use24Hour) {
- startTimeFormat = HOUR_MINUTE_24;
- endTimeFormat = HOUR_MINUTE_24;
+ startTimeFormat = endTimeFormat =
+ res.getString(com.android.internal.R.string.hour_minute_24);
} else {
boolean abbrevTime = (flags & (FORMAT_ABBREV_TIME | FORMAT_ABBREV_ALL)) != 0;
boolean capAMPM = (flags & FORMAT_CAP_AMPM) != 0;
diff --git a/core/java/android/util/DisplayMetrics.java b/core/java/android/util/DisplayMetrics.java
index 987be2b..245148d 100644
--- a/core/java/android/util/DisplayMetrics.java
+++ b/core/java/android/util/DisplayMetrics.java
@@ -103,10 +103,10 @@
}
/**
- * Update the display metrics based on the compatibility info and configuration.
+ * Update the display metrics based on the compatibility info and orientation
* {@hide}
*/
- public void updateMetrics(CompatibilityInfo compatibilityInfo, Configuration configuration) {
+ public void updateMetrics(CompatibilityInfo compatibilityInfo, int orientation) {
if (compatibilityInfo.mScalingRequired) {
float invertedRatio = compatibilityInfo.mApplicationInvertedScale;
density *= invertedRatio;
@@ -116,31 +116,42 @@
widthPixels *= invertedRatio;
heightPixels *= invertedRatio;
}
- if (!compatibilityInfo.mExpandable) {
+ if (!compatibilityInfo.mConfiguredExpandable) {
// Note: this assume that configuration is updated before calling
// updateMetrics method.
int defaultWidth;
int defaultHeight;
- switch (configuration.orientation) {
+ switch (orientation) {
case Configuration.ORIENTATION_LANDSCAPE: {
defaultWidth = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_HEIGHT * density);
defaultHeight = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_WIDTH * density);
break;
}
- case Configuration.ORIENTATION_UNDEFINED:
case Configuration.ORIENTATION_PORTRAIT:
case Configuration.ORIENTATION_SQUARE:
default: {
defaultWidth = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_WIDTH * density);
defaultHeight = (int)(CompatibilityInfo.DEFAULT_PORTRAIT_HEIGHT * density);
+ break;
+ }
+ case Configuration.ORIENTATION_UNDEFINED: {
+ // don't change
+ return;
}
}
- // adjust the size only when the device's screen is bigger.
- if (defaultWidth < widthPixels) {
- widthPixels = defaultWidth;
- }
- if (defaultHeight < heightPixels) {
- heightPixels = defaultHeight;
+
+ if (defaultWidth == widthPixels && defaultHeight == heightPixels) {
+ // the screen size is same as expected size. make it expandable
+ compatibilityInfo.mExpandable = true;
+ } else {
+ compatibilityInfo.mExpandable = false;
+ // adjust the size only when the device's screen is bigger.
+ if (defaultWidth < widthPixels) {
+ widthPixels = defaultWidth;
+ }
+ if (defaultHeight < heightPixels) {
+ heightPixels = defaultHeight;
+ }
}
}
}
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index d8bab56..ee8229d 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -129,7 +129,6 @@
boolean mIsAnimating;
private CompatibilityInfo mCompatibilityInfo;
- private int[] mWindowLayoutParamsBackup = null;
final View.AttachInfo mAttachInfo;
@@ -388,10 +387,11 @@
if (mView == null) {
mView = view;
mWindowAttributes.copyFrom(attrs);
- mCompatibilityInfo =
- mView.getContext().getResources().getCompatibilityInfo();
- if (mCompatibilityInfo.mScalingRequired) {
- mWindowLayoutParamsBackup = new int[4];
+ mCompatibilityInfo = mView.getContext().getResources().getCompatibilityInfo();
+ boolean restore = false;
+ if (mCompatibilityInfo.mScalingRequired || !mCompatibilityInfo.mExpandable) {
+ restore = true;
+ mWindowAttributes.backup();
}
if (!mCompatibilityInfo.mExpandable) {
adjustWindowAttributesForCompatibleMode(mWindowAttributes);
@@ -420,6 +420,11 @@
unscheduleTraversals();
throw new RuntimeException("Adding window failed", e);
}
+
+ if (restore) {
+ mWindowAttributes.restore();
+ }
+
if (mCompatibilityInfo.mScalingRequired) {
mAttachInfo.mContentInsets.scale(
mCompatibilityInfo.mApplicationInvertedScale);
@@ -1921,9 +1926,6 @@
} else {
didFinish = false;
}
- if (event != null && mCompatibilityInfo.mScalingRequired) {
- event.scale(mCompatibilityInfo.mApplicationInvertedScale);
- }
if (DEBUG_TRACKBALL) Log.v(TAG, "Motion event:" + event);
@@ -2355,13 +2357,15 @@
boolean restore = false;
float appScale = mCompatibilityInfo.mApplicationScale;
boolean scalingRequired = mCompatibilityInfo.mScalingRequired;
-
if (params != null && !mCompatibilityInfo.mExpandable) {
+ restore = true;
+ params.backup();
adjustWindowAttributesForCompatibleMode(params);
}
if (params != null && scalingRequired) {
+ if (!restore) params.backup();
restore = true;
- params.scale(appScale, mWindowLayoutParamsBackup);
+ params.scale(appScale);
}
int relayoutResult = sWindowSession.relayout(
mWindow, params,
@@ -2370,7 +2374,7 @@
viewVisibility, insetsPending, mWinFrame,
mPendingContentInsets, mPendingVisibleInsets, mSurface);
if (restore) {
- params.restore(mWindowLayoutParamsBackup);
+ params.restore();
}
if (scalingRequired) {
float invertedScale = mCompatibilityInfo.mApplicationInvertedScale;
@@ -2396,12 +2400,15 @@
if (attrs.width == ViewGroup.LayoutParams.FILL_PARENT) {
attrs.width = metrics.widthPixels;
attrs.gravity |= Gravity.CENTER_HORIZONTAL;
+ mWindowAttributesChanged = attrs == mWindowAttributes;
}
if (attrs.height == ViewGroup.LayoutParams.FILL_PARENT) {
attrs.height = metrics.heightPixels;
+ attrs.gravity |= Gravity.TOP;
+ mWindowAttributesChanged = attrs == mWindowAttributes;
}
if (DEBUG_LAYOUT) {
- Log.d(TAG, "Attributes fixed for compatibility : " + attrs);
+ Log.d(TAG, "Adjusted Attributes for compatibility : " + attrs);
}
}
}
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index ec2069c..e1c4687 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -818,6 +818,9 @@
public static final int SCREEN_ORIENTATION_CHANGED = 1<<10;
public static final int SCREEN_BRIGHTNESS_CHANGED = 1<<11;
+ // internal buffer to backup/restore parameters under compatibility mode.
+ private int[] mCompatibilityParamsBackup = null;
+
public final int copyFrom(LayoutParams o) {
int changes = 0;
@@ -975,37 +978,47 @@
/**
* Scale the layout params' coordinates and size.
- * Returns the original info as a backup so that the caller can
- * restore the layout params;
*/
- void scale(float scale, int[] backup) {
- if (scale != 1.0f) {
- backup[0] = x;
- backup[1] = y;
- x *= scale;
- y *= scale;
- if (width > 0) {
- backup[2] = width;
- width *= scale;
- }
- if (height > 0) {
- backup[3] = height;
- height *= scale;
- }
+ void scale(float scale) {
+ x *= scale;
+ y *= scale;
+ if (width > 0) {
+ width *= scale;
+ }
+ if (height > 0) {
+ height *= scale;
}
}
/**
- * Restore the layout params' coordinates and size.
+ * Backup the layout parameters used in compatibility mode.
+ * @see LayoutParams#restore()
*/
- void restore(int[] backup) {
- x = backup[0];
- y = backup[1];
- if (width > 0) {
- width = backup[2];
+ void backup() {
+ int[] backup = mCompatibilityParamsBackup;
+ if (backup == null) {
+ // we backup 5 elements, x, y, width, height and gravity.
+ backup = mCompatibilityParamsBackup = new int[5];
}
- if (height > 0) {
+ backup[0] = x;
+ backup[1] = y;
+ backup[2] = width;
+ backup[3] = height;
+ backup[4] = gravity;
+ }
+
+ /**
+ * Restore the layout params' coordinates, size and gravity
+ * @see LayoutParams#backup()
+ */
+ void restore() {
+ int[] backup = mCompatibilityParamsBackup;
+ if (backup != null) {
+ x = backup[0];
+ y = backup[1];
+ width = backup[2];
height = backup[3];
+ gravity = backup[4];
}
}
diff --git a/core/java/android/widget/TabHost.java b/core/java/android/widget/TabHost.java
index 5bf8035..103d44d 100644
--- a/core/java/android/widget/TabHost.java
+++ b/core/java/android/widget/TabHost.java
@@ -177,7 +177,7 @@
// leaving touch mode.. if nothing has focus, let's give it to
// the indicator of the current tab
if (!mCurrentView.hasFocus() || mCurrentView.isFocused()) {
- mTabWidget.getChildAt(mCurrentTab).requestFocus();
+ mTabWidget.getChildTabViewAt(mCurrentTab).requestFocus();
}
}
}
@@ -197,6 +197,12 @@
}
View tabIndicator = tabSpec.mIndicatorStrategy.createIndicatorView();
tabIndicator.setOnKeyListener(mTabKeyListener);
+
+ // If this is a custom view, then do not draw the bottom strips for
+ // the tab indicators.
+ if (tabSpec.mIndicatorStrategy instanceof ViewIndicatorStrategy) {
+ mTabWidget.setDrawBottomStrips(false);
+ }
mTabWidget.addView(tabIndicator);
mTabSpecs.add(tabSpec);
@@ -235,7 +241,7 @@
public View getCurrentTabView() {
if (mCurrentTab >= 0 && mCurrentTab < mTabSpecs.size()) {
- return mTabWidget.getChildAt(mCurrentTab);
+ return mTabWidget.getChildTabViewAt(mCurrentTab);
}
return null;
}
@@ -273,7 +279,7 @@
&& (mCurrentView.isRootNamespace())
&& (mCurrentView.hasFocus())
&& (mCurrentView.findFocus().focusSearch(View.FOCUS_UP) == null)) {
- mTabWidget.getChildAt(mCurrentTab).requestFocus();
+ mTabWidget.getChildTabViewAt(mCurrentTab).requestFocus();
playSoundEffect(SoundEffectConstants.NAVIGATION_UP);
return true;
}
@@ -411,6 +417,14 @@
}
/**
+ * Specify a view as the tab indicator.
+ */
+ public TabSpec setIndicator(View view) {
+ mIndicatorStrategy = new ViewIndicatorStrategy(view);
+ return this;
+ }
+
+ /**
* Specify the id of the view that should be used as the content
* of the tab.
*/
@@ -437,7 +451,7 @@
}
- String getTag() {
+ public String getTag() {
return mTag;
}
}
@@ -526,6 +540,22 @@
}
/**
+ * How to create a tab indicator by specifying a view.
+ */
+ private class ViewIndicatorStrategy implements IndicatorStrategy {
+
+ private final View mView;
+
+ private ViewIndicatorStrategy(View view) {
+ mView = view;
+ }
+
+ public View createIndicatorView() {
+ return mView;
+ }
+ }
+
+ /**
* How to create the tab content via a view id.
*/
private class ViewIdContentStrategy implements ContentStrategy {
diff --git a/core/java/android/widget/TabWidget.java b/core/java/android/widget/TabWidget.java
index 20cddcb..a26bfa2 100644
--- a/core/java/android/widget/TabWidget.java
+++ b/core/java/android/widget/TabWidget.java
@@ -49,6 +49,8 @@
private Drawable mBottomLeftStrip;
private Drawable mBottomRightStrip;
private boolean mStripMoved;
+ private Drawable mDividerDrawable;
+ private boolean mDrawBottomStrips = true;
public TabWidget(Context context) {
this(context, null);
@@ -87,9 +89,68 @@
setOnFocusChangeListener(this);
}
+ /**
+ * Returns the tab indicator view at the given index.
+ *
+ * @param index the zero-based index of the tab indicator view to return
+ * @return the tab indicator view at the given index
+ */
+ public View getChildTabViewAt(int index) {
+ // If we are using dividers, then instead of tab views at 0, 1, 2, ...
+ // we have tab views at 0, 2, 4, ...
+ if (mDividerDrawable != null) {
+ index *= 2;
+ }
+ return getChildAt(index);
+ }
+
+ /**
+ * Returns the number of tab indicator views.
+ * @return the number of tab indicator views.
+ */
+ public int getTabCount() {
+ int children = getChildCount();
+
+ // If we have dividers, then we will always have an odd number of
+ // children: 1, 3, 5, ... and we want to convert that sequence to
+ // this: 1, 2, 3, ...
+ if (mDividerDrawable != null) {
+ children = (children + 1) / 2;
+ }
+ return children;
+ }
+
+ /**
+ * Sets the drawable to use as a divider between the tab indicators.
+ * @param drawable the divider drawable
+ */
+ public void setDividerDrawable(Drawable drawable) {
+ mDividerDrawable = drawable;
+ }
+
+ /**
+ * Sets the drawable to use as a divider between the tab indicators.
+ * @param resId the resource identifier of the drawable to use as a
+ * divider.
+ */
+ public void setDividerDrawable(int resId) {
+ mDividerDrawable = mContext.getResources().getDrawable(resId);
+ }
+
+ /**
+ * Controls whether the bottom strips on the tab indicators are drawn or
+ * not. The default is to draw them. If the user specifies a custom
+ * view for the tab indicators, then the TabHost class calls this method
+ * to disable drawing of the bottom strips.
+ * @param drawBottomStrips true if the bottom strips should be drawn.
+ */
+ void setDrawBottomStrips(boolean drawBottomStrips) {
+ mDrawBottomStrips = drawBottomStrips;
+ }
+
@Override
public void childDrawableStateChanged(View child) {
- if (child == getChildAt(mSelectedTab)) {
+ if (child == getChildTabViewAt(mSelectedTab)) {
// To make sure that the bottom strip is redrawn
invalidate();
}
@@ -100,7 +161,14 @@
public void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
- View selectedChild = getChildAt(mSelectedTab);
+ // If the user specified a custom view for the tab indicators, then
+ // do not draw the bottom strips.
+ if (!mDrawBottomStrips) {
+ // Skip drawing the bottom strips.
+ return;
+ }
+
+ View selectedChild = getChildTabViewAt(mSelectedTab);
mBottomLeftStrip.setState(selectedChild.getDrawableState());
mBottomRightStrip.setState(selectedChild.getDrawableState());
@@ -157,13 +225,13 @@
* @see #focusCurrentTab
*/
public void setCurrentTab(int index) {
- if (index < 0 || index >= getChildCount()) {
+ if (index < 0 || index >= getTabCount()) {
return;
}
- getChildAt(mSelectedTab).setSelected(false);
+ getChildTabViewAt(mSelectedTab).setSelected(false);
mSelectedTab = index;
- getChildAt(mSelectedTab).setSelected(true);
+ getChildTabViewAt(mSelectedTab).setSelected(true);
mStripMoved = true;
}
@@ -189,17 +257,17 @@
// change the focus if applicable.
if (oldTab != index) {
- getChildAt(index).requestFocus();
+ getChildTabViewAt(index).requestFocus();
}
}
@Override
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
- int count = getChildCount();
+ int count = getTabCount();
- for (int i=0; i<count; i++) {
- View child = getChildAt(i);
+ for (int i = 0; i < count; i++) {
+ View child = getChildTabViewAt(i);
child.setEnabled(enabled);
}
}
@@ -218,17 +286,26 @@
child.setFocusable(true);
child.setClickable(true);
+ // If we have dividers between the tabs and we already have at least one
+ // tab, then add a divider before adding the next tab.
+ if (mDividerDrawable != null && getTabCount() > 0) {
+ View divider = new View(mContext);
+ final LinearLayout.LayoutParams lp = new LayoutParams(
+ mDividerDrawable.getIntrinsicWidth(),
+ mDividerDrawable.getIntrinsicHeight());
+ lp.setMargins(0, 0, 0, 0);
+ divider.setLayoutParams(lp);
+ divider.setBackgroundDrawable(mDividerDrawable);
+ super.addView(divider);
+ }
super.addView(child);
// TODO: detect this via geometry with a tabwidget listener rather
// than potentially interfere with the view's listener
- child.setOnClickListener(new TabClickListener(getChildCount() - 1));
+ child.setOnClickListener(new TabClickListener(getTabCount() - 1));
child.setOnFocusChangeListener(this);
}
-
-
-
/**
* Provides a way for {@link TabHost} to be notified that the user clicked on a tab indicator.
*/
@@ -238,14 +315,15 @@
public void onFocusChange(View v, boolean hasFocus) {
if (v == this && hasFocus) {
- getChildAt(mSelectedTab).requestFocus();
+ getChildTabViewAt(mSelectedTab).requestFocus();
return;
}
if (hasFocus) {
int i = 0;
- while (i < getChildCount()) {
- if (getChildAt(i) == v) {
+ int numTabs = getTabCount();
+ while (i < numTabs) {
+ if (getChildTabViewAt(i) == v) {
setCurrentTab(i);
mSelectionChangedListener.onTabSelectionChanged(i, false);
break;
diff --git a/core/res/res/values-ar-rEG/donottranslate-cldr.xml b/core/res/res/values-ar-rEG/donottranslate-cldr.xml
index 64f174ec..c88ab7f 100644
--- a/core/res/res/values-ar-rEG/donottranslate-cldr.xml
+++ b/core/res/res/values-ar-rEG/donottranslate-cldr.xml
@@ -91,8 +91,9 @@
<string name="today">اليوم</string>
<string name="tomorrow">غدًا</string>
+ <string name="hour_minute_24">%-k:%M</string>
<string name="hour_minute_ampm">%-l:%M %p</string>
- <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %p</string>
<string name="numeric_date">%-e/%-m/%Y</string>
<string name="numeric_date_format">d/M/yyyy</string>
<string name="month_day_year">%-e %B، %Y</string>
diff --git a/core/res/res/values-bg-rBG/donottranslate-cldr.xml b/core/res/res/values-bg-rBG/donottranslate-cldr.xml
index ae39696..44b2cf9 100644
--- a/core/res/res/values-bg-rBG/donottranslate-cldr.xml
+++ b/core/res/res/values-bg-rBG/donottranslate-cldr.xml
@@ -91,8 +91,9 @@
<string name="today">Днес</string>
<string name="tomorrow">Утре</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %p</string>
<string name="numeric_date">%d.%m.%Y</string>
<string name="numeric_date_format">dd.MM.yyyy</string>
<string name="month_day_year">%d %B %Y</string>
diff --git a/core/res/res/values-ca-rES/donottranslate-cldr.xml b/core/res/res/values-ca-rES/donottranslate-cldr.xml
index 34ed196..52341fe 100644
--- a/core/res/res/values-ca-rES/donottranslate-cldr.xml
+++ b/core/res/res/values-ca-rES/donottranslate-cldr.xml
@@ -91,8 +91,9 @@
<string name="today">avui</string>
<string name="tomorrow">demà</string>
- <string name="hour_minute_ampm">%-k:%M</string>
- <string name="hour_minute_cap_ampm">%-k:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
<string name="numeric_date">%d/%m/%Y</string>
<string name="numeric_date_format">dd/MM/yyyy</string>
<string name="month_day_year">%-e de %B de %Y</string>
diff --git a/core/res/res/values-cs-rCZ/donottranslate-cldr.xml b/core/res/res/values-cs-rCZ/donottranslate-cldr.xml
index c735778..48e0b27 100644
--- a/core/res/res/values-cs-rCZ/donottranslate-cldr.xml
+++ b/core/res/res/values-cs-rCZ/donottranslate-cldr.xml
@@ -91,8 +91,9 @@
<string name="today">Dnes</string>
<string name="tomorrow">Zítra</string>
- <string name="hour_minute_ampm">%-k:%M</string>
- <string name="hour_minute_cap_ampm">%-k:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
<string name="numeric_date">%-e.%-m.%Y</string>
<string name="numeric_date_format">d.M.yyyy</string>
<string name="month_day_year">%-e. %B %Y</string>
diff --git a/core/res/res/values-cs/donottranslate-cldr.xml b/core/res/res/values-cs/donottranslate-cldr.xml
index c735778..48e0b27 100644
--- a/core/res/res/values-cs/donottranslate-cldr.xml
+++ b/core/res/res/values-cs/donottranslate-cldr.xml
@@ -91,8 +91,9 @@
<string name="today">Dnes</string>
<string name="tomorrow">Zítra</string>
- <string name="hour_minute_ampm">%-k:%M</string>
- <string name="hour_minute_cap_ampm">%-k:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
<string name="numeric_date">%-e.%-m.%Y</string>
<string name="numeric_date_format">d.M.yyyy</string>
<string name="month_day_year">%-e. %B %Y</string>
diff --git a/core/res/res/values-da-rDK/donottranslate-cldr.xml b/core/res/res/values-da-rDK/donottranslate-cldr.xml
index e0cc394..4b4794c 100644
--- a/core/res/res/values-da-rDK/donottranslate-cldr.xml
+++ b/core/res/res/values-da-rDK/donottranslate-cldr.xml
@@ -91,8 +91,9 @@
<string name="today">i dag</string>
<string name="tomorrow">i morgen</string>
- <string name="hour_minute_ampm">%H.%M</string>
- <string name="hour_minute_cap_ampm">%H.%M</string>
+ <string name="hour_minute_24">%H.%M</string>
+ <string name="hour_minute_ampm">%-l.%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l.%M %^p</string>
<string name="numeric_date">%d/%m/%Y</string>
<string name="numeric_date_format">dd/MM/yyyy</string>
<string name="month_day_year">%-e. %b %Y</string>
diff --git a/core/res/res/values-de-rAT/donottranslate-cldr.xml b/core/res/res/values-de-rAT/donottranslate-cldr.xml
index 2399e69..24aa25c 100644
--- a/core/res/res/values-de-rAT/donottranslate-cldr.xml
+++ b/core/res/res/values-de-rAT/donottranslate-cldr.xml
@@ -58,8 +58,9 @@
<string name="today">Heute</string>
<string name="tomorrow">Morgen</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
<string name="numeric_date">%d.%m.%Y</string>
<string name="numeric_date_format">dd.MM.yyyy</string>
<string name="month_day_year">%d. %B %Y</string>
diff --git a/core/res/res/values-de-rCH/donottranslate-cldr.xml b/core/res/res/values-de-rCH/donottranslate-cldr.xml
index 7081d02..4a3d96c 100644
--- a/core/res/res/values-de-rCH/donottranslate-cldr.xml
+++ b/core/res/res/values-de-rCH/donottranslate-cldr.xml
@@ -91,8 +91,9 @@
<string name="today">Heute</string>
<string name="tomorrow">Morgen</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
<string name="numeric_date">%d.%m.%Y</string>
<string name="numeric_date_format">dd.MM.yyyy</string>
<string name="month_day_year">%-e. %B %Y</string>
diff --git a/core/res/res/values-de-rDE/donottranslate-cldr.xml b/core/res/res/values-de-rDE/donottranslate-cldr.xml
index 7081d02..4a3d96c 100644
--- a/core/res/res/values-de-rDE/donottranslate-cldr.xml
+++ b/core/res/res/values-de-rDE/donottranslate-cldr.xml
@@ -91,8 +91,9 @@
<string name="today">Heute</string>
<string name="tomorrow">Morgen</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
<string name="numeric_date">%d.%m.%Y</string>
<string name="numeric_date_format">dd.MM.yyyy</string>
<string name="month_day_year">%-e. %B %Y</string>
diff --git a/core/res/res/values-de-rLI/donottranslate-cldr.xml b/core/res/res/values-de-rLI/donottranslate-cldr.xml
index 7081d02..4a3d96c 100644
--- a/core/res/res/values-de-rLI/donottranslate-cldr.xml
+++ b/core/res/res/values-de-rLI/donottranslate-cldr.xml
@@ -91,8 +91,9 @@
<string name="today">Heute</string>
<string name="tomorrow">Morgen</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
<string name="numeric_date">%d.%m.%Y</string>
<string name="numeric_date_format">dd.MM.yyyy</string>
<string name="month_day_year">%-e. %B %Y</string>
diff --git a/core/res/res/values-de/donottranslate-cldr.xml b/core/res/res/values-de/donottranslate-cldr.xml
index 7081d02..4a3d96c 100644
--- a/core/res/res/values-de/donottranslate-cldr.xml
+++ b/core/res/res/values-de/donottranslate-cldr.xml
@@ -91,8 +91,9 @@
<string name="today">Heute</string>
<string name="tomorrow">Morgen</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
<string name="numeric_date">%d.%m.%Y</string>
<string name="numeric_date_format">dd.MM.yyyy</string>
<string name="month_day_year">%-e. %B %Y</string>
diff --git a/core/res/res/values-el-rGR/donottranslate-cldr.xml b/core/res/res/values-el-rGR/donottranslate-cldr.xml
index d6a1010..ccfa794 100644
--- a/core/res/res/values-el-rGR/donottranslate-cldr.xml
+++ b/core/res/res/values-el-rGR/donottranslate-cldr.xml
@@ -91,8 +91,9 @@
<string name="today">Σήμερα</string>
<string name="tomorrow">Αύριο</string>
+ <string name="hour_minute_24">%-k:%M</string>
<string name="hour_minute_ampm">%-l:%M %p</string>
- <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %p</string>
<string name="numeric_date">%d/%m/%Y</string>
<string name="numeric_date_format">dd/MM/yyyy</string>
<string name="month_day_year">%d %B %Y</string>
diff --git a/core/res/res/values-en-rAU/donottranslate-cldr.xml b/core/res/res/values-en-rAU/donottranslate-cldr.xml
index 9e4b88e..452d586 100644
--- a/core/res/res/values-en-rAU/donottranslate-cldr.xml
+++ b/core/res/res/values-en-rAU/donottranslate-cldr.xml
@@ -91,6 +91,7 @@
<string name="today">Today</string>
<string name="tomorrow">Tomorrow</string>
+ <string name="hour_minute_24">%H:%M</string>
<string name="hour_minute_ampm">%-l:%M%p</string>
<string name="hour_minute_cap_ampm">%-l:%M%^p</string>
<string name="numeric_date">%-e/%m/%Y</string>
diff --git a/core/res/res/values-en-rCA/donottranslate-cldr.xml b/core/res/res/values-en-rCA/donottranslate-cldr.xml
index 5340c29..ce7bbd0 100644
--- a/core/res/res/values-en-rCA/donottranslate-cldr.xml
+++ b/core/res/res/values-en-rCA/donottranslate-cldr.xml
@@ -91,6 +91,7 @@
<string name="today">Today</string>
<string name="tomorrow">Tomorrow</string>
+ <string name="hour_minute_24">%H:%M</string>
<string name="hour_minute_ampm">%-l:%M%p</string>
<string name="hour_minute_cap_ampm">%-l:%M%^p</string>
<string name="numeric_date">%Y-%m-%d</string>
diff --git a/core/res/res/values-en-rGB/donottranslate-cldr.xml b/core/res/res/values-en-rGB/donottranslate-cldr.xml
index 226968a..36afbd3b 100644
--- a/core/res/res/values-en-rGB/donottranslate-cldr.xml
+++ b/core/res/res/values-en-rGB/donottranslate-cldr.xml
@@ -91,8 +91,9 @@
<string name="today">Today</string>
<string name="tomorrow">Tomorrow</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%H:%M</string>
+ <string name="hour_minute_ampm">%-l:%M%p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M%^p</string>
<string name="numeric_date">%d/%m/%Y</string>
<string name="numeric_date_format">dd/MM/yyyy</string>
<string name="month_day_year">%-e %B %Y</string>
diff --git a/core/res/res/values-en-rIE/donottranslate-cldr.xml b/core/res/res/values-en-rIE/donottranslate-cldr.xml
index 2809bc0..dd8e730 100644
--- a/core/res/res/values-en-rIE/donottranslate-cldr.xml
+++ b/core/res/res/values-en-rIE/donottranslate-cldr.xml
@@ -91,8 +91,9 @@
<string name="today">Today</string>
<string name="tomorrow">Tomorrow</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%H:%M</string>
+ <string name="hour_minute_ampm">%-l:%M%p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M%^p</string>
<string name="numeric_date">%d/%m/%Y</string>
<string name="numeric_date_format">dd/MM/yyyy</string>
<string name="month_day_year">%-e %B %Y</string>
diff --git a/core/res/res/values-en-rIN/donottranslate-cldr.xml b/core/res/res/values-en-rIN/donottranslate-cldr.xml
index 82fce91..df44b4a 100644
--- a/core/res/res/values-en-rIN/donottranslate-cldr.xml
+++ b/core/res/res/values-en-rIN/donottranslate-cldr.xml
@@ -91,6 +91,7 @@
<string name="today">Today</string>
<string name="tomorrow">Tomorrow</string>
+ <string name="hour_minute_24">%H:%M</string>
<string name="hour_minute_ampm">%-l:%M%p</string>
<string name="hour_minute_cap_ampm">%-l:%M%^p</string>
<string name="numeric_date">%d/%m/%Y</string>
diff --git a/core/res/res/values-en-rNZ/donottranslate-cldr.xml b/core/res/res/values-en-rNZ/donottranslate-cldr.xml
index 1055981..1ed626e 100644
--- a/core/res/res/values-en-rNZ/donottranslate-cldr.xml
+++ b/core/res/res/values-en-rNZ/donottranslate-cldr.xml
@@ -91,6 +91,7 @@
<string name="today">Today</string>
<string name="tomorrow">Tomorrow</string>
+ <string name="hour_minute_24">%H:%M</string>
<string name="hour_minute_ampm">%-l:%M%p</string>
<string name="hour_minute_cap_ampm">%-l:%M%^p</string>
<string name="numeric_date">%-e/%m/%Y</string>
diff --git a/core/res/res/values-en-rSG/donottranslate-cldr.xml b/core/res/res/values-en-rSG/donottranslate-cldr.xml
index e3808a7..b13a986 100644
--- a/core/res/res/values-en-rSG/donottranslate-cldr.xml
+++ b/core/res/res/values-en-rSG/donottranslate-cldr.xml
@@ -91,6 +91,7 @@
<string name="today">Today</string>
<string name="tomorrow">Tomorrow</string>
+ <string name="hour_minute_24">%H:%M</string>
<string name="hour_minute_ampm">%-l:%M%p</string>
<string name="hour_minute_cap_ampm">%-l:%M%^p</string>
<string name="numeric_date">%-m/%-e/%Y</string>
diff --git a/core/res/res/values-en-rUS/donottranslate-cldr.xml b/core/res/res/values-en-rUS/donottranslate-cldr.xml
index e3808a7..b13a986 100644
--- a/core/res/res/values-en-rUS/donottranslate-cldr.xml
+++ b/core/res/res/values-en-rUS/donottranslate-cldr.xml
@@ -91,6 +91,7 @@
<string name="today">Today</string>
<string name="tomorrow">Tomorrow</string>
+ <string name="hour_minute_24">%H:%M</string>
<string name="hour_minute_ampm">%-l:%M%p</string>
<string name="hour_minute_cap_ampm">%-l:%M%^p</string>
<string name="numeric_date">%-m/%-e/%Y</string>
diff --git a/core/res/res/values-en-rZA/donottranslate-cldr.xml b/core/res/res/values-en-rZA/donottranslate-cldr.xml
index bfde8a3..bc2083d 100644
--- a/core/res/res/values-en-rZA/donottranslate-cldr.xml
+++ b/core/res/res/values-en-rZA/donottranslate-cldr.xml
@@ -91,6 +91,7 @@
<string name="today">Today</string>
<string name="tomorrow">Tomorrow</string>
+ <string name="hour_minute_24">%H:%M</string>
<string name="hour_minute_ampm">%-l:%M%p</string>
<string name="hour_minute_cap_ampm">%-l:%M%^p</string>
<string name="numeric_date">%Y/%m/%d</string>
diff --git a/core/res/res/values-es-rES/donottranslate-cldr.xml b/core/res/res/values-es-rES/donottranslate-cldr.xml
index aeb93ea..5c6f721 100644
--- a/core/res/res/values-es-rES/donottranslate-cldr.xml
+++ b/core/res/res/values-es-rES/donottranslate-cldr.xml
@@ -91,8 +91,9 @@
<string name="today">hoy</string>
<string name="tomorrow">mañana</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
<string name="numeric_date">%d/%m/%Y</string>
<string name="numeric_date_format">dd/MM/yyyy</string>
<string name="month_day_year">%-e de %B de %Y</string>
diff --git a/core/res/res/values-es-rUS/donottranslate-cldr.xml b/core/res/res/values-es-rUS/donottranslate-cldr.xml
index 6bcdfd7..9ba828d 100644
--- a/core/res/res/values-es-rUS/donottranslate-cldr.xml
+++ b/core/res/res/values-es-rUS/donottranslate-cldr.xml
@@ -91,6 +91,7 @@
<string name="today">hoy</string>
<string name="tomorrow">mañana</string>
+ <string name="hour_minute_24">%-k:%M</string>
<string name="hour_minute_ampm">%-l:%M %p</string>
<string name="hour_minute_cap_ampm">%-l:%M %^p</string>
<string name="numeric_date">%-m/%-e/%Y</string>
diff --git a/core/res/res/values-es/donottranslate-cldr.xml b/core/res/res/values-es/donottranslate-cldr.xml
index aeb93ea..5c6f721 100644
--- a/core/res/res/values-es/donottranslate-cldr.xml
+++ b/core/res/res/values-es/donottranslate-cldr.xml
@@ -91,8 +91,9 @@
<string name="today">hoy</string>
<string name="tomorrow">mañana</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
<string name="numeric_date">%d/%m/%Y</string>
<string name="numeric_date_format">dd/MM/yyyy</string>
<string name="month_day_year">%-e de %B de %Y</string>
diff --git a/core/res/res/values-fi-rFI/donottranslate-cldr.xml b/core/res/res/values-fi-rFI/donottranslate-cldr.xml
index 96b5cd6..36dbd04 100644
--- a/core/res/res/values-fi-rFI/donottranslate-cldr.xml
+++ b/core/res/res/values-fi-rFI/donottranslate-cldr.xml
@@ -91,8 +91,9 @@
<string name="today">tänään</string>
<string name="tomorrow">huomenna</string>
- <string name="hour_minute_ampm">%-k.%M</string>
- <string name="hour_minute_cap_ampm">%-k.%M</string>
+ <string name="hour_minute_24">%-k.%M</string>
+ <string name="hour_minute_ampm">%-l.%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l.%M %^p</string>
<string name="numeric_date">%-e.%-m.%Y</string>
<string name="numeric_date_format">d.M.yyyy</string>
<string name="month_day_year">%-e. %B %Y</string>
diff --git a/core/res/res/values-fr-rBE/donottranslate-cldr.xml b/core/res/res/values-fr-rBE/donottranslate-cldr.xml
index 01f6c0c..5a6f345 100644
--- a/core/res/res/values-fr-rBE/donottranslate-cldr.xml
+++ b/core/res/res/values-fr-rBE/donottranslate-cldr.xml
@@ -91,8 +91,9 @@
<string name="today">aujourd’hui</string>
<string name="tomorrow">demain</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
<string name="numeric_date">%-e/%m/%Y</string>
<string name="numeric_date_format">d/MM/yyyy</string>
<string name="month_day_year">%-e %B %Y</string>
diff --git a/core/res/res/values-fr-rCA/donottranslate-cldr.xml b/core/res/res/values-fr-rCA/donottranslate-cldr.xml
index 8039e273..68f659a 100644
--- a/core/res/res/values-fr-rCA/donottranslate-cldr.xml
+++ b/core/res/res/values-fr-rCA/donottranslate-cldr.xml
@@ -91,8 +91,9 @@
<string name="today">aujourd’hui</string>
<string name="tomorrow">demain</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
<string name="numeric_date">%Y-%m-%d</string>
<string name="numeric_date_format">yyyy-MM-dd</string>
<string name="month_day_year">%-e %B %Y</string>
diff --git a/core/res/res/values-fr-rCH/donottranslate-cldr.xml b/core/res/res/values-fr-rCH/donottranslate-cldr.xml
index 63c2d2b..0ca1549 100644
--- a/core/res/res/values-fr-rCH/donottranslate-cldr.xml
+++ b/core/res/res/values-fr-rCH/donottranslate-cldr.xml
@@ -91,8 +91,9 @@
<string name="today">aujourd’hui</string>
<string name="tomorrow">demain</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
<string name="numeric_date">%d.%m.%Y</string>
<string name="numeric_date_format">dd.MM.yyyy</string>
<string name="month_day_year">%-e %B %Y</string>
diff --git a/core/res/res/values-fr-rFR/donottranslate-cldr.xml b/core/res/res/values-fr-rFR/donottranslate-cldr.xml
index ac168be..c3fce4c 100644
--- a/core/res/res/values-fr-rFR/donottranslate-cldr.xml
+++ b/core/res/res/values-fr-rFR/donottranslate-cldr.xml
@@ -91,8 +91,9 @@
<string name="today">aujourd’hui</string>
<string name="tomorrow">demain</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
<string name="numeric_date">%d/%m/%Y</string>
<string name="numeric_date_format">dd/MM/yyyy</string>
<string name="month_day_year">%-e %B %Y</string>
diff --git a/core/res/res/values-fr/donottranslate-cldr.xml b/core/res/res/values-fr/donottranslate-cldr.xml
index ac168be..c3fce4c 100644
--- a/core/res/res/values-fr/donottranslate-cldr.xml
+++ b/core/res/res/values-fr/donottranslate-cldr.xml
@@ -91,8 +91,9 @@
<string name="today">aujourd’hui</string>
<string name="tomorrow">demain</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
<string name="numeric_date">%d/%m/%Y</string>
<string name="numeric_date_format">dd/MM/yyyy</string>
<string name="month_day_year">%-e %B %Y</string>
diff --git a/core/res/res/values-he-rIL/donottranslate-cldr.xml b/core/res/res/values-he-rIL/donottranslate-cldr.xml
index 316db35..11e820d 100644
--- a/core/res/res/values-he-rIL/donottranslate-cldr.xml
+++ b/core/res/res/values-he-rIL/donottranslate-cldr.xml
@@ -91,8 +91,9 @@
<string name="today">היום</string>
<string name="tomorrow">מחר</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %p</string>
<string name="numeric_date">%d/%m/%Y</string>
<string name="numeric_date_format">dd/MM/yyyy</string>
<string name="month_day_year">%-e ב%B %Y</string>
diff --git a/core/res/res/values-hi-rIN/donottranslate-cldr.xml b/core/res/res/values-hi-rIN/donottranslate-cldr.xml
index 6e8b887..44f29c0 100644
--- a/core/res/res/values-hi-rIN/donottranslate-cldr.xml
+++ b/core/res/res/values-hi-rIN/donottranslate-cldr.xml
@@ -91,6 +91,7 @@
<string name="today">Today</string>
<string name="tomorrow">Tomorrow</string>
+ <string name="hour_minute_24">%-k:%M</string>
<string name="hour_minute_ampm">%-l:%M %p</string>
<string name="hour_minute_cap_ampm">%-l:%M %^p</string>
<string name="numeric_date">%-e-%-m-%Y</string>
diff --git a/core/res/res/values-hu-rHU/donottranslate-cldr.xml b/core/res/res/values-hu-rHU/donottranslate-cldr.xml
index 18c680f..a5493bb 100644
--- a/core/res/res/values-hu-rHU/donottranslate-cldr.xml
+++ b/core/res/res/values-hu-rHU/donottranslate-cldr.xml
@@ -91,8 +91,9 @@
<string name="today">ma</string>
<string name="tomorrow">holnap</string>
- <string name="hour_minute_ampm">%-k:%M</string>
- <string name="hour_minute_cap_ampm">%-k:%M</string>
+ <string name="hour_minute_24">%H:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
<string name="numeric_date">%Y.%m.%d.</string>
<string name="numeric_date_format">yyyy.MM.dd.</string>
<string name="month_day_year">%Y. %B %-e.</string>
diff --git a/core/res/res/values-id-rID/donottranslate-cldr.xml b/core/res/res/values-id-rID/donottranslate-cldr.xml
index 6120a7b..a09be25 100644
--- a/core/res/res/values-id-rID/donottranslate-cldr.xml
+++ b/core/res/res/values-id-rID/donottranslate-cldr.xml
@@ -91,8 +91,9 @@
<string name="today">Today</string>
<string name="tomorrow">Tomorrow</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
<string name="numeric_date">%d/%m/%Y</string>
<string name="numeric_date_format">dd/MM/yyyy</string>
<string name="month_day_year">%-e %B %Y</string>
diff --git a/core/res/res/values-it-rCH/donottranslate-cldr.xml b/core/res/res/values-it-rCH/donottranslate-cldr.xml
index 8dc042d..48571a0e 100644
--- a/core/res/res/values-it-rCH/donottranslate-cldr.xml
+++ b/core/res/res/values-it-rCH/donottranslate-cldr.xml
@@ -86,8 +86,9 @@
<string name="today">oggi</string>
<string name="tomorrow">domani</string>
- <string name="hour_minute_ampm">%H.%M</string>
- <string name="hour_minute_cap_ampm">%H.%M</string>
+ <string name="hour_minute_24">%H:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
<string name="numeric_date">%d.%m.%Y</string>
<string name="numeric_date_format">dd.MM.yyyy</string>
<string name="month_day_year">%-e %B %Y</string>
diff --git a/core/res/res/values-it-rIT/donottranslate-cldr.xml b/core/res/res/values-it-rIT/donottranslate-cldr.xml
index 93cda6e..d20a631 100644
--- a/core/res/res/values-it-rIT/donottranslate-cldr.xml
+++ b/core/res/res/values-it-rIT/donottranslate-cldr.xml
@@ -86,8 +86,9 @@
<string name="today">oggi</string>
<string name="tomorrow">domani</string>
- <string name="hour_minute_ampm">%H.%M</string>
- <string name="hour_minute_cap_ampm">%H.%M</string>
+ <string name="hour_minute_24">%H:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
<string name="numeric_date">%d/%m/%Y</string>
<string name="numeric_date_format">dd/MM/yyyy</string>
<string name="month_day_year">%d %B %Y</string>
diff --git a/core/res/res/values-it/donottranslate-cldr.xml b/core/res/res/values-it/donottranslate-cldr.xml
index 93cda6e..d20a631 100644
--- a/core/res/res/values-it/donottranslate-cldr.xml
+++ b/core/res/res/values-it/donottranslate-cldr.xml
@@ -86,8 +86,9 @@
<string name="today">oggi</string>
<string name="tomorrow">domani</string>
- <string name="hour_minute_ampm">%H.%M</string>
- <string name="hour_minute_cap_ampm">%H.%M</string>
+ <string name="hour_minute_24">%H:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
<string name="numeric_date">%d/%m/%Y</string>
<string name="numeric_date_format">dd/MM/yyyy</string>
<string name="month_day_year">%d %B %Y</string>
diff --git a/core/res/res/values-ja-rJP/donottranslate-cldr.xml b/core/res/res/values-ja-rJP/donottranslate-cldr.xml
index e2d1f2e..52c93133 100644
--- a/core/res/res/values-ja-rJP/donottranslate-cldr.xml
+++ b/core/res/res/values-ja-rJP/donottranslate-cldr.xml
@@ -91,8 +91,9 @@
<string name="today">今日</string>
<string name="tomorrow">明日</string>
- <string name="hour_minute_ampm">%-k:%M</string>
- <string name="hour_minute_cap_ampm">%-k:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%p%-l:%M</string>
+ <string name="hour_minute_cap_ampm">%p%-l:%M</string>
<string name="numeric_date">%Y/%m/%d</string>
<string name="numeric_date_format">yyyy/MM/dd</string>
<string name="month_day_year">%Y年%-m月%-e日</string>
diff --git a/core/res/res/values-ja/donottranslate-cldr.xml b/core/res/res/values-ja/donottranslate-cldr.xml
index e2d1f2e..52c93133 100644
--- a/core/res/res/values-ja/donottranslate-cldr.xml
+++ b/core/res/res/values-ja/donottranslate-cldr.xml
@@ -91,8 +91,9 @@
<string name="today">今日</string>
<string name="tomorrow">明日</string>
- <string name="hour_minute_ampm">%-k:%M</string>
- <string name="hour_minute_cap_ampm">%-k:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%p%-l:%M</string>
+ <string name="hour_minute_cap_ampm">%p%-l:%M</string>
<string name="numeric_date">%Y/%m/%d</string>
<string name="numeric_date_format">yyyy/MM/dd</string>
<string name="month_day_year">%Y年%-m月%-e日</string>
diff --git a/core/res/res/values-ko-rKR/donottranslate-cldr.xml b/core/res/res/values-ko-rKR/donottranslate-cldr.xml
index 61e82f8..f641f65 100644
--- a/core/res/res/values-ko-rKR/donottranslate-cldr.xml
+++ b/core/res/res/values-ko-rKR/donottranslate-cldr.xml
@@ -79,8 +79,9 @@
<string name="today">오늘</string>
<string name="tomorrow">내일</string>
- <string name="hour_minute_ampm">%p %-l:%M</string>
- <string name="hour_minute_cap_ampm">%^p %-l:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %p</string>
<string name="numeric_date">%Y. %-m. %-e.</string>
<string name="numeric_date_format">yyyy. M. d.</string>
<string name="month_day_year">%Y년 %-m월 %-e일</string>
diff --git a/core/res/res/values-ko/donottranslate-cldr.xml b/core/res/res/values-ko/donottranslate-cldr.xml
index 61e82f8..f641f65 100644
--- a/core/res/res/values-ko/donottranslate-cldr.xml
+++ b/core/res/res/values-ko/donottranslate-cldr.xml
@@ -79,8 +79,9 @@
<string name="today">오늘</string>
<string name="tomorrow">내일</string>
- <string name="hour_minute_ampm">%p %-l:%M</string>
- <string name="hour_minute_cap_ampm">%^p %-l:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %p</string>
<string name="numeric_date">%Y. %-m. %-e.</string>
<string name="numeric_date_format">yyyy. M. d.</string>
<string name="month_day_year">%Y년 %-m월 %-e일</string>
diff --git a/core/res/res/values-lt-rLT/donottranslate-cldr.xml b/core/res/res/values-lt-rLT/donottranslate-cldr.xml
index d004f70..87d7aae 100644
--- a/core/res/res/values-lt-rLT/donottranslate-cldr.xml
+++ b/core/res/res/values-lt-rLT/donottranslate-cldr.xml
@@ -91,8 +91,9 @@
<string name="today">šiandien</string>
<string name="tomorrow">rytoj</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %p</string>
<string name="numeric_date">%Y-%m-%d</string>
<string name="numeric_date_format">yyyy-MM-dd</string>
<string name="month_day_year">%Y m. %B %-e d.</string>
diff --git a/core/res/res/values-lv-rLV/donottranslate-cldr.xml b/core/res/res/values-lv-rLV/donottranslate-cldr.xml
index d0751d0..bfc2d3b 100644
--- a/core/res/res/values-lv-rLV/donottranslate-cldr.xml
+++ b/core/res/res/values-lv-rLV/donottranslate-cldr.xml
@@ -91,8 +91,9 @@
<string name="today">šodien</string>
<string name="tomorrow">rīt</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%H:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
<string name="numeric_date">%d.%m.%Y</string>
<string name="numeric_date_format">dd.MM.yyyy</string>
<string name="month_day_year">%Y. gada %-e. %B</string>
diff --git a/core/res/res/values-mcc204-pt/strings.xml b/core/res/res/values-mcc204-pt/strings.xml
new file mode 100644
index 0000000..7d96230
--- /dev/null
+++ b/core/res/res/values-mcc204-pt/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2009 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.
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="locale_replacement">"nl_nl"</string>
+</resources>
diff --git a/core/res/res/values-mcc230-pt/strings.xml b/core/res/res/values-mcc230-pt/strings.xml
new file mode 100644
index 0000000..d3ecdbb
--- /dev/null
+++ b/core/res/res/values-mcc230-pt/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2009 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.
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="locale_replacement">"cs_cz"</string>
+</resources>
diff --git a/core/res/res/values-mcc232-pt/strings.xml b/core/res/res/values-mcc232-pt/strings.xml
new file mode 100644
index 0000000..4773838
--- /dev/null
+++ b/core/res/res/values-mcc232-pt/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2009 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.
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="locale_replacement">"de_at"</string>
+</resources>
diff --git a/core/res/res/values-mcc234-pt/strings.xml b/core/res/res/values-mcc234-pt/strings.xml
new file mode 100644
index 0000000..2538b73
--- /dev/null
+++ b/core/res/res/values-mcc234-pt/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2009 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.
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="locale_replacement">"en_gb"</string>
+</resources>
diff --git a/core/res/res/values-mcc260-pt/strings.xml b/core/res/res/values-mcc260-pt/strings.xml
new file mode 100644
index 0000000..1161f9a
--- /dev/null
+++ b/core/res/res/values-mcc260-pt/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2009 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.
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="locale_replacement">"pl_pl"</string>
+</resources>
diff --git a/core/res/res/values-mcc262-pt/strings.xml b/core/res/res/values-mcc262-pt/strings.xml
new file mode 100644
index 0000000..9505cf4
--- /dev/null
+++ b/core/res/res/values-mcc262-pt/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2009 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.
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="locale_replacement">"de_de"</string>
+</resources>
diff --git a/core/res/res/values-nb/donottranslate-cldr.xml b/core/res/res/values-nb/donottranslate-cldr.xml
index 1aebf2e..61271ed 100644
--- a/core/res/res/values-nb/donottranslate-cldr.xml
+++ b/core/res/res/values-nb/donottranslate-cldr.xml
@@ -91,8 +91,9 @@
<string name="today">i dag</string>
<string name="tomorrow">i morgen</string>
- <string name="hour_minute_ampm">%H.%M</string>
- <string name="hour_minute_cap_ampm">%H.%M</string>
+ <string name="hour_minute_24">%H.%M</string>
+ <string name="hour_minute_ampm">%-l.%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l.%M %^p</string>
<string name="numeric_date">%d.%m.%Y</string>
<string name="numeric_date_format">dd.MM.yyyy</string>
<string name="month_day_year">%-e. %B %Y</string>
diff --git a/core/res/res/values-nl-rBE/donottranslate-cldr.xml b/core/res/res/values-nl-rBE/donottranslate-cldr.xml
index 3ab87b0..b29f0c0 100644
--- a/core/res/res/values-nl-rBE/donottranslate-cldr.xml
+++ b/core/res/res/values-nl-rBE/donottranslate-cldr.xml
@@ -91,8 +91,9 @@
<string name="today">Vandaag</string>
<string name="tomorrow">Morgen</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%H:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
<string name="numeric_date">%-e/%m/%Y</string>
<string name="numeric_date_format">d/MM/yyyy</string>
<string name="month_day_year">%-e %B %Y</string>
diff --git a/core/res/res/values-nl-rNL/donottranslate-cldr.xml b/core/res/res/values-nl-rNL/donottranslate-cldr.xml
index accd086..a35d9e6 100644
--- a/core/res/res/values-nl-rNL/donottranslate-cldr.xml
+++ b/core/res/res/values-nl-rNL/donottranslate-cldr.xml
@@ -91,8 +91,9 @@
<string name="today">Vandaag</string>
<string name="tomorrow">Morgen</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%H:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
<string name="numeric_date">%d-%m-%Y</string>
<string name="numeric_date_format">dd-MM-yyyy</string>
<string name="month_day_year">%-e %B %Y</string>
diff --git a/core/res/res/values-nl/donottranslate-cldr.xml b/core/res/res/values-nl/donottranslate-cldr.xml
index accd086..a35d9e6 100644
--- a/core/res/res/values-nl/donottranslate-cldr.xml
+++ b/core/res/res/values-nl/donottranslate-cldr.xml
@@ -91,8 +91,9 @@
<string name="today">Vandaag</string>
<string name="tomorrow">Morgen</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%H:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
<string name="numeric_date">%d-%m-%Y</string>
<string name="numeric_date_format">dd-MM-yyyy</string>
<string name="month_day_year">%-e %B %Y</string>
diff --git a/core/res/res/values-pl-rPL/donottranslate-cldr.xml b/core/res/res/values-pl-rPL/donottranslate-cldr.xml
index 2d23d61..4537692 100644
--- a/core/res/res/values-pl-rPL/donottranslate-cldr.xml
+++ b/core/res/res/values-pl-rPL/donottranslate-cldr.xml
@@ -91,8 +91,9 @@
<string name="today">Dzisiaj</string>
<string name="tomorrow">Jutro</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
<string name="numeric_date">%d-%m-%Y</string>
<string name="numeric_date_format">dd-MM-yyyy</string>
<string name="month_day_year">%-e %B %Y</string>
diff --git a/core/res/res/values-pl/donottranslate-cldr.xml b/core/res/res/values-pl/donottranslate-cldr.xml
index 2d23d61..4537692 100644
--- a/core/res/res/values-pl/donottranslate-cldr.xml
+++ b/core/res/res/values-pl/donottranslate-cldr.xml
@@ -91,8 +91,9 @@
<string name="today">Dzisiaj</string>
<string name="tomorrow">Jutro</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
<string name="numeric_date">%d-%m-%Y</string>
<string name="numeric_date_format">dd-MM-yyyy</string>
<string name="month_day_year">%-e %B %Y</string>
diff --git a/core/res/res/values-pt-rBR/donottranslate-cldr.xml b/core/res/res/values-pt-rBR/donottranslate-cldr.xml
index 0976292..493a3cb 100644
--- a/core/res/res/values-pt-rBR/donottranslate-cldr.xml
+++ b/core/res/res/values-pt-rBR/donottranslate-cldr.xml
@@ -91,8 +91,9 @@
<string name="today">Hoje</string>
<string name="tomorrow">Amanhã</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%-kh%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
<string name="numeric_date">%d/%m/%Y</string>
<string name="numeric_date_format">dd/MM/yyyy</string>
<string name="month_day_year">%-e de %B de %Y</string>
diff --git a/core/res/res/values-pt-rPT/donottranslate-cldr.xml b/core/res/res/values-pt-rPT/donottranslate-cldr.xml
index bbb8c1b..e179c11 100644
--- a/core/res/res/values-pt-rPT/donottranslate-cldr.xml
+++ b/core/res/res/values-pt-rPT/donottranslate-cldr.xml
@@ -91,8 +91,9 @@
<string name="today">Hoje</string>
<string name="tomorrow">Amanhã</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%-kh%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
<string name="numeric_date">%d/%m/%Y</string>
<string name="numeric_date_format">dd/MM/yyyy</string>
<string name="month_day_year">%-e de %B de %Y</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
new file mode 100644
index 0000000..bcfcd52
--- /dev/null
+++ b/core/res/res/values-pt/strings.xml
@@ -0,0 +1,799 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2009 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.
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="byteShort">"B"</string>
+ <string name="kilobyteShort">"KB"</string>
+ <string name="megabyteShort">"MB"</string>
+ <string name="gigabyteShort">"GB"</string>
+ <string name="terabyteShort">"TB"</string>
+ <string name="petabyteShort">"PB"</string>
+ <string name="untitled">"<sem título>"</string>
+ <string name="ellipsis">"…"</string>
+ <string name="emptyPhoneNumber">"(Nenhum número de telefone)"</string>
+ <string name="unknownName">"(Desconhecido)"</string>
+ <string name="defaultVoiceMailAlphaTag">"Correio de voz"</string>
+ <string name="defaultMsisdnAlphaTag">"MSISDN1"</string>
+ <string name="mmiError">"Problema de conexão ou código MMI inválido."</string>
+ <string name="serviceEnabled">"O serviço foi ativado."</string>
+ <string name="serviceEnabledFor">"O serviço foi ativado para:"</string>
+ <string name="serviceDisabled">"O serviço foi desativado."</string>
+ <string name="serviceRegistered">"O registro foi bem-sucedido."</string>
+ <string name="serviceErased">"Exclusão bem-sucedida."</string>
+ <string name="passwordIncorrect">"Senha incorreta"</string>
+ <string name="mmiComplete">"MMI completo."</string>
+ <string name="badPin">"O PIN antigo digitado não está correto."</string>
+ <string name="badPuk">"O PUK digitado não está correto."</string>
+ <string name="mismatchPin">"Os PINs digitados não correspondem."</string>
+ <string name="invalidPin">"Digite um PIN com 4 a 8 números."</string>
+ <string name="needPuk">"Seu cartão SIM está bloqueado pelo código PUK. Digite o PUK para desbloqueá-lo."</string>
+ <string name="needPuk2">"Digite PUK2 para desbloquear cartão SIM."</string>
+ <string name="ClipMmi">"ID do chamador"</string>
+ <string name="ClirMmi">"ID de quem realiza a chamada"</string>
+ <string name="CfMmi">"Transferência de chamada"</string>
+ <string name="CwMmi">"Chamada em espera"</string>
+ <string name="BaMmi">"Bloqueio de chamada"</string>
+ <string name="PwdMmi">"Alteração da senha"</string>
+ <string name="PinMmi">"Alteração de PIN"</string>
+ <!-- no translation found for CnipMmi (3110534680557857162) -->
+ <skip />
+ <!-- no translation found for CnirMmi (3062102121430548731) -->
+ <skip />
+ <!-- no translation found for ThreeWCMmi (9051047170321190368) -->
+ <skip />
+ <!-- no translation found for RuacMmi (7827887459138308886) -->
+ <skip />
+ <!-- no translation found for CndMmi (3116446237081575808) -->
+ <skip />
+ <!-- no translation found for DndMmi (1265478932418334331) -->
+ <skip />
+ <string name="CLIRDefaultOnNextCallOn">"ID do chamador assume o padrão de restrito. Próxima chamada: restrita"</string>
+ <string name="CLIRDefaultOnNextCallOff">"ID do chamador assume o padrão de restrito. Próxima chamada: não restrita"</string>
+ <string name="CLIRDefaultOffNextCallOn">"ID do chamador assume o padrão de não restrito. Próxima chamada: restrita"</string>
+ <string name="CLIRDefaultOffNextCallOff">"ID do chamador assume o padrão de não restrito. Próxima chamada: não restrita"</string>
+ <string name="serviceNotProvisioned">"Serviço não fornecido"</string>
+ <string name="CLIRPermanent">"A configuração da ID do chamador não pode ser alterada."</string>
+ <!-- no translation found for RestrictedChangedTitle (5592189398956187498) -->
+ <skip />
+ <!-- no translation found for RestrictedOnData (8653794784690065540) -->
+ <skip />
+ <!-- no translation found for RestrictedOnEmergency (6581163779072833665) -->
+ <skip />
+ <!-- no translation found for RestrictedOnNormal (2045364908281990708) -->
+ <skip />
+ <!-- no translation found for RestrictedOnAll (4923139582141626159) -->
+ <skip />
+ <string name="serviceClassVoice">"Voz"</string>
+ <string name="serviceClassData">"Dados"</string>
+ <string name="serviceClassFAX">"FAX"</string>
+ <string name="serviceClassSMS">"SMS"</string>
+ <string name="serviceClassDataAsync">"Assíncrono"</string>
+ <string name="serviceClassDataSync">"Sincronizar"</string>
+ <string name="serviceClassPacket">"Pacote"</string>
+ <string name="serviceClassPAD">"PAD"</string>
+ <!-- no translation found for roamingText0 (7170335472198694945) -->
+ <skip />
+ <!-- no translation found for roamingText1 (5314861519752538922) -->
+ <skip />
+ <!-- no translation found for roamingText2 (8969929049081268115) -->
+ <skip />
+ <!-- no translation found for roamingText3 (5148255027043943317) -->
+ <skip />
+ <!-- no translation found for roamingText4 (8808456682550796530) -->
+ <skip />
+ <!-- no translation found for roamingText5 (7604063252850354350) -->
+ <skip />
+ <!-- no translation found for roamingText6 (2059440825782871513) -->
+ <skip />
+ <!-- no translation found for roamingText7 (7112078724097233605) -->
+ <skip />
+ <!-- no translation found for roamingText8 (5989569778604089291) -->
+ <skip />
+ <!-- no translation found for roamingText9 (7969296811355152491) -->
+ <skip />
+ <!-- no translation found for roamingText10 (3992906999815316417) -->
+ <skip />
+ <!-- no translation found for roamingText11 (4154476854426920970) -->
+ <skip />
+ <!-- no translation found for roamingText12 (1189071119992726320) -->
+ <skip />
+ <!-- no translation found for roamingTextSearching (8360141885972279963) -->
+ <skip />
+ <string name="cfTemplateNotForwarded">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Não transferido"</string>
+ <string name="cfTemplateForwarded">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
+ <string name="cfTemplateForwardedTime">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g> após <xliff:g id="TIME_DELAY">{2}</xliff:g> segundos"</string>
+ <string name="cfTemplateRegistered">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Não transferido"</string>
+ <string name="cfTemplateRegisteredTime">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: Não transferido"</string>
+ <!-- no translation found for fcComplete (3118848230966886575) -->
+ <skip />
+ <!-- no translation found for fcError (3327560126588500777) -->
+ <skip />
+ <string name="httpErrorOk">"OK"</string>
+ <string name="httpError">"A página da web contém um erro."</string>
+ <string name="httpErrorLookup">"Não foi possível encontrar o URL."</string>
+ <string name="httpErrorUnsupportedAuthScheme">"O esquema de autenticação não é suportado."</string>
+ <string name="httpErrorAuth">"Falha na autenticação."</string>
+ <string name="httpErrorProxyAuth">"Falha na autenticação pelo servidor proxy."</string>
+ <string name="httpErrorConnect">"Falha na conexão com o servidor."</string>
+ <string name="httpErrorIO">"Falha de comunicação com o servidor. Tente novamente mais tarde."</string>
+ <string name="httpErrorTimeout">"Tempo limite da conexão com o servidor esgotado."</string>
+ <string name="httpErrorRedirectLoop">"A página contém muitos redirecionamentos do servidor."</string>
+ <string name="httpErrorUnsupportedScheme">"O protocolo não é suportado."</string>
+ <string name="httpErrorFailedSslHandshake">"Não foi possível estabelecer uma conexão segura."</string>
+ <string name="httpErrorBadUrl">"A página não pode ser aberta, pois o URL é inválido."</string>
+ <string name="httpErrorFile">"Não foi possível acessar o arquivo."</string>
+ <string name="httpErrorFileNotFound">"O arquivo solicitado não foi encontrado."</string>
+ <string name="httpErrorTooManyRequests">"Muitas solicitações sendo processadas. Tente novamente mais tarde."</string>
+ <string name="contentServiceSync">"Sincronizar"</string>
+ <string name="contentServiceSyncNotificationTitle">"Sincronizar"</string>
+ <string name="contentServiceTooManyDeletesNotificationDesc">"Muitas exclusões do <xliff:g id="CONTENT_TYPE">%s</xliff:g>."</string>
+ <string name="low_memory">"O armazenamento do telefone está cheio! Exclua alguns arquivos para liberar espaço."</string>
+ <string name="me">"Eu"</string>
+ <string name="power_dialog">"Opções do telefone"</string>
+ <string name="silent_mode">"Modo silencioso"</string>
+ <string name="turn_on_radio">"Ativar rede sem fio"</string>
+ <string name="turn_off_radio">"Desativar a rede sem fio"</string>
+ <string name="screen_lock">"Bloqueio de tela"</string>
+ <string name="power_off">"Desligar"</string>
+ <string name="shutdown_progress">"Desligando…"</string>
+ <string name="shutdown_confirm">"Seu telefone desligará"</string>
+ <string name="no_recent_tasks">"Nenhum aplicativo recente."</string>
+ <string name="global_actions">"Opções do telefone"</string>
+ <string name="global_action_lock">"Bloqueio de tela"</string>
+ <string name="global_action_power_off">"Desligar"</string>
+ <string name="global_action_toggle_silent_mode">"Modo silencioso"</string>
+ <string name="global_action_silent_mode_on_status">"O som está DESLIGADO"</string>
+ <string name="global_action_silent_mode_off_status">"O som está ATIVADO"</string>
+ <!-- no translation found for global_actions_toggle_airplane_mode (5884330306926307456) -->
+ <skip />
+ <!-- no translation found for global_actions_airplane_mode_on_status (2719557982608919750) -->
+ <skip />
+ <!-- no translation found for global_actions_airplane_mode_off_status (5075070442854490296) -->
+ <skip />
+ <string name="safeMode">"Modo de segurança"</string>
+ <!-- no translation found for android_system_label (6577375335728551336) -->
+ <skip />
+ <string name="permgrouplab_costMoney">"Serviços que custam dinheiro"</string>
+ <string name="permgroupdesc_costMoney">"Permite que os aplicativos façam coisas que podem custar dinheiro."</string>
+ <string name="permgrouplab_messages">"Suas mensagens"</string>
+ <string name="permgroupdesc_messages">"Ler e gravar suas mensagens SMS, e-mail e outras mensagens."</string>
+ <string name="permgrouplab_personalInfo">"Suas informações pessoais"</string>
+ <string name="permgroupdesc_personalInfo">"Acesso direto aos seus contatos e calendário armazenados no telefone."</string>
+ <string name="permgrouplab_location">"Sua localização"</string>
+ <string name="permgroupdesc_location">"Monitore seu local físico"</string>
+ <string name="permgrouplab_network">"Comunicação de rede"</string>
+ <string name="permgroupdesc_network">"Permite que os aplicativos acessem diversos recursos de rede."</string>
+ <string name="permgrouplab_accounts">"Suas contas do Google"</string>
+ <string name="permgroupdesc_accounts">"Acesse as contas do Google disponíveis."</string>
+ <string name="permgrouplab_hardwareControls">"Controles de hardware"</string>
+ <string name="permgroupdesc_hardwareControls">"Acesso direto ao hardware no handset."</string>
+ <string name="permgrouplab_phoneCalls">"Chamadas telefônicas"</string>
+ <string name="permgroupdesc_phoneCalls">"Monitorar, registrar e processar chamadas telefônicas."</string>
+ <string name="permgrouplab_systemTools">"Ferramentas do sistema"</string>
+ <string name="permgroupdesc_systemTools">"Acesso de nível inferior e controle do sistema."</string>
+ <string name="permgrouplab_developmentTools">"Ferramentas de desenvolvimento"</string>
+ <string name="permgroupdesc_developmentTools">"Recursos necessários apenas aos desenvolvedores de aplicativo."</string>
+ <!-- no translation found for permgrouplab_storage (1971118770546336966) -->
+ <skip />
+ <!-- no translation found for permgroupdesc_storage (9203302214915355774) -->
+ <skip />
+ <string name="permlab_statusBar">"desativar ou modificar a barra de status"</string>
+ <string name="permdesc_statusBar">"Permite que os aplicativos desativem a barra de status ou adicionem e removam ícones do sistema."</string>
+ <string name="permlab_expandStatusBar">"expandir/recolher barra de status"</string>
+ <string name="permdesc_expandStatusBar">"Permite que um aplicativo expanda ou recolha a barra de status."</string>
+ <string name="permlab_processOutgoingCalls">"Interceptar chamadas realizadas"</string>
+ <string name="permdesc_processOutgoingCalls">"Permite que aplicativos processem chamadas realizadas e alterem o número a ser discado. Aplicativos maliciosos podem monitorar, redirecionar ou impedir chamadas realizadas."</string>
+ <string name="permlab_receiveSms">"receber SMS"</string>
+ <string name="permdesc_receiveSms">"Permite que o aplicativo receba e processe mensagens SMS. Aplicativos maliciosos podem monitorar suas mensagens ou excluí-las sem mostrá-las a você."</string>
+ <string name="permlab_receiveMms">"receber MMS"</string>
+ <string name="permdesc_receiveMms">"Permite que o aplicativo receba e processe mensagens MMS. Aplicativos maliciosos podem monitorar suas mensagens ou excluí-las sem mostrá-las a você."</string>
+ <string name="permlab_sendSms">"enviar mensagens SMS"</string>
+ <string name="permdesc_sendSms">"Permite que os aplicativos enviem mensagens SMS. Os aplicativos maliciosos podem causar prejuízo financeiro a você ao enviar mensagens sem a sua confirmação."</string>
+ <string name="permlab_readSms">"ler SMS ou MMS"</string>
+ <string name="permdesc_readSms">"Permite que um aplicativo leia mensagens SMS armazenadas no seu telefone ou cartão SIM. Aplicativos maliciosos podem ler suas mensagens confidenciais."</string>
+ <string name="permlab_writeSms">"editar SMS ou MMS"</string>
+ <string name="permdesc_writeSms">"Permite que um aplicativo grave mensagens SMS armazenadas no seu telefone ou cartão SIM. Aplicativos maliciosos podem excluir suas mensagens."</string>
+ <string name="permlab_receiveWapPush">"receber WAP"</string>
+ <string name="permdesc_receiveWapPush">"Permite que o aplicativo receba e processe mensagens WAP. Aplicativos maliciosos podem monitorar suas mensagens ou excluí-las sem mostrá-las a você."</string>
+ <string name="permlab_getTasks">"recuperar aplicativos em execução"</string>
+ <string name="permdesc_getTasks">"Permite que os aplicativos recuperem informações sobre as tarefas em execução no momento ou recentemente. Pode permitir que aplicativos maliciosos descubram informações particulares sobre outros aplicativos."</string>
+ <string name="permlab_reorderTasks">"reorganizar os aplicativos em execução"</string>
+ <string name="permdesc_reorderTasks">"Permite que um aplicativo mova as tarefas para o primeiro ou segundo plano. Os aplicativos maliciosos podem forçar sua permanência no primeiro plano sem o seu controle."</string>
+ <string name="permlab_setDebugApp">"ativar depuração do aplicativo"</string>
+ <string name="permdesc_setDebugApp">"Permite que um aplicativo ative a depuração de outro aplicativo. Aplicativos maliciosos podem usar isso para encerrar outros aplicativos."</string>
+ <string name="permlab_changeConfiguration">"alterar as configurações da sua IU"</string>
+ <string name="permdesc_changeConfiguration">"Permite que um aplicativo mude a configuração atual, como a localidade ou o tamanho geral de fonte."</string>
+ <string name="permlab_restartPackages">"reiniciar outros aplicativos"</string>
+ <string name="permdesc_restartPackages">"Permite que um aplicativo reinicie outros aplicativos forçosamente."</string>
+ <string name="permlab_setProcessForeground">"impedir a interrupção"</string>
+ <string name="permdesc_setProcessForeground">"Permite que um aplicativo faça qualquer processo executar em primeiro plano, não podendo ser encerrado. Normalmente não é necessário para aplicativos normais."</string>
+ <string name="permlab_forceBack">"forçar fechamento do aplicativo"</string>
+ <string name="permdesc_forceBack">"Permite que um aplicativo force qualquer atividade que esteja em primeiro plano a fechar e voltar. Normalmente não é necessário para aplicativos normais."</string>
+ <string name="permlab_dump">"recuperar estado interno do sistema"</string>
+ <string name="permdesc_dump">"Permite que um aplicativo recupere o estado interno do sistema. Aplicativos maliciosos podem recuperar um ampla variedade de informações privadas e seguras, as quais não deveriam precisar normalmente."</string>
+ <string name="permlab_addSystemService">"publicar serviços de nível inferior"</string>
+ <string name="permdesc_addSystemService">"Permite que o aplicativo publique seus próprios serviços do sistema de nível inferior. Aplicativos maliciosos podem seqüestrar o sistema e roubar ou corromper quaisquer dados contidos nele."</string>
+ <!-- no translation found for permlab_shutdown (7185747824038909016) -->
+ <skip />
+ <!-- no translation found for permdesc_shutdown (7046500838746291775) -->
+ <skip />
+ <!-- no translation found for permlab_stopAppSwitches (4138608610717425573) -->
+ <skip />
+ <!-- no translation found for permdesc_stopAppSwitches (3857886086919033794) -->
+ <skip />
+ <string name="permlab_runSetActivityWatcher">"monitorar e controle toda inicialização de aplicativo"</string>
+ <string name="permdesc_runSetActivityWatcher">"Permite que um aplicativo monitore e controle como o sistema inicia as atividades. Os aplicativos maliciosos podem comprometer completamente o sistema. Esta permissão é necessária apenas para desenvolvimento, nunca para uso normal do telefone."</string>
+ <string name="permlab_broadcastPackageRemoved">"enviar transmissão de pacote removido"</string>
+ <string name="permdesc_broadcastPackageRemoved">"Permite que um aplicativo transmita uma notificação de que o pacote de um aplicativo foi removido. Aplicativos maliciosos podem usar isso para encerrar outro aplicativo em execução."</string>
+ <string name="permlab_broadcastSmsReceived">"enviar transmissão de SMS recebido"</string>
+ <string name="permdesc_broadcastSmsReceived">"Permite que um aplicativo transmita uma notificação de que uma mensagem SMS foi recebida. Aplicativos maliciosos podem usar isso para forjar o recebimento de mensagens SMS."</string>
+ <string name="permlab_broadcastWapPush">"enviar transmissão de WAP-PUSH recebido"</string>
+ <string name="permdesc_broadcastWapPush">"Permite que um aplicativo transmita uma notificação de que uma mensagem WAP PUSH foi recebida. Aplicativos maliciosos podem usar isso para forjar o recebimento de uma mensagem MMS ou substituir silenciosamente o conteúdo de qualquer página da web por variantes maliciosas."</string>
+ <string name="permlab_setProcessLimit">"limitar o número de processos em execução"</string>
+ <string name="permdesc_setProcessLimit">"Permite que um aplicativo controle o número máximo de processos que serão executados. Nunca é necessário para aplicativos normais."</string>
+ <string name="permlab_setAlwaysFinish">"fazer todos os aplicativos em segundo plano fechar"</string>
+ <string name="permdesc_setAlwaysFinish">"Permite que um aplicativo controle se as atividades são sempre concluídas assim que vão para o segundo plano. Nunca é necessário para aplicativos normais."</string>
+ <string name="permlab_fotaUpdate">"instalar automaticamente atualizações do sistema"</string>
+ <string name="permdesc_fotaUpdate">"Permite que um aplicativo receba notificações sobre atualizações pendentes do sistema e dispare suas instalações. Aplicativos maliciosos podem usar isso para corromper o sistema com atualizações não autorizadas ou normalmente interferem com o processo de atualização."</string>
+ <string name="permlab_batteryStats">"Modificar as estatísticas da bateria"</string>
+ <string name="permdesc_batteryStats">"Permite a modificação das estatísticas coletadas sobre a bateria. Não deve ser usado em aplicativos normais."</string>
+ <!-- no translation found for permlab_backup (470013022865453920) -->
+ <skip />
+ <!-- no translation found for permdesc_backup (2305432853944929371) -->
+ <skip />
+ <string name="permlab_internalSystemWindow">"exibir janelas não autorizadas"</string>
+ <string name="permdesc_internalSystemWindow">"Permite a criação de janelas que devem ser usadas pela interface de usuário do sistema interno. Normalmente não é necessário para aplicativos normais."</string>
+ <string name="permlab_systemAlertWindow">"exibir alertas do nível do sistema"</string>
+ <string name="permdesc_systemAlertWindow">"Permite que um aplicativo mostre janelas de alerta do sistema. Aplicativos maliciosos podem assumir o controle de toda a tela do telefone."</string>
+ <string name="permlab_setAnimationScale">"modificar a velocidade de animação global"</string>
+ <string name="permdesc_setAnimationScale">"Permite que um aplicativo altere a velocidade de animação global (animações mais rápidas ou mais lentas) a qualquer momento."</string>
+ <string name="permlab_manageAppTokens">"gerenciar os símbolos do aplicativo"</string>
+ <string name="permdesc_manageAppTokens">"Permite que um aplicativo crie e gerencie seus próprio símbolos, ignorando a ordem-Z (Z-ordering). Normalmente não é necessário para aplicativos normais."</string>
+ <string name="permlab_injectEvents">"pressionar as teclas e os botões de controle"</string>
+ <string name="permdesc_injectEvents">"Permite que um aplicativo proporcione seus próprios eventos de entrada (pressionamentos de tecla etc.) a outros aplicativos. Aplicativos maliciosos podem usar isso para assumir o controle do telefone."</string>
+ <string name="permlab_readInputState">"registrar o que você digita e as ações que executa"</string>
+ <string name="permdesc_readInputState">"Permite que os aplicativos observem as teclas que você pressiona ao interagir com outro aplicativo (como ao digitar uma senha). Normalmente não é necessário para aplicativos normais."</string>
+ <string name="permlab_bindInputMethod">"aderir a um método de entrada"</string>
+ <string name="permdesc_bindInputMethod">"Permite que o portador se vincule à interface de nível superior de um método de entrada. Normalmente não é necessário em aplicativos normais."</string>
+ <string name="permlab_setOrientation">"alterar orientação da tela"</string>
+ <string name="permdesc_setOrientation">"Permite que um aplicativo altere a rotação da tela a qualquer momento. Normalmente não é necessário para aplicativos normais."</string>
+ <string name="permlab_signalPersistentProcesses">"enviar sinais de Linux aos aplicativos"</string>
+ <string name="permdesc_signalPersistentProcesses">"Permite que o aplicativo solicite que o sinal fornecido seja enviado a todos os processos persistentes."</string>
+ <string name="permlab_persistentActivity">"fazer com que o aplicativo execute sempre"</string>
+ <string name="permdesc_persistentActivity">"Permite que um aplicativo torne partes dele mesmo persistentes, para que o sistema não possa usá-lo para outros aplicativos."</string>
+ <string name="permlab_deletePackages">"excluir aplicativos"</string>
+ <string name="permdesc_deletePackages">"Permite que um aplicativo exclua pacotes do Android. Aplicativos maliciosos podem usar isso para excluir aplicativos importantes."</string>
+ <string name="permlab_clearAppUserData">"excluir os dados de outros aplicativos"</string>
+ <string name="permdesc_clearAppUserData">"Permite que um aplicativo limpe os dados do usuário."</string>
+ <string name="permlab_deleteCacheFiles">"excluir o cache de outros aplicativos"</string>
+ <string name="permdesc_deleteCacheFiles">"Permite que um aplicativo exclua arquivos armazenados em cache."</string>
+ <string name="permlab_getPackageSize">"medir o espaço de armazenamento do aplicativo"</string>
+ <string name="permdesc_getPackageSize">"Permite que um aplicativo recupere seu código, dados e tamanho de cache"</string>
+ <string name="permlab_installPackages">"instalar os aplicativos diretamente"</string>
+ <string name="permdesc_installPackages">"Permite que um aplicativo instale pacotes novos ou atualizados do Android. Aplicativos maliciosos podem usar isso para adicionar novos aplicativos com permissões aleatórias avançadas."</string>
+ <string name="permlab_clearAppCache">"excluir todos os dados do cache do aplicativo"</string>
+ <string name="permdesc_clearAppCache">"Permite que um aplicativo libere espaço de armazenamento do telefone excluindo arquivos no diretório de cache do aplicativo. O acesso é normalmente restrito ao processo do sistema."</string>
+ <string name="permlab_readLogs">"ler arquivos do registro do sistema"</string>
+ <string name="permdesc_readLogs">"Permite que um aplicativo leia os diversos arquivos de registro do sistema. Isso permite que ele descubra informações gerais sobre o que você está fazendo com o telefone, mas esses arquivos não devem conter informações pessoais ou privadas."</string>
+ <string name="permlab_diagnostic">"ler/gravar em recursos que pertencem ao diagnóstico"</string>
+ <string name="permdesc_diagnostic">"Permite que um aplicativo leia e grave em qualquer recurso que pertença ao grupo diag; por exemplo, arquivos em /dev. Isso poderia afetar a estabilidade e a segurança do sistema. Por isso, SÓ deve ser usado para diagnósticos específicos do hardware pelo fabricante ou operador."</string>
+ <string name="permlab_changeComponentState">"ativar ou desativar componentes do aplicativo"</string>
+ <string name="permdesc_changeComponentState">"Permite que um aplicativo altere a ativação ou desativação de um componente de outro aplicativo. Aplicativos maliciosos podem usar isso para desativar recursos importantes do telefone. É preciso ter permissão e cuidado no uso, pois é possível deixar os componentes do aplicativo em um estado inutilizável, inconsistente ou instável."</string>
+ <string name="permlab_setPreferredApplications">"definir aplicativos preferidos"</string>
+ <string name="permdesc_setPreferredApplications">"Permite que um aplicativo modifique seus aplicativos preferidos. Isso pode permitir que aplicativos maliciosos alterem silenciosamente os aplicativos em execução, falsificando seus aplicativos existentes para coletar seus dados privados."</string>
+ <string name="permlab_writeSettings">"modificar configurações globais do sistema"</string>
+ <string name="permdesc_writeSettings">"Permite que um aplicativo modifique os dados da configuração do sistema. Aplicativos maliciosos podem corromper a configuração do sistema."</string>
+ <string name="permlab_writeSecureSettings">"modificar configurações de segurança do sistema"</string>
+ <string name="permdesc_writeSecureSettings">"Permite que um aplicativo modifique os dados das configurações de segurança dos sistemas. Não deve ser usado em aplicativos normais."</string>
+ <string name="permlab_writeGservices">"modificar o mapa de serviços do Google"</string>
+ <string name="permdesc_writeGservices">"Permite que um aplicativo modifique o mapa de serviços do Google. Não deve ser usado em aplicativos normais."</string>
+ <string name="permlab_receiveBootCompleted">"iniciar automaticamente na inicialização"</string>
+ <string name="permdesc_receiveBootCompleted">"Permite que um aplicativo se inicie assim que o sistema termina de inicializar. Isso pode causar uma demora na inicialização do telefone e faz com que todo o telefone fique mais lento pela execução contínua do aplicativo."</string>
+ <string name="permlab_broadcastSticky">"enviar transmissão complexa"</string>
+ <string name="permdesc_broadcastSticky">"Permite que um aplicativo envie transmissões persistentes, as quais permanecem após o término da transmissão. Aplicativos maliciosos podem tornar o telefone lento ou instável fazendo com que use muita memória."</string>
+ <string name="permlab_readContacts">"ler dados de contato"</string>
+ <string name="permdesc_readContacts">"Permite que um aplicativo leia todos os dados de contato (endereço) armazenados no telefone. Aplicativos maliciosos podem usar isso para enviar seus dados a outras pessoas."</string>
+ <string name="permlab_writeContacts">"gravar dados de contato"</string>
+ <string name="permdesc_writeContacts">"Permite que um aplicativo modifique os dados de contato (endereço) armazenados no telefone. Aplicativos maliciosos podem usar isso para apagar ou modificar seus dados de contato."</string>
+ <string name="permlab_writeOwnerData">"gravar dados do proprietário"</string>
+ <string name="permdesc_writeOwnerData">"Permite que um aplicativo modifique os dados do proprietário do telefone armazenados no seu telefone. Aplicativos maliciosos podem usar isso para apagar ou modificar os dados do proprietário."</string>
+ <string name="permlab_readOwnerData">"ler dados do proprietário"</string>
+ <string name="permdesc_readOwnerData">"Permite que um aplicativo leia os dados do proprietário do telefone armazenados no seu telefone. Aplicativos maliciosos podem usar isso para ler os dados do proprietário."</string>
+ <string name="permlab_readCalendar">"ler os dados do calendário"</string>
+ <string name="permdesc_readCalendar">"Permite que um aplicativo leia todos os eventos de calendário armazenados no seu telefone. Aplicativos maliciosos podem usar isso para enviar os eventos do seu calendário a outras pessoas."</string>
+ <string name="permlab_writeCalendar">"gravar dados do calendário"</string>
+ <string name="permdesc_writeCalendar">"Permite que um aplicativo modifique os eventos do calendário armazenados no seu telefone. Aplicativos maliciosos podem usar isso para apagar ou modificar seus dados de contato."</string>
+ <string name="permlab_accessMockLocation">"imitar fontes de localização para teste"</string>
+ <string name="permdesc_accessMockLocation">"Criar imitação de fontes de localização para teste. Os aplicativos maliciosos podem usar isso para sobrescrever o local e/ou status retornado pelas fontes de localização reais como GPS ou provedores de rede."</string>
+ <string name="permlab_accessLocationExtraCommands">"acessar comandos extra do provedor de localização"</string>
+ <string name="permdesc_accessLocationExtraCommands">"Acessar comandos extra de fornecedor de localização. Aplicativos maliciosos podem usar isso para interferir com a operação do GPS ou com outras fontes de localização."</string>
+ <!-- no translation found for permlab_installLocationProvider (6578101199825193873) -->
+ <skip />
+ <!-- no translation found for permdesc_installLocationProvider (5449175116732002106) -->
+ <skip />
+ <string name="permlab_accessFineLocation">"Localização precisa (GPS)"</string>
+ <string name="permdesc_accessFineLocation">"Acesse fontes de localização precisa como o sistema GPS (Global Positioning System) no telefone, quando estiver disponível. Aplicativos maliciosos podem usar isso para determinar onde você está e também pode consumir energia da bateria."</string>
+ <string name="permlab_accessCoarseLocation">"Local inadequado (com base na rede)"</string>
+ <string name="permdesc_accessCoarseLocation">"Acessar fontes de localização aproximada como o banco de dados de rede de celular para determinar a localização aproximada de um telefone, quando houver disponibilidade. Aplicativos maliciosos podem usar isso para determinar sua localização aproximada."</string>
+ <string name="permlab_accessSurfaceFlinger">"acessar SurfaceFlinger"</string>
+ <string name="permdesc_accessSurfaceFlinger">"Permite que o aplicativo use os recursos de nível inferior do SurfaceFlinger."</string>
+ <string name="permlab_readFrameBuffer">"ler buffer do quadro"</string>
+ <string name="permdesc_readFrameBuffer">"Permite que o aplicativo leia o conteúdo do buffer do quadro."</string>
+ <string name="permlab_modifyAudioSettings">"alterar as configurações do seu áudio"</string>
+ <string name="permdesc_modifyAudioSettings">"Permite que o aplicativo modifique as configurações de áudio globais como volume e roteamento."</string>
+ <string name="permlab_recordAudio">"gravar áudio"</string>
+ <string name="permdesc_recordAudio">"Permite que o aplicativo acesso o caminho do registro de áudio."</string>
+ <string name="permlab_camera">"tirar fotos"</string>
+ <string name="permdesc_camera">"Permite que o aplicativo tire fotos com a câmera. Isso permite que o aplicativo colete imagens exibidas pela câmera a qualquer momento."</string>
+ <string name="permlab_brick">"desativar permanentemente o telefone"</string>
+ <string name="permdesc_brick">"Permite que o aplicativo desative todo o telefone permanentemente. Isso é muito perigoso."</string>
+ <string name="permlab_reboot">"forçar reinicializarão do telefone"</string>
+ <string name="permdesc_reboot">"Permite que o aplicativo force a reinicialização do telefone."</string>
+ <string name="permlab_mount_unmount_filesystems">"montar e desmontar sistemas de arquivos"</string>
+ <string name="permdesc_mount_unmount_filesystems">"Permite que o aplicativo monte e desmonte sistemas de arquivos para armazenamento removível."</string>
+ <!-- no translation found for permlab_mount_format_filesystems (5523285143576718981) -->
+ <skip />
+ <!-- no translation found for permdesc_mount_format_filesystems (574060044906047386) -->
+ <skip />
+ <string name="permlab_vibrate">"controlar vibrador"</string>
+ <string name="permdesc_vibrate">"Permite que o aplicativo controle o vibrador."</string>
+ <string name="permlab_flashlight">"controlar lanterna"</string>
+ <string name="permdesc_flashlight">"Permite que o aplicativo controle a lanterna."</string>
+ <string name="permlab_hardware_test">"testar hardware"</string>
+ <string name="permdesc_hardware_test">"Permite que o aplicativo controle diversos periféricos para teste de hardware."</string>
+ <string name="permlab_callPhone">"chamar números de telefone diretamente"</string>
+ <string name="permdesc_callPhone">"Permite que o aplicativo chame números de telefone sem sua intervenção. Aplicativos maliciosos podem causar a aparição de chamadas inesperadas na conta do seu telefone. Observe que isso não permite que o aplicativo ligue para números de emergência."</string>
+ <string name="permlab_callPrivileged">"chamar quaisquer números de telefone diretamente"</string>
+ <string name="permdesc_callPrivileged">"Permite que o aplicativo chame qualquer número de telefone, incluindo números de emergência, sem sua intervenção. Aplicativos maliciosos podem fazer chamadas desnecessárias e ilegais para serviços de emergência."</string>
+ <string name="permlab_locationUpdates">"controlar notificações de atualização de localização"</string>
+ <string name="permdesc_locationUpdates">"Permite a ativação/desativação das notificações sobre atualização de localização pelo rádio. Não deve ser usado em aplicativos normais."</string>
+ <string name="permlab_checkinProperties">"acessar propriedades de verificação"</string>
+ <string name="permdesc_checkinProperties">"Permite acesso de leitura/gravação às propriedades enviadas pelo serviço de verificação. Não deve ser usado em aplicativos normais."</string>
+ <!-- no translation found for permlab_bindGadget (776905339015863471) -->
+ <skip />
+ <!-- no translation found for permdesc_bindGadget (2098697834497452046) -->
+ <skip />
+ <string name="permlab_modifyPhoneState">"modificar estado do telefone"</string>
+ <string name="permdesc_modifyPhoneState">"Permite que o aplicativo controle os recursos do telefone do dispositivo. Um aplicativo com essa permissão pode alternar entre redes, ligar e desligar o rádio e executar ações parecidas sem o notificar."</string>
+ <string name="permlab_readPhoneState">"ler estado do telefone"</string>
+ <string name="permdesc_readPhoneState">"Permite que o aplicativo acesse os recursos do telefone do aparelho. Um aplicativo com essa permissão pode determinar o número deste telefone, se uma chamada está ativa, o número com o qual está chamada está conectada e outras coisas semelhantes."</string>
+ <string name="permlab_wakeLock">"impedir que o telefone entre em repouso"</string>
+ <string name="permdesc_wakeLock">"Permite que um aplicativo impeça o telefone de entrar em repouso."</string>
+ <string name="permlab_devicePower">"ligar ou desligar o telefone"</string>
+ <string name="permdesc_devicePower">"Permite que o aplicativo ligue ou desligue o telefone."</string>
+ <string name="permlab_factoryTest">"executar no modo de teste de fábrica"</string>
+ <string name="permdesc_factoryTest">"Executar como um teste de fabricante de nível inferior, permitindo o acesso completo ao hardware do telefone. Disponível apenas quando um telefone está executando no modo de teste de fábrica."</string>
+ <string name="permlab_setWallpaper">"definir papel de parede"</string>
+ <string name="permdesc_setWallpaper">"Permite que o aplicativo defina o papel de parede do sistema."</string>
+ <string name="permlab_setWallpaperHints">"definir dicas de tamanho de papel de parede"</string>
+ <string name="permdesc_setWallpaperHints">"Permite que o aplicativo defina as dicas de tamanho do papel de parede do sistema."</string>
+ <string name="permlab_masterClear">"reiniciar o sistema com o padrão de fábrica"</string>
+ <string name="permdesc_masterClear">"Permite que um aplicativo reinicie completamente o sistema com suas configurações de fábrica, apagando todos os dados, configuração e aplicativos instalados."</string>
+ <string name="permlab_setTimeZone">"definir fuso horário"</string>
+ <string name="permdesc_setTimeZone">"Permite que um aplicativo altere o fuso horário do telefone."</string>
+ <string name="permlab_getAccounts">"descobrir contas conhecidas"</string>
+ <string name="permdesc_getAccounts">"Permite que um aplicativo obtenha a lista de contas conhecidas pelo telefone."</string>
+ <string name="permlab_accessNetworkState">"exibir estado da rede"</string>
+ <string name="permdesc_accessNetworkState">"Permite que um aplicativo exiba o estado de todas as redes."</string>
+ <string name="permlab_createNetworkSockets">"acesso total à Internet"</string>
+ <string name="permdesc_createNetworkSockets">"Permite que um aplicativo crie soquetes de rede."</string>
+ <string name="permlab_writeApnSettings">"gravar configurações de Nome do ponto de acesso"</string>
+ <string name="permdesc_writeApnSettings">"Permite que um aplicativo modifique as configurações de APN, como Proxy e a Porta de qualquer APN."</string>
+ <string name="permlab_changeNetworkState">"alterar conectividade da rede"</string>
+ <string name="permdesc_changeNetworkState">"Permite que um aplicativo mude o estado da conectividade da rede."</string>
+ <!-- no translation found for permlab_changeBackgroundDataSetting (1400666012671648741) -->
+ <skip />
+ <!-- no translation found for permdesc_changeBackgroundDataSetting (1001482853266638864) -->
+ <skip />
+ <string name="permlab_accessWifiState">"exibir estado da rede Wi-Fi"</string>
+ <string name="permdesc_accessWifiState">"Permite que um aplicativo exiba as informações sobre o estado da rede Wi-Fi."</string>
+ <string name="permlab_changeWifiState">"Alterar estado de Wi-Fi"</string>
+ <string name="permdesc_changeWifiState">"Permite que um aplicativo se conecte e desconecte dos pontos de acesso Wi-Fi e faça alterações nas redes Wi-Fi configuradas."</string>
+ <!-- no translation found for permlab_changeWifiMulticastState (1368253871483254784) -->
+ <skip />
+ <!-- no translation found for permdesc_changeWifiMulticastState (8199464507656067553) -->
+ <skip />
+ <string name="permlab_bluetoothAdmin">"administração do bluetooth"</string>
+ <string name="permdesc_bluetoothAdmin">"Permite que um aplicativo configure o telefone Bluetooth local, além de descobrir e parear com dispositivos remotos."</string>
+ <string name="permlab_bluetooth">"criar conexões Bluetooth"</string>
+ <string name="permdesc_bluetooth">"Permite que um aplicativo exiba a configuração do telefone Bluetooth local e faça e aceite conexões com os dispositivos pareados."</string>
+ <string name="permlab_disableKeyguard">"desativar bloqueio de teclado"</string>
+ <string name="permdesc_disableKeyguard">"Permite que um aplicativo desative o bloqueio do teclado e qualquer segurança de senha associada. Um exemplo legítimo disso é o telefone desativando o bloqueio do teclado ao receber uma chamada e reativando o bloqueio ao final da chamada."</string>
+ <string name="permlab_readSyncSettings">"ler configurações de sincronização"</string>
+ <string name="permdesc_readSyncSettings">"Permite que um aplicativo leia as configurações de sincronização, por exemplo se a sincronização está ativada para Contatos."</string>
+ <string name="permlab_writeSyncSettings">"gravar configurações de sincronização"</string>
+ <string name="permdesc_writeSyncSettings">"Permite que um aplicativo modifique as configurações de sincronização, por exemplo se a sincronização está ativada para Contatos."</string>
+ <string name="permlab_readSyncStats">"ler estatísticas de sincronização"</string>
+ <string name="permdesc_readSyncStats">"Permite que um aplicativo leia as estatísticas de sincronização; por exemplo, o histórico de sincronizações realizadas."</string>
+ <string name="permlab_subscribedFeedsRead">"ler feeds inscritos"</string>
+ <string name="permdesc_subscribedFeedsRead">"Permite que um aplicativo obtenha detalhes sobre os feeds sincronizados atualmente."</string>
+ <string name="permlab_subscribedFeedsWrite">"gravar feeds inscritos"</string>
+ <string name="permdesc_subscribedFeedsWrite">"Permite que um aplicativo modifique seus feeds sincronizados recentemente. Isso poderia permitir que um aplicativo malicioso alterasse seus feeds sincronizados."</string>
+ <!-- no translation found for permlab_readDictionary (432535716804748781) -->
+ <skip />
+ <!-- no translation found for permdesc_readDictionary (1082972603576360690) -->
+ <skip />
+ <!-- no translation found for permlab_writeDictionary (6703109511836343341) -->
+ <skip />
+ <!-- no translation found for permdesc_writeDictionary (2241256206524082880) -->
+ <skip />
+ <!-- no translation found for permlab_sdcardWrite (8079403759001777291) -->
+ <skip />
+ <!-- no translation found for permdesc_sdcardWrite (6643963204976471878) -->
+ <skip />
+ <string-array name="phoneTypes">
+ <item>"Página Inicial"</item>
+ <item>"Celular"</item>
+ <item>"Trabalho"</item>
+ <item>"Fax comercial"</item>
+ <item>"Fax doméstico"</item>
+ <item>"Pager"</item>
+ <item>"Outro"</item>
+ <item>"Personalizar"</item>
+ </string-array>
+ <string-array name="emailAddressTypes">
+ <item>"Página Inicial"</item>
+ <item>"Trabalho"</item>
+ <item>"Outro"</item>
+ <item>"Personalizar"</item>
+ </string-array>
+ <!-- no translation found for mobileEmailTypeName (2858957283716687707) -->
+ <skip />
+ <string-array name="postalAddressTypes">
+ <item>"Página Inicial"</item>
+ <item>"Trabalho"</item>
+ <item>"Outro"</item>
+ <item>"Personalizar"</item>
+ </string-array>
+ <string-array name="imAddressTypes">
+ <item>"Página Inicial"</item>
+ <item>"Trabalho"</item>
+ <item>"Outro"</item>
+ <item>"Personalizar"</item>
+ </string-array>
+ <string-array name="organizationTypes">
+ <item>"Trabalho"</item>
+ <item>"Outro"</item>
+ <item>"Personalizar"</item>
+ </string-array>
+ <string-array name="imProtocols">
+ <item>"AIM"</item>
+ <item>"Windows Live"</item>
+ <item>"Yahoo"</item>
+ <item>"Skype"</item>
+ <item>"QQ"</item>
+ <item>"Google Talk"</item>
+ <item>"ICQ"</item>
+ <item>"Jabber"</item>
+ </string-array>
+ <string name="keyguard_password_enter_pin_code">"Digite o código PIN"</string>
+ <string name="keyguard_password_wrong_pin_code">"Código PIN incorreto!"</string>
+ <string name="keyguard_label_text">"Para desbloquear, pressione Menu e 0."</string>
+ <string name="emergency_call_dialog_number_for_display">"Número de emergência"</string>
+ <string name="lockscreen_carrier_default">"(Sem serviço)"</string>
+ <string name="lockscreen_screen_locked">"Tela bloqueada."</string>
+ <string name="lockscreen_instructions_when_pattern_enabled">"Pressione Menu para desbloquear ou fazer chamada de emergência."</string>
+ <string name="lockscreen_instructions_when_pattern_disabled">"Pressione Menu para desbloquear."</string>
+ <string name="lockscreen_pattern_instructions">"Desenhar padrão para desbloqueio"</string>
+ <string name="lockscreen_emergency_call">"Chamada de emergência"</string>
+ <string name="lockscreen_pattern_correct">"Correto!"</string>
+ <string name="lockscreen_pattern_wrong">"Sentimos muito, tente novamente"</string>
+ <!-- no translation found for lockscreen_plugged_in (613343852842944435) -->
+ <skip />
+ <string name="lockscreen_low_battery">"Conecte o carregador."</string>
+ <string name="lockscreen_missing_sim_message_short">"Sem cartão SIM."</string>
+ <string name="lockscreen_missing_sim_message">"Não há um cartão SIM no telefone."</string>
+ <string name="lockscreen_missing_sim_instructions">"Insira um cartão SIM."</string>
+ <string name="lockscreen_network_locked_message">"Rede bloqueada"</string>
+ <string name="lockscreen_sim_puk_locked_message">"O cartão SIM está bloqueado pelo PUK."</string>
+ <!-- no translation found for lockscreen_sim_puk_locked_instructions (635967534992394321) -->
+ <skip />
+ <string name="lockscreen_sim_locked_message">"O cartão SIM está bloqueado."</string>
+ <string name="lockscreen_sim_unlock_progress_dialog_message">"Desbloqueando cartão SIM…"</string>
+ <string name="lockscreen_too_many_failed_attempts_dialog_message">"Você desenhou incorretamente seu padrão de desbloqueio <xliff:g id="NUMBER_0">%d</xliff:g> vezes. "\n\n"Tente novamente em <xliff:g id="NUMBER_1">%d</xliff:g> segundos."</string>
+ <string name="lockscreen_failed_attempts_almost_glogin">"Você desenhou seu padrão de desbloqueio incorretamente <xliff:g id="NUMBER_0">%d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%d</xliff:g> tentativas sem êxito, você receberá uma solicitação para desbloquear o telefone usando seu login do Google."\n\n" Tente novamente em <xliff:g id="NUMBER_2">%d</xliff:g> segundos."</string>
+ <string name="lockscreen_too_many_failed_attempts_countdown">"Tentar novamente em <xliff:g id="NUMBER">%d</xliff:g> segundos."</string>
+ <string name="lockscreen_forgot_pattern_button_text">"Esqueceu o padrão?"</string>
+ <string name="lockscreen_glogin_too_many_attempts">"Muitas tentativas de padrão!"</string>
+ <!-- no translation found for lockscreen_glogin_instructions (1816635201812207709) -->
+ <skip />
+ <string name="lockscreen_glogin_username_hint">"Nome de usuário (e-mail)"</string>
+ <string name="lockscreen_glogin_password_hint">"Senha"</string>
+ <string name="lockscreen_glogin_submit_button">"Fazer login"</string>
+ <string name="lockscreen_glogin_invalid_input">"Nome de usuário ou senha inválida."</string>
+ <!-- no translation found for hour_ampm (4329881288269772723) -->
+ <skip />
+ <!-- no translation found for hour_cap_ampm (1829009197680861107) -->
+ <skip />
+ <string name="status_bar_clear_all_button">"Limpar notificações"</string>
+ <string name="status_bar_no_notifications_title">"Sem modificações"</string>
+ <string name="status_bar_ongoing_events_title">"Em andamento"</string>
+ <string name="status_bar_latest_events_title">"Notificações"</string>
+ <!-- no translation found for battery_status_text_percent_format (7660311274698797147) -->
+ <skip />
+ <string name="battery_status_charging">"Carregando..."</string>
+ <string name="battery_low_title">"Conecte o carregador"</string>
+ <string name="battery_low_subtitle">"A carga da bateria está ficando baixa:"</string>
+ <string name="battery_low_percent_format">"menos de <xliff:g id="NUMBER">%d%%</xliff:g> restantes."</string>
+ <string name="factorytest_failed">"Falha no teste de fábrica"</string>
+ <string name="factorytest_not_system">"A ação FACTORY_TEST é suportada apenas para pacotes instalados em /system/app."</string>
+ <string name="factorytest_no_action">"Nenhum pacote foi encontrado que forneça a ação FACTORY_TEST."</string>
+ <string name="factorytest_reboot">"Reiniciar"</string>
+ <!-- no translation found for js_dialog_title (8143918455087008109) -->
+ <skip />
+ <!-- no translation found for js_dialog_title_default (6961903213729667573) -->
+ <skip />
+ <!-- no translation found for js_dialog_before_unload (1901675448179653089) -->
+ <skip />
+ <string name="save_password_label">"Confirmar"</string>
+ <string name="save_password_message">"Deseja que o navegador se lembre desta senha?"</string>
+ <string name="save_password_notnow">"Não agora"</string>
+ <string name="save_password_remember">"Lembre-se"</string>
+ <string name="save_password_never">"Nunca"</string>
+ <string name="open_permission_deny">"Você não tem permissão para abrir essa página."</string>
+ <string name="text_copied">"Texto copiado para a área de transferência."</string>
+ <string name="more_item_label">"Mais"</string>
+ <string name="prepend_shortcut_label">"Menu+"</string>
+ <string name="menu_space_shortcut_label">"espaço"</string>
+ <string name="menu_enter_shortcut_label">"enter"</string>
+ <string name="menu_delete_shortcut_label">"excluir"</string>
+ <string name="search_go">"Procurar"</string>
+ <string name="oneMonthDurationPast">"1 mês atrás"</string>
+ <string name="beforeOneMonthDurationPast">"Antes de 1 mês atrás"</string>
+ <plurals name="num_seconds_ago">
+ <item quantity="one">"1 segundo atrás"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> segundos atrás"</item>
+ </plurals>
+ <plurals name="num_minutes_ago">
+ <item quantity="one">"1 minute atrás"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> minutos atrás"</item>
+ </plurals>
+ <plurals name="num_hours_ago">
+ <item quantity="one">"1 hora trás"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> horas atrás"</item>
+ </plurals>
+ <plurals name="num_days_ago">
+ <item quantity="one">"ontem"</item>
+ <item quantity="other">"<xliff:g id="COUNT">%d</xliff:g> dias atrás"</item>
+ </plurals>
+ <plurals name="in_num_seconds">
+ <item quantity="one">"em 1 segundo"</item>
+ <item quantity="other">"em <xliff:g id="COUNT">%d</xliff:g> segundos"</item>
+ </plurals>
+ <plurals name="in_num_minutes">
+ <item quantity="one">"em 1 minuto"</item>
+ <item quantity="other">"em <xliff:g id="COUNT">%d</xliff:g> minutos"</item>
+ </plurals>
+ <plurals name="in_num_hours">
+ <item quantity="one">"em 1 hora"</item>
+ <item quantity="other">"em <xliff:g id="COUNT">%d</xliff:g> horas"</item>
+ </plurals>
+ <plurals name="in_num_days">
+ <item quantity="one">"amanhã"</item>
+ <item quantity="other">"em <xliff:g id="COUNT">%d</xliff:g> dias"</item>
+ </plurals>
+ <!-- no translation found for abbrev_num_seconds_ago:one (1849036840200069118) -->
+ <!-- no translation found for abbrev_num_seconds_ago:other (3699169366650930415) -->
+ <!-- no translation found for abbrev_num_minutes_ago:one (6361490147113871545) -->
+ <!-- no translation found for abbrev_num_minutes_ago:other (851164968597150710) -->
+ <!-- no translation found for abbrev_num_hours_ago:one (4796212039724722116) -->
+ <!-- no translation found for abbrev_num_hours_ago:other (6889970745748538901) -->
+ <!-- no translation found for abbrev_num_days_ago:one (8463161711492680309) -->
+ <!-- no translation found for abbrev_num_days_ago:other (3453342639616481191) -->
+ <!-- no translation found for abbrev_in_num_seconds:one (5842225370795066299) -->
+ <!-- no translation found for abbrev_in_num_seconds:other (5495880108825805108) -->
+ <!-- no translation found for abbrev_in_num_minutes:one (562786149928284878) -->
+ <!-- no translation found for abbrev_in_num_minutes:other (4216113292706568726) -->
+ <!-- no translation found for abbrev_in_num_hours:one (3274708118124045246) -->
+ <!-- no translation found for abbrev_in_num_hours:other (3705373766798013406) -->
+ <!-- no translation found for abbrev_in_num_days:one (2178576254385739855) -->
+ <!-- no translation found for abbrev_in_num_days:other (2973062968038355991) -->
+ <string name="preposition_for_date">"em %s"</string>
+ <string name="preposition_for_time">"a %s"</string>
+ <string name="preposition_for_year">"em %s"</string>
+ <string name="day">"dia"</string>
+ <string name="days">"dias"</string>
+ <string name="hour">"hora"</string>
+ <string name="hours">"horas"</string>
+ <string name="minute">"minuto"</string>
+ <string name="minutes">"minutos"</string>
+ <string name="second">"segundos"</string>
+ <string name="seconds">"segundos"</string>
+ <string name="week">"semana"</string>
+ <string name="weeks">"semanas"</string>
+ <string name="year">"ano"</string>
+ <string name="years">"anos"</string>
+ <string name="every_weekday">"Todo dia de semana (Seg–Sex)"</string>
+ <string name="daily">"Diariamente"</string>
+ <string name="weekly">"Semanalmente em <xliff:g id="DAY">%s</xliff:g>"</string>
+ <string name="monthly">"Mensalmente"</string>
+ <string name="yearly">"Anualmente"</string>
+ <string name="VideoView_error_title">"Não é possível reproduzir o vídeo"</string>
+ <!-- no translation found for VideoView_error_text_invalid_progressive_playback (897920883624437033) -->
+ <skip />
+ <string name="VideoView_error_text_unknown">"Sentimos muito, este vídeo não pode ser reproduzido."</string>
+ <string name="VideoView_error_button">"OK"</string>
+ <!-- no translation found for relative_time (1818557177829411417) -->
+ <skip />
+ <string name="noon">"meio-dia"</string>
+ <string name="Noon">"Meio-dia"</string>
+ <string name="midnight">"meia-noite"</string>
+ <string name="Midnight">"Meia-noite"</string>
+ <string name="elapsed_time_short_format_mm_ss">"<xliff:g id="MINUTES">%1$02d</xliff:g>:<xliff:g id="SECONDS">%2$02d</xliff:g>"</string>
+ <string name="elapsed_time_short_format_h_mm_ss">"<xliff:g id="HOURS">%1$d</xliff:g>:<xliff:g id="MINUTES">%2$02d</xliff:g>:<xliff:g id="SECONDS">%3$02d</xliff:g>"</string>
+ <string name="selectAll">"Selecionar tudo"</string>
+ <string name="selectText">"Selecionar texto"</string>
+ <string name="stopSelectingText">"Interromper seleção de texto"</string>
+ <string name="cut">"Recortar"</string>
+ <string name="cutAll">"Recortar tudo"</string>
+ <string name="copy">"Copiar"</string>
+ <string name="copyAll">"Copiar tudo"</string>
+ <string name="paste">"Colar"</string>
+ <string name="copyUrl">"Copiar URL"</string>
+ <string name="inputMethod">"Método de entrada"</string>
+ <!-- no translation found for addToDictionary (726256909274177272) -->
+ <skip />
+ <string name="editTextMenuTitle">"Editar texto"</string>
+ <string name="low_internal_storage_view_title">"Pouco espaço"</string>
+ <string name="low_internal_storage_view_text">"O espaço de armazenamento do telefone está diminuindo."</string>
+ <string name="ok">"OK"</string>
+ <string name="cancel">"Cancelar"</string>
+ <string name="yes">"OK"</string>
+ <string name="no">"Cancelar"</string>
+ <!-- no translation found for dialog_alert_title (2049658708609043103) -->
+ <skip />
+ <string name="capital_on">"LIGAR"</string>
+ <string name="capital_off">"DESLIGADO"</string>
+ <string name="whichApplication">"Completar ação usando"</string>
+ <string name="alwaysUse">"Use por padrão para esta ação."</string>
+ <string name="clearDefaultHintMsg">"Limpar o padrão nas Configurações da página inicial> Aplicativos > Gerenciar aplicativos."</string>
+ <string name="chooseActivity">"Selecione uma ação"</string>
+ <string name="noApplications">"Nenhum aplicativo pode executar essa ação."</string>
+ <string name="aerr_title">"Sentimos muito."</string>
+ <string name="aerr_application">"O aplicativo <xliff:g id="APPLICATION">%1$s</xliff:g>(processo <xliff:g id="PROCESS">%2$s</xliff:g>) parou inesperadamente. Tente novamente."</string>
+ <string name="aerr_process">"O processo <xliff:g id="PROCESS">%1$s</xliff:g> parou inesperadamente. Tente novamente."</string>
+ <string name="anr_title">"Sentimos muito."</string>
+ <string name="anr_activity_application">"A atividade <xliff:g id="ACTIVITY">%1$s</xliff:g> (no aplicativo <xliff:g id="APPLICATION">%2$s</xliff:g>) não está respondendo."</string>
+ <string name="anr_activity_process">"A atividade <xliff:g id="ACTIVITY">%1$s</xliff:g> (<xliff:g id="PROCESS">%2$s</xliff:g> em processamento) não está respondendo."</string>
+ <string name="anr_application_process">"O aplicativo <xliff:g id="APPLICATION">%1$s</xliff:g> (<xliff:g id="PROCESS">%2$s</xliff:g> em processamento) não está respondendo."</string>
+ <string name="anr_process">"O processo <xliff:g id="PROCESS">%1$s</xliff:g> não está respondendo."</string>
+ <string name="force_close">"Forçar fechamento"</string>
+ <!-- no translation found for report (4060218260984795706) -->
+ <skip />
+ <string name="wait">"Aguarde"</string>
+ <string name="debug">"Depuração"</string>
+ <string name="sendText">"Selecione uma ação para texto"</string>
+ <string name="volume_ringtone">"Volume da campainha"</string>
+ <string name="volume_music">"Volume da mídia"</string>
+ <string name="volume_music_hint_playing_through_bluetooth">"Reprodução usando Bluetooth"</string>
+ <string name="volume_call">"Volume da chamada recebida"</string>
+ <!-- no translation found for volume_bluetooth_call (2002891926351151534) -->
+ <skip />
+ <string name="volume_alarm">"Volume do alarme"</string>
+ <string name="volume_notification">"Volume da notificação"</string>
+ <string name="volume_unknown">"Volume"</string>
+ <string name="ringtone_default">"Ringtone padrão"</string>
+ <string name="ringtone_default_with_actual">"Ringtone padrão (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+ <string name="ringtone_silent">"Silencioso"</string>
+ <string name="ringtone_picker_title">"Ringtones"</string>
+ <string name="ringtone_unknown">"Ringtone desconhecido"</string>
+ <plurals name="wifi_available">
+ <item quantity="one">"Rede Wi-Fi disponível"</item>
+ <item quantity="other">"Redes Wi-Fi disponíveis"</item>
+ </plurals>
+ <plurals name="wifi_available_detailed">
+ <item quantity="one">"Redes Wi-Fi abertas disponíveis"</item>
+ <item quantity="other">"Redes Wi-Fi abertas disponíveis"</item>
+ </plurals>
+ <string name="select_character">"Inserir caractere"</string>
+ <string name="sms_control_default_app_name">"Aplicativo desconhecido"</string>
+ <string name="sms_control_title">"Envio de mensagens SMS"</string>
+ <string name="sms_control_message">"Uma grande quantidade de mensagens SMS está sendo enviada. Selecione \"OK\" para continuar ou \"Cancelar\" para parar de enviar."</string>
+ <string name="sms_control_yes">"OK"</string>
+ <string name="sms_control_no">"Cancelar"</string>
+ <string name="date_time_set">"Definir"</string>
+ <string name="default_permission_group">"Padrão"</string>
+ <string name="no_permissions">"Nenhuma permissão é necessária"</string>
+ <string name="perms_hide"><b>"Ocultar"</b></string>
+ <string name="perms_show_all"><b>"Mostrar tudo"</b></string>
+ <string name="googlewebcontenthelper_loading">"Carregando…"</string>
+ <string name="usb_storage_title">"Conectado via USB"</string>
+ <string name="usb_storage_message">"Você conectou o telefone ao seu computador via USB. Selecione \"Montar\" se quiser copiar os arquivos entre seu computador e o cartão SD do telefone."</string>
+ <string name="usb_storage_button_mount">"Montar"</string>
+ <string name="usb_storage_button_unmount">"Não montar"</string>
+ <string name="usb_storage_error_message">"Há um problema com o uso do seu cartão SD para armazenamento USB."</string>
+ <string name="usb_storage_notification_title">"Conectado via USB"</string>
+ <string name="usb_storage_notification_message">"Selecione para copiar os arquivos para/do computador."</string>
+ <!-- no translation found for usb_storage_stop_notification_title (2336058396663516017) -->
+ <skip />
+ <!-- no translation found for usb_storage_stop_notification_message (2591813490269841539) -->
+ <skip />
+ <!-- no translation found for usb_storage_stop_title (6014127947456185321) -->
+ <skip />
+ <!-- no translation found for usb_storage_stop_message (2390958966725232848) -->
+ <skip />
+ <!-- no translation found for usb_storage_stop_button_mount (1181858854166273345) -->
+ <skip />
+ <!-- no translation found for usb_storage_stop_button_unmount (3774611918660582898) -->
+ <skip />
+ <!-- no translation found for usb_storage_stop_error_message (3917317248440072084) -->
+ <skip />
+ <!-- no translation found for extmedia_format_title (8663247929551095854) -->
+ <skip />
+ <!-- no translation found for extmedia_format_message (3621369962433523619) -->
+ <skip />
+ <!-- no translation found for extmedia_format_button_format (4131064560127478695) -->
+ <skip />
+ <string name="select_input_method">"Selecionar método de entrada"</string>
+ <string name="fast_scroll_alphabet">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+ <string name="fast_scroll_numeric_alphabet">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
+ <!-- no translation found for candidates_style (4333913089637062257) -->
+ <skip />
+ <!-- no translation found for ext_media_checking_notification_title (5457603418970994050) -->
+ <skip />
+ <!-- no translation found for ext_media_checking_notification_message (4747432538578886744) -->
+ <skip />
+ <!-- no translation found for ext_media_nofs_notification_title (780477838241212997) -->
+ <skip />
+ <!-- no translation found for ext_media_nofs_notification_message (1312266820092958014) -->
+ <skip />
+ <!-- no translation found for ext_media_unmountable_notification_title (6410723906019100189) -->
+ <skip />
+ <!-- no translation found for ext_media_unmountable_notification_message (2679412884290061775) -->
+ <skip />
+ <!-- no translation found for ext_media_badremoval_notification_title (6872152882604407837) -->
+ <skip />
+ <!-- no translation found for ext_media_badremoval_notification_message (7260183293747448241) -->
+ <skip />
+ <!-- no translation found for ext_media_safe_unmount_notification_title (6729801130790616200) -->
+ <skip />
+ <!-- no translation found for ext_media_safe_unmount_notification_message (7613960686747592770) -->
+ <skip />
+ <!-- no translation found for ext_media_nomedia_notification_title (8902518030404381318) -->
+ <skip />
+ <!-- no translation found for ext_media_nomedia_notification_message (4205117227342822275) -->
+ <skip />
+ <!-- no translation found for activity_list_empty (4168820609403385789) -->
+ <skip />
+ <!-- no translation found for permlab_pkgUsageStats (8787352074326748892) -->
+ <skip />
+ <!-- no translation found for permdesc_pkgUsageStats (891553695716752835) -->
+ <skip />
+ <!-- no translation found for tutorial_double_tap_to_zoom_message_short (1311810005957319690) -->
+ <skip />
+ <!-- no translation found for gadget_host_error_inflating (2613287218853846830) -->
+ <skip />
+ <!-- no translation found for ime_action_go (8320845651737369027) -->
+ <skip />
+ <!-- no translation found for ime_action_search (658110271822807811) -->
+ <skip />
+ <!-- no translation found for ime_action_send (2316166556349314424) -->
+ <skip />
+ <!-- no translation found for ime_action_next (3138843904009813834) -->
+ <skip />
+ <!-- no translation found for ime_action_done (8971516117910934605) -->
+ <skip />
+ <!-- no translation found for ime_action_default (2840921885558045721) -->
+ <skip />
+ <!-- no translation found for dial_number_using (5789176425167573586) -->
+ <skip />
+ <!-- no translation found for create_contact_using (4947405226788104538) -->
+ <skip />
+ <!-- no translation found for accessibility_compound_button_selected (5612776946036285686) -->
+ <skip />
+ <!-- no translation found for accessibility_compound_button_unselected (8864512895673924091) -->
+ <skip />
+</resources>
diff --git a/core/res/res/values-ro-rRO/donottranslate-cldr.xml b/core/res/res/values-ro-rRO/donottranslate-cldr.xml
index 10fc10e..1b3438f 100644
--- a/core/res/res/values-ro-rRO/donottranslate-cldr.xml
+++ b/core/res/res/values-ro-rRO/donottranslate-cldr.xml
@@ -91,8 +91,9 @@
<string name="today">azi</string>
<string name="tomorrow">mâine</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
<string name="numeric_date">%d.%m.%Y</string>
<string name="numeric_date_format">dd.MM.yyyy</string>
<string name="month_day_year">%-e %B %Y</string>
diff --git a/core/res/res/values-ru-rRU/donottranslate-cldr.xml b/core/res/res/values-ru-rRU/donottranslate-cldr.xml
index c5b22b6..9197d12 100644
--- a/core/res/res/values-ru-rRU/donottranslate-cldr.xml
+++ b/core/res/res/values-ru-rRU/donottranslate-cldr.xml
@@ -91,8 +91,9 @@
<string name="today">Сегодня</string>
<string name="tomorrow">Завтра</string>
- <string name="hour_minute_ampm">%-k:%M</string>
- <string name="hour_minute_cap_ampm">%-k:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
<string name="numeric_date">%d.%m.%Y</string>
<string name="numeric_date_format">dd.MM.yyyy</string>
<string name="month_day_year">%-e %B %Y г.</string>
diff --git a/core/res/res/values-ru/donottranslate-cldr.xml b/core/res/res/values-ru/donottranslate-cldr.xml
index c5b22b6..9197d12 100644
--- a/core/res/res/values-ru/donottranslate-cldr.xml
+++ b/core/res/res/values-ru/donottranslate-cldr.xml
@@ -91,8 +91,9 @@
<string name="today">Сегодня</string>
<string name="tomorrow">Завтра</string>
- <string name="hour_minute_ampm">%-k:%M</string>
- <string name="hour_minute_cap_ampm">%-k:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
<string name="numeric_date">%d.%m.%Y</string>
<string name="numeric_date_format">dd.MM.yyyy</string>
<string name="month_day_year">%-e %B %Y г.</string>
diff --git a/core/res/res/values-sk-rSK/donottranslate-cldr.xml b/core/res/res/values-sk-rSK/donottranslate-cldr.xml
index 75352f7..5ebb0b2 100644
--- a/core/res/res/values-sk-rSK/donottranslate-cldr.xml
+++ b/core/res/res/values-sk-rSK/donottranslate-cldr.xml
@@ -91,8 +91,9 @@
<string name="today">Dnes</string>
<string name="tomorrow">Zajtra</string>
- <string name="hour_minute_ampm">%-k:%M</string>
- <string name="hour_minute_cap_ampm">%-k:%M</string>
+ <string name="hour_minute_24">%H:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %p</string>
<string name="numeric_date">%-e.%-m.%Y</string>
<string name="numeric_date_format">d.M.yyyy</string>
<string name="month_day_year">%-e. %B %Y</string>
diff --git a/core/res/res/values-sl-rSI/donottranslate-cldr.xml b/core/res/res/values-sl-rSI/donottranslate-cldr.xml
index 8885a9f..dc01c8c 100644
--- a/core/res/res/values-sl-rSI/donottranslate-cldr.xml
+++ b/core/res/res/values-sl-rSI/donottranslate-cldr.xml
@@ -91,8 +91,9 @@
<string name="today">Danes</string>
<string name="tomorrow">Jutri</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
<string name="numeric_date">%-e. %m. %Y</string>
<string name="numeric_date_format">d. MM. yyyy</string>
<string name="month_day_year">%d. %B %Y</string>
diff --git a/core/res/res/values-sr-rRS/donottranslate-cldr.xml b/core/res/res/values-sr-rRS/donottranslate-cldr.xml
index f97d6c6..cf4f7cb 100644
--- a/core/res/res/values-sr-rRS/donottranslate-cldr.xml
+++ b/core/res/res/values-sr-rRS/donottranslate-cldr.xml
@@ -91,8 +91,9 @@
<string name="today">данас</string>
<string name="tomorrow">сутра</string>
- <string name="hour_minute_ampm">%H.%M</string>
- <string name="hour_minute_cap_ampm">%H.%M</string>
+ <string name="hour_minute_24">%H.%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %p</string>
<string name="numeric_date">%-e.%-m.%Y.</string>
<string name="numeric_date_format">d.M.yyyy.</string>
<string name="month_day_year">%d. %B %Y.</string>
diff --git a/core/res/res/values-sv-rSE/donottranslate-cldr.xml b/core/res/res/values-sv-rSE/donottranslate-cldr.xml
index eb7305f..39e1f85 100644
--- a/core/res/res/values-sv-rSE/donottranslate-cldr.xml
+++ b/core/res/res/values-sv-rSE/donottranslate-cldr.xml
@@ -91,8 +91,9 @@
<string name="today">idag</string>
<string name="tomorrow">imorgon</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%-k.%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
<string name="numeric_date">%Y-%m-%d</string>
<string name="numeric_date_format">yyyy-MM-dd</string>
<string name="month_day_year">%-e %B %Y</string>
diff --git a/core/res/res/values-th-rTH/donottranslate-cldr.xml b/core/res/res/values-th-rTH/donottranslate-cldr.xml
index 0398b56..fec840b 100644
--- a/core/res/res/values-th-rTH/donottranslate-cldr.xml
+++ b/core/res/res/values-th-rTH/donottranslate-cldr.xml
@@ -91,8 +91,9 @@
<string name="today">วันนี้</string>
<string name="tomorrow">พรุ่งนี้</string>
- <string name="hour_minute_ampm">%-k:%M</string>
- <string name="hour_minute_cap_ampm">%-k:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %p</string>
<string name="numeric_date">%-e/%-m/%Y</string>
<string name="numeric_date_format">d/M/yyyy</string>
<string name="month_day_year">%-e %B %Y</string>
diff --git a/core/res/res/values-tr-rTR/donottranslate-cldr.xml b/core/res/res/values-tr-rTR/donottranslate-cldr.xml
index 2de1359..28b2d59 100644
--- a/core/res/res/values-tr-rTR/donottranslate-cldr.xml
+++ b/core/res/res/values-tr-rTR/donottranslate-cldr.xml
@@ -91,8 +91,9 @@
<string name="today">Bugün</string>
<string name="tomorrow">Yarın</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%H:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
<string name="numeric_date">%d %m %Y</string>
<string name="numeric_date_format">dd MM yyyy</string>
<string name="month_day_year">%d %B %Y</string>
diff --git a/core/res/res/values-uk-rUA/donottranslate-cldr.xml b/core/res/res/values-uk-rUA/donottranslate-cldr.xml
index 024a9b3..5c3542d 100644
--- a/core/res/res/values-uk-rUA/donottranslate-cldr.xml
+++ b/core/res/res/values-uk-rUA/donottranslate-cldr.xml
@@ -91,8 +91,9 @@
<string name="today">Сьогодні</string>
<string name="tomorrow">Завтра</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %p</string>
<string name="numeric_date">%d.%m.%Y</string>
<string name="numeric_date_format">dd.MM.yyyy</string>
<string name="month_day_year">%-e %B %Y р.</string>
diff --git a/core/res/res/values-vi-rVN/donottranslate-cldr.xml b/core/res/res/values-vi-rVN/donottranslate-cldr.xml
index 674c37f..5f14fe0 100644
--- a/core/res/res/values-vi-rVN/donottranslate-cldr.xml
+++ b/core/res/res/values-vi-rVN/donottranslate-cldr.xml
@@ -91,8 +91,9 @@
<string name="today">Today</string>
<string name="tomorrow">Tomorrow</string>
- <string name="hour_minute_ampm">%H:%M</string>
- <string name="hour_minute_cap_ampm">%H:%M</string>
+ <string name="hour_minute_24">%-k:%M</string>
+ <string name="hour_minute_ampm">%-l:%M %p</string>
+ <string name="hour_minute_cap_ampm">%-l:%M %^p</string>
<string name="numeric_date">%d/%m/%Y</string>
<string name="numeric_date_format">dd/MM/yyyy</string>
<string name="month_day_year">Ngày %d tháng %-m năm %Y</string>
diff --git a/core/res/res/values-zh-rCN/donottranslate-cldr.xml b/core/res/res/values-zh-rCN/donottranslate-cldr.xml
index d18ce36..faf6fee 100644
--- a/core/res/res/values-zh-rCN/donottranslate-cldr.xml
+++ b/core/res/res/values-zh-rCN/donottranslate-cldr.xml
@@ -91,8 +91,9 @@
<string name="today">今天</string>
<string name="tomorrow">明天</string>
+ <string name="hour_minute_24">%-k:%M</string>
<string name="hour_minute_ampm">%p%-l:%M</string>
- <string name="hour_minute_cap_ampm">%^p%-l:%M</string>
+ <string name="hour_minute_cap_ampm">%p%-l:%M</string>
<string name="numeric_date">%Y-%-m-%-e</string>
<string name="numeric_date_format">yyyy-M-d</string>
<string name="month_day_year">%Y年%-m月%-e日</string>
diff --git a/core/res/res/values-zh-rTW/donottranslate-cldr.xml b/core/res/res/values-zh-rTW/donottranslate-cldr.xml
index d18ce36..faf6fee 100644
--- a/core/res/res/values-zh-rTW/donottranslate-cldr.xml
+++ b/core/res/res/values-zh-rTW/donottranslate-cldr.xml
@@ -91,8 +91,9 @@
<string name="today">今天</string>
<string name="tomorrow">明天</string>
+ <string name="hour_minute_24">%-k:%M</string>
<string name="hour_minute_ampm">%p%-l:%M</string>
- <string name="hour_minute_cap_ampm">%^p%-l:%M</string>
+ <string name="hour_minute_cap_ampm">%p%-l:%M</string>
<string name="numeric_date">%Y-%-m-%-e</string>
<string name="numeric_date_format">yyyy-M-d</string>
<string name="month_day_year">%Y年%-m月%-e日</string>
diff --git a/core/res/res/values/donottranslate-cldr.xml b/core/res/res/values/donottranslate-cldr.xml
index e3808a7..b13a986 100644
--- a/core/res/res/values/donottranslate-cldr.xml
+++ b/core/res/res/values/donottranslate-cldr.xml
@@ -91,6 +91,7 @@
<string name="today">Today</string>
<string name="tomorrow">Tomorrow</string>
+ <string name="hour_minute_24">%H:%M</string>
<string name="hour_minute_ampm">%-l:%M%p</string>
<string name="hour_minute_cap_ampm">%-l:%M%^p</string>
<string name="numeric_date">%-m/%-e/%Y</string>
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPlayerApiTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPlayerApiTest.java
index e01bd53..ea42f53 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPlayerApiTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPlayerApiTest.java
@@ -80,7 +80,6 @@
assertTrue("MIDI getDuration", duratoinWithinTolerence);
}
- @Suppress
@MediumTest
public void testWMA9GetDuration() throws Exception {
int duration = CodecTest.getDuration(MediaNames.WMA9);
@@ -122,7 +121,6 @@
assertTrue("MIDI GetCurrentPosition", currentPosition);
}
- @Suppress
@LargeTest
public void testWMA9GetCurrentPosition() throws Exception {
boolean currentPosition = CodecTest.getCurrentPosition(MediaNames.WMA9);
@@ -160,7 +158,6 @@
assertTrue("MIDI Pause", isPaused);
}
- @Suppress
@LargeTest
public void testWMA9Pause() throws Exception {
boolean isPaused = CodecTest.pause(MediaNames.WMA9);
@@ -232,7 +229,6 @@
assertTrue("MIDI setLooping", isLoop);
}
- @Suppress
@LargeTest
public void testWMA9SetLooping() throws Exception {
boolean isLoop = CodecTest.setLooping(MediaNames.WMA9);
@@ -271,7 +267,6 @@
assertTrue("MIDI seekTo", isLoop);
}
- @Suppress
@LargeTest
public void testWMA9SeekTo() throws Exception {
boolean isLoop = CodecTest.seekTo(MediaNames.WMA9);
@@ -310,7 +305,7 @@
boolean isEnd = CodecTest.seekToEnd(MediaNames.MIDI);
assertTrue("MIDI seekToEnd", isEnd);
}
-
+
@Suppress
@LargeTest
public void testWMA9SeekToEnd() throws Exception {
@@ -388,7 +383,6 @@
assertTrue("H264AMR SeekTo", isSeek);
}
- @Suppress
@LargeTest
public void testVideoWMVSeekTo() throws Exception {
boolean isSeek = CodecTest.videoSeekTo(MediaNames.VIDEO_WMV);
diff --git a/packages/TtsService/Android.mk b/packages/TtsService/Android.mk
new file mode 100644
index 0000000..2737fb4
--- /dev/null
+++ b/packages/TtsService/Android.mk
@@ -0,0 +1,13 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := user
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files) \
+
+LOCAL_PACKAGE_NAME := TtsService
+LOCAL_CERTIFICATE := platform
+
+include $(BUILD_PACKAGE)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/packages/TtsService/AndroidManifest.xml b/packages/TtsService/AndroidManifest.xml
new file mode 100755
index 0000000..1dc25c6
--- /dev/null
+++ b/packages/TtsService/AndroidManifest.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.tts">
+ <application android:label="TTS Service">
+ <service android:enabled="true"
+ android:name=".TtsService"
+ android:label="TTS Service">
+ <intent-filter>
+ <action android:name="android.intent.action.USE_TTS"/>
+ <category android:name="android.intent.category.TTS"/>
+ </intent-filter>
+ </service>
+ </application>
+ <uses-permission android:name="android.permission.INTERNET"/>
+</manifest>
diff --git a/packages/TtsService/MODULE_LICENSE_APACHE2 b/packages/TtsService/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/packages/TtsService/MODULE_LICENSE_APACHE2
diff --git a/packages/TtsService/NOTICE b/packages/TtsService/NOTICE
new file mode 100644
index 0000000..64aaa8d
--- /dev/null
+++ b/packages/TtsService/NOTICE
@@ -0,0 +1,190 @@
+
+ Copyright (c) 2009, 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.
+
+ 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.
+
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
diff --git a/tts/jni/Android.mk b/packages/TtsService/jni/Android.mk
similarity index 100%
rename from tts/jni/Android.mk
rename to packages/TtsService/jni/Android.mk
diff --git a/tts/jni/android_tts_SynthProxy.cpp b/packages/TtsService/jni/android_tts_SynthProxy.cpp
similarity index 100%
rename from tts/jni/android_tts_SynthProxy.cpp
rename to packages/TtsService/jni/android_tts_SynthProxy.cpp
diff --git a/tts/java/android/tts/SynthProxy.java b/packages/TtsService/src/android/tts/SynthProxy.java
similarity index 100%
rename from tts/java/android/tts/SynthProxy.java
rename to packages/TtsService/src/android/tts/SynthProxy.java
diff --git a/tts/java/android/tts/TtsService.java b/packages/TtsService/src/android/tts/TtsService.java
similarity index 97%
rename from tts/java/android/tts/TtsService.java
rename to packages/TtsService/src/android/tts/TtsService.java
index 2373e96..8a64113 100755
--- a/tts/java/android/tts/TtsService.java
+++ b/packages/TtsService/src/android/tts/TtsService.java
@@ -15,7 +15,8 @@
*/
package android.tts;
-import android.tts.ITts.Stub;
+import android.speech.tts.ITts.Stub;
+import android.speech.tts.ITtsCallback;
import android.app.Service;
import android.content.Context;
@@ -91,7 +92,7 @@
private static final String CATEGORY = "android.intent.category.TTS";
private static final String PKGNAME = "android.tts";
- final RemoteCallbackList<ITtsCallback> mCallbacks = new RemoteCallbackList<ITtsCallback>();
+ final RemoteCallbackList<android.speech.tts.ITtsCallback> mCallbacks = new RemoteCallbackList<ITtsCallback>();
private Boolean mIsSpeaking;
private ArrayList<SpeechItem> mSpeechQueue;
@@ -116,16 +117,7 @@
// app.
prefs = PreferenceManager.getDefaultSharedPreferences(this);
- PackageManager pm = this.getPackageManager();
- String soLibPath = "";
- try {
- soLibPath = pm.getApplicationInfo("com.svox.pico", 0).dataDir;
- } catch (NameNotFoundException e) {
- // This exception cannot actually happen as com.svox.pico is
- // included with the system image.
- e.printStackTrace();
- }
- soLibPath = soLibPath + "/lib/libttspico.so";
+ String soLibPath = "/system/lib/libttspico.so";
nativeSynth = new SynthProxy(soLibPath);
mSelf = this;
@@ -537,7 +529,7 @@
return null;
}
- private final ITts.Stub mBinder = new Stub() {
+ private final android.speech.tts.ITts.Stub mBinder = new Stub() {
public void registerCallback(ITtsCallback cb) {
if (cb != null)
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index 42a895c..f871496 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -25,6 +25,7 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageDataObserver;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
@@ -53,6 +54,7 @@
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileNotFoundException;
+import java.io.IOException;
import java.io.PrintWriter;
import java.lang.String;
import java.util.ArrayList;
@@ -70,7 +72,10 @@
private static final int MSG_RUN_BACKUP = 1;
private static final int MSG_RUN_FULL_BACKUP = 2;
-
+
+ // Timeout interval for deciding that a bind or clear-data has taken too long
+ static final long TIMEOUT_INTERVAL = 10 * 1000;
+
private Context mContext;
private PackageManager mPackageManager;
private final IActivityManager mActivityManager;
@@ -108,6 +113,10 @@
private IBackupAgent mConnectedAgent;
private volatile boolean mConnecting;
+ // A similar synchronicity mechanism around clearing apps' data for restore
+ private final Object mClearDataLock = new Object();
+ private volatile boolean mClearingData;
+
private int mTransportId;
private File mStateDir;
@@ -207,80 +216,6 @@
}
}
- void processOneBackup(BackupRequest request, IBackupAgent agent, IBackupTransport transport) {
- final String packageName = request.appInfo.packageName;
- Log.d(TAG, "processOneBackup doBackup() on " + packageName);
-
- try {
- // Look up the package info & signatures. This is first so that if it
- // throws an exception, there's no file setup yet that would need to
- // be unraveled.
- PackageInfo packInfo = mPackageManager.getPackageInfo(packageName,
- PackageManager.GET_SIGNATURES);
-
- // !!! TODO: get the state file dir from the transport
- File savedStateName = new File(mStateDir, packageName);
- File backupDataName = new File(mDataDir, packageName + ".data");
- File newStateName = new File(mStateDir, packageName + ".new");
-
- // In a full backup, we pass a null ParcelFileDescriptor as
- // the saved-state "file"
- ParcelFileDescriptor savedState = (request.fullBackup) ? null
- : ParcelFileDescriptor.open(savedStateName,
- ParcelFileDescriptor.MODE_READ_ONLY |
- ParcelFileDescriptor.MODE_CREATE);
-
- backupDataName.delete();
- ParcelFileDescriptor backupData =
- ParcelFileDescriptor.open(backupDataName,
- ParcelFileDescriptor.MODE_READ_WRITE |
- ParcelFileDescriptor.MODE_CREATE);
-
- newStateName.delete();
- ParcelFileDescriptor newState =
- ParcelFileDescriptor.open(newStateName,
- ParcelFileDescriptor.MODE_READ_WRITE |
- ParcelFileDescriptor.MODE_CREATE);
-
- // Run the target's backup pass
- boolean success = false;
- try {
- agent.doBackup(savedState, backupData, newState);
- success = true;
- } finally {
- if (savedState != null) {
- savedState.close();
- }
- backupData.close();
- newState.close();
- }
-
- // Now propagate the newly-backed-up data to the transport
- if (success) {
- if (DEBUG) Log.v(TAG, "doBackup() success; calling transport");
- backupData =
- ParcelFileDescriptor.open(backupDataName, ParcelFileDescriptor.MODE_READ_ONLY);
- int error = transport.performBackup(packInfo, backupData);
-
- // !!! TODO: After successful transport, delete the now-stale data
- // and juggle the files so that next time the new state is passed
- //backupDataName.delete();
- newStateName.renameTo(savedStateName);
- }
- } catch (NameNotFoundException e) {
- Log.e(TAG, "Package not found on backup: " + packageName);
- } catch (FileNotFoundException fnf) {
- Log.w(TAG, "File not found on backup: ");
- fnf.printStackTrace();
- } catch (RemoteException e) {
- Log.d(TAG, "Remote target " + request.appInfo.packageName + " threw during backup:");
- e.printStackTrace();
- } catch (Exception e) {
- Log.w(TAG, "Final exception guard in backup: ");
- e.printStackTrace();
- }
- }
-
// Add the backup agents in the given package to our set of known backup participants.
// If 'packageName' is null, adds all backup agents in the whole system.
void addPackageParticipantsLocked(String packageName) {
@@ -424,11 +359,14 @@
Log.d(TAG, "awaiting agent for " + app);
// success; wait for the agent to arrive
- while (mConnecting && mConnectedAgent == null) {
+ // only wait 10 seconds for the clear data to happen
+ long timeoutMark = System.currentTimeMillis() + TIMEOUT_INTERVAL;
+ while (mConnecting && mConnectedAgent == null
+ && (System.currentTimeMillis() < timeoutMark)) {
try {
- mAgentConnectLock.wait(10000);
+ mAgentConnectLock.wait(5000);
} catch (InterruptedException e) {
- // just retry
+ // just bail
return null;
}
}
@@ -447,6 +385,37 @@
return agent;
}
+ // clear an application's data, blocking until the operation completes or times out
+ void clearApplicationDataSynchronous(String packageName) {
+ ClearDataObserver observer = new ClearDataObserver();
+
+ synchronized(mClearDataLock) {
+ mClearingData = true;
+ mPackageManager.clearApplicationUserData(packageName, observer);
+
+ // only wait 10 seconds for the clear data to happen
+ long timeoutMark = System.currentTimeMillis() + TIMEOUT_INTERVAL;
+ while (mClearingData && (System.currentTimeMillis() < timeoutMark)) {
+ try {
+ mClearDataLock.wait(5000);
+ } catch (InterruptedException e) {
+ // won't happen, but still.
+ mClearingData = false;
+ }
+ }
+ }
+ }
+
+ class ClearDataObserver extends IPackageDataObserver.Stub {
+ public void onRemoveCompleted(String packageName, boolean succeeded)
+ throws android.os.RemoteException {
+ synchronized(mClearDataLock) {
+ mClearingData = false;
+ notifyAll();
+ }
+ }
+ }
+
// ----- Back up a set of applications via a worker thread -----
class PerformBackupThread extends Thread {
@@ -508,13 +477,88 @@
mActivityManager.unbindBackupAgent(request.appInfo);
} catch (SecurityException ex) {
// Try for the next one.
- Log.d(TAG, "error in bind", ex);
+ Log.d(TAG, "error in bind/backup", ex);
} catch (RemoteException e) {
- // can't happen
+ Log.v(TAG, "bind/backup threw");
+ e.printStackTrace();
}
}
}
+
+ void processOneBackup(BackupRequest request, IBackupAgent agent, IBackupTransport transport) {
+ final String packageName = request.appInfo.packageName;
+ Log.d(TAG, "processOneBackup doBackup() on " + packageName);
+
+ try {
+ // Look up the package info & signatures. This is first so that if it
+ // throws an exception, there's no file setup yet that would need to
+ // be unraveled.
+ PackageInfo packInfo = mPackageManager.getPackageInfo(packageName,
+ PackageManager.GET_SIGNATURES);
+
+ // !!! TODO: get the state file dir from the transport
+ File savedStateName = new File(mStateDir, packageName);
+ File backupDataName = new File(mDataDir, packageName + ".data");
+ File newStateName = new File(mStateDir, packageName + ".new");
+
+ // In a full backup, we pass a null ParcelFileDescriptor as
+ // the saved-state "file"
+ ParcelFileDescriptor savedState = (request.fullBackup) ? null
+ : ParcelFileDescriptor.open(savedStateName,
+ ParcelFileDescriptor.MODE_READ_ONLY |
+ ParcelFileDescriptor.MODE_CREATE);
+
+ backupDataName.delete();
+ ParcelFileDescriptor backupData =
+ ParcelFileDescriptor.open(backupDataName,
+ ParcelFileDescriptor.MODE_READ_WRITE |
+ ParcelFileDescriptor.MODE_CREATE);
+
+ newStateName.delete();
+ ParcelFileDescriptor newState =
+ ParcelFileDescriptor.open(newStateName,
+ ParcelFileDescriptor.MODE_READ_WRITE |
+ ParcelFileDescriptor.MODE_CREATE);
+
+ // Run the target's backup pass
+ boolean success = false;
+ try {
+ agent.doBackup(savedState, backupData, newState);
+ success = true;
+ } finally {
+ if (savedState != null) {
+ savedState.close();
+ }
+ backupData.close();
+ newState.close();
+ }
+
+ // Now propagate the newly-backed-up data to the transport
+ if (success) {
+ if (DEBUG) Log.v(TAG, "doBackup() success; calling transport");
+ backupData =
+ ParcelFileDescriptor.open(backupDataName, ParcelFileDescriptor.MODE_READ_ONLY);
+ int error = transport.performBackup(packInfo, backupData);
+
+ // !!! TODO: After successful transport, delete the now-stale data
+ // and juggle the files so that next time the new state is passed
+ //backupDataName.delete();
+ newStateName.renameTo(savedStateName);
+ }
+ } catch (NameNotFoundException e) {
+ Log.e(TAG, "Package not found on backup: " + packageName);
+ } catch (FileNotFoundException fnf) {
+ Log.w(TAG, "File not found on backup: ");
+ fnf.printStackTrace();
+ } catch (RemoteException e) {
+ Log.d(TAG, "Remote target " + request.appInfo.packageName + " threw during backup:");
+ e.printStackTrace();
+ } catch (Exception e) {
+ Log.w(TAG, "Final exception guard in backup: ");
+ e.printStackTrace();
+ }
+ }
}
@@ -524,12 +568,12 @@
// ApplicationInfo struct if it is; null if not.
//
// !!! TODO: also consider signatures
- ApplicationInfo isRestorable(PackageInfo packageInfo) {
+ PackageInfo isRestorable(PackageInfo packageInfo) {
if (packageInfo.packageName != null) {
try {
- ApplicationInfo app = mPackageManager.getApplicationInfo(packageInfo.packageName,
+ PackageInfo app = mPackageManager.getPackageInfo(packageInfo.packageName,
PackageManager.GET_SIGNATURES);
- if ((app.flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0) {
+ if ((app.applicationInfo.flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0) {
return app;
}
} catch (Exception e) {
@@ -541,6 +585,7 @@
class PerformRestoreThread extends Thread {
private IBackupTransport mTransport;
+ private RestoreSet mImage;
PerformRestoreThread(IBackupTransport transport) {
mTransport = transport;
@@ -556,6 +601,7 @@
* 3. for each app in the restore set:
* 3.a. if it's restorable on this device, add it to the restore queue
* 4. for each app in the restore queue:
+ * 4.a. clear the app data
* 4.b. get the restore data for the app from the transport
* 4.c. launch the backup agent for the app
* 4.d. agent.doRestore() with the data from the server
@@ -577,13 +623,14 @@
RestoreSet[] images = mTransport.getAvailableRestoreSets();
if (images.length > 0) {
// !!! for now we always take the first set
- RestoreSet image = images[0];
+ mImage = images[0];
// build the set of apps we will attempt to restore
- PackageInfo[] packages = mTransport.getAppSet(image.token);
- HashSet<ApplicationInfo> appsToRestore = new HashSet<ApplicationInfo>();
+ PackageInfo[] packages = mTransport.getAppSet(mImage.token);
+ HashSet<PackageInfo> appsToRestore = new HashSet<PackageInfo>();
for (PackageInfo pkg: packages) {
- ApplicationInfo app = isRestorable(pkg);
+ // get the real PackageManager idea of the package
+ PackageInfo app = isRestorable(pkg);
if (app != null) {
appsToRestore.add(app);
}
@@ -609,19 +656,23 @@
}
// restore each app in the queue
- void doQueuedRestores(HashSet<ApplicationInfo> appsToRestore) {
- for (ApplicationInfo app : appsToRestore) {
+ void doQueuedRestores(HashSet<PackageInfo> appsToRestore) {
+ for (PackageInfo app : appsToRestore) {
Log.d(TAG, "starting agent for restore of " + app);
- IBackupAgent agent = null;
try {
- agent = bindToAgentSynchronous(app, IApplicationThread.BACKUP_MODE_RESTORE);
+ // Remove the app's data first
+ clearApplicationDataSynchronous(app.packageName);
+
+ // Now perform the restore into the clean app
+ IBackupAgent agent = bindToAgentSynchronous(app.applicationInfo,
+ IApplicationThread.BACKUP_MODE_RESTORE);
if (agent != null) {
processOneRestore(app, agent);
}
// unbind even on timeout, just in case
- mActivityManager.unbindBackupAgent(app);
+ mActivityManager.unbindBackupAgent(app.applicationInfo);
} catch (SecurityException ex) {
// Try for the next one.
Log.d(TAG, "error in bind", ex);
@@ -632,9 +683,67 @@
}
}
- // do the guts of a restore
- void processOneRestore(ApplicationInfo app, IBackupAgent agent) {
+ // Do the guts of a restore of one application, derived from the 'mImage'
+ // restore set via the 'mTransport' transport.
+ void processOneRestore(PackageInfo app, IBackupAgent agent) {
// !!! TODO: actually run the restore through mTransport
+ final String packageName = app.packageName;
+
+ // !!! TODO: get the dirs from the transport
+ File backupDataName = new File(mDataDir, packageName + ".restore");
+ backupDataName.delete();
+ try {
+ ParcelFileDescriptor backupData =
+ ParcelFileDescriptor.open(backupDataName,
+ ParcelFileDescriptor.MODE_READ_WRITE |
+ ParcelFileDescriptor.MODE_CREATE);
+
+ // Run the transport's restore pass
+ // Run the target's backup pass
+ int err = -1;
+ try {
+ err = mTransport.getRestoreData(mImage.token, app, backupData);
+ } catch (RemoteException e) {
+ // can't happen
+ } finally {
+ backupData.close();
+ }
+
+ // Okay, we have the data. Now have the agent do the restore.
+ File newStateName = new File(mStateDir, packageName + ".new");
+ ParcelFileDescriptor newState =
+ ParcelFileDescriptor.open(newStateName,
+ ParcelFileDescriptor.MODE_READ_WRITE |
+ ParcelFileDescriptor.MODE_CREATE);
+
+ backupData = ParcelFileDescriptor.open(backupDataName,
+ ParcelFileDescriptor.MODE_READ_ONLY);
+
+ boolean success = false;
+ try {
+ agent.doRestore(backupData, newState);
+ success = true;
+ } catch (Exception e) {
+ Log.e(TAG, "Restore failed for " + packageName);
+ e.printStackTrace();
+ } finally {
+ newState.close();
+ backupData.close();
+ }
+
+ // if everything went okay, remember the recorded state now
+ if (success) {
+ File savedStateName = new File(mStateDir, packageName);
+ newStateName.renameTo(savedStateName);
+ }
+ } catch (FileNotFoundException fnfe) {
+ Log.v(TAG, "Couldn't open file for restore: " + fnfe);
+ } catch (IOException ioe) {
+ Log.e(TAG, "Unable to process restore file: " + ioe);
+ } catch (Exception e) {
+ Log.e(TAG, "Final exception guard in restore:");
+ e.printStackTrace();
+ }
}
}
diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java
index adf07dd..fc37290 100644
--- a/services/java/com/android/server/LocationManagerService.java
+++ b/services/java/com/android/server/LocationManagerService.java
@@ -769,8 +769,8 @@
if (!record.mReceiver.callProviderEnabledLocked(provider, enabled)) {
if (deadReceivers == null) {
deadReceivers = new ArrayList<Receiver>();
- deadReceivers.add(record.mReceiver);
}
+ deadReceivers.add(record.mReceiver);
}
listeners++;
}
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index 6a2e62f..0d142da 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -58,6 +58,8 @@
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.pm.Signature;
+import android.content.res.CompatibilityInfo;
+import android.content.res.Configuration;
import android.net.Uri;
import android.os.Binder;
import android.os.Build;
@@ -259,6 +261,7 @@
final ResolveInfo mResolveInfo = new ResolveInfo();
ComponentName mResolveComponentName;
PackageParser.Package mPlatformPackage;
+ private boolean mCompatibilityModeEnabled = true;
public static final IPackageManager main(Context context, boolean factoryTest) {
PackageManagerService m = new PackageManagerService(context, factoryTest);
@@ -509,7 +512,7 @@
} // synchronized (mPackages)
} // synchronized (mInstallLock)
}
-
+
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
@@ -885,7 +888,11 @@
+ ": " + p);
if (p != null) {
// Note: isEnabledLP() does not apply here - always return info
- return PackageParser.generateApplicationInfo(p, flags);
+ ApplicationInfo appInfo = PackageParser.generateApplicationInfo(p, flags);
+ if (!mCompatibilityModeEnabled) {
+ appInfo.disableCompatibilityMode();
+ }
+ return appInfo;
}
if ("android".equals(packageName)||"system".equals(packageName)) {
return mAndroidApplication;
@@ -952,10 +959,35 @@
public ActivityInfo getActivityInfo(ComponentName component, int flags) {
synchronized (mPackages) {
PackageParser.Activity a = mActivities.mActivities.get(component);
- if (Config.LOGV) Log.v(
- TAG, "getActivityInfo " + component + ": " + a);
+
+ if (Config.LOGV) Log.v(TAG, "getActivityInfo " + component + ": " + a);
if (a != null && mSettings.isEnabledLP(a.info, flags)) {
- return PackageParser.generateActivityInfo(a, flags);
+ ActivityInfo ainfo = PackageParser.generateActivityInfo(a, flags);
+ if (ainfo != null && (flags & PackageManager.GET_EXPANDABLE) != 0) {
+ ApplicationInfo appInfo = getApplicationInfo(component.getPackageName(),
+ PackageManager.GET_EXPANDABLE | PackageManager.GET_SUPPORTS_DENSITIES);
+ if (appInfo != null && !appInfo.expandable) {
+ // Check if the screen size is same as what the application expect.
+ CompatibilityInfo info = new CompatibilityInfo(appInfo);
+ DisplayMetrics metrics = new DisplayMetrics();
+ metrics.setTo(mMetrics);
+ int orientation = mMetrics.widthPixels > mMetrics.heightPixels ?
+ Configuration.ORIENTATION_LANDSCAPE :
+ Configuration.ORIENTATION_PORTRAIT;
+ metrics.updateMetrics(info, orientation);
+ if (!info.mExpandable) {
+ // Don't allow an app that cannot expand to handle rotation.
+ ainfo.configChanges &= ~ ActivityInfo.CONFIG_ORIENTATION;
+ } else {
+ appInfo.expandable = true;
+ }
+ if (DEBUG_SETTINGS) {
+ Log.d(TAG, "component=" + component +
+ ", expandable:" + appInfo.expandable);
+ }
+ }
+ }
+ return ainfo;
}
if (mResolveComponentName.equals(component)) {
return mResolveActivity;
@@ -4709,6 +4741,14 @@
public void systemReady() {
mSystemReady = true;
+
+ // Read the compatibilty setting when the system is ready.
+ mCompatibilityModeEnabled = android.provider.Settings.System.getInt(
+ mContext.getContentResolver(),
+ android.provider.Settings.System.COMPATIBILITY_MODE, 1) == 1;
+ if (DEBUG_SETTINGS) {
+ Log.d(TAG, "compatibility mode:" + mCompatibilityModeEnabled);
+ }
}
public boolean isSafeMode() {
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index a04d73a..828b8aa 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -133,16 +133,16 @@
static final boolean DEBUG_STARTING_WINDOW = false;
static final boolean DEBUG_REORDER = false;
static final boolean SHOW_TRANSACTIONS = false;
-
+
static final boolean PROFILE_ORIENTATION = false;
static final boolean BLUR = true;
static final boolean localLOGV = DEBUG;
-
+
static final int LOG_WM_NO_SURFACE_MEMORY = 31000;
-
+
/** How long to wait for first key repeat, in milliseconds */
static final int KEY_REPEAT_FIRST_DELAY = 750;
-
+
/** How long to wait for subsequent key repeats, in milliseconds */
static final int KEY_REPEAT_DELAY = 50;
@@ -150,16 +150,16 @@
* for multiple windows of the same type and Z-ordering adjustment
* with TYPE_LAYER_OFFSET. */
static final int TYPE_LAYER_MULTIPLIER = 10000;
-
+
/** Offset from TYPE_LAYER_MULTIPLIER for moving a group of windows above
* or below others in the same layer. */
static final int TYPE_LAYER_OFFSET = 1000;
-
+
/** How much to increment the layer for each window, to reserve room
* for effect surfaces between them.
*/
static final int WINDOW_LAYER_MULTIPLIER = 5;
-
+
/** The maximum length we will accept for a loaded animation duration:
* this is 10 seconds.
*/
@@ -173,21 +173,21 @@
/** Adjustment to time to perform a dim, to make it more dramatic.
*/
static final int DIM_DURATION_MULTIPLIER = 6;
-
+
static final int UPDATE_FOCUS_NORMAL = 0;
static final int UPDATE_FOCUS_WILL_ASSIGN_LAYERS = 1;
static final int UPDATE_FOCUS_PLACING_SURFACES = 2;
static final int UPDATE_FOCUS_WILL_PLACE_SURFACES = 3;
-
+
/** The minimum time between dispatching touch events. */
int mMinWaitTimeBetweenTouchEvents = 1000 / 35;
// Last touch event time
long mLastTouchEventTime = 0;
-
+
// Last touch event type
int mLastTouchEventType = OTHER_EVENT;
-
+
// Time to wait before calling useractivity again. This saves CPU usage
// when we get a flood of touch events.
static final int MIN_TIME_BETWEEN_USERACTIVITIES = 1000;
@@ -195,10 +195,11 @@
// Last time we call user activity
long mLastUserActivityCallTime = 0;
- // Last time we updated battery stats
+ // Last time we updated battery stats
long mLastBatteryStatsCallTime = 0;
-
+
private static final String SYSTEM_SECURE = "ro.secure";
+ private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
/**
* Condition waited on by {@link #reenableKeyguard} to know the call to
@@ -224,20 +225,20 @@
final Context mContext;
final boolean mHaveInputMethods;
-
+
final boolean mLimitedAlphaCompositing;
-
+
final WindowManagerPolicy mPolicy = PolicyManager.makeNewWindowManager();
final IActivityManager mActivityManager;
-
+
final IBatteryStats mBatteryStats;
-
+
/**
* All currently active sessions with clients.
*/
final HashSet<Session> mSessions = new HashSet<Session>();
-
+
/**
* Mapping from an IWindow IBinder to the server's Window object.
* This is also used as the lock for all of our state.
@@ -255,7 +256,7 @@
* over them.
*/
final ArrayList<WindowToken> mTokenList = new ArrayList<WindowToken>();
-
+
/**
* Window tokens that are in the process of exiting, but still
* on screen for animations.
@@ -314,9 +315,9 @@
* list or contain windows that need to be force removed.
*/
ArrayList<WindowState> mForceRemoves;
-
+
IInputMethodManager mInputMethodManager;
-
+
SurfaceSession mFxSession;
Surface mDimSurface;
boolean mDimShown;
@@ -326,9 +327,9 @@
long mLastDimAnimTime;
Surface mBlurSurface;
boolean mBlurShown;
-
+
int mTransactionSequence = 0;
-
+
final float[] mTmpFloats = new float[9];
boolean mSafeMode;
@@ -340,7 +341,7 @@
int mLastRotationFlags;
ArrayList<IRotationWatcher> mRotationWatchers
= new ArrayList<IRotationWatcher>();
-
+
boolean mLayoutNeeded = true;
boolean mAnimationPending = false;
boolean mDisplayFrozen = false;
@@ -352,7 +353,7 @@
// perform a rotation animation when turning off shows the lock screen which
// changes the orientation.
PowerManager.WakeLock mScreenFrozenLock;
-
+
// State management of app transitions. When we are preparing for a
// transition, mNextAppTransition will be the kind of transition to
// perform or TRANSIT_NONE if we are not waiting. If we are waiting,
@@ -365,40 +366,40 @@
boolean mSkipAppTransitionAnimation = false;
final ArrayList<AppWindowToken> mOpeningApps = new ArrayList<AppWindowToken>();
final ArrayList<AppWindowToken> mClosingApps = new ArrayList<AppWindowToken>();
-
+
//flag to detect fat touch events
boolean mFatTouch = false;
Display mDisplay;
-
+
H mH = new H();
WindowState mCurrentFocus = null;
WindowState mLastFocus = null;
-
+
// This just indicates the window the input method is on top of, not
// necessarily the window its input is going to.
WindowState mInputMethodTarget = null;
WindowState mUpcomingInputMethodTarget = null;
boolean mInputMethodTargetWaitingAnim;
int mInputMethodAnimLayerAdjustment;
-
+
WindowState mInputMethodWindow = null;
final ArrayList<WindowState> mInputMethodDialogs = new ArrayList<WindowState>();
AppWindowToken mFocusedApp = null;
PowerManagerService mPowerManager;
-
+
float mWindowAnimationScale = 1.0f;
float mTransitionAnimationScale = 1.0f;
-
+
final KeyWaiter mKeyWaiter = new KeyWaiter();
final KeyQ mQueue;
final InputDispatcherThread mInputThread;
// Who is holding the screen on.
Session mHoldingScreenOn;
-
+
/**
* Whether the UI is currently running in touch mode (not showing
* navigational focus because the user is directly pressing the screen).
@@ -408,14 +409,14 @@
private ViewServer mViewServer;
final Rect mTempRect = new Rect();
-
+
final Configuration mTempConfiguration = new Configuration();
-
+
public static WindowManagerService main(Context context,
PowerManagerService pm, boolean haveInputMethods) {
WMThread thr = new WMThread(context, pm, haveInputMethods);
thr.start();
-
+
synchronized (thr) {
while (thr.mService == null) {
try {
@@ -424,17 +425,17 @@
}
}
}
-
+
return thr.mService;
}
-
+
static class WMThread extends Thread {
WindowManagerService mService;
-
+
private final Context mContext;
private final PowerManagerService mPM;
private final boolean mHaveInputMethods;
-
+
public WMThread(Context context, PowerManagerService pm,
boolean haveInputMethods) {
super("WindowManager");
@@ -442,19 +443,19 @@
mPM = pm;
mHaveInputMethods = haveInputMethods;
}
-
+
public void run() {
Looper.prepare();
WindowManagerService s = new WindowManagerService(mContext, mPM,
mHaveInputMethods);
android.os.Process.setThreadPriority(
android.os.Process.THREAD_PRIORITY_DISPLAY);
-
+
synchronized (this) {
mService = s;
notifyAll();
}
-
+
Looper.loop();
}
}
@@ -465,7 +466,7 @@
private final Context mContext;
private final PowerManagerService mPM;
boolean mRunning = false;
-
+
public PolicyThread(WindowManagerPolicy policy,
WindowManagerService service, Context context,
PowerManagerService pm) {
@@ -475,7 +476,7 @@
mContext = context;
mPM = pm;
}
-
+
public void run() {
Looper.prepare();
//Looper.myLooper().setMessageLogging(new LogPrinter(
@@ -483,12 +484,12 @@
android.os.Process.setThreadPriority(
android.os.Process.THREAD_PRIORITY_FOREGROUND);
mPolicy.init(mContext, mService, mPM);
-
+
synchronized (this) {
mRunning = true;
notifyAll();
}
-
+
Looper.loop();
}
}
@@ -499,7 +500,7 @@
mHaveInputMethods = haveInputMethods;
mLimitedAlphaCompositing = context.getResources().getBoolean(
com.android.internal.R.bool.config_sf_limitedAlpha);
-
+
mPowerManager = pm;
mPowerManager.setPolicy(mPolicy);
PowerManager pmc = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
@@ -515,14 +516,14 @@
Settings.System.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
mTransitionAnimationScale = Settings.System.getFloat(context.getContentResolver(),
Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
-
+
mQueue = new KeyQ();
mInputThread = new InputDispatcherThread();
-
+
PolicyThread thr = new PolicyThread(mPolicy, this, context, pm);
thr.start();
-
+
synchronized (thr) {
while (!thr.mRunning) {
try {
@@ -531,9 +532,9 @@
}
}
}
-
+
mInputThread.start();
-
+
// Add ourself to the Watchdog monitors.
Watchdog.getInstance().addMonitor(this);
}
@@ -586,12 +587,12 @@
}
return -1;
}
-
+
private void addWindowToListInOrderLocked(WindowState win, boolean addToToken) {
final IWindow client = win.mClient;
final WindowToken token = win.mToken;
final ArrayList localmWindows = mWindows;
-
+
final int N = localmWindows.size();
final WindowState attached = win.mAttachedWindow;
int i;
@@ -616,12 +617,12 @@
} else {
int newIdx = findIdxBasedOnAppTokens(win);
if(newIdx != -1) {
- //there is a window above this one associated with the same
- //apptoken note that the window could be a floating window
- //that was created later or a window at the top of the list of
+ //there is a window above this one associated with the same
+ //apptoken note that the window could be a floating window
+ //that was created later or a window at the top of the list of
//windows associated with this token.
localmWindows.add(newIdx+1, win);
- }
+ }
}
}
} else {
@@ -647,7 +648,7 @@
// we need to look some more.
if (pos != null) {
// Move behind any windows attached to this one.
- WindowToken atoken =
+ WindowToken atoken =
mTokenMap.get(((WindowState)pos).mClient.asBinder());
if (atoken != null) {
final int NC = atoken.windows.size();
@@ -770,12 +771,12 @@
}
}
}
-
+
if (win.mAppToken != null && addToToken) {
win.mAppToken.allAppWindows.add(win);
}
}
-
+
static boolean canBeImeTarget(WindowState w) {
final int fl = w.mAttrs.flags
& (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM);
@@ -784,7 +785,7 @@
}
return false;
}
-
+
int findDesiredInputMethodWindowIndexLocked(boolean willMove) {
final ArrayList localmWindows = mWindows;
final int N = localmWindows.size();
@@ -793,12 +794,12 @@
while (i > 0) {
i--;
w = (WindowState)localmWindows.get(i);
-
+
//Log.i(TAG, "Checking window @" + i + " " + w + " fl=0x"
// + Integer.toHexString(w.mAttrs.flags));
if (canBeImeTarget(w)) {
//Log.i(TAG, "Putting input method here!");
-
+
// Yet more tricksyness! If this window is a "starting"
// window, we do actually want to be on top of it, but
// it is not -really- where input will go. So if the caller
@@ -816,16 +817,16 @@
break;
}
}
-
+
mUpcomingInputMethodTarget = w;
-
+
if (DEBUG_INPUT_METHOD) Log.v(TAG, "Desired input method target="
+ w + " willMove=" + willMove);
-
+
if (willMove && w != null) {
final WindowState curTarget = mInputMethodTarget;
if (curTarget != null && curTarget.mAppToken != null) {
-
+
// Now some fun for dealing with window animations that
// modify the Z order. We need to look at all windows below
// the current target that are in this app, finding the highest
@@ -851,14 +852,14 @@
pos--;
}
}
-
+
if (highestTarget != null) {
- if (DEBUG_INPUT_METHOD) Log.v(TAG, "mNextAppTransition="
+ if (DEBUG_INPUT_METHOD) Log.v(TAG, "mNextAppTransition="
+ mNextAppTransition + " " + highestTarget
+ " animating=" + highestTarget.isAnimating()
+ " layer=" + highestTarget.mAnimLayer
+ " new layer=" + w.mAnimLayer);
-
+
if (mNextAppTransition != WindowManagerPolicy.TRANSIT_NONE) {
// If we are currently setting up for an animation,
// hold everything until we can find out what will happen.
@@ -877,7 +878,7 @@
}
}
}
-
+
//Log.i(TAG, "Placing input method @" + (i+1));
if (w != null) {
if (willMove) {
@@ -904,7 +905,7 @@
}
return -1;
}
-
+
void addInputMethodWindowToListLocked(WindowState win) {
int pos = findDesiredInputMethodWindowIndexLocked(true);
if (pos >= 0) {
@@ -917,7 +918,7 @@
addWindowToListInOrderLocked(win, true);
moveInputMethodDialogsLocked(pos);
}
-
+
void setInputMethodAnimLayerAdjustment(int adj) {
if (DEBUG_LAYERS) Log.v(TAG, "Setting im layer adj to " + adj);
mInputMethodAnimLayerAdjustment = adj;
@@ -944,7 +945,7 @@
+ " anim layer: " + imw.mAnimLayer);
}
}
-
+
private int tmpRemoveWindowLocked(int interestingPos, WindowState win) {
int wpos = mWindows.indexOf(win);
if (wpos >= 0) {
@@ -963,7 +964,7 @@
}
return interestingPos;
}
-
+
private void reAddWindowToListInOrderLocked(WindowState win) {
addWindowToListInOrderLocked(win, false);
// This is a hack to get all of the child windows added as well
@@ -975,7 +976,7 @@
reAddWindowLocked(wpos, win);
}
}
-
+
void logWindowList(String prefix) {
int N = mWindows.size();
while (N > 0) {
@@ -983,10 +984,10 @@
Log.v(TAG, prefix + "#" + N + ": " + mWindows.get(N));
}
}
-
+
void moveInputMethodDialogsLocked(int pos) {
ArrayList<WindowState> dialogs = mInputMethodDialogs;
-
+
final int N = dialogs.size();
if (DEBUG_INPUT_METHOD) Log.v(TAG, "Removing " + N + " dialogs w/pos=" + pos);
for (int i=0; i<N; i++) {
@@ -996,7 +997,7 @@
Log.v(TAG, "Window list w/pos=" + pos);
logWindowList(" ");
}
-
+
if (pos >= 0) {
final AppWindowToken targetAppToken = mInputMethodTarget.mAppToken;
if (pos < mWindows.size()) {
@@ -1027,25 +1028,25 @@
}
}
}
-
+
boolean moveInputMethodWindowsIfNeededLocked(boolean needAssignLayers) {
final WindowState imWin = mInputMethodWindow;
final int DN = mInputMethodDialogs.size();
if (imWin == null && DN == 0) {
return false;
}
-
+
int imPos = findDesiredInputMethodWindowIndexLocked(true);
if (imPos >= 0) {
// In this case, the input method windows are to be placed
// immediately above the window they are targeting.
-
+
// First check to see if the input method windows are already
// located here, and contiguous.
final int N = mWindows.size();
WindowState firstImWin = imPos < N
? (WindowState)mWindows.get(imPos) : null;
-
+
// Figure out the actual input method window that should be
// at the bottom of their stack.
WindowState baseImWin = imWin != null
@@ -1054,7 +1055,7 @@
WindowState cw = (WindowState)baseImWin.mChildWindows.get(0);
if (cw.mSubLayer < 0) baseImWin = cw;
}
-
+
if (firstImWin == baseImWin) {
// The windows haven't moved... but are they still contiguous?
// First find the top IM window.
@@ -1078,7 +1079,7 @@
return false;
}
}
-
+
if (imWin != null) {
if (DEBUG_INPUT_METHOD) {
Log.v(TAG, "Moving IM from " + imPos);
@@ -1099,11 +1100,11 @@
} else {
moveInputMethodDialogsLocked(imPos);
}
-
+
} else {
// In this case, the input method windows go in a fixed layer,
// because they aren't currently associated with a focus window.
-
+
if (imWin != null) {
if (DEBUG_INPUT_METHOD) Log.v(TAG, "Moving IM from " + imPos);
tmpRemoveWindowLocked(0, imWin);
@@ -1117,20 +1118,20 @@
} else {
moveInputMethodDialogsLocked(-1);;
}
-
+
}
-
+
if (needAssignLayers) {
assignLayersLocked();
}
-
+
return true;
}
-
+
void adjustInputMethodDialogsLocked() {
moveInputMethodDialogsLocked(findDesiredInputMethodWindowIndexLocked(true));
}
-
+
public int addWindow(Session session, IWindow client,
WindowManager.LayoutParams attrs, int viewVisibility,
Rect outContentInsets) {
@@ -1138,11 +1139,11 @@
if (res != WindowManagerImpl.ADD_OKAY) {
return res;
}
-
+
boolean reportNewConfig = false;
WindowState attachedWindow = null;
WindowState win = null;
-
+
synchronized(mWindowMap) {
// Instantiating a Display requires talking with the simulator,
// so don't do it until we know the system is mostly up and
@@ -1153,14 +1154,14 @@
mQueue.setDisplay(mDisplay);
reportNewConfig = true;
}
-
+
if (mWindowMap.containsKey(client.asBinder())) {
Log.w(TAG, "Window " + client + " is already added");
return WindowManagerImpl.ADD_DUPLICATE_ADD;
}
if (attrs.type >= FIRST_SUB_WINDOW && attrs.type <= LAST_SUB_WINDOW) {
- attachedWindow = windowForClientLocked(null, attrs.token);
+ attachedWindow = windowForClientLocked(null, attrs.token);
if (attachedWindow == null) {
Log.w(TAG, "Attempted to add window with token that is not a window: "
+ attrs.token + ". Aborting.");
@@ -1227,7 +1228,7 @@
}
mPolicy.adjustWindowParamsLw(win.mAttrs);
-
+
res = mPolicy.prepareAddWindowLw(win, attrs);
if (res != WindowManagerImpl.ADD_OKAY) {
return res;
@@ -1236,9 +1237,9 @@
// From now on, no exceptions or errors allowed!
res = WindowManagerImpl.ADD_OKAY;
-
+
final long origId = Binder.clearCallingIdentity();
-
+
if (addToken) {
mTokenMap.put(attrs.token, token);
mTokenList.add(token);
@@ -1252,7 +1253,7 @@
}
boolean imMayMove = true;
-
+
if (attrs.type == TYPE_INPUT_METHOD) {
mInputMethodWindow = win;
addInputMethodWindowToListLocked(win);
@@ -1265,18 +1266,18 @@
} else {
addWindowToListInOrderLocked(win, true);
}
-
+
win.mEnterAnimationPending = true;
-
+
mPolicy.getContentInsetHintLw(attrs, outContentInsets);
-
+
if (mInTouchMode) {
res |= WindowManagerImpl.ADD_FLAG_IN_TOUCH_MODE;
}
if (win == null || win.mAppToken == null || !win.mAppToken.clientHidden) {
res |= WindowManagerImpl.ADD_FLAG_APP_VISIBLE;
}
-
+
boolean focusChanged = false;
if (win.canReceiveKeys()) {
if ((focusChanged=updateFocusedWindowLocked(UPDATE_FOCUS_WILL_ASSIGN_LAYERS))
@@ -1284,15 +1285,15 @@
imMayMove = false;
}
}
-
+
if (imMayMove) {
- moveInputMethodWindowsIfNeededLocked(false);
+ moveInputMethodWindowsIfNeededLocked(false);
}
-
+
assignLayersLocked();
// Don't do layout here, the window must call
// relayout to be displayed, so we'll do it there.
-
+
//dump();
if (focusChanged) {
@@ -1322,10 +1323,10 @@
}
}
Binder.restoreCallingIdentity(origId);
-
+
return res;
}
-
+
public void removeWindow(Session session, IWindow client) {
synchronized(mWindowMap) {
WindowState win = windowForClientLocked(session, client);
@@ -1335,7 +1336,7 @@
removeWindowLocked(session, win);
}
}
-
+
public void removeWindowLocked(Session session, WindowState win) {
if (localLOGV || DEBUG_FOCUS) Log.v(
@@ -1345,7 +1346,7 @@
+ ", surface=" + win.mSurface);
final long origId = Binder.clearCallingIdentity();
-
+
if (DEBUG_APP_TRANSITIONS) Log.v(
TAG, "Remove " + win + ": mSurface=" + win.mSurface
+ " mExiting=" + win.mExiting
@@ -1365,7 +1366,7 @@
// If we are not currently running the exit animation, we
// need to see about starting one.
if (wasVisible=win.isWinVisibleLw()) {
-
+
int transit = WindowManagerPolicy.TRANSIT_EXIT;
if (win.getAttrs().type == TYPE_APPLICATION_STARTING) {
transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
@@ -1402,17 +1403,17 @@
updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
Binder.restoreCallingIdentity(origId);
}
-
+
private void removeWindowInnerLocked(Session session, WindowState win) {
mKeyWaiter.releasePendingPointerLocked(win.mSession);
mKeyWaiter.releasePendingTrackballLocked(win.mSession);
-
+
win.mRemoved = true;
-
+
if (mInputMethodTarget == win) {
moveInputMethodWindowsIfNeededLocked(false);
}
-
+
mPolicy.removeWindowLw(win);
win.removeLocked();
@@ -1424,7 +1425,7 @@
} else if (win.mAttrs.type == TYPE_INPUT_METHOD_DIALOG) {
mInputMethodDialogs.remove(win);
}
-
+
final WindowToken token = win.mToken;
final AppWindowToken atoken = win.mAppToken;
token.windows.remove(win);
@@ -1461,7 +1462,7 @@
mH.sendMessage(m);
}
}
-
+
if (!mInLayout) {
assignLayersLocked();
mLayoutNeeded = true;
@@ -1492,7 +1493,7 @@
}
void setInsetsWindow(Session session, IWindow client,
- int touchableInsets, Rect contentInsets,
+ int touchableInsets, Rect contentInsets,
Rect visibleInsets) {
long origId = Binder.clearCallingIdentity();
try {
@@ -1511,7 +1512,7 @@
Binder.restoreCallingIdentity(origId);
}
}
-
+
public void getWindowDisplayFrame(Session session, IWindow client,
Rect outDisplayFrame) {
synchronized(mWindowMap) {
@@ -1533,7 +1534,7 @@
boolean inTouchMode;
Configuration newConfig = null;
long origId = Binder.clearCallingIdentity();
-
+
synchronized(mWindowMap) {
WindowState win = windowForClientLocked(session, client);
if (win == null) {
@@ -1545,7 +1546,7 @@
if (attrs != null) {
mPolicy.adjustWindowParamsLw(attrs);
}
-
+
int attrChanges = 0;
int flagChanges = 0;
if (attrs != null) {
@@ -1577,11 +1578,11 @@
boolean imMayMove = (flagChanges&(
WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM |
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)) != 0;
-
+
boolean focusMayChange = win.mViewVisibility != viewVisibility
|| ((flagChanges&WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) != 0)
|| (!win.mRelayoutCalled);
-
+
win.mRelayoutCalled = true;
final int oldVisibility = win.mViewVisibility;
win.mViewVisibility = viewVisibility;
@@ -1669,17 +1670,17 @@
}
//System.out.println("Relayout " + win + ": focus=" + mCurrentFocus);
}
-
+
// updateFocusedWindowLocked() already assigned layers so we only need to
// reassign them at this point if the IM window state gets shuffled
boolean assignLayers = false;
-
+
if (imMayMove) {
if (moveInputMethodWindowsIfNeededLocked(false)) {
assignLayers = true;
}
}
-
+
mLayoutNeeded = true;
win.mGivenInsetsPending = insetsPending;
if (assignLayers) {
@@ -1695,7 +1696,7 @@
outVisibleInsets.set(win.mVisibleInsets);
if (localLOGV) Log.v(
TAG, "Relayout given client " + client.asBinder()
- + ", requestedWidth=" + requestedWidth
+ + ", requestedWidth=" + requestedWidth
+ ", requestedHeight=" + requestedHeight
+ ", viewVisibility=" + viewVisibility
+ "\nRelayout returning frame=" + outFrame
@@ -1710,9 +1711,9 @@
if (newConfig != null) {
sendNewConfiguration();
}
-
+
Binder.restoreCallingIdentity(origId);
-
+
return (inTouchMode ? WindowManagerImpl.RELAYOUT_IN_TOUCH_MODE : 0)
| (displayed ? WindowManagerImpl.RELAYOUT_FIRST_TIME : 0);
}
@@ -1749,7 +1750,7 @@
}
return null;
}
-
+
private void applyEnterAnimationLocked(WindowState win) {
int transit = WindowManagerPolicy.TRANSIT_SHOW;
if (win.mEnterAnimationPending) {
@@ -1767,7 +1768,7 @@
// an animation of the same type, then just leave that one alone.
return true;
}
-
+
// Only apply an animation if the display isn't frozen. If it is
// frozen, there is no reason to animate and it can cause strange
// artifacts when we unfreeze the display if some different animation
@@ -1832,7 +1833,7 @@
}
return null;
}
-
+
private boolean applyAnimationLocked(AppWindowToken wtoken,
WindowManager.LayoutParams lp, int transit, boolean enter) {
// Only apply an animation if the display isn't frozen. If it is
@@ -1931,7 +1932,7 @@
if (Binder.getCallingPid() == Process.myPid()) {
return true;
}
-
+
if (mContext.checkCallingPermission(permission)
== PackageManager.PERMISSION_GRANTED) {
return true;
@@ -1943,7 +1944,7 @@
Log.w(TAG, msg);
return false;
}
-
+
AppWindowToken findAppWindowToken(IBinder token) {
WindowToken wtoken = mTokenMap.get(token);
if (wtoken == null) {
@@ -1951,13 +1952,13 @@
}
return wtoken.appWindowToken;
}
-
+
public void addWindowToken(IBinder token, int type) {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
"addWindowToken()")) {
return;
}
-
+
synchronized(mWindowMap) {
WindowToken wtoken = mTokenMap.get(token);
if (wtoken != null) {
@@ -1969,7 +1970,7 @@
mTokenList.add(wtoken);
}
}
-
+
public void removeWindowToken(IBinder token) {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
"removeWindowToken()")) {
@@ -1984,17 +1985,17 @@
boolean delayed = false;
if (!wtoken.hidden) {
wtoken.hidden = true;
-
+
final int N = wtoken.windows.size();
boolean changed = false;
-
+
for (int i=0; i<N; i++) {
WindowState win = wtoken.windows.get(i);
if (win.isAnimating()) {
delayed = true;
}
-
+
if (win.isVisibleNow()) {
applyAnimationLocked(win,
WindowManagerPolicy.TRANSIT_EXIT, false);
@@ -2009,12 +2010,12 @@
performLayoutAndPlaceSurfacesLocked();
updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL);
}
-
+
if (delayed) {
mExitingTokens.add(wtoken);
}
}
-
+
} else {
Log.w(TAG, "Attempted to remove non-existing token: " + token);
}
@@ -2028,7 +2029,7 @@
"addAppToken()")) {
return;
}
-
+
synchronized(mWindowMap) {
AppWindowToken wtoken = findAppWindowToken(token.asBinder());
if (wtoken != null) {
@@ -2043,15 +2044,15 @@
if (localLOGV) Log.v(TAG, "Adding new app token: " + wtoken);
mTokenMap.put(token.asBinder(), wtoken);
mTokenList.add(wtoken);
-
+
// Application tokens start out hidden.
wtoken.hidden = true;
wtoken.hiddenRequested = true;
-
+
//dump();
}
}
-
+
public void setAppGroupId(IBinder token, int groupId) {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
"setAppStartingIcon()")) {
@@ -2067,7 +2068,7 @@
wtoken.groupId = groupId;
}
}
-
+
public int getOrientationFromWindowsLocked() {
int pos = mWindows.size() - 1;
while (pos >= 0) {
@@ -2091,7 +2092,7 @@
}
return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
}
-
+
public int getOrientationFromAppTokensLocked() {
int pos = mAppTokens.size() - 1;
int curGroup = 0;
@@ -2133,7 +2134,7 @@
// to use the orientation behind it, then just take whatever
// orientation it has and ignores whatever is under it.
lastFullscreen = wtoken.appFullscreen;
- if (lastFullscreen
+ if (lastFullscreen
&& or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
return or;
}
@@ -2150,7 +2151,7 @@
}
return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
}
-
+
public Configuration updateOrientationFromAppTokens(
Configuration currentConfig, IBinder freezeThisOneIfNeeded) {
Configuration config;
@@ -2165,11 +2166,11 @@
Binder.restoreCallingIdentity(ident);
return config;
}
-
+
/*
* The orientation is computed from non-application windows first. If none of
* the non-application windows specify orientation, the orientation is computed from
- * application tokens.
+ * application tokens.
* @see android.view.IWindowManager#updateOrientationFromAppTokens(
* android.os.IBinder)
*/
@@ -2179,7 +2180,7 @@
long ident = Binder.clearCallingIdentity();
try {
int req = computeForcedAppOrientationLocked();
-
+
if (req != mForcedAppOrientation) {
changed = true;
mForcedAppOrientation = req;
@@ -2187,7 +2188,7 @@
//action like disabling/enabling sensors etc.,
mPolicy.setCurrentOrientationLw(req);
}
-
+
if (changed) {
changed = setRotationUncheckedLocked(
WindowManagerPolicy.USE_LAST_ROTATION,
@@ -2219,10 +2220,10 @@
} finally {
Binder.restoreCallingIdentity(ident);
}
-
+
return null;
}
-
+
int computeForcedAppOrientationLocked() {
int req = getOrientationFromWindowsLocked();
if (req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) {
@@ -2230,35 +2231,35 @@
}
return req;
}
-
+
public void setAppOrientation(IApplicationToken token, int requestedOrientation) {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
"setAppOrientation()")) {
return;
}
-
+
synchronized(mWindowMap) {
AppWindowToken wtoken = findAppWindowToken(token.asBinder());
if (wtoken == null) {
Log.w(TAG, "Attempted to set orientation of non-existing app token: " + token);
return;
}
-
+
wtoken.requestedOrientation = requestedOrientation;
}
}
-
+
public int getAppOrientation(IApplicationToken token) {
synchronized(mWindowMap) {
AppWindowToken wtoken = findAppWindowToken(token.asBinder());
if (wtoken == null) {
return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
}
-
+
return wtoken.requestedOrientation;
}
}
-
+
public void setFocusedApp(IBinder token, boolean moveFocusNow) {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
"setFocusedApp()")) {
@@ -2297,7 +2298,7 @@
"prepareAppTransition()")) {
return;
}
-
+
synchronized(mWindowMap) {
if (DEBUG_APP_TRANSITIONS) Log.v(
TAG, "Prepare app transition: transit=" + transit
@@ -2320,13 +2321,13 @@
public int getPendingAppTransition() {
return mNextAppTransition;
}
-
+
public void executeAppTransition() {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
"executeAppTransition()")) {
return;
}
-
+
synchronized(mWindowMap) {
if (DEBUG_APP_TRANSITIONS) Log.v(
TAG, "Execute app transition: mNextAppTransition=" + mNextAppTransition);
@@ -2351,7 +2352,7 @@
if (DEBUG_STARTING_WINDOW) Log.v(
TAG, "setAppStartingIcon: token=" + token + " pkg=" + pkg
+ " transferFrom=" + transferFrom);
-
+
AppWindowToken wtoken = findAppWindowToken(token);
if (wtoken == null) {
Log.w(TAG, "Attempted to set icon of non-existing app token: " + token);
@@ -2364,11 +2365,11 @@
if (mDisplayFrozen) {
return;
}
-
+
if (wtoken.startingData != null) {
return;
}
-
+
if (transferFrom != null) {
AppWindowToken ttoken = findAppWindowToken(transferFrom);
if (ttoken != null) {
@@ -2384,7 +2385,7 @@
"Moving existing starting from " + ttoken
+ " to " + wtoken);
final long origId = Binder.clearCallingIdentity();
-
+
// Transfer the starting window over to the new
// token.
wtoken.startingData = ttoken.startingData;
@@ -2402,7 +2403,7 @@
ttoken.allAppWindows.remove(startingWindow);
addWindowToListInOrderLocked(startingWindow, true);
wtoken.allAppWindows.add(startingWindow);
-
+
// Propagate other interesting state between the
// tokens. If the old token is displayed, we should
// immediately force the new one to be displayed. If
@@ -2432,7 +2433,7 @@
wtoken.updateLayers();
ttoken.updateLayers();
}
-
+
updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
mLayoutNeeded = true;
performLayoutAndPlaceSurfacesLocked();
@@ -2462,7 +2463,7 @@
if (!createIfNeeded) {
return;
}
-
+
mStartingIconInTransition = true;
wtoken.startingData = new StartingData(
pkg, theme, nonLocalizedLabel,
@@ -2492,7 +2493,7 @@
wtoken.willBeHidden = true;
}
}
-
+
boolean setTokenVisibilityLocked(AppWindowToken wtoken, WindowManager.LayoutParams lp,
boolean visible, int transit, boolean performLayout) {
boolean delayed = false;
@@ -2501,7 +2502,7 @@
wtoken.clientHidden = !visible;
wtoken.sendAppVisibilityToClients();
}
-
+
wtoken.willBeHidden = false;
if (wtoken.hidden == visible) {
final int N = wtoken.allAppWindows.size();
@@ -2509,9 +2510,9 @@
if (DEBUG_APP_TRANSITIONS) Log.v(
TAG, "Changing app " + wtoken + " hidden=" + wtoken.hidden
+ " performLayout=" + performLayout);
-
+
boolean runningAppAnimation = false;
-
+
if (transit != WindowManagerPolicy.TRANSIT_NONE) {
if (wtoken.animation == sDummyAnimation) {
wtoken.animation = null;
@@ -2522,7 +2523,7 @@
delayed = runningAppAnimation = true;
}
}
-
+
for (int i=0; i<N; i++) {
WindowState win = wtoken.allAppWindows.get(i);
if (win == wtoken.startingWindow) {
@@ -2532,7 +2533,7 @@
if (win.isAnimating()) {
delayed = true;
}
-
+
//Log.i(TAG, "Window " + win + ": vis=" + win.isVisible());
//win.dump(" ");
if (visible) {
@@ -2567,11 +2568,11 @@
swin.mPolicyVisibilityAfterAnim = false;
}
}
-
+
if (DEBUG_APP_TRANSITIONS) Log.v(TAG, "setTokenVisibilityLocked: " + wtoken
+ ": hidden=" + wtoken.hidden + " hiddenRequested="
+ wtoken.hiddenRequested);
-
+
if (changed && performLayout) {
mLayoutNeeded = true;
updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES);
@@ -2582,7 +2583,7 @@
if (wtoken.animation != null) {
delayed = true;
}
-
+
return delayed;
}
@@ -2609,7 +2610,7 @@
+ " hidden=" + wtoken.hidden
+ " hiddenRequested=" + wtoken.hiddenRequested, e);
}
-
+
// If we are preparing an app transition, then delay changing
// the visibility of this token until we execute that transition.
if (!mDisplayFrozen && mNextAppTransition != WindowManagerPolicy.TRANSIT_NONE) {
@@ -2618,7 +2619,7 @@
return;
}
wtoken.hiddenRequested = !visible;
-
+
if (DEBUG_APP_TRANSITIONS) Log.v(
TAG, "Setting dummy animation on: " + wtoken);
wtoken.setDummyAnimation();
@@ -2630,7 +2631,7 @@
wtoken.allDrawn = false;
wtoken.startingDisplayed = false;
wtoken.startingMoved = false;
-
+
if (wtoken.clientHidden) {
// In the case where we are making an app visible
// but holding off for a transition, we still need
@@ -2646,7 +2647,7 @@
}
return;
}
-
+
final long origId = Binder.clearCallingIdentity();
setTokenVisibilityLocked(wtoken, null, visible, WindowManagerPolicy.TRANSIT_NONE, true);
wtoken.updateReportedVisibilityLocked();
@@ -2687,7 +2688,7 @@
}
}
}
-
+
public void startAppFreezingScreenLocked(AppWindowToken wtoken,
int configChanges) {
if (DEBUG_ORIENTATION) {
@@ -2715,7 +2716,7 @@
}
}
}
-
+
public void startAppFreezingScreen(IBinder token, int configChanges) {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
"setAppFreezingScreen()")) {
@@ -2727,7 +2728,7 @@
if (DEBUG_ORIENTATION) Log.v(TAG, "Skipping set freeze of " + token);
return;
}
-
+
AppWindowToken wtoken = findAppWindowToken(token);
if (wtoken == null || wtoken.appToken == null) {
Log.w(TAG, "Attempted to freeze screen with non-existing app token: " + wtoken);
@@ -2738,7 +2739,7 @@
Binder.restoreCallingIdentity(origId);
}
}
-
+
public void stopAppFreezingScreen(IBinder token, boolean force) {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
"setAppFreezingScreen()")) {
@@ -2757,7 +2758,7 @@
Binder.restoreCallingIdentity(origId);
}
}
-
+
public void removeAppToken(IBinder token) {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
"removeAppToken()")) {
@@ -2806,7 +2807,7 @@
} else {
Log.w(TAG, "Attempted to remove non-existing app token: " + token);
}
-
+
if (!delayed && wtoken != null) {
wtoken.updateReportedVisibilityLocked();
}
@@ -2840,13 +2841,13 @@
Log.v(TAG, " #" + i + ": " + mAppTokens.get(i).token);
}
}
-
+
void dumpWindowsLocked() {
for (int i=mWindows.size()-1; i>=0; i--) {
Log.v(TAG, " #" + i + ": " + mWindows.get(i));
}
}
-
+
private int findWindowOffsetLocked(int tokenPos) {
final int NW = mWindows.size();
@@ -2917,7 +2918,7 @@
}
return index;
}
-
+
private final int reAddAppWindowsLocked(int index, WindowToken token) {
final int NW = token.windows.size();
for (int i=0; i<NW; i++) {
@@ -2944,7 +2945,7 @@
mAppTokens.add(index, wtoken);
if (DEBUG_REORDER) Log.v(TAG, "Moved " + token + " to " + index + ":");
if (DEBUG_REORDER) dumpAppTokensLocked();
-
+
final long origId = Binder.clearCallingIdentity();
if (DEBUG_REORDER) Log.v(TAG, "Removing windows in " + token + ":");
if (DEBUG_REORDER) dumpWindowsLocked();
@@ -3055,7 +3056,7 @@
// -------------------------------------------------------------
// Misc IWindowSession methods
// -------------------------------------------------------------
-
+
public void disableKeyguard(IBinder token, String tag) {
if (mContext.checkCallingPermission(android.Manifest.permission.DISABLE_KEYGUARD)
!= PackageManager.PERMISSION_GRANTED) {
@@ -3109,13 +3110,13 @@
public boolean inKeyguardRestrictedInputMode() {
return mPolicy.inKeyguardRestrictedKeyInputMode();
}
-
+
static float fixScale(float scale) {
if (scale < 0) scale = 0;
else if (scale > 20) scale = 20;
return Math.abs(scale);
}
-
+
public void setAnimationScale(int which, float scale) {
if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
"setAnimationScale()")) {
@@ -3129,11 +3130,11 @@
case 0: mWindowAnimationScale = fixScale(scale); break;
case 1: mTransitionAnimationScale = fixScale(scale); break;
}
-
+
// Persist setting
mH.obtainMessage(H.PERSIST_ANIMATION_SCALE).sendToTarget();
}
-
+
public void setAnimationScales(float[] scales) {
if (!checkCallingPermission(android.Manifest.permission.SET_ANIMATION_SCALE,
"setAnimationScale()")) {
@@ -3148,11 +3149,11 @@
mTransitionAnimationScale = fixScale(scales[1]);
}
}
-
+
// Persist setting
mH.obtainMessage(H.PERSIST_ANIMATION_SCALE).sendToTarget();
}
-
+
public float getAnimationScale(int which) {
switch (which) {
case 0: return mWindowAnimationScale;
@@ -3160,11 +3161,11 @@
}
return 0;
}
-
+
public float[] getAnimationScales() {
return new float[] { mWindowAnimationScale, mTransitionAnimationScale };
}
-
+
public int getSwitchState(int sw) {
if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
"getSwitchState()")) {
@@ -3172,7 +3173,7 @@
}
return KeyInputQueue.getSwitchState(sw);
}
-
+
public int getSwitchStateForDevice(int devid, int sw) {
if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
"getSwitchStateForDevice()")) {
@@ -3180,7 +3181,7 @@
}
return KeyInputQueue.getSwitchState(devid, sw);
}
-
+
public int getScancodeState(int sw) {
if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
"getScancodeState()")) {
@@ -3188,7 +3189,7 @@
}
return KeyInputQueue.getScancodeState(sw);
}
-
+
public int getScancodeStateForDevice(int devid, int sw) {
if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
"getScancodeStateForDevice()")) {
@@ -3196,7 +3197,7 @@
}
return KeyInputQueue.getScancodeState(devid, sw);
}
-
+
public int getKeycodeState(int sw) {
if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
"getKeycodeState()")) {
@@ -3204,7 +3205,7 @@
}
return KeyInputQueue.getKeycodeState(sw);
}
-
+
public int getKeycodeStateForDevice(int devid, int sw) {
if (!checkCallingPermission(android.Manifest.permission.READ_INPUT_STATE,
"getKeycodeStateForDevice()")) {
@@ -3212,11 +3213,11 @@
}
return KeyInputQueue.getKeycodeState(devid, sw);
}
-
+
public boolean hasKeys(int[] keycodes, boolean[] keyExists) {
return KeyInputQueue.hasKeys(keycodes, keyExists);
}
-
+
public void enableScreenAfterBoot() {
synchronized(mWindowMap) {
if (mSystemBooted) {
@@ -3224,10 +3225,10 @@
}
mSystemBooted = true;
}
-
+
performEnableScreen();
}
-
+
public void enableScreenIfNeededLocked() {
if (mDisplayEnabled) {
return;
@@ -3237,7 +3238,7 @@
}
mH.sendMessage(mH.obtainMessage(H.ENABLE_SCREEN));
}
-
+
public void performEnableScreen() {
synchronized(mWindowMap) {
if (mDisplayEnabled) {
@@ -3246,7 +3247,7 @@
if (!mSystemBooted) {
return;
}
-
+
// Don't enable the screen until all existing windows
// have been drawn.
final int N = mWindows.size();
@@ -3256,7 +3257,7 @@
return;
}
}
-
+
mDisplayEnabled = true;
if (false) {
Log.i(TAG, "ENABLING SCREEN!");
@@ -3279,21 +3280,21 @@
Log.e(TAG, "Boot completed: SurfaceFlinger is dead!");
}
}
-
+
mPolicy.enableScreenAfterBoot();
-
+
// Make sure the last requested orientation has been applied.
setRotationUnchecked(WindowManagerPolicy.USE_LAST_ROTATION, false,
mLastRotationFlags | Surface.FLAGS_ORIENTATION_ANIMATION_DISABLE);
}
-
+
public void setInTouchMode(boolean mode) {
synchronized(mWindowMap) {
mInTouchMode = mode;
}
}
- public void setRotation(int rotation,
+ public void setRotation(int rotation,
boolean alwaysSendConfiguration, int animFlags) {
if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
"setRotation()")) {
@@ -3302,18 +3303,18 @@
setRotationUnchecked(rotation, alwaysSendConfiguration, animFlags);
}
-
+
public void setRotationUnchecked(int rotation,
boolean alwaysSendConfiguration, int animFlags) {
if(DEBUG_ORIENTATION) Log.v(TAG,
"alwaysSendConfiguration set to "+alwaysSendConfiguration);
-
+
long origId = Binder.clearCallingIdentity();
boolean changed;
synchronized(mWindowMap) {
changed = setRotationUncheckedLocked(rotation, animFlags);
}
-
+
if (changed) {
sendNewConfiguration();
synchronized(mWindowMap) {
@@ -3324,10 +3325,10 @@
//update configuration ignoring orientation change
sendNewConfiguration();
}
-
+
Binder.restoreCallingIdentity(origId);
}
-
+
public boolean setRotationUncheckedLocked(int rotation, int animFlags) {
boolean changed;
if (rotation == WindowManagerPolicy.USE_LAST_ROTATION) {
@@ -3341,9 +3342,9 @@
mRotation, mDisplayEnabled);
if (DEBUG_ORIENTATION) Log.v(TAG, "new rotation is set to " + rotation);
changed = mDisplayEnabled && mRotation != rotation;
-
+
if (changed) {
- if (DEBUG_ORIENTATION) Log.v(TAG,
+ if (DEBUG_ORIENTATION) Log.v(TAG,
"Rotation changed to " + rotation
+ " from " + mRotation
+ " (forceApp=" + mForcedAppOrientation
@@ -3372,10 +3373,10 @@
}
}
} //end if changed
-
+
return changed;
}
-
+
public int getRotation() {
return mRotation;
}
@@ -3394,7 +3395,7 @@
}
}
};
-
+
synchronized (mWindowMap) {
try {
watcher.asBinder().linkToDeath(dr, 0);
@@ -3402,7 +3403,7 @@
} catch (RemoteException e) {
// Client died, no cleanup needed.
}
-
+
return mRotation;
}
}
@@ -3418,7 +3419,7 @@
* @see com.android.server.ViewServer#VIEW_SERVER_DEFAULT_PORT
*/
public boolean startViewServer(int port) {
- if ("1".equals(SystemProperties.get(SYSTEM_SECURE, "0"))) {
+ if (isSystemSecure()) {
return false;
}
@@ -3435,7 +3436,7 @@
try {
return mViewServer.start();
} catch (IOException e) {
- Log.w(TAG, "View server did not start");
+ Log.w(TAG, "View server did not start");
}
}
return false;
@@ -3450,6 +3451,11 @@
return false;
}
+ private boolean isSystemSecure() {
+ return "1".equals(SystemProperties.get(SYSTEM_SECURE, "1")) &&
+ "0".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
+ }
+
/**
* Stops the view server if it exists.
*
@@ -3459,7 +3465,7 @@
* @see com.android.server.ViewServer
*/
public boolean stopViewServer() {
- if ("1".equals(SystemProperties.get(SYSTEM_SECURE, "0"))) {
+ if (isSystemSecure()) {
return false;
}
@@ -3481,7 +3487,7 @@
* @see com.android.server.ViewServer
*/
public boolean isViewServerRunning() {
- if ("1".equals(SystemProperties.get(SYSTEM_SECURE, "0"))) {
+ if (isSystemSecure()) {
return false;
}
@@ -3502,7 +3508,7 @@
* @return False if an error occured, true otherwise.
*/
boolean viewServerListWindows(Socket client) {
- if ("1".equals(SystemProperties.get(SYSTEM_SECURE, "0"))) {
+ if (isSystemSecure()) {
return false;
}
@@ -3569,7 +3575,7 @@
* not indicate whether the command itself was successful.
*/
boolean viewServerWindowCommand(Socket client, String command, String parameters) {
- if ("1".equals(SystemProperties.get(SYSTEM_SECURE, "0"))) {
+ if (isSystemSecure()) {
return false;
}
@@ -3659,13 +3665,13 @@
} catch (RemoteException e) {
}
}
-
+
public Configuration computeNewConfiguration() {
synchronized (mWindowMap) {
return computeNewConfigurationLocked();
}
}
-
+
Configuration computeNewConfigurationLocked() {
Configuration config = new Configuration();
if (!computeNewConfigurationLocked(config)) {
@@ -3686,7 +3692,7 @@
}
return config;
}
-
+
boolean computeNewConfigurationLocked(Configuration config) {
if (mDisplay == null) {
return false;
@@ -3706,7 +3712,7 @@
mPolicy.adjustConfigurationLw(config);
return true;
}
-
+
// -------------------------------------------------------------
// Input Events and Focus Management
// -------------------------------------------------------------
@@ -3776,9 +3782,9 @@
Object targetObj = mKeyWaiter.waitForNextEventTarget(null, qev,
ev, true, false);
-
+
int action = ev.getAction();
-
+
if (action == MotionEvent.ACTION_UP) {
// let go of our target
mKeyWaiter.mMotionTarget = null;
@@ -3809,11 +3815,11 @@
ev.recycle();
return true;
}
-
+
WindowState target = (WindowState)targetObj;
-
+
final long eventTime = ev.getEventTime();
-
+
//Log.i(TAG, "Sending " + ev + " to " + target);
if (uid != 0 && uid != target.mSession.mUid) {
@@ -3830,8 +3836,8 @@
return false;
}
}
-
- if ((target.mAttrs.flags &
+
+ if ((target.mAttrs.flags &
WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES) != 0) {
//target wants to ignore fat touch events
boolean cheekPress = mPolicy.isCheekPressedAgainstScreen(ev);
@@ -3858,7 +3864,7 @@
if(mFatTouch) {
//two cases here
//an invalid down followed by 0 or moves(valid or invalid)
- //a valid down, invalid move, more moves. want to ignore till up
+ //a valid down, invalid move, more moves. want to ignore till up
returnFlag = true;
} else if(cheekPress) {
//valid down followed by invalid moves
@@ -3943,7 +3949,7 @@
mKeyWaiter.bindTargetWindowLocked(target);
}
}
-
+
// finally offset the event to the target's coordinate system and
// dispatch the event.
try {
@@ -3964,14 +3970,14 @@
}
return false;
}
-
+
/**
* @return Returns true if event was dispatched, false if it was dropped for any reason
*/
private boolean dispatchTrackball(QueuedEvent qev, MotionEvent ev, int pid, int uid) {
if (DEBUG_INPUT) Log.v(
TAG, "dispatchTrackball [" + ev.getAction() +"] <" + ev.getX() + ", " + ev.getY() + ">");
-
+
Object focusObj = mKeyWaiter.waitForNextEventTarget(null, qev,
ev, false, false);
if (focusObj == null) {
@@ -3989,9 +3995,9 @@
ev.recycle();
return true;
}
-
+
WindowState focus = (WindowState)focusObj;
-
+
if (uid != 0 && uid != focus.mSession.mUid) {
if (mContext.checkPermission(
android.Manifest.permission.INJECT_EVENTS, pid, uid)
@@ -4006,9 +4012,9 @@
return false;
}
}
-
+
final long eventTime = ev.getEventTime();
-
+
synchronized(mWindowMap) {
if (qev != null && ev.getAction() == MotionEvent.ACTION_MOVE) {
mKeyWaiter.bindTargetWindowLocked(focus,
@@ -4020,7 +4026,7 @@
mKeyWaiter.bindTargetWindowLocked(focus);
}
}
-
+
try {
focus.mClient.dispatchTrackball(ev, eventTime);
return true;
@@ -4033,10 +4039,10 @@
// removed.
}
}
-
+
return false;
}
-
+
/**
* @return Returns true if event was dispatched, false if it was dropped for any reason
*/
@@ -4052,9 +4058,9 @@
if (focusObj == mKeyWaiter.CONSUMED_EVENT_TOKEN) {
return true;
}
-
+
WindowState focus = (WindowState)focusObj;
-
+
if (DEBUG_INPUT) Log.v(
TAG, "Dispatching to " + focus + ": " + event);
@@ -4068,7 +4074,7 @@
return false;
}
}
-
+
synchronized(mWindowMap) {
mKeyWaiter.bindTargetWindowLocked(focus);
}
@@ -4076,7 +4082,7 @@
// NOSHIP extra state logging
mKeyWaiter.recordDispatchState(event, focus);
// END NOSHIP
-
+
try {
if (DEBUG_INPUT || DEBUG_FOCUS) {
Log.v(TAG, "Delivering key " + event.getKeyCode()
@@ -4093,10 +4099,10 @@
// removed.
}
}
-
+
return false;
}
-
+
public void pauseKeyDispatching(IBinder _token) {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
"pauseKeyDispatching()")) {
@@ -4135,11 +4141,11 @@
mKeyWaiter.setEventDispatchingLocked(enabled);
}
}
-
+
/**
* Injects a keystroke event into the UI.
- *
- * @param ev A motion event describing the keystroke action. (Be sure to use
+ *
+ * @param ev A motion event describing the keystroke action. (Be sure to use
* {@link SystemClock#uptimeMillis()} as the timebase.)
* @param sync If true, wait for the event to be completed before returning to the caller.
* @return Returns true if event was dispatched, false if it was dropped for any reason
@@ -4170,9 +4176,9 @@
/**
* Inject a pointer (touch) event into the UI.
- *
- * @param ev A motion event describing the pointer (touch) action. (As noted in
- * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use
+ *
+ * @param ev A motion event describing the pointer (touch) action. (As noted in
+ * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use
* {@link SystemClock#uptimeMillis()} as the timebase.)
* @param sync If true, wait for the event to be completed before returning to the caller.
* @return Returns true if event was dispatched, false if it was dropped for any reason
@@ -4182,14 +4188,14 @@
if (sync) {
mKeyWaiter.waitForNextEventTarget(null, null, null, false, true);
}
- return result;
+ return result;
}
-
+
/**
* Inject a trackball (navigation device) event into the UI.
- *
- * @param ev A motion event describing the trackball action. (As noted in
- * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use
+ *
+ * @param ev A motion event describing the trackball action. (As noted in
+ * {@link MotionEvent#obtain(long, long, int, float, float, int)}, be sure to use
* {@link SystemClock#uptimeMillis()} as the timebase.)
* @param sync If true, wait for the event to be completed before returning to the caller.
* @return Returns true if event was dispatched, false if it was dropped for any reason
@@ -4201,7 +4207,7 @@
}
return result;
}
-
+
private WindowState getFocusedWindow() {
synchronized (mWindowMap) {
return getFocusedWindowLocked();
@@ -4211,7 +4217,7 @@
private WindowState getFocusedWindowLocked() {
return mCurrentFocus;
}
-
+
/**
* This class holds the state for dispatching key events. This state
* is protected by the KeyWaiter instance, NOT by the window lock. You
@@ -4233,7 +4239,7 @@
private boolean wasFrozen;
private boolean focusPaused;
private WindowState curFocus;
-
+
DispatchState(KeyEvent theEvent, WindowState theFocus) {
focus = theFocus;
event = theEvent;
@@ -4255,7 +4261,7 @@
focusPaused = theFocus.mToken.paused;
}
}
-
+
public String toString() {
return "{{" + event + " to " + focus + " @ " + time
+ " lw=" + lastWin + " lb=" + lastBinder
@@ -4274,10 +4280,10 @@
public static final int RETURN_NOTHING = 0;
public static final int RETURN_PENDING_POINTER = 1;
public static final int RETURN_PENDING_TRACKBALL = 2;
-
+
final Object SKIP_TARGET_TOKEN = new Object();
final Object CONSUMED_EVENT_TOKEN = new Object();
-
+
private WindowState mLastWin = null;
private IBinder mLastBinder = null;
private boolean mFinished = true;
@@ -4285,10 +4291,10 @@
private boolean mEventDispatching = true;
private long mTimeToSwitch = 0;
/* package */ boolean mWasFrozen = false;
-
+
// Target of Motion events
WindowState mMotionTarget;
-
+
// Windows above the target who would like to receive an "outside"
// touch event for any down events outside of them.
WindowState mOutsideTouchTargets;
@@ -4333,9 +4339,9 @@
}
targetWin = (WindowState)target;
}
-
+
AppWindowToken targetApp = null;
-
+
// Now: is it okay to send the next event to this window?
synchronized (this) {
// First: did we come here based on the last window not
@@ -4344,7 +4350,7 @@
if (!targetIsNew && mLastWin == null) {
continue;
}
-
+
// We never dispatch events if not finished with the
// last one, or the display is frozen.
if (mFinished && !mDisplayFrozen) {
@@ -4363,7 +4369,7 @@
if (targetIsNew && !targetWin.mToken.paused) {
return targetWin;
}
-
+
// If we didn't find a target window, and there is no
// focused app window, then just eat the events.
} else if (mFocusedApp == null) {
@@ -4373,7 +4379,7 @@
return null;
}
}
-
+
if (DEBUG_INPUT) Log.v(
TAG, "Waiting for last key in " + mLastBinder
+ " target=" + targetWin
@@ -4384,10 +4390,10 @@
+ (targetWin != null ? targetWin.mToken.paused : false)
+ " mFocusedApp=" + mFocusedApp
+ " mCurrentFocus=" + mCurrentFocus);
-
+
targetApp = targetWin != null
? targetWin.mAppToken : mFocusedApp;
-
+
long curTimeout = keyDispatchingTimeout;
if (mTimeToSwitch != 0) {
long now = SystemClock.uptimeMillis();
@@ -4403,7 +4409,7 @@
curTimeout = switchTimeout;
}
}
-
+
try {
// after that continue
// processing keys, so we don't get stuck.
@@ -4467,7 +4473,7 @@
synchronized (this) {
if (abort && (mLastWin == targetWin || targetWin == null)) {
mFinished = true;
- if (mLastWin != null) {
+ if (mLastWin != null) {
if (DEBUG_INPUT) Log.v(TAG,
"Window " + mLastWin +
" timed out on key input");
@@ -4492,11 +4498,11 @@
}
}
}
-
+
Object findTargetWindow(KeyEvent nextKey, QueuedEvent qev,
MotionEvent nextMotion, boolean isPointerEvent) {
mOutsideTouchTargets = null;
-
+
if (nextKey != null) {
// Find the target window for a normal key event.
final int keycode = nextKey.getKeyCode();
@@ -4510,23 +4516,23 @@
+ nextKey);
return SKIP_TARGET_TOKEN;
}
-
+
// System.out.println("##### [" + SystemClock.uptimeMillis() + "] WindowManagerService.dispatchKey(" + keycode + ", " + down + ", " + repeatCount + ")");
-
+
WindowState focus = null;
synchronized(mWindowMap) {
focus = getFocusedWindowLocked();
}
-
+
wakeupIfNeeded(focus, LocalPowerManager.BUTTON_EVENT);
-
+
if (mPolicy.interceptKeyTi(focus,
keycode, nextKey.getMetaState(), down, repeatCount)) {
return CONSUMED_EVENT_TOKEN;
}
-
+
return focus;
-
+
} else if (!isPointerEvent) {
boolean dispatch = mKeyWaiter.checkShouldDispatchKey(-1);
if (!dispatch) {
@@ -4534,20 +4540,20 @@
+ nextMotion);
return SKIP_TARGET_TOKEN;
}
-
+
WindowState focus = null;
synchronized(mWindowMap) {
focus = getFocusedWindowLocked();
}
-
+
wakeupIfNeeded(focus, LocalPowerManager.BUTTON_EVENT);
return focus;
}
-
+
if (nextMotion == null) {
return SKIP_TARGET_TOKEN;
}
-
+
boolean dispatch = mKeyWaiter.checkShouldDispatchKey(
KeyEvent.KEYCODE_UNKNOWN);
if (!dispatch) {
@@ -4555,18 +4561,18 @@
+ nextMotion);
return SKIP_TARGET_TOKEN;
}
-
+
// Find the target window for a pointer event.
int action = nextMotion.getAction();
final float xf = nextMotion.getX();
final float yf = nextMotion.getY();
final long eventTime = nextMotion.getEventTime();
-
+
final boolean screenWasOff = qev != null
&& (qev.flags&WindowManagerPolicy.FLAG_BRIGHT_HERE) != 0;
-
+
WindowState target = null;
-
+
synchronized(mWindowMap) {
synchronized (this) {
if (action == MotionEvent.ACTION_DOWN) {
@@ -4579,12 +4585,12 @@
+ mMotionTarget);
mMotionTarget = null;
}
-
+
// ACTION_DOWN is special, because we need to lock next events to
// the window we'll land onto.
final int x = (int)xf;
final int y = (int)yf;
-
+
final ArrayList windows = mWindows;
final int N = windows.size();
WindowState topErrWindow = null;
@@ -4645,7 +4651,7 @@
}
break;
}
-
+
if ((flags & WindowManager.LayoutParams
.FLAG_WATCH_OUTSIDE_TOUCH) != 0) {
child.mNextOutsideTouch = mOutsideTouchTargets;
@@ -4662,18 +4668,18 @@
mMotionTarget = null;
}
}
-
+
target = mMotionTarget;
}
}
-
+
wakeupIfNeeded(target, eventType(nextMotion));
-
+
// Pointer events are a little different -- if there isn't a
// target found for any event, then just drop it.
return target != null ? target : SKIP_TARGET_TOKEN;
}
-
+
boolean checkShouldDispatchKey(int keycode) {
synchronized (this) {
if (mPolicy.isAppSwitchKeyTqTiLwLi(keycode)) {
@@ -4687,14 +4693,14 @@
return true;
}
}
-
+
void bindTargetWindowLocked(WindowState win,
int pendingWhat, QueuedEvent pendingMotion) {
synchronized (this) {
bindTargetWindowLockedLocked(win, pendingWhat, pendingMotion);
}
}
-
+
void bindTargetWindowLocked(WindowState win) {
synchronized (this) {
bindTargetWindowLockedLocked(win, RETURN_NOTHING, null);
@@ -4712,7 +4718,7 @@
releasePendingPointerLocked(s);
s.mPendingPointerMove = pendingMotion;
s.mPendingPointerWindow = win;
- if (DEBUG_INPUT) Log.v(TAG,
+ if (DEBUG_INPUT) Log.v(TAG,
"bindTargetToWindow " + s.mPendingPointerMove);
} else if (pendingWhat == RETURN_PENDING_TRACKBALL) {
releasePendingTrackballLocked(s);
@@ -4721,7 +4727,7 @@
}
}
}
-
+
void releasePendingPointerLocked(Session s) {
if (DEBUG_INPUT) Log.v(TAG,
"releasePendingPointer " + s.mPendingPointerMove);
@@ -4730,14 +4736,14 @@
s.mPendingPointerMove = null;
}
}
-
+
void releasePendingTrackballLocked(Session s) {
if (s.mPendingTrackballMove != null) {
mQueue.recycleEvent(s.mPendingTrackballMove);
s.mPendingTrackballMove = null;
}
}
-
+
MotionEvent finishedKey(Session session, IWindow client, boolean force,
int returnWhat) {
if (DEBUG_INPUT) Log.v(
@@ -4766,7 +4772,7 @@
session.mPendingTrackballMove = null;
session.mPendingTrackballWindow = null;
}
-
+
if (mLastBinder == client.asBinder()) {
if (DEBUG_INPUT) Log.v(
TAG, "finishedKey: last paused="
@@ -4782,7 +4788,7 @@
notifyAll();
}
}
-
+
if (qev != null) {
MotionEvent res = (MotionEvent)qev.event;
if (DEBUG_INPUT) Log.v(TAG,
@@ -4802,7 +4808,7 @@
notifyAll();
}
}
-
+
void handleNewWindowLocked(WindowState newWindow) {
if (!newWindow.canReceiveKeys()) {
return;
@@ -4903,7 +4909,7 @@
notifyAll();
}
}
-
+
void appSwitchComing() {
synchronized (this) {
// Don't wait for more than .5 seconds for app to finish
@@ -4916,13 +4922,13 @@
notifyAll();
}
}
-
+
private final void doFinishedKeyLocked(boolean doRecycle) {
if (mLastWin != null) {
releasePendingPointerLocked(mLastWin.mSession);
releasePendingTrackballLocked(mLastWin.mSession);
}
-
+
if (mLastWin == null || !mLastWin.mToken.paused
|| !mLastWin.isVisibleLw()) {
// If the current window has been paused, we aren't -really-
@@ -4938,7 +4944,7 @@
private class KeyQ extends KeyInputQueue
implements KeyInputQueue.FilterCallback {
PowerManager.WakeLock mHoldingScreen;
-
+
KeyQ() {
super(mContext);
PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
@@ -4952,7 +4958,7 @@
if (mPolicy.preprocessInputEventTq(event)) {
return true;
}
-
+
switch (event.type) {
case RawInputEvent.EV_KEY: {
// XXX begin hack
@@ -4972,11 +4978,11 @@
}
}
// XXX end hack
-
+
boolean screenIsOff = !mPowerManager.screenIsOn();
boolean screenIsDim = !mPowerManager.screenIsBright();
int actions = mPolicy.interceptKeyTq(event, !screenIsOff);
-
+
if ((actions & WindowManagerPolicy.ACTION_GO_TO_SLEEP) != 0) {
mPowerManager.goToSleep(event.when);
}
@@ -4991,7 +4997,7 @@
mPowerManager.userActivity(event.when, false,
LocalPowerManager.BUTTON_EVENT, false);
}
-
+
if ((actions & WindowManagerPolicy.ACTION_PASS_TO_USER) != 0) {
if (event.value != 0 && mPolicy.isAppSwitchKeyTqTiLwLi(event.keycode)) {
filterQueue(this);
@@ -5002,7 +5008,7 @@
return false;
}
}
-
+
case RawInputEvent.EV_REL: {
boolean screenIsOff = !mPowerManager.screenIsOn();
boolean screenIsDim = !mPowerManager.screenIsBright();
@@ -5019,7 +5025,7 @@
}
return true;
}
-
+
case RawInputEvent.EV_ABS: {
boolean screenIsOff = !mPowerManager.screenIsOn();
boolean screenIsDim = !mPowerManager.screenIsBright();
@@ -5036,7 +5042,7 @@
}
return true;
}
-
+
default:
return true;
}
@@ -5056,7 +5062,7 @@
return FILTER_KEEP;
}
}
-
+
/**
* Must be called with the main window manager lock held.
*/
@@ -5077,11 +5083,11 @@
mSafeMode = mPolicy.detectSafeMode();
return mSafeMode;
}
-
+
public void systemReady() {
mPolicy.systemReady();
}
-
+
private final class InputDispatcherThread extends Thread {
// Time to wait when there is nothing to do: 9999 seconds.
static final int LONG_WAIT=9999*1000;
@@ -5089,7 +5095,7 @@
public InputDispatcherThread() {
super("InputDispatcher");
}
-
+
@Override
public void run() {
while (true) {
@@ -5100,11 +5106,11 @@
}
}
}
-
+
private void process() {
android.os.Process.setThreadPriority(
android.os.Process.THREAD_PRIORITY_URGENT_DISPLAY);
-
+
// The last key event we saw
KeyEvent lastKey = null;
@@ -5112,12 +5118,12 @@
long lastKeyTime = SystemClock.uptimeMillis();
long nextKeyTime = lastKeyTime+LONG_WAIT;
- // How many successive repeats we generated
+ // How many successive repeats we generated
int keyRepeatCount = 0;
// Need to report that configuration has changed?
boolean configChanged = false;
-
+
while (true) {
long curTime = SystemClock.uptimeMillis();
@@ -5198,14 +5204,14 @@
mQueue.recycleEvent(ev);
break;
}
-
+
} else if (configChanged) {
configChanged = false;
sendNewConfiguration();
-
+
} else if (lastKey != null) {
curTime = SystemClock.uptimeMillis();
-
+
// Timeout occurred while key was down. If it is at or
// past the key repeat time, dispatch the repeat.
if (DEBUG_INPUT) Log.v(
@@ -5214,7 +5220,7 @@
if (curTime < nextKeyTime) {
continue;
}
-
+
lastKeyTime = nextKeyTime;
nextKeyTime = nextKeyTime + KEY_REPEAT_DELAY;
keyRepeatCount++;
@@ -5222,14 +5228,14 @@
TAG, "Key repeat: count=" + keyRepeatCount
+ ", next @ " + nextKeyTime);
dispatchKey(KeyEvent.changeTimeRepeat(lastKey, curTime, keyRepeatCount), 0, 0);
-
+
} else {
curTime = SystemClock.uptimeMillis();
-
+
lastKeyTime = curTime;
nextKeyTime = curTime + LONG_WAIT;
}
-
+
} catch (Exception e) {
Log.e(TAG,
"Input thread received uncaught exception: " + e, e);
@@ -5252,14 +5258,14 @@
SurfaceSession mSurfaceSession;
int mNumWindow = 0;
boolean mClientDead = false;
-
+
/**
* Current pointer move event being dispatched to client window... must
* hold key lock to access.
*/
QueuedEvent mPendingPointerMove;
WindowState mPendingPointerWindow;
-
+
/**
* Current trackball move event being dispatched to client window... must
* hold key lock to access.
@@ -5279,7 +5285,7 @@
sb.append(mUid);
sb.append("}");
mStringName = sb.toString();
-
+
synchronized (mWindowMap) {
if (mInputMethodManager == null && mHaveInputMethods) {
IBinder b = ServiceManager.getService(
@@ -5310,7 +5316,7 @@
Binder.restoreCallingIdentity(ident);
}
}
-
+
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
@@ -5344,11 +5350,11 @@
int viewVisibility, Rect outContentInsets) {
return addWindow(this, window, attrs, viewVisibility, outContentInsets);
}
-
+
public void remove(IWindow window) {
removeWindow(this, window);
}
-
+
public int relayout(IWindow window, WindowManager.LayoutParams attrs,
int requestedWidth, int requestedHeight, int viewFlags,
boolean insetsPending, Rect outFrame, Rect outContentInsets,
@@ -5357,21 +5363,21 @@
requestedWidth, requestedHeight, viewFlags, insetsPending,
outFrame, outContentInsets, outVisibleInsets, outSurface);
}
-
+
public void setTransparentRegion(IWindow window, Region region) {
setTransparentRegionWindow(this, window, region);
}
-
+
public void setInsets(IWindow window, int touchableInsets,
Rect contentInsets, Rect visibleInsets) {
setInsetsWindow(this, window, touchableInsets, contentInsets,
visibleInsets);
}
-
+
public void getDisplayFrame(IWindow window, Rect outDisplayFrame) {
getWindowDisplayFrame(this, window, outDisplayFrame);
}
-
+
public void finishDrawing(IWindow window) {
if (localLOGV) Log.v(
TAG, "IWindow finishDrawing called for " + window);
@@ -5391,7 +5397,7 @@
return mKeyWaiter.finishedKey(this, window, false,
KeyWaiter.RETURN_PENDING_POINTER);
}
-
+
public MotionEvent getPendingTrackballMove(IWindow window) {
if (localLOGV) Log.v(
TAG, "IWindow getPendingMotionEvent called for " + window);
@@ -5423,7 +5429,7 @@
}
}
}
-
+
void windowAddedLocked() {
if (mSurfaceSession == null) {
if (localLOGV) Log.v(
@@ -5438,7 +5444,7 @@
mNumWindow--;
killSessionLocked();
}
-
+
void killSessionLocked() {
if (mNumWindow <= 0 && mClientDead) {
mSessions.remove(this);
@@ -5457,7 +5463,7 @@
}
}
}
-
+
void dump(PrintWriter pw, String prefix) {
pw.print(prefix); pw.print("mNumWindow="); pw.print(mNumWindow);
pw.print(" mClientDead="); pw.print(mClientDead);
@@ -5518,11 +5524,11 @@
boolean mHaveFrame;
WindowState mNextOutsideTouch;
-
+
// Actual frame shown on-screen (may be modified by animation)
final Rect mShownFrame = new Rect();
final Rect mLastShownFrame = new Rect();
-
+
/**
* Insets that determine the actually visible area
*/
@@ -5542,19 +5548,19 @@
* given internal insets before laying out other windows based on it.
*/
boolean mGivenInsetsPending;
-
+
/**
* These are the content insets that were given during layout for
* this window, to be applied to windows behind it.
*/
final Rect mGivenContentInsets = new Rect();
-
+
/**
* These are the visible insets that were given during layout for
* this window, to be applied to windows behind it.
*/
final Rect mGivenVisibleInsets = new Rect();
-
+
/**
* Flag indicating whether the touchable region should be adjusted by
* the visible insets; if false the area outside the visible insets is
@@ -5562,7 +5568,7 @@
* tests.
*/
int mTouchableInsets = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;
-
+
// Current transformation being applied.
float mDsDx=1, mDtDx=0, mDsDy=0, mDtDy=1;
float mLastDsDx=1, mLastDtDx=0, mLastDsDy=0, mLastDtDy=1;
@@ -5601,7 +5607,7 @@
// where we don't yet have a surface, but should have one soon, so
// we can give the window focus before waiting for the relayout.
boolean mRelayoutCalled;
-
+
// This is set after the Surface has been created but before the
// window has been drawn. During this time the surface is hidden.
boolean mDrawPending;
@@ -5616,7 +5622,7 @@
// to delay showing the surface until all windows in a token are ready
// to be shown.
boolean mReadyToShow;
-
+
// Set when the window has been shown in the screen the first time.
boolean mHasDrawn;
@@ -5625,17 +5631,17 @@
// Currently on the mDestroySurface list?
boolean mDestroying;
-
+
// Completely remove from window manager after exit animation?
boolean mRemoveOnExit;
// Set when the orientation is changing and this window has not yet
// been updated for the new orientation.
boolean mOrientationChanging;
-
+
// Is this window now (or just being) removed?
boolean mRemoved;
-
+
WindowState(Session s, IWindow c, WindowToken token,
WindowState attachedWindow, WindowManager.LayoutParams a,
int viewVisibility) {
@@ -5661,7 +5667,7 @@
return;
}
mDeathRecipient = deathRecipient;
-
+
if ((mAttrs.type >= FIRST_SUB_WINDOW &&
mAttrs.type <= LAST_SUB_WINDOW)) {
// The multiplier here is to reserve space for multiple
@@ -5737,7 +5743,7 @@
w = mAttrs.width == mAttrs.FILL_PARENT ? pw : mRequestedWidth;
h = mAttrs.height== mAttrs.FILL_PARENT ? ph : mRequestedHeight;
}
-
+
final Rect container = mContainingFrame;
container.set(pf);
@@ -5746,12 +5752,12 @@
final Rect content = mContentFrame;
content.set(cf);
-
+
final Rect visible = mVisibleFrame;
visible.set(vf);
-
+
final Rect frame = mFrame;
-
+
//System.out.println("In: w=" + w + " h=" + h + " container=" +
// container + " x=" + mAttrs.x + " y=" + mAttrs.y);
@@ -5763,7 +5769,7 @@
// Now make sure the window fits in the overall display.
Gravity.applyDisplay(mAttrs.gravity, df, frame);
-
+
// Make sure the content and visible frames are inside of the
// final window frame.
if (content.left < frame.left) content.left = frame.left;
@@ -5774,19 +5780,19 @@
if (visible.top < frame.top) visible.top = frame.top;
if (visible.right > frame.right) visible.right = frame.right;
if (visible.bottom > frame.bottom) visible.bottom = frame.bottom;
-
+
final Rect contentInsets = mContentInsets;
contentInsets.left = content.left-frame.left;
contentInsets.top = content.top-frame.top;
contentInsets.right = frame.right-content.right;
contentInsets.bottom = frame.bottom-content.bottom;
-
+
final Rect visibleInsets = mVisibleInsets;
visibleInsets.left = visible.left-frame.left;
visibleInsets.top = visible.top-frame.top;
visibleInsets.right = frame.right-visible.right;
visibleInsets.bottom = frame.bottom-visible.bottom;
-
+
if (localLOGV) {
//if ("com.google.android.youtube".equals(mAttrs.packageName)
// && mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
@@ -5799,7 +5805,7 @@
//}
}
}
-
+
public Rect getFrameLw() {
return mFrame;
}
@@ -5827,11 +5833,11 @@
public Rect getGivenContentInsetsLw() {
return mGivenContentInsets;
}
-
+
public Rect getGivenVisibleInsetsLw() {
return mGivenVisibleInsets;
}
-
+
public WindowManager.LayoutParams getAttrs() {
return mAttrs;
}
@@ -5839,7 +5845,7 @@
public int getSurfaceLayer() {
return mLayer;
}
-
+
public IApplicationToken getAppToken() {
return mAppToken != null ? mAppToken.appToken : null;
}
@@ -5873,7 +5879,7 @@
mAnimation = null;
}
}
-
+
Surface createSurfaceLocked() {
if (mSurface == null) {
mDrawPending = true;
@@ -5913,7 +5919,7 @@
try {
mSurface = new Surface(
- mSession.mSurfaceSession, mSession.mPid,
+ mSession.mSurfaceSession, mSession.mPid,
0, w, h, mAttrs.format, flags);
} catch (Surface.OutOfResourcesException e) {
Log.w(TAG, "OutOfResourcesException creating surface");
@@ -5923,7 +5929,7 @@
Log.e(TAG, "Exception creating surface", e);
return null;
}
-
+
if (localLOGV) Log.v(
TAG, "Got surface: " + mSurface
+ ", set left=" + mFrame.left + " top=" + mFrame.top
@@ -5960,7 +5966,7 @@
}
return mSurface;
}
-
+
void destroySurfaceLocked() {
// Window is no longer on-screen, so can no longer receive
// key events... if we were waiting for it to finish
@@ -5973,7 +5979,7 @@
if (mAppToken != null && this == mAppToken.startingWindow) {
mAppToken.startingDisplayed = false;
}
-
+
if (localLOGV) Log.v(
TAG, "Window " + this
+ " destroying surface " + mSurface + ", session " + mSession);
@@ -6063,7 +6069,7 @@
enableScreenIfNeededLocked();
applyEnterAnimationLocked(this);
-
+
int i = mChildWindows.size();
while (i > 0) {
i--;
@@ -6073,7 +6079,7 @@
c.performShowLocked();
}
}
-
+
if (mAttrs.type != TYPE_APPLICATION_STARTING
&& mAppToken != null) {
mAppToken.firstWindowDrawn = true;
@@ -6089,13 +6095,13 @@
}
return true;
}
-
+
// This must be called while inside a transaction. Returns true if
// there is more animation to run.
boolean stepAnimationLocked(long currentTime, int dw, int dh) {
if (!mDisplayFrozen) {
// We will run animations as long as the display isn't frozen.
-
+
if (!mDrawPending && !mCommitDrawPending && mAnimation != null) {
mHasTransformation = true;
mHasLocalTransformation = true;
@@ -6153,7 +6159,7 @@
mLocalAnimating = true;
mAnimation = null;
}
-
+
if (!mAnimating && !mLocalAnimating) {
return false;
}
@@ -6162,7 +6168,7 @@
TAG, "Animation done in " + this + ": exiting=" + mExiting
+ ", reportedVisible="
+ (mAppToken != null ? mAppToken.reportedVisible : false));
-
+
mAnimating = false;
mLocalAnimating = false;
mAnimation = null;
@@ -6186,7 +6192,7 @@
mFinishedStarting.add(mAppToken);
mH.sendEmptyMessage(H.FINISHED_STARTING);
}
-
+
finishExit();
if (mAppToken != null) {
@@ -6202,16 +6208,16 @@
+ ": exiting=" + mExiting
+ " remove=" + mRemoveOnExit
+ " windowAnimating=" + isWindowAnimating());
-
+
final int N = mChildWindows.size();
for (int i=0; i<N; i++) {
((WindowState)mChildWindows.get(i)).finishExit();
}
-
+
if (!mExiting) {
return;
}
-
+
if (isWindowAnimating()) {
return;
}
@@ -6238,7 +6244,7 @@
mRemoveOnExit = false;
}
}
-
+
boolean isIdentityMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
if (dsdx < .99999f || dsdx > 1.00001f) return false;
if (dtdy < .99999f || dtdy > 1.00001f) return false;
@@ -6246,7 +6252,7 @@
if (dsdy < -.000001f || dsdy > .000001f) return false;
return true;
}
-
+
void computeShownFrameLocked() {
final boolean selfTransformation = mHasLocalTransformation;
Transformation attachedTransformation =
@@ -6257,7 +6263,7 @@
? mAppToken.transformation : null;
if (selfTransformation || attachedTransformation != null
|| appTransformation != null) {
- // cache often used attributes locally
+ // cache often used attributes locally
final Rect frame = mFrame;
final float tmpFloats[] = mTmpFloats;
final Matrix tmpMatrix = mTmpMatrix;
@@ -6279,7 +6285,7 @@
// Here we must not transform the position of the surface
// since it is already included in the transformation.
//Log.i(TAG, "Transform: " + matrix);
-
+
tmpMatrix.getValues(tmpFloats);
mDsDx = tmpFloats[Matrix.MSCALE_X];
mDtDx = tmpFloats[Matrix.MSKEW_X];
@@ -6314,14 +6320,14 @@
} else {
//Log.i(TAG, "Not applying alpha transform");
}
-
+
if (localLOGV) Log.v(
TAG, "Continuing animation in " + this +
": " + mShownFrame +
", alpha=" + mTransformation.getAlpha());
return;
}
-
+
mShownFrame.set(mFrame);
mShownAlpha = mAlpha;
mDsDx = 1;
@@ -6329,7 +6335,7 @@
mDsDy = 0;
mDtDy = 1;
}
-
+
/**
* Is this window visible? It is not visible if there is no
* surface, or we are in the process of running an exit animation
@@ -6392,7 +6398,7 @@
&& (!mAttachedHidden || mAnimating);
}
}
-
+
/**
* Like isOnScreen(), but we don't return true if the window is part
* of a transition that has not yet been started.
@@ -6411,7 +6417,7 @@
final AppWindowToken atoken = mAppToken;
return mAnimation != null
|| (attached != null && attached.mAnimation != null)
- || (atoken != null &&
+ || (atoken != null &&
(atoken.animation != null
|| atoken.inPendingTransaction));
}
@@ -6453,7 +6459,7 @@
}
return false;
}
-
+
boolean isFullscreenOpaque(int screenWidth, int screenHeight) {
if (mAttrs.format != PixelFormat.OPAQUE || mSurface == null
|| mAnimation != null || mDrawPending || mCommitDrawPending) {
@@ -6545,7 +6551,7 @@
void dump(PrintWriter pw, String prefix) {
StringBuilder sb = new StringBuilder(64);
-
+
pw.print(prefix); pw.print("mSession="); pw.print(mSession);
pw.print(" mClient="); pw.println(mClient.asBinder());
pw.print(prefix); pw.print("mAttrs="); pw.println(mAttrs);
@@ -6661,7 +6667,7 @@
+ " " + mAttrs.getTitle() + " paused=" + mToken.paused + "}";
}
}
-
+
// -------------------------------------------------------------
// Window Token State
// -------------------------------------------------------------
@@ -6672,17 +6678,17 @@
// The type of window this token is for, as per WindowManager.LayoutParams.
final int windowType;
-
+
// Set if this token was explicitly added by a client, so should
// not be removed when all windows are removed.
final boolean explicit;
-
+
// For printing.
String stringName;
-
+
// If this is an AppWindowToken, this is non-null.
AppWindowToken appWindowToken;
-
+
// All of the windows associated with this token.
final ArrayList<WindowState> windows = new ArrayList<WindowState>();
@@ -6733,7 +6739,7 @@
int groupId = -1;
boolean appFullscreen;
int requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
-
+
// These are used for determining when all windows associated with
// an activity have been drawn, so they can be made visible together
// at the same time.
@@ -6742,20 +6748,20 @@
int numDrawnWindows;
boolean inPendingTransaction;
boolean allDrawn;
-
+
// Is this token going to be hidden in a little while? If so, it
// won't be taken into account for setting the screen orientation.
boolean willBeHidden;
-
+
// Is this window's surface needed? This is almost like hidden, except
// it will sometimes be true a little earlier: when the token has
// been shown, but is still waiting for its app transition to execute
// before making its windows shown.
boolean hiddenRequested;
-
+
// Have we told the window clients to hide themselves?
boolean clientHidden;
-
+
// Last visibility state we reported to the app token.
boolean reportedVisible;
@@ -6764,16 +6770,16 @@
// Have we been asked to have this token keep the screen frozen?
boolean freezingScreen;
-
+
boolean animating;
Animation animation;
boolean hasTransformation;
final Transformation transformation = new Transformation();
-
+
// Offset to the window of all layers in the token, for use by
// AppWindowToken animations.
int animLayerAdjustment;
-
+
// Information about an application starting window if displayed.
StartingData startingData;
WindowState startingWindow;
@@ -6788,7 +6794,7 @@
appWindowToken = this;
appToken = _token;
}
-
+
public void setAnimation(Animation anim) {
if (localLOGV) Log.v(
TAG, "Setting animation in " + this + ": " + anim);
@@ -6803,13 +6809,13 @@
} else if (zorder == Animation.ZORDER_BOTTOM) {
adj = -TYPE_LAYER_OFFSET;
}
-
+
if (animLayerAdjustment != adj) {
animLayerAdjustment = adj;
updateLayers();
}
}
-
+
public void setDummyAnimation() {
if (animation == null) {
if (localLOGV) Log.v(
@@ -6824,7 +6830,7 @@
animating = true;
}
}
-
+
void updateLayers() {
final int N = allAppWindows.size();
final int adj = animLayerAdjustment;
@@ -6838,7 +6844,7 @@
}
}
}
-
+
void sendAppVisibilityToClients() {
final int N = allAppWindows.size();
for (int i=0; i<N; i++) {
@@ -6855,7 +6861,7 @@
}
}
}
-
+
void showAllWindowsLocked() {
final int NW = allAppWindows.size();
for (int i=0; i<NW; i++) {
@@ -6865,12 +6871,12 @@
w.performShowLocked();
}
}
-
+
// This must be called while inside a transaction.
boolean stepAnimationLocked(long currentTime, int dw, int dh) {
if (!mDisplayFrozen) {
// We will run animations as long as the display isn't frozen.
-
+
if (animation == sDummyAnimation) {
// This guy is going to animate, but not yet. For now count
// it is not animating for purposes of scheduling transactions;
@@ -6878,7 +6884,7 @@
// a real animation and the next call will execute normally.
return false;
}
-
+
if ((allDrawn || animating || startingDisplayed) && animation != null) {
if (!animating) {
if (DEBUG_ANIM) Log.v(
@@ -6914,7 +6920,7 @@
}
hasTransformation = false;
-
+
if (!animating) {
return false;
}
@@ -6924,7 +6930,7 @@
if (mInputMethodTarget != null && mInputMethodTarget.mAppToken == this) {
moveInputMethodWindowsIfNeededLocked(true);
}
-
+
if (DEBUG_ANIM) Log.v(
TAG, "Animation done in " + this
+ ": reportedVisible=" + reportedVisible);
@@ -6934,13 +6940,13 @@
animLayerAdjustment = 0;
updateLayers();
}
-
+
final int N = windows.size();
for (int i=0; i<N; i++) {
((WindowState)windows.get(i)).finishExit();
}
updateReportedVisibilityLocked();
-
+
return false;
}
@@ -6948,11 +6954,11 @@
if (appToken == null) {
return;
}
-
+
int numInteresting = 0;
int numVisible = 0;
boolean nowGone = true;
-
+
if (DEBUG_VISIBILITY) Log.v(TAG, "Update reported visibility: " + this);
final int N = allAppWindows.size();
for (int i=0; i<N; i++) {
@@ -6986,7 +6992,7 @@
nowGone = false;
}
}
-
+
boolean nowVisible = numInteresting > 0 && numVisible >= numInteresting;
if (DEBUG_VISIBILITY) Log.v(TAG, "VIS " + this + ": interesting="
+ numInteresting + " visible=" + numVisible);
@@ -7003,7 +7009,7 @@
mH.sendMessage(m);
}
}
-
+
void dump(PrintWriter pw, String prefix) {
super.dump(pw, prefix);
if (appToken != null) {
@@ -7068,7 +7074,7 @@
return stringName;
}
}
-
+
public static WindowManager.LayoutParams findAnimations(
ArrayList<AppWindowToken> order,
ArrayList<AppWindowToken> tokenList1,
@@ -7076,7 +7082,7 @@
// We need to figure out which animation to use...
WindowManager.LayoutParams animParams = null;
int animSrc = 0;
-
+
//Log.i(TAG, "Looking for animations...");
for (int i=order.size()-1; i>=0; i--) {
AppWindowToken wtoken = order.get(i);
@@ -7105,10 +7111,10 @@
}
}
}
-
+
return animParams;
}
-
+
// -------------------------------------------------------------
// DummyAnimation
// -------------------------------------------------------------
@@ -7122,7 +7128,7 @@
}
}
static final Animation sDummyAnimation = new DummyAnimation();
-
+
// -------------------------------------------------------------
// Async Handler
// -------------------------------------------------------------
@@ -7133,7 +7139,7 @@
final CharSequence nonLocalizedLabel;
final int labelRes;
final int icon;
-
+
StartingData(String _pkg, int _theme, CharSequence _nonLocalizedLabel,
int _labelRes, int _icon) {
pkg = _pkg;
@@ -7160,19 +7166,19 @@
public static final int ENABLE_SCREEN = 16;
public static final int APP_FREEZE_TIMEOUT = 17;
public static final int COMPUTE_AND_SEND_NEW_CONFIGURATION = 18;
-
+
private Session mLastReportedHold;
-
+
public H() {
}
-
+
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case REPORT_FOCUS_CHANGE: {
WindowState lastFocus;
WindowState newFocus;
-
+
synchronized(mWindowMap) {
lastFocus = mLastFocus;
newFocus = mCurrentFocus;
@@ -7216,7 +7222,7 @@
case REPORT_LOSING_FOCUS: {
ArrayList<WindowState> losers;
-
+
synchronized(mWindowMap) {
losers = mLosingFocus;
mLosingFocus = new ArrayList<WindowState>();
@@ -7248,10 +7254,10 @@
// Animation has been canceled... do nothing.
return;
}
-
+
if (DEBUG_STARTING_WINDOW) Log.v(TAG, "Add starting "
+ wtoken + ": pkg=" + sd.pkg);
-
+
View view = null;
try {
view = mPolicy.addStartingWindow(
@@ -7378,7 +7384,7 @@
} catch (RemoteException ex) {
}
} break;
-
+
case WINDOW_FREEZE_TIMEOUT: {
synchronized (mWindowMap) {
Log.w(TAG, "Window freeze timeout expired.");
@@ -7395,7 +7401,7 @@
}
break;
}
-
+
case HOLD_SCREEN_CHANGED: {
Session oldHold;
Session newHold;
@@ -7404,7 +7410,7 @@
newHold = (Session)msg.obj;
mLastReportedHold = newHold;
}
-
+
if (oldHold != newHold) {
try {
if (oldHold != null) {
@@ -7422,7 +7428,7 @@
}
break;
}
-
+
case APP_TRANSITION_TIMEOUT: {
synchronized (mWindowMap) {
if (mNextAppTransition != WindowManagerPolicy.TRANSIT_NONE) {
@@ -7435,7 +7441,7 @@
}
break;
}
-
+
case PERSIST_ANIMATION_SCALE: {
Settings.System.putFloat(mContext.getContentResolver(),
Settings.System.WINDOW_ANIMATION_SCALE, mWindowAnimationScale);
@@ -7443,7 +7449,7 @@
Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
break;
}
-
+
case FORCE_GC: {
synchronized(mWindowMap) {
if (mAnimationPending) {
@@ -7463,12 +7469,12 @@
Runtime.getRuntime().gc();
break;
}
-
+
case ENABLE_SCREEN: {
performEnableScreen();
break;
}
-
+
case APP_FREEZE_TIMEOUT: {
synchronized (mWindowMap) {
Log.w(TAG, "App freeze timeout expired.");
@@ -7484,14 +7490,14 @@
}
break;
}
-
+
case COMPUTE_AND_SEND_NEW_CONFIGURATION: {
if (updateOrientationFromAppTokens(null, null) != null) {
sendNewConfiguration();
}
break;
}
-
+
}
}
}
@@ -7525,7 +7531,7 @@
}
return false;
}
-
+
// -------------------------------------------------------------
// Internals
// -------------------------------------------------------------
@@ -7533,7 +7539,7 @@
final WindowState windowForClientLocked(Session session, IWindow client) {
return windowForClientLocked(session, client.asBinder());
}
-
+
final WindowState windowForClientLocked(Session session, IBinder client) {
WindowState win = mWindowMap.get(client);
if (localLOGV) Log.v(
@@ -7558,7 +7564,7 @@
int curBaseLayer = 0;
int curLayer = 0;
int i;
-
+
for (i=0; i<N; i++) {
WindowState w = (WindowState)mWindows.get(i);
if (w.mBaseLayer == curBaseLayer || w.mIsImWindow) {
@@ -7614,11 +7620,11 @@
}
}
}
-
+
mInLayout = true;
try {
performLayoutAndPlaceSurfacesLockedInner(recoveringMemory);
-
+
int i = mPendingRemove.size()-1;
if (i >= 0) {
while (i >= 0) {
@@ -7654,7 +7660,7 @@
int i;
// FIRST LOOP: Perform a layout, if needed.
-
+
while (mLayoutNeeded) {
mPolicy.beginLayoutLw(dw, dh);
@@ -7689,7 +7695,7 @@
}
}
}
-
+
// Now perform layout of attached windows, which usually
// depend on the position of the window they are attached to.
// XXX does not deal with windows that are attached to windows
@@ -7720,7 +7726,7 @@
}
}
}
-
+
private final void performLayoutAndPlaceSurfacesLockedInner(
boolean recoveringMemory) {
final long currentTime = SystemClock.uptimeMillis();
@@ -7732,11 +7738,11 @@
// FIRST LOOP: Perform a layout, if needed.
performLayoutLockedInner();
-
+
if (mFxSession == null) {
mFxSession = new SurfaceSession();
}
-
+
if (SHOW_TRANSACTIONS) Log.i(TAG, ">>> OPEN TRANSACTION");
// Initialize state of exiting tokens.
@@ -8060,7 +8066,7 @@
!w.mLastContentInsets.equals(w.mContentInsets);
w.mVisibleInsetsChanged =
!w.mLastVisibleInsets.equals(w.mVisibleInsets);
- if (!w.mLastFrame.equals(w.mFrame)
+ if (!w.mLastFrame.equals(w.mFrame)
|| w.mContentInsetsChanged
|| w.mVisibleInsetsChanged) {
w.mLastFrame.set(w.mFrame);
@@ -8082,7 +8088,7 @@
w.mAppToken.allDrawn = false;
}
}
- if (DEBUG_ORIENTATION) Log.v(TAG,
+ if (DEBUG_ORIENTATION) Log.v(TAG,
"Resizing window " + w + " to " + w.mFrame);
mResizingWindows.add(w);
} else if (w.mOrientationChanging) {
@@ -8272,7 +8278,7 @@
if (SHOW_TRANSACTIONS) Log.i(TAG, " DIM "
+ mDimSurface + ": CREATE");
try {
- mDimSurface = new Surface(mFxSession, 0,
+ mDimSurface = new Surface(mFxSession, 0,
-1, 16, 16,
PixelFormat.OPAQUE,
Surface.FX_SURFACE_DIM);
@@ -8327,7 +8333,7 @@
if (SHOW_TRANSACTIONS) Log.i(TAG, " BLUR "
+ mBlurSurface + ": CREATE");
try {
- mBlurSurface = new Surface(mFxSession, 0,
+ mBlurSurface = new Surface(mFxSession, 0,
-1, 16, 16,
PixelFormat.OPAQUE,
Surface.FX_SURFACE_BLUR);
@@ -8381,7 +8387,7 @@
} else {
more = false;
}
-
+
// Do we need to continue animating?
if (more) {
if (SHOW_TRANSACTIONS) Log.i(TAG, " DIM "
@@ -8407,7 +8413,7 @@
}
}
}
-
+
if (!blurring && mBlurShown) {
if (SHOW_TRANSACTIONS) Log.i(TAG, " BLUR " + mBlurSurface
+ ": HIDE");
@@ -8425,7 +8431,7 @@
}
Surface.closeTransaction();
-
+
if (DEBUG_ORIENTATION && mDisplayFrozen) Log.v(TAG,
"With display frozen, orientationChangeComplete="
+ orientationChangeComplete);
@@ -8438,7 +8444,7 @@
stopFreezingDisplayLocked();
}
}
-
+
i = mResizingWindows.size();
if (i > 0) {
do {
@@ -8456,7 +8462,7 @@
} while (i > 0);
mResizingWindows.clear();
}
-
+
// Destroy the surface of any windows that are no longer visible.
i = mDestroySurface.size();
if (i > 0) {
@@ -8515,13 +8521,13 @@
mH.sendMessageDelayed(mH.obtainMessage(H.ANIMATE), delay);
}
}
-
+
/**
* Have the surface flinger show a surface, robustly dealing with
* error conditions. In particular, if there is not enough memory
* to show the surface, then we will try to get rid of other surfaces
* in order to succeed.
- *
+ *
* @return Returns true if the surface was successfully shown.
*/
boolean showSurfaceRobustlyLocked(WindowState win) {
@@ -8533,22 +8539,22 @@
} catch (RuntimeException e) {
Log.w(TAG, "Failure showing surface " + win.mSurface + " in " + win);
}
-
+
reclaimSomeSurfaceMemoryLocked(win, "show");
-
+
return false;
}
-
+
void reclaimSomeSurfaceMemoryLocked(WindowState win, String operation) {
final Surface surface = win.mSurface;
-
+
EventLog.writeEvent(LOG_WM_NO_SURFACE_MEMORY, win.toString(),
win.mSession.mPid, operation);
-
+
if (mForceRemoves == null) {
mForceRemoves = new ArrayList<WindowState>();
}
-
+
long callingIdentity = Binder.clearCallingIdentity();
try {
// There was some problem... first, do a sanity check of the
@@ -8582,7 +8588,7 @@
}
}
}
-
+
boolean killedApps = false;
if (!leakedSurface) {
Log.w(TAG, "No leaked surfaces; killing applicatons!");
@@ -8606,7 +8612,7 @@
}
}
}
-
+
if (leakedSurface || killedApps) {
// We managed to reclaim some memory, so get rid of the trouble
// surface and ask the app to request another one.
@@ -8615,7 +8621,7 @@
surface.clear();
win.mSurface = null;
}
-
+
try {
win.mClient.dispatchGetNewSurface();
} catch (RemoteException e) {
@@ -8625,7 +8631,7 @@
Binder.restoreCallingIdentity(callingIdentity);
}
}
-
+
private boolean updateFocusedWindowLocked(int mode) {
WindowState newFocus = computeFocusedWindowLocked();
if (mCurrentFocus != newFocus) {
@@ -8638,7 +8644,7 @@
final WindowState oldFocus = mCurrentFocus;
mCurrentFocus = newFocus;
mLosingFocus.remove(newFocus);
-
+
final WindowState imWindow = mInputMethodWindow;
if (newFocus != imWindow && oldFocus != imWindow) {
if (moveInputMethodWindowsIfNeededLocked(
@@ -8654,7 +8660,7 @@
assignLayersLocked();
}
}
-
+
if (newFocus != null && mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS) {
mKeyWaiter.handleNewWindowLocked(newFocus);
}
@@ -8682,13 +8688,13 @@
+ ", canReceive=" + win.canReceiveKeys());
AppWindowToken thisApp = win.mAppToken;
-
+
// If this window's application has been removed, just skip it.
if (thisApp != null && thisApp.removed) {
i--;
continue;
}
-
+
// If there is a focused app, don't allow focus to go to any
// windows below it. If this is an application window, step
// through the app tokens until we find its app.
@@ -8745,9 +8751,9 @@
}
return;
}
-
+
mScreenFrozenLock.acquire();
-
+
long now = SystemClock.uptimeMillis();
//Log.i(TAG, "Freezing, gc pending: " + mFreezeGcPending + ", now " + now);
if (mFreezeGcPending != 0) {
@@ -8760,32 +8766,32 @@
} else {
mFreezeGcPending = now;
}
-
+
mDisplayFrozen = true;
if (mNextAppTransition != WindowManagerPolicy.TRANSIT_NONE) {
mNextAppTransition = WindowManagerPolicy.TRANSIT_NONE;
mAppTransitionReady = true;
}
-
+
if (PROFILE_ORIENTATION) {
File file = new File("/data/system/frozen");
Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
}
Surface.freezeDisplay(0);
}
-
+
private void stopFreezingDisplayLocked() {
if (!mDisplayFrozen) {
return;
}
-
+
mDisplayFrozen = false;
mH.removeMessages(H.APP_FREEZE_TIMEOUT);
if (PROFILE_ORIENTATION) {
Debug.stopMethodTracing();
}
Surface.unfreezeDisplay(0);
-
+
// Reset the key delivery timeout on unfreeze, too. We force a wakeup here
// too because regular key delivery processing should resume immediately.
synchronized (mKeyWaiter) {
@@ -8801,10 +8807,10 @@
mH.removeMessages(H.FORCE_GC);
mH.sendMessageDelayed(mH.obtainMessage(H.FORCE_GC),
2000);
-
+
mScreenFrozenLock.release();
}
-
+
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (mContext.checkCallingOrSelfPermission("android.permission.DUMP")
@@ -8814,7 +8820,7 @@
+ ", uid=" + Binder.getCallingUid());
return;
}
-
+
synchronized(mWindowMap) {
pw.println("Current Window Manager state:");
for (int i=mWindows.size()-1; i>=0; i--) {
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 14dcfd5..6a81178 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -10422,11 +10422,14 @@
// Not backing this app up any more; reset its OOM adjustment
updateOomAdjLocked(proc);
- try {
- proc.thread.scheduleDestroyBackupAgent(appInfo);
- } catch (Exception e) {
- Log.e(TAG, "Exception when unbinding backup agent:");
- e.printStackTrace();
+ // If the app crashed during backup, 'thread' will be null here
+ if (proc.thread != null) {
+ try {
+ proc.thread.scheduleDestroyBackupAgent(appInfo);
+ } catch (Exception e) {
+ Log.e(TAG, "Exception when unbinding backup agent:");
+ e.printStackTrace();
+ }
}
}
}
diff --git a/telephony/java/com/android/internal/telephony/RIL.java b/telephony/java/com/android/internal/telephony/RIL.java
index 9227f29..900683b 100644
--- a/telephony/java/com/android/internal/telephony/RIL.java
+++ b/telephony/java/com/android/internal/telephony/RIL.java
@@ -1259,13 +1259,15 @@
RILRequest rr
= RILRequest.obtain(RIL_REQUEST_SETUP_DATA_CALL, result);
- rr.mp.writeInt(5);
+ rr.mp.writeInt(6);
rr.mp.writeString(radioTechnology);
rr.mp.writeString(profile);
rr.mp.writeString(apn);
rr.mp.writeString(user);
rr.mp.writeString(password);
+ //TODO(): Add to the APN database, AuthType is set to CHAP/PAP
+ rr.mp.writeString("3");
if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " "
+ apn);
@@ -2107,6 +2109,7 @@
case RIL_REQUEST_GET_SMSC_ADDRESS: ret = responseString(p); break;
case RIL_REQUEST_SET_SMSC_ADDRESS: ret = responseVoid(p); break;
case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE: ret = responseVoid(p); break;
+ case RIL_REQUEST_REPORT_SMS_MEMORY_STATUS: ret = responseVoid(p); break;
default:
throw new RuntimeException("Unrecognized solicited response: " + rr.mRequest);
//break;
@@ -2631,13 +2634,14 @@
private Object
responseSMS(Parcel p) {
- int messageRef;
+ int messageRef, errorCode;
String ackPDU;
messageRef = p.readInt();
ackPDU = p.readString();
+ errorCode = p.readInt();
- SmsResponse response = new SmsResponse(messageRef, ackPDU);
+ SmsResponse response = new SmsResponse(messageRef, ackPDU, errorCode);
return response;
}
diff --git a/telephony/java/com/android/internal/telephony/SmsResponse.java b/telephony/java/com/android/internal/telephony/SmsResponse.java
index 3c4df56..bd79e02 100644
--- a/telephony/java/com/android/internal/telephony/SmsResponse.java
+++ b/telephony/java/com/android/internal/telephony/SmsResponse.java
@@ -26,9 +26,15 @@
int messageRef;
/** ackPdu for the just-sent SMS. */
String ackPdu;
+ /**
+ * errorCode: See 3GPP 27.005, 3.2.5 for GSM/UMTS,
+ * 3GPP2 N.S0005 (IS-41C) Table 171 for CDMA, -1 if unknown or not applicable.
+ */
+ int errorCode;
- public SmsResponse(int messageRef, String ackPdu) {
+ public SmsResponse(int messageRef, String ackPdu, int errorCode) {
this.messageRef = messageRef;
this.ackPdu = ackPdu;
+ this.errorCode = errorCode;
}
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java
index 719e92c..da9fd0c4 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaCallTracker.java
@@ -934,6 +934,7 @@
droppedDuringPoll.clear();
break;
+ case EVENT_REPOLL_AFTER_DELAY:
case EVENT_CALL_STATE_CHANGE:
pollCallsWhenSafe();
break;
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java b/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java
index 3833fc9..588bdf0 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java
@@ -487,10 +487,12 @@
}
// A null cnapName should be the same as ""
- if (TextUtils.isEmpty(dc.name) && !TextUtils.isEmpty(cnapName)) {
- changed = true;
- cnapName = "";
- } else if (dc.name.equals(cnapName) == false) {
+ if (TextUtils.isEmpty(dc.name)) {
+ if (!TextUtils.isEmpty(cnapName)) {
+ changed = true;
+ cnapName = "";
+ }
+ } else if (!dc.name.equals(cnapName)) {
changed = true;
cnapName = dc.name;
}
diff --git a/tests/DumpRenderTree/assets/run_reliability_tests.py b/tests/DumpRenderTree/assets/run_reliability_tests.py
index 076c508..b038740 100755
--- a/tests/DumpRenderTree/assets/run_reliability_tests.py
+++ b/tests/DumpRenderTree/assets/run_reliability_tests.py
@@ -18,6 +18,7 @@
TEST_LIST_FILE = "/sdcard/android/reliability_tests_list.txt"
TEST_STATUS_FILE = "/sdcard/android/reliability_running_test.txt"
TEST_TIMEOUT_FILE = "/sdcard/android/reliability_timeout_test.txt"
+TEST_LOAD_TIME_FILE = "/sdcard/android/reliability_load_time.txt"
HTTP_URL_FILE = "urllist_http"
HTTPS_URL_FILE = "urllist_https"
NUM_URLS = 25
@@ -62,6 +63,36 @@
os.system(cmd)
+def ProcessPageLoadTime(raw_log):
+ """Processes the raw page load time logged by test app."""
+ log_handle = open(raw_log, "r")
+ load_times = {}
+
+ for line in log_handle:
+ line = line.strip()
+ pair = line.split("|")
+ if len(pair) != 2:
+ logging.info("Line has more than one '|': " + line)
+ continue
+ if pair[0] not in load_times:
+ load_times[pair[0]] = [0, 0]
+ try:
+ pair[1] = int(pair[1])
+ except ValueError:
+ logging.info("Lins has non-numeric load time: " + line)
+ continue
+ load_times[pair[0]][0] += pair[1]
+ load_times[pair[0]][1] += 1
+
+ log_handle.close()
+
+ # rewrite the average time to file
+ log_handle = open(raw_log, "w")
+ for url, times in load_times.iteritems():
+ log_handle.write("%s|%f\n" % (url, float(times[0]) / times[1]))
+ log_handle.close()
+
+
def main(options, args):
"""Send the url list to device and start testing, restart if crashed."""
@@ -141,8 +172,13 @@
# Call ReliabilityTestsAutoTest#startReliabilityTests
test_cmd = (test_cmd_prefix + " -e class "
"com.android.dumprendertree.ReliabilityTest#"
- "runReliabilityTest -e timeout %s -e delay %s %s" %
- (str(timeout_ms), str(manual_delay), test_cmd_postfix))
+ "runReliabilityTest -e timeout %s -e delay %s" %
+ (str(timeout_ms), str(manual_delay)))
+
+ if options.logtime:
+ test_cmd += " -e logtime true"
+
+ test_cmd += test_cmd_postfix
adb_output = subprocess.Popen(test_cmd, shell=True,
stdout=subprocess.PIPE,
@@ -176,12 +212,20 @@
else:
logging.info("No crash found.")
+ # get timeout file from sdcard
test_cmd = (adb_cmd + "pull \"" + TEST_TIMEOUT_FILE + "\" \""
+ timedout_file + "\"")
-
subprocess.Popen(test_cmd, shell=True, stdout=subprocess.PIPE,
stderr=subprocess.PIPE).communicate()
+ if options.logtime:
+ # get logged page load times from sdcard
+ test_cmd = (adb_cmd + "pull \"" + TEST_LOAD_TIME_FILE + "\" \""
+ + options.logtime + "\"")
+ subprocess.Popen(test_cmd, shell=True, stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE).communicate()
+ ProcessPageLoadTime(options.logtime)
+
if "__main__" == __name__:
option_parser = optparse.OptionParser()
@@ -206,5 +250,8 @@
option_parser.add_option("-b", "--bugreport",
default=".",
help="the directory to store bugreport for crashes")
+ option_parser.add_option("-l", "--logtime",
+ default=None,
+ help="Logs page load time for each url to the file")
opts, arguments = option_parser.parse_args()
main(opts, arguments)
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoRunner.java b/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoRunner.java
index 57e06a1..e00d3ad 100755
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoRunner.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoRunner.java
@@ -69,11 +69,16 @@
String r = (String)icicle.get("rebaseline");
this.mRebaseline = (r != null && r.toLowerCase().equals("true"));
super.onCreate(icicle);
+
+ String logtime = (String) icicle.get("logtime");
+ this.mLogtime = (logtime != null
+ && logtime.toLowerCase().equals("true"));
}
public String mTestPath = null;
public int mTimeoutInMillis = 0;
public int mDelay = 0;
public boolean mRebaseline = false;
+ public boolean mLogtime = false;
}
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTest.java b/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTest.java
index 22c458c..16973be 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTest.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTest.java
@@ -1,6 +1,7 @@
package com.android.dumprendertree;
import android.os.Handler;
+import android.os.Message;
import android.test.ActivityInstrumentationTestCase2;
import android.util.Log;
@@ -15,43 +16,44 @@
import java.io.OutputStream;
public class ReliabilityTest extends ActivityInstrumentationTestCase2<ReliabilityTestActivity> {
-
+
private static final String LOGTAG = "ReliabilityTest";
private static final String PKG_NAME = "com.android.dumprendertree";
private static final String TEST_LIST_FILE = "/sdcard/android/reliability_tests_list.txt";
private static final String TEST_STATUS_FILE = "/sdcard/android/reliability_running_test.txt";
private static final String TEST_TIMEOUT_FILE = "/sdcard/android/reliability_timeout_test.txt";
+ private static final String TEST_LOAD_TIME_FILE = "/sdcard/android/reliability_load_time.txt";
private static final String TEST_DONE = "#DONE";
static final String RELIABILITY_TEST_RUNNER_FILES[] = {
"run_reliability_tests.py"
};
-
+
public ReliabilityTest() {
super(PKG_NAME, ReliabilityTestActivity.class);
}
-
+
public void runReliabilityTest() throws Throwable {
ReliabilityTestActivity activity = getActivity();
LayoutTestsAutoRunner runner = (LayoutTestsAutoRunner)getInstrumentation();
-
+
File testListFile = new File(TEST_LIST_FILE);
if(!testListFile.exists())
throw new FileNotFoundException("test list file not found.");
-
+
BufferedReader listReader = new BufferedReader(
new FileReader(testListFile));
-
+
//always try to resume first, hence cleaning up status will be the
//responsibility of driver scripts
String lastUrl = readTestStatus();
if(lastUrl != null && !TEST_DONE.equals(lastUrl))
fastForward(listReader, lastUrl);
-
+
String url = null;
Handler handler = null;
boolean timeoutFlag = false;
long start, elapsed;
-
+
//read from BufferedReader instead of populating a list in advance,
//this will avoid excessive memory usage in case of a large list
while((url = listReader.readLine()) != null) {
@@ -65,9 +67,13 @@
//use message to send new URL to avoid interacting with
//WebView in non-UI thread
handler = activity.getHandler();
- handler.sendMessage(handler.obtainMessage(
- ReliabilityTestActivity.MSG_NAVIGATE,
- runner.mTimeoutInMillis, runner.mDelay, url));
+ Message msg = handler.obtainMessage(
+ ReliabilityTestActivity.MSG_NAVIGATE,
+ runner.mTimeoutInMillis, runner.mDelay);
+ msg.getData().putString(ReliabilityTestActivity.MSG_NAV_URL, url);
+ msg.getData().putBoolean(ReliabilityTestActivity.MSG_NAV_LOGTIME,
+ runner.mLogtime);
+ handler.sendMessage(msg);
timeoutFlag = activity.waitUntilDone();
elapsed = System.currentTimeMillis() - start;
if(elapsed < 1000) {
@@ -79,6 +85,9 @@
if(timeoutFlag) {
writeTimeoutFile(url);
}
+ if(runner.mLogtime) {
+ writeLoadTime(url, activity.getPageLoadTime());
+ }
System.runFinalization();
System.gc();
System.gc();
@@ -87,7 +96,7 @@
activity.finish();
listReader.close();
}
-
+
public void copyRunnerAssetsToCache() {
try {
String out_dir = getActivity().getApplicationContext()
@@ -112,7 +121,7 @@
Log.e(LOGTAG, "Cannot extract scripts for testing.", e);
}
}
-
+
private void updateTestStatus(String s) {
// write last tested url into status file
try {
@@ -124,7 +133,7 @@
Log.e(LOGTAG, "Cannot update file " + TEST_STATUS_FILE, e);
}
}
-
+
private String readTestStatus() {
// read out the test name it stopped last time.
String status = null;
@@ -141,12 +150,12 @@
}
return status;
}
-
+
private void fastForward(BufferedReader testListReader, String lastUrl) {
//fastforward the BufferedReader to the position right after last url
if(lastUrl == null)
return;
-
+
String line = null;
try {
while((line = testListReader.readLine()) != null) {
@@ -160,7 +169,7 @@
}
private void writeTimeoutFile(String s) {
- //append to the file containing the list of timeout urls
+ //append to the file containing the list of timeout urls
try {
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream(TEST_TIMEOUT_FILE, true));
@@ -171,4 +180,16 @@
Log.e(LOGTAG, "Cannot update file " + TEST_TIMEOUT_FILE, e);
}
}
+
+ private void writeLoadTime(String s, long time) {
+ //append to the file containing the list of timeout urls
+ try {
+ BufferedOutputStream bos = new BufferedOutputStream(
+ new FileOutputStream(TEST_LOAD_TIME_FILE, true));
+ bos.write((s + '|' + time + '\n').getBytes());
+ bos.close();
+ } catch (Exception e) {
+ Log.e(LOGTAG, "Cannot update file " + TEST_LOAD_TIME_FILE, e);
+ }
+ }
}
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTestActivity.java b/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTestActivity.java
index 8e7ac08..5ddd0b3 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTestActivity.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/ReliabilityTestActivity.java
@@ -21,52 +21,57 @@
import android.widget.LinearLayout.LayoutParams;
public class ReliabilityTestActivity extends Activity {
-
+
public static final String TEST_URL_ACTION = "com.andrdoid.dumprendertree.TestUrlAction";
public static final String PARAM_URL = "URL";
public static final String PARAM_TIMEOUT = "Timeout";
public static final int RESULT_TIMEOUT = 0xDEAD;
public static final int MSG_TIMEOUT = 0xC001;
public static final int MSG_NAVIGATE = 0xC002;
-
+ public static final String MSG_NAV_URL = "url";
+ public static final String MSG_NAV_LOGTIME = "logtime";
+
private static final String LOGTAG = "ReliabilityTestActivity";
-
+
private WebView webView;
private SimpleWebViewClient webViewClient;
private SimpleChromeClient chromeClient;
private Handler handler;
private boolean timeoutFlag;
+ private boolean logTime;
private boolean pageDone;
private Object pageDoneLock;
private int pageStartCount;
private int manualDelay;
+ private long startTime;
+ private long pageLoadTime;
private PageDoneRunner pageDoneRunner = new PageDoneRunner();
-
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.v(LOGTAG, "onCreate, inst=" + Integer.toHexString(hashCode()));
-
+
LinearLayout contentView = new LinearLayout(this);
contentView.setOrientation(LinearLayout.VERTICAL);
setContentView(contentView);
setTitle("Idle");
-
+
webView = new WebView(this);
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(false);
webView.getSettings().setLayoutAlgorithm(LayoutAlgorithm.NORMAL);
-
+
webViewClient = new SimpleWebViewClient();
chromeClient = new SimpleChromeClient();
webView.setWebViewClient(webViewClient);
webView.setWebChromeClient(chromeClient);
-
+
contentView.addView(webView, new LayoutParams(
ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.FILL_PARENT, 0.0f));
-
+
handler = new Handler() {
@Override
public void handleMessage(Message msg) {
@@ -76,15 +81,16 @@
return;
case MSG_NAVIGATE:
manualDelay = msg.arg2;
- navigate((String)msg.obj, msg.arg1);
+ navigate(msg.getData().getString(MSG_NAV_URL), msg.arg1);
+ logTime = msg.getData().getBoolean(MSG_NAV_LOGTIME);
return;
}
}
};
-
+
pageDoneLock = new Object();
}
-
+
public void reset() {
synchronized (pageDoneLock) {
pageDone = false;
@@ -93,42 +99,46 @@
pageStartCount = 0;
chromeClient.resetJsTimeout();
}
-
+
private void navigate(String url, int timeout) {
if(url == null) {
Log.v(LOGTAG, "URL is null, cancelling...");
finish();
}
webView.stopLoading();
+ if(logTime) {
+ webView.clearCache(true);
+ }
+ startTime = System.currentTimeMillis();
Log.v(LOGTAG, "Navigating to URL: " + url);
webView.loadUrl(url);
-
+
if(timeout != 0) {
//set a timer with specified timeout (in ms)
handler.sendMessageDelayed(handler.obtainMessage(MSG_TIMEOUT),
timeout);
}
}
-
+
@Override
protected void onDestroy() {
Log.v(LOGTAG, "onDestroy, inst=" + Integer.toHexString(hashCode()));
super.onDestroy();
}
-
+
private boolean isPageDone() {
synchronized (pageDoneLock) {
return pageDone;
}
}
-
+
private void setPageDone(boolean pageDone) {
synchronized (pageDoneLock) {
this.pageDone = pageDone;
pageDoneLock.notifyAll();
}
}
-
+
private void handleTimeout() {
int progress = webView.getProgress();
webView.stopLoading();
@@ -136,7 +146,7 @@
timeoutFlag = true;
handler.postDelayed(pageDoneRunner, manualDelay);
}
-
+
public boolean waitUntilDone() {
validateNotAppThread();
synchronized (pageDoneLock) {
@@ -150,11 +160,11 @@
}
return timeoutFlag;
}
-
+
public Handler getHandler() {
return handler;
}
-
+
private final void validateNotAppThread() {
if (ActivityThread.currentActivityThread() != null) {
throw new RuntimeException(
@@ -162,8 +172,12 @@
}
}
+ public long getPageLoadTime() {
+ return pageLoadTime;
+ }
+
class SimpleWebViewClient extends WebViewClient {
-
+
@Override
public void onReceivedError(WebView view, int errorCode, String description,
String failingUrl) {
@@ -171,27 +185,27 @@
+ ", description=" + description
+ ", url=" + failingUrl);
}
-
+
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
//ignore certificate error
Log.v(LOGTAG, "Received SSL error: " + error.toString());
handler.proceed();
}
-
+
@Override
public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host,
String realm) {
// cancel http auth request
handler.cancel();
}
-
+
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
pageStartCount++;
Log.v(LOGTAG, "onPageStarted: " + url);
}
-
+
@Override
public void onPageFinished(WebView view, String url) {
Log.v(LOGTAG, "onPageFinished: " + url);
@@ -200,23 +214,23 @@
handler.postDelayed(new WebViewStatusChecker(), 500);
}
}
-
+
class SimpleChromeClient extends WebChromeClient {
-
+
private int timeoutCounter = 0;
-
+
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
result.confirm();
return true;
}
-
+
@Override
public boolean onJsBeforeUnload(WebView view, String url, String message, JsResult result) {
result.confirm();
return true;
}
-
+
@Override
public boolean onJsConfirm(WebView view, String url, String message, JsResult result) {
result.confirm();
@@ -229,32 +243,32 @@
result.confirm();
return true;
}
-
+
@Override
public boolean onJsTimeout() {
timeoutCounter++;
Log.v(LOGTAG, "JavaScript timeout, count=" + timeoutCounter);
return timeoutCounter > 2;
}
-
+
public void resetJsTimeout() {
timeoutCounter = 0;
}
-
+
@Override
public void onReceivedTitle(WebView view, String title) {
ReliabilityTestActivity.this.setTitle(title);
}
}
-
+
class WebViewStatusChecker implements Runnable {
-
+
private int initialStartCount;
-
+
public WebViewStatusChecker() {
initialStartCount = pageStartCount;
}
-
+
public void run() {
if (initialStartCount == pageStartCount) {
//perform cleanup
@@ -264,11 +278,12 @@
}
}
}
-
+
class PageDoneRunner implements Runnable {
-
+
public void run() {
Log.v(LOGTAG, "Finishing URL: " + webView.getUrl());
+ pageLoadTime = System.currentTimeMillis() - startTime;
setPageDone(true);
}
}
diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp
index 770c7d8..b004664 100644
--- a/tools/aapt/ResourceTable.cpp
+++ b/tools/aapt/ResourceTable.cpp
@@ -1516,8 +1516,9 @@
String8(value).string());
}
#endif
-
- sp<Entry> e = getEntry(package, type, name, sourcePos, params, doSetIndex);
+
+ sp<Entry> e = getEntry(package, type, name, sourcePos, overwrite,
+ params, doSetIndex);
if (e == NULL) {
return UNKNOWN_ERROR;
}
@@ -1560,8 +1561,7 @@
String8(name).string());
return UNKNOWN_ERROR;
}
-
- sp<Entry> e = getEntry(package, type, name, sourcePos, params);
+ sp<Entry> e = getEntry(package, type, name, sourcePos, overlay, params);
if (e == NULL) {
return UNKNOWN_ERROR;
}
@@ -1615,8 +1615,7 @@
sourcePos.file.striing(), sourcePos.line, String8(type).string());
}
#endif
-
- sp<Entry> e = getEntry(package, type, name, sourcePos, params);
+ sp<Entry> e = getEntry(package, type, name, sourcePos, replace, params);
if (e == NULL) {
return UNKNOWN_ERROR;
}
@@ -2899,7 +2898,7 @@
mItem.sourcePos.file.string(), mItem.sourcePos.line);
return UNKNOWN_ERROR;
}
-
+
mType = TYPE_ITEM;
mItem = item;
mItemFormat = format;
@@ -3219,11 +3218,17 @@
sp<ResourceTable::Entry> ResourceTable::Type::getEntry(const String16& entry,
const SourcePos& sourcePos,
const ResTable_config* config,
- bool doSetIndex)
+ bool doSetIndex,
+ bool overlay)
{
int pos = -1;
sp<ConfigList> c = mConfigs.valueFor(entry);
if (c == NULL) {
+ if (overlay == true) {
+ sourcePos.error("Resource %s appears in overlay but not"
+ " in the base package.\n", String8(entry).string());
+ return NULL;
+ }
c = new ConfigList(entry, sourcePos);
mConfigs.add(entry, c);
pos = (int)mOrderedConfigs.size();
@@ -3522,6 +3527,7 @@
const String16& type,
const String16& name,
const SourcePos& sourcePos,
+ bool overlay,
const ResTable_config* config,
bool doSetIndex)
{
@@ -3529,7 +3535,7 @@
if (t == NULL) {
return NULL;
}
- return t->getEntry(name, sourcePos, config, doSetIndex);
+ return t->getEntry(name, sourcePos, config, doSetIndex, overlay);
}
sp<const ResourceTable::Entry> ResourceTable::getEntry(uint32_t resID,
diff --git a/tools/aapt/ResourceTable.h b/tools/aapt/ResourceTable.h
index 20865ea..ec4331a 100644
--- a/tools/aapt/ResourceTable.h
+++ b/tools/aapt/ResourceTable.h
@@ -418,7 +418,8 @@
sp<Entry> getEntry(const String16& entry,
const SourcePos& pos,
const ResTable_config* config = NULL,
- bool doSetIndex = false);
+ bool doSetIndex = false,
+ bool overlay = false);
const SourcePos& getFirstPublicSourcePos() const { return *mFirstPublicSourcePos; }
@@ -502,6 +503,7 @@
const String16& type,
const String16& name,
const SourcePos& pos,
+ bool overlay,
const ResTable_config* config = NULL,
bool doSetIndex = false);
sp<const Entry> getEntry(uint32_t resID,