summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/17.txt1
-rw-r--r--api/current.txt33
-rw-r--r--cmds/pm/src/com/android/commands/pm/Pm.java41
-rw-r--r--cmds/svc/src/com/android/commands/svc/PowerCommand.java10
-rw-r--r--core/java/android/app/Activity.java33
-rw-r--r--core/java/android/app/ActivityManager.java5
-rw-r--r--core/java/android/app/ActivityThread.java49
-rw-r--r--core/java/android/app/ApplicationPackageManager.java25
-rw-r--r--core/java/android/app/ContextImpl.java11
-rw-r--r--core/java/android/app/FragmentManager.java143
-rw-r--r--core/java/android/app/KeyguardManager.java5
-rw-r--r--core/java/android/app/WallpaperManager.java7
-rw-r--r--core/java/android/content/ContentProvider.java4
-rw-r--r--core/java/android/content/Context.java11
-rw-r--r--core/java/android/content/ContextWrapper.java7
-rw-r--r--core/java/android/content/Intent.java16
-rw-r--r--core/java/android/content/pm/IPackageManager.aidl8
-rw-r--r--core/java/android/content/pm/PackageManager.java42
-rw-r--r--core/java/android/content/pm/VerificationParams.aidl19
-rw-r--r--core/java/android/content/pm/VerificationParams.java187
-rw-r--r--core/java/android/hardware/display/DisplayManager.java185
-rw-r--r--core/java/android/hardware/usb/IUsbManager.aidl8
-rw-r--r--core/java/android/inputmethodservice/InputMethodService.java3
-rw-r--r--core/java/android/net/MobileDataStateTracker.java13
-rw-r--r--core/java/android/net/NetworkStateTracker.java6
-rw-r--r--core/java/android/os/BatteryManager.java2
-rw-r--r--core/java/android/os/BatteryStats.java3
-rw-r--r--core/java/android/os/FactoryTest.java35
-rw-r--r--core/java/android/os/FileUtils.java2
-rw-r--r--core/java/android/os/UEventObserver.java196
-rw-r--r--core/java/android/provider/Settings.java1
-rw-r--r--core/java/android/service/dreams/DreamManagerService.java4
-rw-r--r--core/java/android/service/wallpaper/WallpaperService.java10
-rwxr-xr-xcore/java/android/speech/tts/TextToSpeech.java29
-rw-r--r--core/java/android/text/TextUtils.java7
-rw-r--r--core/java/android/text/style/LocaleSpan.java84
-rw-r--r--core/java/android/view/Choreographer.java3
-rw-r--r--core/java/android/view/Display.java48
-rw-r--r--core/java/android/view/DisplayInfo.java13
-rw-r--r--core/java/android/view/HardwareRenderer.java8
-rw-r--r--core/java/android/view/IWindowSession.aidl8
-rw-r--r--core/java/android/view/Surface.java19
-rw-r--r--core/java/android/view/SurfaceView.java14
-rw-r--r--core/java/android/view/View.java908
-rw-r--r--core/java/android/view/ViewConfiguration.java5
-rw-r--r--core/java/android/view/ViewDebug.java15
-rw-r--r--core/java/android/view/ViewGroup.java122
-rw-r--r--core/java/android/view/ViewPropertyAnimator.java2
-rw-r--r--core/java/android/view/ViewRootImpl.java144
-rw-r--r--core/java/android/view/Window.java14
-rw-r--r--core/java/android/view/WindowManagerGlobal.java516
-rw-r--r--core/java/android/view/WindowManagerImpl.java557
-rw-r--r--core/java/android/view/WindowManagerPolicy.java10
-rw-r--r--core/java/android/webkit/WebSettings.java13
-rw-r--r--core/java/android/webkit/WebSettingsClassic.java19
-rw-r--r--core/java/android/webkit/WebView.java2
-rw-r--r--core/java/android/webkit/WebViewClassic.java23
-rw-r--r--core/java/android/webkit/WebViewFactoryProvider.java10
-rw-r--r--core/java/android/widget/Switch.java2
-rw-r--r--core/java/android/widget/TextView.java21
-rw-r--r--core/java/android/widget/Toast.java5
-rw-r--r--core/java/com/android/internal/app/ResolverActivity.java9
-rw-r--r--core/java/com/android/internal/os/ZygoteInit.java8
-rw-r--r--core/java/com/android/internal/view/RotationPolicy.java7
-rw-r--r--core/jni/android/graphics/Paint.cpp50
-rw-r--r--core/jni/android/graphics/TextLayoutCache.cpp17
-rw-r--r--core/jni/android/graphics/TextLayoutCache.h4
-rw-r--r--core/jni/android_os_FileUtils.cpp6
-rw-r--r--core/jni/android_view_Surface.cpp10
-rw-r--r--core/res/res/values-af/strings.xml6
-rw-r--r--core/res/res/values-am/strings.xml6
-rw-r--r--core/res/res/values-ar/strings.xml4
-rw-r--r--core/res/res/values-be/strings.xml6
-rw-r--r--core/res/res/values-bg/strings.xml6
-rw-r--r--core/res/res/values-ca/strings.xml6
-rw-r--r--core/res/res/values-cs/strings.xml4
-rw-r--r--core/res/res/values-da/strings.xml6
-rw-r--r--core/res/res/values-de/strings.xml6
-rw-r--r--core/res/res/values-el/strings.xml6
-rw-r--r--core/res/res/values-en-rGB/strings.xml6
-rw-r--r--core/res/res/values-es-rUS/strings.xml6
-rw-r--r--core/res/res/values-es/strings.xml6
-rw-r--r--core/res/res/values-et/strings.xml6
-rw-r--r--core/res/res/values-fa/strings.xml4
-rw-r--r--core/res/res/values-fi/strings.xml6
-rw-r--r--core/res/res/values-fr/strings.xml6
-rw-r--r--core/res/res/values-hi/strings.xml6
-rw-r--r--core/res/res/values-hr/strings.xml6
-rw-r--r--core/res/res/values-hu/strings.xml6
-rw-r--r--core/res/res/values-in/strings.xml6
-rw-r--r--core/res/res/values-it/strings.xml6
-rw-r--r--core/res/res/values-iw/strings.xml4
-rw-r--r--core/res/res/values-ja/strings.xml6
-rw-r--r--core/res/res/values-ko/strings.xml6
-rw-r--r--core/res/res/values-lt/strings.xml6
-rw-r--r--core/res/res/values-lv/strings.xml6
-rw-r--r--core/res/res/values-ms/strings.xml4
-rw-r--r--core/res/res/values-nb/strings.xml6
-rw-r--r--core/res/res/values-nl/strings.xml6
-rw-r--r--core/res/res/values-pl/strings.xml6
-rw-r--r--core/res/res/values-pt-rPT/strings.xml6
-rw-r--r--core/res/res/values-pt/strings.xml6
-rw-r--r--core/res/res/values-rm/strings.xml6
-rw-r--r--core/res/res/values-ro/strings.xml6
-rw-r--r--core/res/res/values-ru/strings.xml6
-rw-r--r--core/res/res/values-sk/strings.xml6
-rw-r--r--core/res/res/values-sl/strings.xml6
-rw-r--r--core/res/res/values-sr/strings.xml6
-rw-r--r--core/res/res/values-sv/strings.xml6
-rw-r--r--core/res/res/values-sw/strings.xml6
-rw-r--r--core/res/res/values-th/strings.xml6
-rw-r--r--core/res/res/values-tl/strings.xml6
-rw-r--r--core/res/res/values-tr/strings.xml6
-rw-r--r--core/res/res/values-uk/strings.xml6
-rw-r--r--core/res/res/values-vi/strings.xml6
-rw-r--r--core/res/res/values-zh-rCN/strings.xml10
-rw-r--r--core/res/res/values-zh-rTW/strings.xml6
-rw-r--r--core/res/res/values-zu/strings.xml6
-rw-r--r--core/res/res/values/public.xml1
-rwxr-xr-xcore/res/res/values/strings.xml5
-rw-r--r--core/tests/coretests/src/android/content/pm/VerificationParamsTest.java171
-rw-r--r--data/fonts/Android.mk11
-rw-r--r--data/fonts/fallback_fonts-ja.xml121
-rw-r--r--data/fonts/fallback_fonts.xml11
-rw-r--r--data/fonts/vendor_fonts.xml34
-rw-r--r--docs/html/intl/ja/index.jd159
-rw-r--r--drm/jni/Android.mk3
-rw-r--r--drm/jni/android_drm_DrmManagerClient.cpp105
-rw-r--r--keystore/java/android/security/AndroidKeyStore.java463
-rw-r--r--keystore/java/android/security/AndroidKeyStoreProvider.java34
-rw-r--r--keystore/java/android/security/KeyStore.java18
-rw-r--r--keystore/tests/src/android/security/AndroidKeyStoreTest.java1383
-rwxr-xr-xkeystore/tests/src/android/security/KeyStoreTest.java50
-rw-r--r--libs/hwui/FontRenderer.cpp4
-rw-r--r--location/java/android/location/ILocationManager.aidl2
-rw-r--r--location/java/android/location/LocationManager.java8
-rwxr-xr-xmedia/jni/mediaeditor/VideoEditorClasses.cpp9
-rwxr-xr-xmedia/jni/mediaeditor/VideoEditorJava.cpp3
-rwxr-xr-xmedia/jni/mediaeditor/VideoEditorMain.cpp5
-rw-r--r--packages/FakeOemFeatures/src/com/android/fakeoemfeatures/FakeApp.java2
-rw-r--r--packages/SystemUI/AndroidManifest.xml8
-rw-r--r--packages/SystemUI/res/values/strings.xml9
-rw-r--r--packages/SystemUI/src/com/android/systemui/ImageWallpaper.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/SystemUIService.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/UniverseBackground.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java30
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java38
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/tablet/ShirtPocket.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java36
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java137
-rw-r--r--policy/src/com/android/internal/policy/impl/GlobalActions.java17
-rw-r--r--policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java3
-rw-r--r--policy/src/com/android/internal/policy/impl/KeyguardViewManager.java6
-rw-r--r--policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java6
-rwxr-xr-xpolicy/src/com/android/internal/policy/impl/PhoneWindowManager.java35
-rw-r--r--services/java/com/android/server/BatteryService.java14
-rw-r--r--services/java/com/android/server/ConnectivityService.java5
-rw-r--r--services/java/com/android/server/DockObserver.java233
-rw-r--r--services/java/com/android/server/LocationManagerService.java49
-rw-r--r--services/java/com/android/server/SystemServer.java9
-rw-r--r--services/java/com/android/server/WallpaperManagerService.java4
-rw-r--r--services/java/com/android/server/WiredAccessoryObserver.java305
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java3
-rw-r--r--services/java/com/android/server/am/ProviderMap.java14
-rw-r--r--services/java/com/android/server/display/DisplayAdapter.java39
-rw-r--r--services/java/com/android/server/display/DisplayDevice.java14
-rw-r--r--services/java/com/android/server/display/DisplayDeviceInfo.java10
-rw-r--r--services/java/com/android/server/display/DisplayManagerService.java239
-rw-r--r--services/java/com/android/server/display/HeadlessDisplayAdapter.java38
-rw-r--r--services/java/com/android/server/display/SurfaceFlingerDisplayAdapter.java33
-rw-r--r--services/java/com/android/server/input/InputManagerService.java8
-rw-r--r--services/java/com/android/server/location/GeofenceManager.java14
-rw-r--r--services/java/com/android/server/location/LocationBlacklist.java135
-rw-r--r--services/java/com/android/server/pm/PackageManagerService.java87
-rw-r--r--services/java/com/android/server/pm/PreferredActivity.java18
-rw-r--r--services/java/com/android/server/pm/UserManagerService.java2
-rw-r--r--services/java/com/android/server/power/DisplayPowerController.java54
-rw-r--r--services/java/com/android/server/power/ElectronBeam.java10
-rw-r--r--services/java/com/android/server/usb/UsbDebuggingManager.java322
-rw-r--r--services/java/com/android/server/usb/UsbDeviceManager.java26
-rw-r--r--services/java/com/android/server/usb/UsbService.java10
-rw-r--r--services/java/com/android/server/wm/AppWindowAnimator.java2
-rw-r--r--services/java/com/android/server/wm/ScreenRotationAnimation.java16
-rw-r--r--services/java/com/android/server/wm/StrictModeFlash.java4
-rw-r--r--services/java/com/android/server/wm/Watermark.java6
-rw-r--r--services/java/com/android/server/wm/WindowAnimator.java4
-rwxr-xr-xservices/java/com/android/server/wm/WindowManagerService.java78
-rw-r--r--services/java/com/android/server/wm/WindowStateAnimator.java30
-rw-r--r--services/jni/com_android_server_BatteryService.cpp12
-rw-r--r--services/jni/com_android_server_input_InputManagerService.cpp17
-rw-r--r--test-runner/src/android/test/mock/MockContext.java7
-rw-r--r--test-runner/src/android/test/mock/MockPackageManager.java11
-rw-r--r--tools/layoutlib/bridge/src/android/view/AttachInfo_Accessor.java7
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java7
-rw-r--r--wifi/java/android/net/wifi/ScanResult.java30
-rw-r--r--wifi/java/android/net/wifi/WifiNative.java16
-rw-r--r--wifi/java/android/net/wifi/WifiStateMachine.java198
201 files changed, 6527 insertions, 2731 deletions
diff --git a/api/17.txt b/api/17.txt
index c43802f..d002449 100644
--- a/api/17.txt
+++ b/api/17.txt
@@ -24500,7 +24500,6 @@ package android.view {
field public static final int SYSTEM_UI_FLAG_VISIBLE = 0; // 0x0
field public static final int SYSTEM_UI_LAYOUT_FLAGS = 1536; // 0x600
field public static final int TEXT_ALIGNMENT_INHERIT = 0; // 0x0
- field public static final int TEXT_ALIGNMENT_RESOLVED_DEFAULT = 131072; // 0x20000
field public static final android.util.Property TRANSLATION_X;
field public static final android.util.Property TRANSLATION_Y;
field protected static final java.lang.String VIEW_LOG_TAG = "View";
diff --git a/api/current.txt b/api/current.txt
index b489dfd..e1d07e2 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5838,7 +5838,7 @@ package android.content {
field public static final java.lang.String EXTRA_KEY_EVENT = "android.intent.extra.KEY_EVENT";
field public static final java.lang.String EXTRA_LOCAL_ONLY = "android.intent.extra.LOCAL_ONLY";
field public static final java.lang.String EXTRA_NOT_UNKNOWN_SOURCE = "android.intent.extra.NOT_UNKNOWN_SOURCE";
- field public static final java.lang.String EXTRA_ORIGINATING_URL = "android.intent.extra.ORIGINATING_URL";
+ field public static final java.lang.String EXTRA_ORIGINATING_URI = "android.intent.extra.ORIGINATING_URI";
field public static final java.lang.String EXTRA_PHONE_NUMBER = "android.intent.extra.PHONE_NUMBER";
field public static final java.lang.String EXTRA_REFERRER = "android.intent.extra.REFERRER";
field public static final java.lang.String EXTRA_REMOTE_INTENT_TOKEN = "android.intent.extra.remote_intent_token";
@@ -9981,6 +9981,15 @@ package android.hardware {
package android.hardware.display {
public final class DisplayManager {
+ method public android.view.Display getDisplay(int, android.content.Context);
+ method public void registerDisplayListener(android.hardware.display.DisplayManager.DisplayListener, android.os.Handler);
+ method public void unregisterDisplayListener(android.hardware.display.DisplayManager.DisplayListener);
+ }
+
+ public static abstract interface DisplayManager.DisplayListener {
+ method public abstract void onDisplayAdded(int);
+ method public abstract void onDisplayChanged(int);
+ method public abstract void onDisplayRemoved(int);
}
}
@@ -13217,6 +13226,7 @@ package android.net.wifi {
field public java.lang.String capabilities;
field public int frequency;
field public int level;
+ field public long timestamp;
}
public final class SupplicantState extends java.lang.Enum implements android.os.Parcelable {
@@ -15515,6 +15525,7 @@ package android.os {
field public static final int BATTERY_HEALTH_UNSPECIFIED_FAILURE = 6; // 0x6
field public static final int BATTERY_PLUGGED_AC = 1; // 0x1
field public static final int BATTERY_PLUGGED_USB = 2; // 0x2
+ field public static final int BATTERY_PLUGGED_WIRELESS = 4; // 0x4
field public static final int BATTERY_STATUS_CHARGING = 2; // 0x2
field public static final int BATTERY_STATUS_DISCHARGING = 3; // 0x3
field public static final int BATTERY_STATUS_FULL = 5; // 0x5
@@ -22494,6 +22505,17 @@ package android.text.style {
method public abstract void chooseHeight(java.lang.CharSequence, int, int, int, int, android.graphics.Paint.FontMetricsInt, android.text.TextPaint);
}
+ public class LocaleSpan extends android.text.style.MetricAffectingSpan implements android.text.ParcelableSpan {
+ ctor public LocaleSpan(java.util.Locale);
+ ctor public LocaleSpan(android.os.Parcel);
+ method public int describeContents();
+ method public java.util.Locale getLocale();
+ method public int getSpanTypeId();
+ method public void updateDrawState(android.text.TextPaint);
+ method public void updateMeasureState(android.text.TextPaint);
+ method public void writeToParcel(android.os.Parcel, int);
+ }
+
public class MaskFilterSpan extends android.text.style.CharacterStyle implements android.text.style.UpdateAppearance {
ctor public MaskFilterSpan(android.graphics.MaskFilter);
method public android.graphics.MaskFilter getMaskFilter();
@@ -24579,6 +24601,7 @@ package android.view {
method public final android.content.Context getContext();
method protected android.view.ContextMenu.ContextMenuInfo getContextMenuInfo();
method public static int getDefaultSize(int, int);
+ method public android.view.Display getDisplay();
method public final int[] getDrawableState();
method public android.graphics.Bitmap getDrawingCache();
method public android.graphics.Bitmap getDrawingCache(boolean);
@@ -25029,16 +25052,15 @@ package android.view {
field public static final int SYSTEM_UI_FLAG_VISIBLE = 0; // 0x0
field public static final int SYSTEM_UI_LAYOUT_FLAGS = 1536; // 0x600
field public static final int TEXT_ALIGNMENT_CENTER = 4; // 0x4
- field protected static int TEXT_ALIGNMENT_DEFAULT;
+ field public static int TEXT_ALIGNMENT_DEFAULT;
field public static final int TEXT_ALIGNMENT_GRAVITY = 1; // 0x1
field public static final int TEXT_ALIGNMENT_INHERIT = 0; // 0x0
- field public static final int TEXT_ALIGNMENT_RESOLVED_DEFAULT = 131072; // 0x20000
field public static final int TEXT_ALIGNMENT_TEXT_END = 3; // 0x3
field public static final int TEXT_ALIGNMENT_TEXT_START = 2; // 0x2
field public static final int TEXT_ALIGNMENT_VIEW_END = 6; // 0x6
field public static final int TEXT_ALIGNMENT_VIEW_START = 5; // 0x5
field public static final int TEXT_DIRECTION_ANY_RTL = 2; // 0x2
- field protected static int TEXT_DIRECTION_DEFAULT;
+ field public static int TEXT_DIRECTION_DEFAULT;
field public static final int TEXT_DIRECTION_FIRST_STRONG = 1; // 0x1
field public static final int TEXT_DIRECTION_INHERIT = 0; // 0x0
field public static final int TEXT_DIRECTION_LOCALE = 5; // 0x5
@@ -26927,6 +26949,7 @@ package android.webkit {
method public synchronized boolean getUseWideViewPort();
method public deprecated synchronized int getUserAgent();
method public synchronized java.lang.String getUserAgentString();
+ method public static java.lang.String getDefaultUserAgent(android.content.Context);
method public void setAllowContentAccess(boolean);
method public void setAllowFileAccess(boolean);
method public abstract void setAllowFileAccessFromFileURLs(boolean);
@@ -29294,6 +29317,7 @@ package android.widget {
method public static int getTextColor(android.content.Context, android.content.res.TypedArray, int);
method public final android.content.res.ColorStateList getTextColors();
method public static android.content.res.ColorStateList getTextColors(android.content.Context, android.content.res.TypedArray);
+ method public java.util.Locale getTextLocale();
method public float getTextScaleX();
method public float getTextSize();
method public int getTotalPaddingBottom();
@@ -29396,6 +29420,7 @@ package android.widget {
method public void setTextIsSelectable(boolean);
method public final void setTextKeepState(java.lang.CharSequence);
method public final void setTextKeepState(java.lang.CharSequence, android.widget.TextView.BufferType);
+ method public void setTextLocale(java.util.Locale);
method public void setTextScaleX(float);
method public void setTextSize(float);
method public void setTextSize(int, float);
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index eb1f9a2..b34fd05 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -36,6 +36,7 @@ import android.content.pm.ParceledListSlice;
import android.content.pm.PermissionGroupInfo;
import android.content.pm.PermissionInfo;
import android.content.pm.UserInfo;
+import android.content.pm.VerificationParams;
import android.content.res.AssetManager;
import android.content.res.Resources;
import android.net.Uri;
@@ -787,6 +788,8 @@ public final class Pm {
String macAlgo = null;
byte[] macKey = null;
byte[] tag = null;
+ String originatingUriString = null;
+ String referrer = null;
while ((opt=nextOption()) != null) {
if (opt.equals("-l")) {
@@ -850,6 +853,20 @@ public final class Pm {
showUsage();
return;
}
+ } else if (opt.equals("--originating-uri")) {
+ originatingUriString = nextOptionData();
+ if (originatingUriString == null) {
+ System.err.println("Error: must supply argument for --originating-uri");
+ showUsage();
+ return;
+ }
+ } else if (opt.equals("--referrer")) {
+ referrer = nextOptionData();
+ if (referrer == null) {
+ System.err.println("Error: must supply argument for --referrer");
+ showUsage();
+ return;
+ }
} else {
System.err.println("Error: Unknown option: " + opt);
showUsage();
@@ -897,6 +914,20 @@ public final class Pm {
final Uri apkURI;
final Uri verificationURI;
+ final Uri originatingURI;
+ final Uri referrerURI;
+
+ if (originatingUriString != null) {
+ originatingURI = Uri.parse(originatingUriString);
+ } else {
+ originatingURI = null;
+ }
+
+ if (referrer != null) {
+ referrerURI = Uri.parse(referrer);
+ } else {
+ referrerURI = null;
+ }
// Populate apkURI, must be present
final String apkFilePath = nextArg();
@@ -920,8 +951,11 @@ public final class Pm {
PackageInstallObserver obs = new PackageInstallObserver();
try {
- mPm.installPackageWithVerification(apkURI, obs, installFlags, installerPackageName,
- verificationURI, null, encryptionParams);
+ VerificationParams verificationParams = new VerificationParams(verificationURI,
+ originatingURI, referrerURI, null);
+
+ mPm.installPackageWithVerificationAndEncryption(apkURI, obs, installFlags,
+ installerPackageName, verificationParams, encryptionParams);
synchronized (obs) {
while (!obs.finished) {
@@ -1441,7 +1475,8 @@ public final class Pm {
System.err.println(" pm list libraries");
System.err.println(" pm path PACKAGE");
System.err.println(" pm install [-l] [-r] [-t] [-i INSTALLER_PACKAGE_NAME] [-s] [-f]");
- System.err.println(" [--algo <algorithm name> --key <key-in-hex> --iv <IV-in-hex>] PATH");
+ System.err.println(" [--algo <algorithm name> --key <key-in-hex> --iv <IV-in-hex>]");
+ System.err.println(" [--originating-uri <URI>] [--referrer <URI>] PATH");
System.err.println(" pm uninstall [-k] PACKAGE");
System.err.println(" pm clear PACKAGE");
System.err.println(" pm enable PACKAGE_OR_COMPONENT");
diff --git a/cmds/svc/src/com/android/commands/svc/PowerCommand.java b/cmds/svc/src/com/android/commands/svc/PowerCommand.java
index deef2a3..ec3ec3e 100644
--- a/cmds/svc/src/com/android/commands/svc/PowerCommand.java
+++ b/cmds/svc/src/com/android/commands/svc/PowerCommand.java
@@ -37,7 +37,7 @@ public class PowerCommand extends Svc.Command {
public String longHelp() {
return shortHelp() + "\n"
+ "\n"
- + "usage: svc power stayon [true|false|usb|ac]\n"
+ + "usage: svc power stayon [true|false|usb|ac|wireless]\n"
+ " Set the 'keep awake while plugged in' setting.\n";
}
@@ -48,7 +48,8 @@ public class PowerCommand extends Svc.Command {
int val;
if ("true".equals(args[2])) {
val = BatteryManager.BATTERY_PLUGGED_AC |
- BatteryManager.BATTERY_PLUGGED_USB;
+ BatteryManager.BATTERY_PLUGGED_USB |
+ BatteryManager.BATTERY_PLUGGED_WIRELESS;
}
else if ("false".equals(args[2])) {
val = 0;
@@ -56,8 +57,9 @@ public class PowerCommand extends Svc.Command {
val = BatteryManager.BATTERY_PLUGGED_USB;
} else if ("ac".equals(args[2])) {
val = BatteryManager.BATTERY_PLUGGED_AC;
- }
- else {
+ } else if ("wireless".equals(args[2])) {
+ val = BatteryManager.BATTERY_PLUGGED_WIRELESS;
+ } else {
break fail;
}
IPowerManager pm
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 809acac..395a79c 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -74,7 +74,7 @@ import android.view.ViewGroup.LayoutParams;
import android.view.ViewManager;
import android.view.Window;
import android.view.WindowManager;
-import android.view.WindowManagerImpl;
+import android.view.WindowManagerGlobal;
import android.view.accessibility.AccessibilityEvent;
import android.widget.AdapterView;
@@ -4733,6 +4733,29 @@ public class Activity extends ContextThemeWrapper
mLoaderManager.dump(prefix + " ", fd, writer, args);
}
mFragments.dump(prefix, fd, writer, args);
+ writer.print(prefix); writer.println("View Hierarchy:");
+ dumpViewHierarchy(prefix + " ", writer, getWindow().getDecorView());
+ }
+
+ private void dumpViewHierarchy(String prefix, PrintWriter writer, View view) {
+ writer.print(prefix);
+ if (view == null) {
+ writer.println("null");
+ return;
+ }
+ writer.println(view.toString());
+ if (!(view instanceof ViewGroup)) {
+ return;
+ }
+ ViewGroup grp = (ViewGroup)view;
+ final int N = grp.getChildCount();
+ if (N <= 0) {
+ return;
+ }
+ prefix = prefix + " ";
+ for (int i=0; i<N; i++) {
+ dumpViewHierarchy(prefix, writer, grp.getChildAt(i));
+ }
}
/**
@@ -4995,7 +5018,9 @@ public class Activity extends ContextThemeWrapper
mEmbeddedID = id;
mLastNonConfigurationInstances = lastNonConfigurationInstances;
- mWindow.setWindowManager(null, mToken, mComponent.flattenToString(),
+ mWindow.setWindowManager(
+ (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
+ mToken, mComponent.flattenToString(),
(info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
if (mParent != null) {
mWindow.setContainer(mParent.getWindow());
@@ -5042,7 +5067,7 @@ public class Activity extends ContextThemeWrapper
if (mStopped) {
mStopped = false;
if (mToken != null && mParent == null) {
- WindowManagerImpl.getDefault().setStoppedState(mToken, false);
+ WindowManagerGlobal.getInstance().setStoppedState(mToken, false);
}
synchronized (mManagedCursors) {
@@ -5142,7 +5167,7 @@ public class Activity extends ContextThemeWrapper
}
if (mToken != null && mParent == null) {
- WindowManagerImpl.getDefault().setStoppedState(mToken, true);
+ WindowManagerGlobal.getInstance().setStoppedState(mToken, true);
}
mFragments.dispatchStop();
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 2c6d5d9..58e6616 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -30,6 +30,7 @@ import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Point;
+import android.hardware.display.DisplayManager;
import android.os.Binder;
import android.os.Bundle;
import android.os.Debug;
@@ -366,7 +367,7 @@ public class ActivityManager {
* (which tends to consume a lot more RAM).
* @hide
*/
- static public boolean isHighEndGfx(Display display) {
+ static public boolean isHighEndGfx() {
MemInfoReader reader = new MemInfoReader();
reader.readMemInfo();
if (reader.getTotalSize() >= (512*1024*1024)) {
@@ -374,6 +375,8 @@ public class ActivityManager {
// we can afford the overhead of graphics acceleration.
return true;
}
+
+ Display display = DisplayManager.getInstance().getRealDisplay(Display.DEFAULT_DISPLAY);
Point p = new Point();
display.getRealSize(p);
int pixels = p.x * p.y;
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 7eb86f4..4740e53 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -42,6 +42,7 @@ import android.database.sqlite.SQLiteDebug;
import android.database.sqlite.SQLiteDebug.DbStats;
import android.graphics.Bitmap;
import android.graphics.Canvas;
+import android.hardware.display.DisplayManager;
import android.net.IConnectivityManager;
import android.net.Proxy;
import android.net.ProxyProperties;
@@ -79,8 +80,9 @@ import android.view.ViewManager;
import android.view.ViewRootImpl;
import android.view.Window;
import android.view.WindowManager;
-import android.view.WindowManagerImpl;
+import android.view.WindowManagerGlobal;
import android.renderscript.RenderScript;
+import android.security.AndroidKeyStoreProvider;
import com.android.internal.os.BinderInternal;
import com.android.internal.os.RuntimeInit;
@@ -95,6 +97,7 @@ import java.io.IOException;
import java.io.PrintWriter;
import java.lang.ref.WeakReference;
import java.net.InetAddress;
+import java.security.Security;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
@@ -1055,7 +1058,7 @@ public final class ActivityThread {
@Override
public void dumpGfxInfo(FileDescriptor fd, String[] args) {
dumpGraphicsInfo(fd);
- WindowManagerImpl.getDefault().dumpGfxInfo(fd);
+ WindowManagerGlobal.getInstance().dumpGfxInfo(fd);
}
@Override
@@ -1553,13 +1556,23 @@ public final class ActivityThread {
if (dm != null && !forceUpdate) {
return dm;
}
+
+ DisplayManager displayManager = DisplayManager.getInstance();
+ if (displayManager == null) {
+ // may be null early in system startup
+ dm = new DisplayMetrics();
+ dm.setToDefaults();
+ return dm;
+ }
+
if (dm == null) {
dm = new DisplayMetrics();
mDisplayMetrics.put(ci, dm);
}
+
CompatibilityInfoHolder cih = new CompatibilityInfoHolder();
cih.set(ci);
- Display d = WindowManagerImpl.getDefault().makeCompatible(cih).getDefaultDisplay();
+ Display d = displayManager.getCompatibleDisplay(Display.DEFAULT_DISPLAY, cih);
d.getMetrics(dm);
//Slog.i("foo", "New metrics: w=" + metrics.widthPixels + " h="
// + metrics.heightPixels + " den=" + metrics.density
@@ -2631,7 +2644,7 @@ public final class ActivityThread {
r.mPendingRemoveWindowManager.removeViewImmediate(r.mPendingRemoveWindow);
IBinder wtoken = r.mPendingRemoveWindow.getWindowToken();
if (wtoken != null) {
- WindowManagerImpl.getDefault().closeAll(wtoken,
+ WindowManagerGlobal.getInstance().closeAll(wtoken,
r.activity.getClass().getName(), "Activity");
}
}
@@ -3166,7 +3179,7 @@ public final class ActivityThread {
apk.mCompatibilityInfo.set(data.info);
}
handleConfigurationChanged(mConfiguration, data.info);
- WindowManagerImpl.getDefault().reportNewConfiguration(mConfiguration);
+ WindowManagerGlobal.getInstance().reportNewConfiguration(mConfiguration);
}
private void deliverResults(ActivityClientRecord r, List<ResultInfo> results) {
@@ -3355,7 +3368,7 @@ public final class ActivityThread {
}
}
if (wtoken != null && r.mPendingRemoveWindow == null) {
- WindowManagerImpl.getDefault().closeAll(wtoken,
+ WindowManagerGlobal.getInstance().closeAll(wtoken,
r.activity.getClass().getName(), "Activity");
}
r.activity.mDecor = null;
@@ -3367,7 +3380,7 @@ public final class ActivityThread {
// by the app will leak. Well we try to warning them a lot
// about leaking windows, because that is a bug, so if they are
// using this recreate facility then they get to live with leaks.
- WindowManagerImpl.getDefault().closeAll(token,
+ WindowManagerGlobal.getInstance().closeAll(token,
r.activity.getClass().getName(), "Activity");
}
@@ -3795,7 +3808,7 @@ public final class ActivityThread {
}
// Cleanup hardware accelerated stuff
- WindowManagerImpl.getDefault().trimLocalMemory();
+ WindowManagerGlobal.getInstance().trimLocalMemory();
freeTextLayoutCachesIfNeeded(configDiff);
@@ -3935,7 +3948,7 @@ public final class ActivityThread {
final void handleTrimMemory(int level) {
if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Trimming memory to level: " + level);
- final WindowManagerImpl windowManager = WindowManagerImpl.getDefault();
+ final WindowManagerGlobal windowManager = WindowManagerGlobal.getInstance();
windowManager.startTrimMemory(level);
ArrayList<ComponentCallbacks2> callbacks;
@@ -3948,7 +3961,7 @@ public final class ActivityThread {
callbacks.get(i).onTrimMemory(level);
}
- windowManager.endTrimMemory();
+ windowManager.endTrimMemory();
}
private void setupGraphicsSupport(LoadedApk info, File cacheDir) {
@@ -4001,8 +4014,7 @@ public final class ActivityThread {
// Persistent processes on low-memory devices do not get to
// use hardware accelerated drawing, since this can add too much
// overhead to the process.
- final Display display = WindowManagerImpl.getDefault().getDefaultDisplay();
- if (!ActivityManager.isHighEndGfx(display)) {
+ if (!ActivityManager.isHighEndGfx()) {
HardwareRenderer.disable(false);
}
}
@@ -4055,13 +4067,14 @@ public final class ActivityThread {
final ContextImpl appContext = new ContextImpl();
appContext.init(data.info, null, this);
- final File cacheDir = appContext.getCacheDir();
-
- // Provide a usable directory for temporary files
- System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath());
+ if (!Process.isIsolated()) {
+ final File cacheDir = appContext.getCacheDir();
- setupGraphicsSupport(data.info, cacheDir);
+ // Provide a usable directory for temporary files
+ System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath());
+ setupGraphicsSupport(data.info, cacheDir);
+ }
/**
* For system applications on userdebug/eng builds, log stack
* traces of disk and network access to dropbox for analysis.
@@ -4799,6 +4812,8 @@ public final class ActivityThread {
// StrictMode) on debug builds, but using DropBox, not logs.
CloseGuard.setEnabled(false);
+ Security.addProvider(new AndroidKeyStoreProvider());
+
Process.setArgV0("<pre-initialized>");
Looper.prepareMainLooper();
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 115c867..7ab7086 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -43,6 +43,7 @@ import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.pm.ManifestDigest;
import android.content.pm.UserInfo;
+import android.content.pm.VerificationParams;
import android.content.pm.VerifierDeviceIdentity;
import android.content.res.Resources;
import android.content.res.XmlResourceParser;
@@ -984,6 +985,18 @@ final class ApplicationPackageManager extends PackageManager {
}
@Override
+ public void installPackageWithVerificationAndEncryption(Uri packageURI,
+ IPackageInstallObserver observer, int flags, String installerPackageName,
+ VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) {
+ try {
+ mPM.installPackageWithVerificationAndEncryption(packageURI, observer, flags,
+ installerPackageName, verificationParams, encryptionParams);
+ } catch (RemoteException e) {
+ // Should never happen!
+ }
+ }
+
+ @Override
public void verifyPendingInstall(int id, int response) {
try {
mPM.verifyPendingInstall(id, response);
@@ -1106,7 +1119,17 @@ final class ApplicationPackageManager extends PackageManager {
public void addPreferredActivity(IntentFilter filter,
int match, ComponentName[] set, ComponentName activity) {
try {
- mPM.addPreferredActivity(filter, match, set, activity);
+ mPM.addPreferredActivity(filter, match, set, activity, UserHandle.myUserId());
+ } catch (RemoteException e) {
+ // Should never happen!
+ }
+ }
+
+ @Override
+ public void addPreferredActivity(IntentFilter filter, int match,
+ ComponentName[] set, ComponentName activity, int userId) {
+ try {
+ mPM.addPreferredActivity(filter, match, set, activity, userId);
} catch (RemoteException e) {
// Should never happen!
}
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 08947a4..0543f05 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -95,7 +95,9 @@ import android.telephony.TelephonyManager;
import android.content.ClipboardManager;
import android.util.AndroidRuntimeException;
import android.util.Log;
+import android.view.CompatibilityInfoHolder;
import android.view.ContextThemeWrapper;
+import android.view.Display;
import android.view.WindowManagerImpl;
import android.view.accessibility.AccessibilityManager;
import android.view.inputmethod.InputMethodManager;
@@ -499,8 +501,8 @@ class ContextImpl extends Context {
registerService(WINDOW_SERVICE, new ServiceFetcher() {
public Object getService(ContextImpl ctx) {
- return WindowManagerImpl.getDefault().makeCompatible(
- ctx.mPackageInfo.mCompatibilityInfo);
+ return new WindowManagerImpl(ctx.getOuterContext(),
+ Display.DEFAULT_DISPLAY);
}});
registerService(USER_SERVICE, new ServiceFetcher() {
@@ -1609,6 +1611,11 @@ class ContextImpl extends Context {
return mRestricted;
}
+ @Override
+ public CompatibilityInfoHolder getCompatibilityInfo() {
+ return mPackageInfo.mCompatibilityInfo;
+ }
+
private File getDataDirFile() {
if (mPackageInfo != null) {
return mPackageInfo.getDataDirFile();
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index c1e11bb..52a6557 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -428,92 +428,26 @@ final class FragmentManagerImpl extends FragmentManager {
}
};
- private void logViewHierarchy(String prefix, View view) {
- StringBuilder builder = new StringBuilder(128);
- builder.append(prefix);
- DebugUtils.buildShortClassTag(view, builder);
- int id = view.getId();
- if (id != -1) {
- builder.append(" #");
- builder.append(Integer.toHexString(id));
- if (id != 0 && id != -1) {
- try {
- String pkgname;
- switch (id&0xff000000) {
- case 0x7f000000:
- pkgname="app";
- break;
- case 0x01000000:
- pkgname="android";
- break;
- default:
- pkgname = view.getResources().getResourcePackageName(id);
- break;
- }
- String typename = view.getResources().getResourceTypeName(id);
- String entryname = view.getResources().getResourceEntryName(id);
- builder.append(" (");
- builder.append(pkgname);
- builder.append(":");
- builder.append(typename);
- builder.append("/");
- builder.append(entryname);
- builder.append(")");
- } catch (Resources.NotFoundException e) {
- }
- }
- }
- Object tag = view.getTag();
- if (tag != null) {
- builder.append(" ");
- builder.append(tag);
- }
- builder.append("}");
- Log.e(TAG, builder.toString());
-
- if (!(view instanceof ViewGroup)) {
- return;
- }
- ViewGroup grp = (ViewGroup)view;
- final int N = grp.getChildCount();
- if (N <= 0) {
- return;
- }
- prefix = prefix + " ";
- for (int i=0; i<N; i++) {
- logViewHierarchy(prefix, grp.getChildAt(i));
- }
- }
-
- private void throwNoViewFound(Fragment f) {
- String msg = "No view found for id 0x"
- + Integer.toHexString(f.mContainerId) + " ("
- + f.getResources().getResourceName(f.mContainerId)
- + ") for fragment " + f;
- Log.e(TAG, msg);
- Log.e(TAG, "Activity state:");
- if (f.getActivity() != null) {
+ private void throwException(RuntimeException ex) {
+ Log.e(TAG, ex.getMessage());
+ LogWriter logw = new LogWriter(Log.ERROR, TAG);
+ PrintWriter pw = new PrintWriter(logw);
+ if (mActivity != null) {
+ Log.e(TAG, "Activity state:");
try {
- LogWriter logw = new LogWriter(Log.ERROR, TAG);
- PrintWriter pw = new PrintWriter(logw);
- f.getActivity().dump(" ", null, pw, new String[] { });
+ mActivity.dump(" ", null, pw, new String[] { });
} catch (Exception e) {
Log.e(TAG, "Failed dumping state", e);
}
} else {
- Log.e(TAG, " NULL ACTIVITY!");
- }
- Log.e(TAG, "View hierarchy:");
- if (f.getActivity() != null) {
+ Log.e(TAG, "Fragment manager state:");
try {
- logViewHierarchy(" ", f.getActivity().getWindow().getDecorView());
+ dump(" ", null, pw, new String[] { });
} catch (Exception e) {
- Log.e(TAG, "Failed dumping view hierarchy", e);
+ Log.e(TAG, "Failed dumping state", e);
}
- } else {
- Log.e(TAG, " NULL ACTIVITY!");
}
- throw new IllegalArgumentException(msg);
+ throw ex;
}
@Override
@@ -608,8 +542,8 @@ final class FragmentManagerImpl extends FragmentManager {
@Override
public void putFragment(Bundle bundle, String key, Fragment fragment) {
if (fragment.mIndex < 0) {
- throw new IllegalStateException("Fragment " + fragment
- + " is not currently in the FragmentManager");
+ throwException(new IllegalStateException("Fragment " + fragment
+ + " is not currently in the FragmentManager"));
}
bundle.putInt(key, fragment.mIndex);
}
@@ -621,13 +555,13 @@ final class FragmentManagerImpl extends FragmentManager {
return null;
}
if (index >= mActive.size()) {
- throw new IllegalStateException("Fragement no longer exists for key "
- + key + ": index " + index);
+ throwException(new IllegalStateException("Fragement no longer exists for key "
+ + key + ": index " + index));
}
Fragment f = mActive.get(index);
if (f == null) {
- throw new IllegalStateException("Fragement no longer exists for key "
- + key + ": index " + index);
+ throwException(new IllegalStateException("Fragement no longer exists for key "
+ + key + ": index " + index));
}
return f;
}
@@ -635,8 +569,8 @@ final class FragmentManagerImpl extends FragmentManager {
@Override
public Fragment.SavedState saveFragmentInstanceState(Fragment fragment) {
if (fragment.mIndex < 0) {
- throw new IllegalStateException("Fragment " + fragment
- + " is not currently in the FragmentManager");
+ throwException(new IllegalStateException("Fragment " + fragment
+ + " is not currently in the FragmentManager"));
}
if (fragment.mState > Fragment.INITIALIZING) {
Bundle result = saveFragmentBasicState(fragment);
@@ -913,7 +847,11 @@ final class FragmentManagerImpl extends FragmentManager {
if (f.mContainerId != 0) {
container = (ViewGroup)mActivity.findViewById(f.mContainerId);
if (container == null && !f.mRestored) {
- throwNoViewFound(f);
+ throwException(new IllegalArgumentException(
+ "No view found for id 0x"
+ + Integer.toHexString(f.mContainerId) + " ("
+ + f.getResources().getResourceName(f.mContainerId)
+ + ") for fragment " + f));
}
}
f.mContainer = container;
@@ -1674,12 +1612,9 @@ final class FragmentManagerImpl extends FragmentManager {
Fragment f = mActive.get(i);
if (f != null) {
if (f.mIndex < 0) {
- String msg = "Failure saving state: active " + f
- + " has cleared index: " + f.mIndex;
- Slog.e(TAG, msg);
- dump(" ", null, new PrintWriter(new LogWriter(
- Log.ERROR, TAG, Log.LOG_ID_SYSTEM)), new String[] { });
- throw new IllegalStateException(msg);
+ throwException(new IllegalStateException(
+ "Failure saving state: active " + f
+ + " has cleared index: " + f.mIndex));
}
haveFragments = true;
@@ -1692,12 +1627,9 @@ final class FragmentManagerImpl extends FragmentManager {
if (f.mTarget != null) {
if (f.mTarget.mIndex < 0) {
- String msg = "Failure saving state: " + f
- + " has target not in fragment manager: " + f.mTarget;
- Slog.e(TAG, msg);
- dump(" ", null, new PrintWriter(new LogWriter(
- Log.ERROR, TAG, Log.LOG_ID_SYSTEM)), new String[] { });
- throw new IllegalStateException(msg);
+ throwException(new IllegalStateException(
+ "Failure saving state: " + f
+ + " has target not in fragment manager: " + f.mTarget));
}
if (fs.mSavedFragmentState == null) {
fs.mSavedFragmentState = new Bundle();
@@ -1736,12 +1668,9 @@ final class FragmentManagerImpl extends FragmentManager {
for (int i=0; i<N; i++) {
added[i] = mAdded.get(i).mIndex;
if (added[i] < 0) {
- String msg = "Failure saving state: active " + mAdded.get(i)
- + " has cleared index: " + added[i];
- Slog.e(TAG, msg);
- dump(" ", null, new PrintWriter(new LogWriter(
- Log.ERROR, TAG, Log.LOG_ID_SYSTEM)), new String[] { });
- throw new IllegalStateException(msg);
+ throwException(new IllegalStateException(
+ "Failure saving state: active " + mAdded.get(i)
+ + " has cleared index: " + added[i]));
}
if (DEBUG) Log.v(TAG, "saveAllState: adding fragment #" + i
+ ": " + mAdded.get(i));
@@ -1846,8 +1775,8 @@ final class FragmentManagerImpl extends FragmentManager {
for (int i=0; i<fms.mAdded.length; i++) {
Fragment f = mActive.get(fms.mAdded[i]);
if (f == null) {
- throw new IllegalStateException(
- "No instantiated fragment for index #" + fms.mAdded[i]);
+ throwException(new IllegalStateException(
+ "No instantiated fragment for index #" + fms.mAdded[i]));
}
f.mAdded = true;
if (DEBUG) Log.v(TAG, "restoreAllState: making added #" + i + ": " + f);
@@ -1875,7 +1804,7 @@ final class FragmentManagerImpl extends FragmentManager {
}
public void attachActivity(Activity activity) {
- if (mActivity != null) throw new IllegalStateException();
+ if (mActivity != null) throw new IllegalStateException("Already attached");
mActivity = activity;
}
diff --git a/core/java/android/app/KeyguardManager.java b/core/java/android/app/KeyguardManager.java
index ef61af7..22a21cd 100644
--- a/core/java/android/app/KeyguardManager.java
+++ b/core/java/android/app/KeyguardManager.java
@@ -16,13 +16,12 @@
package android.app;
-import android.content.Context;
import android.os.Binder;
import android.os.RemoteException;
import android.os.IBinder;
-import android.os.ServiceManager;
import android.view.IWindowManager;
import android.view.IOnKeyguardExitResult;
+import android.view.WindowManagerGlobal;
/**
* Class that can be used to lock and unlock the keyboard. Get an instance of this
@@ -111,7 +110,7 @@ public class KeyguardManager {
KeyguardManager() {
- mWM = IWindowManager.Stub.asInterface(ServiceManager.getService(Context.WINDOW_SERVICE));
+ mWM = WindowManagerGlobal.getWindowManagerService();
}
/**
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index 27843ac..1ad2e6d 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -43,6 +43,7 @@ import android.util.DisplayMetrics;
import android.util.Log;
import android.view.ViewRootImpl;
import android.view.WindowManager;
+import android.view.WindowManagerGlobal;
import java.io.FileOutputStream;
import java.io.IOException;
@@ -689,7 +690,7 @@ public class WallpaperManager {
public void setWallpaperOffsets(IBinder windowToken, float xOffset, float yOffset) {
try {
//Log.v(TAG, "Sending new wallpaper offsets from app...");
- ViewRootImpl.getWindowSession(mContext.getMainLooper()).setWallpaperPosition(
+ WindowManagerGlobal.getWindowSession(mContext.getMainLooper()).setWallpaperPosition(
windowToken, xOffset, yOffset, mWallpaperXStep, mWallpaperYStep);
//Log.v(TAG, "...app returning after sending offsets!");
} catch (RemoteException e) {
@@ -727,7 +728,7 @@ public class WallpaperManager {
int x, int y, int z, Bundle extras) {
try {
//Log.v(TAG, "Sending new wallpaper offsets from app...");
- ViewRootImpl.getWindowSession(mContext.getMainLooper()).sendWallpaperCommand(
+ WindowManagerGlobal.getWindowSession(mContext.getMainLooper()).sendWallpaperCommand(
windowToken, action, x, y, z, extras, false);
//Log.v(TAG, "...app returning after sending offsets!");
} catch (RemoteException e) {
@@ -747,7 +748,7 @@ public class WallpaperManager {
*/
public void clearWallpaperOffsets(IBinder windowToken) {
try {
- ViewRootImpl.getWindowSession(mContext.getMainLooper()).setWallpaperPosition(
+ WindowManagerGlobal.getWindowSession(mContext.getMainLooper()).setWallpaperPosition(
windowToken, -1, -1, -1, -1);
} catch (RemoteException e) {
// Ignore.
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index 8a69c3a..23d8f46 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -279,7 +279,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
final int uid = Binder.getCallingUid();
String missingPerm = null;
- if (uid == mMyUid) {
+ if (UserHandle.isSameApp(uid, mMyUid)) {
return;
}
@@ -340,7 +340,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
final int uid = Binder.getCallingUid();
String missingPerm = null;
- if (uid == mMyUid) {
+ if (UserHandle.isSameApp(uid, mMyUid)) {
return;
}
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index a70bf6c..1460bf5 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -34,6 +34,7 @@ import android.os.Handler;
import android.os.Looper;
import android.os.UserHandle;
import android.util.AttributeSet;
+import android.view.CompatibilityInfoHolder;
import java.io.File;
import java.io.FileInputStream;
@@ -2464,6 +2465,16 @@ public abstract class Context {
public abstract Context createConfigurationContext(Configuration overrideConfiguration);
/**
+ * Gets the compatibility info holder for this context. This information
+ * is provided on a per-application basis and is used to simulate lower density
+ * display metrics for legacy applications.
+ *
+ * @return The compatibility info holder, or null if not required by the application.
+ * @hide
+ */
+ public abstract CompatibilityInfoHolder getCompatibilityInfo();
+
+ /**
* Indicates whether this Context is restricted.
*
* @return True if this Context is restricted, false otherwise.
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index 75842be..3a13725 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -31,6 +31,7 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.UserHandle;
+import android.view.CompatibilityInfoHolder;
import java.io.File;
import java.io.FileInputStream;
@@ -543,4 +544,10 @@ public class ContextWrapper extends Context {
public boolean isRestricted() {
return mBase.isRestricted();
}
+
+ /** @hide */
+ @Override
+ public CompatibilityInfoHolder getCompatibilityInfo() {
+ return mBase.getCompatibilityInfo();
+ }
}
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 0190555..06edf32 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -571,7 +571,7 @@ import java.util.Set;
* <li> {@link #EXTRA_INITIAL_INTENTS}
* <li> {@link #EXTRA_INTENT}
* <li> {@link #EXTRA_KEY_EVENT}
- * <li> {@link #EXTRA_ORIGINATING_URL}
+ * <li> {@link #EXTRA_ORIGINATING_URI}
* <li> {@link #EXTRA_PHONE_NUMBER}
* <li> {@link #EXTRA_REFERRER}
* <li> {@link #EXTRA_REMOTE_INTENT_TOKEN}
@@ -1288,17 +1288,17 @@ public class Intent implements Parcelable, Cloneable {
= "android.intent.extra.NOT_UNKNOWN_SOURCE";
/**
- * Used as a string extra field with {@link #ACTION_INSTALL_PACKAGE} and
- * {@link #ACTION_VIEW} to indicate the URL from which the local APK in the Intent
+ * Used as a URI extra field with {@link #ACTION_INSTALL_PACKAGE} and
+ * {@link #ACTION_VIEW} to indicate the URI from which the local APK in the Intent
* data field originated from.
*/
- public static final String EXTRA_ORIGINATING_URL
- = "android.intent.extra.ORIGINATING_URL";
+ public static final String EXTRA_ORIGINATING_URI
+ = "android.intent.extra.ORIGINATING_URI";
/**
- * Used as a string extra field with {@link #ACTION_INSTALL_PACKAGE} and
- * {@link #ACTION_VIEW} to indicate the HTTP referrer associated with the Intent
- * data field or {@link #EXTRA_ORIGINATING_URL}.
+ * Used as a URI extra field with {@link #ACTION_INSTALL_PACKAGE} and
+ * {@link #ACTION_VIEW} to indicate the HTTP referrer URI associated with the Intent
+ * data field or {@link #EXTRA_ORIGINATING_URI}.
*/
public static final String EXTRA_REFERRER
= "android.intent.extra.REFERRER";
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 22807a4..f266b00 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -39,6 +39,7 @@ import android.content.pm.PermissionInfo;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.pm.UserInfo;
+import android.content.pm.VerificationParams;
import android.content.pm.VerifierDeviceIdentity;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
@@ -200,7 +201,7 @@ interface IPackageManager {
List<PackageInfo> getPreferredPackages(int flags);
void addPreferredActivity(in IntentFilter filter, int match,
- in ComponentName[] set, in ComponentName activity);
+ in ComponentName[] set, in ComponentName activity, int userId);
void replacePreferredActivity(in IntentFilter filter, int match,
in ComponentName[] set, in ComponentName activity);
@@ -362,6 +363,11 @@ interface IPackageManager {
int flags, in String installerPackageName, in Uri verificationURI,
in ManifestDigest manifestDigest, in ContainerEncryptionParams encryptionParams);
+ void installPackageWithVerificationAndEncryption(in Uri packageURI,
+ in IPackageInstallObserver observer, int flags, in String installerPackageName,
+ in VerificationParams verificationParams,
+ in ContainerEncryptionParams encryptionParams);
+
void verifyPendingInstall(int id, int verificationCode);
VerifierDeviceIdentity getVerifierDeviceIdentity();
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index f287ca5..e9e0ee3 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -2227,6 +2227,37 @@ public abstract class PackageManager {
ContainerEncryptionParams encryptionParams);
/**
+ * Similar to
+ * {@link #installPackage(Uri, IPackageInstallObserver, int, String)} but
+ * with an extra verification information provided.
+ *
+ * @param packageURI The location of the package file to install. This can
+ * be a 'file:' or a 'content:' URI.
+ * @param observer An observer callback to get notified when the package
+ * installation is complete.
+ * {@link IPackageInstallObserver#packageInstalled(String, int)}
+ * will be called when that happens. observer may be null to
+ * indicate that no callback is desired.
+ * @param flags - possible values: {@link #INSTALL_FORWARD_LOCK},
+ * {@link #INSTALL_REPLACE_EXISTING}, {@link #INSTALL_ALLOW_TEST}
+ * .
+ * @param installerPackageName Optional package name of the application that
+ * is performing the installation. This identifies which market
+ * the package came from.
+ * @param verificationParams an object that holds signal information to
+ * assist verification. May be {@code null}.
+ * @param encryptionParams if the package to be installed is encrypted,
+ * these parameters describing the encryption and authentication
+ * used. May be {@code null}.
+ *
+ * @hide
+ */
+ public abstract void installPackageWithVerificationAndEncryption(Uri packageURI,
+ IPackageInstallObserver observer, int flags, String installerPackageName,
+ VerificationParams verificationParams,
+ ContainerEncryptionParams encryptionParams);
+
+ /**
* Allows a package listening to the
* {@link Intent#ACTION_PACKAGE_NEEDS_VERIFICATION package verification
* broadcast} to respond to the package manager. The response must include
@@ -2460,6 +2491,17 @@ public abstract class PackageManager {
ComponentName[] set, ComponentName activity);
/**
+ * Same as {@link #addPreferredActivity(IntentFilter, int,
+ ComponentName[], ComponentName)}, but with a specific userId to apply the preference
+ to.
+ * @hide
+ */
+ public void addPreferredActivity(IntentFilter filter, int match,
+ ComponentName[] set, ComponentName activity, int userId) {
+ throw new RuntimeException("Not implemented. Must override in a subclass.");
+ }
+
+ /**
* @deprecated This is a protected API that should not have been available
* to third party applications. It is the platform's responsibility for
* assigning preferred activities and this can not be directly modified.
diff --git a/core/java/android/content/pm/VerificationParams.aidl b/core/java/android/content/pm/VerificationParams.aidl
new file mode 100644
index 0000000..5bb7f69
--- /dev/null
+++ b/core/java/android/content/pm/VerificationParams.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content.pm;
+
+parcelable VerificationParams;
diff --git a/core/java/android/content/pm/VerificationParams.java b/core/java/android/content/pm/VerificationParams.java
new file mode 100644
index 0000000..9bec87e
--- /dev/null
+++ b/core/java/android/content/pm/VerificationParams.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content.pm;
+
+import android.content.pm.ManifestDigest;
+import android.net.Uri;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Represents verification parameters used to verify packages to be installed.
+ *
+ * @hide
+ */
+public class VerificationParams implements Parcelable {
+ /** What we print out first when toString() is called. */
+ private static final String TO_STRING_PREFIX = "VerificationParams{";
+
+ /** The location of the supplementary verification file. */
+ private final Uri mVerificationURI;
+
+ /** URI referencing where the package was downloaded from. */
+ private final Uri mOriginatingURI;
+
+ /** HTTP referrer URI associated with the originatingURI. */
+ private final Uri mReferrer;
+
+ /**
+ * An object that holds the digest of the package which can be used to
+ * verify ownership.
+ */
+ private final ManifestDigest mManifestDigest;
+
+ /**
+ * Creates verification specifications for installing with application verification.
+ *
+ * @param verificationURI The location of the supplementary verification
+ * file. This can be a 'file:' or a 'content:' URI. May be {@code null}.
+ * @param originatingURI URI referencing where the package was downloaded
+ * from. May be {@code null}.
+ * @param referrer HTTP referrer URI associated with the originatingURI.
+ * May be {@code null}.
+ * @param manifestDigest an object that holds the digest of the package
+ * which can be used to verify ownership. May be {@code null}.
+ */
+ public VerificationParams(Uri verificationURI, Uri originatingURI, Uri referrer,
+ ManifestDigest manifestDigest) {
+ mVerificationURI = verificationURI;
+ mOriginatingURI = originatingURI;
+ mReferrer = referrer;
+ mManifestDigest = manifestDigest;
+ }
+
+ public Uri getVerificationURI() {
+ return mVerificationURI;
+ }
+
+ public Uri getOriginatingURI() {
+ return mOriginatingURI;
+ }
+
+ public Uri getReferrer() {
+ return mReferrer;
+ }
+
+ public ManifestDigest getManifestDigest() {
+ return mManifestDigest;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+
+ if (!(o instanceof VerificationParams)) {
+ return false;
+ }
+
+ final VerificationParams other = (VerificationParams) o;
+
+ if (mVerificationURI == null && other.mVerificationURI != null) {
+ return false;
+ }
+ if (!mVerificationURI.equals(other.mVerificationURI)) {
+ return false;
+ }
+
+ if (mOriginatingURI == null && other.mOriginatingURI != null) {
+ return false;
+ }
+ if (!mOriginatingURI.equals(other.mOriginatingURI)) {
+ return false;
+ }
+
+ if (mReferrer == null && other.mReferrer != null) {
+ return false;
+ }
+ if (!mReferrer.equals(other.mReferrer)) {
+ return false;
+ }
+
+ if (mManifestDigest == null && other.mManifestDigest != null) {
+ return false;
+ }
+ if (mManifestDigest != null && !mManifestDigest.equals(other.mManifestDigest)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 3;
+
+ hash += 5 * (mVerificationURI==null?1:mVerificationURI.hashCode());
+ hash += 7 * (mOriginatingURI==null?1:mOriginatingURI.hashCode());
+ hash += 11 * (mReferrer==null?1:mReferrer.hashCode());
+ hash += 13 * (mManifestDigest==null?1:mManifestDigest.hashCode());
+
+ return hash;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder(TO_STRING_PREFIX);
+
+ sb.append("mVerificationURI=");
+ sb.append(mVerificationURI.toString());
+ sb.append(",mOriginatingURI=");
+ sb.append(mOriginatingURI.toString());
+ sb.append(",mReferrer=");
+ sb.append(mReferrer.toString());
+ sb.append(",mManifestDigest=");
+ sb.append(mManifestDigest.toString());
+ sb.append('}');
+
+ return sb.toString();
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeParcelable(mVerificationURI, 0);
+ dest.writeParcelable(mOriginatingURI, 0);
+ dest.writeParcelable(mReferrer, 0);
+ dest.writeParcelable(mManifestDigest, 0);
+ }
+
+
+ private VerificationParams(Parcel source) {
+ mVerificationURI = source.readParcelable(Uri.class.getClassLoader());
+ mOriginatingURI = source.readParcelable(Uri.class.getClassLoader());
+ mReferrer = source.readParcelable(Uri.class.getClassLoader());
+ mManifestDigest = source.readParcelable(ManifestDigest.class.getClassLoader());
+ }
+
+ public static final Parcelable.Creator<VerificationParams> CREATOR =
+ new Parcelable.Creator<VerificationParams>() {
+ public VerificationParams createFromParcel(Parcel source) {
+ return new VerificationParams(source);
+ }
+
+ public VerificationParams[] newArray(int size) {
+ return new VerificationParams[size];
+ }
+ };
+}
diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java
index 640044b..a73115c 100644
--- a/core/java/android/hardware/display/DisplayManager.java
+++ b/core/java/android/hardware/display/DisplayManager.java
@@ -17,12 +17,20 @@
package android.hardware.display;
import android.content.Context;
+import android.os.Handler;
import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.Log;
+import android.util.SparseArray;
+import android.view.CompatibilityInfoHolder;
+import android.view.Display;
import android.view.DisplayInfo;
+import java.util.ArrayList;
+
/**
* Manages the properties, media routing and power state of attached displays.
* <p>
@@ -34,25 +42,41 @@ import android.view.DisplayInfo;
*/
public final class DisplayManager {
private static final String TAG = "DisplayManager";
+ private static final boolean DEBUG = false;
+
+ private static final int MSG_DISPLAY_ADDED = 1;
+ private static final int MSG_DISPLAY_REMOVED = 2;
+ private static final int MSG_DISPLAY_CHANGED = 3;
private static DisplayManager sInstance;
private final IDisplayManager mDm;
+ // Guarded by mDisplayLock
+ private final Object mDisplayLock = new Object();
+ private final ArrayList<DisplayListenerDelegate> mDisplayListeners =
+ new ArrayList<DisplayListenerDelegate>();
+
+
private DisplayManager(IDisplayManager dm) {
mDm = dm;
}
/**
* Gets an instance of the display manager.
- * @return The display manager instance.
+ *
+ * @return The display manager instance, may be null early in system startup
+ * before the display manager has been fully initialized.
+ *
* @hide
*/
public static DisplayManager getInstance() {
synchronized (DisplayManager.class) {
if (sInstance == null) {
IBinder b = ServiceManager.getService(Context.DISPLAY_SERVICE);
- sInstance = new DisplayManager(IDisplayManager.Stub.asInterface(b));
+ if (b != null) {
+ sInstance = new DisplayManager(IDisplayManager.Stub.asInterface(b));
+ }
}
return sInstance;
}
@@ -74,4 +98,161 @@ public final class DisplayManager {
return false;
}
}
+
+ /**
+ * Gets information about a logical display.
+ *
+ * The display metrics may be adjusted to provide compatibility
+ * for legacy applications.
+ *
+ * @param displayId The logical display id.
+ * @param applicationContext The application context from which to obtain
+ * compatible metrics.
+ * @return The display object.
+ */
+ public Display getDisplay(int displayId, Context applicationContext) {
+ if (applicationContext == null) {
+ throw new IllegalArgumentException("applicationContext must not be null");
+ }
+
+ CompatibilityInfoHolder cih = null;
+ if (displayId == Display.DEFAULT_DISPLAY) {
+ cih = applicationContext.getCompatibilityInfo();
+ }
+ return getCompatibleDisplay(displayId, cih);
+ }
+
+ /**
+ * Gets information about a logical display.
+ *
+ * The display metrics may be adjusted to provide compatibility
+ * for legacy applications.
+ *
+ * @param displayId The logical display id.
+ * @param cih The compatibility info, or null if none is required.
+ * @return The display object.
+ *
+ * @hide
+ */
+ public Display getCompatibleDisplay(int displayId, CompatibilityInfoHolder cih) {
+ return new Display(displayId, cih);
+ }
+
+ /**
+ * Gets information about a logical display without applying any compatibility metrics.
+ *
+ * @param displayId The logical display id.
+ * @return The display object.
+ *
+ * @hide
+ */
+ public Display getRealDisplay(int displayId) {
+ return getCompatibleDisplay(displayId, null);
+ }
+
+ /**
+ * Registers an display listener to receive notifications about when
+ * displays are added, removed or changed.
+ *
+ * @param listener The listener to register.
+ * @param handler The handler on which the listener should be invoked, or null
+ * if the listener should be invoked on the calling thread's looper.
+ *
+ * @see #unregisterDisplayListener
+ */
+ public void registerDisplayListener(DisplayListener listener, Handler handler) {
+ if (listener == null) {
+ throw new IllegalArgumentException("listener must not be null");
+ }
+
+ synchronized (mDisplayLock) {
+ int index = findDisplayListenerLocked(listener);
+ if (index < 0) {
+ mDisplayListeners.add(new DisplayListenerDelegate(listener, handler));
+ }
+ }
+ }
+
+ /**
+ * Unregisters an input device listener.
+ *
+ * @param listener The listener to unregister.
+ *
+ * @see #registerDisplayListener
+ */
+ public void unregisterDisplayListener(DisplayListener listener) {
+ if (listener == null) {
+ throw new IllegalArgumentException("listener must not be null");
+ }
+
+ synchronized (mDisplayLock) {
+ int index = findDisplayListenerLocked(listener);
+ if (index >= 0) {
+ DisplayListenerDelegate d = mDisplayListeners.get(index);
+ d.removeCallbacksAndMessages(null);
+ mDisplayListeners.remove(index);
+ }
+ }
+ }
+
+ private int findDisplayListenerLocked(DisplayListener listener) {
+ final int numListeners = mDisplayListeners.size();
+ for (int i = 0; i < numListeners; i++) {
+ if (mDisplayListeners.get(i).mListener == listener) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Listens for changes in available display devices.
+ */
+ public interface DisplayListener {
+ /**
+ * Called whenever a logical display has been added to the system.
+ * Use {@link DisplayManager#getDisplay} to get more information about the display.
+ *
+ * @param displayId The id of the logical display that was added.
+ */
+ void onDisplayAdded(int displayId);
+
+ /**
+ * Called whenever a logical display has been removed from the system.
+ *
+ * @param displayId The id of the logical display that was removed.
+ */
+ void onDisplayRemoved(int displayId);
+
+ /**
+ * Called whenever the properties of a logical display have changed.
+ *
+ * @param displayId The id of the logical display that changed.
+ */
+ void onDisplayChanged(int displayId);
+ }
+
+ private static final class DisplayListenerDelegate extends Handler {
+ public final DisplayListener mListener;
+
+ public DisplayListenerDelegate(DisplayListener listener, Handler handler) {
+ super(handler != null ? handler.getLooper() : Looper.myLooper());
+ mListener = listener;
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_DISPLAY_ADDED:
+ mListener.onDisplayAdded(msg.arg1);
+ break;
+ case MSG_DISPLAY_REMOVED:
+ mListener.onDisplayRemoved(msg.arg1);
+ break;
+ case MSG_DISPLAY_CHANGED:
+ mListener.onDisplayChanged(msg.arg1);
+ break;
+ }
+ }
+ }
}
diff --git a/core/java/android/hardware/usb/IUsbManager.aidl b/core/java/android/hardware/usb/IUsbManager.aidl
index 9bab797..98bd4f5 100644
--- a/core/java/android/hardware/usb/IUsbManager.aidl
+++ b/core/java/android/hardware/usb/IUsbManager.aidl
@@ -87,4 +87,12 @@ interface IUsbManager
/* Sets the file path for USB mass storage backing file. */
void setMassStorageBackingFile(String path);
+
+ /* Allow USB debugging from the attached host. If alwaysAllow is true, add the
+ * the public key to list of host keys that the user has approved.
+ */
+ void allowUsbDebugging(boolean alwaysAllow, String publicKey);
+
+ /* Deny USB debugging from the attached host */
+ void denyUsbDebugging();
}
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index a9de289..d5b9edc 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -39,7 +39,6 @@ import android.text.method.MovementMethod;
import android.util.Log;
import android.util.PrintWriterPrinter;
import android.util.Printer;
-import android.view.Display;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.LayoutInflater;
@@ -630,7 +629,7 @@ public class InputMethodService extends AbstractInputMethodService {
if (mWindow != null) {
throw new IllegalStateException("Must be called before onCreate()");
}
- if (ActivityManager.isHighEndGfx(new Display(Display.DEFAULT_DISPLAY, null))) {
+ if (ActivityManager.isHighEndGfx()) {
mHardwareAccelerated = true;
return true;
}
diff --git a/core/java/android/net/MobileDataStateTracker.java b/core/java/android/net/MobileDataStateTracker.java
index 00438a1..d59fa6a 100644
--- a/core/java/android/net/MobileDataStateTracker.java
+++ b/core/java/android/net/MobileDataStateTracker.java
@@ -184,8 +184,17 @@ public class MobileDataStateTracker implements NetworkStateTracker {
if (!TextUtils.equals(apnType, mApnType)) {
return;
}
- mNetworkInfo.setSubtype(TelephonyManager.getDefault().getNetworkType(),
- TelephonyManager.getDefault().getNetworkTypeName());
+
+ int oldSubtype = mNetworkInfo.getSubtype();
+ int newSubType = TelephonyManager.getDefault().getNetworkType();
+ String subTypeName = TelephonyManager.getDefault().getNetworkTypeName();
+ mNetworkInfo.setSubtype(newSubType, subTypeName);
+ if (newSubType != oldSubtype && mNetworkInfo.isConnected()) {
+ Message msg = mTarget.obtainMessage(EVENT_NETWORK_SUBTYPE_CHANGED,
+ oldSubtype, 0, mNetworkInfo);
+ msg.sendToTarget();
+ }
+
PhoneConstants.DataState state = Enum.valueOf(PhoneConstants.DataState.class,
intent.getStringExtra(PhoneConstants.STATE_KEY));
String reason = intent.getStringExtra(PhoneConstants.STATE_CHANGE_REASON_KEY);
diff --git a/core/java/android/net/NetworkStateTracker.java b/core/java/android/net/NetworkStateTracker.java
index 313c174..eae89f1 100644
--- a/core/java/android/net/NetworkStateTracker.java
+++ b/core/java/android/net/NetworkStateTracker.java
@@ -63,6 +63,12 @@ public interface NetworkStateTracker {
public static final int EVENT_RESTORE_DEFAULT_NETWORK = 6;
/**
+ * msg.what = EVENT_NETWORK_SUBTYPE_CHANGED
+ * msg.obj = NetworkInfo object
+ */
+ public static final int EVENT_NETWORK_SUBTYPE_CHANGED = 7;
+
+ /**
* -------------------------------------------------------------
* Control Interface
* -------------------------------------------------------------
diff --git a/core/java/android/os/BatteryManager.java b/core/java/android/os/BatteryManager.java
index c62715b..7b16f4d 100644
--- a/core/java/android/os/BatteryManager.java
+++ b/core/java/android/os/BatteryManager.java
@@ -115,4 +115,6 @@ public class BatteryManager {
public static final int BATTERY_PLUGGED_AC = 1;
/** Power source is a USB port. */
public static final int BATTERY_PLUGGED_USB = 2;
+ /** Power source is wireless. */
+ public static final int BATTERY_PLUGGED_WIRELESS = 4;
}
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index fcc0ae4..54f2fe3 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -2071,6 +2071,9 @@ public abstract class BatteryStats implements Parcelable {
case BatteryManager.BATTERY_PLUGGED_USB:
pw.print("usb");
break;
+ case BatteryManager.BATTERY_PLUGGED_WIRELESS:
+ pw.print("wireless");
+ break;
default:
pw.print(oldPlug);
break;
diff --git a/core/java/android/os/FactoryTest.java b/core/java/android/os/FactoryTest.java
new file mode 100644
index 0000000..ec99697
--- /dev/null
+++ b/core/java/android/os/FactoryTest.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os;
+
+/**
+ * Provides support for in-place factory test functions.
+ *
+ * This class provides a few properties that alter the normal operation of the system
+ * during factory testing.
+ *
+ * {@hide}
+ */
+public final class FactoryTest {
+ /**
+ * When true, long-press on power should immediately cause the device to
+ * shut down, without prompting the user.
+ */
+ public static boolean isLongPressOnPowerOffEnabled() {
+ return SystemProperties.getInt("factory.long_press_power_off", 0) != 0;
+ }
+}
diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java
index 7c103aa..0941d71 100644
--- a/core/java/android/os/FileUtils.java
+++ b/core/java/android/os/FileUtils.java
@@ -53,8 +53,6 @@ public class FileUtils {
public static native int setPermissions(String file, int mode, int uid, int gid);
- public static native int setUMask(int mask);
-
/** returns the FAT file system volume ID for the volume mounted
* at the given mount point, or -1 for failure
* @param mountPoint point for FAT volume
diff --git a/core/java/android/os/UEventObserver.java b/core/java/android/os/UEventObserver.java
index b924e84..d33382b 100644
--- a/core/java/android/os/UEventObserver.java
+++ b/core/java/android/os/UEventObserver.java
@@ -37,14 +37,79 @@ import java.util.HashMap;
* @hide
*/
public abstract class UEventObserver {
- private static final String TAG = UEventObserver.class.getSimpleName();
+ private static UEventThread sThread;
+
+ private static native void native_setup();
+ private static native int next_event(byte[] buffer);
+
+ public UEventObserver() {
+ }
+
+ protected void finalize() throws Throwable {
+ try {
+ stopObserving();
+ } finally {
+ super.finalize();
+ }
+ }
+
+ private static UEventThread getThread() {
+ synchronized (UEventObserver.class) {
+ if (sThread == null) {
+ sThread = new UEventThread();
+ sThread.start();
+ }
+ return sThread;
+ }
+ }
+
+ private static UEventThread peekThread() {
+ synchronized (UEventObserver.class) {
+ return sThread;
+ }
+ }
+
+ /**
+ * Begin observation of UEvent's.<p>
+ * This method will cause the UEvent thread to start if this is the first
+ * invocation of startObserving in this process.<p>
+ * Once called, the UEvent thread will call onUEvent() when an incoming
+ * UEvent matches the specified string.<p>
+ * This method can be called multiple times to register multiple matches.
+ * Only one call to stopObserving is required even with multiple registered
+ * matches.
+ * @param match A substring of the UEvent to match. Use "" to match all
+ * UEvent's
+ */
+ public final void startObserving(String match) {
+ final UEventThread t = getThread();
+ t.addObserver(match, this);
+ }
+
+ /**
+ * End observation of UEvent's.<p>
+ * This process's UEvent thread will never call onUEvent() on this
+ * UEventObserver after this call. Repeated calls have no effect.
+ */
+ public final void stopObserving() {
+ final UEventThread t = getThread();
+ if (t != null) {
+ t.removeObserver(this);
+ }
+ }
+
+ /**
+ * Subclasses of UEventObserver should override this method to handle
+ * UEvents.
+ */
+ public abstract void onUEvent(UEvent event);
/**
* Representation of a UEvent.
*/
- static public class UEvent {
+ public static final class UEvent {
// collection of key=value pairs parsed from the uevent message
- public HashMap<String,String> mMap = new HashMap<String,String>();
+ private final HashMap<String,String> mMap = new HashMap<String,String>();
public UEvent(String message) {
int offset = 0;
@@ -79,20 +144,20 @@ public abstract class UEventObserver {
}
}
- private static UEventThread sThread;
- private static boolean sThreadStarted = false;
-
- private static class UEventThread extends Thread {
+ private static final class UEventThread extends Thread {
/** Many to many mapping of string match to observer.
* Multimap would be better, but not available in android, so use
* an ArrayList where even elements are the String match and odd
* elements the corresponding UEventObserver observer */
- private ArrayList<Object> mObservers = new ArrayList<Object>();
-
- UEventThread() {
+ private final ArrayList<Object> mKeysAndObservers = new ArrayList<Object>();
+
+ private final ArrayList<UEventObserver> mTempObserversToSignal =
+ new ArrayList<UEventObserver>();
+
+ public UEventThread() {
super("UEventObserver");
}
-
+
public void run() {
native_setup();
@@ -101,91 +166,54 @@ public abstract class UEventObserver {
while (true) {
len = next_event(buffer);
if (len > 0) {
- String bufferStr = new String(buffer, 0, len); // easier to search a String
- synchronized (mObservers) {
- for (int i = 0; i < mObservers.size(); i += 2) {
- if (bufferStr.indexOf((String)mObservers.get(i)) != -1) {
- ((UEventObserver)mObservers.get(i+1))
- .onUEvent(new UEvent(bufferStr));
- }
- }
+ sendEvent(new String(buffer, 0, len));
+ }
+ }
+ }
+
+ private void sendEvent(String message) {
+ synchronized (mKeysAndObservers) {
+ final int N = mKeysAndObservers.size();
+ for (int i = 0; i < N; i += 2) {
+ final String key = (String)mKeysAndObservers.get(i);
+ if (message.indexOf(key) != -1) {
+ final UEventObserver observer =
+ (UEventObserver)mKeysAndObservers.get(i + 1);
+ mTempObserversToSignal.add(observer);
}
}
}
+
+ if (!mTempObserversToSignal.isEmpty()) {
+ final UEvent event = new UEvent(message);
+ final int N = mTempObserversToSignal.size();
+ for (int i = 0; i < N; i++) {
+ final UEventObserver observer = mTempObserversToSignal.get(i);
+ observer.onUEvent(event);
+ }
+ mTempObserversToSignal.clear();
+ }
}
+
public void addObserver(String match, UEventObserver observer) {
- synchronized(mObservers) {
- mObservers.add(match);
- mObservers.add(observer);
+ synchronized (mKeysAndObservers) {
+ mKeysAndObservers.add(match);
+ mKeysAndObservers.add(observer);
}
}
+
/** Removes every key/value pair where value=observer from mObservers */
public void removeObserver(UEventObserver observer) {
- synchronized(mObservers) {
- boolean found = true;
- while (found) {
- found = false;
- for (int i = 0; i < mObservers.size(); i += 2) {
- if (mObservers.get(i+1) == observer) {
- mObservers.remove(i+1);
- mObservers.remove(i);
- found = true;
- break;
- }
+ synchronized (mKeysAndObservers) {
+ for (int i = 0; i < mKeysAndObservers.size(); ) {
+ if (mKeysAndObservers.get(i + 1) == observer) {
+ mKeysAndObservers.remove(i + 1);
+ mKeysAndObservers.remove(i);
+ } else {
+ i += 2;
}
}
}
}
}
-
- private static native void native_setup();
- private static native int next_event(byte[] buffer);
-
- private static final synchronized void ensureThreadStarted() {
- if (sThreadStarted == false) {
- sThread = new UEventThread();
- sThread.start();
- sThreadStarted = true;
- }
- }
-
- /**
- * Begin observation of UEvent's.<p>
- * This method will cause the UEvent thread to start if this is the first
- * invocation of startObserving in this process.<p>
- * Once called, the UEvent thread will call onUEvent() when an incoming
- * UEvent matches the specified string.<p>
- * This method can be called multiple times to register multiple matches.
- * Only one call to stopObserving is required even with multiple registered
- * matches.
- * @param match A substring of the UEvent to match. Use "" to match all
- * UEvent's
- */
- public final synchronized void startObserving(String match) {
- ensureThreadStarted();
- sThread.addObserver(match, this);
- }
-
- /**
- * End observation of UEvent's.<p>
- * This process's UEvent thread will never call onUEvent() on this
- * UEventObserver after this call. Repeated calls have no effect.
- */
- public final synchronized void stopObserving() {
- sThread.removeObserver(this);
- }
-
- /**
- * Subclasses of UEventObserver should override this method to handle
- * UEvents.
- */
- public abstract void onUEvent(UEvent event);
-
- protected void finalize() throws Throwable {
- try {
- stopObserving();
- } finally {
- super.finalize();
- }
- }
}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 6dbba46..28273f0 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1147,6 +1147,7 @@ public final class Settings {
* <li>{@code 0} to never stay on while plugged in</li>
* <li>{@link BatteryManager#BATTERY_PLUGGED_AC} to stay on for AC charger</li>
* <li>{@link BatteryManager#BATTERY_PLUGGED_USB} to stay on for USB charger</li>
+ * <li>{@link BatteryManager#BATTERY_PLUGGED_WIRELESS} to stay on for wireless charger</li>
* </ul>
* These values can be OR-ed together.
*/
diff --git a/core/java/android/service/dreams/DreamManagerService.java b/core/java/android/service/dreams/DreamManagerService.java
index fc3f501..5d6b17e 100644
--- a/core/java/android/service/dreams/DreamManagerService.java
+++ b/core/java/android/service/dreams/DreamManagerService.java
@@ -18,6 +18,7 @@ import android.provider.Settings;
import android.util.Slog;
import android.view.IWindowManager;
import android.view.WindowManager;
+import android.view.WindowManagerGlobal;
/**
*
@@ -44,8 +45,7 @@ public class DreamManagerService
public DreamManagerService(Context context) {
if (DEBUG) Slog.v(TAG, "DreamManagerService startup");
mContext = context;
- mIWindowManager = IWindowManager.Stub.asInterface(
- ServiceManager.getService(Context.WINDOW_SERVICE));
+ mIWindowManager = WindowManagerGlobal.getWindowManagerService();
}
private void checkPermission(String permission) {
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index b513915..efa8911 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -36,7 +36,6 @@ import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
-import android.os.Process;
import android.os.RemoteException;
import android.util.Log;
import android.util.LogPrinter;
@@ -51,9 +50,8 @@ import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.View;
import android.view.ViewGroup;
-import android.view.ViewRootImpl;
import android.view.WindowManager;
-import android.view.WindowManagerImpl;
+import android.view.WindowManagerGlobal;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -674,8 +672,8 @@ public abstract class WallpaperService extends Service {
}
}
- redrawNeeded |= creating
- || (relayoutResult&WindowManagerImpl.RELAYOUT_RES_FIRST_TIME) != 0;
+ redrawNeeded |= creating || (relayoutResult
+ & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0;
if (forceReport || creating || surfaceCreating
|| formatChanged || sizeChanged) {
@@ -762,7 +760,7 @@ public abstract class WallpaperService extends Service {
mWindowToken = wrapper.mWindowToken;
mSurfaceHolder.setSizeFromLayout();
mInitializing = true;
- mSession = ViewRootImpl.getWindowSession(getMainLooper());
+ mSession = WindowManagerGlobal.getWindowSession(getMainLooper());
mWindow.setSession(mSession);
diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java
index 7a174af..5e367cb 100755
--- a/core/java/android/speech/tts/TextToSpeech.java
+++ b/core/java/android/speech/tts/TextToSpeech.java
@@ -1282,6 +1282,7 @@ public class TextToSpeech {
}
};
+ @Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.i(TAG, "Connected to " + name);
synchronized(mStartLock) {
@@ -1305,6 +1306,7 @@ public class TextToSpeech {
return mCallback;
}
+ @Override
public void onServiceDisconnected(ComponentName name) {
synchronized(mStartLock) {
mService = null;
@@ -1317,24 +1319,33 @@ public class TextToSpeech {
public void disconnect() {
mContext.unbindService(this);
+
+ synchronized (mStartLock) {
+ mService = null;
+ // If this is the active connection, clear it
+ if (mServiceConnection == this) {
+ mServiceConnection = null;
+ }
+
+ }
}
public <R> R runAction(Action<R> action, R errorResult, String method, boolean reconnect) {
- try {
- synchronized (mStartLock) {
+ synchronized (mStartLock) {
+ try {
if (mService == null) {
Log.w(TAG, method + " failed: not connected to TTS engine");
return errorResult;
}
return action.run(mService);
+ } catch (RemoteException ex) {
+ Log.e(TAG, method + " failed", ex);
+ if (reconnect) {
+ disconnect();
+ initTts();
+ }
+ return errorResult;
}
- } catch (RemoteException ex) {
- Log.e(TAG, method + " failed", ex);
- if (reconnect) {
- disconnect();
- initTts();
- }
- return errorResult;
}
}
}
diff --git a/core/java/android/text/TextUtils.java b/core/java/android/text/TextUtils.java
index 83a70f3..987062a 100644
--- a/core/java/android/text/TextUtils.java
+++ b/core/java/android/text/TextUtils.java
@@ -27,6 +27,7 @@ import android.text.style.CharacterStyle;
import android.text.style.EasyEditSpan;
import android.text.style.ForegroundColorSpan;
import android.text.style.LeadingMarginSpan;
+import android.text.style.LocaleSpan;
import android.text.style.MetricAffectingSpan;
import android.text.style.QuoteSpan;
import android.text.style.RelativeSizeSpan;
@@ -587,6 +588,8 @@ public class TextUtils {
public static final int SUGGESTION_RANGE_SPAN = 21;
/** @hide */
public static final int EASY_EDIT_SPAN = 22;
+ /** @hide */
+ public static final int LOCALE_SPAN = 23;
/**
* Flatten a CharSequence and whatever styles can be copied across processes
@@ -754,6 +757,10 @@ public class TextUtils {
readSpan(p, sp, new EasyEditSpan());
break;
+ case LOCALE_SPAN:
+ readSpan(p, sp, new LocaleSpan(p));
+ break;
+
default:
throw new RuntimeException("bogus span encoding " + kind);
}
diff --git a/core/java/android/text/style/LocaleSpan.java b/core/java/android/text/style/LocaleSpan.java
new file mode 100644
index 0000000..a12c42f
--- /dev/null
+++ b/core/java/android/text/style/LocaleSpan.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.text.style;
+
+import android.graphics.Paint;
+import android.os.Parcel;
+import android.text.ParcelableSpan;
+import android.text.TextPaint;
+import android.text.TextUtils;
+import java.util.Locale;
+
+/**
+ * Changes the {@link Locale} of the text to which the span is attached.
+ */
+public class LocaleSpan extends MetricAffectingSpan implements ParcelableSpan {
+ private final Locale mLocale;
+
+ /**
+ * Creates a LocaleSpan.
+ * @param locale The {@link Locale} of the text to which the span is
+ * attached.
+ */
+ public LocaleSpan(Locale locale) {
+ mLocale = locale;
+ }
+
+ public LocaleSpan(Parcel src) {
+ mLocale = new Locale(src.readString(), src.readString(), src.readString());
+ }
+
+ @Override
+ public int getSpanTypeId() {
+ return TextUtils.LOCALE_SPAN;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(mLocale.getLanguage());
+ dest.writeString(mLocale.getCountry());
+ dest.writeString(mLocale.getVariant());
+ }
+
+ /**
+ * Returns the {@link Locale}.
+ *
+ * @return The {@link Locale} for this span.
+ */
+ public Locale getLocale() {
+ return mLocale;
+ }
+
+ @Override
+ public void updateDrawState(TextPaint ds) {
+ apply(ds, mLocale);
+ }
+
+ @Override
+ public void updateMeasureState(TextPaint paint) {
+ apply(paint, mLocale);
+ }
+
+ private static void apply(Paint paint, Locale locale) {
+ paint.setTextLocale(locale);
+ }
+}
diff --git a/core/java/android/view/Choreographer.java b/core/java/android/view/Choreographer.java
index 6288ce5..392d1f2 100644
--- a/core/java/android/view/Choreographer.java
+++ b/core/java/android/view/Choreographer.java
@@ -16,6 +16,7 @@
package android.view;
+import android.hardware.display.DisplayManager;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
@@ -165,7 +166,7 @@ public final class Choreographer {
mDisplayEventReceiver = USE_VSYNC ? new FrameDisplayEventReceiver(looper) : null;
mLastFrameTimeNanos = Long.MIN_VALUE;
- Display d = WindowManagerImpl.getDefault().getDefaultDisplay();
+ Display d = DisplayManager.getInstance().getRealDisplay(Display.DEFAULT_DISPLAY);
mFrameIntervalNanos = (long)(1000000000 / d.getRefreshRate());
mCallbackQueues = new CallbackQueue[CALLBACK_LAST + 1];
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index 5409b38..6f8ca13 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -67,20 +67,16 @@ public final class Display {
private int mCachedAppHeightCompat;
/**
- * The default Display id.
+ * The default Display id, which is the id of the built-in primary display
+ * assuming there is one.
*/
public static final int DEFAULT_DISPLAY = 0;
/**
- * Uninitialized display.
- * @hide
- */
- public static final int NO_DISPLAY = -1;
-
- /**
* Internal method to create a display.
* Applications should use {@link android.view.WindowManager#getDefaultDisplay()}
- * to get a display object for the default display.
+ * or {@link android.hardware.display.DisplayManager#getDisplay}
+ * to get a display object.
*
* @hide
*/
@@ -114,6 +110,31 @@ public final class Display {
}
/**
+ * Gets the display's layer stack.
+ *
+ * Each display has its own independent layer stack upon which surfaces
+ * are placed to be managed by surface flinger.
+ *
+ * @return The layer stack number.
+ * @hide
+ */
+ public int getLayerStack() {
+ // Note: This is the current convention but there is no requirement that
+ // the display id and layer stack id be the same.
+ return mDisplayId;
+ }
+
+ /**
+ * Gets the compatibility info used by this display instance.
+ *
+ * @return The compatibility info holder, or null if none is required.
+ * @hide
+ */
+ public CompatibilityInfoHolder getCompatibilityInfo() {
+ return mCompatibilityInfo;
+ }
+
+ /**
* Gets the size of the display, in pixels.
* <p>
* Note that this value should <em>not</em> be used for computing layouts,
@@ -361,5 +382,16 @@ public final class Display {
mLastCachedAppSizeUpdate = now;
}
}
+
+ // For debugging purposes
+ @Override
+ public String toString() {
+ synchronized (this) {
+ updateDisplayInfoLocked();
+ mDisplayInfo.getAppMetrics(mTempMetrics, mCompatibilityInfo);
+ return "Display id " + mDisplayId + ": " + mDisplayInfo
+ + ", " + mTempMetrics;
+ }
+ }
}
diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java
index c65ce63..e38f245 100644
--- a/core/java/android/view/DisplayInfo.java
+++ b/core/java/android/view/DisplayInfo.java
@@ -223,4 +223,17 @@ public final class DisplayInfo implements Parcelable {
}
}
}
+
+ // For debugging purposes
+ @Override
+ public String toString() {
+ return "app " + appWidth + " x " + appHeight
+ + ", real " + logicalWidth + " x " + logicalHeight
+ + ", largest app " + largestNominalAppWidth + " x " + largestNominalAppHeight
+ + ", smallest app " + smallestNominalAppWidth + " x " + smallestNominalAppHeight
+ + ", " + refreshRate + " fps"
+ + ", rotation " + rotation
+ + ", density " + logicalDensityDpi
+ + ", " + physicalXDpi + " x " + physicalYDpi + " dpi";
+ }
}
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index 188fede..f906e24 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -1101,7 +1101,7 @@ public abstract class HardwareRenderer {
attachInfo.mIgnoreDirtyState = true;
attachInfo.mDrawingTime = SystemClock.uptimeMillis();
- view.mPrivateFlags |= View.DRAWN;
+ view.mPrivateFlags |= View.PFLAG_DRAWN;
final int surfaceState = checkCurrent();
if (surfaceState != SURFACE_STATE_ERROR) {
@@ -1135,9 +1135,9 @@ public abstract class HardwareRenderer {
callbacks.onHardwarePreDraw(canvas);
try {
- view.mRecreateDisplayList =
- (view.mPrivateFlags & View.INVALIDATED) == View.INVALIDATED;
- view.mPrivateFlags &= ~View.INVALIDATED;
+ view.mRecreateDisplayList = (view.mPrivateFlags & View.PFLAG_INVALIDATED)
+ == View.PFLAG_INVALIDATED;
+ view.mPrivateFlags &= ~View.PFLAG_INVALIDATED;
long getDisplayListStartTime = 0;
if (mProfileEnabled) {
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl
index e93e480..c5d9255 100644
--- a/core/java/android/view/IWindowSession.aidl
+++ b/core/java/android/view/IWindowSession.aidl
@@ -59,8 +59,8 @@ interface IWindowSession {
* @param requestedWidth The width the window wants to be.
* @param requestedHeight The height the window wants to be.
* @param viewVisibility Window root view's visibility.
- * @param flags Request flags: {@link WindowManagerImpl#RELAYOUT_INSETS_PENDING},
- * {@link WindowManagerImpl#RELAYOUT_DEFER_SURFACE_DESTROY}.
+ * @param flags Request flags: {@link WindowManagerGlobal#RELAYOUT_INSETS_PENDING},
+ * {@link WindowManagerGlobal#RELAYOUT_DEFER_SURFACE_DESTROY}.
* @param outFrame Rect in which is placed the new position/size on
* screen.
* @param outContentInsets Rect in which is placed the offsets from
@@ -79,8 +79,8 @@ interface IWindowSession {
* was last displayed.
* @param outSurface Object in which is placed the new display surface.
*
- * @return int Result flags: {@link WindowManagerImpl#RELAYOUT_SHOW_FOCUS},
- * {@link WindowManagerImpl#RELAYOUT_FIRST_TIME}.
+ * @return int Result flags: {@link WindowManagerGlobal#RELAYOUT_SHOW_FOCUS},
+ * {@link WindowManagerGlobal#RELAYOUT_FIRST_TIME}.
*/
int relayout(IWindow window, int seq, in WindowManager.LayoutParams attrs,
int requestedWidth, int requestedHeight, int viewVisibility,
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index 5f5d1f2..517b514 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -246,22 +246,9 @@ public class Surface implements Parcelable {
native private static void nativeClassInit();
static { nativeClassInit(); }
- /** create a surface @hide */
- public Surface(SurfaceSession s,
- int pid, int displayId, int w, int h, int format, int flags)
- throws OutOfResourcesException {
- checkHeadless();
-
- if (DEBUG_RELEASE) {
- mCreationStack = new Exception();
- }
- mCanvas = new CompatibleCanvas();
- init(s,pid,null,displayId,w,h,format,flags);
- }
-
/** create a surface with a name @hide */
public Surface(SurfaceSession s,
- int pid, String name, int displayId, int w, int h, int format, int flags)
+ int pid, String name, int layerStack, int w, int h, int format, int flags)
throws OutOfResourcesException {
checkHeadless();
@@ -269,7 +256,7 @@ public class Surface implements Parcelable {
mCreationStack = new Exception();
}
mCanvas = new CompatibleCanvas();
- init(s,pid,name,displayId,w,h,format,flags);
+ init(s, pid, name, layerStack, w, h, format, flags);
mName = name;
}
@@ -470,7 +457,7 @@ public class Surface implements Parcelable {
/** @hide */
public native void setWindowCrop(Rect crop);
/** @hide */
- public native void setDisplayId(int displayId);
+ public native void setLayerStack(int layerStack);
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index f4d40cb..fdf1c22 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -296,7 +296,7 @@ public class SurfaceView extends View {
}
boolean opaque = true;
- if ((mPrivateFlags & SKIP_DRAW) == 0) {
+ if ((mPrivateFlags & PFLAG_SKIP_DRAW) == 0) {
// this view draws, remove it from the transparent region
opaque = super.gatherTransparentRegion(region);
} else if (region != null) {
@@ -320,7 +320,7 @@ public class SurfaceView extends View {
public void draw(Canvas canvas) {
if (mWindowType != WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
// draw() is not called when SKIP_DRAW is set
- if ((mPrivateFlags & SKIP_DRAW) == 0) {
+ if ((mPrivateFlags & PFLAG_SKIP_DRAW) == 0) {
// punch a whole in the view-hierarchy below us
canvas.drawColor(0, PorterDuff.Mode.CLEAR);
}
@@ -332,7 +332,7 @@ public class SurfaceView extends View {
protected void dispatchDraw(Canvas canvas) {
if (mWindowType != WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
// if SKIP_DRAW is cleared, draw() has already punched a hole
- if ((mPrivateFlags & SKIP_DRAW) == SKIP_DRAW) {
+ if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) {
// punch a whole in the view-hierarchy below us
canvas.drawColor(0, PorterDuff.Mode.CLEAR);
}
@@ -480,10 +480,10 @@ public class SurfaceView extends View {
relayoutResult = mSession.relayout(
mWindow, mWindow.mSeq, mLayout, mWidth, mHeight,
visible ? VISIBLE : GONE,
- WindowManagerImpl.RELAYOUT_DEFER_SURFACE_DESTROY,
+ WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY,
mWinFrame, mContentInsets,
mVisibleInsets, mConfiguration, mNewSurface);
- if ((relayoutResult&WindowManagerImpl.RELAYOUT_RES_FIRST_TIME) != 0) {
+ if ((relayoutResult & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0) {
mReportDrawNeeded = true;
}
@@ -516,8 +516,8 @@ public class SurfaceView extends View {
SurfaceHolder.Callback callbacks[] = null;
- final boolean surfaceChanged =
- (relayoutResult&WindowManagerImpl.RELAYOUT_RES_SURFACE_CHANGED) != 0;
+ final boolean surfaceChanged = (relayoutResult
+ & WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED) != 0;
if (mSurfaceCreated && (surfaceChanged || (!visible && visibleChanged))) {
mSurfaceCreated = false;
if (mSurface.isValid()) {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 2f2c906..b1f5e9e 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -39,6 +39,7 @@ import android.graphics.Region;
import android.graphics.Shader;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
+import android.hardware.display.DisplayManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
@@ -1568,17 +1569,17 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
// for mPrivateFlags:
/** {@hide} */
- static final int WANTS_FOCUS = 0x00000001;
+ static final int PFLAG_WANTS_FOCUS = 0x00000001;
/** {@hide} */
- static final int FOCUSED = 0x00000002;
+ static final int PFLAG_FOCUSED = 0x00000002;
/** {@hide} */
- static final int SELECTED = 0x00000004;
+ static final int PFLAG_SELECTED = 0x00000004;
/** {@hide} */
- static final int IS_ROOT_NAMESPACE = 0x00000008;
+ static final int PFLAG_IS_ROOT_NAMESPACE = 0x00000008;
/** {@hide} */
- static final int HAS_BOUNDS = 0x00000010;
+ static final int PFLAG_HAS_BOUNDS = 0x00000010;
/** {@hide} */
- static final int DRAWN = 0x00000020;
+ static final int PFLAG_DRAWN = 0x00000020;
/**
* When this flag is set, this view is running an animation on behalf of its
* children and should therefore not cancel invalidate requests, even if they
@@ -1586,58 +1587,58 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*
* {@hide}
*/
- static final int DRAW_ANIMATION = 0x00000040;
+ static final int PFLAG_DRAW_ANIMATION = 0x00000040;
/** {@hide} */
- static final int SKIP_DRAW = 0x00000080;
+ static final int PFLAG_SKIP_DRAW = 0x00000080;
/** {@hide} */
- static final int ONLY_DRAWS_BACKGROUND = 0x00000100;
+ static final int PFLAG_ONLY_DRAWS_BACKGROUND = 0x00000100;
/** {@hide} */
- static final int REQUEST_TRANSPARENT_REGIONS = 0x00000200;
+ static final int PFLAG_REQUEST_TRANSPARENT_REGIONS = 0x00000200;
/** {@hide} */
- static final int DRAWABLE_STATE_DIRTY = 0x00000400;
+ static final int PFLAG_DRAWABLE_STATE_DIRTY = 0x00000400;
/** {@hide} */
- static final int MEASURED_DIMENSION_SET = 0x00000800;
+ static final int PFLAG_MEASURED_DIMENSION_SET = 0x00000800;
/** {@hide} */
- static final int FORCE_LAYOUT = 0x00001000;
+ static final int PFLAG_FORCE_LAYOUT = 0x00001000;
/** {@hide} */
- static final int LAYOUT_REQUIRED = 0x00002000;
+ static final int PFLAG_LAYOUT_REQUIRED = 0x00002000;
- private static final int PRESSED = 0x00004000;
+ private static final int PFLAG_PRESSED = 0x00004000;
/** {@hide} */
- static final int DRAWING_CACHE_VALID = 0x00008000;
+ static final int PFLAG_DRAWING_CACHE_VALID = 0x00008000;
/**
* Flag used to indicate that this view should be drawn once more (and only once
* more) after its animation has completed.
* {@hide}
*/
- static final int ANIMATION_STARTED = 0x00010000;
+ static final int PFLAG_ANIMATION_STARTED = 0x00010000;
- private static final int SAVE_STATE_CALLED = 0x00020000;
+ private static final int PFLAG_SAVE_STATE_CALLED = 0x00020000;
/**
* Indicates that the View returned true when onSetAlpha() was called and that
* the alpha must be restored.
* {@hide}
*/
- static final int ALPHA_SET = 0x00040000;
+ static final int PFLAG_ALPHA_SET = 0x00040000;
/**
* Set by {@link #setScrollContainer(boolean)}.
*/
- static final int SCROLL_CONTAINER = 0x00080000;
+ static final int PFLAG_SCROLL_CONTAINER = 0x00080000;
/**
* Set by {@link #setScrollContainer(boolean)}.
*/
- static final int SCROLL_CONTAINER_ADDED = 0x00100000;
+ static final int PFLAG_SCROLL_CONTAINER_ADDED = 0x00100000;
/**
* View flag indicating whether this view was invalidated (fully or partially.)
*
* @hide
*/
- static final int DIRTY = 0x00200000;
+ static final int PFLAG_DIRTY = 0x00200000;
/**
* View flag indicating whether this view was invalidated by an opaque
@@ -1645,35 +1646,35 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*
* @hide
*/
- static final int DIRTY_OPAQUE = 0x00400000;
+ static final int PFLAG_DIRTY_OPAQUE = 0x00400000;
/**
- * Mask for {@link #DIRTY} and {@link #DIRTY_OPAQUE}.
+ * Mask for {@link #PFLAG_DIRTY} and {@link #PFLAG_DIRTY_OPAQUE}.
*
* @hide
*/
- static final int DIRTY_MASK = 0x00600000;
+ static final int PFLAG_DIRTY_MASK = 0x00600000;
/**
* Indicates whether the background is opaque.
*
* @hide
*/
- static final int OPAQUE_BACKGROUND = 0x00800000;
+ static final int PFLAG_OPAQUE_BACKGROUND = 0x00800000;
/**
* Indicates whether the scrollbars are opaque.
*
* @hide
*/
- static final int OPAQUE_SCROLLBARS = 0x01000000;
+ static final int PFLAG_OPAQUE_SCROLLBARS = 0x01000000;
/**
* Indicates whether the view is opaque.
*
* @hide
*/
- static final int OPAQUE_MASK = 0x01800000;
+ static final int PFLAG_OPAQUE_MASK = 0x01800000;
/**
* Indicates a prepressed state;
@@ -1683,27 +1684,27 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*
* @hide
*/
- private static final int PREPRESSED = 0x02000000;
+ private static final int PFLAG_PREPRESSED = 0x02000000;
/**
* Indicates whether the view is temporarily detached.
*
* @hide
*/
- static final int CANCEL_NEXT_UP_EVENT = 0x04000000;
+ static final int PFLAG_CANCEL_NEXT_UP_EVENT = 0x04000000;
/**
* Indicates that we should awaken scroll bars once attached
*
* @hide
*/
- private static final int AWAKEN_SCROLL_BARS_ON_ATTACH = 0x08000000;
+ private static final int PFLAG_AWAKEN_SCROLL_BARS_ON_ATTACH = 0x08000000;
/**
* Indicates that the view has received HOVER_ENTER. Cleared on HOVER_EXIT.
* @hide
*/
- private static final int HOVERED = 0x10000000;
+ private static final int PFLAG_HOVERED = 0x10000000;
/**
* Indicates that pivotX or pivotY were explicitly set and we should not assume the center
@@ -1711,10 +1712,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*
* @hide
*/
- private static final int PIVOT_EXPLICITLY_SET = 0x20000000;
+ private static final int PFLAG_PIVOT_EXPLICITLY_SET = 0x20000000;
/** {@hide} */
- static final int ACTIVATED = 0x40000000;
+ static final int PFLAG_ACTIVATED = 0x40000000;
/**
* Indicates that this view was specifically invalidated, not just dirtied because some
@@ -1724,7 +1725,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*
* @hide
*/
- static final int INVALIDATED = 0x80000000;
+ static final int PFLAG_INVALIDATED = 0x80000000;
/* Masks for mPrivateFlags2 */
@@ -1733,7 +1734,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* Cleared when the drag operation concludes.
* @hide
*/
- static final int DRAG_CAN_ACCEPT = 0x00000001;
+ static final int PFLAG2_DRAG_CAN_ACCEPT = 0x00000001;
/**
* Indicates that this view is currently directly under the drag location in a
@@ -1741,7 +1742,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* the drag exits the view, or when the drag operation concludes.
* @hide
*/
- static final int DRAG_HOVERED = 0x00000002;
+ static final int PFLAG2_DRAG_HOVERED = 0x00000002;
/**
* Horizontal layout direction of this view is from Left to Right.
@@ -1771,32 +1772,33 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* Bit shift to get the horizontal layout direction. (bits after DRAG_HOVERED)
* @hide
*/
- static final int LAYOUT_DIRECTION_MASK_SHIFT = 2;
+ static final int PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT = 2;
/**
* Mask for use with private flags indicating bits used for horizontal layout direction.
* @hide
*/
- static final int LAYOUT_DIRECTION_MASK = 0x00000003 << LAYOUT_DIRECTION_MASK_SHIFT;
+ static final int PFLAG2_LAYOUT_DIRECTION_MASK = 0x00000003 << PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT;
/**
* Indicates whether the view horizontal layout direction has been resolved and drawn to the
* right-to-left direction.
* @hide
*/
- static final int LAYOUT_DIRECTION_RESOLVED_RTL = 4 << LAYOUT_DIRECTION_MASK_SHIFT;
+ static final int PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL = 4 << PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT;
/**
* Indicates whether the view horizontal layout direction has been resolved.
* @hide
*/
- static final int LAYOUT_DIRECTION_RESOLVED = 8 << LAYOUT_DIRECTION_MASK_SHIFT;
+ static final int PFLAG2_LAYOUT_DIRECTION_RESOLVED = 8 << PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT;
/**
* Mask for use with private flags indicating bits used for resolved horizontal layout direction.
* @hide
*/
- static final int LAYOUT_DIRECTION_RESOLVED_MASK = 0x0000000C << LAYOUT_DIRECTION_MASK_SHIFT;
+ static final int PFLAG2_LAYOUT_DIRECTION_RESOLVED_MASK = 0x0000000C
+ << PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT;
/*
* Array of horizontal layout direction flags for mapping attribute "layoutDirection" to correct
@@ -1823,7 +1825,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*
* @hide
*/
- static final int HAS_TRANSIENT_STATE = 0x00000100;
+ static final int PFLAG2_HAS_TRANSIENT_STATE = 0x00000100;
/**
@@ -1863,58 +1865,61 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
/**
* Default text direction is inherited
*/
- protected static int TEXT_DIRECTION_DEFAULT = TEXT_DIRECTION_INHERIT;
+ public static int TEXT_DIRECTION_DEFAULT = TEXT_DIRECTION_INHERIT;
/**
* Bit shift to get the horizontal layout direction. (bits after LAYOUT_DIRECTION_RESOLVED)
* @hide
*/
- static final int TEXT_DIRECTION_MASK_SHIFT = 6;
+ static final int PFLAG2_TEXT_DIRECTION_MASK_SHIFT = 6;
/**
* Mask for use with private flags indicating bits used for text direction.
* @hide
*/
- static final int TEXT_DIRECTION_MASK = 0x00000007 << TEXT_DIRECTION_MASK_SHIFT;
+ static final int PFLAG2_TEXT_DIRECTION_MASK = 0x00000007
+ << PFLAG2_TEXT_DIRECTION_MASK_SHIFT;
/**
* Array of text direction flags for mapping attribute "textDirection" to correct
* flag value.
* @hide
*/
- private static final int[] TEXT_DIRECTION_FLAGS = {
- TEXT_DIRECTION_INHERIT << TEXT_DIRECTION_MASK_SHIFT,
- TEXT_DIRECTION_FIRST_STRONG << TEXT_DIRECTION_MASK_SHIFT,
- TEXT_DIRECTION_ANY_RTL << TEXT_DIRECTION_MASK_SHIFT,
- TEXT_DIRECTION_LTR << TEXT_DIRECTION_MASK_SHIFT,
- TEXT_DIRECTION_RTL << TEXT_DIRECTION_MASK_SHIFT,
- TEXT_DIRECTION_LOCALE << TEXT_DIRECTION_MASK_SHIFT
+ private static final int[] PFLAG2_TEXT_DIRECTION_FLAGS = {
+ TEXT_DIRECTION_INHERIT << PFLAG2_TEXT_DIRECTION_MASK_SHIFT,
+ TEXT_DIRECTION_FIRST_STRONG << PFLAG2_TEXT_DIRECTION_MASK_SHIFT,
+ TEXT_DIRECTION_ANY_RTL << PFLAG2_TEXT_DIRECTION_MASK_SHIFT,
+ TEXT_DIRECTION_LTR << PFLAG2_TEXT_DIRECTION_MASK_SHIFT,
+ TEXT_DIRECTION_RTL << PFLAG2_TEXT_DIRECTION_MASK_SHIFT,
+ TEXT_DIRECTION_LOCALE << PFLAG2_TEXT_DIRECTION_MASK_SHIFT
};
/**
* Indicates whether the view text direction has been resolved.
* @hide
*/
- static final int TEXT_DIRECTION_RESOLVED = 0x00000008 << TEXT_DIRECTION_MASK_SHIFT;
+ static final int PFLAG2_TEXT_DIRECTION_RESOLVED = 0x00000008
+ << PFLAG2_TEXT_DIRECTION_MASK_SHIFT;
/**
* Bit shift to get the horizontal layout direction. (bits after DRAG_HOVERED)
* @hide
*/
- static final int TEXT_DIRECTION_RESOLVED_MASK_SHIFT = 10;
+ static final int PFLAG2_TEXT_DIRECTION_RESOLVED_MASK_SHIFT = 10;
/**
* Mask for use with private flags indicating bits used for resolved text direction.
* @hide
*/
- static final int TEXT_DIRECTION_RESOLVED_MASK = 0x00000007 << TEXT_DIRECTION_RESOLVED_MASK_SHIFT;
+ static final int PFLAG2_TEXT_DIRECTION_RESOLVED_MASK = 0x00000007
+ << PFLAG2_TEXT_DIRECTION_RESOLVED_MASK_SHIFT;
/**
* Indicates whether the view text direction has been resolved to the "first strong" heuristic.
* @hide
*/
- static final int TEXT_DIRECTION_RESOLVED_DEFAULT =
- TEXT_DIRECTION_FIRST_STRONG << TEXT_DIRECTION_RESOLVED_MASK_SHIFT;
+ static final int PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT =
+ TEXT_DIRECTION_FIRST_STRONG << PFLAG2_TEXT_DIRECTION_RESOLVED_MASK_SHIFT;
/*
* Default text alignment. The text alignment of this View is inherited from its parent.
@@ -1970,58 +1975,59 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
/**
* Default text alignment is inherited
*/
- protected static int TEXT_ALIGNMENT_DEFAULT = TEXT_ALIGNMENT_GRAVITY;
+ public static int TEXT_ALIGNMENT_DEFAULT = TEXT_ALIGNMENT_GRAVITY;
/**
* Bit shift to get the horizontal layout direction. (bits after DRAG_HOVERED)
* @hide
*/
- static final int TEXT_ALIGNMENT_MASK_SHIFT = 13;
+ static final int PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT = 13;
/**
* Mask for use with private flags indicating bits used for text alignment.
* @hide
*/
- static final int TEXT_ALIGNMENT_MASK = 0x00000007 << TEXT_ALIGNMENT_MASK_SHIFT;
+ static final int PFLAG2_TEXT_ALIGNMENT_MASK = 0x00000007 << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT;
/**
* Array of text direction flags for mapping attribute "textAlignment" to correct
* flag value.
* @hide
*/
- private static final int[] TEXT_ALIGNMENT_FLAGS = {
- TEXT_ALIGNMENT_INHERIT << TEXT_ALIGNMENT_MASK_SHIFT,
- TEXT_ALIGNMENT_GRAVITY << TEXT_ALIGNMENT_MASK_SHIFT,
- TEXT_ALIGNMENT_TEXT_START << TEXT_ALIGNMENT_MASK_SHIFT,
- TEXT_ALIGNMENT_TEXT_END << TEXT_ALIGNMENT_MASK_SHIFT,
- TEXT_ALIGNMENT_CENTER << TEXT_ALIGNMENT_MASK_SHIFT,
- TEXT_ALIGNMENT_VIEW_START << TEXT_ALIGNMENT_MASK_SHIFT,
- TEXT_ALIGNMENT_VIEW_END << TEXT_ALIGNMENT_MASK_SHIFT
+ private static final int[] PFLAG2_TEXT_ALIGNMENT_FLAGS = {
+ TEXT_ALIGNMENT_INHERIT << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT,
+ TEXT_ALIGNMENT_GRAVITY << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT,
+ TEXT_ALIGNMENT_TEXT_START << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT,
+ TEXT_ALIGNMENT_TEXT_END << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT,
+ TEXT_ALIGNMENT_CENTER << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT,
+ TEXT_ALIGNMENT_VIEW_START << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT,
+ TEXT_ALIGNMENT_VIEW_END << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT
};
/**
* Indicates whether the view text alignment has been resolved.
* @hide
*/
- static final int TEXT_ALIGNMENT_RESOLVED = 0x00000008 << TEXT_ALIGNMENT_MASK_SHIFT;
+ static final int PFLAG2_TEXT_ALIGNMENT_RESOLVED = 0x00000008 << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT;
/**
* Bit shift to get the resolved text alignment.
* @hide
*/
- static final int TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT = 17;
+ static final int PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT = 17;
/**
* Mask for use with private flags indicating bits used for text alignment.
* @hide
*/
- static final int TEXT_ALIGNMENT_RESOLVED_MASK = 0x00000007 << TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT;
+ static final int PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK = 0x00000007
+ << PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT;
/**
* Indicates whether if the view text alignment has been resolved to gravity
*/
- public static final int TEXT_ALIGNMENT_RESOLVED_DEFAULT =
- TEXT_ALIGNMENT_GRAVITY << TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT;
+ private static final int PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT =
+ TEXT_ALIGNMENT_GRAVITY << PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT;
// Accessiblity constants for mPrivateFlags2
@@ -2029,7 +2035,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* Shift for the bits in {@link #mPrivateFlags2} related to the
* "importantForAccessibility" attribute.
*/
- static final int IMPORTANT_FOR_ACCESSIBILITY_SHIFT = 20;
+ static final int PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_SHIFT = 20;
/**
* Automatically determine whether a view is important for accessibility.
@@ -2055,26 +2061,27 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* Mask for obtainig the bits which specify how to determine
* whether a view is important for accessibility.
*/
- static final int IMPORTANT_FOR_ACCESSIBILITY_MASK = (IMPORTANT_FOR_ACCESSIBILITY_AUTO
+ static final int PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_MASK = (IMPORTANT_FOR_ACCESSIBILITY_AUTO
| IMPORTANT_FOR_ACCESSIBILITY_YES | IMPORTANT_FOR_ACCESSIBILITY_NO)
- << IMPORTANT_FOR_ACCESSIBILITY_SHIFT;
+ << PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_SHIFT;
/**
* Flag indicating whether a view has accessibility focus.
*/
- static final int ACCESSIBILITY_FOCUSED = 0x00000040 << IMPORTANT_FOR_ACCESSIBILITY_SHIFT;
+ static final int PFLAG2_ACCESSIBILITY_FOCUSED = 0x00000040 << PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_SHIFT;
/**
* Flag indicating whether a view state for accessibility has changed.
*/
- static final int ACCESSIBILITY_STATE_CHANGED = 0x00000080 << IMPORTANT_FOR_ACCESSIBILITY_SHIFT;
+ static final int PFLAG2_ACCESSIBILITY_STATE_CHANGED = 0x00000080
+ << PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_SHIFT;
/**
* Flag indicating whether a view failed the quickReject() check in draw(). This condition
* is used to check whether later changes to the view's transform should invalidate the
* view to force the quickReject test to run again.
*/
- static final int VIEW_QUICK_REJECTED = 0x10000000;
+ static final int PFLAG2_VIEW_QUICK_REJECTED = 0x10000000;
/**
* Flag indicating that start/end padding has been resolved into left/right padding
@@ -2083,7 +2090,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* during measurement. In some special cases this is required such as when an adapter-based
* view measures prospective children without attaching them to a window.
*/
- static final int PADDING_RESOLVED = 0x20000000;
+ static final int PFLAG2_PADDING_RESOLVED = 0x20000000;
// There are a couple of flags left in mPrivateFlags2
@@ -2096,19 +2103,19 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* an animation is cleared between successive frames, in order to tell the associated
* DisplayList to clear its animation matrix.
*/
- static final int VIEW_IS_ANIMATING_TRANSFORM = 0x1;
+ static final int PFLAG3_VIEW_IS_ANIMATING_TRANSFORM = 0x1;
/**
* Flag indicating that view has an alpha animation set on it. This is used to track whether an
* animation is cleared between successive frames, in order to tell the associated
* DisplayList to restore its alpha value.
*/
- static final int VIEW_IS_ANIMATING_ALPHA = 0x2;
+ static final int PFLAG3_VIEW_IS_ANIMATING_ALPHA = 0x2;
/* End of masks for mPrivateFlags3 */
- static final int DRAG_MASK = DRAG_CAN_ACCEPT | DRAG_HOVERED;
+ static final int DRAG_MASK = PFLAG2_DRAG_CAN_ACCEPT | PFLAG2_DRAG_HOVERED;
/**
* Always allow a user to over-scroll this view, provided it is a
@@ -2475,16 +2482,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* {@hide}
*/
@ViewDebug.ExportedProperty(flagMapping = {
- @ViewDebug.FlagToString(mask = FORCE_LAYOUT, equals = FORCE_LAYOUT,
+ @ViewDebug.FlagToString(mask = PFLAG_FORCE_LAYOUT, equals = PFLAG_FORCE_LAYOUT,
name = "FORCE_LAYOUT"),
- @ViewDebug.FlagToString(mask = LAYOUT_REQUIRED, equals = LAYOUT_REQUIRED,
+ @ViewDebug.FlagToString(mask = PFLAG_LAYOUT_REQUIRED, equals = PFLAG_LAYOUT_REQUIRED,
name = "LAYOUT_REQUIRED"),
- @ViewDebug.FlagToString(mask = DRAWING_CACHE_VALID, equals = DRAWING_CACHE_VALID,
+ @ViewDebug.FlagToString(mask = PFLAG_DRAWING_CACHE_VALID, equals = PFLAG_DRAWING_CACHE_VALID,
name = "DRAWING_CACHE_INVALID", outputIf = false),
- @ViewDebug.FlagToString(mask = DRAWN, equals = DRAWN, name = "DRAWN", outputIf = true),
- @ViewDebug.FlagToString(mask = DRAWN, equals = DRAWN, name = "NOT_DRAWN", outputIf = false),
- @ViewDebug.FlagToString(mask = DIRTY_MASK, equals = DIRTY_OPAQUE, name = "DIRTY_OPAQUE"),
- @ViewDebug.FlagToString(mask = DIRTY_MASK, equals = DIRTY, name = "DIRTY")
+ @ViewDebug.FlagToString(mask = PFLAG_DRAWN, equals = PFLAG_DRAWN, name = "DRAWN", outputIf = true),
+ @ViewDebug.FlagToString(mask = PFLAG_DRAWN, equals = PFLAG_DRAWN, name = "NOT_DRAWN", outputIf = false),
+ @ViewDebug.FlagToString(mask = PFLAG_DIRTY_MASK, equals = PFLAG_DIRTY_OPAQUE, name = "DIRTY_OPAQUE"),
+ @ViewDebug.FlagToString(mask = PFLAG_DIRTY_MASK, equals = PFLAG_DIRTY, name = "DIRTY")
})
int mPrivateFlags;
int mPrivateFlags2;
@@ -3100,6 +3107,19 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
private boolean mSendingHoverAccessibilityEvents;
+ /**
+ * Delegate for injecting accessiblity functionality.
+ */
+ AccessibilityDelegate mAccessibilityDelegate;
+
+ /**
+ * Consistency verifier for debugging purposes.
+ * @hide
+ */
+ protected final InputEventConsistencyVerifier mInputEventConsistencyVerifier =
+ InputEventConsistencyVerifier.isInstrumentationEnabled() ?
+ new InputEventConsistencyVerifier(this, 0) : null;
+
private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1);
/**
@@ -3113,10 +3133,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
mResources = context != null ? context.getResources() : null;
mViewFlags = SOUND_EFFECTS_ENABLED | HAPTIC_FEEDBACK_ENABLED;
// Set layout and text direction defaults
- mPrivateFlags2 = (LAYOUT_DIRECTION_DEFAULT << LAYOUT_DIRECTION_MASK_SHIFT) |
- (TEXT_DIRECTION_DEFAULT << TEXT_DIRECTION_MASK_SHIFT) |
- (TEXT_ALIGNMENT_DEFAULT << TEXT_ALIGNMENT_MASK_SHIFT) |
- (IMPORTANT_FOR_ACCESSIBILITY_DEFAULT << IMPORTANT_FOR_ACCESSIBILITY_SHIFT);
+ mPrivateFlags2 = (LAYOUT_DIRECTION_DEFAULT << PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT) |
+ (TEXT_DIRECTION_DEFAULT << PFLAG2_TEXT_DIRECTION_MASK_SHIFT) |
+ (TEXT_ALIGNMENT_DEFAULT << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT) |
+ (IMPORTANT_FOR_ACCESSIBILITY_DEFAULT << PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_SHIFT);
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
setOverScrollMode(OVER_SCROLL_IF_CONTENT_SCROLLS);
mUserPaddingStart = UNDEFINED_PADDING;
@@ -3124,19 +3144,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
/**
- * Delegate for injecting accessiblity functionality.
- */
- AccessibilityDelegate mAccessibilityDelegate;
-
- /**
- * Consistency verifier for debugging purposes.
- * @hide
- */
- protected final InputEventConsistencyVerifier mInputEventConsistencyVerifier =
- InputEventConsistencyVerifier.isInstrumentationEnabled() ?
- new InputEventConsistencyVerifier(this, 0) : null;
-
- /**
* Constructor that is called when inflating a view from XML. This is called
* when a view is being constructed from an XML file, supplying attributes
* that were specified in the XML file. This version uses a default style of
@@ -3346,12 +3353,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
break;
case com.android.internal.R.styleable.View_layoutDirection:
// Clear any layout direction flags (included resolved bits) already set
- mPrivateFlags2 &= ~(LAYOUT_DIRECTION_MASK | LAYOUT_DIRECTION_RESOLVED_MASK);
+ mPrivateFlags2 &= ~(PFLAG2_LAYOUT_DIRECTION_MASK | PFLAG2_LAYOUT_DIRECTION_RESOLVED_MASK);
// Set the layout direction flags depending on the value of the attribute
final int layoutDirection = a.getInt(attr, -1);
final int value = (layoutDirection != -1) ?
LAYOUT_DIRECTION_FLAGS[layoutDirection] : LAYOUT_DIRECTION_DEFAULT;
- mPrivateFlags2 |= (value << LAYOUT_DIRECTION_MASK_SHIFT);
+ mPrivateFlags2 |= (value << PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT);
break;
case com.android.internal.R.styleable.View_drawingCacheQuality:
final int cacheQuality = a.getInt(attr, 0);
@@ -3496,19 +3503,19 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
break;
case R.styleable.View_textDirection:
// Clear any text direction flag already set
- mPrivateFlags2 &= ~TEXT_DIRECTION_MASK;
+ mPrivateFlags2 &= ~PFLAG2_TEXT_DIRECTION_MASK;
// Set the text direction flags depending on the value of the attribute
final int textDirection = a.getInt(attr, -1);
if (textDirection != -1) {
- mPrivateFlags2 |= TEXT_DIRECTION_FLAGS[textDirection];
+ mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_FLAGS[textDirection];
}
break;
case R.styleable.View_textAlignment:
// Clear any text alignment flag already set
- mPrivateFlags2 &= ~TEXT_ALIGNMENT_MASK;
+ mPrivateFlags2 &= ~PFLAG2_TEXT_ALIGNMENT_MASK;
// Set the text alignment flag depending on the value of the attribute
final int textAlignment = a.getInt(attr, TEXT_ALIGNMENT_DEFAULT);
- mPrivateFlags2 |= TEXT_ALIGNMENT_FLAGS[textAlignment];
+ mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_FLAGS[textAlignment];
break;
case R.styleable.View_importantForAccessibility:
setImportantForAccessibility(a.getInt(attr,
@@ -3588,6 +3595,81 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
mResources = null;
}
+ public String toString() {
+ StringBuilder out = new StringBuilder(128);
+ out.append(getClass().getName());
+ out.append('{');
+ out.append(Integer.toHexString(System.identityHashCode(this)));
+ out.append(' ');
+ switch (mViewFlags&VISIBILITY_MASK) {
+ case VISIBLE: out.append('V'); break;
+ case INVISIBLE: out.append('I'); break;
+ case GONE: out.append('G'); break;
+ default: out.append('.'); break;
+ }
+ out.append((mViewFlags&FOCUSABLE_MASK) == FOCUSABLE ? 'F' : '.');
+ out.append((mViewFlags&ENABLED_MASK) == ENABLED ? 'E' : '.');
+ out.append((mViewFlags&DRAW_MASK) == WILL_NOT_DRAW ? '.' : 'D');
+ out.append((mViewFlags&SCROLLBARS_HORIZONTAL) != 0 ? 'H' : '.');
+ out.append((mViewFlags&SCROLLBARS_VERTICAL) != 0 ? 'V' : '.');
+ out.append((mViewFlags&CLICKABLE) != 0 ? 'C' : '.');
+ out.append((mViewFlags&LONG_CLICKABLE) != 0 ? 'L' : '.');
+ out.append(' ');
+ out.append((mPrivateFlags&PFLAG_IS_ROOT_NAMESPACE) != 0 ? 'R' : '.');
+ out.append((mPrivateFlags&PFLAG_FOCUSED) != 0 ? 'F' : '.');
+ out.append((mPrivateFlags&PFLAG_SELECTED) != 0 ? 'S' : '.');
+ if ((mPrivateFlags&PFLAG_PREPRESSED) != 0) {
+ out.append('p');
+ } else {
+ out.append((mPrivateFlags&PFLAG_PRESSED) != 0 ? 'P' : '.');
+ }
+ out.append((mPrivateFlags&PFLAG_HOVERED) != 0 ? 'H' : '.');
+ out.append((mPrivateFlags&PFLAG_ACTIVATED) != 0 ? 'A' : '.');
+ out.append((mPrivateFlags&PFLAG_INVALIDATED) != 0 ? 'I' : '.');
+ out.append((mPrivateFlags&PFLAG_DIRTY_MASK) != 0 ? 'D' : '.');
+ out.append(' ');
+ out.append(mLeft);
+ out.append(',');
+ out.append(mTop);
+ out.append('-');
+ out.append(mRight);
+ out.append(',');
+ out.append(mBottom);
+ final int id = getId();
+ if (id != NO_ID) {
+ out.append(" #");
+ out.append(Integer.toHexString(id));
+ final Resources r = mResources;
+ if (id != 0 && r != null) {
+ try {
+ String pkgname;
+ switch (id&0xff000000) {
+ case 0x7f000000:
+ pkgname="app";
+ break;
+ case 0x01000000:
+ pkgname="android";
+ break;
+ default:
+ pkgname = r.getResourcePackageName(id);
+ break;
+ }
+ String typename = r.getResourceTypeName(id);
+ String entryname = r.getResourceEntryName(id);
+ out.append(" ");
+ out.append(pkgname);
+ out.append(":");
+ out.append(typename);
+ out.append("/");
+ out.append(entryname);
+ } catch (Resources.NotFoundException e) {
+ }
+ }
+ }
+ out.append("}");
+ return out.toString();
+ }
+
/**
* <p>
* Initializes the fading edges from a given set of styled attributes. This
@@ -4145,8 +4227,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
System.out.println(this + " requestFocus()");
}
- if ((mPrivateFlags & FOCUSED) == 0) {
- mPrivateFlags |= FOCUSED;
+ if ((mPrivateFlags & PFLAG_FOCUSED) == 0) {
+ mPrivateFlags |= PFLAG_FOCUSED;
if (mParent != null) {
mParent.requestChildFocus(this, this);
@@ -4230,8 +4312,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
System.out.println(this + " clearFocus()");
}
- if ((mPrivateFlags & FOCUSED) != 0) {
- mPrivateFlags &= ~FOCUSED;
+ if ((mPrivateFlags & PFLAG_FOCUSED) != 0) {
+ mPrivateFlags &= ~PFLAG_FOCUSED;
if (mParent != null) {
mParent.clearChildFocus(this);
@@ -4265,8 +4347,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
System.out.println(this + " unFocus()");
}
- if ((mPrivateFlags & FOCUSED) != 0) {
- mPrivateFlags &= ~FOCUSED;
+ if ((mPrivateFlags & PFLAG_FOCUSED) != 0) {
+ mPrivateFlags &= ~PFLAG_FOCUSED;
onFocusChanged(false, 0, null);
refreshDrawableState();
@@ -4285,7 +4367,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
@ViewDebug.ExportedProperty(category = "focus")
public boolean hasFocus() {
- return (mPrivateFlags & FOCUSED) != 0;
+ return (mPrivateFlags & PFLAG_FOCUSED) != 0;
}
/**
@@ -4985,7 +5067,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
@ViewDebug.ExportedProperty(category = "focus")
public boolean isFocused() {
- return (mPrivateFlags & FOCUSED) != 0;
+ return (mPrivateFlags & PFLAG_FOCUSED) != 0;
}
/**
@@ -4996,7 +5078,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* be found.
*/
public View findFocus() {
- return (mPrivateFlags & FOCUSED) != 0 ? this : null;
+ return (mPrivateFlags & PFLAG_FOCUSED) != 0 ? this : null;
}
/**
@@ -5009,7 +5091,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @attr ref android.R.styleable#View_isScrollContainer
*/
public boolean isScrollContainer() {
- return (mPrivateFlags & SCROLL_CONTAINER_ADDED) != 0;
+ return (mPrivateFlags & PFLAG_SCROLL_CONTAINER_ADDED) != 0;
}
/**
@@ -5023,16 +5105,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
public void setScrollContainer(boolean isScrollContainer) {
if (isScrollContainer) {
- if (mAttachInfo != null && (mPrivateFlags&SCROLL_CONTAINER_ADDED) == 0) {
+ if (mAttachInfo != null && (mPrivateFlags&PFLAG_SCROLL_CONTAINER_ADDED) == 0) {
mAttachInfo.mScrollContainers.add(this);
- mPrivateFlags |= SCROLL_CONTAINER_ADDED;
+ mPrivateFlags |= PFLAG_SCROLL_CONTAINER_ADDED;
}
- mPrivateFlags |= SCROLL_CONTAINER;
+ mPrivateFlags |= PFLAG_SCROLL_CONTAINER;
} else {
- if ((mPrivateFlags&SCROLL_CONTAINER_ADDED) != 0) {
+ if ((mPrivateFlags&PFLAG_SCROLL_CONTAINER_ADDED) != 0) {
mAttachInfo.mScrollContainers.remove(this);
}
- mPrivateFlags &= ~(SCROLL_CONTAINER|SCROLL_CONTAINER_ADDED);
+ mPrivateFlags &= ~(PFLAG_SCROLL_CONTAINER|PFLAG_SCROLL_CONTAINER_ADDED);
}
}
@@ -5539,7 +5621,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
@ViewDebug.IntToString(from = LAYOUT_DIRECTION_LOCALE, to = "LOCALE")
})
public int getLayoutDirection() {
- return (mPrivateFlags2 & LAYOUT_DIRECTION_MASK) >> LAYOUT_DIRECTION_MASK_SHIFT;
+ return (mPrivateFlags2 & PFLAG2_LAYOUT_DIRECTION_MASK) >> PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT;
}
/**
@@ -5557,13 +5639,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
public void setLayoutDirection(int layoutDirection) {
if (getLayoutDirection() != layoutDirection) {
// Reset the current layout direction and the resolved one
- mPrivateFlags2 &= ~LAYOUT_DIRECTION_MASK;
+ mPrivateFlags2 &= ~PFLAG2_LAYOUT_DIRECTION_MASK;
resetResolvedLayoutDirection();
// Reset padding resolution
- mPrivateFlags2 &= ~PADDING_RESOLVED;
+ mPrivateFlags2 &= ~PFLAG2_PADDING_RESOLVED;
// Set the new layout direction (filtered)
mPrivateFlags2 |=
- ((layoutDirection << LAYOUT_DIRECTION_MASK_SHIFT) & LAYOUT_DIRECTION_MASK);
+ ((layoutDirection << PFLAG2_LAYOUT_DIRECTION_MASK_SHIFT) & PFLAG2_LAYOUT_DIRECTION_MASK);
resolveRtlProperties();
// ... and ask for a layout pass
requestLayout();
@@ -5583,14 +5665,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
public int getResolvedLayoutDirection() {
final int targetSdkVersion = getContext().getApplicationInfo().targetSdkVersion;
if (targetSdkVersion < JELLY_BEAN_MR1) {
- mPrivateFlags2 |= LAYOUT_DIRECTION_RESOLVED;
+ mPrivateFlags2 |= PFLAG2_LAYOUT_DIRECTION_RESOLVED;
return LAYOUT_DIRECTION_LTR;
}
// The layout direction will be resolved only if needed
- if ((mPrivateFlags2 & LAYOUT_DIRECTION_RESOLVED) != LAYOUT_DIRECTION_RESOLVED) {
+ if ((mPrivateFlags2 & PFLAG2_LAYOUT_DIRECTION_RESOLVED) != PFLAG2_LAYOUT_DIRECTION_RESOLVED) {
resolveLayoutDirection();
}
- return ((mPrivateFlags2 & LAYOUT_DIRECTION_RESOLVED_RTL) == LAYOUT_DIRECTION_RESOLVED_RTL) ?
+ return ((mPrivateFlags2 & PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL) == PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL) ?
LAYOUT_DIRECTION_RTL : LAYOUT_DIRECTION_LTR;
}
@@ -5619,7 +5701,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
@ViewDebug.ExportedProperty(category = "layout")
public boolean hasTransientState() {
- return (mPrivateFlags2 & HAS_TRANSIENT_STATE) == HAS_TRANSIENT_STATE;
+ return (mPrivateFlags2 & PFLAG2_HAS_TRANSIENT_STATE) == PFLAG2_HAS_TRANSIENT_STATE;
}
/**
@@ -5646,8 +5728,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
if ((hasTransientState && mTransientStateCount == 1) ||
(!hasTransientState && mTransientStateCount == 0)) {
// update flag if we've just incremented up from 0 or decremented down to 0
- mPrivateFlags2 = (mPrivateFlags2 & ~HAS_TRANSIENT_STATE) |
- (hasTransientState ? HAS_TRANSIENT_STATE : 0);
+ mPrivateFlags2 = (mPrivateFlags2 & ~PFLAG2_HAS_TRANSIENT_STATE) |
+ (hasTransientState ? PFLAG2_HAS_TRANSIENT_STATE : 0);
if (mParent != null) {
try {
mParent.childHasTransientStateChanged(this, hasTransientState);
@@ -5770,12 +5852,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* the View's internal state from a previously set "pressed" state.
*/
public void setPressed(boolean pressed) {
- final boolean needsRefresh = pressed != ((mPrivateFlags & PRESSED) == PRESSED);
+ final boolean needsRefresh = pressed != ((mPrivateFlags & PFLAG_PRESSED) == PFLAG_PRESSED);
if (pressed) {
- mPrivateFlags |= PRESSED;
+ mPrivateFlags |= PFLAG_PRESSED;
} else {
- mPrivateFlags &= ~PRESSED;
+ mPrivateFlags &= ~PFLAG_PRESSED;
}
if (needsRefresh) {
@@ -5806,7 +5888,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @return true if the view is currently pressed, false otherwise
*/
public boolean isPressed() {
- return (mPrivateFlags & PRESSED) == PRESSED;
+ return (mPrivateFlags & PFLAG_PRESSED) == PFLAG_PRESSED;
}
/**
@@ -6133,7 +6215,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @return True if this View is accessibility focused.
*/
boolean isAccessibilityFocused() {
- return (mPrivateFlags2 & ACCESSIBILITY_FOCUSED) != 0;
+ return (mPrivateFlags2 & PFLAG2_ACCESSIBILITY_FOCUSED) != 0;
}
/**
@@ -6158,8 +6240,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
if ((mViewFlags & VISIBILITY_MASK) != VISIBLE) {
return false;
}
- if ((mPrivateFlags2 & ACCESSIBILITY_FOCUSED) == 0) {
- mPrivateFlags2 |= ACCESSIBILITY_FOCUSED;
+ if ((mPrivateFlags2 & PFLAG2_ACCESSIBILITY_FOCUSED) == 0) {
+ mPrivateFlags2 |= PFLAG2_ACCESSIBILITY_FOCUSED;
ViewRootImpl viewRootImpl = getViewRootImpl();
if (viewRootImpl != null) {
viewRootImpl.setAccessibilityFocus(this, null);
@@ -6181,8 +6263,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @hide
*/
public void clearAccessibilityFocus() {
- if ((mPrivateFlags2 & ACCESSIBILITY_FOCUSED) != 0) {
- mPrivateFlags2 &= ~ACCESSIBILITY_FOCUSED;
+ if ((mPrivateFlags2 & PFLAG2_ACCESSIBILITY_FOCUSED) != 0) {
+ mPrivateFlags2 &= ~PFLAG2_ACCESSIBILITY_FOCUSED;
invalidate();
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED);
notifyAccessibilityStateChanged();
@@ -6230,8 +6312,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* another view.
*/
void clearAccessibilityFocusNoCallbacks() {
- if ((mPrivateFlags2 & ACCESSIBILITY_FOCUSED) != 0) {
- mPrivateFlags2 &= ~ACCESSIBILITY_FOCUSED;
+ if ((mPrivateFlags2 & PFLAG2_ACCESSIBILITY_FOCUSED) != 0) {
+ mPrivateFlags2 &= ~PFLAG2_ACCESSIBILITY_FOCUSED;
invalidate();
}
}
@@ -6388,8 +6470,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
@ViewDebug.IntToString(from = IMPORTANT_FOR_ACCESSIBILITY_NO, to = "no")
})
public int getImportantForAccessibility() {
- return (mPrivateFlags2 & IMPORTANT_FOR_ACCESSIBILITY_MASK)
- >> IMPORTANT_FOR_ACCESSIBILITY_SHIFT;
+ return (mPrivateFlags2 & PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_MASK)
+ >> PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_SHIFT;
}
/**
@@ -6407,9 +6489,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
public void setImportantForAccessibility(int mode) {
if (mode != getImportantForAccessibility()) {
- mPrivateFlags2 &= ~IMPORTANT_FOR_ACCESSIBILITY_MASK;
- mPrivateFlags2 |= (mode << IMPORTANT_FOR_ACCESSIBILITY_SHIFT)
- & IMPORTANT_FOR_ACCESSIBILITY_MASK;
+ mPrivateFlags2 &= ~PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_MASK;
+ mPrivateFlags2 |= (mode << PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_SHIFT)
+ & PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_MASK;
notifyAccessibilityStateChanged();
}
}
@@ -6422,8 +6504,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @hide
*/
public boolean isImportantForAccessibility() {
- final int mode = (mPrivateFlags2 & IMPORTANT_FOR_ACCESSIBILITY_MASK)
- >> IMPORTANT_FOR_ACCESSIBILITY_SHIFT;
+ final int mode = (mPrivateFlags2 & PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_MASK)
+ >> PFLAG2_IMPORTANT_FOR_ACCESSIBILITY_SHIFT;
switch (mode) {
case IMPORTANT_FOR_ACCESSIBILITY_YES:
return true;
@@ -6532,8 +6614,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
if (!AccessibilityManager.getInstance(mContext).isEnabled()) {
return;
}
- if ((mPrivateFlags2 & ACCESSIBILITY_STATE_CHANGED) == 0) {
- mPrivateFlags2 |= ACCESSIBILITY_STATE_CHANGED;
+ if ((mPrivateFlags2 & PFLAG2_ACCESSIBILITY_STATE_CHANGED) == 0) {
+ mPrivateFlags2 |= PFLAG2_ACCESSIBILITY_STATE_CHANGED;
if (mParent != null) {
mParent.childAccessibilityStateChanged(this);
}
@@ -6547,7 +6629,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @hide
*/
public void resetAccessibilityStateChanged() {
- mPrivateFlags2 &= ~ACCESSIBILITY_STATE_CHANGED;
+ mPrivateFlags2 &= ~PFLAG2_ACCESSIBILITY_STATE_CHANGED;
}
/**
@@ -6799,7 +6881,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
public void onStartTemporaryDetach() {
removeUnsetPressCallback();
- mPrivateFlags |= CANCEL_NEXT_UP_EVENT;
+ mPrivateFlags |= PFLAG_CANCEL_NEXT_UP_EVENT;
}
/**
@@ -7118,13 +7200,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
if (isPressed()) {
setPressed(false);
}
- if (imm != null && (mPrivateFlags & FOCUSED) != 0) {
+ if (imm != null && (mPrivateFlags & PFLAG_FOCUSED) != 0) {
imm.focusOut(this);
}
removeLongPressCallback();
removeTapCallback();
onFocusLost();
- } else if (imm != null && (mPrivateFlags & FOCUSED) != 0) {
+ } else if (imm != null && (mPrivateFlags & PFLAG_FOCUSED) != 0) {
imm.focusIn(this);
}
refreshDrawableState();
@@ -7164,7 +7246,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
if (mAttachInfo != null) {
initialAwakenScrollBars();
} else {
- mPrivateFlags |= AWAKEN_SCROLL_BARS_ON_ATTACH;
+ mPrivateFlags |= PFLAG_AWAKEN_SCROLL_BARS_ON_ATTACH;
}
}
}
@@ -7265,7 +7347,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
outRect.bottom -= insets.bottom;
return;
}
- Display d = WindowManagerImpl.getDefault().getDefaultDisplay();
+ Display d = DisplayManager.getInstance().getRealDisplay(Display.DEFAULT_DISPLAY);
d.getRectSize(outRect);
}
@@ -7764,7 +7846,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
@ViewDebug.ExportedProperty
public boolean isHovered() {
- return (mPrivateFlags & HOVERED) != 0;
+ return (mPrivateFlags & PFLAG_HOVERED) != 0;
}
/**
@@ -7784,14 +7866,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
public void setHovered(boolean hovered) {
if (hovered) {
- if ((mPrivateFlags & HOVERED) == 0) {
- mPrivateFlags |= HOVERED;
+ if ((mPrivateFlags & PFLAG_HOVERED) == 0) {
+ mPrivateFlags |= PFLAG_HOVERED;
refreshDrawableState();
onHoverChanged(true);
}
} else {
- if ((mPrivateFlags & HOVERED) != 0) {
- mPrivateFlags &= ~HOVERED;
+ if ((mPrivateFlags & PFLAG_HOVERED) != 0) {
+ mPrivateFlags &= ~PFLAG_HOVERED;
refreshDrawableState();
onHoverChanged(false);
}
@@ -7823,7 +7905,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
final int viewFlags = mViewFlags;
if ((viewFlags & ENABLED_MASK) == DISABLED) {
- if (event.getAction() == MotionEvent.ACTION_UP && (mPrivateFlags & PRESSED) != 0) {
+ if (event.getAction() == MotionEvent.ACTION_UP && (mPrivateFlags & PFLAG_PRESSED) != 0) {
setPressed(false);
}
// A disabled view that is clickable still consumes the touch
@@ -7842,8 +7924,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
(viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE)) {
switch (event.getAction()) {
case MotionEvent.ACTION_UP:
- boolean prepressed = (mPrivateFlags & PREPRESSED) != 0;
- if ((mPrivateFlags & PRESSED) != 0 || prepressed) {
+ boolean prepressed = (mPrivateFlags & PFLAG_PREPRESSED) != 0;
+ if ((mPrivateFlags & PFLAG_PRESSED) != 0 || prepressed) {
// take focus if we don't have it already and we should in
// touch mode.
boolean focusTaken = false;
@@ -7905,7 +7987,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
// For views inside a scrolling container, delay the pressed feedback for
// a short period in case this is a scroll.
if (isInScrollingContainer) {
- mPrivateFlags |= PREPRESSED;
+ mPrivateFlags |= PFLAG_PREPRESSED;
if (mPendingCheckForTap == null) {
mPendingCheckForTap = new CheckForTap();
}
@@ -7930,7 +8012,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
if (!pointInView(x, y, mTouchSlop)) {
// Outside button
removeTapCallback();
- if ((mPrivateFlags & PRESSED) != 0) {
+ if ((mPrivateFlags & PFLAG_PRESSED) != 0) {
// Remove any future long press/tap checks
removeLongPressCallback();
@@ -7981,7 +8063,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* Remove the prepress detection timer.
*/
private void removeUnsetPressCallback() {
- if ((mPrivateFlags & PRESSED) != 0 && mUnsetPressedState != null) {
+ if ((mPrivateFlags & PFLAG_PRESSED) != 0 && mUnsetPressedState != null) {
setPressed(false);
removeCallbacks(mUnsetPressedState);
}
@@ -7992,7 +8074,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
private void removeTapCallback() {
if (mPendingCheckForTap != null) {
- mPrivateFlags &= ~PREPRESSED;
+ mPrivateFlags &= ~PFLAG_PREPRESSED;
removeCallbacks(mPendingCheckForTap);
}
}
@@ -8057,13 +8139,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
/* Check if the FOCUSABLE bit has changed */
if (((changed & FOCUSABLE_MASK) != 0) &&
- ((privateFlags & HAS_BOUNDS) !=0)) {
+ ((privateFlags & PFLAG_HAS_BOUNDS) !=0)) {
if (((old & FOCUSABLE_MASK) == FOCUSABLE)
- && ((privateFlags & FOCUSED) != 0)) {
+ && ((privateFlags & PFLAG_FOCUSED) != 0)) {
/* Give up focus if we are no longer focusable */
clearFocus();
} else if (((old & FOCUSABLE_MASK) == NOT_FOCUSABLE)
- && ((privateFlags & FOCUSED) == 0)) {
+ && ((privateFlags & PFLAG_FOCUSED) == 0)) {
/*
* Tell the view system that we are now available to take focus
* if no one else already has it.
@@ -8082,7 +8164,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* it was not visible. Marking it drawn ensures that the invalidation will
* go through.
*/
- mPrivateFlags |= DRAWN;
+ mPrivateFlags |= PFLAG_DRAWN;
invalidate(true);
needGlobalAttributesUpdate(true);
@@ -8112,7 +8194,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
// Mark the view drawn to ensure that it gets invalidated properly the next
// time it is visible and gets invalidated
- mPrivateFlags |= DRAWN;
+ mPrivateFlags |= PFLAG_DRAWN;
}
if (mAttachInfo != null) {
mAttachInfo.mViewVisibilityChanged = true;
@@ -8126,7 +8208,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* If this view is becoming invisible, set the DRAWN flag so that
* the next invalidate() will not be skipped.
*/
- mPrivateFlags |= DRAWN;
+ mPrivateFlags |= PFLAG_DRAWN;
if (((mViewFlags & VISIBILITY_MASK) == INVISIBLE) && hasFocus()) {
// root view becoming invisible shouldn't clear focus and accessibility focus
@@ -8157,25 +8239,25 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
if ((changed & DRAWING_CACHE_ENABLED) != 0) {
destroyDrawingCache();
- mPrivateFlags &= ~DRAWING_CACHE_VALID;
+ mPrivateFlags &= ~PFLAG_DRAWING_CACHE_VALID;
invalidateParentCaches();
}
if ((changed & DRAWING_CACHE_QUALITY_MASK) != 0) {
destroyDrawingCache();
- mPrivateFlags &= ~DRAWING_CACHE_VALID;
+ mPrivateFlags &= ~PFLAG_DRAWING_CACHE_VALID;
}
if ((changed & DRAW_MASK) != 0) {
if ((mViewFlags & WILL_NOT_DRAW) != 0) {
if (mBackground != null) {
- mPrivateFlags &= ~SKIP_DRAW;
- mPrivateFlags |= ONLY_DRAWS_BACKGROUND;
+ mPrivateFlags &= ~PFLAG_SKIP_DRAW;
+ mPrivateFlags |= PFLAG_ONLY_DRAWS_BACKGROUND;
} else {
- mPrivateFlags |= SKIP_DRAW;
+ mPrivateFlags |= PFLAG_SKIP_DRAW;
}
} else {
- mPrivateFlags &= ~SKIP_DRAW;
+ mPrivateFlags &= ~PFLAG_SKIP_DRAW;
}
requestLayout();
invalidate(true);
@@ -8483,7 +8565,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
// asked for the matrix; recalculate it with the current values
// Figure out if we need to update the pivot point
- if ((mPrivateFlags & PIVOT_EXPLICITLY_SET) == 0) {
+ if ((mPrivateFlags & PFLAG_PIVOT_EXPLICITLY_SET) == 0) {
if ((mRight - mLeft) != info.mPrevWidth || (mBottom - mTop) != info.mPrevHeight) {
info.mPrevWidth = mRight - mLeft;
info.mPrevHeight = mBottom - mTop;
@@ -8627,7 +8709,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
if (mDisplayList != null) {
mDisplayList.setCameraDistance(-Math.abs(distance) / dpi);
}
- if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) {
+ if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) {
// View was rejected last time it was drawn by its parent; this may have changed
invalidateParentIfNeeded();
}
@@ -8673,7 +8755,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
if (mDisplayList != null) {
mDisplayList.setRotation(rotation);
}
- if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) {
+ if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) {
// View was rejected last time it was drawn by its parent; this may have changed
invalidateParentIfNeeded();
}
@@ -8724,7 +8806,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
if (mDisplayList != null) {
mDisplayList.setRotationY(rotationY);
}
- if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) {
+ if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) {
// View was rejected last time it was drawn by its parent; this may have changed
invalidateParentIfNeeded();
}
@@ -8775,7 +8857,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
if (mDisplayList != null) {
mDisplayList.setRotationX(rotationX);
}
- if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) {
+ if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) {
// View was rejected last time it was drawn by its parent; this may have changed
invalidateParentIfNeeded();
}
@@ -8818,7 +8900,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
if (mDisplayList != null) {
mDisplayList.setScaleX(scaleX);
}
- if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) {
+ if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) {
// View was rejected last time it was drawn by its parent; this may have changed
invalidateParentIfNeeded();
}
@@ -8861,7 +8943,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
if (mDisplayList != null) {
mDisplayList.setScaleY(scaleY);
}
- if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) {
+ if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) {
// View was rejected last time it was drawn by its parent; this may have changed
invalidateParentIfNeeded();
}
@@ -8902,7 +8984,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
public void setPivotX(float pivotX) {
ensureTransformationInfo();
- mPrivateFlags |= PIVOT_EXPLICITLY_SET;
+ mPrivateFlags |= PFLAG_PIVOT_EXPLICITLY_SET;
final TransformationInfo info = mTransformationInfo;
if (info.mPivotX != pivotX) {
invalidateViewProperty(true, false);
@@ -8912,7 +8994,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
if (mDisplayList != null) {
mDisplayList.setPivotX(pivotX);
}
- if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) {
+ if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) {
// View was rejected last time it was drawn by its parent; this may have changed
invalidateParentIfNeeded();
}
@@ -8952,7 +9034,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
public void setPivotY(float pivotY) {
ensureTransformationInfo();
- mPrivateFlags |= PIVOT_EXPLICITLY_SET;
+ mPrivateFlags |= PFLAG_PIVOT_EXPLICITLY_SET;
final TransformationInfo info = mTransformationInfo;
if (info.mPivotY != pivotY) {
invalidateViewProperty(true, false);
@@ -8962,7 +9044,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
if (mDisplayList != null) {
mDisplayList.setPivotY(pivotY);
}
- if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) {
+ if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) {
// View was rejected last time it was drawn by its parent; this may have changed
invalidateParentIfNeeded();
}
@@ -9022,12 +9104,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
if (mTransformationInfo.mAlpha != alpha) {
mTransformationInfo.mAlpha = alpha;
if (onSetAlpha((int) (alpha * 255))) {
- mPrivateFlags |= ALPHA_SET;
+ mPrivateFlags |= PFLAG_ALPHA_SET;
// subclass is handling alpha - don't optimize rendering cache invalidation
invalidateParentCaches();
invalidate(true);
} else {
- mPrivateFlags &= ~ALPHA_SET;
+ mPrivateFlags &= ~PFLAG_ALPHA_SET;
invalidateViewProperty(true, false);
if (mDisplayList != null) {
mDisplayList.setAlpha(alpha);
@@ -9052,10 +9134,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
mTransformationInfo.mAlpha = alpha;
boolean subclassHandlesAlpha = onSetAlpha((int) (alpha * 255));
if (subclassHandlesAlpha) {
- mPrivateFlags |= ALPHA_SET;
+ mPrivateFlags |= PFLAG_ALPHA_SET;
return true;
} else {
- mPrivateFlags &= ~ALPHA_SET;
+ mPrivateFlags &= ~PFLAG_ALPHA_SET;
if (mDisplayList != null) {
mDisplayList.setAlpha(alpha);
}
@@ -9115,16 +9197,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
onSizeChanged(width, mBottom - mTop, width, oldHeight);
if (!matrixIsIdentity) {
- if ((mPrivateFlags & PIVOT_EXPLICITLY_SET) == 0) {
+ if ((mPrivateFlags & PFLAG_PIVOT_EXPLICITLY_SET) == 0) {
// A change in dimension means an auto-centered pivot point changes, too
mTransformationInfo.mMatrixDirty = true;
}
- mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
+ mPrivateFlags |= PFLAG_DRAWN; // force another invalidation with the new orientation
invalidate(true);
}
mBackgroundSizeChanged = true;
invalidateParentIfNeeded();
- if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) {
+ if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) {
// View was rejected last time it was drawn by its parent; this may have changed
invalidateParentIfNeeded();
}
@@ -9147,7 +9229,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @return The dirty state of this view.
*/
public boolean isDirty() {
- return (mPrivateFlags & DIRTY_MASK) != 0;
+ return (mPrivateFlags & PFLAG_DIRTY_MASK) != 0;
}
/**
@@ -9188,16 +9270,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
onSizeChanged(width, mBottom - mTop, width, oldHeight);
if (!matrixIsIdentity) {
- if ((mPrivateFlags & PIVOT_EXPLICITLY_SET) == 0) {
+ if ((mPrivateFlags & PFLAG_PIVOT_EXPLICITLY_SET) == 0) {
// A change in dimension means an auto-centered pivot point changes, too
mTransformationInfo.mMatrixDirty = true;
}
- mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
+ mPrivateFlags |= PFLAG_DRAWN; // force another invalidation with the new orientation
invalidate(true);
}
mBackgroundSizeChanged = true;
invalidateParentIfNeeded();
- if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) {
+ if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) {
// View was rejected last time it was drawn by its parent; this may have changed
invalidateParentIfNeeded();
}
@@ -9255,16 +9337,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
onSizeChanged(mRight - mLeft, height, oldWidth, height);
if (!matrixIsIdentity) {
- if ((mPrivateFlags & PIVOT_EXPLICITLY_SET) == 0) {
+ if ((mPrivateFlags & PFLAG_PIVOT_EXPLICITLY_SET) == 0) {
// A change in dimension means an auto-centered pivot point changes, too
mTransformationInfo.mMatrixDirty = true;
}
- mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
+ mPrivateFlags |= PFLAG_DRAWN; // force another invalidation with the new orientation
invalidate(true);
}
mBackgroundSizeChanged = true;
invalidateParentIfNeeded();
- if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) {
+ if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) {
// View was rejected last time it was drawn by its parent; this may have changed
invalidateParentIfNeeded();
}
@@ -9319,16 +9401,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
onSizeChanged(mRight - mLeft, height, oldWidth, height);
if (!matrixIsIdentity) {
- if ((mPrivateFlags & PIVOT_EXPLICITLY_SET) == 0) {
+ if ((mPrivateFlags & PFLAG_PIVOT_EXPLICITLY_SET) == 0) {
// A change in dimension means an auto-centered pivot point changes, too
mTransformationInfo.mMatrixDirty = true;
}
- mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
+ mPrivateFlags |= PFLAG_DRAWN; // force another invalidation with the new orientation
invalidate(true);
}
mBackgroundSizeChanged = true;
invalidateParentIfNeeded();
- if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) {
+ if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) {
// View was rejected last time it was drawn by its parent; this may have changed
invalidateParentIfNeeded();
}
@@ -9416,7 +9498,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
if (mDisplayList != null) {
mDisplayList.setTranslationX(translationX);
}
- if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) {
+ if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) {
// View was rejected last time it was drawn by its parent; this may have changed
invalidateParentIfNeeded();
}
@@ -9457,7 +9539,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
if (mDisplayList != null) {
mDisplayList.setTranslationY(translationY);
}
- if ((mPrivateFlags2 & VIEW_QUICK_REJECTED) == VIEW_QUICK_REJECTED) {
+ if ((mPrivateFlags2 & PFLAG2_VIEW_QUICK_REJECTED) == PFLAG2_VIEW_QUICK_REJECTED) {
// View was rejected last time it was drawn by its parent; this may have changed
invalidateParentIfNeeded();
}
@@ -9928,12 +10010,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
if (skipInvalidate()) {
return;
}
- if ((mPrivateFlags & (DRAWN | HAS_BOUNDS)) == (DRAWN | HAS_BOUNDS) ||
- (mPrivateFlags & DRAWING_CACHE_VALID) == DRAWING_CACHE_VALID ||
- (mPrivateFlags & INVALIDATED) != INVALIDATED) {
- mPrivateFlags &= ~DRAWING_CACHE_VALID;
- mPrivateFlags |= INVALIDATED;
- mPrivateFlags |= DIRTY;
+ if ((mPrivateFlags & (PFLAG_DRAWN | PFLAG_HAS_BOUNDS)) == (PFLAG_DRAWN | PFLAG_HAS_BOUNDS) ||
+ (mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == PFLAG_DRAWING_CACHE_VALID ||
+ (mPrivateFlags & PFLAG_INVALIDATED) != PFLAG_INVALIDATED) {
+ mPrivateFlags &= ~PFLAG_DRAWING_CACHE_VALID;
+ mPrivateFlags |= PFLAG_INVALIDATED;
+ mPrivateFlags |= PFLAG_DIRTY;
final ViewParent p = mParent;
final AttachInfo ai = mAttachInfo;
//noinspection PointlessBooleanExpression,ConstantConditions
@@ -9971,12 +10053,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
if (skipInvalidate()) {
return;
}
- if ((mPrivateFlags & (DRAWN | HAS_BOUNDS)) == (DRAWN | HAS_BOUNDS) ||
- (mPrivateFlags & DRAWING_CACHE_VALID) == DRAWING_CACHE_VALID ||
- (mPrivateFlags & INVALIDATED) != INVALIDATED) {
- mPrivateFlags &= ~DRAWING_CACHE_VALID;
- mPrivateFlags |= INVALIDATED;
- mPrivateFlags |= DIRTY;
+ if ((mPrivateFlags & (PFLAG_DRAWN | PFLAG_HAS_BOUNDS)) == (PFLAG_DRAWN | PFLAG_HAS_BOUNDS) ||
+ (mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == PFLAG_DRAWING_CACHE_VALID ||
+ (mPrivateFlags & PFLAG_INVALIDATED) != PFLAG_INVALIDATED) {
+ mPrivateFlags &= ~PFLAG_DRAWING_CACHE_VALID;
+ mPrivateFlags |= PFLAG_INVALIDATED;
+ mPrivateFlags |= PFLAG_DIRTY;
final ViewParent p = mParent;
final AttachInfo ai = mAttachInfo;
//noinspection PointlessBooleanExpression,ConstantConditions
@@ -10023,15 +10105,15 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
if (skipInvalidate()) {
return;
}
- if ((mPrivateFlags & (DRAWN | HAS_BOUNDS)) == (DRAWN | HAS_BOUNDS) ||
- (invalidateCache && (mPrivateFlags & DRAWING_CACHE_VALID) == DRAWING_CACHE_VALID) ||
- (mPrivateFlags & INVALIDATED) != INVALIDATED || isOpaque() != mLastIsOpaque) {
+ if ((mPrivateFlags & (PFLAG_DRAWN | PFLAG_HAS_BOUNDS)) == (PFLAG_DRAWN | PFLAG_HAS_BOUNDS) ||
+ (invalidateCache && (mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == PFLAG_DRAWING_CACHE_VALID) ||
+ (mPrivateFlags & PFLAG_INVALIDATED) != PFLAG_INVALIDATED || isOpaque() != mLastIsOpaque) {
mLastIsOpaque = isOpaque();
- mPrivateFlags &= ~DRAWN;
- mPrivateFlags |= DIRTY;
+ mPrivateFlags &= ~PFLAG_DRAWN;
+ mPrivateFlags |= PFLAG_DIRTY;
if (invalidateCache) {
- mPrivateFlags |= INVALIDATED;
- mPrivateFlags &= ~DRAWING_CACHE_VALID;
+ mPrivateFlags |= PFLAG_INVALIDATED;
+ mPrivateFlags &= ~PFLAG_DRAWING_CACHE_VALID;
}
final AttachInfo ai = mAttachInfo;
final ViewParent p = mParent;
@@ -10072,12 +10154,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* list properties are not being used in this view
*/
void invalidateViewProperty(boolean invalidateParent, boolean forceRedraw) {
- if (mDisplayList == null || (mPrivateFlags & DRAW_ANIMATION) == DRAW_ANIMATION) {
+ if (mDisplayList == null || (mPrivateFlags & PFLAG_DRAW_ANIMATION) == PFLAG_DRAW_ANIMATION) {
if (invalidateParent) {
invalidateParentCaches();
}
if (forceRedraw) {
- mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
+ mPrivateFlags |= PFLAG_DRAWN; // force another invalidation with the new orientation
}
invalidate(false);
} else {
@@ -10121,7 +10203,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
protected void invalidateParentCaches() {
if (mParent instanceof View) {
- ((View) mParent).mPrivateFlags |= INVALIDATED;
+ ((View) mParent).mPrivateFlags |= PFLAG_INVALIDATED;
}
}
@@ -10153,7 +10235,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
@ViewDebug.ExportedProperty(category = "drawing")
public boolean isOpaque() {
- return (mPrivateFlags & OPAQUE_MASK) == OPAQUE_MASK &&
+ return (mPrivateFlags & PFLAG_OPAQUE_MASK) == PFLAG_OPAQUE_MASK &&
((mTransformationInfo != null ? mTransformationInfo.mAlpha : 1.0f) >= 1.0f);
}
@@ -10167,17 +10249,17 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
// - Doesn't have scrollbars or scrollbars are inside overlay
if (mBackground != null && mBackground.getOpacity() == PixelFormat.OPAQUE) {
- mPrivateFlags |= OPAQUE_BACKGROUND;
+ mPrivateFlags |= PFLAG_OPAQUE_BACKGROUND;
} else {
- mPrivateFlags &= ~OPAQUE_BACKGROUND;
+ mPrivateFlags &= ~PFLAG_OPAQUE_BACKGROUND;
}
final int flags = mViewFlags;
if (((flags & SCROLLBARS_VERTICAL) == 0 && (flags & SCROLLBARS_HORIZONTAL) == 0) ||
(flags & SCROLLBARS_STYLE_MASK) == SCROLLBARS_INSIDE_OVERLAY) {
- mPrivateFlags |= OPAQUE_SCROLLBARS;
+ mPrivateFlags |= PFLAG_OPAQUE_SCROLLBARS;
} else {
- mPrivateFlags &= ~OPAQUE_SCROLLBARS;
+ mPrivateFlags &= ~PFLAG_OPAQUE_SCROLLBARS;
}
}
@@ -10185,7 +10267,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @hide
*/
protected boolean hasOpaqueScrollbars() {
- return (mPrivateFlags & OPAQUE_SCROLLBARS) == OPAQUE_SCROLLBARS;
+ return (mPrivateFlags & PFLAG_OPAQUE_SCROLLBARS) == PFLAG_OPAQUE_SCROLLBARS;
}
/**
@@ -11230,13 +11312,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @see #onDetachedFromWindow()
*/
protected void onAttachedToWindow() {
- if ((mPrivateFlags & REQUEST_TRANSPARENT_REGIONS) != 0) {
+ if ((mPrivateFlags & PFLAG_REQUEST_TRANSPARENT_REGIONS) != 0) {
mParent.requestTransparentRegion(this);
}
- if ((mPrivateFlags & AWAKEN_SCROLL_BARS_ON_ATTACH) != 0) {
+ if ((mPrivateFlags & PFLAG_AWAKEN_SCROLL_BARS_ON_ATTACH) != 0) {
initialAwakenScrollBars();
- mPrivateFlags &= ~AWAKEN_SCROLL_BARS_ON_ATTACH;
+ mPrivateFlags &= ~PFLAG_AWAKEN_SCROLL_BARS_ON_ATTACH;
}
jumpDrawablesToCurrentState();
@@ -11297,7 +11379,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
public void resolveLayoutDirection() {
// Clear any previous layout direction resolution
- mPrivateFlags2 &= ~LAYOUT_DIRECTION_RESOLVED_MASK;
+ mPrivateFlags2 &= ~PFLAG2_LAYOUT_DIRECTION_RESOLVED_MASK;
if (hasRtlSupport()) {
// Set resolved depending on layout direction
@@ -11314,15 +11396,15 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
if (!viewGroup.canResolveLayoutDirection()) return;
if (viewGroup.getResolvedLayoutDirection() == LAYOUT_DIRECTION_RTL) {
- mPrivateFlags2 |= LAYOUT_DIRECTION_RESOLVED_RTL;
+ mPrivateFlags2 |= PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL;
}
break;
case LAYOUT_DIRECTION_RTL:
- mPrivateFlags2 |= LAYOUT_DIRECTION_RESOLVED_RTL;
+ mPrivateFlags2 |= PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL;
break;
case LAYOUT_DIRECTION_LOCALE:
if(isLayoutDirectionRtl(Locale.getDefault())) {
- mPrivateFlags2 |= LAYOUT_DIRECTION_RESOLVED_RTL;
+ mPrivateFlags2 |= PFLAG2_LAYOUT_DIRECTION_RESOLVED_RTL;
}
break;
default:
@@ -11331,7 +11413,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
// Set to resolved
- mPrivateFlags2 |= LAYOUT_DIRECTION_RESOLVED;
+ mPrivateFlags2 |= PFLAG2_LAYOUT_DIRECTION_RESOLVED;
onResolvedLayoutDirectionChanged();
}
@@ -11347,7 +11429,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* Return if padding has been resolved
*/
boolean isPaddingResolved() {
- return (mPrivateFlags2 & PADDING_RESOLVED) != 0;
+ return (mPrivateFlags2 & PFLAG2_PADDING_RESOLVED) != 0;
}
/**
@@ -11403,7 +11485,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
onPaddingChanged(resolvedLayoutDirection);
}
- mPrivateFlags2 |= PADDING_RESOLVED;
+ mPrivateFlags2 |= PFLAG2_PADDING_RESOLVED;
}
/**
@@ -11439,7 +11521,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
public void resetResolvedLayoutDirection() {
// Reset the current resolved bits
- mPrivateFlags2 &= ~LAYOUT_DIRECTION_RESOLVED_MASK;
+ mPrivateFlags2 &= ~PFLAG2_LAYOUT_DIRECTION_RESOLVED_MASK;
onResolvedLayoutDirectionReset();
// Reset also the text direction
resetResolvedTextDirection();
@@ -11473,7 +11555,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @see #onAttachedToWindow()
*/
protected void onDetachedFromWindow() {
- mPrivateFlags &= ~CANCEL_NEXT_UP_EVENT;
+ mPrivateFlags &= ~PFLAG_CANCEL_NEXT_UP_EVENT;
removeUnsetPressCallback();
removeLongPressCallback();
@@ -11499,7 +11581,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
resetResolvedLayoutDirection();
resetResolvedTextAlignment();
resetAccessibilityStateChanged();
- mPrivateFlags2 &= ~PADDING_RESOLVED;
+ mPrivateFlags2 &= ~PFLAG2_PADDING_RESOLVED;
}
/**
@@ -11541,6 +11623,15 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
/**
+ * Gets the logical display to which the view's window has been attached.
+ *
+ * @return The logical display, or null if the view is not currently attached to a window.
+ */
+ public Display getDisplay() {
+ return mAttachInfo != null ? mAttachInfo.mDisplay : null;
+ }
+
+ /**
* Retrieve private session object this view hierarchy is using to
* communicate with the window manager.
* @return the session object to communicate with the window manager
@@ -11558,14 +11649,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
mAttachInfo = info;
mWindowAttachCount++;
// We will need to evaluate the drawable state at least once.
- mPrivateFlags |= DRAWABLE_STATE_DIRTY;
+ mPrivateFlags |= PFLAG_DRAWABLE_STATE_DIRTY;
if (mFloatingTreeObserver != null) {
info.mTreeObserver.merge(mFloatingTreeObserver);
mFloatingTreeObserver = null;
}
- if ((mPrivateFlags&SCROLL_CONTAINER) != 0) {
+ if ((mPrivateFlags&PFLAG_SCROLL_CONTAINER) != 0) {
mAttachInfo.mScrollContainers.add(this);
- mPrivateFlags |= SCROLL_CONTAINER_ADDED;
+ mPrivateFlags |= PFLAG_SCROLL_CONTAINER_ADDED;
}
performCollectViewAttributes(mAttachInfo, visibility);
onAttachedToWindow();
@@ -11587,7 +11678,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
if (vis != GONE) {
onWindowVisibilityChanged(vis);
}
- if ((mPrivateFlags&DRAWABLE_STATE_DIRTY) != 0) {
+ if ((mPrivateFlags&PFLAG_DRAWABLE_STATE_DIRTY) != 0) {
// If nobody has evaluated the drawable state yet, then do it now.
refreshDrawableState();
}
@@ -11617,9 +11708,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
}
- if ((mPrivateFlags & SCROLL_CONTAINER_ADDED) != 0) {
+ if ((mPrivateFlags & PFLAG_SCROLL_CONTAINER_ADDED) != 0) {
mAttachInfo.mScrollContainers.remove(this);
- mPrivateFlags &= ~SCROLL_CONTAINER_ADDED;
+ mPrivateFlags &= ~PFLAG_SCROLL_CONTAINER_ADDED;
}
mAttachInfo = null;
@@ -11651,9 +11742,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
protected void dispatchSaveInstanceState(SparseArray<Parcelable> container) {
if (mID != NO_ID && (mViewFlags & SAVE_DISABLED_MASK) == 0) {
- mPrivateFlags &= ~SAVE_STATE_CALLED;
+ mPrivateFlags &= ~PFLAG_SAVE_STATE_CALLED;
Parcelable state = onSaveInstanceState();
- if ((mPrivateFlags & SAVE_STATE_CALLED) == 0) {
+ if ((mPrivateFlags & PFLAG_SAVE_STATE_CALLED) == 0) {
throw new IllegalStateException(
"Derived class did not call super.onSaveInstanceState()");
}
@@ -11687,7 +11778,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @see #setSaveEnabled(boolean)
*/
protected Parcelable onSaveInstanceState() {
- mPrivateFlags |= SAVE_STATE_CALLED;
+ mPrivateFlags |= PFLAG_SAVE_STATE_CALLED;
return BaseSavedState.EMPTY_STATE;
}
@@ -11722,9 +11813,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
if (state != null) {
// Log.i("View", "Restoreing #" + Integer.toHexString(mID)
// + ": " + state);
- mPrivateFlags &= ~SAVE_STATE_CALLED;
+ mPrivateFlags &= ~PFLAG_SAVE_STATE_CALLED;
onRestoreInstanceState(state);
- if ((mPrivateFlags & SAVE_STATE_CALLED) == 0) {
+ if ((mPrivateFlags & PFLAG_SAVE_STATE_CALLED) == 0) {
throw new IllegalStateException(
"Derived class did not call super.onRestoreInstanceState()");
}
@@ -11745,7 +11836,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @see #dispatchRestoreInstanceState(android.util.SparseArray)
*/
protected void onRestoreInstanceState(Parcelable state) {
- mPrivateFlags |= SAVE_STATE_CALLED;
+ mPrivateFlags |= PFLAG_SAVE_STATE_CALLED;
if (state != BaseSavedState.EMPTY_STATE && state != null) {
throw new IllegalArgumentException("Wrong state class, expecting View State but "
+ "received " + state.getClass().toString() + " instead. This usually happens "
@@ -11960,7 +12051,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
return null;
}
- if ((mPrivateFlags & DRAWING_CACHE_VALID) == 0 || mHardwareLayer == null) {
+ if ((mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == 0 || mHardwareLayer == null) {
if (mHardwareLayer == null) {
mHardwareLayer = mAttachInfo.mHardwareRenderer.createHardwareLayer(
width, height, isOpaque());
@@ -12090,10 +12181,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
@SuppressWarnings({"UnusedDeclaration"})
public void outputDirtyFlags(String indent, boolean clear, int clearMask) {
- Log.d("View", indent + this + " DIRTY(" + (mPrivateFlags & View.DIRTY_MASK) +
- ") DRAWN(" + (mPrivateFlags & DRAWN) + ")" + " CACHE_VALID(" +
- (mPrivateFlags & View.DRAWING_CACHE_VALID) +
- ") INVALIDATED(" + (mPrivateFlags & INVALIDATED) + ")");
+ Log.d("View", indent + this + " DIRTY(" + (mPrivateFlags & View.PFLAG_DIRTY_MASK) +
+ ") DRAWN(" + (mPrivateFlags & PFLAG_DRAWN) + ")" + " CACHE_VALID(" +
+ (mPrivateFlags & View.PFLAG_DRAWING_CACHE_VALID) +
+ ") INVALIDATED(" + (mPrivateFlags & PFLAG_INVALIDATED) + ")");
if (clear) {
mPrivateFlags &= clearMask;
}
@@ -12157,15 +12248,15 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
return null;
}
- if (((mPrivateFlags & DRAWING_CACHE_VALID) == 0 ||
+ if (((mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == 0 ||
displayList == null || !displayList.isValid() ||
(!isLayer && mRecreateDisplayList))) {
// Don't need to recreate the display list, just need to tell our
// children to restore/recreate theirs
if (displayList != null && displayList.isValid() &&
!isLayer && !mRecreateDisplayList) {
- mPrivateFlags |= DRAWN | DRAWING_CACHE_VALID;
- mPrivateFlags &= ~DIRTY_MASK;
+ mPrivateFlags |= PFLAG_DRAWN | PFLAG_DRAWING_CACHE_VALID;
+ mPrivateFlags &= ~PFLAG_DIRTY_MASK;
dispatchGetDisplayList();
return displayList;
@@ -12220,12 +12311,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
canvas.translate(-mScrollX, -mScrollY);
if (!isLayer) {
- mPrivateFlags |= DRAWN | DRAWING_CACHE_VALID;
- mPrivateFlags &= ~DIRTY_MASK;
+ mPrivateFlags |= PFLAG_DRAWN | PFLAG_DRAWING_CACHE_VALID;
+ mPrivateFlags &= ~PFLAG_DIRTY_MASK;
}
// Fast path for layouts with no backgrounds
- if ((mPrivateFlags & SKIP_DRAW) == SKIP_DRAW) {
+ if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) {
dispatchDraw(canvas);
} else {
draw(canvas);
@@ -12243,8 +12334,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
}
} else if (!isLayer) {
- mPrivateFlags |= DRAWN | DRAWING_CACHE_VALID;
- mPrivateFlags &= ~DIRTY_MASK;
+ mPrivateFlags |= PFLAG_DRAWN | PFLAG_DRAWING_CACHE_VALID;
+ mPrivateFlags &= ~PFLAG_DIRTY_MASK;
}
return displayList;
@@ -12366,7 +12457,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
public void setDrawingCacheBackgroundColor(int color) {
if (color != mDrawingCacheBackgroundColor) {
mDrawingCacheBackgroundColor = color;
- mPrivateFlags &= ~DRAWING_CACHE_VALID;
+ mPrivateFlags &= ~PFLAG_DRAWING_CACHE_VALID;
}
}
@@ -12412,7 +12503,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @see #destroyDrawingCache()
*/
public void buildDrawingCache(boolean autoScale) {
- if ((mPrivateFlags & DRAWING_CACHE_VALID) == 0 || (autoScale ?
+ if ((mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == 0 || (autoScale ?
mDrawingCache == null : mUnscaledDrawingCache == null)) {
mCachingFailed = false;
@@ -12528,15 +12619,15 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
canvas.translate(-mScrollX, -mScrollY);
- mPrivateFlags |= DRAWN;
+ mPrivateFlags |= PFLAG_DRAWN;
if (mAttachInfo == null || !mAttachInfo.mHardwareAccelerated ||
mLayerType != LAYER_TYPE_NONE) {
- mPrivateFlags |= DRAWING_CACHE_VALID;
+ mPrivateFlags |= PFLAG_DRAWING_CACHE_VALID;
}
// Fast path for layouts with no backgrounds
- if ((mPrivateFlags & SKIP_DRAW) == SKIP_DRAW) {
- mPrivateFlags &= ~DIRTY_MASK;
+ if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) {
+ mPrivateFlags &= ~PFLAG_DIRTY_MASK;
dispatchDraw(canvas);
} else {
draw(canvas);
@@ -12604,10 +12695,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
// Temporarily remove the dirty mask
int flags = mPrivateFlags;
- mPrivateFlags &= ~DIRTY_MASK;
+ mPrivateFlags &= ~PFLAG_DIRTY_MASK;
// Fast path for layouts with no backgrounds
- if ((mPrivateFlags & SKIP_DRAW) == SKIP_DRAW) {
+ if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) {
dispatchDraw(canvas);
} else {
draw(canvas);
@@ -12797,7 +12888,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
} else if ((flags & ViewGroup.FLAG_INVALIDATE_REQUIRED) == 0) {
// The child need to draw an animation, potentially offscreen, so
// make sure we do not cancel invalidate requests
- parent.mPrivateFlags |= DRAW_ANIMATION;
+ parent.mPrivateFlags |= PFLAG_DRAW_ANIMATION;
parent.invalidate(mLeft, mTop, mRight, mBottom);
}
} else {
@@ -12810,7 +12901,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
// The child need to draw an animation, potentially offscreen, so
// make sure we do not cancel invalidate requests
- parent.mPrivateFlags |= DRAW_ANIMATION;
+ parent.mPrivateFlags |= PFLAG_DRAW_ANIMATION;
final int left = mLeft + (int) region.left;
final int top = mTop + (int) region.top;
@@ -12872,7 +12963,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
mTransformationInfo.matrix3D = new Matrix();
}
displayList.setCameraDistance(mTransformationInfo.mCamera.getLocationZ());
- if ((mPrivateFlags & PIVOT_EXPLICITLY_SET) == PIVOT_EXPLICITLY_SET) {
+ if ((mPrivateFlags & PFLAG_PIVOT_EXPLICITLY_SET) == PFLAG_PIVOT_EXPLICITLY_SET) {
displayList.setPivotX(getPivotX());
displayList.setPivotY(getPivotY());
}
@@ -12920,15 +13011,15 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
more = drawAnimation(parent, drawingTime, a, scalingRequired);
concatMatrix = a.willChangeTransformationMatrix();
if (concatMatrix) {
- mPrivateFlags3 |= VIEW_IS_ANIMATING_TRANSFORM;
+ mPrivateFlags3 |= PFLAG3_VIEW_IS_ANIMATING_TRANSFORM;
}
transformToApply = parent.mChildTransformation;
} else {
- if ((mPrivateFlags3 & VIEW_IS_ANIMATING_TRANSFORM) == VIEW_IS_ANIMATING_TRANSFORM &&
+ if ((mPrivateFlags3 & PFLAG3_VIEW_IS_ANIMATING_TRANSFORM) == PFLAG3_VIEW_IS_ANIMATING_TRANSFORM &&
mDisplayList != null) {
// No longer animating: clear out old animation matrix
mDisplayList.setAnimationMatrix(null);
- mPrivateFlags3 &= ~VIEW_IS_ANIMATING_TRANSFORM;
+ mPrivateFlags3 &= ~PFLAG3_VIEW_IS_ANIMATING_TRANSFORM;
}
if (!useDisplayListProperties &&
(flags & ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) != 0) {
@@ -12947,21 +13038,21 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
// Sets the flag as early as possible to allow draw() implementations
// to call invalidate() successfully when doing animations
- mPrivateFlags |= DRAWN;
+ mPrivateFlags |= PFLAG_DRAWN;
if (!concatMatrix && (flags & ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) == 0 &&
canvas.quickReject(mLeft, mTop, mRight, mBottom, Canvas.EdgeType.BW) &&
- (mPrivateFlags & DRAW_ANIMATION) == 0) {
- mPrivateFlags2 |= VIEW_QUICK_REJECTED;
+ (mPrivateFlags & PFLAG_DRAW_ANIMATION) == 0) {
+ mPrivateFlags2 |= PFLAG2_VIEW_QUICK_REJECTED;
return more;
}
- mPrivateFlags2 &= ~VIEW_QUICK_REJECTED;
+ mPrivateFlags2 &= ~PFLAG2_VIEW_QUICK_REJECTED;
if (hardwareAccelerated) {
// Clear INVALIDATED flag to allow invalidation to occur during rendering, but
// retain the flag's value temporarily in the mRecreateDisplayList flag
- mRecreateDisplayList = (mPrivateFlags & INVALIDATED) == INVALIDATED;
- mPrivateFlags &= ~INVALIDATED;
+ mRecreateDisplayList = (mPrivateFlags & PFLAG_INVALIDATED) == PFLAG_INVALIDATED;
+ mPrivateFlags &= ~PFLAG_INVALIDATED;
}
DisplayList displayList = null;
@@ -13045,7 +13136,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
float alpha = useDisplayListProperties ? 1 : getAlpha();
if (transformToApply != null || alpha < 1 || !hasIdentityMatrix() ||
- (mPrivateFlags3 & VIEW_IS_ANIMATING_ALPHA) == VIEW_IS_ANIMATING_ALPHA) {
+ (mPrivateFlags3 & PFLAG3_VIEW_IS_ANIMATING_ALPHA) == PFLAG3_VIEW_IS_ANIMATING_ALPHA) {
if (transformToApply != null || !childHasIdentityMatrix) {
int transX = 0;
int transY = 0;
@@ -13085,11 +13176,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
// Deal with alpha if it is or used to be <1
if (alpha < 1 ||
- (mPrivateFlags3 & VIEW_IS_ANIMATING_ALPHA) == VIEW_IS_ANIMATING_ALPHA) {
+ (mPrivateFlags3 & PFLAG3_VIEW_IS_ANIMATING_ALPHA) == PFLAG3_VIEW_IS_ANIMATING_ALPHA) {
if (alpha < 1) {
- mPrivateFlags3 |= VIEW_IS_ANIMATING_ALPHA;
+ mPrivateFlags3 |= PFLAG3_VIEW_IS_ANIMATING_ALPHA;
} else {
- mPrivateFlags3 &= ~VIEW_IS_ANIMATING_ALPHA;
+ mPrivateFlags3 &= ~PFLAG3_VIEW_IS_ANIMATING_ALPHA;
}
parent.mGroupFlags |= ViewGroup.FLAG_CLEAR_TRANSFORMATION;
if (hasNoCache) {
@@ -13110,13 +13201,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
} else {
// Alpha is handled by the child directly, clobber the layer's alpha
- mPrivateFlags |= ALPHA_SET;
+ mPrivateFlags |= PFLAG_ALPHA_SET;
}
}
}
- } else if ((mPrivateFlags & ALPHA_SET) == ALPHA_SET) {
+ } else if ((mPrivateFlags & PFLAG_ALPHA_SET) == PFLAG_ALPHA_SET) {
onSetAlpha(255);
- mPrivateFlags &= ~ALPHA_SET;
+ mPrivateFlags &= ~PFLAG_ALPHA_SET;
}
if ((flags & ViewGroup.FLAG_CLIP_CHILDREN) == ViewGroup.FLAG_CLIP_CHILDREN &&
@@ -13163,19 +13254,19 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
if (!layerRendered) {
if (!hasDisplayList) {
// Fast path for layouts with no backgrounds
- if ((mPrivateFlags & SKIP_DRAW) == SKIP_DRAW) {
- mPrivateFlags &= ~DIRTY_MASK;
+ if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) {
+ mPrivateFlags &= ~PFLAG_DIRTY_MASK;
dispatchDraw(canvas);
} else {
draw(canvas);
}
} else {
- mPrivateFlags &= ~DIRTY_MASK;
+ mPrivateFlags &= ~PFLAG_DIRTY_MASK;
((HardwareCanvas) canvas).drawDisplayList(displayList, null, flags);
}
}
} else if (cache != null) {
- mPrivateFlags &= ~DIRTY_MASK;
+ mPrivateFlags &= ~PFLAG_DIRTY_MASK;
Paint cachePaint;
if (layerType == LAYER_TYPE_NONE) {
@@ -13215,7 +13306,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
// display lists to render, force an invalidate to allow the animation to
// continue drawing another frame
parent.invalidate(true);
- if (a.hasAlpha() && (mPrivateFlags & ALPHA_SET) == ALPHA_SET) {
+ if (a.hasAlpha() && (mPrivateFlags & PFLAG_ALPHA_SET) == PFLAG_ALPHA_SET) {
// alpha animations should cause the child to recreate its display list
invalidate(true);
}
@@ -13237,9 +13328,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
public void draw(Canvas canvas) {
final int privateFlags = mPrivateFlags;
- final boolean dirtyOpaque = (privateFlags & DIRTY_MASK) == DIRTY_OPAQUE &&
+ final boolean dirtyOpaque = (privateFlags & PFLAG_DIRTY_MASK) == PFLAG_DIRTY_OPAQUE &&
(mAttachInfo == null || !mAttachInfo.mIgnoreDirtyState);
- mPrivateFlags = (privateFlags & ~DIRTY_MASK) | DRAWN;
+ mPrivateFlags = (privateFlags & ~PFLAG_DIRTY_MASK) | PFLAG_DRAWN;
/*
* Draw traversal performs several drawing steps which must be executed
@@ -13494,12 +13585,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
String output = "";
int numFlags = 0;
- if ((privateFlags & WANTS_FOCUS) == WANTS_FOCUS) {
+ if ((privateFlags & PFLAG_WANTS_FOCUS) == PFLAG_WANTS_FOCUS) {
output += "WANTS_FOCUS";
numFlags++;
}
- if ((privateFlags & FOCUSED) == FOCUSED) {
+ if ((privateFlags & PFLAG_FOCUSED) == PFLAG_FOCUSED) {
if (numFlags > 0) {
output += " ";
}
@@ -13507,7 +13598,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
numFlags++;
}
- if ((privateFlags & SELECTED) == SELECTED) {
+ if ((privateFlags & PFLAG_SELECTED) == PFLAG_SELECTED) {
if (numFlags > 0) {
output += " ";
}
@@ -13515,7 +13606,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
numFlags++;
}
- if ((privateFlags & IS_ROOT_NAMESPACE) == IS_ROOT_NAMESPACE) {
+ if ((privateFlags & PFLAG_IS_ROOT_NAMESPACE) == PFLAG_IS_ROOT_NAMESPACE) {
if (numFlags > 0) {
output += " ";
}
@@ -13523,7 +13614,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
numFlags++;
}
- if ((privateFlags & HAS_BOUNDS) == HAS_BOUNDS) {
+ if ((privateFlags & PFLAG_HAS_BOUNDS) == PFLAG_HAS_BOUNDS) {
if (numFlags > 0) {
output += " ";
}
@@ -13531,7 +13622,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
numFlags++;
}
- if ((privateFlags & DRAWN) == DRAWN) {
+ if ((privateFlags & PFLAG_DRAWN) == PFLAG_DRAWN) {
if (numFlags > 0) {
output += " ";
}
@@ -13548,7 +13639,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @return true if the layout will be forced during next layout pass
*/
public boolean isLayoutRequested() {
- return (mPrivateFlags & FORCE_LAYOUT) == FORCE_LAYOUT;
+ return (mPrivateFlags & PFLAG_FORCE_LAYOUT) == PFLAG_FORCE_LAYOUT;
}
/**
@@ -13578,9 +13669,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
int oldB = mBottom;
int oldR = mRight;
boolean changed = setFrame(l, t, r, b);
- if (changed || (mPrivateFlags & LAYOUT_REQUIRED) == LAYOUT_REQUIRED) {
+ if (changed || (mPrivateFlags & PFLAG_LAYOUT_REQUIRED) == PFLAG_LAYOUT_REQUIRED) {
onLayout(changed, l, t, r, b);
- mPrivateFlags &= ~LAYOUT_REQUIRED;
+ mPrivateFlags &= ~PFLAG_LAYOUT_REQUIRED;
ListenerInfo li = mListenerInfo;
if (li != null && li.mOnLayoutChangeListeners != null) {
@@ -13592,7 +13683,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
}
}
- mPrivateFlags &= ~FORCE_LAYOUT;
+ mPrivateFlags &= ~PFLAG_FORCE_LAYOUT;
}
/**
@@ -13636,7 +13727,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
changed = true;
// Remember our drawn bit
- int drawn = mPrivateFlags & DRAWN;
+ int drawn = mPrivateFlags & PFLAG_DRAWN;
int oldWidth = mRight - mLeft;
int oldHeight = mBottom - mTop;
@@ -13655,11 +13746,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
mDisplayList.setLeftTopRightBottom(mLeft, mTop, mRight, mBottom);
}
- mPrivateFlags |= HAS_BOUNDS;
+ mPrivateFlags |= PFLAG_HAS_BOUNDS;
if (sizeChanged) {
- if ((mPrivateFlags & PIVOT_EXPLICITLY_SET) == 0) {
+ if ((mPrivateFlags & PFLAG_PIVOT_EXPLICITLY_SET) == 0) {
// A change in dimension means an auto-centered pivot point changes, too
if (mTransformationInfo != null) {
mTransformationInfo.mMatrixDirty = true;
@@ -13674,7 +13765,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
// This is because someone may have invalidated this view
// before this call to setFrame came in, thereby clearing
// the DRAWN bit.
- mPrivateFlags |= DRAWN;
+ mPrivateFlags |= PFLAG_DRAWN;
invalidate(sizeChanged);
// parent display list may need to be recreated based on a change in the bounds
// of any child
@@ -13852,7 +13943,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @see #getDrawableState
*/
public void refreshDrawableState() {
- mPrivateFlags |= DRAWABLE_STATE_DIRTY;
+ mPrivateFlags |= PFLAG_DRAWABLE_STATE_DIRTY;
drawableStateChanged();
ViewParent parent = mParent;
@@ -13872,11 +13963,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @see #onCreateDrawableState(int)
*/
public final int[] getDrawableState() {
- if ((mDrawableState != null) && ((mPrivateFlags & DRAWABLE_STATE_DIRTY) == 0)) {
+ if ((mDrawableState != null) && ((mPrivateFlags & PFLAG_DRAWABLE_STATE_DIRTY) == 0)) {
return mDrawableState;
} else {
mDrawableState = onCreateDrawableState(0);
- mPrivateFlags &= ~DRAWABLE_STATE_DIRTY;
+ mPrivateFlags &= ~PFLAG_DRAWABLE_STATE_DIRTY;
return mDrawableState;
}
}
@@ -13907,12 +13998,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
int privateFlags = mPrivateFlags;
int viewStateIndex = 0;
- if ((privateFlags & PRESSED) != 0) viewStateIndex |= VIEW_STATE_PRESSED;
+ if ((privateFlags & PFLAG_PRESSED) != 0) viewStateIndex |= VIEW_STATE_PRESSED;
if ((mViewFlags & ENABLED_MASK) == ENABLED) viewStateIndex |= VIEW_STATE_ENABLED;
if (isFocused()) viewStateIndex |= VIEW_STATE_FOCUSED;
- if ((privateFlags & SELECTED) != 0) viewStateIndex |= VIEW_STATE_SELECTED;
+ if ((privateFlags & PFLAG_SELECTED) != 0) viewStateIndex |= VIEW_STATE_SELECTED;
if (hasWindowFocus()) viewStateIndex |= VIEW_STATE_WINDOW_FOCUSED;
- if ((privateFlags & ACTIVATED) != 0) viewStateIndex |= VIEW_STATE_ACTIVATED;
+ if ((privateFlags & PFLAG_ACTIVATED) != 0) viewStateIndex |= VIEW_STATE_ACTIVATED;
if (mAttachInfo != null && mAttachInfo.mHardwareAccelerationRequested &&
HardwareRenderer.isAvailable()) {
// This is set if HW acceleration is requested, even if the current
@@ -13920,11 +14011,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
// windows to better match their app.
viewStateIndex |= VIEW_STATE_ACCELERATED;
}
- if ((privateFlags & HOVERED) != 0) viewStateIndex |= VIEW_STATE_HOVERED;
+ if ((privateFlags & PFLAG_HOVERED) != 0) viewStateIndex |= VIEW_STATE_HOVERED;
final int privateFlags2 = mPrivateFlags2;
- if ((privateFlags2 & DRAG_CAN_ACCEPT) != 0) viewStateIndex |= VIEW_STATE_DRAG_CAN_ACCEPT;
- if ((privateFlags2 & DRAG_HOVERED) != 0) viewStateIndex |= VIEW_STATE_DRAG_HOVERED;
+ if ((privateFlags2 & PFLAG2_DRAG_CAN_ACCEPT) != 0) viewStateIndex |= VIEW_STATE_DRAG_CAN_ACCEPT;
+ if ((privateFlags2 & PFLAG2_DRAG_HOVERED) != 0) viewStateIndex |= VIEW_STATE_DRAG_HOVERED;
drawableState = VIEW_STATE_SETS[viewStateIndex];
@@ -13932,10 +14023,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
if (false) {
Log.i("View", "drawableStateIndex=" + viewStateIndex);
Log.i("View", toString()
- + " pressed=" + ((privateFlags & PRESSED) != 0)
+ + " pressed=" + ((privateFlags & PFLAG_PRESSED) != 0)
+ " en=" + ((mViewFlags & ENABLED_MASK) == ENABLED)
+ " fo=" + hasFocus()
- + " sl=" + ((privateFlags & SELECTED) != 0)
+ + " sl=" + ((privateFlags & PFLAG_SELECTED) != 0)
+ " wf=" + hasWindowFocus()
+ ": " + Arrays.toString(drawableState));
}
@@ -14076,7 +14167,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
background.setLayoutDirection(getResolvedLayoutDirection());
if (background.getPadding(padding)) {
// Reset padding resolution
- mPrivateFlags2 &= ~PADDING_RESOLVED;
+ mPrivateFlags2 &= ~PFLAG2_PADDING_RESOLVED;
switch (background.getLayoutDirection()) {
case LAYOUT_DIRECTION_RTL:
internalSetPadding(padding.right, padding.top, padding.left, padding.bottom);
@@ -14101,23 +14192,23 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
background.setVisible(getVisibility() == VISIBLE, false);
mBackground = background;
- if ((mPrivateFlags & SKIP_DRAW) != 0) {
- mPrivateFlags &= ~SKIP_DRAW;
- mPrivateFlags |= ONLY_DRAWS_BACKGROUND;
+ if ((mPrivateFlags & PFLAG_SKIP_DRAW) != 0) {
+ mPrivateFlags &= ~PFLAG_SKIP_DRAW;
+ mPrivateFlags |= PFLAG_ONLY_DRAWS_BACKGROUND;
requestLayout = true;
}
} else {
/* Remove the background */
mBackground = null;
- if ((mPrivateFlags & ONLY_DRAWS_BACKGROUND) != 0) {
+ if ((mPrivateFlags & PFLAG_ONLY_DRAWS_BACKGROUND) != 0) {
/*
* This view ONLY drew the background before and we're removing
* the background, so now it won't draw anything
* (hence we SKIP_DRAW)
*/
- mPrivateFlags &= ~ONLY_DRAWS_BACKGROUND;
- mPrivateFlags |= SKIP_DRAW;
+ mPrivateFlags &= ~PFLAG_ONLY_DRAWS_BACKGROUND;
+ mPrivateFlags |= PFLAG_SKIP_DRAW;
}
/*
@@ -14174,7 +14265,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
public void setPadding(int left, int top, int right, int bottom) {
// Reset padding resolution
- mPrivateFlags2 &= ~PADDING_RESOLVED;
+ mPrivateFlags2 &= ~PFLAG2_PADDING_RESOLVED;
mUserPaddingStart = UNDEFINED_PADDING;
mUserPaddingEnd = UNDEFINED_PADDING;
@@ -14261,7 +14352,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
public void setPaddingRelative(int start, int top, int end, int bottom) {
// Reset padding resolution
- mPrivateFlags2 &= ~PADDING_RESOLVED;
+ mPrivateFlags2 &= ~PFLAG2_PADDING_RESOLVED;
mUserPaddingStart = start;
mUserPaddingEnd = end;
@@ -14392,8 +14483,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @param selected true if the view must be selected, false otherwise
*/
public void setSelected(boolean selected) {
- if (((mPrivateFlags & SELECTED) != 0) != selected) {
- mPrivateFlags = (mPrivateFlags & ~SELECTED) | (selected ? SELECTED : 0);
+ if (((mPrivateFlags & PFLAG_SELECTED) != 0) != selected) {
+ mPrivateFlags = (mPrivateFlags & ~PFLAG_SELECTED) | (selected ? PFLAG_SELECTED : 0);
if (!selected) resetPressedState();
invalidate(true);
refreshDrawableState();
@@ -14421,7 +14512,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
@ViewDebug.ExportedProperty
public boolean isSelected() {
- return (mPrivateFlags & SELECTED) != 0;
+ return (mPrivateFlags & PFLAG_SELECTED) != 0;
}
/**
@@ -14438,8 +14529,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @param activated true if the view must be activated, false otherwise
*/
public void setActivated(boolean activated) {
- if (((mPrivateFlags & ACTIVATED) != 0) != activated) {
- mPrivateFlags = (mPrivateFlags & ~ACTIVATED) | (activated ? ACTIVATED : 0);
+ if (((mPrivateFlags & PFLAG_ACTIVATED) != 0) != activated) {
+ mPrivateFlags = (mPrivateFlags & ~PFLAG_ACTIVATED) | (activated ? PFLAG_ACTIVATED : 0);
invalidate(true);
refreshDrawableState();
dispatchSetActivated(activated);
@@ -14463,7 +14554,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
@ViewDebug.ExportedProperty
public boolean isActivated() {
- return (mPrivateFlags & ACTIVATED) != 0;
+ return (mPrivateFlags & PFLAG_ACTIVATED) != 0;
}
/**
@@ -14751,9 +14842,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
public void setIsRootNamespace(boolean isRoot) {
if (isRoot) {
- mPrivateFlags |= IS_ROOT_NAMESPACE;
+ mPrivateFlags |= PFLAG_IS_ROOT_NAMESPACE;
} else {
- mPrivateFlags &= ~IS_ROOT_NAMESPACE;
+ mPrivateFlags &= ~PFLAG_IS_ROOT_NAMESPACE;
}
}
@@ -14763,7 +14854,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @return true if the view belongs to the root namespace, false otherwise
*/
public boolean isRootNamespace() {
- return (mPrivateFlags&IS_ROOT_NAMESPACE) != 0;
+ return (mPrivateFlags&PFLAG_IS_ROOT_NAMESPACE) != 0;
}
/**
@@ -14912,7 +15003,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
Log.d(VIEW_LOG_TAG, output);
- if ((mPrivateFlags & FOCUSED) != 0) {
+ if ((mPrivateFlags & PFLAG_FOCUSED) != 0) {
output = debugIndent(depth) + " FOCUSED";
Log.d(VIEW_LOG_TAG, output);
}
@@ -14992,8 +15083,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* tree.
*/
public void requestLayout() {
- mPrivateFlags |= FORCE_LAYOUT;
- mPrivateFlags |= INVALIDATED;
+ mPrivateFlags |= PFLAG_FORCE_LAYOUT;
+ mPrivateFlags |= PFLAG_INVALIDATED;
if (mParent != null && !mParent.isLayoutRequested()) {
mParent.requestLayout();
@@ -15006,8 +15097,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* on the parent.
*/
public void forceLayout() {
- mPrivateFlags |= FORCE_LAYOUT;
- mPrivateFlags |= INVALIDATED;
+ mPrivateFlags |= PFLAG_FORCE_LAYOUT;
+ mPrivateFlags |= PFLAG_INVALIDATED;
}
/**
@@ -15031,12 +15122,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @see #onMeasure(int, int)
*/
public final void measure(int widthMeasureSpec, int heightMeasureSpec) {
- if ((mPrivateFlags & FORCE_LAYOUT) == FORCE_LAYOUT ||
+ if ((mPrivateFlags & PFLAG_FORCE_LAYOUT) == PFLAG_FORCE_LAYOUT ||
widthMeasureSpec != mOldWidthMeasureSpec ||
heightMeasureSpec != mOldHeightMeasureSpec) {
// first clears the measured dimension flag
- mPrivateFlags &= ~MEASURED_DIMENSION_SET;
+ mPrivateFlags &= ~PFLAG_MEASURED_DIMENSION_SET;
if (!isPaddingResolved()) {
resolvePadding();
@@ -15047,13 +15138,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
// flag not set, setMeasuredDimension() was not invoked, we raise
// an exception to warn the developer
- if ((mPrivateFlags & MEASURED_DIMENSION_SET) != MEASURED_DIMENSION_SET) {
+ if ((mPrivateFlags & PFLAG_MEASURED_DIMENSION_SET) != PFLAG_MEASURED_DIMENSION_SET) {
throw new IllegalStateException("onMeasure() did not set the"
+ " measured dimension by calling"
+ " setMeasuredDimension()");
}
- mPrivateFlags |= LAYOUT_REQUIRED;
+ mPrivateFlags |= PFLAG_LAYOUT_REQUIRED;
}
mOldWidthMeasureSpec = widthMeasureSpec;
@@ -15127,7 +15218,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
mMeasuredWidth = measuredWidth;
mMeasuredHeight = measuredHeight;
- mPrivateFlags |= MEASURED_DIMENSION_SET;
+ mPrivateFlags |= PFLAG_MEASURED_DIMENSION_SET;
}
/**
@@ -15371,7 +15462,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @see #getAnimation()
*/
protected void onAnimationStart() {
- mPrivateFlags |= ANIMATION_STARTED;
+ mPrivateFlags |= PFLAG_ANIMATION_STARTED;
}
/**
@@ -15383,7 +15474,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @see #getAnimation()
*/
protected void onAnimationEnd() {
- mPrivateFlags &= ~ANIMATION_STARTED;
+ mPrivateFlags &= ~PFLAG_ANIMATION_STARTED;
}
/**
@@ -15420,14 +15511,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
final AttachInfo attachInfo = mAttachInfo;
if (region != null && attachInfo != null) {
final int pflags = mPrivateFlags;
- if ((pflags & SKIP_DRAW) == 0) {
+ if ((pflags & PFLAG_SKIP_DRAW) == 0) {
// The SKIP_DRAW flag IS NOT set, so this view draws. We need to
// remove it from the transparent region.
final int[] location = attachInfo.mTransparentLocation;
getLocationInWindow(location);
region.op(location[0], location[1], location[0] + mRight - mLeft,
location[1] + mBottom - mTop, Region.Op.DIFFERENCE);
- } else if ((pflags & ONLY_DRAWS_BACKGROUND) != 0 && mBackground != null) {
+ } else if ((pflags & PFLAG_ONLY_DRAWS_BACKGROUND) != 0 && mBackground != null) {
// The ONLY_DRAWS_BACKGROUND flag IS set and the background drawable
// exists, so we remove the background drawable's non-transparent
// parts from this transparent region.
@@ -15904,7 +15995,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
boolean canAcceptDrag() {
- return (mPrivateFlags2 & DRAG_CAN_ACCEPT) != 0;
+ return (mPrivateFlags2 & PFLAG2_DRAG_CAN_ACCEPT) != 0;
}
/**
@@ -16169,7 +16260,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
@ViewDebug.IntToString(from = TEXT_DIRECTION_LOCALE, to = "LOCALE")
})
public int getTextDirection() {
- return (mPrivateFlags2 & TEXT_DIRECTION_MASK) >> TEXT_DIRECTION_MASK_SHIFT;
+ return (mPrivateFlags2 & PFLAG2_TEXT_DIRECTION_MASK) >> PFLAG2_TEXT_DIRECTION_MASK_SHIFT;
}
/**
@@ -16187,10 +16278,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
public void setTextDirection(int textDirection) {
if (getTextDirection() != textDirection) {
// Reset the current text direction and the resolved one
- mPrivateFlags2 &= ~TEXT_DIRECTION_MASK;
+ mPrivateFlags2 &= ~PFLAG2_TEXT_DIRECTION_MASK;
resetResolvedTextDirection();
// Set the new text direction
- mPrivateFlags2 |= ((textDirection << TEXT_DIRECTION_MASK_SHIFT) & TEXT_DIRECTION_MASK);
+ mPrivateFlags2 |= ((textDirection << PFLAG2_TEXT_DIRECTION_MASK_SHIFT) & PFLAG2_TEXT_DIRECTION_MASK);
// Refresh
requestLayout();
invalidate(true);
@@ -16215,10 +16306,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
public int getResolvedTextDirection() {
// The text direction will be resolved only if needed
- if ((mPrivateFlags2 & TEXT_DIRECTION_RESOLVED) != TEXT_DIRECTION_RESOLVED) {
+ if ((mPrivateFlags2 & PFLAG2_TEXT_DIRECTION_RESOLVED) != PFLAG2_TEXT_DIRECTION_RESOLVED) {
resolveTextDirection();
}
- return (mPrivateFlags2 & TEXT_DIRECTION_RESOLVED_MASK) >> TEXT_DIRECTION_RESOLVED_MASK_SHIFT;
+ return (mPrivateFlags2 & PFLAG2_TEXT_DIRECTION_RESOLVED_MASK) >> PFLAG2_TEXT_DIRECTION_RESOLVED_MASK_SHIFT;
}
/**
@@ -16227,7 +16318,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
public void resolveTextDirection() {
// Reset any previous text direction resolution
- mPrivateFlags2 &= ~(TEXT_DIRECTION_RESOLVED | TEXT_DIRECTION_RESOLVED_MASK);
+ mPrivateFlags2 &= ~(PFLAG2_TEXT_DIRECTION_RESOLVED | PFLAG2_TEXT_DIRECTION_RESOLVED_MASK);
if (hasRtlSupport()) {
// Set resolved text direction flag depending on text direction flag
@@ -16246,15 +16337,15 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
case TEXT_DIRECTION_RTL:
case TEXT_DIRECTION_LOCALE:
mPrivateFlags2 |=
- (parentResolvedDirection << TEXT_DIRECTION_RESOLVED_MASK_SHIFT);
+ (parentResolvedDirection << PFLAG2_TEXT_DIRECTION_RESOLVED_MASK_SHIFT);
break;
default:
// Default resolved direction is "first strong" heuristic
- mPrivateFlags2 |= TEXT_DIRECTION_RESOLVED_DEFAULT;
+ mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT;
}
} else {
// We cannot do the resolution if there is no parent, so use the default one
- mPrivateFlags2 |= TEXT_DIRECTION_RESOLVED_DEFAULT;
+ mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT;
}
break;
case TEXT_DIRECTION_FIRST_STRONG:
@@ -16263,19 +16354,19 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
case TEXT_DIRECTION_RTL:
case TEXT_DIRECTION_LOCALE:
// Resolved direction is the same as text direction
- mPrivateFlags2 |= (textDirection << TEXT_DIRECTION_RESOLVED_MASK_SHIFT);
+ mPrivateFlags2 |= (textDirection << PFLAG2_TEXT_DIRECTION_RESOLVED_MASK_SHIFT);
break;
default:
// Default resolved direction is "first strong" heuristic
- mPrivateFlags2 |= TEXT_DIRECTION_RESOLVED_DEFAULT;
+ mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT;
}
} else {
// Default resolved direction is "first strong" heuristic
- mPrivateFlags2 |= TEXT_DIRECTION_RESOLVED_DEFAULT;
+ mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED_DEFAULT;
}
// Set to resolved
- mPrivateFlags2 |= TEXT_DIRECTION_RESOLVED;
+ mPrivateFlags2 |= PFLAG2_TEXT_DIRECTION_RESOLVED;
onResolvedTextDirectionChanged();
}
@@ -16308,7 +16399,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* reset is done.
*/
public void resetResolvedTextDirection() {
- mPrivateFlags2 &= ~(TEXT_DIRECTION_RESOLVED | TEXT_DIRECTION_RESOLVED_MASK);
+ mPrivateFlags2 &= ~(PFLAG2_TEXT_DIRECTION_RESOLVED | PFLAG2_TEXT_DIRECTION_RESOLVED_MASK);
onResolvedTextDirectionReset();
}
@@ -16344,7 +16435,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
@ViewDebug.IntToString(from = TEXT_ALIGNMENT_VIEW_END, to = "VIEW_END")
})
public int getTextAlignment() {
- return (mPrivateFlags2 & TEXT_ALIGNMENT_MASK) >> TEXT_ALIGNMENT_MASK_SHIFT;
+ return (mPrivateFlags2 & PFLAG2_TEXT_ALIGNMENT_MASK) >> PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT;
}
/**
@@ -16365,10 +16456,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
public void setTextAlignment(int textAlignment) {
if (textAlignment != getTextAlignment()) {
// Reset the current and resolved text alignment
- mPrivateFlags2 &= ~TEXT_ALIGNMENT_MASK;
+ mPrivateFlags2 &= ~PFLAG2_TEXT_ALIGNMENT_MASK;
resetResolvedTextAlignment();
// Set the new text alignment
- mPrivateFlags2 |= ((textAlignment << TEXT_ALIGNMENT_MASK_SHIFT) & TEXT_ALIGNMENT_MASK);
+ mPrivateFlags2 |= ((textAlignment << PFLAG2_TEXT_ALIGNMENT_MASK_SHIFT) & PFLAG2_TEXT_ALIGNMENT_MASK);
// Refresh
requestLayout();
invalidate(true);
@@ -16402,10 +16493,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
})
public int getResolvedTextAlignment() {
// If text alignment is not resolved, then resolve it
- if ((mPrivateFlags2 & TEXT_ALIGNMENT_RESOLVED) != TEXT_ALIGNMENT_RESOLVED) {
+ if ((mPrivateFlags2 & PFLAG2_TEXT_ALIGNMENT_RESOLVED) != PFLAG2_TEXT_ALIGNMENT_RESOLVED) {
resolveTextAlignment();
}
- return (mPrivateFlags2 & TEXT_ALIGNMENT_RESOLVED_MASK) >> TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT;
+ return (mPrivateFlags2 & PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK) >> PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT;
}
/**
@@ -16414,7 +16505,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
public void resolveTextAlignment() {
// Reset any previous text alignment resolution
- mPrivateFlags2 &= ~(TEXT_ALIGNMENT_RESOLVED | TEXT_ALIGNMENT_RESOLVED_MASK);
+ mPrivateFlags2 &= ~(PFLAG2_TEXT_ALIGNMENT_RESOLVED | PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK);
if (hasRtlSupport()) {
// Set resolved text alignment flag depending on text alignment flag
@@ -16436,16 +16527,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
// Resolved text alignment is the same as the parent resolved
// text alignment
mPrivateFlags2 |=
- (parentResolvedTextAlignment << TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT);
+ (parentResolvedTextAlignment << PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT);
break;
default:
// Use default resolved text alignment
- mPrivateFlags2 |= TEXT_ALIGNMENT_RESOLVED_DEFAULT;
+ mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT;
}
}
else {
// We cannot do the resolution if there is no parent so use the default
- mPrivateFlags2 |= TEXT_ALIGNMENT_RESOLVED_DEFAULT;
+ mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT;
}
break;
case TEXT_ALIGNMENT_GRAVITY:
@@ -16455,19 +16546,19 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
case TEXT_ALIGNMENT_VIEW_START:
case TEXT_ALIGNMENT_VIEW_END:
// Resolved text alignment is the same as text alignment
- mPrivateFlags2 |= (textAlignment << TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT);
+ mPrivateFlags2 |= (textAlignment << PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK_SHIFT);
break;
default:
// Use default resolved text alignment
- mPrivateFlags2 |= TEXT_ALIGNMENT_RESOLVED_DEFAULT;
+ mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT;
}
} else {
// Use default resolved text alignment
- mPrivateFlags2 |= TEXT_ALIGNMENT_RESOLVED_DEFAULT;
+ mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED_DEFAULT;
}
// Set the resolved
- mPrivateFlags2 |= TEXT_ALIGNMENT_RESOLVED;
+ mPrivateFlags2 |= PFLAG2_TEXT_ALIGNMENT_RESOLVED;
onResolvedTextAlignmentChanged();
}
@@ -16501,7 +16592,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
public void resetResolvedTextAlignment() {
// Reset any previous text alignment resolution
- mPrivateFlags2 &= ~(TEXT_ALIGNMENT_RESOLVED | TEXT_ALIGNMENT_RESOLVED_MASK);
+ mPrivateFlags2 &= ~(PFLAG2_TEXT_ALIGNMENT_RESOLVED | PFLAG2_TEXT_ALIGNMENT_RESOLVED_MASK);
onResolvedTextAlignmentReset();
}
@@ -16831,7 +16922,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
private final class CheckForTap implements Runnable {
public void run() {
- mPrivateFlags &= ~PREPRESSED;
+ mPrivateFlags &= ~PFLAG_PREPRESSED;
setPressed(true);
checkForLongClick(ViewConfiguration.getTapTimeout());
}
@@ -17179,6 +17270,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
final IBinder mWindowToken;
+ final Display mDisplay;
+
final Callbacks mRootCallbacks;
HardwareCanvas mHardwareCanvas;
@@ -17438,11 +17531,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*
* @param handler the events handler the view must use
*/
- AttachInfo(IWindowSession session, IWindow window,
+ AttachInfo(IWindowSession session, IWindow window, Display display,
ViewRootImpl viewRootImpl, Handler handler, Callbacks effectPlayer) {
mSession = session;
mWindow = window;
mWindowToken = window.asBinder();
+ mDisplay = display;
mViewRootImpl = viewRootImpl;
mHandler = handler;
mRootCallbacks = effectPlayer;
diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java
index 3082976..499075e 100644
--- a/core/java/android/view/ViewConfiguration.java
+++ b/core/java/android/view/ViewConfiguration.java
@@ -279,7 +279,8 @@ public class ViewConfiguration {
mWindowTouchSlop = (int) (sizeAndDensity * WINDOW_TOUCH_SLOP + 0.5f);
// Size of the screen in bytes, in ARGB_8888 format
- final Display display = WindowManagerImpl.getDefault().getDefaultDisplay();
+ final WindowManager win = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
+ final Display display = win.getDefaultDisplay();
final Point size = new Point();
display.getRealSize(size);
mMaximumDrawingCacheSize = 4 * size.x * size.y;
@@ -288,7 +289,7 @@ public class ViewConfiguration {
mOverflingDistance = (int) (sizeAndDensity * OVERFLING_DISTANCE + 0.5f);
if (!sHasPermanentMenuKeySet) {
- IWindowManager wm = WindowManagerImpl.getWindowManagerService();
+ IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
try {
sHasPermanentMenuKey = !wm.hasSystemNavBar() && !wm.hasNavigationBar();
sHasPermanentMenuKeySet = true;
diff --git a/core/java/android/view/ViewDebug.java b/core/java/android/view/ViewDebug.java
index dae9265..1286eb9 100644
--- a/core/java/android/view/ViewDebug.java
+++ b/core/java/android/view/ViewDebug.java
@@ -497,8 +497,8 @@ public class ViewDebug {
throws IOException {
long durationMeasure =
- (root || (view.mPrivateFlags & View.MEASURED_DIMENSION_SET) != 0) ? profileViewOperation(
- view, new ViewOperation<Void>() {
+ (root || (view.mPrivateFlags & View.PFLAG_MEASURED_DIMENSION_SET) != 0)
+ ? profileViewOperation(view, new ViewOperation<Void>() {
public Void[] pre() {
forceLayout(view);
return null;
@@ -524,8 +524,8 @@ public class ViewDebug {
})
: 0;
long durationLayout =
- (root || (view.mPrivateFlags & View.LAYOUT_REQUIRED) != 0) ? profileViewOperation(
- view, new ViewOperation<Void>() {
+ (root || (view.mPrivateFlags & View.PFLAG_LAYOUT_REQUIRED) != 0)
+ ? profileViewOperation(view, new ViewOperation<Void>() {
public Void[] pre() {
return null;
}
@@ -538,9 +538,8 @@ public class ViewDebug {
}
}) : 0;
long durationDraw =
- (root || !view.willNotDraw() || (view.mPrivateFlags & View.DRAWN) != 0) ? profileViewOperation(
- view,
- new ViewOperation<Object>() {
+ (root || !view.willNotDraw() || (view.mPrivateFlags & View.PFLAG_DRAWN) != 0)
+ ? profileViewOperation(view, new ViewOperation<Object>() {
public Object[] pre() {
final DisplayMetrics metrics =
(view != null && view.getResources() != null) ?
@@ -651,7 +650,7 @@ public class ViewDebug {
final boolean localVisible = view.getVisibility() == View.VISIBLE && visible;
- if ((view.mPrivateFlags & View.SKIP_DRAW) != View.SKIP_DRAW) {
+ if ((view.mPrivateFlags & View.PFLAG_SKIP_DRAW) != View.PFLAG_SKIP_DRAW) {
final int id = view.getId();
String name = view.getClass().getSimpleName();
if (id != View.NO_ID) {
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index bfe0ca5..3ab0e94 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -804,7 +804,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
*/
@Override
public boolean hasFocus() {
- return (mPrivateFlags & FOCUSED) != 0 || mFocused != null;
+ return (mPrivateFlags & PFLAG_FOCUSED) != 0 || mFocused != null;
}
/*
@@ -898,7 +898,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
for (int i = 0; i < childrenCount; i++) {
View child = children[i];
if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE
- && (child.mPrivateFlags & IS_ROOT_NAMESPACE) == 0) {
+ && (child.mPrivateFlags & PFLAG_IS_ROOT_NAMESPACE) == 0) {
child.findViewsWithText(outViews, text, flags);
}
}
@@ -1177,7 +1177,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
final View view = mCurrentDragView;
event.mAction = DragEvent.ACTION_DRAG_EXITED;
view.dispatchDragEvent(event);
- view.mPrivateFlags2 &= ~View.DRAG_HOVERED;
+ view.mPrivateFlags2 &= ~View.PFLAG2_DRAG_HOVERED;
view.refreshDrawableState();
}
mCurrentDragView = target;
@@ -1186,7 +1186,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
if (target != null) {
event.mAction = DragEvent.ACTION_DRAG_ENTERED;
target.dispatchDragEvent(event);
- target.mPrivateFlags2 |= View.DRAG_HOVERED;
+ target.mPrivateFlags2 |= View.PFLAG2_DRAG_HOVERED;
target.refreshDrawableState();
}
event.mAction = action; // restore the event's original state
@@ -1220,7 +1220,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
if (mCurrentDragView != null) {
final View view = mCurrentDragView;
view.dispatchDragEvent(event);
- view.mPrivateFlags2 &= ~View.DRAG_HOVERED;
+ view.mPrivateFlags2 &= ~View.PFLAG2_DRAG_HOVERED;
view.refreshDrawableState();
mCurrentDragView = null;
@@ -1281,7 +1281,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
mDragNotifiedChildren.add(child);
canAccept = child.dispatchDragEvent(mCurrentDrag);
if (canAccept && !child.canAcceptDrag()) {
- child.mPrivateFlags2 |= View.DRAG_CAN_ACCEPT;
+ child.mPrivateFlags2 |= View.PFLAG2_DRAG_CAN_ACCEPT;
child.refreshDrawableState();
}
}
@@ -1330,9 +1330,11 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
*/
@Override
public boolean dispatchKeyEventPreIme(KeyEvent event) {
- if ((mPrivateFlags & (FOCUSED | HAS_BOUNDS)) == (FOCUSED | HAS_BOUNDS)) {
+ if ((mPrivateFlags & (PFLAG_FOCUSED | PFLAG_HAS_BOUNDS))
+ == (PFLAG_FOCUSED | PFLAG_HAS_BOUNDS)) {
return super.dispatchKeyEventPreIme(event);
- } else if (mFocused != null && (mFocused.mPrivateFlags & HAS_BOUNDS) == HAS_BOUNDS) {
+ } else if (mFocused != null && (mFocused.mPrivateFlags & PFLAG_HAS_BOUNDS)
+ == PFLAG_HAS_BOUNDS) {
return mFocused.dispatchKeyEventPreIme(event);
}
return false;
@@ -1347,11 +1349,13 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
mInputEventConsistencyVerifier.onKeyEvent(event, 1);
}
- if ((mPrivateFlags & (FOCUSED | HAS_BOUNDS)) == (FOCUSED | HAS_BOUNDS)) {
+ if ((mPrivateFlags & (PFLAG_FOCUSED | PFLAG_HAS_BOUNDS))
+ == (PFLAG_FOCUSED | PFLAG_HAS_BOUNDS)) {
if (super.dispatchKeyEvent(event)) {
return true;
}
- } else if (mFocused != null && (mFocused.mPrivateFlags & HAS_BOUNDS) == HAS_BOUNDS) {
+ } else if (mFocused != null && (mFocused.mPrivateFlags & PFLAG_HAS_BOUNDS)
+ == PFLAG_HAS_BOUNDS) {
if (mFocused.dispatchKeyEvent(event)) {
return true;
}
@@ -1368,9 +1372,11 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
*/
@Override
public boolean dispatchKeyShortcutEvent(KeyEvent event) {
- if ((mPrivateFlags & (FOCUSED | HAS_BOUNDS)) == (FOCUSED | HAS_BOUNDS)) {
+ if ((mPrivateFlags & (PFLAG_FOCUSED | PFLAG_HAS_BOUNDS))
+ == (PFLAG_FOCUSED | PFLAG_HAS_BOUNDS)) {
return super.dispatchKeyShortcutEvent(event);
- } else if (mFocused != null && (mFocused.mPrivateFlags & HAS_BOUNDS) == HAS_BOUNDS) {
+ } else if (mFocused != null && (mFocused.mPrivateFlags & PFLAG_HAS_BOUNDS)
+ == PFLAG_HAS_BOUNDS) {
return mFocused.dispatchKeyShortcutEvent(event);
}
return false;
@@ -1385,11 +1391,13 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
mInputEventConsistencyVerifier.onTrackballEvent(event, 1);
}
- if ((mPrivateFlags & (FOCUSED | HAS_BOUNDS)) == (FOCUSED | HAS_BOUNDS)) {
+ if ((mPrivateFlags & (PFLAG_FOCUSED | PFLAG_HAS_BOUNDS))
+ == (PFLAG_FOCUSED | PFLAG_HAS_BOUNDS)) {
if (super.dispatchTrackballEvent(event)) {
return true;
}
- } else if (mFocused != null && (mFocused.mPrivateFlags & HAS_BOUNDS) == HAS_BOUNDS) {
+ } else if (mFocused != null && (mFocused.mPrivateFlags & PFLAG_HAS_BOUNDS)
+ == PFLAG_HAS_BOUNDS) {
if (mFocused.dispatchTrackballEvent(event)) {
return true;
}
@@ -1715,8 +1723,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
final float x = event.getX();
final float y = event.getY();
+ final boolean customOrder = isChildrenDrawingOrderEnabled();
for (int i = childrenCount - 1; i >= 0; i--) {
- final View child = children[i];
+ final int childIndex = customOrder ? getChildDrawingOrder(childrenCount, i) : i;
+ final View child = children[childIndex];
if (!canViewReceivePointerEvents(child)
|| !isTransformedTouchPointInView(x, y, child, null)) {
continue;
@@ -1738,9 +1748,11 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
@Override
protected boolean dispatchGenericFocusedEvent(MotionEvent event) {
// Send the event to the focused child or to this view group if it has focus.
- if ((mPrivateFlags & (FOCUSED | HAS_BOUNDS)) == (FOCUSED | HAS_BOUNDS)) {
+ if ((mPrivateFlags & (PFLAG_FOCUSED | PFLAG_HAS_BOUNDS))
+ == (PFLAG_FOCUSED | PFLAG_HAS_BOUNDS)) {
return super.dispatchGenericFocusedEvent(event);
- } else if (mFocused != null && (mFocused.mPrivateFlags & HAS_BOUNDS) == HAS_BOUNDS) {
+ } else if (mFocused != null && (mFocused.mPrivateFlags & PFLAG_HAS_BOUNDS)
+ == PFLAG_HAS_BOUNDS) {
return mFocused.dispatchGenericMotionEvent(event);
}
return false;
@@ -1841,8 +1853,11 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
final float x = ev.getX(actionIndex);
final float y = ev.getY(actionIndex);
+ final boolean customOrder = isChildrenDrawingOrderEnabled();
for (int i = childrenCount - 1; i >= 0; i--) {
- final View child = children[i];
+ final int childIndex = customOrder ?
+ getChildDrawingOrder(childrenCount, i) : i;
+ final View child = children[childIndex];
if (!canViewReceivePointerEvents(child)
|| !isTransformedTouchPointInView(x, y, child, null)) {
continue;
@@ -1860,7 +1875,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
if (dispatchTransformedTouchEvent(ev, false, child, idBitsToAssign)) {
// Child wants to receive touch within its bounds.
mLastTouchDownTime = ev.getDownTime();
- mLastTouchDownIndex = i;
+ mLastTouchDownIndex = childIndex;
mLastTouchDownX = ev.getX();
mLastTouchDownY = ev.getY();
newTouchTarget = addTouchTarget(child, idBitsToAssign);
@@ -1951,8 +1966,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
* Returns true if the flag was previously set.
*/
private static boolean resetCancelNextUpFlag(View view) {
- if ((view.mPrivateFlags & CANCEL_NEXT_UP_EVENT) != 0) {
- view.mPrivateFlags &= ~CANCEL_NEXT_UP_EVENT;
+ if ((view.mPrivateFlags & PFLAG_CANCEL_NEXT_UP_EVENT) != 0) {
+ view.mPrivateFlags &= ~PFLAG_CANCEL_NEXT_UP_EVENT;
return true;
}
return false;
@@ -2769,7 +2784,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
}
// We will draw our child's animation, let's reset the flag
- mPrivateFlags &= ~DRAW_ANIMATION;
+ mPrivateFlags &= ~PFLAG_DRAW_ANIMATION;
mGroupFlags &= ~FLAG_INVALIDATE_REQUIRED;
boolean more = false;
@@ -2889,8 +2904,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
final View child = children[i];
if (((child.mViewFlags & VISIBILITY_MASK) == VISIBLE || child.getAnimation() != null) &&
child.hasStaticLayer()) {
- child.mRecreateDisplayList = (child.mPrivateFlags & INVALIDATED) == INVALIDATED;
- child.mPrivateFlags &= ~INVALIDATED;
+ child.mRecreateDisplayList = (child.mPrivateFlags & PFLAG_INVALIDATED)
+ == PFLAG_INVALIDATED;
+ child.mPrivateFlags &= ~PFLAG_INVALIDATED;
child.getDisplayList();
child.mRecreateDisplayList = false;
}
@@ -3033,7 +3049,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
for (int i = 0; i < len; i++) {
View v = where[i];
- if ((v.mPrivateFlags & IS_ROOT_NAMESPACE) == 0) {
+ if ((v.mPrivateFlags & PFLAG_IS_ROOT_NAMESPACE) == 0) {
v = v.findViewById(id);
if (v != null) {
@@ -3060,7 +3076,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
for (int i = 0; i < len; i++) {
View v = where[i];
- if ((v.mPrivateFlags & IS_ROOT_NAMESPACE) == 0) {
+ if ((v.mPrivateFlags & PFLAG_IS_ROOT_NAMESPACE) == 0) {
v = v.findViewWithTag(tag);
if (v != null) {
@@ -3087,7 +3103,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
for (int i = 0; i < len; i++) {
View v = where[i];
- if (v != childToSkip && (v.mPrivateFlags & IS_ROOT_NAMESPACE) == 0) {
+ if (v != childToSkip && (v.mPrivateFlags & PFLAG_IS_ROOT_NAMESPACE) == 0) {
v = v.findViewByPredicate(predicate);
if (v != null) {
@@ -3297,7 +3313,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
boolean preventRequestLayout) {
child.mParent = null;
addViewInner(child, index, params, preventRequestLayout);
- child.mPrivateFlags = (child.mPrivateFlags & ~DIRTY_MASK) | DRAWN;
+ child.mPrivateFlags = (child.mPrivateFlags & ~PFLAG_DIRTY_MASK) | PFLAG_DRAWN;
return true;
}
@@ -3307,7 +3323,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
* @param child the child on which to perform the cleanup
*/
protected void cleanupLayoutState(View child) {
- child.mPrivateFlags &= ~View.FORCE_LAYOUT;
+ child.mPrivateFlags &= ~View.PFLAG_FORCE_LAYOUT;
}
private void addViewInner(View child, int index, LayoutParams params,
@@ -3854,9 +3870,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
addInArray(child, index);
child.mParent = this;
- child.mPrivateFlags = (child.mPrivateFlags & ~DIRTY_MASK & ~DRAWING_CACHE_VALID) |
- DRAWN | INVALIDATED;
- this.mPrivateFlags |= INVALIDATED;
+ child.mPrivateFlags = (child.mPrivateFlags & ~PFLAG_DIRTY_MASK
+ & ~PFLAG_DRAWING_CACHE_VALID)
+ | PFLAG_DRAWN | PFLAG_INVALIDATED;
+ this.mPrivateFlags |= PFLAG_INVALIDATED;
if (child.hasFocus()) {
requestChildFocus(child, child.findFocus());
@@ -3957,7 +3974,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
// If the child is drawing an animation, we want to copy this flag onto
// ourselves and the parent to make sure the invalidate request goes
// through
- final boolean drawAnimation = (child.mPrivateFlags & DRAW_ANIMATION) == DRAW_ANIMATION;
+ final boolean drawAnimation = (child.mPrivateFlags & PFLAG_DRAW_ANIMATION)
+ == PFLAG_DRAW_ANIMATION;
// Check whether the child that requests the invalidate is fully opaque
// Views being animated or transformed are not considered opaque because we may
@@ -3967,11 +3985,11 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
child.getAnimation() == null && childMatrix.isIdentity();
// Mark the child as dirty, using the appropriate flag
// Make sure we do not set both flags at the same time
- int opaqueFlag = isOpaque ? DIRTY_OPAQUE : DIRTY;
+ int opaqueFlag = isOpaque ? PFLAG_DIRTY_OPAQUE : PFLAG_DIRTY;
if (child.mLayerType != LAYER_TYPE_NONE) {
- mPrivateFlags |= INVALIDATED;
- mPrivateFlags &= ~DRAWING_CACHE_VALID;
+ mPrivateFlags |= PFLAG_INVALIDATED;
+ mPrivateFlags &= ~PFLAG_DRAWING_CACHE_VALID;
child.mLocalDirtyRect.union(dirty);
}
@@ -4013,7 +4031,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
if (drawAnimation) {
if (view != null) {
- view.mPrivateFlags |= DRAW_ANIMATION;
+ view.mPrivateFlags |= PFLAG_DRAW_ANIMATION;
} else if (parent instanceof ViewRootImpl) {
((ViewRootImpl) parent).mIsAnimating = true;
}
@@ -4024,10 +4042,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
if (view != null) {
if ((view.mViewFlags & FADING_EDGE_MASK) != 0 &&
view.getSolidColor() == 0) {
- opaqueFlag = DIRTY;
+ opaqueFlag = PFLAG_DIRTY;
}
- if ((view.mPrivateFlags & DIRTY_MASK) != DIRTY) {
- view.mPrivateFlags = (view.mPrivateFlags & ~DIRTY_MASK) | opaqueFlag;
+ if ((view.mPrivateFlags & PFLAG_DIRTY_MASK) != PFLAG_DIRTY) {
+ view.mPrivateFlags = (view.mPrivateFlags & ~PFLAG_DIRTY_MASK) | opaqueFlag;
}
}
@@ -4058,8 +4076,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
* does not intersect with this ViewGroup's bounds.
*/
public ViewParent invalidateChildInParent(final int[] location, final Rect dirty) {
- if ((mPrivateFlags & DRAWN) == DRAWN ||
- (mPrivateFlags & DRAWING_CACHE_VALID) == DRAWING_CACHE_VALID) {
+ if ((mPrivateFlags & PFLAG_DRAWN) == PFLAG_DRAWN ||
+ (mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == PFLAG_DRAWING_CACHE_VALID) {
if ((mGroupFlags & (FLAG_OPTIMIZE_INVALIDATE | FLAG_ANIMATION_DONE)) !=
FLAG_OPTIMIZE_INVALIDATE) {
dirty.offset(location[CHILD_LEFT_INDEX] - mScrollX,
@@ -4073,20 +4091,20 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
dirty.setEmpty();
}
}
- mPrivateFlags &= ~DRAWING_CACHE_VALID;
+ mPrivateFlags &= ~PFLAG_DRAWING_CACHE_VALID;
location[CHILD_LEFT_INDEX] = left;
location[CHILD_TOP_INDEX] = top;
if (mLayerType != LAYER_TYPE_NONE) {
- mPrivateFlags |= INVALIDATED;
+ mPrivateFlags |= PFLAG_INVALIDATED;
mLocalDirtyRect.union(dirty);
}
return mParent;
} else {
- mPrivateFlags &= ~DRAWN & ~DRAWING_CACHE_VALID;
+ mPrivateFlags &= ~PFLAG_DRAWN & ~PFLAG_DRAWING_CACHE_VALID;
location[CHILD_LEFT_INDEX] = mLeft;
location[CHILD_TOP_INDEX] = mTop;
@@ -4098,7 +4116,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
}
if (mLayerType != LAYER_TYPE_NONE) {
- mPrivateFlags |= INVALIDATED;
+ mPrivateFlags |= PFLAG_INVALIDATED;
mLocalDirtyRect.union(dirty);
}
@@ -4160,8 +4178,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
* coordinate system, pruning the invalidation if the parent has already been invalidated.
*/
private ViewParent invalidateChildInParentFast(int left, int top, final Rect dirty) {
- if ((mPrivateFlags & DRAWN) == DRAWN ||
- (mPrivateFlags & DRAWING_CACHE_VALID) == DRAWING_CACHE_VALID) {
+ if ((mPrivateFlags & PFLAG_DRAWN) == PFLAG_DRAWN ||
+ (mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == PFLAG_DRAWING_CACHE_VALID) {
dirty.offset(left - mScrollX, top - mScrollY);
if ((mGroupFlags & FLAG_CLIP_CHILDREN) == 0 ||
@@ -4924,11 +4942,11 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
view.clearAnimation();
}
- if ((view.mPrivateFlags & ANIMATION_STARTED) == ANIMATION_STARTED) {
+ if ((view.mPrivateFlags & PFLAG_ANIMATION_STARTED) == PFLAG_ANIMATION_STARTED) {
view.onAnimationEnd();
// Should be performed by onAnimationEnd() but this avoid an infinite loop,
// so we'd rather be safe than sorry
- view.mPrivateFlags &= ~ANIMATION_STARTED;
+ view.mPrivateFlags &= ~PFLAG_ANIMATION_STARTED;
// Draw one more frame after the animation is done
mGroupFlags |= FLAG_INVALIDATE_REQUIRED;
}
@@ -5027,7 +5045,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
@Override
public boolean gatherTransparentRegion(Region region) {
// If no transparent regions requested, we are always opaque.
- final boolean meOpaque = (mPrivateFlags & View.REQUEST_TRANSPARENT_REGIONS) == 0;
+ final boolean meOpaque = (mPrivateFlags & View.PFLAG_REQUEST_TRANSPARENT_REGIONS) == 0;
if (meOpaque && region == null) {
// The caller doesn't care about the region, so stop now.
return true;
@@ -5052,7 +5070,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
*/
public void requestTransparentRegion(View child) {
if (child != null) {
- child.mPrivateFlags |= View.REQUEST_TRANSPARENT_REGIONS;
+ child.mPrivateFlags |= View.PFLAG_REQUEST_TRANSPARENT_REGIONS;
if (mParent != null) {
mParent.requestTransparentRegion(this);
}
diff --git a/core/java/android/view/ViewPropertyAnimator.java b/core/java/android/view/ViewPropertyAnimator.java
index ce6f4c5..d8db14c 100644
--- a/core/java/android/view/ViewPropertyAnimator.java
+++ b/core/java/android/view/ViewPropertyAnimator.java
@@ -1036,7 +1036,7 @@ public class ViewPropertyAnimator {
if ((propertyMask & TRANSFORM_MASK) != 0) {
mView.mTransformationInfo.mMatrixDirty = true;
if (!useDisplayListProperties) {
- mView.mPrivateFlags |= View.DRAWN; // force another invalidation
+ mView.mPrivateFlags |= View.PFLAG_DRAWN; // force another invalidation
}
}
// invalidate(false) in all cases except if alphaHandled gets set to true
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index afcbaaf..725d9b5 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -18,7 +18,6 @@ package android.view;
import android.Manifest;
import android.animation.LayoutTransition;
-import android.animation.ValueAnimator;
import android.app.ActivityManagerNative;
import android.content.ClipDescription;
import android.content.ComponentCallbacks;
@@ -88,7 +87,7 @@ import java.util.HashSet;
/**
* The top of a view hierarchy, implementing the needed protocol between View
* and the WindowManager. This is for the most part an internal implementation
- * detail of {@link WindowManagerImpl}.
+ * detail of {@link WindowManagerGlobal}.
*
* {@hide}
*/
@@ -126,11 +125,6 @@ public final class ViewRootImpl implements ViewParent,
*/
static final int MAX_TRACKBALL_DELAY = 250;
- static IWindowSession sWindowSession;
-
- static final Object mStaticInit = new Object();
- static boolean mInitialized = false;
-
static final ThreadLocal<RunQueue> sRunQueues = new ThreadLocal<RunQueue>();
static final ArrayList<Runnable> sFirstDrawHandlers = new ArrayList<Runnable>();
@@ -143,6 +137,9 @@ public final class ViewRootImpl implements ViewParent,
private static boolean sRenderThreadQueried = false;
private static final Object[] sRenderThreadQueryLock = new Object[0];
+ final IWindowSession mWindowSession;
+ final Display mDisplay;
+
long mLastTrackballTime = 0;
final TrackballAxis mTrackballAxisX = new TrackballAxis();
final TrackballAxis mTrackballAxisY = new TrackballAxis();
@@ -250,7 +247,7 @@ public final class ViewRootImpl implements ViewParent,
boolean mAdded;
boolean mAddedTouchMode;
- CompatibilityInfoHolder mCompatibilityInfo;
+ final CompatibilityInfoHolder mCompatibilityInfo;
// These are accessed by multiple threads.
final Rect mWinFrame; // frame given by window manager.
@@ -322,24 +319,6 @@ public final class ViewRootImpl implements ViewParent,
InputEventConsistencyVerifier.isInstrumentationEnabled() ?
new InputEventConsistencyVerifier(this, 0) : null;
- public static IWindowSession getWindowSession(Looper mainLooper) {
- synchronized (mStaticInit) {
- if (!mInitialized) {
- try {
- InputMethodManager imm = InputMethodManager.getInstance(mainLooper);
- IWindowManager windowManager = WindowManagerImpl.getWindowManagerService();
- sWindowSession = windowManager.openSession(
- imm.getClient(), imm.getInputContext());
- float animatorScale = windowManager.getAnimationScale(2);
- ValueAnimator.setDurationScale(animatorScale);
- mInitialized = true;
- } catch (RemoteException e) {
- }
- }
- return sWindowSession;
- }
- }
-
static final class SystemUiVisibilityInfo {
int seq;
int globalVisibility;
@@ -347,7 +326,7 @@ public final class ViewRootImpl implements ViewParent,
int localChanges;
}
- public ViewRootImpl(Context context) {
+ public ViewRootImpl(Context context, Display display) {
super();
if (MEASURE_LATENCY) {
@@ -359,7 +338,11 @@ public final class ViewRootImpl implements ViewParent,
// Initialize the statics when this class is first instantiated. This is
// done here instead of in the static block because Zygote does not
// allow the spawning of threads.
- getWindowSession(context.getMainLooper());
+ mWindowSession = WindowManagerGlobal.getWindowSession(context.getMainLooper());
+ mDisplay = display;
+
+ CompatibilityInfoHolder cih = display.getCompatibilityInfo();
+ mCompatibilityInfo = cih != null ? cih : new CompatibilityInfoHolder();
mThread = Thread.currentThread();
mLocation = new WindowLeaked(null);
@@ -383,7 +366,7 @@ public final class ViewRootImpl implements ViewParent,
new AccessibilityInteractionConnectionManager();
mAccessibilityManager.addAccessibilityStateChangeListener(
mAccessibilityInteractionConnectionManager);
- mAttachInfo = new View.AttachInfo(sWindowSession, mWindow, this, mHandler, this);
+ mAttachInfo = new View.AttachInfo(mWindowSession, mWindow, display, this, mHandler, this);
mViewConfiguration = ViewConfiguration.get(context);
mDensity = context.getResources().getDisplayMetrics().densityDpi;
mNoncompatDensity = context.getResources().getDisplayMetrics().noncompatDensityDpi;
@@ -460,9 +443,10 @@ public final class ViewRootImpl implements ViewParent,
* @hide
*/
static boolean isInTouchMode() {
- if (mInitialized) {
+ IWindowSession windowSession = WindowManagerGlobal.peekWindowSession();
+ if (windowSession != null) {
try {
- return sWindowSession.getInTouchMode();
+ return windowSession.getInTouchMode();
} catch (RemoteException e) {
}
}
@@ -541,8 +525,8 @@ public final class ViewRootImpl implements ViewParent,
mOrigWindowType = mWindowAttributes.type;
mAttachInfo.mRecomputeGlobalAttributes = true;
collectViewAttributes();
- res = sWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
- getHostVisibility(), Display.DEFAULT_DISPLAY,
+ res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
+ getHostVisibility(), mDisplay.getDisplayId(),
mAttachInfo.mContentInsets, mInputChannel);
} catch (RemoteException e) {
mAdded = false;
@@ -565,7 +549,7 @@ public final class ViewRootImpl implements ViewParent,
mPendingContentInsets.set(mAttachInfo.mContentInsets);
mPendingVisibleInsets.set(0, 0, 0, 0);
if (DEBUG_LAYOUT) Log.v(TAG, "Added window " + mWindow);
- if (res < WindowManagerImpl.ADD_OKAY) {
+ if (res < WindowManagerGlobal.ADD_OKAY) {
mView = null;
mAttachInfo.mRootView = null;
mAdded = false;
@@ -573,33 +557,33 @@ public final class ViewRootImpl implements ViewParent,
unscheduleTraversals();
setAccessibilityFocus(null, null);
switch (res) {
- case WindowManagerImpl.ADD_BAD_APP_TOKEN:
- case WindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN:
- throw new WindowManagerImpl.BadTokenException(
+ case WindowManagerGlobal.ADD_BAD_APP_TOKEN:
+ case WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN:
+ throw new WindowManager.BadTokenException(
"Unable to add window -- token " + attrs.token
+ " is not valid; is your activity running?");
- case WindowManagerImpl.ADD_NOT_APP_TOKEN:
- throw new WindowManagerImpl.BadTokenException(
+ case WindowManagerGlobal.ADD_NOT_APP_TOKEN:
+ throw new WindowManager.BadTokenException(
"Unable to add window -- token " + attrs.token
+ " is not for an application");
- case WindowManagerImpl.ADD_APP_EXITING:
- throw new WindowManagerImpl.BadTokenException(
+ case WindowManagerGlobal.ADD_APP_EXITING:
+ throw new WindowManager.BadTokenException(
"Unable to add window -- app for token " + attrs.token
+ " is exiting");
- case WindowManagerImpl.ADD_DUPLICATE_ADD:
- throw new WindowManagerImpl.BadTokenException(
+ case WindowManagerGlobal.ADD_DUPLICATE_ADD:
+ throw new WindowManager.BadTokenException(
"Unable to add window -- window " + mWindow
+ " has already been added");
- case WindowManagerImpl.ADD_STARTING_NOT_NEEDED:
+ case WindowManagerGlobal.ADD_STARTING_NOT_NEEDED:
// Silently ignore -- we would have just removed it
// right away, anyway.
return;
- case WindowManagerImpl.ADD_MULTIPLE_SINGLETON:
- throw new WindowManagerImpl.BadTokenException(
+ case WindowManagerGlobal.ADD_MULTIPLE_SINGLETON:
+ throw new WindowManager.BadTokenException(
"Unable to add window " + mWindow +
" -- another window of this type already exists");
- case WindowManagerImpl.ADD_PERMISSION_DENIED:
- throw new WindowManagerImpl.BadTokenException(
+ case WindowManagerGlobal.ADD_PERMISSION_DENIED:
+ throw new WindowManager.BadTokenException(
"Unable to add window " + mWindow +
" -- permission denied for this window type");
}
@@ -622,8 +606,8 @@ public final class ViewRootImpl implements ViewParent,
}
view.assignParent(this);
- mAddedTouchMode = (res&WindowManagerImpl.ADD_FLAG_IN_TOUCH_MODE) != 0;
- mAppVisible = (res&WindowManagerImpl.ADD_FLAG_APP_VISIBLE) != 0;
+ mAddedTouchMode = (res & WindowManagerGlobal.ADD_FLAG_IN_TOUCH_MODE) != 0;
+ mAppVisible = (res & WindowManagerGlobal.ADD_FLAG_APP_VISIBLE) != 0;
if (mAccessibilityManager.isEnabled()) {
mAccessibilityInteractionConnectionManager.ensureConnection();
@@ -1164,9 +1148,8 @@ public final class ViewRootImpl implements ViewParent,
if (lp.type == WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL) {
// NOTE -- system code, won't try to do compat mode.
- Display disp = WindowManagerImpl.getDefault().getDefaultDisplay();
Point size = new Point();
- disp.getRealSize(size);
+ mDisplay.getRealSize(size);
desiredWindowWidth = size.x;
desiredWindowHeight = size.y;
} else {
@@ -1251,9 +1234,8 @@ public final class ViewRootImpl implements ViewParent,
if (lp.type == WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL) {
// NOTE -- system code, won't try to do compat mode.
- Display disp = WindowManagerImpl.getDefault().getDefaultDisplay();
Point size = new Point();
- disp.getRealSize(size);
+ mDisplay.getRealSize(size);
desiredWindowWidth = size.x;
desiredWindowHeight = size.y;
} else {
@@ -1303,7 +1285,7 @@ public final class ViewRootImpl implements ViewParent,
}
}
- if (params != null && (host.mPrivateFlags & View.REQUEST_TRANSPARENT_REGIONS) != 0) {
+ if (params != null && (host.mPrivateFlags & View.PFLAG_REQUEST_TRANSPARENT_REGIONS) != 0) {
if (!PixelFormat.formatHasAlpha(params.format)) {
params.format = PixelFormat.TRANSLUCENT;
}
@@ -1502,7 +1484,7 @@ public final class ViewRootImpl implements ViewParent,
} catch (Surface.OutOfResourcesException e) {
Log.e(TAG, "OutOfResourcesException initializing HW surface", e);
try {
- if (!sWindowSession.outOfMemory(mWindow)) {
+ if (!mWindowSession.outOfMemory(mWindow)) {
Slog.w(TAG, "No processes killed for memory; killing self");
Process.killProcess(Process.myPid());
}
@@ -1535,7 +1517,7 @@ public final class ViewRootImpl implements ViewParent,
} catch (Surface.OutOfResourcesException e) {
Log.e(TAG, "OutOfResourcesException updating HW surface", e);
try {
- if (!sWindowSession.outOfMemory(mWindow)) {
+ if (!mWindowSession.outOfMemory(mWindow)) {
Slog.w(TAG, "No processes killed for memory; killing self");
Process.killProcess(Process.myPid());
}
@@ -1629,7 +1611,7 @@ public final class ViewRootImpl implements ViewParent,
if (!mStopped) {
boolean focusChangedDueToTouchMode = ensureTouchModeLocally(
- (relayoutResult&WindowManagerImpl.RELAYOUT_RES_IN_TOUCH_MODE) != 0);
+ (relayoutResult&WindowManagerGlobal.RELAYOUT_RES_IN_TOUCH_MODE) != 0);
if (focusChangedDueToTouchMode || mWidth != host.getMeasuredWidth()
|| mHeight != host.getMeasuredHeight() || contentInsetsChanged) {
int childWidthMeasureSpec = getRootMeasureSpec(mWidth, lp.width);
@@ -1709,7 +1691,7 @@ public final class ViewRootImpl implements ViewParent,
// By this point all views have been sized and positionned
// We can compute the transparent area
- if ((host.mPrivateFlags & View.REQUEST_TRANSPARENT_REGIONS) != 0) {
+ if ((host.mPrivateFlags & View.PFLAG_REQUEST_TRANSPARENT_REGIONS) != 0) {
// start out transparent
// TODO: AVOID THAT CALL BY CACHING THE RESULT?
host.getLocationInWindow(mTmpLocation);
@@ -1726,7 +1708,7 @@ public final class ViewRootImpl implements ViewParent,
mPreviousTransparentRegion.set(mTransparentRegion);
// reconfigure window manager
try {
- sWindowSession.setTransparentRegion(mWindow, mTransparentRegion);
+ mWindowSession.setTransparentRegion(mWindow, mTransparentRegion);
} catch (RemoteException e) {
}
}
@@ -1775,7 +1757,7 @@ public final class ViewRootImpl implements ViewParent,
}
try {
- sWindowSession.setInsets(mWindow, insets.mTouchableInsets,
+ mWindowSession.setInsets(mWindow, insets.mTouchableInsets,
contentInsets, visibleInsets, touchableRegion);
} catch (RemoteException e) {
}
@@ -1800,7 +1782,7 @@ public final class ViewRootImpl implements ViewParent,
+ mRealFocusedView);
}
}
- if ((relayoutResult&WindowManagerImpl.RELAYOUT_RES_ANIMATING) != 0) {
+ if ((relayoutResult & WindowManagerGlobal.RELAYOUT_RES_ANIMATING) != 0) {
// The first time we relayout the window, if the system is
// doing window animations, we want to hold of on any future
// draws until the animation is done.
@@ -1831,7 +1813,7 @@ public final class ViewRootImpl implements ViewParent,
}
// Remember if we must report the next draw.
- if ((relayoutResult & WindowManagerImpl.RELAYOUT_RES_FIRST_TIME) != 0) {
+ if ((relayoutResult & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0) {
mReportNextDraw = true;
}
@@ -1893,7 +1875,7 @@ public final class ViewRootImpl implements ViewParent,
// the test below should not fail unless someone is messing with us
checkThread();
if (mView == child) {
- mView.mPrivateFlags |= View.REQUEST_TRANSPARENT_REGIONS;
+ mView.mPrivateFlags |= View.PFLAG_REQUEST_TRANSPARENT_REGIONS;
// Need to make sure we re-evaluate the window attributes next
// time around, to ensure the window has the correct format.
mWindowAttributesChanged = true;
@@ -2061,7 +2043,7 @@ public final class ViewRootImpl implements ViewParent,
}
}
try {
- sWindowSession.finishDrawing(mWindow);
+ mWindowSession.finishDrawing(mWindow);
} catch (RemoteException e) {
}
}
@@ -2217,7 +2199,7 @@ public final class ViewRootImpl implements ViewParent,
} catch (Surface.OutOfResourcesException e) {
Log.e(TAG, "OutOfResourcesException locking surface", e);
try {
- if (!sWindowSession.outOfMemory(mWindow)) {
+ if (!mWindowSession.outOfMemory(mWindow)) {
Slog.w(TAG, "No processes killed for memory; killing self");
Process.killProcess(Process.myPid());
}
@@ -2256,7 +2238,7 @@ public final class ViewRootImpl implements ViewParent,
dirty.setEmpty();
mIsAnimating = false;
attachInfo.mDrawingTime = SystemClock.uptimeMillis();
- mView.mPrivateFlags |= View.DRAWN;
+ mView.mPrivateFlags |= View.PFLAG_DRAWN;
if (DEBUG_DRAW) {
Context cxt = mView.getContext();
@@ -2646,7 +2628,7 @@ public final class ViewRootImpl implements ViewParent,
mInputEventReceiver = null;
}
try {
- sWindowSession.remove(mWindow);
+ mWindowSession.remove(mWindow);
} catch (RemoteException e) {
}
@@ -2891,7 +2873,7 @@ public final class ViewRootImpl implements ViewParent,
} catch (Surface.OutOfResourcesException e) {
Log.e(TAG, "OutOfResourcesException locking surface", e);
try {
- if (!sWindowSession.outOfMemory(mWindow)) {
+ if (!mWindowSession.outOfMemory(mWindow)) {
Slog.w(TAG, "No processes killed for memory; killing self");
Process.killProcess(Process.myPid());
}
@@ -3036,7 +3018,7 @@ public final class ViewRootImpl implements ViewParent,
// tell the window manager
try {
- sWindowSession.setInTouchMode(inTouchMode);
+ mWindowSession.setInTouchMode(inTouchMode);
} catch (RemoteException e) {
throw new RuntimeException(e);
}
@@ -3750,10 +3732,10 @@ public final class ViewRootImpl implements ViewParent,
if (prevDragView != mCurrentDragView) {
try {
if (prevDragView != null) {
- sWindowSession.dragRecipientExited(mWindow);
+ mWindowSession.dragRecipientExited(mWindow);
}
if (mCurrentDragView != null) {
- sWindowSession.dragRecipientEntered(mWindow);
+ mWindowSession.dragRecipientEntered(mWindow);
}
} catch (RemoteException e) {
Slog.e(TAG, "Unable to note drag target change");
@@ -3765,7 +3747,7 @@ public final class ViewRootImpl implements ViewParent,
mDragDescription = null;
try {
Log.i(TAG, "Reporting drop result: " + result);
- sWindowSession.reportDropResult(mWindow, result);
+ mWindowSession.reportDropResult(mWindow, result);
} catch (RemoteException e) {
Log.e(TAG, "Unable to report drop result");
}
@@ -3867,11 +3849,11 @@ public final class ViewRootImpl implements ViewParent,
params.type = mOrigWindowType;
}
}
- int relayoutResult = sWindowSession.relayout(
+ int relayoutResult = mWindowSession.relayout(
mWindow, mSeq, params,
(int) (mView.getMeasuredWidth() * appScale + 0.5f),
(int) (mView.getMeasuredHeight() * appScale + 0.5f),
- viewVisibility, insetsPending ? WindowManagerImpl.RELAYOUT_INSETS_PENDING : 0,
+ viewVisibility, insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0,
mWinFrame, mPendingContentInsets, mPendingVisibleInsets,
mPendingConfiguration, mSurface);
//Log.d(TAG, "<<<<<< BACK FROM relayout");
@@ -3928,7 +3910,7 @@ public final class ViewRootImpl implements ViewParent,
*/
public boolean performHapticFeedback(int effectId, boolean always) {
try {
- return sWindowSession.performHapticFeedback(mWindow, effectId, always);
+ return mWindowSession.performHapticFeedback(mWindow, effectId, always);
} catch (RemoteException e) {
return false;
}
@@ -4007,8 +3989,8 @@ public final class ViewRootImpl implements ViewParent,
// animation info.
try {
if ((relayoutWindow(mWindowAttributes, viewVisibility, false)
- & WindowManagerImpl.RELAYOUT_RES_FIRST_TIME) != 0) {
- sWindowSession.finishDrawing(mWindow);
+ & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0) {
+ mWindowSession.finishDrawing(mWindow);
}
} catch (RemoteException e) {
}
@@ -4726,9 +4708,11 @@ public final class ViewRootImpl implements ViewParent,
static class W extends IWindow.Stub {
private final WeakReference<ViewRootImpl> mViewAncestor;
+ private final IWindowSession mWindowSession;
W(ViewRootImpl viewAncestor) {
mViewAncestor = new WeakReference<ViewRootImpl>(viewAncestor);
+ mWindowSession = viewAncestor.mWindowSession;
}
public void resized(Rect frame, Rect contentInsets,
@@ -4827,7 +4811,7 @@ public final class ViewRootImpl implements ViewParent,
boolean sync) {
if (sync) {
try {
- sWindowSession.wallpaperOffsetsComplete(asBinder());
+ mWindowSession.wallpaperOffsetsComplete(asBinder());
} catch (RemoteException e) {
}
}
@@ -4837,7 +4821,7 @@ public final class ViewRootImpl implements ViewParent,
int z, Bundle extras, boolean sync) {
if (sync) {
try {
- sWindowSession.wallpaperCommandComplete(asBinder(), null);
+ mWindowSession.wallpaperCommandComplete(asBinder(), null);
} catch (RemoteException e) {
}
}
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index f57f056..a242895 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -16,7 +16,6 @@
package android.view;
-import android.app.Application;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.TypedArray;
@@ -455,7 +454,7 @@ public abstract class Window {
* display panels. This is <em>not</em> used for displaying the
* Window itself -- that must be done by the client.
*
- * @param wm The ViewManager for adding new windows.
+ * @param wm The window manager for adding new windows.
*/
public void setWindowManager(WindowManager wm, IBinder appToken, String appName) {
setWindowManager(wm, appToken, appName, false);
@@ -466,7 +465,7 @@ public abstract class Window {
* display panels. This is <em>not</em> used for displaying the
* Window itself -- that must be done by the client.
*
- * @param wm The ViewManager for adding new windows.
+ * @param wm The window manager for adding new windows.
*/
public void setWindowManager(WindowManager wm, IBinder appToken, String appName,
boolean hardwareAccelerated) {
@@ -475,14 +474,9 @@ public abstract class Window {
mHardwareAccelerated = hardwareAccelerated
|| SystemProperties.getBoolean(PROPERTY_HARDWARE_UI, false);
if (wm == null) {
- wm = WindowManagerImpl.getDefault();
+ wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
}
- mWindowManager = ((WindowManagerImpl)wm).makeLocal(this);
- }
-
- CompatibilityInfoHolder getCompatibilityInfo() {
- Application app = (Application)mContext.getApplicationContext();
- return app != null ? app.mLoadedApk.mCompatibilityInfo : null;
+ mWindowManager = ((WindowManagerImpl)wm).createLocalWindowManager(this);
}
void adjustLayoutParamsForSubWindow(WindowManager.LayoutParams wp) {
diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java
new file mode 100644
index 0000000..7855763c
--- /dev/null
+++ b/core/java/android/view/WindowManagerGlobal.java
@@ -0,0 +1,516 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import android.animation.ValueAnimator;
+import android.app.ActivityManager;
+import android.content.ComponentCallbacks2;
+import android.content.res.Configuration;
+import android.opengl.ManagedEGLContext;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.SystemProperties;
+import android.util.AndroidRuntimeException;
+import android.util.Log;
+import android.view.inputmethod.InputMethodManager;
+
+import java.io.FileDescriptor;
+import java.io.FileOutputStream;
+import java.io.PrintWriter;
+
+/**
+ * Provides low-level communication with the system window manager for
+ * operations that are not associated with any particular context.
+ *
+ * This class is only used internally to implement global functions where
+ * the caller already knows the display and relevant compatibility information
+ * for the operation. For most purposes, you should use {@link WindowManager} instead
+ * since it is bound to a context.
+ *
+ * @see WindowManagerImpl
+ * @hide
+ */
+public final class WindowManagerGlobal {
+ private static final String TAG = "WindowManager";
+
+ /**
+ * The user is navigating with keys (not the touch screen), so
+ * navigational focus should be shown.
+ */
+ public static final int RELAYOUT_RES_IN_TOUCH_MODE = 0x1;
+
+ /**
+ * This is the first time the window is being drawn,
+ * so the client must call drawingFinished() when done
+ */
+ public static final int RELAYOUT_RES_FIRST_TIME = 0x2;
+
+ /**
+ * The window manager has changed the surface from the last call.
+ */
+ public static final int RELAYOUT_RES_SURFACE_CHANGED = 0x4;
+
+ /**
+ * The window manager is currently animating. It will call
+ * IWindow.doneAnimating() when done.
+ */
+ public static final int RELAYOUT_RES_ANIMATING = 0x8;
+
+ /**
+ * Flag for relayout: the client will be later giving
+ * internal insets; as a result, the window will not impact other window
+ * layouts until the insets are given.
+ */
+ public static final int RELAYOUT_INSETS_PENDING = 0x1;
+
+ /**
+ * Flag for relayout: the client may be currently using the current surface,
+ * so if it is to be destroyed as a part of the relayout the destroy must
+ * be deferred until later. The client will call performDeferredDestroy()
+ * when it is okay.
+ */
+ public static final int RELAYOUT_DEFER_SURFACE_DESTROY = 0x2;
+
+ public static final int ADD_FLAG_APP_VISIBLE = 0x2;
+ public static final int ADD_FLAG_IN_TOUCH_MODE = RELAYOUT_RES_IN_TOUCH_MODE;
+
+ public static final int ADD_OKAY = 0;
+ public static final int ADD_BAD_APP_TOKEN = -1;
+ public static final int ADD_BAD_SUBWINDOW_TOKEN = -2;
+ public static final int ADD_NOT_APP_TOKEN = -3;
+ public static final int ADD_APP_EXITING = -4;
+ public static final int ADD_DUPLICATE_ADD = -5;
+ public static final int ADD_STARTING_NOT_NEEDED = -6;
+ public static final int ADD_MULTIPLE_SINGLETON = -7;
+ public static final int ADD_PERMISSION_DENIED = -8;
+
+ private static WindowManagerGlobal sDefaultWindowManager;
+ private static IWindowManager sWindowManagerService;
+ private static IWindowSession sWindowSession;
+
+ private final Object mLock = new Object();
+
+ private View[] mViews;
+ private ViewRootImpl[] mRoots;
+ private WindowManager.LayoutParams[] mParams;
+ private boolean mNeedsEglTerminate;
+
+ private Runnable mSystemPropertyUpdater;
+
+ private WindowManagerGlobal() {
+ }
+
+ public static WindowManagerGlobal getInstance() {
+ synchronized (WindowManagerGlobal.class) {
+ if (sDefaultWindowManager == null) {
+ sDefaultWindowManager = new WindowManagerGlobal();
+ }
+ return sDefaultWindowManager;
+ }
+ }
+
+ public static IWindowManager getWindowManagerService() {
+ synchronized (WindowManagerGlobal.class) {
+ if (sWindowManagerService == null) {
+ sWindowManagerService = IWindowManager.Stub.asInterface(
+ ServiceManager.getService("window"));
+ }
+ return sWindowManagerService;
+ }
+ }
+
+ public static IWindowSession getWindowSession(Looper mainLooper) {
+ synchronized (WindowManagerGlobal.class) {
+ if (sWindowSession == null) {
+ try {
+ InputMethodManager imm = InputMethodManager.getInstance(mainLooper);
+ IWindowManager windowManager = getWindowManagerService();
+ sWindowSession = windowManager.openSession(
+ imm.getClient(), imm.getInputContext());
+ float animatorScale = windowManager.getAnimationScale(2);
+ ValueAnimator.setDurationScale(animatorScale);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to open window session", e);
+ }
+ }
+ return sWindowSession;
+ }
+ }
+
+ public static IWindowSession peekWindowSession() {
+ synchronized (WindowManagerGlobal.class) {
+ return sWindowSession;
+ }
+ }
+
+ public void addView(View view, ViewGroup.LayoutParams params,
+ Display display, Window parentWindow) {
+ if (view == null) {
+ throw new IllegalArgumentException("view must not be null");
+ }
+ if (display == null) {
+ throw new IllegalArgumentException("display must not be null");
+ }
+ if (!(params instanceof WindowManager.LayoutParams)) {
+ throw new IllegalArgumentException("Params must be WindowManager.LayoutParams");
+ }
+
+ final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams)params;
+ if (parentWindow != null) {
+ parentWindow.adjustLayoutParamsForSubWindow(wparams);
+ }
+
+ ViewRootImpl root;
+ View panelParentView = null;
+
+ synchronized (mLock) {
+ // Start watching for system property changes.
+ if (mSystemPropertyUpdater == null) {
+ mSystemPropertyUpdater = new Runnable() {
+ @Override public void run() {
+ synchronized (mLock) {
+ for (ViewRootImpl root : mRoots) {
+ root.loadSystemProperties();
+ }
+ }
+ }
+ };
+ SystemProperties.addChangeCallback(mSystemPropertyUpdater);
+ }
+
+ int index = findViewLocked(view, false);
+ if (index >= 0) {
+ throw new IllegalStateException("View " + view
+ + " has already been added to the window manager.");
+ }
+
+ // If this is a panel window, then find the window it is being
+ // attached to for future reference.
+ if (wparams.type >= WindowManager.LayoutParams.FIRST_SUB_WINDOW &&
+ wparams.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) {
+ final int count = mViews != null ? mViews.length : 0;
+ for (int i=0; i<count; i++) {
+ if (mRoots[i].mWindow.asBinder() == wparams.token) {
+ panelParentView = mViews[i];
+ }
+ }
+ }
+
+ root = new ViewRootImpl(view.getContext(), display);
+
+ view.setLayoutParams(wparams);
+
+ if (mViews == null) {
+ index = 1;
+ mViews = new View[1];
+ mRoots = new ViewRootImpl[1];
+ mParams = new WindowManager.LayoutParams[1];
+ } else {
+ index = mViews.length + 1;
+ Object[] old = mViews;
+ mViews = new View[index];
+ System.arraycopy(old, 0, mViews, 0, index-1);
+ old = mRoots;
+ mRoots = new ViewRootImpl[index];
+ System.arraycopy(old, 0, mRoots, 0, index-1);
+ old = mParams;
+ mParams = new WindowManager.LayoutParams[index];
+ System.arraycopy(old, 0, mParams, 0, index-1);
+ }
+ index--;
+
+ mViews[index] = view;
+ mRoots[index] = root;
+ mParams[index] = wparams;
+ }
+
+ // do this last because it fires off messages to start doing things
+ root.setView(view, wparams, panelParentView);
+ }
+
+ public void updateViewLayout(View view, ViewGroup.LayoutParams params) {
+ if (view == null) {
+ throw new IllegalArgumentException("view must not be null");
+ }
+ if (!(params instanceof WindowManager.LayoutParams)) {
+ throw new IllegalArgumentException("Params must be WindowManager.LayoutParams");
+ }
+
+ final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams)params;
+
+ view.setLayoutParams(wparams);
+
+ synchronized (mLock) {
+ int index = findViewLocked(view, true);
+ ViewRootImpl root = mRoots[index];
+ mParams[index] = wparams;
+ root.setLayoutParams(wparams, false);
+ }
+ }
+
+ public void removeView(View view, boolean immediate) {
+ if (view == null) {
+ throw new IllegalArgumentException("view must not be null");
+ }
+
+ synchronized (mLock) {
+ int index = findViewLocked(view, true);
+ View curView = removeViewLocked(index, immediate);
+ if (curView == view) {
+ return;
+ }
+
+ throw new IllegalStateException("Calling with view " + view
+ + " but the ViewAncestor is attached to " + curView);
+ }
+ }
+
+ public void closeAll(IBinder token, String who, String what) {
+ synchronized (mLock) {
+ if (mViews == null)
+ return;
+
+ int count = mViews.length;
+ //Log.i("foo", "Closing all windows of " + token);
+ for (int i=0; i<count; i++) {
+ //Log.i("foo", "@ " + i + " token " + mParams[i].token
+ // + " view " + mRoots[i].getView());
+ if (token == null || mParams[i].token == token) {
+ ViewRootImpl root = mRoots[i];
+
+ //Log.i("foo", "Force closing " + root);
+ if (who != null) {
+ WindowLeaked leak = new WindowLeaked(
+ what + " " + who + " has leaked window "
+ + root.getView() + " that was originally added here");
+ leak.setStackTrace(root.getLocation().getStackTrace());
+ Log.e(TAG, leak.getMessage(), leak);
+ }
+
+ removeViewLocked(i, false);
+ i--;
+ count--;
+ }
+ }
+ }
+ }
+
+ private View removeViewLocked(int index, boolean immediate) {
+ ViewRootImpl root = mRoots[index];
+ View view = root.getView();
+
+ if (view != null) {
+ InputMethodManager imm = InputMethodManager.getInstance(view.getContext());
+ if (imm != null) {
+ imm.windowDismissed(mViews[index].getWindowToken());
+ }
+ }
+ root.die(immediate);
+
+ final int count = mViews.length;
+
+ // remove it from the list
+ View[] tmpViews = new View[count-1];
+ removeItem(tmpViews, mViews, index);
+ mViews = tmpViews;
+
+ ViewRootImpl[] tmpRoots = new ViewRootImpl[count-1];
+ removeItem(tmpRoots, mRoots, index);
+ mRoots = tmpRoots;
+
+ WindowManager.LayoutParams[] tmpParams
+ = new WindowManager.LayoutParams[count-1];
+ removeItem(tmpParams, mParams, index);
+ mParams = tmpParams;
+
+ if (view != null) {
+ view.assignParent(null);
+ // func doesn't allow null... does it matter if we clear them?
+ //view.setLayoutParams(null);
+ }
+ return view;
+ }
+
+ private static void removeItem(Object[] dst, Object[] src, int index) {
+ if (dst.length > 0) {
+ if (index > 0) {
+ System.arraycopy(src, 0, dst, 0, index);
+ }
+ if (index < dst.length) {
+ System.arraycopy(src, index+1, dst, index, src.length-index-1);
+ }
+ }
+ }
+
+ private int findViewLocked(View view, boolean required) {
+ synchronized (mLock) {
+ if (mViews != null) {
+ final int count = mViews.length;
+ for (int i = 0; i < count; i++) {
+ if (mViews[i] == view) {
+ return i;
+ }
+ }
+ }
+ if (required) {
+ throw new IllegalArgumentException("View not attached to window manager");
+ }
+ return -1;
+ }
+ }
+
+ public void startTrimMemory(int level) {
+ if (HardwareRenderer.isAvailable()) {
+ // On low-end gfx devices we trim when memory is moderate;
+ // on high-end devices we do this when low.
+ if (level >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
+ || (level >= ComponentCallbacks2.TRIM_MEMORY_MODERATE
+ && !ActivityManager.isHighEndGfx())) {
+ // Destroy all hardware surfaces and resources associated to
+ // known windows
+ synchronized (mLock) {
+ if (mViews == null) return;
+ int count = mViews.length;
+ for (int i = 0; i < count; i++) {
+ mRoots[i].terminateHardwareResources();
+ }
+ }
+ // Force a full memory flush
+ mNeedsEglTerminate = true;
+ HardwareRenderer.startTrimMemory(ComponentCallbacks2.TRIM_MEMORY_COMPLETE);
+ return;
+ }
+
+ HardwareRenderer.startTrimMemory(level);
+ }
+ }
+
+ public void endTrimMemory() {
+ HardwareRenderer.endTrimMemory();
+
+ if (mNeedsEglTerminate) {
+ ManagedEGLContext.doTerminate();
+ mNeedsEglTerminate = false;
+ }
+ }
+
+ public void trimLocalMemory() {
+ synchronized (mLock) {
+ if (mViews == null) return;
+ int count = mViews.length;
+ for (int i = 0; i < count; i++) {
+ mRoots[i].destroyHardwareLayers();
+ }
+ }
+ }
+
+ public void dumpGfxInfo(FileDescriptor fd) {
+ FileOutputStream fout = new FileOutputStream(fd);
+ PrintWriter pw = new PrintWriter(fout);
+ try {
+ synchronized (mLock) {
+ if (mViews != null) {
+ final int count = mViews.length;
+
+ pw.println("Profile data in ms:");
+
+ for (int i = 0; i < count; i++) {
+ ViewRootImpl root = mRoots[i];
+ String name = getWindowName(root);
+ pw.printf("\n\t%s", name);
+
+ HardwareRenderer renderer =
+ root.getView().mAttachInfo.mHardwareRenderer;
+ if (renderer != null) {
+ renderer.dumpGfxInfo(pw);
+ }
+ }
+
+ pw.println("\nView hierarchy:\n");
+
+ int viewsCount = 0;
+ int displayListsSize = 0;
+ int[] info = new int[2];
+
+ for (int i = 0; i < count; i++) {
+ ViewRootImpl root = mRoots[i];
+ root.dumpGfxInfo(info);
+
+ String name = getWindowName(root);
+ pw.printf(" %s\n %d views, %.2f kB of display lists",
+ name, info[0], info[1] / 1024.0f);
+ HardwareRenderer renderer =
+ root.getView().mAttachInfo.mHardwareRenderer;
+ if (renderer != null) {
+ pw.printf(", %d frames rendered", renderer.getFrameCount());
+ }
+ pw.printf("\n\n");
+
+ viewsCount += info[0];
+ displayListsSize += info[1];
+ }
+
+ pw.printf("\nTotal ViewRootImpl: %d\n", count);
+ pw.printf("Total Views: %d\n", viewsCount);
+ pw.printf("Total DisplayList: %.2f kB\n\n", displayListsSize / 1024.0f);
+ }
+ }
+ } finally {
+ pw.flush();
+ }
+ }
+
+ private static String getWindowName(ViewRootImpl root) {
+ return root.mWindowAttributes.getTitle() + "/" +
+ root.getClass().getName() + '@' + Integer.toHexString(root.hashCode());
+ }
+
+ public void setStoppedState(IBinder token, boolean stopped) {
+ synchronized (mLock) {
+ if (mViews != null) {
+ int count = mViews.length;
+ for (int i=0; i < count; i++) {
+ if (token == null || mParams[i].token == token) {
+ ViewRootImpl root = mRoots[i];
+ root.setStopped(stopped);
+ }
+ }
+ }
+ }
+ }
+
+ public void reportNewConfiguration(Configuration config) {
+ synchronized (mLock) {
+ if (mViews != null) {
+ int count = mViews.length;
+ config = new Configuration(config);
+ for (int i=0; i < count; i++) {
+ ViewRootImpl root = mRoots[i];
+ root.requestUpdateConfiguration(config);
+ }
+ }
+ }
+ }
+}
+
+final class WindowLeaked extends AndroidRuntimeException {
+ public WindowLeaked(String msg) {
+ super(msg);
+ }
+}
diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java
index bd95cdb..bf061df 100644
--- a/core/java/android/view/WindowManagerImpl.java
+++ b/core/java/android/view/WindowManagerImpl.java
@@ -16,34 +16,20 @@
package android.view;
-import android.app.ActivityManager;
-import android.content.ComponentCallbacks2;
-import android.content.res.Configuration;
-import android.opengl.ManagedEGLContext;
-import android.os.IBinder;
-import android.os.ServiceManager;
-import android.os.SystemProperties;
-import android.util.AndroidRuntimeException;
-import android.util.Log;
-import android.view.inputmethod.InputMethodManager;
-
-import java.io.FileDescriptor;
-import java.io.FileOutputStream;
-import java.io.PrintWriter;
-
-final class WindowLeaked extends AndroidRuntimeException {
- public WindowLeaked(String msg) {
- super(msg);
- }
-}
+import android.content.Context;
+import android.hardware.display.DisplayManager;
/**
- * Low-level communication with the global system window manager. It implements
- * the ViewManager interface, allowing you to add any View subclass as a
- * top-level window on the screen. Additional window manager specific layout
- * parameters are defined for control over how windows are displayed.
- * It also implements the WindowManager interface, allowing you to control the
- * displays attached to the device.
+ * Provides low-level communication with the system window manager for
+ * operations that are bound to a particular context, display or parent window.
+ * Instances of this object are sensitive to the compatibility info associated
+ * with the running application.
+ *
+ * This object implements the {@link ViewManager} interface,
+ * allowing you to add any View subclass as a top-level window on the screen.
+ * Additional window manager specific layout parameters are defined for
+ * control over how windows are displayed. It also implements the {@link WindowManager}
+ * interface, allowing you to control the displays attached to the device.
*
* <p>Applications will not normally use WindowManager directly, instead relying
* on the higher-level facilities in {@link android.app.Activity} and
@@ -51,531 +37,58 @@ final class WindowLeaked extends AndroidRuntimeException {
*
* <p>Even for low-level window manager access, it is almost never correct to use
* this class. For example, {@link android.app.Activity#getWindowManager}
- * provides a ViewManager for adding windows that are associated with that
+ * provides a window manager for adding windows that are associated with that
* activity -- the window manager will not normally allow you to add arbitrary
* windows that are not associated with an activity.
- *
+ *
+ * @see WindowManager
+ * @see WindowManagerGlobal
* @hide
*/
-public class WindowManagerImpl implements WindowManager {
- private static final String TAG = "WindowManager";
-
- /**
- * The user is navigating with keys (not the touch screen), so
- * navigational focus should be shown.
- */
- public static final int RELAYOUT_RES_IN_TOUCH_MODE = 0x1;
-
- /**
- * This is the first time the window is being drawn,
- * so the client must call drawingFinished() when done
- */
- public static final int RELAYOUT_RES_FIRST_TIME = 0x2;
-
- /**
- * The window manager has changed the surface from the last call.
- */
- public static final int RELAYOUT_RES_SURFACE_CHANGED = 0x4;
-
- /**
- * The window manager is currently animating. It will call
- * IWindow.doneAnimating() when done.
- */
- public static final int RELAYOUT_RES_ANIMATING = 0x8;
-
- /**
- * Flag for relayout: the client will be later giving
- * internal insets; as a result, the window will not impact other window
- * layouts until the insets are given.
- */
- public static final int RELAYOUT_INSETS_PENDING = 0x1;
-
- /**
- * Flag for relayout: the client may be currently using the current surface,
- * so if it is to be destroyed as a part of the relayout the destroy must
- * be deferred until later. The client will call performDeferredDestroy()
- * when it is okay.
- */
- public static final int RELAYOUT_DEFER_SURFACE_DESTROY = 0x2;
-
- public static final int ADD_FLAG_APP_VISIBLE = 0x2;
- public static final int ADD_FLAG_IN_TOUCH_MODE = RELAYOUT_RES_IN_TOUCH_MODE;
-
- public static final int ADD_OKAY = 0;
- public static final int ADD_BAD_APP_TOKEN = -1;
- public static final int ADD_BAD_SUBWINDOW_TOKEN = -2;
- public static final int ADD_NOT_APP_TOKEN = -3;
- public static final int ADD_APP_EXITING = -4;
- public static final int ADD_DUPLICATE_ADD = -5;
- public static final int ADD_STARTING_NOT_NEEDED = -6;
- public static final int ADD_MULTIPLE_SINGLETON = -7;
- public static final int ADD_PERMISSION_DENIED = -8;
-
- private static WindowManagerImpl sDefaultWindowManager;
- private static IWindowManager sWindowManagerService;
-
- private final WindowManagerState mState;
+public final class WindowManagerImpl implements WindowManager {
+ private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();
+ private final Context mContext;
+ private final Display mDisplay;
private final Window mParentWindow;
- private final CompatibilityInfoHolder mCompatibilityInfo;
- private final Display mDefaultDisplay;
- private WindowManagerImpl(WindowManagerState state, Window parentWindow,
- CompatibilityInfoHolder compatibilityInfo) {
- mState = state;
- mParentWindow = parentWindow;
- mCompatibilityInfo = compatibilityInfo;
- mDefaultDisplay = mState.getDefaultDisplay(mCompatibilityInfo);
+ public WindowManagerImpl(Context context, int displayId) {
+ mContext = context;
+ mDisplay = DisplayManager.getInstance().getDisplay(displayId, mContext);
+ mParentWindow = null;
}
- public static WindowManagerImpl getDefault() {
- synchronized (WindowManagerImpl.class) {
- if (sDefaultWindowManager == null) {
- sDefaultWindowManager = new WindowManagerImpl(
- new WindowManagerState(), null, null);
- }
- return sDefaultWindowManager;
- }
- }
-
- public static IWindowManager getWindowManagerService() {
- synchronized (WindowManagerImpl.class) {
- if (sWindowManagerService == null) {
- sWindowManagerService = IWindowManager.Stub.asInterface(
- ServiceManager.getService("window"));
- }
- return sWindowManagerService;
- }
- }
-
- public WindowManagerImpl makeLocal(Window parentWindow) {
- return new WindowManagerImpl(mState, parentWindow, parentWindow.getCompatibilityInfo());
+ private WindowManagerImpl(Context context, Display display, Window parentWindow) {
+ mContext = context;
+ mDisplay = display;
+ mParentWindow = parentWindow;
}
- public WindowManagerImpl makeCompatible(CompatibilityInfoHolder compatInfo) {
- if (compatInfo == mCompatibilityInfo) {
- return this;
- }
- if (compatInfo == null && mParentWindow == null) {
- return getDefault();
- }
- return new WindowManagerImpl(mState, mParentWindow, compatInfo);
+ public WindowManagerImpl createLocalWindowManager(Window parentWindow) {
+ return new WindowManagerImpl(mContext, mDisplay, parentWindow);
}
@Override
public void addView(View view, ViewGroup.LayoutParams params) {
- mState.addView(view, params, mParentWindow, mCompatibilityInfo);
+ mGlobal.addView(view, params, mDisplay, mParentWindow);
}
@Override
public void updateViewLayout(View view, ViewGroup.LayoutParams params) {
- mState.updateViewLayout(view, params);
+ mGlobal.updateViewLayout(view, params);
}
@Override
public void removeView(View view) {
- mState.removeView(view, false);
+ mGlobal.removeView(view, false);
}
@Override
public void removeViewImmediate(View view) {
- mState.removeView(view, true);
+ mGlobal.removeView(view, true);
}
@Override
public Display getDefaultDisplay() {
- return mDefaultDisplay;
- }
-
- public void closeAll(IBinder token, String who, String what) {
- mState.closeAll(token, who, what);
- }
-
- public void startTrimMemory(int level) {
- mState.startTrimMemory(level);
- }
-
- public void endTrimMemory() {
- mState.endTrimMemory();
- }
-
- public void trimLocalMemory() {
- mState.trimLocalMemory();
- }
-
- public void dumpGfxInfo(FileDescriptor fd) {
- mState.dumpGfxInfo(fd);
- }
-
- public void setStoppedState(IBinder token, boolean stopped) {
- mState.setStoppedState(token, stopped);
- }
-
- public void reportNewConfiguration(Configuration config) {
- mState.reportNewConfiguration(config);
- }
-
- static final class WindowManagerState {
- private final Display mDefaultDisplay;
-
- private View[] mViews;
- private ViewRootImpl[] mRoots;
- private WindowManager.LayoutParams[] mParams;
- private boolean mNeedsEglTerminate;
-
- private Runnable mSystemPropertyUpdater;
-
- public WindowManagerState() {
- mDefaultDisplay = new Display(Display.DEFAULT_DISPLAY, null);
- }
-
- public Display getDefaultDisplay(CompatibilityInfoHolder compatInfo) {
- if (compatInfo == null) {
- return mDefaultDisplay;
- }
- return new Display(Display.DEFAULT_DISPLAY, compatInfo);
- }
-
- public void addView(View view, ViewGroup.LayoutParams params, Window parentWindow,
- CompatibilityInfoHolder cih) {
- if (!(params instanceof WindowManager.LayoutParams)) {
- throw new IllegalArgumentException("Params must be WindowManager.LayoutParams");
- }
-
- final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams)params;
- if (parentWindow != null) {
- parentWindow.adjustLayoutParamsForSubWindow(wparams);
- }
-
- ViewRootImpl root;
- View panelParentView = null;
-
- synchronized (this) {
- // Start watching for system property changes.
- if (mSystemPropertyUpdater == null) {
- mSystemPropertyUpdater = new Runnable() {
- @Override public void run() {
- synchronized (this) {
- synchronized (this) {
- for (ViewRootImpl root : mRoots) {
- root.loadSystemProperties();
- }
- }
- }
- }
- };
- SystemProperties.addChangeCallback(mSystemPropertyUpdater);
- }
-
- int index = findViewLocked(view, false);
- if (index >= 0) {
- throw new IllegalStateException("View " + view
- + " has already been added to the window manager.");
- }
-
- // If this is a panel window, then find the window it is being
- // attached to for future reference.
- if (wparams.type >= WindowManager.LayoutParams.FIRST_SUB_WINDOW &&
- wparams.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) {
- final int count = mViews != null ? mViews.length : 0;
- for (int i=0; i<count; i++) {
- if (mRoots[i].mWindow.asBinder() == wparams.token) {
- panelParentView = mViews[i];
- }
- }
- }
-
- root = new ViewRootImpl(view.getContext());
- if (cih == null) {
- root.mCompatibilityInfo = new CompatibilityInfoHolder();
- } else {
- root.mCompatibilityInfo = cih;
- }
-
- view.setLayoutParams(wparams);
-
- if (mViews == null) {
- index = 1;
- mViews = new View[1];
- mRoots = new ViewRootImpl[1];
- mParams = new WindowManager.LayoutParams[1];
- } else {
- index = mViews.length + 1;
- Object[] old = mViews;
- mViews = new View[index];
- System.arraycopy(old, 0, mViews, 0, index-1);
- old = mRoots;
- mRoots = new ViewRootImpl[index];
- System.arraycopy(old, 0, mRoots, 0, index-1);
- old = mParams;
- mParams = new WindowManager.LayoutParams[index];
- System.arraycopy(old, 0, mParams, 0, index-1);
- }
- index--;
-
- mViews[index] = view;
- mRoots[index] = root;
- mParams[index] = wparams;
- }
-
- // do this last because it fires off messages to start doing things
- root.setView(view, wparams, panelParentView);
- }
-
- public void updateViewLayout(View view, ViewGroup.LayoutParams params) {
- if (!(params instanceof WindowManager.LayoutParams)) {
- throw new IllegalArgumentException("Params must be WindowManager.LayoutParams");
- }
-
- final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams)params;
-
- view.setLayoutParams(wparams);
-
- synchronized (this) {
- int index = findViewLocked(view, true);
- ViewRootImpl root = mRoots[index];
- mParams[index] = wparams;
- root.setLayoutParams(wparams, false);
- }
- }
-
- public void removeView(View view, boolean immediate) {
- synchronized (this) {
- int index = findViewLocked(view, true);
- View curView = removeViewLocked(index, immediate);
- if (curView == view) {
- return;
- }
-
- throw new IllegalStateException("Calling with view " + view
- + " but the ViewAncestor is attached to " + curView);
- }
- }
-
- public void closeAll(IBinder token, String who, String what) {
- synchronized (this) {
- if (mViews == null)
- return;
-
- int count = mViews.length;
- //Log.i("foo", "Closing all windows of " + token);
- for (int i=0; i<count; i++) {
- //Log.i("foo", "@ " + i + " token " + mParams[i].token
- // + " view " + mRoots[i].getView());
- if (token == null || mParams[i].token == token) {
- ViewRootImpl root = mRoots[i];
-
- //Log.i("foo", "Force closing " + root);
- if (who != null) {
- WindowLeaked leak = new WindowLeaked(
- what + " " + who + " has leaked window "
- + root.getView() + " that was originally added here");
- leak.setStackTrace(root.getLocation().getStackTrace());
- Log.e(TAG, leak.getMessage(), leak);
- }
-
- removeViewLocked(i, false);
- i--;
- count--;
- }
- }
- }
- }
-
- private View removeViewLocked(int index, boolean immediate) {
- ViewRootImpl root = mRoots[index];
- View view = root.getView();
-
- if (view != null) {
- InputMethodManager imm = InputMethodManager.getInstance(view.getContext());
- if (imm != null) {
- imm.windowDismissed(mViews[index].getWindowToken());
- }
- }
- root.die(immediate);
-
- final int count = mViews.length;
-
- // remove it from the list
- View[] tmpViews = new View[count-1];
- removeItem(tmpViews, mViews, index);
- mViews = tmpViews;
-
- ViewRootImpl[] tmpRoots = new ViewRootImpl[count-1];
- removeItem(tmpRoots, mRoots, index);
- mRoots = tmpRoots;
-
- WindowManager.LayoutParams[] tmpParams
- = new WindowManager.LayoutParams[count-1];
- removeItem(tmpParams, mParams, index);
- mParams = tmpParams;
-
- if (view != null) {
- view.assignParent(null);
- // func doesn't allow null... does it matter if we clear them?
- //view.setLayoutParams(null);
- }
- return view;
- }
-
- private static void removeItem(Object[] dst, Object[] src, int index) {
- if (dst.length > 0) {
- if (index > 0) {
- System.arraycopy(src, 0, dst, 0, index);
- }
- if (index < dst.length) {
- System.arraycopy(src, index+1, dst, index, src.length-index-1);
- }
- }
- }
-
- private int findViewLocked(View view, boolean required) {
- synchronized (this) {
- if (mViews != null) {
- final int count = mViews.length;
- for (int i = 0; i < count; i++) {
- if (mViews[i] == view) {
- return i;
- }
- }
- }
- if (required) {
- throw new IllegalArgumentException("View not attached to window manager");
- }
- return -1;
- }
- }
-
- public void startTrimMemory(int level) {
- if (HardwareRenderer.isAvailable()) {
- // On low-end gfx devices we trim when memory is moderate;
- // on high-end devices we do this when low.
- if (level >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
- || (level >= ComponentCallbacks2.TRIM_MEMORY_MODERATE
- && !ActivityManager.isHighEndGfx(mDefaultDisplay))) {
- // Destroy all hardware surfaces and resources associated to
- // known windows
- synchronized (this) {
- if (mViews == null) return;
- int count = mViews.length;
- for (int i = 0; i < count; i++) {
- mRoots[i].terminateHardwareResources();
- }
- }
- // Force a full memory flush
- mNeedsEglTerminate = true;
- HardwareRenderer.startTrimMemory(ComponentCallbacks2.TRIM_MEMORY_COMPLETE);
- return;
- }
-
- HardwareRenderer.startTrimMemory(level);
- }
- }
-
- public void endTrimMemory() {
- HardwareRenderer.endTrimMemory();
-
- if (mNeedsEglTerminate) {
- ManagedEGLContext.doTerminate();
- mNeedsEglTerminate = false;
- }
- }
-
- public void trimLocalMemory() {
- synchronized (this) {
- if (mViews == null) return;
- int count = mViews.length;
- for (int i = 0; i < count; i++) {
- mRoots[i].destroyHardwareLayers();
- }
- }
- }
-
- public void dumpGfxInfo(FileDescriptor fd) {
- FileOutputStream fout = new FileOutputStream(fd);
- PrintWriter pw = new PrintWriter(fout);
- try {
- synchronized (this) {
- if (mViews != null) {
- final int count = mViews.length;
-
- pw.println("Profile data in ms:");
-
- for (int i = 0; i < count; i++) {
- ViewRootImpl root = mRoots[i];
- String name = getWindowName(root);
- pw.printf("\n\t%s", name);
-
- HardwareRenderer renderer =
- root.getView().mAttachInfo.mHardwareRenderer;
- if (renderer != null) {
- renderer.dumpGfxInfo(pw);
- }
- }
-
- pw.println("\nView hierarchy:\n");
-
- int viewsCount = 0;
- int displayListsSize = 0;
- int[] info = new int[2];
-
- for (int i = 0; i < count; i++) {
- ViewRootImpl root = mRoots[i];
- root.dumpGfxInfo(info);
-
- String name = getWindowName(root);
- pw.printf(" %s\n %d views, %.2f kB of display lists",
- name, info[0], info[1] / 1024.0f);
- HardwareRenderer renderer =
- root.getView().mAttachInfo.mHardwareRenderer;
- if (renderer != null) {
- pw.printf(", %d frames rendered", renderer.getFrameCount());
- }
- pw.printf("\n\n");
-
- viewsCount += info[0];
- displayListsSize += info[1];
- }
-
- pw.printf("\nTotal ViewRootImpl: %d\n", count);
- pw.printf("Total Views: %d\n", viewsCount);
- pw.printf("Total DisplayList: %.2f kB\n\n", displayListsSize / 1024.0f);
- }
- }
- } finally {
- pw.flush();
- }
- }
-
- private static String getWindowName(ViewRootImpl root) {
- return root.mWindowAttributes.getTitle() + "/" +
- root.getClass().getName() + '@' + Integer.toHexString(root.hashCode());
- }
-
- public void setStoppedState(IBinder token, boolean stopped) {
- synchronized (this) {
- if (mViews != null) {
- int count = mViews.length;
- for (int i=0; i < count; i++) {
- if (token == null || mParams[i].token == token) {
- ViewRootImpl root = mRoots[i];
- root.setStopped(stopped);
- }
- }
- }
- }
- }
-
- public void reportNewConfiguration(Configuration config) {
- synchronized (this) {
- if (mViews != null) {
- int count = mViews.length;
- config = new Configuration(config);
- for (int i=0; i < count; i++) {
- ViewRootImpl root = mRoots[i];
- root.requestUpdateConfiguration(config);
- }
- }
- }
- }
+ return mDisplay;
}
}
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 7aa3bb4..7173d1d 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -390,8 +390,8 @@ public interface WindowManagerPolicy {
*/
public void switchKeyboardLayout(int deviceId, int direction);
- public void shutdown();
- public void rebootSafeMode();
+ public void shutdown(boolean confirm);
+ public void rebootSafeMode(boolean confirm);
}
/**
@@ -487,9 +487,9 @@ public interface WindowManagerPolicy {
*
* @param attrs The window's LayoutParams.
*
- * @return {@link WindowManagerImpl#ADD_OKAY} if the add can proceed;
+ * @return {@link WindowManagerGlobal#ADD_OKAY} if the add can proceed;
* else an error code, usually
- * {@link WindowManagerImpl#ADD_PERMISSION_DENIED}, to abort the add.
+ * {@link WindowManagerGlobal#ADD_PERMISSION_DENIED}, to abort the add.
*/
public int checkAddPermission(WindowManager.LayoutParams attrs);
@@ -662,7 +662,7 @@ public interface WindowManagerPolicy {
* @param win The window being added.
* @param attrs The window's LayoutParams.
*
- * @return {@link WindowManagerImpl#ADD_OKAY} if the add can proceed, else an
+ * @return {@link WindowManagerGlobal#ADD_OKAY} if the add can proceed, else an
* error code to abort the add.
*/
public int prepareAddWindowLw(WindowState win,
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index 193e98d..074f910 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -16,6 +16,7 @@
package android.webkit;
+import android.content.Context;
import android.os.Message;
import android.os.Build;
@@ -1226,6 +1227,18 @@ public abstract class WebSettings {
}
/**
+ * Returns the default User-Agent used by a WebView.
+ * An instance of WebView could use a different User-Agent if a call
+ * is made to {@link WebSettings#setUserAgent(int)} or
+ * {@link WebSettings#setUserAgentString(String)}.
+ *
+ * @param context a Context object used to access application assets
+ */
+ public static String getDefaultUserAgent(Context context) {
+ return WebView.getFactory().getDefaultUserAgent(context);
+ }
+
+ /**
* Tells the WebView whether it needs to set a node to have focus when
* {@link WebView#requestFocus(int, android.graphics.Rect)} is called. The
* default value is true.
diff --git a/core/java/android/webkit/WebSettingsClassic.java b/core/java/android/webkit/WebSettingsClassic.java
index 66651f7..eac1141 100644
--- a/core/java/android/webkit/WebSettingsClassic.java
+++ b/core/java/android/webkit/WebSettingsClassic.java
@@ -374,6 +374,21 @@ public class WebSettingsClassic extends WebSettings {
synchronized(sLockForLocaleSettings) {
locale = sLocale;
}
+ return getDefaultUserAgentForLocale(mContext, locale);
+ }
+
+ /**
+ * Returns the default User-Agent used by a WebView.
+ * An instance of WebView could use a different User-Agent if a call
+ * is made to {@link WebSettings#setUserAgent(int)} or
+ * {@link WebSettings#setUserAgentString(String)}.
+ *
+ * @param context a Context object used to access application assets
+ * @param locale The Locale to use in the User-Agent string.
+ * @see WebViewFactoryProvider#getDefaultUserAgent(Context)
+ * @see WebView#getDefaultUserAgent(Context)
+ */
+ public static String getDefaultUserAgentForLocale(Context context, Locale locale) {
StringBuffer buffer = new StringBuffer();
// Add version
final String version = Build.VERSION.RELEASE;
@@ -417,9 +432,9 @@ public class WebSettingsClassic extends WebSettings {
buffer.append(" Build/");
buffer.append(id);
}
- String mobile = mContext.getResources().getText(
+ String mobile = context.getResources().getText(
com.android.internal.R.string.web_user_agent_target_content).toString();
- final String base = mContext.getResources().getText(
+ final String base = context.getResources().getText(
com.android.internal.R.string.web_user_agent).toString();
return String.format(base, buffer, mobile);
}
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 436762d..4c5699b 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -1821,7 +1821,7 @@ public class WebView extends AbsoluteLayout
}
}
- private static synchronized WebViewFactoryProvider getFactory() {
+ static synchronized WebViewFactoryProvider getFactory() {
// For now the main purpose of this function (and the factory abstration) is to keep
// us honest and minimize usage of WebViewClassic internals when binding the proxy.
checkThread();
diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java
index 8d79492..9df4852 100644
--- a/core/java/android/webkit/WebViewClassic.java
+++ b/core/java/android/webkit/WebViewClassic.java
@@ -132,6 +132,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.Vector;
@@ -1308,6 +1309,12 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
public WebViewDatabase getWebViewDatabase(Context context) {
return WebViewDatabaseClassic.getInstance(context);
}
+
+ @Override
+ public String getDefaultUserAgent(Context context) {
+ return WebSettingsClassic.getDefaultUserAgentForLocale(context,
+ Locale.getDefault());
+ }
}
private void onHandleUiEvent(MotionEvent event, int eventType, int flags) {
@@ -6441,9 +6448,13 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
mWebViewPrivate.getVerticalScrollFactor());
final int hdelta = (int) (hscroll *
mWebViewPrivate.getHorizontalScrollFactor());
- if (pinScrollBy(hdelta, vdelta, false, 0)) {
- return true;
- }
+
+ abortAnimation();
+ int oldTouchMode = mTouchMode;
+ startScrollingLayer(event.getX(), event.getY());
+ doDrag(hdelta, vdelta);
+ mTouchMode = oldTouchMode;
+ return true;
}
}
}
@@ -7279,11 +7290,7 @@ public final class WebViewClassic implements WebViewProvider, WebViewProvider.Sc
// nativeCreate sets mNativeClass to a non-zero value
String drawableDir = BrowserFrame.getRawResFilename(
BrowserFrame.DRAWABLEDIR, mContext);
- WindowManager windowManager =
- (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
- Display display = windowManager.getDefaultDisplay();
- nativeCreate(msg.arg1, drawableDir,
- ActivityManager.isHighEndGfx(display));
+ nativeCreate(msg.arg1, drawableDir, ActivityManager.isHighEndGfx());
if (mDelaySetPicture != null) {
setNewPicture(mDelaySetPicture, true);
mDelaySetPicture = null;
diff --git a/core/java/android/webkit/WebViewFactoryProvider.java b/core/java/android/webkit/WebViewFactoryProvider.java
index 1d302f1..b1d42aa 100644
--- a/core/java/android/webkit/WebViewFactoryProvider.java
+++ b/core/java/android/webkit/WebViewFactoryProvider.java
@@ -93,4 +93,14 @@ public interface WebViewFactoryProvider {
* @return the singleton WebViewDatabase instance
*/
WebViewDatabase getWebViewDatabase(Context context);
+
+ /**
+ * Returns the default User-Agent used by a WebView.
+ * An instance of WebView could use a different User-Agent if a call
+ * is made to {@link WebSettings#setUserAgent(int)} or
+ * {@link WebSettings#setUserAgentString(String)}.
+ *
+ * @param context a Context object used to access application assets
+ */
+ String getDefaultUserAgent(Context context);
}
diff --git a/core/java/android/widget/Switch.java b/core/java/android/widget/Switch.java
index 5d6491d..1f713d4 100644
--- a/core/java/android/widget/Switch.java
+++ b/core/java/android/widget/Switch.java
@@ -664,7 +664,7 @@ public class Switch extends CompoundButton {
@Override
public void setChecked(boolean checked) {
super.setChecked(checked);
- setThumbPosition(checked);
+ setThumbPosition(isChecked());
invalidate();
}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 5be9899..f502de4 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -2203,6 +2203,27 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
/**
+ * Get the default {@link Locale} of the text in this TextView.
+ * @return the default {@link Locale} of the text in this TextView.
+ */
+ public Locale getTextLocale() {
+ return mTextPaint.getTextLocale();
+ }
+
+ /**
+ * Set the default {@link Locale} of the text in this TextView to the given value. This value
+ * is used to choose appropriate typefaces for ambiguous characters. Typically used for CJK
+ * locales to disambiguate Hanzi/Kanji/Hanja characters.
+ *
+ * @param locale the {@link Locale} for drawing text, must not be null.
+ *
+ * @see Paint#setTextLocale
+ */
+ public void setTextLocale(Locale locale) {
+ mTextPaint.setTextLocale(locale);
+ }
+
+ /**
* @return the size (in pixels) of the default text size in this TextView.
*/
@ViewDebug.ExportedProperty(category = "text")
diff --git a/core/java/android/widget/Toast.java b/core/java/android/widget/Toast.java
index 7dcbc3e..053ade7 100644
--- a/core/java/android/widget/Toast.java
+++ b/core/java/android/widget/Toast.java
@@ -30,7 +30,6 @@ import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
-import android.view.WindowManagerImpl;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
@@ -331,7 +330,7 @@ public class Toast {
View mView;
View mNextView;
- WindowManagerImpl mWM;
+ WindowManager mWM;
TN() {
// XXX This should be changed to use a Dialog, with a Theme.Toast
@@ -371,7 +370,7 @@ public class Toast {
// remove the old view if necessary
handleHide();
mView = mNextView;
- mWM = WindowManagerImpl.getDefault();
+ mWM = (WindowManager)mView.getContext().getSystemService(Context.WINDOW_SERVICE);
// We can resolve the Gravity here by using the Locale for getting
// the layout direction
final Configuration config = mView.getContext().getResources().getConfiguration();
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index e63c57f..bffbe11 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -150,7 +150,8 @@ public class ResolverActivity extends AlertActivity implements AdapterView.OnIte
resizeGrid();
} else if (count == 1) {
- startActivity(mAdapter.intentForPosition(0));
+ startActivityAsUser(mAdapter.intentForPosition(0),
+ new UserHandle(UserHandle.getUserId(mLaunchedFromUid)));
mPackageMonitor.unregister();
mRegistered = false;
finish();
@@ -363,12 +364,12 @@ public class ResolverActivity extends AlertActivity implements AdapterView.OnIte
if (r.match > bestMatch) bestMatch = r.match;
}
getPackageManager().addPreferredActivity(filter, bestMatch, set,
- intent.getComponent());
+ intent.getComponent(), UserHandle.getUserId(mLaunchedFromUid));
}
}
if (intent != null) {
- startActivity(intent);
+ startActivityAsUser(intent, new UserHandle(UserHandle.getUserId(mLaunchedFromUid)));
}
}
@@ -376,7 +377,7 @@ public class ResolverActivity extends AlertActivity implements AdapterView.OnIte
Intent in = new Intent().setAction("android.settings.APPLICATION_DETAILS_SETTINGS")
.setData(Uri.fromParts("package", ri.activityInfo.packageName, null))
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
- startActivity(in);
+ startActivityAsUser(in, new UserHandle(UserHandle.getUserId(mLaunchedFromUid)));
}
private final class DisplayResolveInfo {
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 6ad67c3..9e43749 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -16,16 +16,17 @@
package com.android.internal.os;
+import static libcore.io.OsConstants.S_IRWXG;
+import static libcore.io.OsConstants.S_IRWXO;
+
import android.content.pm.ActivityInfo;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.net.LocalServerSocket;
import android.os.Debug;
-import android.os.FileUtils;
import android.os.Process;
import android.os.SystemClock;
-import android.os.SystemProperties;
import android.util.EventLog;
import android.util.Log;
@@ -33,6 +34,7 @@ import dalvik.system.VMRuntime;
import dalvik.system.Zygote;
import libcore.io.IoUtils;
+import libcore.io.Libcore;
import java.io.BufferedReader;
import java.io.FileDescriptor;
@@ -452,7 +454,7 @@ public class ZygoteInit {
closeServerSocket();
// set umask to 0077 so new files and directories will default to owner-only permissions.
- FileUtils.setUMask(FileUtils.S_IRWXG | FileUtils.S_IRWXO);
+ Libcore.os.umask(S_IRWXG | S_IRWXO);
if (parsedArgs.niceName != null) {
Process.setArgV0(parsedArgs.niceName);
diff --git a/core/java/com/android/internal/view/RotationPolicy.java b/core/java/com/android/internal/view/RotationPolicy.java
index af512a3..98beadb 100644
--- a/core/java/com/android/internal/view/RotationPolicy.java
+++ b/core/java/com/android/internal/view/RotationPolicy.java
@@ -27,6 +27,7 @@ import android.provider.Settings;
import android.util.Log;
import android.view.IWindowManager;
import android.view.Surface;
+import android.view.WindowManagerGlobal;
/**
* Provides helper functions for configuring the display rotation policy.
@@ -79,8 +80,7 @@ public final class RotationPolicy {
@Override
public void run() {
try {
- IWindowManager wm = IWindowManager.Stub.asInterface(
- ServiceManager.getService(Context.WINDOW_SERVICE));
+ IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
if (enabled) {
wm.freezeRotation(-1);
} else {
@@ -107,8 +107,7 @@ public final class RotationPolicy {
@Override
public void run() {
try {
- IWindowManager wm = IWindowManager.Stub.asInterface(
- ServiceManager.getService(Context.WINDOW_SERVICE));
+ IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
if (enabled) {
wm.freezeRotation(Surface.ROTATION_0);
} else {
diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index a65262c..edc9732 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -22,6 +22,7 @@
#include "jni.h"
#include "GraphicsJNI.h"
#include <android_runtime/AndroidRuntime.h>
+#include <ScopedUtfChars.h>
#include "SkBlurDrawLooper.h"
#include "SkColorFilter.h"
@@ -30,6 +31,7 @@
#include "SkShader.h"
#include "SkTypeface.h"
#include "SkXfermode.h"
+#include "unicode/uloc.h"
#include "unicode/ushape.h"
#include "TextLayout.h"
@@ -254,11 +256,51 @@ public:
obj->setTextAlign(align);
}
+ // generate bcp47 identifier for the supplied locale
+ static void toLanguageTag(char* output, size_t outSize,
+ const char* locale) {
+ if (output == NULL || outSize <= 0) {
+ return;
+ }
+ if (locale == NULL) {
+ output[0] = '\0';
+ return;
+ }
+ char canonicalChars[ULOC_FULLNAME_CAPACITY];
+ UErrorCode uErr = U_ZERO_ERROR;
+ uloc_canonicalize(locale, canonicalChars, ULOC_FULLNAME_CAPACITY,
+ &uErr);
+ if (U_SUCCESS(uErr)) {
+ char likelyChars[ULOC_FULLNAME_CAPACITY];
+ uErr = U_ZERO_ERROR;
+ uloc_addLikelySubtags(canonicalChars, likelyChars,
+ ULOC_FULLNAME_CAPACITY, &uErr);
+ if (U_SUCCESS(uErr)) {
+ uErr = U_ZERO_ERROR;
+ uloc_toLanguageTag(likelyChars, output, outSize, FALSE, &uErr);
+ if (U_SUCCESS(uErr)) {
+ return;
+ } else {
+ ALOGD("uloc_toLanguageTag(\"%s\") failed: %s", likelyChars,
+ u_errorName(uErr));
+ }
+ } else {
+ ALOGD("uloc_addLikelySubtags(\"%s\") failed: %s",
+ canonicalChars, u_errorName(uErr));
+ }
+ } else {
+ ALOGD("uloc_canonicalize(\"%s\") failed: %s", locale,
+ u_errorName(uErr));
+ }
+ // unable to build a proper language identifier
+ output[0] = '\0';
+ }
+
static void setTextLocale(JNIEnv* env, jobject clazz, SkPaint* obj, jstring locale) {
- const char* localeArray = env->GetStringUTFChars(locale, NULL);
- SkString skLocale(localeArray);
- obj->setTextLocale(skLocale);
- env->ReleaseStringUTFChars(locale, localeArray);
+ ScopedUtfChars localeChars(env, locale);
+ char langTag[ULOC_FULLNAME_CAPACITY];
+ toLanguageTag(langTag, ULOC_FULLNAME_CAPACITY, localeChars.c_str());
+ obj->setLanguage(SkLanguage(langTag));
}
static jfloat getTextSize(JNIEnv* env, jobject paint) {
diff --git a/core/jni/android/graphics/TextLayoutCache.cpp b/core/jni/android/graphics/TextLayoutCache.cpp
index 9b9b991..7abfcf1 100644
--- a/core/jni/android/graphics/TextLayoutCache.cpp
+++ b/core/jni/android/graphics/TextLayoutCache.cpp
@@ -19,6 +19,7 @@
#include "TextLayoutCache.h"
#include "TextLayout.h"
#include "SkFontHost.h"
+#include "SkTypeface_android.h"
#include <unicode/unistr.h>
#include <unicode/normlzr.h>
#include <unicode/uchar.h>
@@ -224,7 +225,7 @@ void TextLayoutCache::dumpCacheStats() {
*/
TextLayoutCacheKey::TextLayoutCacheKey(): text(NULL), start(0), count(0), contextCount(0),
dirFlags(0), typeface(NULL), textSize(0), textSkewX(0), textScaleX(0), flags(0),
- hinting(SkPaint::kNo_Hinting) {
+ hinting(SkPaint::kNo_Hinting), variant(SkPaint::kDefault_Variant), language() {
}
TextLayoutCacheKey::TextLayoutCacheKey(const SkPaint* paint, const UChar* text,
@@ -237,6 +238,8 @@ TextLayoutCacheKey::TextLayoutCacheKey(const SkPaint* paint, const UChar* text,
textScaleX = paint->getTextScaleX();
flags = paint->getFlags();
hinting = paint->getHinting();
+ variant = paint->getFontVariant();
+ language = paint->getLanguage();
}
TextLayoutCacheKey::TextLayoutCacheKey(const TextLayoutCacheKey& other) :
@@ -251,7 +254,9 @@ TextLayoutCacheKey::TextLayoutCacheKey(const TextLayoutCacheKey& other) :
textSkewX(other.textSkewX),
textScaleX(other.textScaleX),
flags(other.flags),
- hinting(other.hinting) {
+ hinting(other.hinting),
+ variant(other.variant),
+ language(other.language) {
if (other.text) {
textCopy.setTo(other.text, other.contextCount);
}
@@ -288,6 +293,12 @@ int TextLayoutCacheKey::compare(const TextLayoutCacheKey& lhs, const TextLayoutC
deltaInt = lhs.dirFlags - rhs.dirFlags;
if (deltaInt) return (deltaInt);
+ deltaInt = lhs.variant - rhs.variant;
+ if (deltaInt) return (deltaInt);
+
+ if (lhs.language < rhs.language) return -1;
+ if (lhs.language > rhs.language) return +1;
+
return memcmp(lhs.getText(), rhs.getText(), lhs.contextCount * sizeof(UChar));
}
@@ -615,6 +626,8 @@ void TextLayoutShaper::computeRunValues(const SkPaint* paint, const UChar* chars
mShapingPaint.setTextScaleX(paint->getTextScaleX());
mShapingPaint.setFlags(paint->getFlags());
mShapingPaint.setHinting(paint->getHinting());
+ mShapingPaint.setFontVariant(paint->getFontVariant());
+ mShapingPaint.setLanguage(paint->getLanguage());
// Split the BiDi run into Script runs. Harfbuzz will populate the pos, length and script
// into the shaperItem
diff --git a/core/jni/android/graphics/TextLayoutCache.h b/core/jni/android/graphics/TextLayoutCache.h
index f007f9a..64b33a0 100644
--- a/core/jni/android/graphics/TextLayoutCache.h
+++ b/core/jni/android/graphics/TextLayoutCache.h
@@ -32,7 +32,7 @@
#include <SkTemplates.h>
#include <SkUtils.h>
#include <SkAutoKern.h>
-#include "SkTypeface_android.h"
+#include <SkLanguage.h>
#include <unicode/ubidi.h>
#include <unicode/ushape.h>
@@ -102,6 +102,8 @@ private:
SkScalar textScaleX;
uint32_t flags;
SkPaint::Hinting hinting;
+ SkPaint::FontVariant variant;
+ SkLanguage language;
inline const UChar* getText() const { return text ? text : textCopy.string(); }
diff --git a/core/jni/android_os_FileUtils.cpp b/core/jni/android_os_FileUtils.cpp
index 82bfc36..a07f5b7 100644
--- a/core/jni/android_os_FileUtils.cpp
+++ b/core/jni/android_os_FileUtils.cpp
@@ -55,11 +55,6 @@ jint android_os_FileUtils_setPermissions(JNIEnv* env, jobject clazz,
return chmod(file8.string(), mode) == 0 ? 0 : errno;
}
-jint android_os_FileUtils_setUMask(JNIEnv* env, jobject clazz, jint mask)
-{
- return umask(mask);
-}
-
jint android_os_FileUtils_getFatVolumeId(JNIEnv* env, jobject clazz, jstring path)
{
if (path == NULL) {
@@ -83,7 +78,6 @@ jint android_os_FileUtils_getFatVolumeId(JNIEnv* env, jobject clazz, jstring pat
static const JNINativeMethod methods[] = {
{"setPermissions", "(Ljava/lang/String;III)I", (void*)android_os_FileUtils_setPermissions},
- {"setUMask", "(I)I", (void*)android_os_FileUtils_setUMask},
{"getFatVolumeId", "(Ljava/lang/String;)I", (void*)android_os_FileUtils_getFatVolumeId},
};
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index 3ad6406..bada329 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -221,7 +221,7 @@ void setSurface(JNIEnv* env, jobject clazz, const sp<Surface>& surface)
static void Surface_init(
JNIEnv* env, jobject clazz,
jobject session,
- jint, jstring jname, jint dpy, jint w, jint h, jint format, jint flags)
+ jint, jstring jname, jint layerStack, jint w, jint h, jint format, jint flags)
{
if (session == NULL) {
doThrowNPE(env);
@@ -233,12 +233,12 @@ static void Surface_init(
sp<SurfaceControl> surface;
if (jname == NULL) {
- surface = client->createSurface(dpy, w, h, format, flags);
+ surface = client->createSurface(layerStack, w, h, format, flags);
} else {
const jchar* str = env->GetStringCritical(jname, 0);
const String8 name(str, env->GetStringLength(jname));
env->ReleaseStringCritical(jname, str);
- surface = client->createSurface(name, dpy, w, h, format, flags);
+ surface = client->createSurface(name, layerStack, w, h, format, flags);
}
if (surface == 0) {
@@ -717,7 +717,7 @@ static void Surface_setWindowCrop(JNIEnv* env, jobject thiz, jobject crop)
}
}
-static void Surface_setDisplayId(JNIEnv* env, jobject thiz, jint displayId)
+static void Surface_setLayerStack(JNIEnv* env, jobject thiz, jint layerStack)
{
const sp<SurfaceControl>& surface(getSurfaceControl(env, thiz));
if (surface == 0) return;
@@ -863,7 +863,7 @@ static JNINativeMethod gSurfaceMethods[] = {
{"writeToParcel", "(Landroid/os/Parcel;I)V", (void*)Surface_writeToParcel },
{"isConsumerRunningBehind", "()Z", (void*)Surface_isConsumerRunningBehind },
{"setWindowCrop", "(Landroid/graphics/Rect;)V", (void*)Surface_setWindowCrop },
- {"setDisplayId", "(I)V", (void*)Surface_setDisplayId },
+ {"setLayerStack", "(I)V", (void*)Surface_setLayerStack },
};
void nativeClassInit(JNIEnv* env, jclass clazz)
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index db862c8..ad03dd2 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -224,6 +224,10 @@
<string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Laat die program toe om aksies vir verskillende gebruikers op die toestel uit te voer. Kwaadwillige programme kan dit gebruik om die beskerming tussen gebruikers te skend."</string>
<string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"volle lisensie vir interaksie tussen gebruikers"</string>
<string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Laat alle moontlike interaksies tussen gebruikers toe."</string>
+ <!-- no translation found for permlab_manageUsers (1676150911672282428) -->
+ <skip />
+ <!-- no translation found for permdesc_manageUsers (8409306667645355638) -->
+ <skip />
<string name="permlab_getDetailedTasks" msgid="6229468674753529501">"haal besonderhede van lopende programme op"</string>
<string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Laat die program toe om inligting op te haal oor huidige en onlangse lopende take. Kwaadwillige programme kan dalk private inligting oor ander programme ontdek."</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"herrangskik lopende programme"</string>
@@ -1309,4 +1313,6 @@
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth-oudio"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Klaar"</string>
<string name="media_route_button_content_description" msgid="5758553567065145276">"Media-uitvoer"</string>
+ <!-- no translation found for display_manager_built_in_display (9042666544146043569) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index ef8f604..cb649e9 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -224,6 +224,10 @@
<string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"መተግበሪያው በመሣሪያው ላይ በተለያዩ ተጠቃሚዎች ላይ እርምጃዎችን እንዲፈጽም ይፈቅድለታል። ተንኮል-አዘል መተግበሪያዎች ይህንን ተጠቅመው በተጠቃሚዎች መካከል ያለውን ጥበቃ ሊጥሱ ይችላሉ።"</string>
<string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"በተለያዩ ተጠቃሚዎች መካከል መስተጋብር ለመፍጠር ሙሉ ፍቃድ"</string>
<string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"በተለያዩ ተጠቃሚዎች ላይ ሊኖሩ የሚችሉ መስተጋብሮችን ሁሉ ይፈቅዳል።"</string>
+ <!-- no translation found for permlab_manageUsers (1676150911672282428) -->
+ <skip />
+ <!-- no translation found for permdesc_manageUsers (8409306667645355638) -->
+ <skip />
<string name="permlab_getDetailedTasks" msgid="6229468674753529501">"እየሄዱ ስላሉ የመተግበሪያዎች ዝርዝሮች አምጣ"</string>
<string name="permdesc_getDetailedTasks" msgid="153824741440717599">"መተግበሪያው በአሁኑ ጊዜ እየተካሄዱ ስላሉና በቅርብ ጊዜ ስለተካሄዱ ተግባሮች መረጃ ዝርዝር እንዲያወጣ ይፈቅድለታል። ተንኮል-አዘል መተግበሪያዎች ስለ ሌሎች መተግበሪያዎች የግል መረጃ ሊያገኙ ይችላሉ።"</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"አሂድ ትግበራዎችን ድጋሚ ደርድር"</string>
@@ -1309,4 +1313,6 @@
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"የብሉቱዝ ድምጽ"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"ተከናውኗል"</string>
<string name="media_route_button_content_description" msgid="5758553567065145276">"የሚዲያ ውጽዓት"</string>
+ <!-- no translation found for display_manager_built_in_display (9042666544146043569) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 17f4dd1..14d95a5 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -224,6 +224,8 @@
<string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"للسماح للتطبيق بتنفيذ إجراءات بين مستخدمين مختلفين على الجهاز. قد تستخدم التطبيقات الضارة ذلك لانتهاك الحماية بين المستخدمين."</string>
<string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"الترخيص بالكامل للتعامل بين المستخدمين"</string>
<string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"للسماح بجميع التعاملات المحتملة بين المستخدمين."</string>
+ <string name="permlab_manageUsers" msgid="1676150911672282428">"إدارة المستخدمين"</string>
+ <string name="permdesc_manageUsers" msgid="8409306667645355638">"لتمكين التطبيقات من إدارة المستخدمين على الجهاز، بما في ذلك طلب البحث والإنشاء والحذف."</string>
<string name="permlab_getDetailedTasks" msgid="6229468674753529501">"استرداد تفاصيل التطبيقات قيد التشغيل"</string>
<string name="permdesc_getDetailedTasks" msgid="153824741440717599">"يسمح للتطبيق باسترداد معلومات تفصيلية حول المهام قيد التشغيل حاليًا ومؤخرًا. قد تكتشف التطبيقات الضارة معلومات خاصة حول التطبيقات الأخرى."</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"إعادة ترتيب التطبيقات قيد التشغيل"</string>
@@ -1309,4 +1311,6 @@
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"صوت بلوتوث"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"تم"</string>
<string name="media_route_button_content_description" msgid="5758553567065145276">"المنفذ الإعلامي"</string>
+ <!-- no translation found for display_manager_built_in_display (9042666544146043569) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index b9b6cf3..57d0d5c 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -224,6 +224,10 @@
<string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Дазваляе прыкладанню выконваць дзеяннi сярод розных карыстальнiкаў прылады. Шкоднасныя прыкладаннi могуць выкарыстоўваць гэта, каб парушыць абарону памiж карыстальнiкамi."</string>
<string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"поўная ліцэнзія для ўзаемадзеяння паміж карыстальнiкамi"</string>
<string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Дазваляе ўсе магчымыя ўзаемадзеяннi паміж карыстальнікамі."</string>
+ <!-- no translation found for permlab_manageUsers (1676150911672282428) -->
+ <skip />
+ <!-- no translation found for permdesc_manageUsers (8409306667645355638) -->
+ <skip />
<string name="permlab_getDetailedTasks" msgid="6229468674753529501">"атрымаць падрабязныя дадзеныя пра запушчаныя прыкладаннi"</string>
<string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Дазваляе прыкладанню атрымліваць падрабязную інфармацыю пра бягучыя і нядаўна запушчаныя задачы. Шкоднасныя прыкладанні могуць атрымліваць асабістую інфармацыю пра іншыя прыкладаннi."</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"змяніць парадак запушчаных прыкладанняў"</string>
@@ -1309,4 +1313,6 @@
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth-аўдыё"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Гатова"</string>
<string name="media_route_button_content_description" msgid="5758553567065145276">"Мультымедыйны выхад"</string>
+ <!-- no translation found for display_manager_built_in_display (9042666544146043569) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 6370ed4..d5c6268 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -224,6 +224,10 @@
<string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Разрешава на приложението да изпълнява действия за различни потребители на устройството. Злонамерените приложения може да използват това, за да нарушат защитата между потребителите."</string>
<string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"пълен лиценз за взаимодействие с потребителите"</string>
<string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Разрешава всички възможни взаимодействия с потребителите."</string>
+ <!-- no translation found for permlab_manageUsers (1676150911672282428) -->
+ <skip />
+ <!-- no translation found for permdesc_manageUsers (8409306667645355638) -->
+ <skip />
<string name="permlab_getDetailedTasks" msgid="6229468674753529501">"извличане на подробности за изпълняваните прилож."</string>
<string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Разрешава на приложението да извлича подробна информация за задачите, изпълнявани понастоящем и неотдавна. Злонамерените приложения могат да открият поверителна информация за други приложения."</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"пренареждане на изпълняваните приложения"</string>
@@ -1309,4 +1313,6 @@
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Звук през Bluetooth"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Готово"</string>
<string name="media_route_button_content_description" msgid="5758553567065145276">"Изходяща мултимедия"</string>
+ <!-- no translation found for display_manager_built_in_display (9042666544146043569) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 9c6cca1..1fac42f 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -224,6 +224,10 @@
<string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Permet que l\'aplicació dugui a terme accions en diferents usuaris del dispositiu. Les aplicacions malicioses poden fer servir aquest permís per infringir la protecció entre usuaris."</string>
<string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"llicència completa per interaccionar entre usuaris"</string>
<string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Permet totes les interaccions possibles entre usuaris."</string>
+ <!-- no translation found for permlab_manageUsers (1676150911672282428) -->
+ <skip />
+ <!-- no translation found for permdesc_manageUsers (8409306667645355638) -->
+ <skip />
<string name="permlab_getDetailedTasks" msgid="6229468674753529501">"recupera els detalls d\'aplicacions en execució"</string>
<string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Permet que l\'aplicació recuperi informació detallada sobre les tasques que s\'estan executant actualment i que s\'han executat recentment. Les aplicacions malicioses poden descobrir informació privada sobre altres aplicacions."</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"canvia l\'ordre de les aplicacions en execució"</string>
@@ -1309,4 +1313,6 @@
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Àudio per Bluetooth"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Fet"</string>
<string name="media_route_button_content_description" msgid="5758553567065145276">"Sortida de contingut multimèdia"</string>
+ <!-- no translation found for display_manager_built_in_display (9042666544146043569) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 898fe14..fc4e4c0 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -224,6 +224,8 @@
<string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Umožňuje aplikaci provádět akce napříč různými uživateli zařízení. Škodlivé aplikace toto oprávnění mohou zneužít k obejití ochrany mezi uživateli."</string>
<string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"úplné oprávnění k interakcím napříč uživateli"</string>
<string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Povoluje všechny možné interakce napříč uživateli."</string>
+ <string name="permlab_manageUsers" msgid="1676150911672282428">"správa uživatelů"</string>
+ <string name="permdesc_manageUsers" msgid="8409306667645355638">"Umožňuje aplikacím spravovat uživatele v zařízení, včetně vytváření a mazání dotazů."</string>
<string name="permlab_getDetailedTasks" msgid="6229468674753529501">"získání podrobností o spuštěných aplikacích"</string>
<string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Umožňuje aplikaci získat podrobné informace o aktuálně a naposledy spuštěných úlohách. Škodlivé aplikace mohou odhalit soukromé informace o ostatních aplikacích."</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"změna uspořádání spuštěných aplikací"</string>
@@ -1309,4 +1311,6 @@
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth Audio"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Hotovo"</string>
<string name="media_route_button_content_description" msgid="5758553567065145276">"Výstup médií"</string>
+ <!-- no translation found for display_manager_built_in_display (9042666544146043569) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 9ccf3f0..471feaf 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -224,6 +224,10 @@
<string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Tillader, at appen udfører handlinger på tværs af forskellige brugere på enheden. Ondsindede apps kan bruge dette til at krænke beskyttelsen mellem brugere."</string>
<string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"fuld licens til at kommunikere på tværs af brugere"</string>
<string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Tillader alle mulige former for kommunikation på tværs af brugere."</string>
+ <!-- no translation found for permlab_manageUsers (1676150911672282428) -->
+ <skip />
+ <!-- no translation found for permdesc_manageUsers (8409306667645355638) -->
+ <skip />
<string name="permlab_getDetailedTasks" msgid="6229468674753529501">"hente oplysninger om apps, der kører"</string>
<string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Tillader, at appen kan hente oplysninger om aktuelle og seneste opgaver. Ondsindede apps kan muligvis finde personlige oplysninger om andre apps."</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"omorganisere kørende apps"</string>
@@ -1309,4 +1313,6 @@
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth-lyd"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Udfør"</string>
<string name="media_route_button_content_description" msgid="5758553567065145276">"Medieudgang"</string>
+ <!-- no translation found for display_manager_built_in_display (9042666544146043569) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index f72d625..4ce86bb 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -224,6 +224,10 @@
<string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Ermöglicht der App, auf dem Gerät nutzerübergreifend Aktionen durchzuführen. Schädliche Apps können so den zwischen den Nutzern bestehenden Schutz aufheben."</string>
<string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"Vollständige Lizenz zum nutzerübergreifenden Interagieren"</string>
<string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Ermöglicht alle möglichen nutzerübergreifenden Interaktionen"</string>
+ <!-- no translation found for permlab_manageUsers (1676150911672282428) -->
+ <skip />
+ <!-- no translation found for permdesc_manageUsers (8409306667645355638) -->
+ <skip />
<string name="permlab_getDetailedTasks" msgid="6229468674753529501">"Details zu ausgeführten Apps abrufen"</string>
<string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Ermöglicht der App, detaillierte Informationen zu aktuellen und kürzlich ausgeführten Aufgaben abzurufen. Schädliche Apps können so geheime Informationen zu anderen Apps erhalten."</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"Aktive Apps neu ordnen"</string>
@@ -1309,4 +1313,6 @@
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth-Audio"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Fertig"</string>
<string name="media_route_button_content_description" msgid="5758553567065145276">"Medienausgabe"</string>
+ <!-- no translation found for display_manager_built_in_display (9042666544146043569) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 95717a2..e12440f 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -224,6 +224,10 @@
<string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Δίνει στην εφαρμογή τη δυνατότητα να πραγματοποιεί ενέργειες σε όλους τους διαφορετικούς χρήστες στη συσκευή. Οι κακόβουλες εφαρμογές ενδέχεται να χρησιμοποιήσουν αυτή τη δυνατότητα για να παραβιάσουν την προστασία μεταξύ των χρηστών."</string>
<string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"πλήρης άδεια αλληλεπίδρασης στους χρήστες"</string>
<string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Επιτρέπει όλες τις πιθανές αλληλεπιδράσεις στους χρήστες."</string>
+ <!-- no translation found for permlab_manageUsers (1676150911672282428) -->
+ <skip />
+ <!-- no translation found for permdesc_manageUsers (8409306667645355638) -->
+ <skip />
<string name="permlab_getDetailedTasks" msgid="6229468674753529501">"ανάκτηση λεπτομερειών σχετικά με τις εκτελούμενες εφαρμογές"</string>
<string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Επιτρέπει στην εφαρμογή την ανάκτηση λεπτομερών πληροφοριών σχετικά με τις τρέχουσες εκτελούμενες εργασίες και τις εργασίες που έχουν εκτελεστεί πρόσφατα. Τυχόν κακόβουλες εφαρμογές ενδέχεται να ανακαλύψουν ιδιωτικές πληροφορίες σχετικά με άλλες εφαρμογές."</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"αναδιάταξη εκτελούμενων εφαρμογών"</string>
@@ -1309,4 +1313,6 @@
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Ήχος Bluetooth"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Τέλος"</string>
<string name="media_route_button_content_description" msgid="5758553567065145276">"Έξοδος μέσων"</string>
+ <!-- no translation found for display_manager_built_in_display (9042666544146043569) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index eaa3578..90477aa 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -224,6 +224,10 @@
<string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Allows the app to perform actions across different users on the device. Malicious apps may use this to violate the protection between users."</string>
<string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"full license to interact across users"</string>
<string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Allows all possible interactions across users."</string>
+ <!-- no translation found for permlab_manageUsers (1676150911672282428) -->
+ <skip />
+ <!-- no translation found for permdesc_manageUsers (8409306667645355638) -->
+ <skip />
<string name="permlab_getDetailedTasks" msgid="6229468674753529501">"retrieve details of running apps"</string>
<string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Allows the app to retrieve detailed information about currently and recently running tasks. Malicious apps may discover private information about other apps."</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"re-order running apps"</string>
@@ -1309,4 +1313,6 @@
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth audio"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Done"</string>
<string name="media_route_button_content_description" msgid="5758553567065145276">"Media output"</string>
+ <!-- no translation found for display_manager_built_in_display (9042666544146043569) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index b589afb..785f537 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -224,6 +224,10 @@
<string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Permite que la aplicación lleve a cabo acciones entre los diferentes usuarios del dispositivo. Las aplicaciones maliciosas pueden utilizar este permiso para infringir la protección entre usuarios."</string>
<string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"Licencia completa para interactuar con los usuarios"</string>
<string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Permite todas las interacciones posibles con los usuarios."</string>
+ <!-- no translation found for permlab_manageUsers (1676150911672282428) -->
+ <skip />
+ <!-- no translation found for permdesc_manageUsers (8409306667645355638) -->
+ <skip />
<string name="permlab_getDetailedTasks" msgid="6229468674753529501">"recuperar información sobre las aplicaciones en ejecución"</string>
<string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Permite que la aplicación recupere información detallada sobre tareas en ejecución y recientemente ejecutadas. Las aplicaciones malintencionadas pueden hallar información privada sobre otras aplicaciones."</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"reorganizar aplicaciones en ejecución"</string>
@@ -1309,4 +1313,6 @@
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Audio Bluetooth"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Listo"</string>
<string name="media_route_button_content_description" msgid="5758553567065145276">"Salida multimedia"</string>
+ <!-- no translation found for display_manager_built_in_display (9042666544146043569) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index ec7bbb2..9e43161 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -224,6 +224,10 @@
<string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Permite que la aplicación lleve a cabo acciones entre los diferentes usuarios del dispositivo. Las aplicaciones maliciosas pueden utilizar este permiso para infringir la protección entre usuarios."</string>
<string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"licencia completa para interactuar con los usuarios"</string>
<string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Permite que la aplicación interactúe con los usuarios."</string>
+ <!-- no translation found for permlab_manageUsers (1676150911672282428) -->
+ <skip />
+ <!-- no translation found for permdesc_manageUsers (8409306667645355638) -->
+ <skip />
<string name="permlab_getDetailedTasks" msgid="6229468674753529501">"recuperar información de aplicaciones en ejecución"</string>
<string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Permite que la aplicación recupere información sobre tareas que se están ejecutando en este momento o que se han ejecutado recientemente. Las aplicaciones malintencionadas pueden usar este servicio para acceder a información privada sobre otras aplicaciones."</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"reorganizar aplicaciones en ejecución"</string>
@@ -1309,4 +1313,6 @@
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Audio Bluetooth"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Fin"</string>
<string name="media_route_button_content_description" msgid="5758553567065145276">"Salida multimedia"</string>
+ <!-- no translation found for display_manager_built_in_display (9042666544146043569) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 957e941..459ec02 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -224,6 +224,10 @@
<string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Lubab rakendusel teha toiminguid seadme erinevatel kasutajakontodel. Pahatahtlikud rakendused võivad kasutada seda kasutajatevahelise kaitse rikkumiseks."</string>
<string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"täielik litsents teha toiminguid erinevatel kasutajakontodel"</string>
<string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Lubab kõiki võimalikke toiminguid erinevatel kasutajakontodel."</string>
+ <!-- no translation found for permlab_manageUsers (1676150911672282428) -->
+ <skip />
+ <!-- no translation found for permdesc_manageUsers (8409306667645355638) -->
+ <skip />
<string name="permlab_getDetailedTasks" msgid="6229468674753529501">"töötavate rakenduste üksikasjade toomine"</string>
<string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Võimaldab rakendusel tuua üksikasjalikku teavet praegu töötavate ja hiljuti käitatud ülesannete kohta. Pahatahtlikud rakendused võivad tuvastada privaatset teavet muude rakenduste kohta."</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"käitatud rakenduste ümberjärjestamine"</string>
@@ -1309,4 +1313,6 @@
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth-heli"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Valmis"</string>
<string name="media_route_button_content_description" msgid="5758553567065145276">"Meediaväljund"</string>
+ <!-- no translation found for display_manager_built_in_display (9042666544146043569) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 6f99078..ecdebe8 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -224,6 +224,8 @@
<string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"به برنامه اجازه می‌دهد اقداماتی در بین کاربران مختلف در دستگاه انجام دهد. ممکن است برنامه‌های مخرب از این قابلیت برای نقض حفاظت موجود در بین کاربران استفاده کنند."</string>
<string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"مجوز کامل برای ارتباط بین کاربران"</string>
<string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"اجازه می‌دهد همه ارتباطات ممکن بین کاربران انجام شود."</string>
+ <string name="permlab_manageUsers" msgid="1676150911672282428">"مدیریت کاربران"</string>
+ <string name="permdesc_manageUsers" msgid="8409306667645355638">"به برنامه‌ها اجازه می‌دهد مدیریت کاربران، از قبیل پرسش، ایجاد و حذف کاربران، را در دستگاه انجام دهند."</string>
<string name="permlab_getDetailedTasks" msgid="6229468674753529501">"بازیابی جزئیات برنامه‌های در حال اجرا"</string>
<string name="permdesc_getDetailedTasks" msgid="153824741440717599">"به برنامه اجازه می‎دهد تا اطلاعات مفصلی مربوط به کارهایی که در حال حاضر و اخیراً اجرا می‎شوند را بازیابی کند. برنامه‎های مخرب می‎توانند اطلاعات شخصی مربوط به برنامه‎های دیگر را پیدا کنند."</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"تنظیم مجدد ترتیب برنامه‎های در حال اجرا"</string>
@@ -1309,4 +1311,6 @@
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"بلوتوث‌های صوتی"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"انجام شد"</string>
<string name="media_route_button_content_description" msgid="5758553567065145276">"خروجی رسانه"</string>
+ <!-- no translation found for display_manager_built_in_display (9042666544146043569) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index e06dfcc..0542261 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -224,6 +224,10 @@
<string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Antaa sovelluksen suorittaa käyttäjien välisiä toimintoja laitteessa. Haitalliset sovellukset voivat vahingoittaa käyttäjien välistä suojausta."</string>
<string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"lupa suorittaa käyttäjien välisiä toimintoja"</string>
<string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Sallii kaikki käyttäjien väliset toiminnot."</string>
+ <!-- no translation found for permlab_manageUsers (1676150911672282428) -->
+ <skip />
+ <!-- no translation found for permdesc_manageUsers (8409306667645355638) -->
+ <skip />
<string name="permlab_getDetailedTasks" msgid="6229468674753529501">"hae tiedot suoritettavista sovelluksista"</string>
<string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Antaa sovellukselle oikeuden noutaa käynnissä oleviin ja käynnissä olleisiin tehtäviin liittyviä tietoja. Haitalliset sovellukset saattavat saada näin muihin sovelluksiin liittyviä yksityisiä tietoja."</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"käynnissä olevien sovellusten järjesteleminen"</string>
@@ -1309,4 +1313,6 @@
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth-ääni"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Valmis"</string>
<string name="media_route_button_content_description" msgid="5758553567065145276">"Median äänentoisto"</string>
+ <!-- no translation found for display_manager_built_in_display (9042666544146043569) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index e98000a..e6eeace 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -224,6 +224,10 @@
<string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Permet à l\'application d\'effectuer des actions entre les différents utilisateurs de l\'appareil. Les applications malveillantes peuvent utiliser cette autorisation pour passer outre la protection entre les utilisateurs."</string>
<string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"autorisation totale d\'interagir entre les utilisateurs"</string>
<string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Permet toutes les interactions possibles entre les utilisateurs."</string>
+ <!-- no translation found for permlab_manageUsers (1676150911672282428) -->
+ <skip />
+ <!-- no translation found for permdesc_manageUsers (8409306667645355638) -->
+ <skip />
<string name="permlab_getDetailedTasks" msgid="6229468674753529501">"récupérer les détails des applications en cours d\'exécution"</string>
<string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Permet à l\'application de récupérer des informations détaillées sur les tâches en cours d\'exécution ou récemment exécutées. Des applications malveillantes peuvent utiliser cette fonctionnalité pour obtenir des informations confidentielles relatives à d\'autres applications."</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"réorganiser les applications en cours d\'exécution"</string>
@@ -1309,4 +1313,6 @@
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Audio Bluetooth"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"OK"</string>
<string name="media_route_button_content_description" msgid="5758553567065145276">"Sortie multimédia"</string>
+ <!-- no translation found for display_manager_built_in_display (9042666544146043569) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index cf8fa01..f9f54cb 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -224,6 +224,10 @@
<string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"एप्लिकेशन को उपकरण पर भिन्न उपयोगकर्ताओं के बीच कार्य निष्पादित करने देता है. दुर्भावनापूर्ण एप्लिकेशन उपयोगकर्ताओं के बीच सुरक्षा का उल्लंघन करने के लिए इसका उपयोग कर सकते हैं."</string>
<string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"उपयोगकर्ताओं के बीच सहभागिता करने के लिए पूर्ण लाइसेंस"</string>
<string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"उपयोगकर्ताओं के बीच सभी संभव सहभागिता करने देता है."</string>
+ <!-- no translation found for permlab_manageUsers (1676150911672282428) -->
+ <skip />
+ <!-- no translation found for permdesc_manageUsers (8409306667645355638) -->
+ <skip />
<string name="permlab_getDetailedTasks" msgid="6229468674753529501">"चल रहे एप्‍लिकेशन के विवरण प्राप्त करें"</string>
<string name="permdesc_getDetailedTasks" msgid="153824741440717599">"एप्लिकेशन को वर्तमान में और हाल ही में चल रहे कार्यों की जानकारी प्राप्त करने देता है. दुर्भावनापूर्ण एप्लिकेशन अन्य एप्लिकेशन के बारे में निजी जानकारी खोज सकते हैं."</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"चल रहे एप्‍लिकेशन पुन: क्रमित करें"</string>
@@ -1309,4 +1313,6 @@
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth ऑडियो"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"पूर्ण"</string>
<string name="media_route_button_content_description" msgid="5758553567065145276">"मीडिया आउटपुट"</string>
+ <!-- no translation found for display_manager_built_in_display (9042666544146043569) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 2029530..b25ed2b 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -224,6 +224,10 @@
<string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Omogućuje aplikaciji izvršavanje radnji među korisnicima na uređaju. Zlonamjerne aplikacije mogu to iskoristiti za narušavanje zaštite među korisnicima."</string>
<string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"dozvola za potpunu interakciju među korisnicima"</string>
<string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Omogućuje sve moguće interakcije među korisnicima."</string>
+ <!-- no translation found for permlab_manageUsers (1676150911672282428) -->
+ <skip />
+ <!-- no translation found for permdesc_manageUsers (8409306667645355638) -->
+ <skip />
<string name="permlab_getDetailedTasks" msgid="6229468674753529501">"dohvaćanje pojedinosti o pokrenutim aplikacijama"</string>
<string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Aplikaciji omogućuje dohvaćanje detaljnih informacija o trenutačno i nedavno pokrenutim zadacima. Zlonamjerne aplikacije mogu otkriti privatne informacije o drugim aplikacijama."</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"promjena redoslijeda pokrenutih aplikacija"</string>
@@ -1309,4 +1313,6 @@
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth zvuk"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Gotovo"</string>
<string name="media_route_button_content_description" msgid="5758553567065145276">"Medijski izlaz"</string>
+ <!-- no translation found for display_manager_built_in_display (9042666544146043569) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 421c5be..2f048de 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -224,6 +224,10 @@
<string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Lehetővé teszi az alkalmazás számára, hogy több felhasználó között végezzen különféle műveleteket az eszközön. A rosszindulatú alkalmazások arra használhatják ezt, hogy megsértsék a felhasználók biztonságát."</string>
<string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"teljes licenc a felhasználók közötti interakcióhoz"</string>
<string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Lehetővé teszi az összes lehetséges interakciót a felhasználók között."</string>
+ <!-- no translation found for permlab_manageUsers (1676150911672282428) -->
+ <skip />
+ <!-- no translation found for permdesc_manageUsers (8409306667645355638) -->
+ <skip />
<string name="permlab_getDetailedTasks" msgid="6229468674753529501">"futó alkalmazások részleteinek lekérése"</string>
<string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Lehetővé teszi az alkalmazás számára a jelenleg és a nemrég futó feladatok részletes adatainak lekérését. A rosszindulatú alkalmazások más alkalmazásokkal kapcsolatos privát adatokhoz férhetnek hozzá."</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"futó alkalmazások átrendezése"</string>
@@ -1309,4 +1313,6 @@
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth hang"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Kész"</string>
<string name="media_route_button_content_description" msgid="5758553567065145276">"Médiakimenet"</string>
+ <!-- no translation found for display_manager_built_in_display (9042666544146043569) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index ef759e0..9c7841f 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -224,6 +224,10 @@
<string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Mengizinkan aplikasi melakukan tindakan antar-pengguna yang berbeda pada perangkat. Aplikasi berbahaya dapat menggunakan ini untuk mengganggu perlindungan antar-pengguna."</string>
<string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"lisensi penuh untuk berinteraksi antar-pengguna"</string>
<string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Mengizinkan semua interaksi yang mungkin antar-pengguna."</string>
+ <!-- no translation found for permlab_manageUsers (1676150911672282428) -->
+ <skip />
+ <!-- no translation found for permdesc_manageUsers (8409306667645355638) -->
+ <skip />
<string name="permlab_getDetailedTasks" msgid="6229468674753529501">"mengambil detail aplikasi yang sedang berjalan"</string>
<string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Izinkan aplikasi mengambil informasi mendetail tentang tugas yang saat ini dan baru-baru ini dijalankan. Aplikasi berbahaya dapat menemukan informasi pribadi tentang aplikasi lain."</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"menyusun ulang apl yang berjalan"</string>
@@ -1309,4 +1313,6 @@
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Audio Bluetooth"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Selesai"</string>
<string name="media_route_button_content_description" msgid="5758553567065145276">"Keluaran media"</string>
+ <!-- no translation found for display_manager_built_in_display (9042666544146043569) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 5f64c20..6388fcf 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -224,6 +224,10 @@
<string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Consente all\'applicazione di compiere azioni per diversi utenti sul dispositivo. Le applicazioni dannose potrebbero farne uso per violare la protezione tra utenti."</string>
<string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"licenza completa per l\'interazione tra utenti"</string>
<string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Consente tutte le interazioni possibili tra gli utenti."</string>
+ <!-- no translation found for permlab_manageUsers (1676150911672282428) -->
+ <skip />
+ <!-- no translation found for permdesc_manageUsers (8409306667645355638) -->
+ <skip />
<string name="permlab_getDetailedTasks" msgid="6229468674753529501">"recupero dettagli applicazioni in esecuzione"</string>
<string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Consente all\'applicazione di recuperare informazioni dettagliate sulle attività attualmente e recentemente in esecuzione. Le applicazioni dannose potrebbero scoprire informazioni riservate su altre applicazioni."</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"riordinamento applicazioni in esecuzione"</string>
@@ -1309,4 +1313,6 @@
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Audio Bluetooth"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Fine"</string>
<string name="media_route_button_content_description" msgid="5758553567065145276">"Uscita media"</string>
+ <!-- no translation found for display_manager_built_in_display (9042666544146043569) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 5432f26..ea504f4 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -224,6 +224,8 @@
<string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"מאפשר ליישום לבצע פעולות בין משתמשים שונים במכשיר. יישומים זדוניים עשויים להשתמש ביכולת זו כדי לפרוץ את ההגנה בין משתמשים."</string>
<string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"רישיון מלא לבצע אינטראקציה בין משתמשים"</string>
<string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"מאפשר את כל האינטראקציות האפשריות בין משתמשים."</string>
+ <string name="permlab_manageUsers" msgid="1676150911672282428">"נהל משתמשים"</string>
+ <string name="permdesc_manageUsers" msgid="8409306667645355638">"מאפשר ליישומים לנהל משתמשים במכשיר, כולל שאילתה, יצירה ומחיקה."</string>
<string name="permlab_getDetailedTasks" msgid="6229468674753529501">"אחזור פרטי יישומים פועלים"</string>
<string name="permdesc_getDetailedTasks" msgid="153824741440717599">"מאפשר ליישום לאחזר מידע מפורט על המשימות הנוכחיות הפועלות ועל משימות שפעלו לאחרונה. יישומים זדוניים עלולים לגלות מידע אישי על יישומים אחרים."</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"סידור מחדש של יישומים פעילים"</string>
@@ -1309,4 +1311,6 @@
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"אודיו Bluetooth"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"סיום"</string>
<string name="media_route_button_content_description" msgid="5758553567065145276">"פלט מדיה"</string>
+ <!-- no translation found for display_manager_built_in_display (9042666544146043569) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index f8ab2bf..e94ee54 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -224,6 +224,10 @@
<string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"端末上の各ユーザーに対して操作を実行することをアプリに許可します。この許可を悪意のあるアプリに利用されると、ユーザー間の保護が侵害される恐れがあります。"</string>
<string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"ユーザー間で交流するための完全ライセンス"</string>
<string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"ユーザー間の交流をすべて許可します。"</string>
+ <!-- no translation found for permlab_manageUsers (1676150911672282428) -->
+ <skip />
+ <!-- no translation found for permdesc_manageUsers (8409306667645355638) -->
+ <skip />
<string name="permlab_getDetailedTasks" msgid="6229468674753529501">"実行中のアプリの詳細の取得"</string>
<string name="permdesc_getDetailedTasks" msgid="153824741440717599">"現在実行中のタスクまたは最近実行したタスクに関する情報の取得をアプリに許可します。この許可を悪意のあるアプリに利用されると、他のアプリに関する非公開情報が読み取られる恐れがあります。"</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"実行中のアプリの順序変更"</string>
@@ -1309,4 +1313,6 @@
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth音声"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"完了"</string>
<string name="media_route_button_content_description" msgid="5758553567065145276">"メディア出力"</string>
+ <!-- no translation found for display_manager_built_in_display (9042666544146043569) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index ec301a4..d740602 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -224,6 +224,10 @@
<string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"앱이 기기에서 다양한 사용자에 대한 작업을 수행할 수 있도록 허용합니다. 이 경우 악성 앱이 사용자 간의 보호를 위반할 수 있습니다."</string>
<string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"여러 사용자와의 상호작용을 위한 정식 라이센스"</string>
<string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"여러 사용자와의 가능한 모든 상호작용을 허용합니다."</string>
+ <!-- no translation found for permlab_manageUsers (1676150911672282428) -->
+ <skip />
+ <!-- no translation found for permdesc_manageUsers (8409306667645355638) -->
+ <skip />
<string name="permlab_getDetailedTasks" msgid="6229468674753529501">"실행 중인 앱 세부정보 검색"</string>
<string name="permdesc_getDetailedTasks" msgid="153824741440717599">"앱이 현재 실행 중이거나 최근에 실행된 작업에 대한 상세한 정보를 검색할 수 있도록 허용합니다. 이 경우 악성 앱이 다른 앱에 대한 개인 정보를 검색할 수 있습니다."</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"실행 중인 앱 순서 재지정"</string>
@@ -1309,4 +1313,6 @@
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"블루투스 오디오"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"완료"</string>
<string name="media_route_button_content_description" msgid="5758553567065145276">"미디어 출력"</string>
+ <!-- no translation found for display_manager_built_in_display (9042666544146043569) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 7f44e81..9f95d17 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -224,6 +224,10 @@
<string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Leidžiama programai atlikti veiksmus skirtingų įrenginio naudotojų profiliuose. Kenkėjiškos programos gali pasinaudoti šiuo leidimu, kad pažeistų naudotojų saugumą."</string>
<string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"visa licencija, leidžianti sąveikauti su naudotojais"</string>
<string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Leidžiama bet kokia sąveika tarp naudotojų."</string>
+ <!-- no translation found for permlab_manageUsers (1676150911672282428) -->
+ <skip />
+ <!-- no translation found for permdesc_manageUsers (8409306667645355638) -->
+ <skip />
<string name="permlab_getDetailedTasks" msgid="6229468674753529501">"nuskaityti veikiančių programų išsamią informaciją"</string>
<string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Leidžiama programai nuskaityti išsamią informaciją apie šiuo ir pastaruoju metu vykdomas užduotis. Kenkėjiškos programos gali surasti privačios informacijos apie kitas programas."</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"pertvarkyti vykdomas programas"</string>
@@ -1309,4 +1313,6 @@
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"„Bluetooth“ garsas"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Atlikta"</string>
<string name="media_route_button_content_description" msgid="5758553567065145276">"Medijos išvestis"</string>
+ <!-- no translation found for display_manager_built_in_display (9042666544146043569) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 1d46ccb..a41e397 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -224,6 +224,10 @@
<string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Ļauj lietotnei veikt darbības vairāku ierīces lietotāju kontos. Ļaunprātīgas lietotnes var izmantot šo atļauju, lai apdraudētu lietotāju kontu drošību."</string>
<string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"pilna licence ar atļauju darboties visos lietotāju kontos"</string>
<string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Ļauj veikt jebkādas darbības visos lietotāju kontos."</string>
+ <!-- no translation found for permlab_manageUsers (1676150911672282428) -->
+ <skip />
+ <!-- no translation found for permdesc_manageUsers (8409306667645355638) -->
+ <skip />
<string name="permlab_getDetailedTasks" msgid="6229468674753529501">"Informācijas izguve par izmantotajām lietotnēm"</string>
<string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Ļauj lietotnei izgūt informāciju par šobrīd un nesen veiktajiem uzdevumiem. Ļaunprātīgas lietotnes var atklāt privātu informāciju par citām lietotnēm."</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"pārkārtot izmantotās lietotnes"</string>
@@ -1309,4 +1313,6 @@
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth audio"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Gatavs"</string>
<string name="media_route_button_content_description" msgid="5758553567065145276">"Multivides izeja"</string>
+ <!-- no translation found for display_manager_built_in_display (9042666544146043569) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 5bbebc5..a22ff51 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -224,6 +224,8 @@
<string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Membenarkan apl melakukan tindakan merentasi pengguna berbeza pada peranti. Apl hasad boleh menggunakan ini untuk melanggar perlindungan antara pengguna."</string>
<string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"lesen penuh untuk berinteraksi sesama pengguna"</string>
<string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Membenarkan semua interaksi yang mungkin sesama pengguna."</string>
+ <string name="permlab_manageUsers" msgid="1676150911672282428">"urus pengguna"</string>
+ <string name="permdesc_manageUsers" msgid="8409306667645355638">"Membenarkan apl mengurus pengguna pada peranti ini, termasuk pertanyaan, pembuatan dan pemadaman."</string>
<string name="permlab_getDetailedTasks" msgid="6229468674753529501">"dapatkan butiran apl yang berjalan"</string>
<string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Membenarkan apl untuk mendapatkan maklumat terperinci tentang tugasan yang sedang dan baru berjalan. Apl hasad boleh mendapat maklumat peribadi tentang apl lain."</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"susun semula tertib apl yang dijalankan"</string>
@@ -1309,4 +1311,6 @@
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Audio Bluetooth"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Selesai"</string>
<string name="media_route_button_content_description" msgid="5758553567065145276">"Output media"</string>
+ <!-- no translation found for display_manager_built_in_display (9042666544146043569) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 68f8918..bda2d01 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -224,6 +224,10 @@
<string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Tillater at appen utfører handlinger på tvers av ulike brukere på enheten. Skadelige apper kan utnytte dette til å bryte beskyttelsen mellom brukere."</string>
<string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"full lisens til å samhandle på tvers av brukere"</string>
<string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Tillater alle mulige samhandlinger på tvers av brukere."</string>
+ <!-- no translation found for permlab_manageUsers (1676150911672282428) -->
+ <skip />
+ <!-- no translation found for permdesc_manageUsers (8409306667645355638) -->
+ <skip />
<string name="permlab_getDetailedTasks" msgid="6229468674753529501">"hente informasjon om apper som kjører"</string>
<string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Tillater at appen henter ut informasjon om oppgaver som kjører eller nylig har kjørt. Skadelige apper kan bruke dette til å oppdage privat informasjon om andre apper."</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"Endre rekkefølge på apper som kjører"</string>
@@ -1309,4 +1313,6 @@
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth-lyd"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Fullført"</string>
<string name="media_route_button_content_description" msgid="5758553567065145276">"Medieutgang"</string>
+ <!-- no translation found for display_manager_built_in_display (9042666544146043569) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 985da7e..f8c2a7c 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -224,6 +224,10 @@
<string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Hiermee kan de app acties uitvoeren voor verschillende gebruikers van het apparaat. Schadelijke apps kunnen dit gebruiken om de beveiliging tussen gebruikers te schenden."</string>
<string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"volledige toestemming voor interactie tussen gebruikers"</string>
<string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Hiermee is alle mogelijke interactie tussen gebruikers toegestaan."</string>
+ <!-- no translation found for permlab_manageUsers (1676150911672282428) -->
+ <skip />
+ <!-- no translation found for permdesc_manageUsers (8409306667645355638) -->
+ <skip />
<string name="permlab_getDetailedTasks" msgid="6229468674753529501">"details van actieve apps ophalen"</string>
<string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Hiermee kan de app gedetailleerde informatie over huidige en recent uitgevoerde taken ophalen. Schadelijke apps kunnen op deze manier mogelijk privé-informatie over andere apps achterhalen."</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"actieve apps opnieuw rangschikken"</string>
@@ -1309,4 +1313,6 @@
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth-audio"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Gereed"</string>
<string name="media_route_button_content_description" msgid="5758553567065145276">"Media-uitvoer"</string>
+ <!-- no translation found for display_manager_built_in_display (9042666544146043569) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 19f317d..5a62f56 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -224,6 +224,10 @@
<string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Umożliwia aplikacji wykonywanie działań dotyczących różnych użytkowników urządzenia. Złośliwe aplikacje mogą to wykorzystać do złamania zabezpieczeń na kontach użytkowników."</string>
<string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"pełna licencja na interakcje między użytkownikami"</string>
<string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Zezwala na wszystkie możliwe interakcje między użytkownikami."</string>
+ <!-- no translation found for permlab_manageUsers (1676150911672282428) -->
+ <skip />
+ <!-- no translation found for permdesc_manageUsers (8409306667645355638) -->
+ <skip />
<string name="permlab_getDetailedTasks" msgid="6229468674753529501">"Pobieraj informacje o uruchomionych aplikacjach"</string>
<string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Zezwala aplikacji na pobieranie informacji o obecnie i ostatnio uruchomionych zadaniach. Złośliwe aplikacje mogą uzyskać dostęp do prywatnych informacji na temat innych aplikacji."</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"zmienianie kolejności uruchomionych aplikacji"</string>
@@ -1309,4 +1313,6 @@
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Dźwięk Bluetooth"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Gotowe"</string>
<string name="media_route_button_content_description" msgid="5758553567065145276">"Wyjście multimediów"</string>
+ <!-- no translation found for display_manager_built_in_display (9042666544146043569) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 788d1a2..6ec70b5 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -224,6 +224,10 @@
<string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Permite que a aplicação execute ações com diferentes utilizadores no dispositivo. Aplicações maliciosas poderão utilizar esta opção para violar a proteção entre utilizadores."</string>
<string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"licença completa para interagir entre utilizadores"</string>
<string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Permite todas as interações possíveis entre utilizadores."</string>
+ <!-- no translation found for permlab_manageUsers (1676150911672282428) -->
+ <skip />
+ <!-- no translation found for permdesc_manageUsers (8409306667645355638) -->
+ <skip />
<string name="permlab_getDetailedTasks" msgid="6229468674753529501">"obter detalhes das aplicações em execução"</string>
<string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Permite à aplicação obter informações detalhadas sobre tarefas atualmente em execução e recentemente executadas. As aplicações maliciosas poderão descobrir informações privadas de outras aplicações."</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"reordenar as aplicações em execução"</string>
@@ -1309,4 +1313,6 @@
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Áudio Bluetooth"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Concluído"</string>
<string name="media_route_button_content_description" msgid="5758553567065145276">"Saída de som multimédia"</string>
+ <!-- no translation found for display_manager_built_in_display (9042666544146043569) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 9bdfcd8..377a7d5 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -224,6 +224,10 @@
<string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Permite que o aplicativo execute ações entre os diversos usuários do aparelho. Aplicativos mal-intencionados podem usar isto para violar a proteção entre os usuários."</string>
<string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"permissão total para interagir entre os usuários"</string>
<string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Permite todas as interações possíveis entre os usuários."</string>
+ <!-- no translation found for permlab_manageUsers (1676150911672282428) -->
+ <skip />
+ <!-- no translation found for permdesc_manageUsers (8409306667645355638) -->
+ <skip />
<string name="permlab_getDetailedTasks" msgid="6229468674753529501">"recuperar detalhes dos aplicativos em execução"</string>
<string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Permite que o aplicativo recupere informações detalhadas sobre tarefas executadas atual e recentemente. Aplicativos maliciosos podem descobrir informações privadas sobre outros aplicativos."</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"reordenar os aplicativos em execução"</string>
@@ -1309,4 +1313,6 @@
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Áudio Bluetooth"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Concluído"</string>
<string name="media_route_button_content_description" msgid="5758553567065145276">"Saída de mídia"</string>
+ <!-- no translation found for display_manager_built_in_display (9042666544146043569) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-rm/strings.xml b/core/res/res/values-rm/strings.xml
index 097d6de..a093bfb 100644
--- a/core/res/res/values-rm/strings.xml
+++ b/core/res/res/values-rm/strings.xml
@@ -303,6 +303,10 @@
<skip />
<!-- no translation found for permdesc_interactAcrossUsersFull (376841368395502366) -->
<skip />
+ <!-- no translation found for permlab_manageUsers (1676150911672282428) -->
+ <skip />
+ <!-- no translation found for permdesc_manageUsers (8409306667645355638) -->
+ <skip />
<!-- no translation found for permlab_getDetailedTasks (6229468674753529501) -->
<skip />
<!-- no translation found for permdesc_getDetailedTasks (153824741440717599) -->
@@ -2066,4 +2070,6 @@
<skip />
<!-- no translation found for media_route_button_content_description (5758553567065145276) -->
<skip />
+ <!-- no translation found for display_manager_built_in_display (9042666544146043569) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 7284dd7..466aed8 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -224,6 +224,10 @@
<string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Permite aplicaţiei să efectueze acţiuni pentru diferiţi utilizatori pe dispozitiv. Aplicaţiile rău intenţionate pot utiliza această permisiune pentru a încălca protecţia între utilizatori."</string>
<string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"licenţă completă pentru interacţiune între utilizatori"</string>
<string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Permite toate interacţiunile posibile între utilizatori."</string>
+ <!-- no translation found for permlab_manageUsers (1676150911672282428) -->
+ <skip />
+ <!-- no translation found for permdesc_manageUsers (8409306667645355638) -->
+ <skip />
<string name="permlab_getDetailedTasks" msgid="6229468674753529501">"preia detalii despre aplicaţiile care rulează"</string>
<string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Permite aplicaţiei să preia informaţii detaliate despre activităţile rulate curent şi recent. Aplicaţiile rău intenţionate pot să descopere informaţii private despre alte aplicaţii."</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"reordonare aplicaţii care rulează"</string>
@@ -1309,4 +1313,6 @@
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Audio Bluetooth"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Terminat"</string>
<string name="media_route_button_content_description" msgid="5758553567065145276">"Rezultate media"</string>
+ <!-- no translation found for display_manager_built_in_display (9042666544146043569) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index c32f93a..53a47ef 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -224,6 +224,10 @@
<string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Приложение сможет выполнять действия во всех аккаунтах на этом устройстве. При этом защита от вредоносных приложений может быть недостаточной."</string>
<string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"разрешить полное взаимодействие со всеми аккаунтами"</string>
<string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Приложение сможет выполнять любые действия во всех аккаунтах на этом устройстве."</string>
+ <!-- no translation found for permlab_manageUsers (1676150911672282428) -->
+ <skip />
+ <!-- no translation found for permdesc_manageUsers (8409306667645355638) -->
+ <skip />
<string name="permlab_getDetailedTasks" msgid="6229468674753529501">"получение сведений о работающих приложениях"</string>
<string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Приложение сможет получать подробные сведения о недавно запущенных и выполняемых задачах. При этом конфиденциальная информация о других приложениях не будет защищена от вредоносных программ."</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"Упорядочивание запущенных приложений"</string>
@@ -1309,4 +1313,6 @@
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Воспроизведение звука через Bluetooth"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Готово"</string>
<string name="media_route_button_content_description" msgid="5758553567065145276">"Перенаправлять поток мультимедиа"</string>
+ <!-- no translation found for display_manager_built_in_display (9042666544146043569) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 3464faa..49bdff6 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -224,6 +224,10 @@
<string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Umožňuje aplikácii vykonávať akcie naprieč rôznymi používateľmi zariadenia. Škodlivé aplikácie môžu toto povolenie zneužiť na obídenie ochrany medzi používateľmi."</string>
<string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"plná licencia na interakcie naprieč používateľmi"</string>
<string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Umožňuje všetky možné interakcie naprieč používateľmi."</string>
+ <!-- no translation found for permlab_manageUsers (1676150911672282428) -->
+ <skip />
+ <!-- no translation found for permdesc_manageUsers (8409306667645355638) -->
+ <skip />
<string name="permlab_getDetailedTasks" msgid="6229468674753529501">"načítať podrobnosti o spustených aplikáciách"</string>
<string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Umožňuje aplikácii načítať podrobné informácie o aktuálnych a nedávno spustených úlohách. Škodlivé aplikácie môžu odhaliť súkromné informácie o iných aplikáciách."</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"zmeniť poradie spustených aplikácií"</string>
@@ -1309,4 +1313,6 @@
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth audio"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Hotovo"</string>
<string name="media_route_button_content_description" msgid="5758553567065145276">"Výstup médií"</string>
+ <!-- no translation found for display_manager_built_in_display (9042666544146043569) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 35246b1..3e9ac26 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -224,6 +224,10 @@
<string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Aplikaciji omogoča izvajanje dejanj za različne uporabnike v napravi. Zlonamerne aplikacije lahko to uporabijo za kršitev zaščite med uporabniki."</string>
<string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"polna licenca za interakcijo z uporabniki"</string>
<string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Dovoli vso mogočo interakcijo z uporabniki"</string>
+ <!-- no translation found for permlab_manageUsers (1676150911672282428) -->
+ <skip />
+ <!-- no translation found for permdesc_manageUsers (8409306667645355638) -->
+ <skip />
<string name="permlab_getDetailedTasks" msgid="6229468674753529501">"prejemanje podrobnosti o aplikacijah, ki se izvajajo"</string>
<string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Aplikaciji omogoča, da dobi podatke o trenutnih in nedavno izvajajočih se opravilih. Zlonamerne aplikacije lahko odkrijejo zasebne podatke o drugih aplikacijah."</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"preurejanje programov, ki se izvajajo"</string>
@@ -1309,4 +1313,6 @@
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Zvok prek Bluetootha"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Končano"</string>
<string name="media_route_button_content_description" msgid="5758553567065145276">"Izhod predstavnosti"</string>
+ <!-- no translation found for display_manager_built_in_display (9042666544146043569) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index d5c0561..a1f91fa 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -224,6 +224,10 @@
<string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Дозвољава апликацији да обавља радње између различитих корисника на уређају. Злонамерне апликације могу да користе ово да би угрозиле заштиту између корисника."</string>
<string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"пуна лиценца за интеракцију између корисника"</string>
<string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Дозвољава све могуће интеракције између корисника."</string>
+ <!-- no translation found for permlab_manageUsers (1676150911672282428) -->
+ <skip />
+ <!-- no translation found for permdesc_manageUsers (8409306667645355638) -->
+ <skip />
<string name="permlab_getDetailedTasks" msgid="6229468674753529501">"преузимање детаља о покренутим апликацијама"</string>
<string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Дозвољава апликацији да преузима детаљне информације о актуелним и недавно покренутим задацима. Злонамерне апликације могу да открију приватне информације о другим апликацијама."</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"промена редоследа покренутих апликација"</string>
@@ -1309,4 +1313,6 @@
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth аудио"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Готово"</string>
<string name="media_route_button_content_description" msgid="5758553567065145276">"Излаз медија"</string>
+ <!-- no translation found for display_manager_built_in_display (9042666544146043569) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 89c0796..6aba065 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -224,6 +224,10 @@
<string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Tillåter att appen utför åtgärder mellan användare på enheten. Skadliga appar kan använda detta som ett sätt att kringgå skyddet mellan användare."</string>
<string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"fullständig behörighet att interagera mellan användare"</string>
<string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Tillåter all slags interaktion mellan användare."</string>
+ <!-- no translation found for permlab_manageUsers (1676150911672282428) -->
+ <skip />
+ <!-- no translation found for permdesc_manageUsers (8409306667645355638) -->
+ <skip />
<string name="permlab_getDetailedTasks" msgid="6229468674753529501">"hämta information om aktiva appar"</string>
<string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Tillåter att appen hämtar detaljerad information om uppgifter som körs och har körts. Skadliga appar kan upptäcka personliga uppgifter om andra appar."</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"byt ordning på appar som körs"</string>
@@ -1309,4 +1313,6 @@
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth-ljud"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Klar"</string>
<string name="media_route_button_content_description" msgid="5758553567065145276">"Medieuppspelning"</string>
+ <!-- no translation found for display_manager_built_in_display (9042666544146043569) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 3fd7af0..a055d0b 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -224,6 +224,10 @@
<string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Inaruhusu programu kutenda vitendo kwa watumiaji tofauti kwenye kifaa. Programu hasidi huenda zikatumia hii ili kukiuka ulinzi kati ya watumiaji."</string>
<string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"leseni kamili ili kutagusana na watumiaji"</string>
<string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Inaruhusu miingialiano yote inayowezekana kwa watumiaji."</string>
+ <!-- no translation found for permlab_manageUsers (1676150911672282428) -->
+ <skip />
+ <!-- no translation found for permdesc_manageUsers (8409306667645355638) -->
+ <skip />
<string name="permlab_getDetailedTasks" msgid="6229468674753529501">"epua maelezo ya programu zinazoendeshwa"</string>
<string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Huruhusu programu kuepua maelezo tondoti kuhusu kazi za sasa na zinazoendelea hivi karibuni. Programu hasidi huenda zikagundua maelezo ya kibinafsi kuhusu programu zingine."</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"Agiza tena programu za kuendeshwa"</string>
@@ -1309,4 +1313,6 @@
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Sauti ya Bluetooth"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Kwisha"</string>
<string name="media_route_button_content_description" msgid="5758553567065145276">"Towe la midia"</string>
+ <!-- no translation found for display_manager_built_in_display (9042666544146043569) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 61e25b2..b1639eb 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -224,6 +224,10 @@
<string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"อนุญาตให้แอปพลิเคชันทำงานได้กับผู้ใช้หลายรายบนอุปกรณ์นี้ แอปพลิเคชันที่เป็นอันตรายอาจใช้การทำงานนี้ในการบุกรุกการป้องกันระหว่างผู้ใช้"</string>
<string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"ใบอนุญาตฉบับเต็มสำหรับการโต้ตอบระหว่างผู้ใช้"</string>
<string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"อนุญาตให้ทำการโต้ตอบทุกชนิดที่เป็นไปได้กับผู้ใช้ต่างๆ"</string>
+ <!-- no translation found for permlab_manageUsers (1676150911672282428) -->
+ <skip />
+ <!-- no translation found for permdesc_manageUsers (8409306667645355638) -->
+ <skip />
<string name="permlab_getDetailedTasks" msgid="6229468674753529501">"ดึงรายละเอียดของแอปที่ทำงานอยู่"</string>
<string name="permdesc_getDetailedTasks" msgid="153824741440717599">"อนุญาตให้แอปพลิเคชันดึงข้อมูลเกี่ยวกับงานที่กำลังเรียกใช้อยู่ในปัจจุบันและงานล่าสุด แอปพลิเคชันที่เป็นอันตรายอาจค้นพบข้อมูลเฉพาะตัวเกี่ยวกับแอปพลิเคชันอื่นๆ"</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"จัดลำดับแอปพลิเคชันที่ทำงานอยู่ใหม่"</string>
@@ -1309,4 +1313,6 @@
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"เสียงบลูทูธ"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"เสร็จสิ้น"</string>
<string name="media_route_button_content_description" msgid="5758553567065145276">"เอาต์พุตสื่อ"</string>
+ <!-- no translation found for display_manager_built_in_display (9042666544146043569) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index adf7ef2..ca57d6d 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -224,6 +224,10 @@
<string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Binibigyang-daan ang app upang magsagawa ng mga pagkilos sa kabuuan ng iba\'t ibang mga user sa device. Maaari itong gamitin ng nakakahamak na apps upang lumabag sa proteksyon sa pagitan ng mga user."</string>
<string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"ganap na lisensya upang makipag-ugnayan sa kabuuan ng mga user"</string>
<string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Pinapayagan ang lahat ng posibleng pakikipag-ugnayan sa kabuuan ng mga user."</string>
+ <!-- no translation found for permlab_manageUsers (1676150911672282428) -->
+ <skip />
+ <!-- no translation found for permdesc_manageUsers (8409306667645355638) -->
+ <skip />
<string name="permlab_getDetailedTasks" msgid="6229468674753529501">"bawiin ang mga detalye ng gumaganang apps"</string>
<string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Binibigyang-daan ang app na bawiin ang detalyadong impormasyon tungkol sa mga kasalukuyan at kamakailang gumaganang gawain. Maaaring makatuklas ang nakakahamak na apps ng pribadong impormasyon tungkol sa iba pang apps."</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"muling isaayos ang tumatakbong apps"</string>
@@ -1309,4 +1313,6 @@
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Audio sa Bluetooth"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Tapos na"</string>
<string name="media_route_button_content_description" msgid="5758553567065145276">"Output ng media"</string>
+ <!-- no translation found for display_manager_built_in_display (9042666544146043569) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index e15402a..e3f6236 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -224,6 +224,10 @@
<string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Uygulamaya cihazdaki farklı kullanıcılar arasında işlem gerçekleştirme izni verir. Kötü amaçlı uygulamalar bu izinle kullanıcılar arasındaki korumayı ihlal edebilir."</string>
<string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"kullanıcılar arasında etkileşim kurmak için tam izin"</string>
<string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Kullanıcılar arasında tüm etkileşime izin verir."</string>
+ <!-- no translation found for permlab_manageUsers (1676150911672282428) -->
+ <skip />
+ <!-- no translation found for permdesc_manageUsers (8409306667645355638) -->
+ <skip />
<string name="permlab_getDetailedTasks" msgid="6229468674753529501">"çalışan uygulamaların ayrıntılarını al"</string>
<string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Uygulamaya, şu anda çalışmakta olan ve son çalışan işlemler hakkında ayrıntılı bilgi alma izni verir. Kötü amaçlı uygulamalar diğer uygulamalar hakkında gizli bilgileri ele geçirebilir."</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"çalışan uygulamaları yeniden sırala"</string>
@@ -1309,4 +1313,6 @@
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Bluetooth ses"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Tamamlandı"</string>
<string name="media_route_button_content_description" msgid="5758553567065145276">"Medya çıkışı"</string>
+ <!-- no translation found for display_manager_built_in_display (9042666544146043569) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index d37cbd8..3ff155e 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -224,6 +224,10 @@
<string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Дозволяє програмі виконувати дії щодо різних користувачів на пристрої. Шкідливі програми можуть використовувати це для порушення захисту окремих користувачів."</string>
<string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"повна ліцензія на взаємодію між користувачами"</string>
<string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Дозволяє всі можливі взаємодії щодо користувачів."</string>
+ <!-- no translation found for permlab_manageUsers (1676150911672282428) -->
+ <skip />
+ <!-- no translation found for permdesc_manageUsers (8409306667645355638) -->
+ <skip />
<string name="permlab_getDetailedTasks" msgid="6229468674753529501">"отримувати дані про запущені програми"</string>
<string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Дозволяє програмі отримувати інформацію про поточні й останні запущені завдання. Шкідливі програми можуть виявляти особисту інформацію про інші програми."</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"змінювати порядок запущених програм"</string>
@@ -1309,4 +1313,6 @@
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Аудіо Bluetooth"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Готово"</string>
<string name="media_route_button_content_description" msgid="5758553567065145276">"Вивід медіа-даних"</string>
+ <!-- no translation found for display_manager_built_in_display (9042666544146043569) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 8ce6f4e..fc8a439 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -224,6 +224,10 @@
<string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Cho phép ứng dụng thực hiện hành động giữa những người dùng khác trên thiết bị. Ứng dụng độc hại có thể sử dụng quyền này để vi phạm khả năng bảo vệ giữa người dùng."</string>
<string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"cấp phép đầy đủ để tương tác giữa người dùng"</string>
<string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Cho phép tất cả các tương tác giữa người dùng."</string>
+ <!-- no translation found for permlab_manageUsers (1676150911672282428) -->
+ <skip />
+ <!-- no translation found for permdesc_manageUsers (8409306667645355638) -->
+ <skip />
<string name="permlab_getDetailedTasks" msgid="6229468674753529501">"truy xuất chi tiết về các ứng dụng đang chạy"</string>
<string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Cho phép ứng dụng truy xuất thông tin chi tiết về các tác vụ đã và đang chạy gần đây. Ứng dụng độc hại có thể phát hiện thông tin riêng tư về các ứng dụng khác."</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"sắp xếp lại những ứng dụng đang chạy"</string>
@@ -1309,4 +1313,6 @@
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Âm thanh Bluetooth"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Xong"</string>
<string name="media_route_button_content_description" msgid="5758553567065145276">"Đầu ra phương tiện"</string>
+ <!-- no translation found for display_manager_built_in_display (9042666544146043569) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index c271baa..24637d7 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -224,6 +224,10 @@
<string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"允许该应用在设备上跨多个用户执行操作。恶意应用可能会借此破坏用户之间的保护措施。"</string>
<string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"完全允许在用户之间进行互动"</string>
<string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"允许在用户之间进行所有可能的互动。"</string>
+ <!-- no translation found for permlab_manageUsers (1676150911672282428) -->
+ <skip />
+ <!-- no translation found for permdesc_manageUsers (8409306667645355638) -->
+ <skip />
<string name="permlab_getDetailedTasks" msgid="6229468674753529501">"检索正在运行的应用的详细信息"</string>
<string name="permdesc_getDetailedTasks" msgid="153824741440717599">"允许该应用检索当前正在运行和近期运行的任务的详细信息。恶意应用可能会发现有关其他应用的私密信息。"</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"对正在运行的应用重新排序"</string>
@@ -1068,13 +1072,13 @@
<string name="perms_new_perm_prefix" msgid="8257740710754301407"><font size="12" fgcolor="#ff900000">"新增:"</font></string>
<string name="perms_description_app" msgid="5139836143293299417">"由“<xliff:g id="APP_NAME">%1$s</xliff:g>”提供。"</string>
<string name="usb_storage_activity_title" msgid="4465055157209648641">"USB 大容量存储设备"</string>
- <string name="usb_storage_title" msgid="5901459041398751495">"USB 已连接"</string>
+ <string name="usb_storage_title" msgid="5901459041398751495">"已连接 USB"</string>
<string name="usb_storage_message" product="nosdcard" msgid="3308538094316477839">"您已通过 USB 连接至计算机。如果您要在计算机与 Android 设备的 USB 存储设备之间复制文件,请触摸下面的按钮。"</string>
<string name="usb_storage_message" product="default" msgid="805351000446037811">"您已通过 USB 连接至计算机。如果您要在计算机和 Android 设备的 SD 卡之间复制文件,请触摸下面的按钮。"</string>
<string name="usb_storage_button_mount" msgid="1052259930369508235">"打开 USB 存储设备"</string>
<string name="usb_storage_error_message" product="nosdcard" msgid="3017045217365540658">"使用 USB 存储设备作为 USB 大容量存储设备时出现问题。"</string>
<string name="usb_storage_error_message" product="default" msgid="2876018512716970313">"使用 SD 卡作为 USB 大容量存储设备时出现问题。"</string>
- <string name="usb_storage_notification_title" msgid="8175892554757216525">"USB 已连接"</string>
+ <string name="usb_storage_notification_title" msgid="8175892554757216525">"已连接 USB"</string>
<string name="usb_storage_notification_message" msgid="939822783828183763">"触摸可将文件复制到计算机或从计算机复制到存储设备。"</string>
<string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"关闭 USB 存储设备"</string>
<string name="usb_storage_stop_notification_message" msgid="1656852098555623822">"触摸可关闭 USB 存储设备。"</string>
@@ -1309,4 +1313,6 @@
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"蓝牙音频"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"完成"</string>
<string name="media_route_button_content_description" msgid="5758553567065145276">"媒体输出线路"</string>
+ <!-- no translation found for display_manager_built_in_display (9042666544146043569) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 20a15d1..255890a 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -224,6 +224,10 @@
<string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"允許應用程式對裝置上的所有使用者執行各種動作。請注意,惡意應用程式可能利用此功能侵害使用者之間的保護機制。"</string>
<string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"完整授權對所有使用者執行各種動作"</string>
<string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"允許對所有使用者執行各種可能的動作。"</string>
+ <!-- no translation found for permlab_manageUsers (1676150911672282428) -->
+ <skip />
+ <!-- no translation found for permdesc_manageUsers (8409306667645355638) -->
+ <skip />
<string name="permlab_getDetailedTasks" msgid="6229468674753529501">"擷取執行中應用程式的詳細資訊"</string>
<string name="permdesc_getDetailedTasks" msgid="153824741440717599">"允許應用程式擷取目前及最近所執行任務的詳細資訊。請注意,惡意應用程式可能會找出其他應用程式的不公開資訊。"</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"重新排序正在執行的應用程式"</string>
@@ -1309,4 +1313,6 @@
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"藍牙音訊"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"完成"</string>
<string name="media_route_button_content_description" msgid="5758553567065145276">"媒體輸出"</string>
+ <!-- no translation found for display_manager_built_in_display (9042666544146043569) -->
+ <skip />
</resources>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 8978e52..c303bcd 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -224,6 +224,10 @@
<string name="permdesc_interactAcrossUsers" msgid="364670963623385786">"Ivumela uhlelo lokusebenza ukwenza izenzo kubasebenzisi bonke kudivayisi. Izinhlelo zokusebenza ezingalungile zingasebenzisa lokhu ukwephula ukuvikela phakathi kwabasebenzisi."</string>
<string name="permlab_interactAcrossUsersFull" msgid="2567734285545074105">"ilayisensi egcwele yokuhlanganyela kubasebenzisi"</string>
<string name="permdesc_interactAcrossUsersFull" msgid="376841368395502366">"Ivumela konke ukuhlanganyela phakathi kwabasebenzisi."</string>
+ <!-- no translation found for permlab_manageUsers (1676150911672282428) -->
+ <skip />
+ <!-- no translation found for permdesc_manageUsers (8409306667645355638) -->
+ <skip />
<string name="permlab_getDetailedTasks" msgid="6229468674753529501">"thola kabusha imininingwane yezinhlelo zokusebenza ezisebenzayo"</string>
<string name="permdesc_getDetailedTasks" msgid="153824741440717599">"Ivumela uhlelo lokusebenza ukuthola kabusha ulwazi mayelana nezinto ezenzeka manje nezisanda kwenzeka. Izinhlelo zokusebenza ezingalungile zingathola imininingwane eyimfihlo mayelana nezinye izinhlelo zokusebenza."</string>
<string name="permlab_reorderTasks" msgid="2018575526934422779">"misa kabusha izinsiza ezisebenzayo"</string>
@@ -1309,4 +1313,6 @@
<string name="bluetooth_a2dp_audio_route_name" msgid="8575624030406771015">"Umsindo we-Bluetooth"</string>
<string name="media_route_chooser_grouping_done" msgid="7966438307723317169">"Qedile"</string>
<string name="media_route_button_content_description" msgid="5758553567065145276">"Okukhiphayo kwemidiya"</string>
+ <!-- no translation found for display_manager_built_in_display (9042666544146043569) -->
+ <skip />
</resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 38a431f..0d190ee 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -479,6 +479,7 @@
<java-symbol type="string" name="decline" />
<java-symbol type="string" name="default_text_encoding" />
<java-symbol type="string" name="description_target_unlock_tablet" />
+ <java-symbol type="string" name="display_manager_built_in_display" />
<java-symbol type="string" name="double_tap_toast" />
<java-symbol type="string" name="elapsed_time_short_format_h_mm_ss" />
<java-symbol type="string" name="elapsed_time_short_format_mm_ss" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 620a002..b7ad1e9 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -3639,4 +3639,9 @@
<!-- Content description of a MediaRouteButton for accessibility support -->
<string name="media_route_button_content_description">Media output</string>
+ <!-- Display manager service -->
+
+ <!-- Name of the built-in display. [CHAR LIMIT=50] -->
+ <string name="display_manager_built_in_display">Built-in Screen</string>
+
</resources>
diff --git a/core/tests/coretests/src/android/content/pm/VerificationParamsTest.java b/core/tests/coretests/src/android/content/pm/VerificationParamsTest.java
new file mode 100644
index 0000000..b814e2d
--- /dev/null
+++ b/core/tests/coretests/src/android/content/pm/VerificationParamsTest.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content.pm;
+
+import android.content.pm.ManifestDigest;
+import android.content.pm.VerificationParams;
+import android.net.Uri;
+import android.os.Parcel;
+import android.test.AndroidTestCase;
+
+/**
+ * Tests the android.content.pm.VerificationParams class
+ *
+ * To test run:
+ * ./development/testrunner/runtest.py frameworks-core -c android.content.pm.VerificationParamsTest
+ */
+public class VerificationParamsTest extends AndroidTestCase {
+
+ private final static String VERIFICATION_URI_STRING = "http://verification.uri/path";
+ private final static String ORIGINATING_URI_STRING = "http://originating.uri/path";
+ private final static String REFERRER_STRING = "http://referrer.uri/path";
+ private final static byte[] DIGEST_BYTES = "fake digest".getBytes();
+
+ private final static Uri VERIFICATION_URI = Uri.parse(VERIFICATION_URI_STRING);
+ private final static Uri ORIGINATING_URI = Uri.parse(ORIGINATING_URI_STRING);
+ private final static Uri REFERRER = Uri.parse(REFERRER_STRING);
+
+ private final static ManifestDigest MANIFEST_DIGEST = new ManifestDigest(DIGEST_BYTES);
+
+ public void testParcel() throws Exception {
+ VerificationParams expected = new VerificationParams(VERIFICATION_URI, ORIGINATING_URI,
+ REFERRER, MANIFEST_DIGEST);
+
+ Parcel parcel = Parcel.obtain();
+ expected.writeToParcel(parcel, 0);
+ parcel.setDataPosition(0);
+
+ VerificationParams actual = VerificationParams.CREATOR.createFromParcel(parcel);
+
+ assertEquals(VERIFICATION_URI, actual.getVerificationURI());
+
+ assertEquals(ORIGINATING_URI, actual.getOriginatingURI());
+
+ assertEquals(REFERRER, actual.getReferrer());
+
+ assertEquals(MANIFEST_DIGEST, actual.getManifestDigest());
+ }
+
+ public void testEquals_Success() throws Exception {
+ VerificationParams params1 = new VerificationParams(VERIFICATION_URI, ORIGINATING_URI,
+ REFERRER, MANIFEST_DIGEST);
+
+ VerificationParams params2 = new VerificationParams(
+ Uri.parse(VERIFICATION_URI_STRING), Uri.parse(ORIGINATING_URI_STRING),
+ Uri.parse(REFERRER_STRING), new ManifestDigest(DIGEST_BYTES));
+
+ assertEquals(params1, params2);
+ }
+
+ public void testEquals_VerificationUri_Failure() throws Exception {
+ VerificationParams params1 = new VerificationParams(VERIFICATION_URI, ORIGINATING_URI,
+ REFERRER, MANIFEST_DIGEST);
+
+ VerificationParams params2 = new VerificationParams(
+ Uri.parse("http://a.different.uri/"), Uri.parse(ORIGINATING_URI_STRING),
+ Uri.parse(REFERRER_STRING), new ManifestDigest(DIGEST_BYTES));
+
+ assertFalse(params1.equals(params2));
+ }
+
+ public void testEquals_OriginatingUri_Failure() throws Exception {
+ VerificationParams params1 = new VerificationParams(VERIFICATION_URI, ORIGINATING_URI,
+ REFERRER, MANIFEST_DIGEST);
+
+ VerificationParams params2 = new VerificationParams(
+ Uri.parse(VERIFICATION_URI_STRING), Uri.parse("http://a.different.uri/"),
+ Uri.parse(REFERRER_STRING), new ManifestDigest(DIGEST_BYTES));
+
+ assertFalse(params1.equals(params2));
+ }
+
+ public void testEquals_Referrer_Failure() throws Exception {
+ VerificationParams params1 = new VerificationParams(VERIFICATION_URI, ORIGINATING_URI,
+ REFERRER, MANIFEST_DIGEST);
+
+ VerificationParams params2 = new VerificationParams(
+ Uri.parse(VERIFICATION_URI_STRING), Uri.parse(ORIGINATING_URI_STRING),
+ Uri.parse("http://a.different.uri/"), new ManifestDigest(DIGEST_BYTES));
+
+ assertFalse(params1.equals(params2));
+ }
+
+ public void testEquals_ManifestDigest_Failure() throws Exception {
+ VerificationParams params1 = new VerificationParams(VERIFICATION_URI, ORIGINATING_URI,
+ REFERRER, MANIFEST_DIGEST);
+
+ VerificationParams params2 = new VerificationParams(
+ Uri.parse(VERIFICATION_URI_STRING), Uri.parse(ORIGINATING_URI_STRING),
+ Uri.parse(REFERRER_STRING), new ManifestDigest("a different digest".getBytes()));
+
+ assertFalse(params1.equals(params2));
+ }
+
+ public void testHashCode_Success() throws Exception {
+ VerificationParams params1 = new VerificationParams(VERIFICATION_URI, ORIGINATING_URI,
+ REFERRER, MANIFEST_DIGEST);
+
+ VerificationParams params2 = new VerificationParams(
+ Uri.parse(VERIFICATION_URI_STRING), Uri.parse(ORIGINATING_URI_STRING),
+ Uri.parse(REFERRER_STRING), new ManifestDigest(DIGEST_BYTES));
+
+ assertEquals(params1.hashCode(), params2.hashCode());
+ }
+
+ public void testHashCode_VerificationUri_Failure() throws Exception {
+ VerificationParams params1 = new VerificationParams(VERIFICATION_URI, ORIGINATING_URI,
+ REFERRER, MANIFEST_DIGEST);
+
+ VerificationParams params2 = new VerificationParams(null, Uri.parse(ORIGINATING_URI_STRING),
+ Uri.parse(REFERRER_STRING), new ManifestDigest(DIGEST_BYTES));
+
+ assertFalse(params1.hashCode() == params2.hashCode());
+ }
+
+ public void testHashCode_OriginatingUri_Failure() throws Exception {
+ VerificationParams params1 = new VerificationParams(VERIFICATION_URI, ORIGINATING_URI,
+ REFERRER, MANIFEST_DIGEST);
+
+ VerificationParams params2 = new VerificationParams(
+ Uri.parse(VERIFICATION_URI_STRING), Uri.parse("http://a.different.uri/"),
+ Uri.parse(REFERRER_STRING), new ManifestDigest(DIGEST_BYTES));
+
+ assertFalse(params1.hashCode() == params2.hashCode());
+ }
+
+ public void testHashCode_Referrer_Failure() throws Exception {
+ VerificationParams params1 = new VerificationParams(VERIFICATION_URI, ORIGINATING_URI,
+ REFERRER, MANIFEST_DIGEST);
+
+ VerificationParams params2 = new VerificationParams(
+ Uri.parse(VERIFICATION_URI_STRING), Uri.parse(ORIGINATING_URI_STRING), null,
+ new ManifestDigest(DIGEST_BYTES));
+
+ assertFalse(params1.hashCode() == params2.hashCode());
+ }
+
+ public void testHashCode_ManifestDigest_Failure() throws Exception {
+ VerificationParams params1 = new VerificationParams(VERIFICATION_URI, ORIGINATING_URI,
+ REFERRER, MANIFEST_DIGEST);
+
+ VerificationParams params2 = new VerificationParams(
+ Uri.parse(VERIFICATION_URI_STRING), Uri.parse(ORIGINATING_URI_STRING),
+ Uri.parse(REFERRER_STRING), new ManifestDigest("a different digest".getBytes()));
+
+ assertFalse(params1.hashCode() == params2.hashCode());
+ }
+}
diff --git a/data/fonts/Android.mk b/data/fonts/Android.mk
index 3d6c9d3..7bc172c 100644
--- a/data/fonts/Android.mk
+++ b/data/fonts/Android.mk
@@ -76,14 +76,6 @@ LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_PATH := $(TARGET_OUT)/fonts
include $(BUILD_PREBUILT)
-include $(CLEAR_VARS)
-LOCAL_MODULE := fallback_fonts-ja.xml
-LOCAL_SRC_FILES := $(LOCAL_MODULE)
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)
-include $(BUILD_PREBUILT)
-
droidsans_fallback_src := DroidSansFallbackFull.ttf
extra_font_files := \
DroidSans.ttf \
@@ -91,8 +83,7 @@ extra_font_files := \
DroidSansEthiopic-Regular.ttf \
DroidSansTamil-Regular.ttf \
DroidSansTamil-Bold.ttf \
- MTLmr3m.ttf \
- fallback_fonts-ja.xml
+ MTLmr3m.ttf
endif # SMALLER_FONT_FOOTPRINT
################################
diff --git a/data/fonts/fallback_fonts-ja.xml b/data/fonts/fallback_fonts-ja.xml
deleted file mode 100644
index 82e3a38..0000000
--- a/data/fonts/fallback_fonts-ja.xml
+++ /dev/null
@@ -1,121 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Fallback Fonts
-
- This file specifies the fonts, and the priority order, that will be searched for any
- glyphs not handled by the default fonts specified in /system/etc/system_fonts.xml.
- Each entry consists of a family tag and a list of files (file names) which support that
- family. The fonts for each family are listed in the order of the styles that they
- handle (the order is: regular, bold, italic, and bold-italic). The order in which the
- families are listed in this file represents the order in which these fallback fonts
- will be searched for glyphs that are not supported by the default system fonts (which are
- found in /system/etc/system_fonts.xml).
-
- Note that there is not nameset for fallback fonts, unlike the fonts specified in
- system_fonts.xml. The ability to support specific names in fallback fonts may be supported
- in the future. For now, the lack of files entries here is an indicator to the system that
- these are fallback fonts, instead of default named system fonts.
-
- There is another optional file in /vendor/etc/fallback_fonts.xml. That file can be used to
- provide references to other font families that should be used in addition to the default
- fallback fonts. That file can also specify the order in which the fallback fonts should be
- searched, to ensure that a vendor-provided font will be used before another fallback font
- which happens to handle the same glyph.
-
- Han languages (Chinese, Japanese, and Korean) share a common range of unicode characters;
- their ordering in the fallback or vendor files gives priority to the first in the list.
- Locale-specific ordering can be configured by adding language and region codes to the end
- of the filename (e.g. /system/etc/fallback_fonts-ja.xml). When no region code is used,
- as with this example, all regions are matched. Use separate files for each supported locale.
- The standard fallback file (fallback_fonts.xml) is used when a locale does not have its own
- file. All fallback files must contain the same complete set of fonts; only their ordering
- can differ.
--->
-<familyset>
- <family>
- <fileset>
- <file variant="elegant">DroidNaskh-Regular.ttf</file>
- </fileset>
- </family>
- <family>
- <fileset>
- <file variant="compact">DroidNaskh-Regular-SystemUI.ttf</file>
- </fileset>
- </family>
- <family>
- <fileset>
- <file>DroidSansEthiopic-Regular.ttf</file>
- </fileset>
- </family>
- <family>
- <fileset>
- <file>DroidSansHebrew-Regular.ttf</file>
- <file>DroidSansHebrew-Bold.ttf</file>
- </fileset>
- </family>
- <family>
- <fileset>
- <file>DroidSansThai.ttf</file>
- </fileset>
- </family>
- <family>
- <fileset>
- <file>DroidSansArmenian.ttf</file>
- </fileset>
- </family>
- <family>
- <fileset>
- <file>DroidSansGeorgian.ttf</file>
- </fileset>
- </family>
- <family>
- <fileset>
- <file>DroidSansDevanagari-Regular.ttf</file>
- </fileset>
- </family>
- <family>
- <fileset>
- <file>DroidSansTamil-Regular.ttf</file>
- <file>DroidSansTamil-Bold.ttf</file>
- </fileset>
- </family>
- <family>
- <fileset>
- <file>AnjaliNewLipi-light.ttf</file>
- </fileset>
- </family>
- <family>
- <fileset>
- <file>Lohit-Bengali.ttf</file>
- </fileset>
- </family>
- <family>
- <fileset>
- <file>Lohit-Kannada.ttf</file>
- </fileset>
- </family>
- <family>
- <fileset>
- <file>AndroidEmoji.ttf</file>
- </fileset>
- </family>
- <family>
- <fileset>
- <file>MTLmr3m.ttf</file>
- </fileset>
- </family>
- <family>
- <fileset>
- <file>DroidSansFallback.ttf</file>
- </fileset>
- </family>
- <!--
- Fonts below this point have problematic glyphs and should not be moved
- higher in the fallback list until those glyphs have been fixed.
- -->
- <family>
- <fileset>
- <file>Lohit-Telugu.ttf</file> <!-- masks U+FFBC-10007 -->
- </fileset>
- </family>
-</familyset>
diff --git a/data/fonts/fallback_fonts.xml b/data/fonts/fallback_fonts.xml
index 758adb5..2c9a0c8 100644
--- a/data/fonts/fallback_fonts.xml
+++ b/data/fonts/fallback_fonts.xml
@@ -24,12 +24,9 @@
Han languages (Chinese, Japanese, and Korean) share a common range of unicode characters;
their ordering in the fallback or vendor files gives priority to the first in the list.
- Locale-specific ordering can be configured by adding language and region codes to the end
- of the filename (e.g. /system/etc/fallback_fonts-ja.xml). When no region code is used,
- as with this example, all regions are matched. Use separate files for each supported locale.
- The standard fallback file (fallback_fonts.xml) is used when a locale does not have its own
- file. All fallback files must contain the same complete set of fonts; only their ordering
- can differ.
+ Language-specific ordering can be configured by adding a BCP 47-style "lang" attribute to
+ a "file" element; fonts matching the language of text being drawn will be prioritised over
+ all others.
-->
<familyset>
<family>
@@ -106,7 +103,7 @@
</family>
<family>
<fileset>
- <file>MTLmr3m.ttf</file>
+ <file lang="ja">MTLmr3m.ttf</file>
</fileset>
</family>
<!--
diff --git a/data/fonts/vendor_fonts.xml b/data/fonts/vendor_fonts.xml
index 5850f94..8690ee1 100644
--- a/data/fonts/vendor_fonts.xml
+++ b/data/fonts/vendor_fonts.xml
@@ -7,8 +7,7 @@
that in your makefile, this directory should be referenced as $(TARGET_COPY_OUT_VENDOR)/etc/:
PRODUCT_COPY_FILES += \
- frameworks/base/data/fonts/vendor_fonts.xml:$(TARGET_COPY_OUT_VENDOR)/etc/fallback_fonts.xml \
- frameworks/base/data/fonts/vendor_fonts-ja.xml:$(TARGET_COPY_OUT_VENDOR)/etc/fallback_fonts-ja.xml
+ frameworks/base/data/fonts/vendor_fonts.xml:$(TARGET_COPY_OUT_VENDOR)/etc/fallback_fonts.xml
For example, vendors might want to build configurations for locales that are
better served by fonts which either handle glyphs not supported in the default fonts or which
@@ -32,32 +31,9 @@
Han languages (Chinese, Japanese, and Korean) share a common range of unicode characters;
their ordering in the fallback or vendor files gives priority to the first in the list.
- Locale-specific ordering can be configured by adding language and region codes to the end
- of the filename (e.g. /vendor/etc/fallback_fonts-ja.xml). When no region code is used,
- as with this example, all regions are matched. Use separate files for each supported locale.
- The standard fallback file (fallback_fonts.xml) is used when a locale does not have its own
- file. All fallback files must contain the same complete set of fonts; only their ordering
- can differ. For example, on a device supporting Japanese, but with English as the default,
- /vendor/etc/fallback_fonts.xml might contain:
-
- <familyset>
- <family>
- <fileset>
- <file>DroidSansJapanese.ttf</file>
- </fileset>
- </family>
- </familyset>
-
- placing the Japanese font at the end of the fallback sequence for English, with a corresponding
- /system/vendor/etc/fallback_fonts-ja.xml, placing it at the front of the list.
-
- <familyset>
- <family order="0">
- <fileset>
- <file>DroidSansJapanese.ttf</file>
- </fileset>
- </family>
- </familyset>
+ Language-specific ordering can be configured by adding a BCP 47-style "lang" attribute to
+ a "file" element; fonts matching the language of text being drawn will be prioritised over
+ all others.
The sample configuration below is an example of how one might provide two families of fonts
that get inserted at the first and second (0 and 1) position in the overall fallback fonts.
@@ -82,4 +58,4 @@
</fileset>
</family>
</familyset>
---> \ No newline at end of file
+--->
diff --git a/docs/html/intl/ja/index.jd b/docs/html/intl/ja/index.jd
deleted file mode 100644
index ac36f90..0000000
--- a/docs/html/intl/ja/index.jd
+++ /dev/null
@@ -1,159 +0,0 @@
-home=true
-@jd:body
-
-
- <div id="mainBodyFixed">
- <div id="mainBodyLeft">
- <div id="homeMiddle">
- <div id="topAnnouncement">
- <div id="homeTitle">
- <h2>デベロッパーへのお知らせ</h2>
- </div><!-- end homeTitle -->
- <div id="announcement-block">
- <!-- total max width is 520px -->
- <img src="/assets/images/home/android_adc.png" alt="Android Developer Challenge 2" width="232px" />
- <div id="announcement" style="width:275px">
- <p>第2Android Developer Challengeが、遂に登場しました!このアプリケーション開発コンテストでは、Androidのユーザなら誰でも簡単に参加でき、一等の賞金は$250,000 です。登録の締切日は8月31日になります。</p>
- <p><a href="http://code.google.com/android/adc/">Android Developer Challengeについて詳しくはこちら &raquo;</a></p>
- </div> <!-- end annoucement -->
- </div> <!-- end annoucement-block -->
- </div><!-- end topAnnouncement -->
- <div id="carouselMain" style="height:210px"> <!-- this height can be adjusted based on the content height -->
- </div>
- <div class="clearer"></div>
- <div id="carouselWheel">
- <div class="app-list-container" align="center">
- <a href="javascript:{}" id="arrow-left" onclick="" class="arrow-left-off"></a>
- <div id="list-clip">
- <div style="left: 0px;" id="app-list">
- <!-- populated by buildCarousel() -->
- </div>
- </div><!-- end list-clip -->
- <a href="javascript:{ page_right(); }" id="arrow-right" onclick="" class="arrow-right-on"></a>
- <div class="clearer"></div>
- </div><!-- end app-list container -->
- </div><!-- end carouselWheel -->
- </div><!-- end homeMiddle -->
-
- <div style="clear:both">&nbsp;</div>
- </div><!-- end mainBodyLeft -->
-
- <div id="mainBodyRight">
- <table id="rightColumn">
- <tr>
- <td class="imageCell"><a href="{@docRoot}sdk/index.html"><img src="{@docRoot}assets/images/icon_download.jpg" style="padding:0" /></a></td>
- <td>
- <h2 class="green">ダウンロード</h2>
- <p>Android SDK には、優れたアプリケーションの作成に必要となるツール、サンプル コード、ドキュメントが含まれています。 </p>
- <p><a href="{@docRoot}sdk/index.html">詳細 &raquo;</a></p>
- </td>
- </tr>
- <tr>
- <td colspan="2"><div class="seperator">&nbsp;</div></td>
- </tr>
- <tr>
- <td class="imageCell"><a href="http://play.google.com/apps/publish"><img src="{@docRoot}assets/images/icon_play.png" style="padding:0" /></a></td>
- <td>
- <h2 class="green">公開</h2>
- <p>Android マーケットは、アプリケーションを携帯端末に配信するためのオープン サービスです。</p>
- <p><a href="http://play.google.com/apps/publish">詳細 &raquo;</a></p>
- </td>
- </tr>
- <tr>
- <td colspan="2"><div class="seperator">&nbsp;</div></td>
- </tr>
- <tr>
- <td class="imageCell"><a href="http://source.android.com"><img src="{@docRoot}assets/images/icon_contribute.jpg" style="padding:0" /></a></td>
- <td>
- <h2 class="green">貢献</h2>
- <p>Android オープンソース プロジェクトでは、プラットフォーム全体のソースコードを公開しています。</p>
- <p><a href="http://source.android.com">詳細 &raquo;</a></p>
- </td>
- </tr>
- <tr>
- <td colspan="2"><div class="seperator">&nbsp;</div></td>
- </tr>
- <tr>
- <td class="imageCell"><a href="http://www.youtube.com/user/androiddevelopers"><img src="{@docRoot}assets/images/video-droid.png" style="padding:0" /></a></td>
- <td>
- <h2 class="green">再生</h2>
- <object width="150" height="140"><param name="movie" value="http://www.youtube.com/v/GARMe7Km_gk&hl=en&fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/GARMe7Km_gk&hl=en&fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="150" height="140"></embed></object>
- <p style="margin-top:1em"><a href="{@docRoot}videos/index.html">その他の Android 動画 &raquo;</a></p>
- </td>
- </tr>
-
- </table>
- </div>
- </div>
-
-<!--[if lte IE 6]>
- <style>
- #arrow-left {
- margin:0 0 0 5px;
- }
- #arrow-right {
- margin-left:0;
- }
- .app-list-container {
- margin: 37px 0 0 23px;
- }
- div#list-clip {
- width:468px;
- }
- </style>
-<![endif]-->
-
-<script type="text/javascript">
-
-// * -- carousel dictionary -- * //
- /* layout: imgLeft, imgRight, imgTop
- icon: image for carousel entry. cropped (height:70px, width:90px)
- name: string for carousel entry
- img: image for bulletin post. cropped (height: 170, width:230px)
- title: header for bulletin (optional, insert "" value to skip
- desc: the bulletin post. must include html tags.
- */
-
- var droidList = {
- 'sdk': {
- 'layout':"imgLeft",
- 'icon':"sdk-small.png",
- 'name':"Android 2.0",
- 'img':"eclair-android.png",
- 'title':"Android 2.0",
- 'desc': "<p>Android 2.0 の最新バージョンが公開されました。このリリースには Android 2.0 用の API、最新版デベロッパーツール、複数プラットフォーム(バージョン)サポート、そして Google API のアドオンが含まれています。</p><p><a href='{@docRoot}sdk/index.html'>Android SDK をダウンロード &raquo;</a></p>"
- },
-
- 'io': {
- 'layout':"imgLeft",
- 'icon':"io-small.png",
- 'name':"Google I/O",
- 'img':"io-large.png",
- 'title':"Google I/O Developer Conference",
- 'desc': "<p>Google I/O は、サンフランシスコの Moscone Center で 5 月 27~28 日に開催された開発者会議です。このイベントに参加できなかった方は、各アンドロイド向けセッションを、YouTube ビデオ資料で体験する事が可能<nobr>です</nobr>。</p><p><a href='{@docRoot}videos/index.html'>セッションを参照してください &raquo;</a></p>"
- },
-
- 'mapskey': {
- 'layout':"imgLeft",
- 'icon':"maps-small.png",
- 'name':"Maps API キー",
- 'img':"maps-large.png",
- 'title':"Maps API キー",
- 'desc':"<p>MapView から Google マップを利用する Android アプリケーションを開発する場合は、アプリケーションを登録して Maps API キーを取得する必要があります。この API キーが無いアプリケーションは、Android 上で動作しません。キーの取得は、簡単な手順で行うことができます。</p><p><a href='http://code.google.com/android/add-ons/google-apis/maps-overview.html'>詳細 &raquo;</a></p>"
- },
-
- 'devphone': {
- 'layout':"imgLeft",
- 'icon':"devphone-small.png",
- 'name':"Dev Phone 1",
- 'img':"devphone-large.png",
- 'title':"Android Dev Phone 1",
- 'desc': "<p>この携帯電話を使用することで、開発した Android アプリケーションの実行とデバッグを行うことができます。Android オペレーティングシステムを変更してからリビルドし、携帯電話に書き込むことができます。Android Dev Phone 1 は携帯通信会社に依存しておらず、<a href='http://play.google.com/apps/publish'>Android マーケット</a>に登録済みのデベロッパーなら誰でも購入可能です。</p><p><a href='/tools/device.html#dev-phone-1'>Android Dev Phone 1 の詳細&raquo;</a></p>"
- }
-
- }
-</script>
-<script type="text/javascript" src="{@docRoot}assets/carousel.js"></script>
-<script type="text/javascript">
- initCarousel("sdk");
-</script>
diff --git a/drm/jni/Android.mk b/drm/jni/Android.mk
index f8ecc8c..fff7eee 100644
--- a/drm/jni/Android.mk
+++ b/drm/jni/Android.mk
@@ -35,7 +35,8 @@ LOCAL_C_INCLUDES += \
$(JNI_H_INCLUDE) \
$(TOP)/frameworks/av/drm/libdrmframework/include \
$(TOP)/frameworks/av/drm/libdrmframework/plugins/common/include \
- $(TOP)/frameworks/av/include
+ $(TOP)/frameworks/av/include \
+ $(TOP)/libcore/include
diff --git a/drm/jni/android_drm_DrmManagerClient.cpp b/drm/jni/android_drm_DrmManagerClient.cpp
index 14ec4d6..fb685a2 100644
--- a/drm/jni/android_drm_DrmManagerClient.cpp
+++ b/drm/jni/android_drm_DrmManagerClient.cpp
@@ -20,6 +20,7 @@
#include <jni.h>
#include <JNIHelp.h>
+#include <ScopedLocalRef.h>
#include <android_runtime/AndroidRuntime.h>
#include <drm/DrmInfo.h>
@@ -250,16 +251,18 @@ static jobject android_drm_DrmManagerClient_getConstraintsFromContent(
= getDrmManagerClientImpl(env, thiz)->getConstraints(uniqueId, &pathString, usage);
jclass localRef = env->FindClass("android/content/ContentValues");
+ jmethodID ContentValues_putByteArray =
+ env->GetMethodID(localRef, "put", "(Ljava/lang/String;[B)V");
+ jmethodID ContentValues_putString =
+ env->GetMethodID(localRef, "put", "(Ljava/lang/String;Ljava/lang/String;)V");
+ jmethodID ContentValues_constructor = env->GetMethodID(localRef, "<init>", "()V");
jobject constraints = NULL;
if (NULL != localRef && NULL != pConstraints) {
- // Get the constructor id
- jmethodID constructorId = env->GetMethodID(localRef, "<init>", "()V");
// create the java DrmConstraints object
- constraints = env->NewObject(localRef, constructorId);
+ constraints = env->NewObject(localRef, ContentValues_constructor);
DrmConstraints::KeyIterator keyIt = pConstraints->keyIterator();
-
while (keyIt.hasNext()) {
String8 key = keyIt.next();
@@ -267,18 +270,18 @@ static jobject android_drm_DrmManagerClient_getConstraintsFromContent(
if (DrmConstraints::EXTENDED_METADATA == key) {
const char* value = pConstraints->getAsByteArray(&key);
if (NULL != value) {
- jbyteArray dataArray = env->NewByteArray(strlen(value));
- env->SetByteArrayRegion(dataArray, 0, strlen(value), (jbyte*)value);
- env->CallVoidMethod(
- constraints, env->GetMethodID(localRef, "put", "(Ljava/lang/String;[B)V"),
- env->NewStringUTF(key.string()), dataArray);
+ ScopedLocalRef<jbyteArray> dataArray(env, env->NewByteArray(strlen(value)));
+ ScopedLocalRef<jstring> keyString(env, env->NewStringUTF(key.string()));
+ env->SetByteArrayRegion(dataArray.get(), 0, strlen(value), (jbyte*)value);
+ env->CallVoidMethod(constraints, ContentValues_putByteArray,
+ keyString.get(), dataArray.get());
}
} else {
String8 value = pConstraints->get(key);
- env->CallVoidMethod(
- constraints,
- env->GetMethodID(localRef, "put", "(Ljava/lang/String;Ljava/lang/String;)V"),
- env->NewStringUTF(key.string()), env->NewStringUTF(value.string()));
+ ScopedLocalRef<jstring> keyString(env, env->NewStringUTF(key.string()));
+ ScopedLocalRef<jstring> valueString(env, env->NewStringUTF(value.string()));
+ env->CallVoidMethod(constraints, ContentValues_putString,
+ keyString.get(), valueString.get());
}
}
}
@@ -297,8 +300,10 @@ static jobject android_drm_DrmManagerClient_getMetadataFromContent(
jobject metadata = NULL;
- jclass localRef = NULL;
- localRef = env->FindClass("android/content/ContentValues");
+ jclass localRef = env->FindClass("android/content/ContentValues");
+ jmethodID ContentValues_putString =
+ env->GetMethodID(localRef, "put", "(Ljava/lang/String;Ljava/lang/String;)V");
+
if (NULL != localRef && NULL != pMetadata) {
// Get the constructor id
jmethodID constructorId = NULL;
@@ -313,9 +318,10 @@ static jobject android_drm_DrmManagerClient_getMetadataFromContent(
// insert the entry<constraintKey, constraintValue>
// to newly created java object
String8 value = pMetadata->get(key);
- env->CallVoidMethod(metadata, env->GetMethodID(localRef, "put",
- "(Ljava/lang/String;Ljava/lang/String;)V"),
- env->NewStringUTF(key.string()), env->NewStringUTF(value.string()));
+ ScopedLocalRef<jstring> keyString(env, env->NewStringUTF(key.string()));
+ ScopedLocalRef<jstring> valueString(env, env->NewStringUTF(value.string()));
+ env->CallVoidMethod(metadata, ContentValues_putString,
+ keyString.get(), valueString.get());
}
}
}
@@ -426,29 +432,30 @@ static jobject android_drm_DrmManagerClient_processDrmInfo(
DrmInfo drmInfo(mInfoType, buffer, mMimeType);
jclass clazz = env->FindClass("android/drm/DrmInfo");
+ jmethodID DrmInfo_get = env->GetMethodID(clazz, "get", "(Ljava/lang/String;)Ljava/lang/Object;");
jobject keyIterator
= env->CallObjectMethod(drmInfoObject,
env->GetMethodID(clazz, "keyIterator", "()Ljava/util/Iterator;"));
- jmethodID hasNextId = env->GetMethodID(env->FindClass("java/util/Iterator"), "hasNext", "()Z");
-
- while (env->CallBooleanMethod(keyIterator, hasNextId)) {
- jstring key = (jstring) env->CallObjectMethod(keyIterator,
- env->GetMethodID(env->FindClass("java/util/Iterator"),
- "next", "()Ljava/lang/Object;"));
-
- jobject valueObject = env->CallObjectMethod(drmInfoObject,
- env->GetMethodID(clazz, "get", "(Ljava/lang/String;)Ljava/lang/Object;"), key);
-
- jstring valString = NULL;
- if (NULL != valueObject) {
- valString = (jstring) env->CallObjectMethod(valueObject,
- env->GetMethodID(env->FindClass("java/lang/Object"),
- "toString", "()Ljava/lang/String;"));
+ jclass Iterator_class = env->FindClass("java/util/Iterator");
+ jmethodID Iterator_hasNext = env->GetMethodID(Iterator_class, "hasNext", "()Z");
+ jmethodID Iterator_next = env->GetMethodID(Iterator_class, "next", "()Ljava/lang/Object;");
+
+ jclass Object_class = env->FindClass("java/lang/Object");
+ jmethodID Object_toString = env->GetMethodID(Object_class, "toString", "()Ljava/lang/String;");
+
+ while (env->CallBooleanMethod(keyIterator, Iterator_hasNext)) {
+ ScopedLocalRef<jstring> key(env,
+ (jstring) env->CallObjectMethod(keyIterator, Iterator_next));
+ ScopedLocalRef<jobject> valueObject(env,
+ env->CallObjectMethod(drmInfoObject, DrmInfo_get, key.get()));
+ ScopedLocalRef<jstring> valString(env, NULL);
+ if (NULL != valueObject.get()) {
+ valString.reset((jstring) env->CallObjectMethod(valueObject.get(), Object_toString));
}
- String8 keyString = Utility::getStringValue(env, key);
- String8 valueString = Utility::getStringValue(env, valString);
+ String8 keyString = Utility::getStringValue(env, key.get());
+ String8 valueString = Utility::getStringValue(env, valString.get());
ALOGV("Key: %s | Value: %s", keyString.string(), valueString.string());
drmInfo.put(keyString, valueString);
@@ -508,20 +515,21 @@ static jobject android_drm_DrmManagerClient_acquireDrmInfo(
jobject keyIterator
= env->CallObjectMethod(drmInfoRequest,
env->GetMethodID(clazz, "keyIterator", "()Ljava/util/Iterator;"));
+ jmethodID DrmInfoRequest_get = env->GetMethodID(clazz,
+ "get", "(Ljava/lang/String;)Ljava/lang/Object;");
- jmethodID hasNextId = env->GetMethodID(env->FindClass("java/util/Iterator"), "hasNext", "()Z");
+ jclass Iterator_class = env->FindClass("java/util/Iterator");
+ jmethodID Iterator_hasNext = env->GetMethodID(Iterator_class, "hasNext", "()Z");
+ jmethodID Iterator_next = env->GetMethodID(Iterator_class, "next", "()Ljava/lang/Object;");
- while (env->CallBooleanMethod(keyIterator, hasNextId)) {
- jstring key
- = (jstring) env->CallObjectMethod(keyIterator,
- env->GetMethodID(env->FindClass("java/util/Iterator"),
- "next", "()Ljava/lang/Object;"));
+ while (env->CallBooleanMethod(keyIterator, Iterator_hasNext)) {
+ ScopedLocalRef<jstring> key(env,
+ (jstring) env->CallObjectMethod(keyIterator, Iterator_next));
+ ScopedLocalRef<jstring> value(env,
+ (jstring) env->CallObjectMethod(drmInfoRequest, DrmInfoRequest_get, key.get()));
- jstring value = (jstring) env->CallObjectMethod(drmInfoRequest,
- env->GetMethodID(clazz, "get", "(Ljava/lang/String;)Ljava/lang/Object;"), key);
-
- String8 keyString = Utility::getStringValue(env, key);
- String8 valueString = Utility::getStringValue(env, value);
+ String8 keyString = Utility::getStringValue(env, key.get());
+ String8 valueString = Utility::getStringValue(env, value.get());
ALOGV("Key: %s | Value: %s", keyString.string(), valueString.string());
drmInfoReq.put(keyString, valueString);
@@ -552,9 +560,10 @@ static jobject android_drm_DrmManagerClient_acquireDrmInfo(
while (it.hasNext()) {
String8 key = it.next();
String8 value = pDrmInfo->get(key);
-
+ ScopedLocalRef<jstring> keyString(env, env->NewStringUTF(key.string()));
+ ScopedLocalRef<jstring> valueString(env, env->NewStringUTF(value.string()));
env->CallVoidMethod(drmInfoObject, putMethodId,
- env->NewStringUTF(key.string()), env->NewStringUTF(value.string()));
+ keyString.get(), valueString.get());
}
}
delete [] pDrmInfo->getData().data;
diff --git a/keystore/java/android/security/AndroidKeyStore.java b/keystore/java/android/security/AndroidKeyStore.java
new file mode 100644
index 0000000..a629f8d
--- /dev/null
+++ b/keystore/java/android/security/AndroidKeyStore.java
@@ -0,0 +1,463 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security;
+
+import org.apache.harmony.xnet.provider.jsse.OpenSSLEngine;
+
+import android.util.Log;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.KeyStoreException;
+import java.security.KeyStoreSpi;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+/**
+ * A java.security.KeyStore interface for the Android KeyStore. This class is
+ * hidden from the Android API, but an instance of it can be created via the
+ * {@link java.security.KeyStore#getInstance(String)
+ * KeyStore.getInstance("AndroidKeyStore")} interface. This returns a
+ * java.security.KeyStore backed by this "AndroidKeyStore" implementation.
+ * <p>
+ * This is built on top of Android's keystore daemon. The convention of alias
+ * use is:
+ * <p>
+ * PrivateKeyEntry will have a Credentials.USER_PRIVATE_KEY as the private key,
+ * Credentials.USER_CERTIFICATE as the first certificate in the chain (the one
+ * that corresponds to the private key), and then a Credentials.CA_CERTIFICATE
+ * entry which will have the rest of the chain concatenated in BER format.
+ * <p>
+ * TrustedCertificateEntry will just have a Credentials.CA_CERTIFICATE entry
+ * with a single certificate.
+ *
+ * @hide
+ */
+public class AndroidKeyStore extends KeyStoreSpi {
+ public static final String NAME = "AndroidKeyStore";
+
+ private android.security.KeyStore mKeyStore;
+
+ @Override
+ public Key engineGetKey(String alias, char[] password) throws NoSuchAlgorithmException,
+ UnrecoverableKeyException {
+ if (!isKeyEntry(alias)) {
+ return null;
+ }
+
+ final OpenSSLEngine engine = OpenSSLEngine.getInstance("keystore");
+ try {
+ return engine.getPrivateKeyById(Credentials.USER_PRIVATE_KEY + alias);
+ } catch (InvalidKeyException e) {
+ UnrecoverableKeyException t = new UnrecoverableKeyException("Can't get key");
+ t.initCause(e);
+ throw t;
+ }
+ }
+
+ @Override
+ public Certificate[] engineGetCertificateChain(String alias) {
+ final X509Certificate leaf = (X509Certificate) engineGetCertificate(alias);
+ if (leaf == null) {
+ return null;
+ }
+
+ final Certificate[] caList;
+
+ final byte[] caBytes = mKeyStore.get(Credentials.CA_CERTIFICATE + alias);
+ if (caBytes != null) {
+ final Collection<X509Certificate> caChain = toCertificates(caBytes);
+
+ caList = new Certificate[caChain.size() + 1];
+
+ final Iterator<X509Certificate> it = caChain.iterator();
+ int i = 1;
+ while (it.hasNext()) {
+ caList[i++] = it.next();
+ }
+ } else {
+ caList = new Certificate[1];
+ }
+
+ caList[0] = leaf;
+
+ return caList;
+ }
+
+ @Override
+ public Certificate engineGetCertificate(String alias) {
+ byte[] certificate = mKeyStore.get(Credentials.USER_CERTIFICATE + alias);
+ if (certificate != null) {
+ return toCertificate(certificate);
+ }
+
+ certificate = mKeyStore.get(Credentials.CA_CERTIFICATE + alias);
+ if (certificate != null) {
+ return toCertificate(certificate);
+ }
+
+ return null;
+ }
+
+ private static X509Certificate toCertificate(byte[] bytes) {
+ try {
+ final CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
+ return (X509Certificate) certFactory
+ .generateCertificate(new ByteArrayInputStream(bytes));
+ } catch (CertificateException e) {
+ Log.w(NAME, "Couldn't parse certificate in keystore", e);
+ return null;
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private static Collection<X509Certificate> toCertificates(byte[] bytes) {
+ try {
+ final CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
+ return (Collection<X509Certificate>) certFactory
+ .generateCertificates(new ByteArrayInputStream(bytes));
+ } catch (CertificateException e) {
+ Log.w(NAME, "Couldn't parse certificates in keystore", e);
+ return new ArrayList<X509Certificate>();
+ }
+ }
+
+ private Date getModificationDate(String alias) {
+ final long epochMillis = mKeyStore.getmtime(alias);
+ if (epochMillis == -1L) {
+ return null;
+ }
+
+ return new Date(epochMillis);
+ }
+
+ @Override
+ public Date engineGetCreationDate(String alias) {
+ Date d = getModificationDate(Credentials.USER_PRIVATE_KEY + alias);
+ if (d != null) {
+ return d;
+ }
+
+ d = getModificationDate(Credentials.USER_CERTIFICATE + alias);
+ if (d != null) {
+ return d;
+ }
+
+ return getModificationDate(Credentials.CA_CERTIFICATE + alias);
+ }
+
+ @Override
+ public void engineSetKeyEntry(String alias, Key key, char[] password, Certificate[] chain)
+ throws KeyStoreException {
+ if ((password != null) && (password.length > 0)) {
+ throw new KeyStoreException("entries cannot be protected with passwords");
+ }
+
+ if (key instanceof PrivateKey) {
+ setPrivateKeyEntry(alias, (PrivateKey) key, chain);
+ } else {
+ throw new KeyStoreException("Only PrivateKeys are supported");
+ }
+ }
+
+ private void setPrivateKeyEntry(String alias, PrivateKey key, Certificate[] chain)
+ throws KeyStoreException {
+ // Make sure the PrivateKey format is the one we support.
+ final String keyFormat = key.getFormat();
+ if ((keyFormat == null) || (!"PKCS#8".equals(keyFormat))) {
+ throw new KeyStoreException(
+ "Only PrivateKeys that can be encoded into PKCS#8 are supported");
+ }
+
+ // Make sure we can actually encode the key.
+ final byte[] keyBytes = key.getEncoded();
+ if (keyBytes == null) {
+ throw new KeyStoreException("PrivateKey has no encoding");
+ }
+
+ // Make sure the chain exists since this is a PrivateKey
+ if ((chain == null) || (chain.length == 0)) {
+ throw new KeyStoreException("Must supply at least one Certificate with PrivateKey");
+ }
+
+ // Do chain type checking.
+ X509Certificate[] x509chain = new X509Certificate[chain.length];
+ for (int i = 0; i < chain.length; i++) {
+ if (!"X.509".equals(chain[i].getType())) {
+ throw new KeyStoreException("Certificates must be in X.509 format: invalid cert #"
+ + i);
+ }
+
+ if (!(chain[i] instanceof X509Certificate)) {
+ throw new KeyStoreException("Certificates must be in X.509 format: invalid cert #"
+ + i);
+ }
+
+ x509chain[i] = (X509Certificate) chain[i];
+ }
+
+ final byte[] userCertBytes;
+ try {
+ userCertBytes = x509chain[0].getEncoded();
+ } catch (CertificateEncodingException e) {
+ throw new KeyStoreException("Couldn't encode certificate #1", e);
+ }
+
+ /*
+ * If we have a chain, store it in the CA certificate slot for this
+ * alias as concatenated DER-encoded certificates. These can be
+ * deserialized by {@link CertificateFactory#generateCertificates}.
+ */
+ final byte[] chainBytes;
+ if (chain.length > 1) {
+ /*
+ * The chain is passed in as {user_cert, ca_cert_1, ca_cert_2, ...}
+ * so we only need the certificates starting at index 1.
+ */
+ final byte[][] certsBytes = new byte[x509chain.length - 1][];
+ int totalCertLength = 0;
+ for (int i = 0; i < certsBytes.length; i++) {
+ try {
+ certsBytes[i] = x509chain[i + 1].getEncoded();
+ totalCertLength += certsBytes[i].length;
+ } catch (CertificateEncodingException e) {
+ throw new KeyStoreException("Can't encode Certificate #" + i, e);
+ }
+ }
+
+ /*
+ * Serialize this into one byte array so we can later call
+ * CertificateFactory#generateCertificates to recover them.
+ */
+ chainBytes = new byte[totalCertLength];
+ int outputOffset = 0;
+ for (int i = 0; i < certsBytes.length; i++) {
+ final int certLength = certsBytes[i].length;
+ System.arraycopy(certsBytes[i], 0, chainBytes, outputOffset, certLength);
+ outputOffset += certLength;
+ certsBytes[i] = null;
+ }
+ } else {
+ chainBytes = null;
+ }
+
+ /*
+ * Make sure we clear out all the types we know about before trying to
+ * write.
+ */
+ deleteAllTypesForAlias(alias);
+
+ if (!mKeyStore.importKey(Credentials.USER_PRIVATE_KEY + alias, keyBytes)) {
+ throw new KeyStoreException("Couldn't put private key in keystore");
+ } else if (!mKeyStore.put(Credentials.USER_CERTIFICATE + alias, userCertBytes)) {
+ throw new KeyStoreException("Couldn't put certificate #1 in keystore");
+ } else if (chainBytes != null
+ && !mKeyStore.put(Credentials.CA_CERTIFICATE + alias, chainBytes)) {
+ throw new KeyStoreException("Couldn't put certificate chain in keystore");
+ }
+ }
+
+ @Override
+ public void engineSetKeyEntry(String alias, byte[] userKey, Certificate[] chain)
+ throws KeyStoreException {
+ throw new RuntimeException("Operation not supported because key encoding is unknown");
+ }
+
+ @Override
+ public void engineSetCertificateEntry(String alias, Certificate cert) throws KeyStoreException {
+ if (isKeyEntry(alias)) {
+ throw new KeyStoreException("Entry exists and is not a trusted certificate");
+ }
+
+ final byte[] encoded;
+ try {
+ encoded = cert.getEncoded();
+ } catch (CertificateEncodingException e) {
+ throw new KeyStoreException(e);
+ }
+
+ if (!mKeyStore.put(Credentials.CA_CERTIFICATE + alias, encoded)) {
+ throw new KeyStoreException("Couldn't insert certificate; is KeyStore initialized?");
+ }
+ }
+
+ @Override
+ public void engineDeleteEntry(String alias) throws KeyStoreException {
+ if (!deleteAllTypesForAlias(alias)) {
+ throw new KeyStoreException("No such entry " + alias);
+ }
+ }
+
+ /**
+ * Delete all types (private key, certificate, CA certificate) for a
+ * particular {@code alias}. All three can exist for any given alias.
+ * Returns {@code true} if there was at least one of those types.
+ */
+ private boolean deleteAllTypesForAlias(String alias) {
+ /*
+ * Make sure every type is deleted. There can be all three types, so
+ * don't use a conditional here.
+ */
+ return mKeyStore.delKey(Credentials.USER_PRIVATE_KEY + alias)
+ | mKeyStore.delete(Credentials.USER_CERTIFICATE + alias)
+ | mKeyStore.delete(Credentials.CA_CERTIFICATE + alias);
+ }
+
+ private Set<String> getUniqueAliases() {
+ final String[] rawAliases = mKeyStore.saw("");
+ if (rawAliases == null) {
+ return new HashSet<String>();
+ }
+
+ final Set<String> aliases = new HashSet<String>(rawAliases.length);
+ for (String alias : rawAliases) {
+ final int idx = alias.indexOf('_');
+ if ((idx == -1) || (alias.length() <= idx)) {
+ Log.e(NAME, "invalid alias: " + alias);
+ continue;
+ }
+
+ aliases.add(new String(alias.substring(idx + 1)));
+ }
+
+ return aliases;
+ }
+
+ @Override
+ public Enumeration<String> engineAliases() {
+ return Collections.enumeration(getUniqueAliases());
+ }
+
+ @Override
+ public boolean engineContainsAlias(String alias) {
+ return mKeyStore.contains(Credentials.USER_PRIVATE_KEY + alias)
+ || mKeyStore.contains(Credentials.USER_CERTIFICATE + alias)
+ || mKeyStore.contains(Credentials.CA_CERTIFICATE + alias);
+ }
+
+ @Override
+ public int engineSize() {
+ return getUniqueAliases().size();
+ }
+
+ @Override
+ public boolean engineIsKeyEntry(String alias) {
+ return isKeyEntry(alias);
+ }
+
+ private boolean isKeyEntry(String alias) {
+ return mKeyStore.contains(Credentials.USER_PRIVATE_KEY + alias);
+ }
+
+ @Override
+ public boolean engineIsCertificateEntry(String alias) {
+ return !isKeyEntry(alias) && mKeyStore.contains(Credentials.CA_CERTIFICATE + alias);
+ }
+
+ @Override
+ public String engineGetCertificateAlias(Certificate cert) {
+ if (cert == null) {
+ return null;
+ }
+
+ final Set<String> nonCaEntries = new HashSet<String>();
+
+ /*
+ * First scan the PrivateKeyEntry types. The KeyStoreSpi documentation
+ * says to only compare the first certificate in the chain which is
+ * equivalent to the USER_CERTIFICATE prefix for the Android keystore
+ * convention.
+ */
+ final String[] certAliases = mKeyStore.saw(Credentials.USER_CERTIFICATE);
+ for (String alias : certAliases) {
+ final byte[] certBytes = mKeyStore.get(Credentials.USER_CERTIFICATE + alias);
+ if (certBytes == null) {
+ continue;
+ }
+
+ final Certificate c = toCertificate(certBytes);
+ nonCaEntries.add(alias);
+
+ if (cert.equals(c)) {
+ return alias;
+ }
+ }
+
+ /*
+ * Look at all the TrustedCertificateEntry types. Skip all the
+ * PrivateKeyEntry we looked at above.
+ */
+ final String[] caAliases = mKeyStore.saw(Credentials.CA_CERTIFICATE);
+ for (String alias : caAliases) {
+ if (nonCaEntries.contains(alias)) {
+ continue;
+ }
+
+ final byte[] certBytes = mKeyStore.get(Credentials.CA_CERTIFICATE + alias);
+ if (certBytes == null) {
+ continue;
+ }
+
+ final Certificate c = toCertificate(mKeyStore.get(Credentials.CA_CERTIFICATE + alias));
+ if (cert.equals(c)) {
+ return alias;
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public void engineStore(OutputStream stream, char[] password) throws IOException,
+ NoSuchAlgorithmException, CertificateException {
+ throw new UnsupportedOperationException("Can not serialize AndroidKeyStore to OutputStream");
+ }
+
+ @Override
+ public void engineLoad(InputStream stream, char[] password) throws IOException,
+ NoSuchAlgorithmException, CertificateException {
+ if (stream != null) {
+ throw new IllegalArgumentException("InputStream not supported");
+ }
+
+ if (password != null) {
+ throw new IllegalArgumentException("password not supported");
+ }
+
+ // Unfortunate name collision.
+ mKeyStore = android.security.KeyStore.getInstance();
+ }
+
+}
diff --git a/keystore/java/android/security/AndroidKeyStoreProvider.java b/keystore/java/android/security/AndroidKeyStoreProvider.java
new file mode 100644
index 0000000..df22f58
--- /dev/null
+++ b/keystore/java/android/security/AndroidKeyStoreProvider.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security;
+
+import java.security.Provider;
+
+/**
+ * A provider focused on providing JCA interfaces for the Android KeyStore.
+ *
+ * @hide
+ */
+public class AndroidKeyStoreProvider extends Provider {
+ public static final String PROVIDER_NAME = "AndroidKeyStoreProvider";
+
+ public AndroidKeyStoreProvider() {
+ super(PROVIDER_NAME, 1.0, "Android KeyStore security provider");
+
+ put("KeyStore." + AndroidKeyStore.NAME, AndroidKeyStore.class.getName());
+ }
+}
diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
index f49c429..4637991 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -26,6 +26,7 @@ import java.io.UTFDataFormatException;
import java.nio.charset.Charsets;
import java.nio.charset.ModifiedUtf8;
import java.util.ArrayList;
+import java.util.Date;
/**
* @hide This should not be made public in its present form because it
@@ -228,6 +229,23 @@ public class KeyStore {
return ungrant(getKeyBytes(key), getUidBytes(uid));
}
+ private long getmtime(byte[] key) {
+ final ArrayList<byte[]> values = execute('c', key);
+ if (values == null || values.isEmpty()) {
+ return -1L;
+ }
+
+ return Long.parseLong(new String(values.get(0))) * 1000L;
+ }
+
+ /**
+ * Returns the last modification time of the key in milliseconds since the
+ * epoch. Will return -1L if the key could not be found or other error.
+ */
+ public long getmtime(String key) {
+ return getmtime(getKeyBytes(key));
+ }
+
public int getLastError() {
return mError;
}
diff --git a/keystore/tests/src/android/security/AndroidKeyStoreTest.java b/keystore/tests/src/android/security/AndroidKeyStoreTest.java
new file mode 100644
index 0000000..bff01b8
--- /dev/null
+++ b/keystore/tests/src/android/security/AndroidKeyStoreTest.java
@@ -0,0 +1,1383 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.security;
+
+import android.test.AndroidTestCase;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.security.Key;
+import java.security.KeyFactory;
+import java.security.KeyStore.Entry;
+import java.security.KeyStore.PrivateKeyEntry;
+import java.security.KeyStore.TrustedCertificateEntry;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+public class AndroidKeyStoreTest extends AndroidTestCase {
+ private android.security.KeyStore mAndroidKeyStore;
+
+ private java.security.KeyStore mKeyStore;
+
+ private static final String TEST_ALIAS_1 = "test1";
+
+ private static final String TEST_ALIAS_2 = "test2";
+
+ private static final String TEST_ALIAS_3 = "test3";
+
+ /*
+ * The keys and certificates below are generated with:
+ *
+ * openssl req -new -x509 -days 3650 -extensions v3_ca -keyout cakey.pem -out cacert.pem
+ * openssl req -newkey rsa:1024 -keyout userkey.pem -nodes -days 3650 -out userkey.req
+ * mkdir -p demoCA/newcerts
+ * touch demoCA/index.txt
+ * echo "01" > demoCA/serial
+ * openssl ca -out usercert.pem -in userkey.req -cert cacert.pem -keyfile cakey.pem -days 3650
+ */
+
+ /**
+ * Generated from above and converted with:
+ *
+ * openssl x509 -outform d -in cacert.pem | xxd -i | sed 's/0x/(byte) 0x/g'
+ */
+ private static final byte[] FAKE_CA_1 = {
+ (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0xce, (byte) 0x30, (byte) 0x82,
+ (byte) 0x02, (byte) 0x37, (byte) 0xa0, (byte) 0x03, (byte) 0x02, (byte) 0x01,
+ (byte) 0x02, (byte) 0x02, (byte) 0x09, (byte) 0x00, (byte) 0xe1, (byte) 0x6a,
+ (byte) 0xa2, (byte) 0xf4, (byte) 0x2e, (byte) 0x55, (byte) 0x48, (byte) 0x0a,
+ (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86,
+ (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01,
+ (byte) 0x05, (byte) 0x05, (byte) 0x00, (byte) 0x30, (byte) 0x4f, (byte) 0x31,
+ (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55,
+ (byte) 0x04, (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x55, (byte) 0x53,
+ (byte) 0x31, (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03,
+ (byte) 0x55, (byte) 0x04, (byte) 0x08, (byte) 0x13, (byte) 0x02, (byte) 0x43,
+ (byte) 0x41, (byte) 0x31, (byte) 0x16, (byte) 0x30, (byte) 0x14, (byte) 0x06,
+ (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x07, (byte) 0x13, (byte) 0x0d,
+ (byte) 0x4d, (byte) 0x6f, (byte) 0x75, (byte) 0x6e, (byte) 0x74, (byte) 0x61,
+ (byte) 0x69, (byte) 0x6e, (byte) 0x20, (byte) 0x56, (byte) 0x69, (byte) 0x65,
+ (byte) 0x77, (byte) 0x31, (byte) 0x1b, (byte) 0x30, (byte) 0x19, (byte) 0x06,
+ (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0a, (byte) 0x13, (byte) 0x12,
+ (byte) 0x41, (byte) 0x6e, (byte) 0x64, (byte) 0x72, (byte) 0x6f, (byte) 0x69,
+ (byte) 0x64, (byte) 0x20, (byte) 0x54, (byte) 0x65, (byte) 0x73, (byte) 0x74,
+ (byte) 0x20, (byte) 0x43, (byte) 0x61, (byte) 0x73, (byte) 0x65, (byte) 0x73,
+ (byte) 0x30, (byte) 0x1e, (byte) 0x17, (byte) 0x0d, (byte) 0x31, (byte) 0x32,
+ (byte) 0x30, (byte) 0x38, (byte) 0x31, (byte) 0x34, (byte) 0x31, (byte) 0x36,
+ (byte) 0x35, (byte) 0x35, (byte) 0x34, (byte) 0x34, (byte) 0x5a, (byte) 0x17,
+ (byte) 0x0d, (byte) 0x32, (byte) 0x32, (byte) 0x30, (byte) 0x38, (byte) 0x31,
+ (byte) 0x32, (byte) 0x31, (byte) 0x36, (byte) 0x35, (byte) 0x35, (byte) 0x34,
+ (byte) 0x34, (byte) 0x5a, (byte) 0x30, (byte) 0x4f, (byte) 0x31, (byte) 0x0b,
+ (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
+ (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x55, (byte) 0x53, (byte) 0x31,
+ (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55,
+ (byte) 0x04, (byte) 0x08, (byte) 0x13, (byte) 0x02, (byte) 0x43, (byte) 0x41,
+ (byte) 0x31, (byte) 0x16, (byte) 0x30, (byte) 0x14, (byte) 0x06, (byte) 0x03,
+ (byte) 0x55, (byte) 0x04, (byte) 0x07, (byte) 0x13, (byte) 0x0d, (byte) 0x4d,
+ (byte) 0x6f, (byte) 0x75, (byte) 0x6e, (byte) 0x74, (byte) 0x61, (byte) 0x69,
+ (byte) 0x6e, (byte) 0x20, (byte) 0x56, (byte) 0x69, (byte) 0x65, (byte) 0x77,
+ (byte) 0x31, (byte) 0x1b, (byte) 0x30, (byte) 0x19, (byte) 0x06, (byte) 0x03,
+ (byte) 0x55, (byte) 0x04, (byte) 0x0a, (byte) 0x13, (byte) 0x12, (byte) 0x41,
+ (byte) 0x6e, (byte) 0x64, (byte) 0x72, (byte) 0x6f, (byte) 0x69, (byte) 0x64,
+ (byte) 0x20, (byte) 0x54, (byte) 0x65, (byte) 0x73, (byte) 0x74, (byte) 0x20,
+ (byte) 0x43, (byte) 0x61, (byte) 0x73, (byte) 0x65, (byte) 0x73, (byte) 0x30,
+ (byte) 0x81, (byte) 0x9f, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09,
+ (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d,
+ (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x03,
+ (byte) 0x81, (byte) 0x8d, (byte) 0x00, (byte) 0x30, (byte) 0x81, (byte) 0x89,
+ (byte) 0x02, (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0xa3, (byte) 0x72,
+ (byte) 0xab, (byte) 0xd0, (byte) 0xe4, (byte) 0xad, (byte) 0x2f, (byte) 0xe7,
+ (byte) 0xe2, (byte) 0x79, (byte) 0x07, (byte) 0x36, (byte) 0x3d, (byte) 0x0c,
+ (byte) 0x8d, (byte) 0x42, (byte) 0x9a, (byte) 0x0a, (byte) 0x33, (byte) 0x64,
+ (byte) 0xb3, (byte) 0xcd, (byte) 0xb2, (byte) 0xd7, (byte) 0x3a, (byte) 0x42,
+ (byte) 0x06, (byte) 0x77, (byte) 0x45, (byte) 0x29, (byte) 0xe9, (byte) 0xcb,
+ (byte) 0xb7, (byte) 0x4a, (byte) 0xd6, (byte) 0xee, (byte) 0xad, (byte) 0x01,
+ (byte) 0x91, (byte) 0x9b, (byte) 0x0c, (byte) 0x59, (byte) 0xa1, (byte) 0x03,
+ (byte) 0xfa, (byte) 0xf0, (byte) 0x5a, (byte) 0x7c, (byte) 0x4f, (byte) 0xf7,
+ (byte) 0x8d, (byte) 0x36, (byte) 0x0f, (byte) 0x1f, (byte) 0x45, (byte) 0x7d,
+ (byte) 0x1b, (byte) 0x31, (byte) 0xa1, (byte) 0x35, (byte) 0x0b, (byte) 0x00,
+ (byte) 0xed, (byte) 0x7a, (byte) 0xb6, (byte) 0xc8, (byte) 0x4e, (byte) 0xa9,
+ (byte) 0x86, (byte) 0x4c, (byte) 0x7b, (byte) 0x99, (byte) 0x57, (byte) 0x41,
+ (byte) 0x12, (byte) 0xef, (byte) 0x6b, (byte) 0xbc, (byte) 0x3d, (byte) 0x60,
+ (byte) 0xf2, (byte) 0x99, (byte) 0x1a, (byte) 0xcd, (byte) 0xed, (byte) 0x56,
+ (byte) 0xa4, (byte) 0xe5, (byte) 0x36, (byte) 0x9f, (byte) 0x24, (byte) 0x1f,
+ (byte) 0xdc, (byte) 0x89, (byte) 0x40, (byte) 0xc8, (byte) 0x99, (byte) 0x92,
+ (byte) 0xab, (byte) 0x4a, (byte) 0xb5, (byte) 0x61, (byte) 0x45, (byte) 0x62,
+ (byte) 0xff, (byte) 0xa3, (byte) 0x45, (byte) 0x65, (byte) 0xaf, (byte) 0xf6,
+ (byte) 0x27, (byte) 0x30, (byte) 0x51, (byte) 0x0e, (byte) 0x0e, (byte) 0xeb,
+ (byte) 0x79, (byte) 0x0c, (byte) 0xbe, (byte) 0xb3, (byte) 0x0a, (byte) 0x6f,
+ (byte) 0x29, (byte) 0x06, (byte) 0xdc, (byte) 0x2f, (byte) 0x6b, (byte) 0x51,
+ (byte) 0x02, (byte) 0x03, (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0xa3,
+ (byte) 0x81, (byte) 0xb1, (byte) 0x30, (byte) 0x81, (byte) 0xae, (byte) 0x30,
+ (byte) 0x1d, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x0e,
+ (byte) 0x04, (byte) 0x16, (byte) 0x04, (byte) 0x14, (byte) 0x33, (byte) 0x05,
+ (byte) 0xee, (byte) 0xfe, (byte) 0x6f, (byte) 0x60, (byte) 0xc7, (byte) 0xf9,
+ (byte) 0xa9, (byte) 0xd2, (byte) 0x73, (byte) 0x5c, (byte) 0x8f, (byte) 0x6d,
+ (byte) 0xa2, (byte) 0x2f, (byte) 0x97, (byte) 0x8e, (byte) 0x5d, (byte) 0x51,
+ (byte) 0x30, (byte) 0x7f, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d,
+ (byte) 0x23, (byte) 0x04, (byte) 0x78, (byte) 0x30, (byte) 0x76, (byte) 0x80,
+ (byte) 0x14, (byte) 0x33, (byte) 0x05, (byte) 0xee, (byte) 0xfe, (byte) 0x6f,
+ (byte) 0x60, (byte) 0xc7, (byte) 0xf9, (byte) 0xa9, (byte) 0xd2, (byte) 0x73,
+ (byte) 0x5c, (byte) 0x8f, (byte) 0x6d, (byte) 0xa2, (byte) 0x2f, (byte) 0x97,
+ (byte) 0x8e, (byte) 0x5d, (byte) 0x51, (byte) 0xa1, (byte) 0x53, (byte) 0xa4,
+ (byte) 0x51, (byte) 0x30, (byte) 0x4f, (byte) 0x31, (byte) 0x0b, (byte) 0x30,
+ (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x06,
+ (byte) 0x13, (byte) 0x02, (byte) 0x55, (byte) 0x53, (byte) 0x31, (byte) 0x0b,
+ (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
+ (byte) 0x08, (byte) 0x13, (byte) 0x02, (byte) 0x43, (byte) 0x41, (byte) 0x31,
+ (byte) 0x16, (byte) 0x30, (byte) 0x14, (byte) 0x06, (byte) 0x03, (byte) 0x55,
+ (byte) 0x04, (byte) 0x07, (byte) 0x13, (byte) 0x0d, (byte) 0x4d, (byte) 0x6f,
+ (byte) 0x75, (byte) 0x6e, (byte) 0x74, (byte) 0x61, (byte) 0x69, (byte) 0x6e,
+ (byte) 0x20, (byte) 0x56, (byte) 0x69, (byte) 0x65, (byte) 0x77, (byte) 0x31,
+ (byte) 0x1b, (byte) 0x30, (byte) 0x19, (byte) 0x06, (byte) 0x03, (byte) 0x55,
+ (byte) 0x04, (byte) 0x0a, (byte) 0x13, (byte) 0x12, (byte) 0x41, (byte) 0x6e,
+ (byte) 0x64, (byte) 0x72, (byte) 0x6f, (byte) 0x69, (byte) 0x64, (byte) 0x20,
+ (byte) 0x54, (byte) 0x65, (byte) 0x73, (byte) 0x74, (byte) 0x20, (byte) 0x43,
+ (byte) 0x61, (byte) 0x73, (byte) 0x65, (byte) 0x73, (byte) 0x82, (byte) 0x09,
+ (byte) 0x00, (byte) 0xe1, (byte) 0x6a, (byte) 0xa2, (byte) 0xf4, (byte) 0x2e,
+ (byte) 0x55, (byte) 0x48, (byte) 0x0a, (byte) 0x30, (byte) 0x0c, (byte) 0x06,
+ (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x13, (byte) 0x04, (byte) 0x05,
+ (byte) 0x30, (byte) 0x03, (byte) 0x01, (byte) 0x01, (byte) 0xff, (byte) 0x30,
+ (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86, (byte) 0x48,
+ (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01, (byte) 0x05,
+ (byte) 0x05, (byte) 0x00, (byte) 0x03, (byte) 0x81, (byte) 0x81, (byte) 0x00,
+ (byte) 0x8c, (byte) 0x30, (byte) 0x42, (byte) 0xfa, (byte) 0xeb, (byte) 0x1a,
+ (byte) 0x26, (byte) 0xeb, (byte) 0xda, (byte) 0x56, (byte) 0x32, (byte) 0xf2,
+ (byte) 0x9d, (byte) 0xa5, (byte) 0x24, (byte) 0xd8, (byte) 0x3a, (byte) 0xda,
+ (byte) 0x30, (byte) 0xa6, (byte) 0x8b, (byte) 0x46, (byte) 0xfe, (byte) 0xfe,
+ (byte) 0xdb, (byte) 0xf1, (byte) 0xe6, (byte) 0xe1, (byte) 0x7c, (byte) 0x1b,
+ (byte) 0xe7, (byte) 0x77, (byte) 0x00, (byte) 0xa1, (byte) 0x1c, (byte) 0x19,
+ (byte) 0x17, (byte) 0x73, (byte) 0xb0, (byte) 0xf0, (byte) 0x9d, (byte) 0xf3,
+ (byte) 0x4f, (byte) 0xb6, (byte) 0xbc, (byte) 0xc7, (byte) 0x47, (byte) 0x85,
+ (byte) 0x2a, (byte) 0x4a, (byte) 0xa1, (byte) 0xa5, (byte) 0x58, (byte) 0xf5,
+ (byte) 0xc5, (byte) 0x1a, (byte) 0x51, (byte) 0xb1, (byte) 0x04, (byte) 0x80,
+ (byte) 0xee, (byte) 0x3a, (byte) 0xec, (byte) 0x2f, (byte) 0xe1, (byte) 0xfd,
+ (byte) 0x58, (byte) 0xeb, (byte) 0xed, (byte) 0x82, (byte) 0x9e, (byte) 0x38,
+ (byte) 0xa3, (byte) 0x24, (byte) 0x75, (byte) 0xf7, (byte) 0x3e, (byte) 0xc2,
+ (byte) 0xc5, (byte) 0x27, (byte) 0xeb, (byte) 0x6f, (byte) 0x7b, (byte) 0x50,
+ (byte) 0xda, (byte) 0x43, (byte) 0xdc, (byte) 0x3b, (byte) 0x0b, (byte) 0x6f,
+ (byte) 0x78, (byte) 0x8f, (byte) 0xb0, (byte) 0x66, (byte) 0xe1, (byte) 0x12,
+ (byte) 0x87, (byte) 0x5f, (byte) 0x97, (byte) 0x7b, (byte) 0xca, (byte) 0x14,
+ (byte) 0x79, (byte) 0xf7, (byte) 0xe8, (byte) 0x6c, (byte) 0x72, (byte) 0xdb,
+ (byte) 0x91, (byte) 0x65, (byte) 0x17, (byte) 0x54, (byte) 0xe0, (byte) 0x74,
+ (byte) 0x1d, (byte) 0xac, (byte) 0x47, (byte) 0x04, (byte) 0x12, (byte) 0xe0,
+ (byte) 0xc3, (byte) 0x66, (byte) 0x19, (byte) 0x05, (byte) 0x2e, (byte) 0x7e,
+ (byte) 0xf1, (byte) 0x61
+ };
+
+ /**
+ * Generated from above and converted with:
+ *
+ * openssl pkcs8 -topk8 -outform d -in userkey.pem -nocrypt | xxd -i | sed 's/0x/(byte) 0x/g'
+ */
+ private static final byte[] FAKE_KEY_1 = new byte[] {
+ (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x78, (byte) 0x02, (byte) 0x01,
+ (byte) 0x00, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a,
+ (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01,
+ (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x04, (byte) 0x82,
+ (byte) 0x02, (byte) 0x62, (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x5e,
+ (byte) 0x02, (byte) 0x01, (byte) 0x00, (byte) 0x02, (byte) 0x81, (byte) 0x81,
+ (byte) 0x00, (byte) 0xce, (byte) 0x29, (byte) 0xeb, (byte) 0xf6, (byte) 0x5b,
+ (byte) 0x25, (byte) 0xdc, (byte) 0xa1, (byte) 0xa6, (byte) 0x2c, (byte) 0x66,
+ (byte) 0xcb, (byte) 0x20, (byte) 0x90, (byte) 0x27, (byte) 0x86, (byte) 0x8a,
+ (byte) 0x44, (byte) 0x71, (byte) 0x50, (byte) 0xda, (byte) 0xd3, (byte) 0x02,
+ (byte) 0x77, (byte) 0x55, (byte) 0xe9, (byte) 0xe8, (byte) 0x08, (byte) 0xf3,
+ (byte) 0x36, (byte) 0x9a, (byte) 0xae, (byte) 0xab, (byte) 0x04, (byte) 0x6d,
+ (byte) 0x00, (byte) 0x99, (byte) 0xbf, (byte) 0x7d, (byte) 0x0f, (byte) 0x67,
+ (byte) 0x8b, (byte) 0x1d, (byte) 0xd4, (byte) 0x2b, (byte) 0x7c, (byte) 0xcb,
+ (byte) 0xcd, (byte) 0x33, (byte) 0xc7, (byte) 0x84, (byte) 0x30, (byte) 0xe2,
+ (byte) 0x45, (byte) 0x21, (byte) 0xb3, (byte) 0x75, (byte) 0xf5, (byte) 0x79,
+ (byte) 0x02, (byte) 0xda, (byte) 0x50, (byte) 0xa3, (byte) 0x8b, (byte) 0xce,
+ (byte) 0xc3, (byte) 0x8e, (byte) 0x0f, (byte) 0x25, (byte) 0xeb, (byte) 0x08,
+ (byte) 0x2c, (byte) 0xdd, (byte) 0x1c, (byte) 0xcf, (byte) 0xff, (byte) 0x3b,
+ (byte) 0xde, (byte) 0xb6, (byte) 0xaa, (byte) 0x2a, (byte) 0xa9, (byte) 0xc4,
+ (byte) 0x8a, (byte) 0x24, (byte) 0x24, (byte) 0xe6, (byte) 0x29, (byte) 0x0d,
+ (byte) 0x98, (byte) 0x4c, (byte) 0x32, (byte) 0xa1, (byte) 0x7b, (byte) 0x23,
+ (byte) 0x2b, (byte) 0x42, (byte) 0x30, (byte) 0xee, (byte) 0x78, (byte) 0x08,
+ (byte) 0x47, (byte) 0xad, (byte) 0xf2, (byte) 0x96, (byte) 0xd5, (byte) 0xf1,
+ (byte) 0x62, (byte) 0x42, (byte) 0x2d, (byte) 0x35, (byte) 0x19, (byte) 0xb4,
+ (byte) 0x3c, (byte) 0xc9, (byte) 0xc3, (byte) 0x5f, (byte) 0x03, (byte) 0x16,
+ (byte) 0x3a, (byte) 0x23, (byte) 0xac, (byte) 0xcb, (byte) 0xce, (byte) 0x9e,
+ (byte) 0x51, (byte) 0x2e, (byte) 0x6d, (byte) 0x02, (byte) 0x03, (byte) 0x01,
+ (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x81, (byte) 0x80, (byte) 0x16,
+ (byte) 0x59, (byte) 0xc3, (byte) 0x24, (byte) 0x1d, (byte) 0x33, (byte) 0x98,
+ (byte) 0x9c, (byte) 0xc9, (byte) 0xc8, (byte) 0x2c, (byte) 0x88, (byte) 0xbf,
+ (byte) 0x0a, (byte) 0x01, (byte) 0xce, (byte) 0xfb, (byte) 0x34, (byte) 0x7a,
+ (byte) 0x58, (byte) 0x7a, (byte) 0xb0, (byte) 0xbf, (byte) 0xa6, (byte) 0xb2,
+ (byte) 0x60, (byte) 0xbe, (byte) 0x70, (byte) 0x21, (byte) 0xf5, (byte) 0xfc,
+ (byte) 0x85, (byte) 0x0d, (byte) 0x33, (byte) 0x58, (byte) 0xa1, (byte) 0xe5,
+ (byte) 0x09, (byte) 0x36, (byte) 0x84, (byte) 0xb2, (byte) 0x04, (byte) 0x0a,
+ (byte) 0x02, (byte) 0xd3, (byte) 0x88, (byte) 0x1f, (byte) 0x0c, (byte) 0x2b,
+ (byte) 0x1d, (byte) 0xe9, (byte) 0x3d, (byte) 0xe7, (byte) 0x79, (byte) 0xf9,
+ (byte) 0x32, (byte) 0x5c, (byte) 0x8a, (byte) 0x75, (byte) 0x49, (byte) 0x12,
+ (byte) 0xe4, (byte) 0x05, (byte) 0x26, (byte) 0xd4, (byte) 0x2e, (byte) 0x9e,
+ (byte) 0x1f, (byte) 0xcc, (byte) 0x54, (byte) 0xad, (byte) 0x33, (byte) 0x8d,
+ (byte) 0x99, (byte) 0x00, (byte) 0xdc, (byte) 0xf5, (byte) 0xb4, (byte) 0xa2,
+ (byte) 0x2f, (byte) 0xba, (byte) 0xe5, (byte) 0x62, (byte) 0x30, (byte) 0x6d,
+ (byte) 0xe6, (byte) 0x3d, (byte) 0xeb, (byte) 0x24, (byte) 0xc2, (byte) 0xdc,
+ (byte) 0x5f, (byte) 0xb7, (byte) 0x16, (byte) 0x35, (byte) 0xa3, (byte) 0x98,
+ (byte) 0x98, (byte) 0xa8, (byte) 0xef, (byte) 0xe8, (byte) 0xc4, (byte) 0x96,
+ (byte) 0x6d, (byte) 0x38, (byte) 0xab, (byte) 0x26, (byte) 0x6d, (byte) 0x30,
+ (byte) 0xc2, (byte) 0xa0, (byte) 0x44, (byte) 0xe4, (byte) 0xff, (byte) 0x7e,
+ (byte) 0xbe, (byte) 0x7c, (byte) 0x33, (byte) 0xa5, (byte) 0x10, (byte) 0xad,
+ (byte) 0xd7, (byte) 0x1e, (byte) 0x13, (byte) 0x20, (byte) 0xb3, (byte) 0x1f,
+ (byte) 0x41, (byte) 0x02, (byte) 0x41, (byte) 0x00, (byte) 0xf1, (byte) 0x89,
+ (byte) 0x07, (byte) 0x0f, (byte) 0xe8, (byte) 0xcf, (byte) 0xab, (byte) 0x13,
+ (byte) 0x2a, (byte) 0x8f, (byte) 0x88, (byte) 0x80, (byte) 0x11, (byte) 0x9a,
+ (byte) 0x79, (byte) 0xb6, (byte) 0x59, (byte) 0x3a, (byte) 0x50, (byte) 0x6e,
+ (byte) 0x57, (byte) 0x37, (byte) 0xab, (byte) 0x2a, (byte) 0xd2, (byte) 0xaa,
+ (byte) 0xd9, (byte) 0x72, (byte) 0x73, (byte) 0xff, (byte) 0x8b, (byte) 0x47,
+ (byte) 0x76, (byte) 0xdd, (byte) 0xdc, (byte) 0xf5, (byte) 0x97, (byte) 0x44,
+ (byte) 0x3a, (byte) 0x78, (byte) 0xbe, (byte) 0x17, (byte) 0xb4, (byte) 0x22,
+ (byte) 0x6f, (byte) 0xe5, (byte) 0x23, (byte) 0x70, (byte) 0x1d, (byte) 0x10,
+ (byte) 0x5d, (byte) 0xba, (byte) 0x16, (byte) 0x81, (byte) 0xf1, (byte) 0x45,
+ (byte) 0xce, (byte) 0x30, (byte) 0xb4, (byte) 0xab, (byte) 0x80, (byte) 0xe4,
+ (byte) 0x98, (byte) 0x31, (byte) 0x02, (byte) 0x41, (byte) 0x00, (byte) 0xda,
+ (byte) 0x82, (byte) 0x9d, (byte) 0x3f, (byte) 0xca, (byte) 0x2f, (byte) 0xe1,
+ (byte) 0xd4, (byte) 0x86, (byte) 0x77, (byte) 0x48, (byte) 0xa6, (byte) 0xab,
+ (byte) 0xab, (byte) 0x1c, (byte) 0x42, (byte) 0x5c, (byte) 0xd5, (byte) 0xc7,
+ (byte) 0x46, (byte) 0x59, (byte) 0x91, (byte) 0x3f, (byte) 0xfc, (byte) 0xcc,
+ (byte) 0xec, (byte) 0xc2, (byte) 0x40, (byte) 0x12, (byte) 0x2c, (byte) 0x8d,
+ (byte) 0x1f, (byte) 0xa2, (byte) 0x18, (byte) 0x88, (byte) 0xee, (byte) 0x82,
+ (byte) 0x4a, (byte) 0x5a, (byte) 0x5e, (byte) 0x88, (byte) 0x20, (byte) 0xe3,
+ (byte) 0x7b, (byte) 0xe0, (byte) 0xd8, (byte) 0x3a, (byte) 0x52, (byte) 0x9a,
+ (byte) 0x26, (byte) 0x6a, (byte) 0x04, (byte) 0xec, (byte) 0xe8, (byte) 0xb9,
+ (byte) 0x48, (byte) 0x40, (byte) 0xe1, (byte) 0xe1, (byte) 0x83, (byte) 0xa6,
+ (byte) 0x67, (byte) 0xa6, (byte) 0xfd, (byte) 0x02, (byte) 0x41, (byte) 0x00,
+ (byte) 0x89, (byte) 0x72, (byte) 0x3e, (byte) 0xb0, (byte) 0x90, (byte) 0xfd,
+ (byte) 0x4c, (byte) 0x0e, (byte) 0xd6, (byte) 0x13, (byte) 0x63, (byte) 0xcb,
+ (byte) 0xed, (byte) 0x38, (byte) 0x88, (byte) 0xb6, (byte) 0x79, (byte) 0xc4,
+ (byte) 0x33, (byte) 0x6c, (byte) 0xf6, (byte) 0xf8, (byte) 0xd8, (byte) 0xd0,
+ (byte) 0xbf, (byte) 0x9d, (byte) 0x35, (byte) 0xac, (byte) 0x69, (byte) 0xd2,
+ (byte) 0x2b, (byte) 0xc1, (byte) 0xf9, (byte) 0x24, (byte) 0x7b, (byte) 0xce,
+ (byte) 0xcd, (byte) 0xcb, (byte) 0xa7, (byte) 0xb2, (byte) 0x7a, (byte) 0x0a,
+ (byte) 0x27, (byte) 0x19, (byte) 0xc9, (byte) 0xaf, (byte) 0x0d, (byte) 0x21,
+ (byte) 0x89, (byte) 0x88, (byte) 0x7c, (byte) 0xad, (byte) 0x9e, (byte) 0x8d,
+ (byte) 0x47, (byte) 0x6d, (byte) 0x3f, (byte) 0xce, (byte) 0x7b, (byte) 0xa1,
+ (byte) 0x74, (byte) 0xf1, (byte) 0xa0, (byte) 0xa1, (byte) 0x02, (byte) 0x41,
+ (byte) 0x00, (byte) 0xd9, (byte) 0xa8, (byte) 0xf5, (byte) 0xfe, (byte) 0xce,
+ (byte) 0xe6, (byte) 0x77, (byte) 0x6b, (byte) 0xfe, (byte) 0x2d, (byte) 0xe0,
+ (byte) 0x1e, (byte) 0xb6, (byte) 0x2e, (byte) 0x12, (byte) 0x4e, (byte) 0x40,
+ (byte) 0xaf, (byte) 0x6a, (byte) 0x7b, (byte) 0x37, (byte) 0x49, (byte) 0x2a,
+ (byte) 0x96, (byte) 0x25, (byte) 0x83, (byte) 0x49, (byte) 0xd4, (byte) 0x0c,
+ (byte) 0xc6, (byte) 0x78, (byte) 0x25, (byte) 0x24, (byte) 0x90, (byte) 0x90,
+ (byte) 0x06, (byte) 0x15, (byte) 0x9e, (byte) 0xfe, (byte) 0xf9, (byte) 0xdf,
+ (byte) 0x5b, (byte) 0xf3, (byte) 0x7e, (byte) 0x38, (byte) 0x70, (byte) 0xeb,
+ (byte) 0x57, (byte) 0xd0, (byte) 0xd9, (byte) 0xa7, (byte) 0x0e, (byte) 0x14,
+ (byte) 0xf7, (byte) 0x95, (byte) 0x68, (byte) 0xd5, (byte) 0xc8, (byte) 0xab,
+ (byte) 0x9d, (byte) 0x3a, (byte) 0x2b, (byte) 0x51, (byte) 0xf9, (byte) 0x02,
+ (byte) 0x41, (byte) 0x00, (byte) 0x96, (byte) 0xdf, (byte) 0xe9, (byte) 0x67,
+ (byte) 0x6c, (byte) 0xdc, (byte) 0x90, (byte) 0x14, (byte) 0xb4, (byte) 0x1d,
+ (byte) 0x22, (byte) 0x33, (byte) 0x4a, (byte) 0x31, (byte) 0xc1, (byte) 0x9d,
+ (byte) 0x2e, (byte) 0xff, (byte) 0x9a, (byte) 0x2a, (byte) 0x95, (byte) 0x4b,
+ (byte) 0x27, (byte) 0x74, (byte) 0xcb, (byte) 0x21, (byte) 0xc3, (byte) 0xd2,
+ (byte) 0x0b, (byte) 0xb2, (byte) 0x46, (byte) 0x87, (byte) 0xf8, (byte) 0x28,
+ (byte) 0x01, (byte) 0x8b, (byte) 0xd8, (byte) 0xb9, (byte) 0x4b, (byte) 0xcd,
+ (byte) 0x9a, (byte) 0x96, (byte) 0x41, (byte) 0x0e, (byte) 0x36, (byte) 0x6d,
+ (byte) 0x40, (byte) 0x42, (byte) 0xbc, (byte) 0xd9, (byte) 0xd3, (byte) 0x7b,
+ (byte) 0xbc, (byte) 0xa7, (byte) 0x92, (byte) 0x90, (byte) 0xdd, (byte) 0xa1,
+ (byte) 0x9c, (byte) 0xce, (byte) 0xa1, (byte) 0x87, (byte) 0x11, (byte) 0x51
+ };
+
+ /**
+ * Generated from above and converted with:
+ *
+ * openssl x509 -outform d -in usercert.pem | xxd -i | sed 's/0x/(byte) 0x/g'
+ */
+ private static final byte[] FAKE_USER_1 = new byte[] {
+ (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x95, (byte) 0x30, (byte) 0x82,
+ (byte) 0x01, (byte) 0xfe, (byte) 0xa0, (byte) 0x03, (byte) 0x02, (byte) 0x01,
+ (byte) 0x02, (byte) 0x02, (byte) 0x01, (byte) 0x01, (byte) 0x30, (byte) 0x0d,
+ (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86,
+ (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x05,
+ (byte) 0x00, (byte) 0x30, (byte) 0x4f, (byte) 0x31, (byte) 0x0b, (byte) 0x30,
+ (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x06,
+ (byte) 0x13, (byte) 0x02, (byte) 0x55, (byte) 0x53, (byte) 0x31, (byte) 0x0b,
+ (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
+ (byte) 0x08, (byte) 0x13, (byte) 0x02, (byte) 0x43, (byte) 0x41, (byte) 0x31,
+ (byte) 0x16, (byte) 0x30, (byte) 0x14, (byte) 0x06, (byte) 0x03, (byte) 0x55,
+ (byte) 0x04, (byte) 0x07, (byte) 0x13, (byte) 0x0d, (byte) 0x4d, (byte) 0x6f,
+ (byte) 0x75, (byte) 0x6e, (byte) 0x74, (byte) 0x61, (byte) 0x69, (byte) 0x6e,
+ (byte) 0x20, (byte) 0x56, (byte) 0x69, (byte) 0x65, (byte) 0x77, (byte) 0x31,
+ (byte) 0x1b, (byte) 0x30, (byte) 0x19, (byte) 0x06, (byte) 0x03, (byte) 0x55,
+ (byte) 0x04, (byte) 0x0a, (byte) 0x13, (byte) 0x12, (byte) 0x41, (byte) 0x6e,
+ (byte) 0x64, (byte) 0x72, (byte) 0x6f, (byte) 0x69, (byte) 0x64, (byte) 0x20,
+ (byte) 0x54, (byte) 0x65, (byte) 0x73, (byte) 0x74, (byte) 0x20, (byte) 0x43,
+ (byte) 0x61, (byte) 0x73, (byte) 0x65, (byte) 0x73, (byte) 0x30, (byte) 0x1e,
+ (byte) 0x17, (byte) 0x0d, (byte) 0x31, (byte) 0x32, (byte) 0x30, (byte) 0x38,
+ (byte) 0x31, (byte) 0x34, (byte) 0x32, (byte) 0x33, (byte) 0x32, (byte) 0x35,
+ (byte) 0x34, (byte) 0x38, (byte) 0x5a, (byte) 0x17, (byte) 0x0d, (byte) 0x32,
+ (byte) 0x32, (byte) 0x30, (byte) 0x38, (byte) 0x31, (byte) 0x32, (byte) 0x32,
+ (byte) 0x33, (byte) 0x32, (byte) 0x35, (byte) 0x34, (byte) 0x38, (byte) 0x5a,
+ (byte) 0x30, (byte) 0x55, (byte) 0x31, (byte) 0x0b, (byte) 0x30, (byte) 0x09,
+ (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x06, (byte) 0x13,
+ (byte) 0x02, (byte) 0x55, (byte) 0x53, (byte) 0x31, (byte) 0x0b, (byte) 0x30,
+ (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x08,
+ (byte) 0x13, (byte) 0x02, (byte) 0x43, (byte) 0x41, (byte) 0x31, (byte) 0x1b,
+ (byte) 0x30, (byte) 0x19, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
+ (byte) 0x0a, (byte) 0x13, (byte) 0x12, (byte) 0x41, (byte) 0x6e, (byte) 0x64,
+ (byte) 0x72, (byte) 0x6f, (byte) 0x69, (byte) 0x64, (byte) 0x20, (byte) 0x54,
+ (byte) 0x65, (byte) 0x73, (byte) 0x74, (byte) 0x20, (byte) 0x43, (byte) 0x61,
+ (byte) 0x73, (byte) 0x65, (byte) 0x73, (byte) 0x31, (byte) 0x1c, (byte) 0x30,
+ (byte) 0x1a, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x03,
+ (byte) 0x13, (byte) 0x13, (byte) 0x73, (byte) 0x65, (byte) 0x72, (byte) 0x76,
+ (byte) 0x65, (byte) 0x72, (byte) 0x31, (byte) 0x2e, (byte) 0x65, (byte) 0x78,
+ (byte) 0x61, (byte) 0x6d, (byte) 0x70, (byte) 0x6c, (byte) 0x65, (byte) 0x2e,
+ (byte) 0x63, (byte) 0x6f, (byte) 0x6d, (byte) 0x30, (byte) 0x81, (byte) 0x9f,
+ (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86,
+ (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01,
+ (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x03, (byte) 0x81, (byte) 0x8d,
+ (byte) 0x00, (byte) 0x30, (byte) 0x81, (byte) 0x89, (byte) 0x02, (byte) 0x81,
+ (byte) 0x81, (byte) 0x00, (byte) 0xce, (byte) 0x29, (byte) 0xeb, (byte) 0xf6,
+ (byte) 0x5b, (byte) 0x25, (byte) 0xdc, (byte) 0xa1, (byte) 0xa6, (byte) 0x2c,
+ (byte) 0x66, (byte) 0xcb, (byte) 0x20, (byte) 0x90, (byte) 0x27, (byte) 0x86,
+ (byte) 0x8a, (byte) 0x44, (byte) 0x71, (byte) 0x50, (byte) 0xda, (byte) 0xd3,
+ (byte) 0x02, (byte) 0x77, (byte) 0x55, (byte) 0xe9, (byte) 0xe8, (byte) 0x08,
+ (byte) 0xf3, (byte) 0x36, (byte) 0x9a, (byte) 0xae, (byte) 0xab, (byte) 0x04,
+ (byte) 0x6d, (byte) 0x00, (byte) 0x99, (byte) 0xbf, (byte) 0x7d, (byte) 0x0f,
+ (byte) 0x67, (byte) 0x8b, (byte) 0x1d, (byte) 0xd4, (byte) 0x2b, (byte) 0x7c,
+ (byte) 0xcb, (byte) 0xcd, (byte) 0x33, (byte) 0xc7, (byte) 0x84, (byte) 0x30,
+ (byte) 0xe2, (byte) 0x45, (byte) 0x21, (byte) 0xb3, (byte) 0x75, (byte) 0xf5,
+ (byte) 0x79, (byte) 0x02, (byte) 0xda, (byte) 0x50, (byte) 0xa3, (byte) 0x8b,
+ (byte) 0xce, (byte) 0xc3, (byte) 0x8e, (byte) 0x0f, (byte) 0x25, (byte) 0xeb,
+ (byte) 0x08, (byte) 0x2c, (byte) 0xdd, (byte) 0x1c, (byte) 0xcf, (byte) 0xff,
+ (byte) 0x3b, (byte) 0xde, (byte) 0xb6, (byte) 0xaa, (byte) 0x2a, (byte) 0xa9,
+ (byte) 0xc4, (byte) 0x8a, (byte) 0x24, (byte) 0x24, (byte) 0xe6, (byte) 0x29,
+ (byte) 0x0d, (byte) 0x98, (byte) 0x4c, (byte) 0x32, (byte) 0xa1, (byte) 0x7b,
+ (byte) 0x23, (byte) 0x2b, (byte) 0x42, (byte) 0x30, (byte) 0xee, (byte) 0x78,
+ (byte) 0x08, (byte) 0x47, (byte) 0xad, (byte) 0xf2, (byte) 0x96, (byte) 0xd5,
+ (byte) 0xf1, (byte) 0x62, (byte) 0x42, (byte) 0x2d, (byte) 0x35, (byte) 0x19,
+ (byte) 0xb4, (byte) 0x3c, (byte) 0xc9, (byte) 0xc3, (byte) 0x5f, (byte) 0x03,
+ (byte) 0x16, (byte) 0x3a, (byte) 0x23, (byte) 0xac, (byte) 0xcb, (byte) 0xce,
+ (byte) 0x9e, (byte) 0x51, (byte) 0x2e, (byte) 0x6d, (byte) 0x02, (byte) 0x03,
+ (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0xa3, (byte) 0x7b, (byte) 0x30,
+ (byte) 0x79, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55,
+ (byte) 0x1d, (byte) 0x13, (byte) 0x04, (byte) 0x02, (byte) 0x30, (byte) 0x00,
+ (byte) 0x30, (byte) 0x2c, (byte) 0x06, (byte) 0x09, (byte) 0x60, (byte) 0x86,
+ (byte) 0x48, (byte) 0x01, (byte) 0x86, (byte) 0xf8, (byte) 0x42, (byte) 0x01,
+ (byte) 0x0d, (byte) 0x04, (byte) 0x1f, (byte) 0x16, (byte) 0x1d, (byte) 0x4f,
+ (byte) 0x70, (byte) 0x65, (byte) 0x6e, (byte) 0x53, (byte) 0x53, (byte) 0x4c,
+ (byte) 0x20, (byte) 0x47, (byte) 0x65, (byte) 0x6e, (byte) 0x65, (byte) 0x72,
+ (byte) 0x61, (byte) 0x74, (byte) 0x65, (byte) 0x64, (byte) 0x20, (byte) 0x43,
+ (byte) 0x65, (byte) 0x72, (byte) 0x74, (byte) 0x69, (byte) 0x66, (byte) 0x69,
+ (byte) 0x63, (byte) 0x61, (byte) 0x74, (byte) 0x65, (byte) 0x30, (byte) 0x1d,
+ (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x0e, (byte) 0x04,
+ (byte) 0x16, (byte) 0x04, (byte) 0x14, (byte) 0x32, (byte) 0xa1, (byte) 0x1e,
+ (byte) 0x6b, (byte) 0x69, (byte) 0x04, (byte) 0xfe, (byte) 0xb3, (byte) 0xcd,
+ (byte) 0xf8, (byte) 0xbb, (byte) 0x14, (byte) 0xcd, (byte) 0xff, (byte) 0xd4,
+ (byte) 0x16, (byte) 0xc3, (byte) 0xab, (byte) 0x44, (byte) 0x2f, (byte) 0x30,
+ (byte) 0x1f, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x23,
+ (byte) 0x04, (byte) 0x18, (byte) 0x30, (byte) 0x16, (byte) 0x80, (byte) 0x14,
+ (byte) 0x33, (byte) 0x05, (byte) 0xee, (byte) 0xfe, (byte) 0x6f, (byte) 0x60,
+ (byte) 0xc7, (byte) 0xf9, (byte) 0xa9, (byte) 0xd2, (byte) 0x73, (byte) 0x5c,
+ (byte) 0x8f, (byte) 0x6d, (byte) 0xa2, (byte) 0x2f, (byte) 0x97, (byte) 0x8e,
+ (byte) 0x5d, (byte) 0x51, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09,
+ (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d,
+ (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x05, (byte) 0x00, (byte) 0x03,
+ (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0x46, (byte) 0x42, (byte) 0xef,
+ (byte) 0x56, (byte) 0x89, (byte) 0x78, (byte) 0x90, (byte) 0x38, (byte) 0x24,
+ (byte) 0x9f, (byte) 0x8c, (byte) 0x7a, (byte) 0xce, (byte) 0x7a, (byte) 0xa5,
+ (byte) 0xb5, (byte) 0x1e, (byte) 0x74, (byte) 0x96, (byte) 0x34, (byte) 0x49,
+ (byte) 0x8b, (byte) 0xed, (byte) 0x44, (byte) 0xb3, (byte) 0xc9, (byte) 0x05,
+ (byte) 0xd7, (byte) 0x48, (byte) 0x55, (byte) 0x52, (byte) 0x59, (byte) 0x15,
+ (byte) 0x0b, (byte) 0xaa, (byte) 0x16, (byte) 0x86, (byte) 0xd2, (byte) 0x8e,
+ (byte) 0x16, (byte) 0x99, (byte) 0xe8, (byte) 0x5f, (byte) 0x11, (byte) 0x71,
+ (byte) 0x42, (byte) 0x55, (byte) 0xd1, (byte) 0xc4, (byte) 0x6f, (byte) 0x2e,
+ (byte) 0xa9, (byte) 0x64, (byte) 0x6f, (byte) 0xd8, (byte) 0xfd, (byte) 0x43,
+ (byte) 0x13, (byte) 0x24, (byte) 0xaa, (byte) 0x67, (byte) 0xe6, (byte) 0xf5,
+ (byte) 0xca, (byte) 0x80, (byte) 0x5e, (byte) 0x3a, (byte) 0x3e, (byte) 0xcc,
+ (byte) 0x4f, (byte) 0xba, (byte) 0x87, (byte) 0xe6, (byte) 0xae, (byte) 0xbf,
+ (byte) 0x8f, (byte) 0xd5, (byte) 0x28, (byte) 0x38, (byte) 0x58, (byte) 0x30,
+ (byte) 0x24, (byte) 0xf6, (byte) 0x53, (byte) 0x5b, (byte) 0x41, (byte) 0x53,
+ (byte) 0xe6, (byte) 0x45, (byte) 0xbc, (byte) 0xbe, (byte) 0xe6, (byte) 0xbb,
+ (byte) 0x5d, (byte) 0xd8, (byte) 0xa7, (byte) 0xf9, (byte) 0x64, (byte) 0x99,
+ (byte) 0x04, (byte) 0x43, (byte) 0x75, (byte) 0xd7, (byte) 0x2d, (byte) 0x32,
+ (byte) 0x0a, (byte) 0x94, (byte) 0xaf, (byte) 0x06, (byte) 0x34, (byte) 0xae,
+ (byte) 0x46, (byte) 0xbd, (byte) 0xda, (byte) 0x00, (byte) 0x0e, (byte) 0x25,
+ (byte) 0xc2, (byte) 0xf7, (byte) 0xc9, (byte) 0xc3, (byte) 0x65, (byte) 0xd2,
+ (byte) 0x08, (byte) 0x41, (byte) 0x0a, (byte) 0xf3, (byte) 0x72
+ };
+
+ /**
+ * The amount of time to allow before and after expected time for variance
+ * in timing tests.
+ */
+ private static final long SLOP_TIME_MILLIS = 15000L;
+
+ @Override
+ protected void setUp() throws Exception {
+ mAndroidKeyStore = android.security.KeyStore.getInstance();
+
+ assertTrue(mAndroidKeyStore.reset());
+
+ assertEquals(android.security.KeyStore.State.UNINITIALIZED, mAndroidKeyStore.state());
+
+ assertTrue(mAndroidKeyStore.password("1111"));
+
+ assertEquals(android.security.KeyStore.State.UNLOCKED, mAndroidKeyStore.state());
+
+ assertEquals(0, mAndroidKeyStore.saw("").length);
+
+ mKeyStore = java.security.KeyStore.getInstance(AndroidKeyStore.NAME);
+ }
+
+ private void assertAliases(final String[] expectedAliases) throws KeyStoreException {
+ final Enumeration<String> aliases = mKeyStore.aliases();
+ int count = 0;
+
+ final Set<String> expectedSet = new HashSet<String>();
+ expectedSet.addAll(Arrays.asList(expectedAliases));
+
+ while (aliases.hasMoreElements()) {
+ count++;
+ final String alias = aliases.nextElement();
+ assertTrue("The alias should be in the expected set", expectedSet.contains(alias));
+ expectedSet.remove(alias);
+ }
+ assertTrue("The expected set and actual set should be exactly equal", expectedSet.isEmpty());
+ assertEquals("There should be the correct number of keystore entries",
+ expectedAliases.length, count);
+ }
+
+ public void testKeyStore_Aliases_Success() throws Exception {
+ mKeyStore.load(null, null);
+
+ assertAliases(new String[] {});
+
+ assertTrue(mAndroidKeyStore.generate(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1));
+
+ assertAliases(new String[] { TEST_ALIAS_1 });
+
+ assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_2, FAKE_CA_1));
+
+ assertAliases(new String[] { TEST_ALIAS_1, TEST_ALIAS_2 });
+ }
+
+ public void testKeyStore_Aliases_NotInitialized_Failure() throws Exception {
+ try {
+ mKeyStore.aliases();
+ fail("KeyStore should throw exception when not initialized");
+ } catch (KeyStoreException success) {
+ }
+ }
+
+ public void testKeyStore_ContainsAliases_PrivateAndCA_Success() throws Exception {
+ mKeyStore.load(null, null);
+
+ assertAliases(new String[] {});
+
+ assertTrue(mAndroidKeyStore.generate(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1));
+
+ assertTrue("Should contain generated private key", mKeyStore.containsAlias(TEST_ALIAS_1));
+
+ assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_2, FAKE_CA_1));
+
+ assertTrue("Should contain added CA certificate", mKeyStore.containsAlias(TEST_ALIAS_2));
+
+ assertFalse("Should not contain unadded certificate alias",
+ mKeyStore.containsAlias(TEST_ALIAS_3));
+ }
+
+ public void testKeyStore_ContainsAliases_CAOnly_Success() throws Exception {
+ mKeyStore.load(null, null);
+
+ assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_2, FAKE_CA_1));
+
+ assertTrue("Should contain added CA certificate", mKeyStore.containsAlias(TEST_ALIAS_2));
+ }
+
+ public void testKeyStore_ContainsAliases_NonExistent_Failure() throws Exception {
+ mKeyStore.load(null, null);
+
+ assertFalse("Should contain added CA certificate", mKeyStore.containsAlias(TEST_ALIAS_1));
+ }
+
+ public void testKeyStore_DeleteEntry_Success() throws Exception {
+ mKeyStore.load(null, null);
+
+ // TEST_ALIAS_1
+ assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
+ FAKE_KEY_1));
+ assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1));
+ assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
+
+ // TEST_ALIAS_2
+ assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_2, FAKE_CA_1));
+
+ // TEST_ALIAS_3
+ assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_3, FAKE_CA_1));
+
+ assertAliases(new String[] { TEST_ALIAS_1, TEST_ALIAS_2, TEST_ALIAS_3 });
+
+ mKeyStore.deleteEntry(TEST_ALIAS_1);
+
+ assertAliases(new String[] { TEST_ALIAS_2, TEST_ALIAS_3 });
+
+ mKeyStore.deleteEntry(TEST_ALIAS_3);
+
+ assertAliases(new String[] { TEST_ALIAS_2 });
+
+ mKeyStore.deleteEntry(TEST_ALIAS_2);
+
+ assertAliases(new String[] { });
+ }
+
+ public void testKeyStore_DeleteEntry_EmptyStore_Failure() throws Exception {
+ mKeyStore.load(null, null);
+
+ try {
+ mKeyStore.deleteEntry(TEST_ALIAS_1);
+ fail("Should throw KeyStoreException with non-existent alias");
+ } catch (KeyStoreException success) {
+ }
+ }
+
+ public void testKeyStore_DeleteEntry_NonExistent_Failure() throws Exception {
+ mKeyStore.load(null, null);
+
+ // TEST_ALIAS_1
+ assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
+ FAKE_KEY_1));
+ assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1));
+ assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
+
+ try {
+ mKeyStore.deleteEntry(TEST_ALIAS_2);
+ fail("Should throw KeyStoreException with non-existent alias");
+ } catch (KeyStoreException success) {
+ }
+ }
+
+ public void testKeyStore_GetCertificate_Single_Success() throws Exception {
+ mKeyStore.load(null, null);
+
+ assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
+
+ assertAliases(new String[] { TEST_ALIAS_1 });
+
+ assertNull("Certificate should not exist in keystore",
+ mKeyStore.getCertificate(TEST_ALIAS_2));
+
+ Certificate retrieved = mKeyStore.getCertificate(TEST_ALIAS_1);
+
+ assertNotNull("Retrieved certificate should not be null", retrieved);
+
+ CertificateFactory f = CertificateFactory.getInstance("X.509");
+ Certificate actual = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
+
+ assertEquals("Actual and retrieved certificates should be the same", actual, retrieved);
+ }
+
+ public void testKeyStore_GetCertificate_NonExist_Failure() throws Exception {
+ mKeyStore.load(null, null);
+
+ assertNull("Certificate should not exist in keystore",
+ mKeyStore.getCertificate(TEST_ALIAS_1));
+ }
+
+ public void testKeyStore_GetCertificateAlias_CAEntry_Success() throws Exception {
+ mKeyStore.load(null, null);
+
+ assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
+
+ CertificateFactory f = CertificateFactory.getInstance("X.509");
+ Certificate actual = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
+
+ assertEquals("Stored certificate alias should be found", TEST_ALIAS_1,
+ mKeyStore.getCertificateAlias(actual));
+ }
+
+ public void testKeyStore_GetCertificateAlias_PrivateKeyEntry_Success() throws Exception {
+ mKeyStore.load(null, null);
+
+ assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
+ FAKE_KEY_1));
+ assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1));
+ assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
+
+ CertificateFactory f = CertificateFactory.getInstance("X.509");
+ Certificate actual = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
+
+ assertEquals("Stored certificate alias should be found", TEST_ALIAS_1,
+ mKeyStore.getCertificateAlias(actual));
+ }
+
+ public void testKeyStore_GetCertificateAlias_CAEntry_WithPrivateKeyUsingCA_Success()
+ throws Exception {
+ mKeyStore.load(null, null);
+
+ // Insert TrustedCertificateEntry with CA name
+ assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_2, FAKE_CA_1));
+
+ // Insert PrivateKeyEntry that uses the same CA
+ assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
+ FAKE_KEY_1));
+ assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1));
+ assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
+
+ CertificateFactory f = CertificateFactory.getInstance("X.509");
+ Certificate actual = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
+
+ assertEquals("Stored certificate alias should be found", TEST_ALIAS_2,
+ mKeyStore.getCertificateAlias(actual));
+ }
+
+ public void testKeyStore_GetCertificateAlias_NonExist_Empty_Failure() throws Exception {
+ mKeyStore.load(null, null);
+
+ CertificateFactory f = CertificateFactory.getInstance("X.509");
+ Certificate actual = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
+
+ assertNull("Stored certificate alias should not be found",
+ mKeyStore.getCertificateAlias(actual));
+ }
+
+ public void testKeyStore_GetCertificateAlias_NonExist_Failure() throws Exception {
+ mKeyStore.load(null, null);
+
+ assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
+
+ CertificateFactory f = CertificateFactory.getInstance("X.509");
+ Certificate userCert = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
+
+ assertNull("Stored certificate alias should be found",
+ mKeyStore.getCertificateAlias(userCert));
+ }
+
+ public void testKeyStore_GetCertificateChain_SingleLength_Success() throws Exception {
+ mKeyStore.load(null, null);
+
+ assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
+ FAKE_KEY_1));
+ assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1));
+ assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
+
+ CertificateFactory cf = CertificateFactory.getInstance("X.509");
+ Certificate[] expected = new Certificate[2];
+ expected[0] = cf.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
+ expected[1] = cf.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
+
+ Certificate[] actual = mKeyStore.getCertificateChain(TEST_ALIAS_1);
+
+ assertNotNull("Returned certificate chain should not be null", actual);
+ assertEquals("Returned certificate chain should be correct size", expected.length,
+ actual.length);
+ assertEquals("First certificate should be user certificate", expected[0], actual[0]);
+ assertEquals("Second certificate should be CA certificate", expected[1], actual[1]);
+
+ // Negative test when keystore is populated.
+ assertNull("Stored certificate alias should not be found",
+ mKeyStore.getCertificateChain(TEST_ALIAS_2));
+ }
+
+ public void testKeyStore_GetCertificateChain_NonExist_Failure() throws Exception {
+ mKeyStore.load(null, null);
+
+ assertNull("Stored certificate alias should not be found",
+ mKeyStore.getCertificateChain(TEST_ALIAS_1));
+ }
+
+ public void testKeyStore_GetCreationDate_PrivateKeyEntry_Success() throws Exception {
+ mKeyStore.load(null, null);
+
+ assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
+ FAKE_KEY_1));
+ assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1));
+ assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
+
+ Date now = new Date();
+ Date actual = mKeyStore.getCreationDate(TEST_ALIAS_1);
+
+ Date expectedAfter = new Date(now.getTime() - SLOP_TIME_MILLIS);
+ Date expectedBefore = new Date(now.getTime() + SLOP_TIME_MILLIS);
+
+ assertTrue("Time should be close to current time", actual.before(expectedBefore));
+ assertTrue("Time should be close to current time", actual.after(expectedAfter));
+ }
+
+ public void testKeyStore_GetCreationDate_CAEntry_Success() throws Exception {
+ mKeyStore.load(null, null);
+
+ assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
+
+ Date now = new Date();
+ Date actual = mKeyStore.getCreationDate(TEST_ALIAS_1);
+ assertNotNull("Certificate should be found", actual);
+
+ Date expectedAfter = new Date(now.getTime() - SLOP_TIME_MILLIS);
+ Date expectedBefore = new Date(now.getTime() + SLOP_TIME_MILLIS);
+
+ assertTrue("Time should be close to current time", actual.before(expectedBefore));
+ assertTrue("Time should be close to current time", actual.after(expectedAfter));
+ }
+
+ public void testKeyStore_GetEntry_NullParams_Success() throws Exception {
+ mKeyStore.load(null, null);
+
+ assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
+ FAKE_KEY_1));
+ assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1));
+ assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
+
+ Entry entry = mKeyStore.getEntry(TEST_ALIAS_1, null);
+ assertNotNull("Entry should exist", entry);
+
+ assertTrue("Should be a PrivateKeyEntry", entry instanceof PrivateKeyEntry);
+
+ PrivateKeyEntry keyEntry = (PrivateKeyEntry) entry;
+
+ assertPrivateKeyEntryEquals(keyEntry, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
+ }
+
+ private void assertPrivateKeyEntryEquals(PrivateKeyEntry keyEntry, byte[] key, byte[] cert,
+ byte[] ca) throws Exception {
+ KeyFactory keyFact = KeyFactory.getInstance("RSA");
+ PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(key));
+
+ assertEquals("Returned PrivateKey should be what we inserted", expectedKey,
+ keyEntry.getPrivateKey());
+
+ CertificateFactory certFact = CertificateFactory.getInstance("X.509");
+ Certificate expectedCert = certFact.generateCertificate(new ByteArrayInputStream(cert));
+
+ assertEquals("Returned Certificate should be what we inserted", expectedCert,
+ keyEntry.getCertificate());
+
+ Certificate[] actualChain = keyEntry.getCertificateChain();
+
+ assertEquals("First certificate in chain should be user cert", expectedCert, actualChain[0]);
+
+ if (ca == null) {
+ assertEquals("Certificate chain should not include CAs", 1, actualChain.length);
+ } else {
+ @SuppressWarnings("unchecked")
+ Collection<Certificate> expectedChain = (Collection<Certificate>) certFact
+ .generateCertificates(new ByteArrayInputStream(ca));
+
+ int i = 1;
+ final Iterator<Certificate> it = expectedChain.iterator();
+ while (it.hasNext()) {
+ assertEquals("CA chain certificate should equal what we put in", it.next(),
+ actualChain[i++]);
+ }
+ }
+ }
+
+ public void testKeyStore_GetEntry_Nonexistent_NullParams_Failure() throws Exception {
+ mKeyStore.load(null, null);
+
+ assertNull("A non-existent entry should return null",
+ mKeyStore.getEntry(TEST_ALIAS_1, null));
+ }
+
+ public void testKeyStore_GetKey_NoPassword_Success() throws Exception {
+ mKeyStore.load(null, null);
+
+ assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
+ FAKE_KEY_1));
+ assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1));
+ assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
+
+ Key key = mKeyStore.getKey(TEST_ALIAS_1, null);
+ assertNotNull("Key should exist", key);
+
+ assertTrue("Should be a RSAPrivateKey", key instanceof RSAPrivateKey);
+
+ RSAPrivateKey actualKey = (RSAPrivateKey) key;
+
+ KeyFactory keyFact = KeyFactory.getInstance("RSA");
+ PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
+
+ assertEquals("Inserted key should be same as retrieved key", actualKey, expectedKey);
+ }
+
+ public void testKeyStore_GetKey_Certificate_Failure() throws Exception {
+ mKeyStore.load(null, null);
+
+ assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
+
+ assertNull("Certificate entries should return null", mKeyStore.getKey(TEST_ALIAS_1, null));
+ }
+
+ public void testKeyStore_GetKey_NonExistent_Failure() throws Exception {
+ mKeyStore.load(null, null);
+
+ assertNull("A non-existent entry should return null", mKeyStore.getKey(TEST_ALIAS_1, null));
+ }
+
+ public void testKeyStore_GetProvider_Success() throws Exception {
+ assertEquals(AndroidKeyStoreProvider.PROVIDER_NAME, mKeyStore.getProvider().getName());
+ }
+
+ public void testKeyStore_GetType_Success() throws Exception {
+ assertEquals(AndroidKeyStore.NAME, mKeyStore.getType());
+ }
+
+ public void testKeyStore_IsCertificateEntry_CA_Success() throws Exception {
+ mKeyStore.load(null, null);
+
+ assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
+
+ assertTrue("Should return true for CA certificate",
+ mKeyStore.isCertificateEntry(TEST_ALIAS_1));
+ }
+
+ public void testKeyStore_IsCertificateEntry_PrivateKey_Failure() throws Exception {
+ mKeyStore.load(null, null);
+
+ assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
+ FAKE_KEY_1));
+ assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1));
+ assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
+
+ assertFalse("Should return false for PrivateKeyEntry",
+ mKeyStore.isCertificateEntry(TEST_ALIAS_1));
+ }
+
+ public void testKeyStore_IsCertificateEntry_NonExist_Failure() throws Exception {
+ mKeyStore.load(null, null);
+
+ assertFalse("Should return false for non-existent entry",
+ mKeyStore.isCertificateEntry(TEST_ALIAS_1));
+ }
+
+ public void testKeyStore_IsKeyEntry_PrivateKey_Success() throws Exception {
+ mKeyStore.load(null, null);
+
+ assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
+ FAKE_KEY_1));
+ assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1));
+ assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
+
+ assertTrue("Should return true for PrivateKeyEntry", mKeyStore.isKeyEntry(TEST_ALIAS_1));
+ }
+
+ public void testKeyStore_IsKeyEntry_CA_Failure() throws Exception {
+ mKeyStore.load(null, null);
+
+ assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
+
+ assertFalse("Should return false for CA certificate", mKeyStore.isKeyEntry(TEST_ALIAS_1));
+ }
+
+ public void testKeyStore_IsKeyEntry_NonExist_Failure() throws Exception {
+ mKeyStore.load(null, null);
+
+ assertFalse("Should return false for non-existent entry",
+ mKeyStore.isKeyEntry(TEST_ALIAS_1));
+ }
+
+ public void testKeyStore_SetCertificate_CA_Success() throws Exception {
+ final CertificateFactory f = CertificateFactory.getInstance("X.509");
+ final Certificate actual = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
+
+ mKeyStore.load(null, null);
+
+ mKeyStore.setCertificateEntry(TEST_ALIAS_1, actual);
+ assertAliases(new String[] { TEST_ALIAS_1 });
+
+ Certificate retrieved = mKeyStore.getCertificate(TEST_ALIAS_1);
+
+ assertEquals("Retrieved certificate should be the same as the one inserted", actual,
+ retrieved);
+ }
+
+ public void testKeyStore_SetCertificate_CAExists_Overwrite_Success() throws Exception {
+ mKeyStore.load(null, null);
+
+ assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
+
+ assertAliases(new String[] { TEST_ALIAS_1 });
+
+ final CertificateFactory f = CertificateFactory.getInstance("X.509");
+ final Certificate cert = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
+
+ // TODO have separate FAKE_CA for second test
+ mKeyStore.setCertificateEntry(TEST_ALIAS_1, cert);
+
+ assertAliases(new String[] { TEST_ALIAS_1 });
+ }
+
+ public void testKeyStore_SetCertificate_PrivateKeyExists_Failure() throws Exception {
+ mKeyStore.load(null, null);
+
+ assertTrue(mAndroidKeyStore.importKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_1,
+ FAKE_KEY_1));
+ assertTrue(mAndroidKeyStore.put(Credentials.USER_CERTIFICATE + TEST_ALIAS_1, FAKE_USER_1));
+ assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
+
+ assertAliases(new String[] { TEST_ALIAS_1 });
+
+ final CertificateFactory f = CertificateFactory.getInstance("X.509");
+ final Certificate cert = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
+
+ try {
+ mKeyStore.setCertificateEntry(TEST_ALIAS_1, cert);
+ fail("Should throw when trying to overwrite a PrivateKey entry with a Certificate");
+ } catch (KeyStoreException success) {
+ }
+ }
+
+ public void testKeyStore_SetEntry_PrivateKeyEntry_Success() throws Exception {
+ mKeyStore.load(null, null);
+
+ KeyFactory keyFact = KeyFactory.getInstance("RSA");
+ PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
+
+ final CertificateFactory f = CertificateFactory.getInstance("X.509");
+
+ final Certificate[] expectedChain = new Certificate[2];
+ expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
+ expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
+
+ PrivateKeyEntry expected = new PrivateKeyEntry(expectedKey, expectedChain);
+
+ mKeyStore.setEntry(TEST_ALIAS_1, expected, null);
+
+ Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
+ assertNotNull("Retrieved entry should exist", actualEntry);
+
+ assertTrue("Retrieved entry should be of type PrivateKeyEntry",
+ actualEntry instanceof PrivateKeyEntry);
+
+ PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;
+
+ assertPrivateKeyEntryEquals(actual, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
+ }
+
+ public void testKeyStore_SetEntry_PrivateKeyEntry_Overwrites_PrivateKeyEntry_Success()
+ throws Exception {
+ mKeyStore.load(null, null);
+
+ final KeyFactory keyFact = KeyFactory.getInstance("RSA");
+ final CertificateFactory f = CertificateFactory.getInstance("X.509");
+
+ // Start with PrivateKeyEntry
+ {
+ PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
+
+ final Certificate[] expectedChain = new Certificate[2];
+ expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
+ expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
+
+ PrivateKeyEntry expected = new PrivateKeyEntry(expectedKey, expectedChain);
+
+ mKeyStore.setEntry(TEST_ALIAS_1, expected, null);
+
+ Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
+ assertNotNull("Retrieved entry should exist", actualEntry);
+
+ assertTrue("Retrieved entry should be of type PrivateKeyEntry",
+ actualEntry instanceof PrivateKeyEntry);
+
+ PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;
+
+ assertPrivateKeyEntryEquals(actual, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
+ }
+
+ // TODO make entirely new test vector for the overwrite
+ // Replace with PrivateKeyEntry
+ {
+ PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
+
+ final Certificate[] expectedChain = new Certificate[2];
+ expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
+ expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
+
+ PrivateKeyEntry expected = new PrivateKeyEntry(expectedKey, expectedChain);
+
+ mKeyStore.setEntry(TEST_ALIAS_1, expected, null);
+
+ Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
+ assertNotNull("Retrieved entry should exist", actualEntry);
+
+ assertTrue("Retrieved entry should be of type PrivateKeyEntry",
+ actualEntry instanceof PrivateKeyEntry);
+
+ PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;
+
+ assertPrivateKeyEntryEquals(actual, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
+ }
+ }
+
+ public void testKeyStore_SetEntry_CAEntry_Overwrites_PrivateKeyEntry_Success() throws Exception {
+ mKeyStore.load(null, null);
+
+ final CertificateFactory f = CertificateFactory.getInstance("X.509");
+
+ // Start with TrustedCertificateEntry
+ {
+ final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
+
+ TrustedCertificateEntry expectedCertEntry = new TrustedCertificateEntry(caCert);
+ mKeyStore.setEntry(TEST_ALIAS_1, expectedCertEntry, null);
+
+ Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
+ assertNotNull("Retrieved entry should exist", actualEntry);
+ assertTrue("Retrieved entry should be of type TrustedCertificateEntry",
+ actualEntry instanceof TrustedCertificateEntry);
+ TrustedCertificateEntry actualCertEntry = (TrustedCertificateEntry) actualEntry;
+ assertEquals("Stored and retrieved certificates should be the same",
+ expectedCertEntry.getTrustedCertificate(),
+ actualCertEntry.getTrustedCertificate());
+ }
+
+ // Replace with PrivateKeyEntry
+ {
+ KeyFactory keyFact = KeyFactory.getInstance("RSA");
+ PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
+ final Certificate[] expectedChain = new Certificate[2];
+ expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
+ expectedChain[1] = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
+
+ PrivateKeyEntry expectedPrivEntry = new PrivateKeyEntry(expectedKey, expectedChain);
+
+ mKeyStore.setEntry(TEST_ALIAS_1, expectedPrivEntry, null);
+
+ Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
+ assertNotNull("Retrieved entry should exist", actualEntry);
+ assertTrue("Retrieved entry should be of type PrivateKeyEntry",
+ actualEntry instanceof PrivateKeyEntry);
+
+ PrivateKeyEntry actualPrivEntry = (PrivateKeyEntry) actualEntry;
+ assertPrivateKeyEntryEquals(actualPrivEntry, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
+ }
+ }
+
+ public void testKeyStore_SetEntry_PrivateKeyEntry_Overwrites_CAEntry_Success() throws Exception {
+ mKeyStore.load(null, null);
+
+ final CertificateFactory f = CertificateFactory.getInstance("X.509");
+
+ final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
+
+ // Start with PrivateKeyEntry
+ {
+ KeyFactory keyFact = KeyFactory.getInstance("RSA");
+ PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
+ final Certificate[] expectedChain = new Certificate[2];
+ expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
+ expectedChain[1] = caCert;
+
+ PrivateKeyEntry expectedPrivEntry = new PrivateKeyEntry(expectedKey, expectedChain);
+
+ mKeyStore.setEntry(TEST_ALIAS_1, expectedPrivEntry, null);
+
+ Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
+ assertNotNull("Retrieved entry should exist", actualEntry);
+ assertTrue("Retrieved entry should be of type PrivateKeyEntry",
+ actualEntry instanceof PrivateKeyEntry);
+
+ PrivateKeyEntry actualPrivEntry = (PrivateKeyEntry) actualEntry;
+ assertPrivateKeyEntryEquals(actualPrivEntry, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
+ }
+
+ // Replace with TrustedCertificateEntry
+ {
+ TrustedCertificateEntry expectedCertEntry = new TrustedCertificateEntry(caCert);
+ mKeyStore.setEntry(TEST_ALIAS_1, expectedCertEntry, null);
+
+ Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
+ assertNotNull("Retrieved entry should exist", actualEntry);
+ assertTrue("Retrieved entry should be of type TrustedCertificateEntry",
+ actualEntry instanceof TrustedCertificateEntry);
+ TrustedCertificateEntry actualCertEntry = (TrustedCertificateEntry) actualEntry;
+ assertEquals("Stored and retrieved certificates should be the same",
+ expectedCertEntry.getTrustedCertificate(),
+ actualCertEntry.getTrustedCertificate());
+ }
+ }
+
+ public void testKeyStore_SetEntry_PrivateKeyEntry_Overwrites_ShortPrivateKeyEntry_Success()
+ throws Exception {
+ mKeyStore.load(null, null);
+
+ final CertificateFactory f = CertificateFactory.getInstance("X.509");
+
+ final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
+
+ // Start with PrivateKeyEntry
+ {
+ KeyFactory keyFact = KeyFactory.getInstance("RSA");
+ PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
+ final Certificate[] expectedChain = new Certificate[2];
+ expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
+ expectedChain[1] = caCert;
+
+ PrivateKeyEntry expectedPrivEntry = new PrivateKeyEntry(expectedKey, expectedChain);
+
+ mKeyStore.setEntry(TEST_ALIAS_1, expectedPrivEntry, null);
+
+ Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
+ assertNotNull("Retrieved entry should exist", actualEntry);
+ assertTrue("Retrieved entry should be of type PrivateKeyEntry",
+ actualEntry instanceof PrivateKeyEntry);
+
+ PrivateKeyEntry actualPrivEntry = (PrivateKeyEntry) actualEntry;
+ assertPrivateKeyEntryEquals(actualPrivEntry, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
+ }
+
+ // Replace with PrivateKeyEntry that has no chain
+ {
+ KeyFactory keyFact = KeyFactory.getInstance("RSA");
+ PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
+ final Certificate[] expectedChain = new Certificate[1];
+ expectedChain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
+
+ PrivateKeyEntry expectedPrivEntry = new PrivateKeyEntry(expectedKey, expectedChain);
+
+ mKeyStore.setEntry(TEST_ALIAS_1, expectedPrivEntry, null);
+
+ Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
+ assertNotNull("Retrieved entry should exist", actualEntry);
+ assertTrue("Retrieved entry should be of type PrivateKeyEntry",
+ actualEntry instanceof PrivateKeyEntry);
+
+ PrivateKeyEntry actualPrivEntry = (PrivateKeyEntry) actualEntry;
+ assertPrivateKeyEntryEquals(actualPrivEntry, FAKE_KEY_1, FAKE_USER_1, null);
+ }
+ }
+
+ public void testKeyStore_SetEntry_CAEntry_Overwrites_CAEntry_Success() throws Exception {
+ mKeyStore.load(null, null);
+
+ final CertificateFactory f = CertificateFactory.getInstance("X.509");
+
+ // Insert TrustedCertificateEntry
+ {
+ final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
+
+ TrustedCertificateEntry expectedCertEntry = new TrustedCertificateEntry(caCert);
+ mKeyStore.setEntry(TEST_ALIAS_1, expectedCertEntry, null);
+
+ Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
+ assertNotNull("Retrieved entry should exist", actualEntry);
+ assertTrue("Retrieved entry should be of type TrustedCertificateEntry",
+ actualEntry instanceof TrustedCertificateEntry);
+ TrustedCertificateEntry actualCertEntry = (TrustedCertificateEntry) actualEntry;
+ assertEquals("Stored and retrieved certificates should be the same",
+ expectedCertEntry.getTrustedCertificate(),
+ actualCertEntry.getTrustedCertificate());
+ }
+
+ // Replace with TrustedCertificateEntry of USER
+ {
+ final Certificate userCert = f
+ .generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
+
+ TrustedCertificateEntry expectedUserEntry = new TrustedCertificateEntry(userCert);
+ mKeyStore.setEntry(TEST_ALIAS_1, expectedUserEntry, null);
+
+ Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
+ assertNotNull("Retrieved entry should exist", actualEntry);
+ assertTrue("Retrieved entry should be of type TrustedCertificateEntry",
+ actualEntry instanceof TrustedCertificateEntry);
+ TrustedCertificateEntry actualUserEntry = (TrustedCertificateEntry) actualEntry;
+ assertEquals("Stored and retrieved certificates should be the same",
+ expectedUserEntry.getTrustedCertificate(),
+ actualUserEntry.getTrustedCertificate());
+ }
+ }
+
+ public void testKeyStore_SetKeyEntry_ProtectedKey_Failure() throws Exception {
+ mKeyStore.load(null, null);
+
+ final CertificateFactory f = CertificateFactory.getInstance("X.509");
+
+ final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
+
+ KeyFactory keyFact = KeyFactory.getInstance("RSA");
+ PrivateKey privKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
+ final Certificate[] chain = new Certificate[2];
+ chain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
+ chain[1] = caCert;
+
+ try {
+ mKeyStore.setKeyEntry(TEST_ALIAS_1, privKey, "foo".toCharArray(), chain);
+ fail("Should fail when a password is specified");
+ } catch (KeyStoreException success) {
+ }
+ }
+
+ public void testKeyStore_SetKeyEntry_Success() throws Exception {
+ mKeyStore.load(null, null);
+
+ final CertificateFactory f = CertificateFactory.getInstance("X.509");
+
+ final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
+
+ KeyFactory keyFact = KeyFactory.getInstance("RSA");
+ PrivateKey privKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
+ final Certificate[] chain = new Certificate[2];
+ chain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
+ chain[1] = caCert;
+
+ mKeyStore.setKeyEntry(TEST_ALIAS_1, privKey, null, chain);
+
+ Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
+ assertNotNull("Retrieved entry should exist", actualEntry);
+
+ assertTrue("Retrieved entry should be of type PrivateKeyEntry",
+ actualEntry instanceof PrivateKeyEntry);
+
+ PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;
+
+ assertPrivateKeyEntryEquals(actual, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
+ }
+
+ public void testKeyStore_SetKeyEntry_Replaced_Success() throws Exception {
+ mKeyStore.load(null, null);
+
+ final CertificateFactory f = CertificateFactory.getInstance("X.509");
+
+ final Certificate caCert = f.generateCertificate(new ByteArrayInputStream(FAKE_CA_1));
+
+ // Insert initial key
+ {
+ KeyFactory keyFact = KeyFactory.getInstance("RSA");
+ PrivateKey privKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
+ final Certificate[] chain = new Certificate[2];
+ chain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
+ chain[1] = caCert;
+
+ mKeyStore.setKeyEntry(TEST_ALIAS_1, privKey, null, chain);
+
+ Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
+ assertNotNull("Retrieved entry should exist", actualEntry);
+
+ assertTrue("Retrieved entry should be of type PrivateKeyEntry",
+ actualEntry instanceof PrivateKeyEntry);
+
+ PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;
+
+ assertPrivateKeyEntryEquals(actual, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
+ }
+
+ // TODO make a separate key
+ // Replace key
+ {
+ KeyFactory keyFact = KeyFactory.getInstance("RSA");
+ PrivateKey privKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_1));
+ final Certificate[] chain = new Certificate[2];
+ chain[0] = f.generateCertificate(new ByteArrayInputStream(FAKE_USER_1));
+ chain[1] = caCert;
+
+ mKeyStore.setKeyEntry(TEST_ALIAS_1, privKey, null, chain);
+
+ Entry actualEntry = mKeyStore.getEntry(TEST_ALIAS_1, null);
+ assertNotNull("Retrieved entry should exist", actualEntry);
+
+ assertTrue("Retrieved entry should be of type PrivateKeyEntry",
+ actualEntry instanceof PrivateKeyEntry);
+
+ PrivateKeyEntry actual = (PrivateKeyEntry) actualEntry;
+
+ assertPrivateKeyEntryEquals(actual, FAKE_KEY_1, FAKE_USER_1, FAKE_CA_1);
+ }
+ }
+
+ public void testKeyStore_Size_Success() throws Exception {
+ mKeyStore.load(null, null);
+
+ assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_1, FAKE_CA_1));
+
+ assertEquals("The keystore size should match expected", 1, mKeyStore.size());
+ assertAliases(new String[] { TEST_ALIAS_1 });
+
+ assertTrue(mAndroidKeyStore.put(Credentials.CA_CERTIFICATE + TEST_ALIAS_2, FAKE_CA_1));
+
+ assertEquals("The keystore size should match expected", 2, mKeyStore.size());
+ assertAliases(new String[] { TEST_ALIAS_1, TEST_ALIAS_2 });
+
+ assertTrue(mAndroidKeyStore.generate(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_3));
+
+ assertEquals("The keystore size should match expected", 3, mKeyStore.size());
+ assertAliases(new String[] { TEST_ALIAS_1, TEST_ALIAS_2, TEST_ALIAS_3 });
+
+ assertTrue(mAndroidKeyStore.delete(Credentials.CA_CERTIFICATE + TEST_ALIAS_1));
+
+ assertEquals("The keystore size should match expected", 2, mKeyStore.size());
+ assertAliases(new String[] { TEST_ALIAS_2, TEST_ALIAS_3 });
+
+ assertTrue(mAndroidKeyStore.delKey(Credentials.USER_PRIVATE_KEY + TEST_ALIAS_3));
+
+ assertEquals("The keystore size should match expected", 1, mKeyStore.size());
+ assertAliases(new String[] { TEST_ALIAS_2 });
+ }
+
+ public void testKeyStore_Store_LoadStoreParam_Failure() throws Exception {
+ mKeyStore.load(null, null);
+
+ try {
+ mKeyStore.store(null);
+ fail("Should throw UnsupportedOperationException when trying to store");
+ } catch (UnsupportedOperationException success) {
+ }
+ }
+
+ public void testKeyStore_Load_InputStreamSupplied_Failure() throws Exception {
+ byte[] buf = "FAKE KEYSTORE".getBytes();
+ ByteArrayInputStream is = new ByteArrayInputStream(buf);
+
+ try {
+ mKeyStore.load(is, null);
+ fail("Should throw IllegalArgumentException when InputStream is supplied");
+ } catch (IllegalArgumentException success) {
+ }
+ }
+
+ public void testKeyStore_Load_PasswordSupplied_Failure() throws Exception {
+ try {
+ mKeyStore.load(null, "password".toCharArray());
+ fail("Should throw IllegalArgumentException when password is supplied");
+ } catch (IllegalArgumentException success) {
+ }
+ }
+
+ public void testKeyStore_Store_OutputStream_Failure() throws Exception {
+ mKeyStore.load(null, null);
+
+ OutputStream sink = new ByteArrayOutputStream();
+ try {
+ mKeyStore.store(sink, null);
+ fail("Should throw UnsupportedOperationException when trying to store");
+ } catch (UnsupportedOperationException success) {
+ }
+
+ try {
+ mKeyStore.store(sink, "blah".toCharArray());
+ fail("Should throw UnsupportedOperationException when trying to store");
+ } catch (UnsupportedOperationException success) {
+ }
+ }
+}
diff --git a/keystore/tests/src/android/security/KeyStoreTest.java b/keystore/tests/src/android/security/KeyStoreTest.java
index 9f35b8d..07a2d7b 100755
--- a/keystore/tests/src/android/security/KeyStoreTest.java
+++ b/keystore/tests/src/android/security/KeyStoreTest.java
@@ -19,9 +19,11 @@ package android.security;
import android.app.Activity;
import android.security.KeyStore;
import android.test.ActivityUnitTestCase;
+import android.test.AssertionFailedError;
import android.test.suitebuilder.annotation.MediumTest;
import java.nio.charset.Charsets;
import java.util.Arrays;
+import java.util.Date;
import java.util.HashSet;
/**
@@ -403,4 +405,52 @@ public class KeyStoreTest extends ActivityUnitTestCase<Activity> {
assertFalse("Should fail to ungrant key to other user second time",
mKeyStore.ungrant(TEST_KEYNAME, 0));
}
+
+ /**
+ * The amount of time to allow before and after expected time for variance
+ * in timing tests.
+ */
+ private static final long SLOP_TIME_MILLIS = 15000L;
+
+ public void testGetmtime_Success() throws Exception {
+ assertTrue("Password should work for keystore",
+ mKeyStore.password(TEST_PASSWD));
+
+ assertTrue("Should be able to import key when unlocked",
+ mKeyStore.importKey(TEST_KEYNAME, PRIVKEY_BYTES));
+
+ long now = System.currentTimeMillis();
+ long actual = mKeyStore.getmtime(TEST_KEYNAME);
+
+ long expectedAfter = now - SLOP_TIME_MILLIS;
+ long expectedBefore = now + SLOP_TIME_MILLIS;
+
+ assertLessThan("Time should be close to current time", expectedBefore, actual);
+ assertGreaterThan("Time should be close to current time", expectedAfter, actual);
+ }
+
+ private static void assertLessThan(String explanation, long expectedBefore, long actual) {
+ if (actual >= expectedBefore) {
+ throw new AssertionFailedError(explanation + ": actual=" + actual
+ + ", expected before: " + expectedBefore);
+ }
+ }
+
+ private static void assertGreaterThan(String explanation, long expectedAfter, long actual) {
+ if (actual <= expectedAfter) {
+ throw new AssertionFailedError(explanation + ": actual=" + actual
+ + ", expected after: " + expectedAfter);
+ }
+ }
+
+ public void testGetmtime_NonExist_Failure() throws Exception {
+ assertTrue("Password should work for keystore",
+ mKeyStore.password(TEST_PASSWD));
+
+ assertTrue("Should be able to import key when unlocked",
+ mKeyStore.importKey(TEST_KEYNAME, PRIVKEY_BYTES));
+
+ assertEquals("-1 should be returned for non-existent key",
+ -1L, mKeyStore.getmtime(TEST_KEYNAME2));
+ }
}
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index caeeb87..27e198c 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -148,8 +148,8 @@ bool CacheTexture::fitBitmap(const SkGlyph& glyph, uint32_t *retOriginX, uint32_
cacheBlock->mX += roundedUpW;
if (mHeight - glyphH >= glyphH) {
// There's enough height left over to create a new CacheBlock
- CacheBlock *newBlock = new CacheBlock(oldX, glyphH, roundedUpW,
- mHeight - glyphH);
+ CacheBlock *newBlock = new CacheBlock(oldX, glyphH + TEXTURE_BORDER_SIZE,
+ roundedUpW, mHeight - glyphH - TEXTURE_BORDER_SIZE);
#if DEBUG_FONT_RENDERER
ALOGD("fitBitmap: Created new block: this, x, y, w, h = %p, %d, %d, %d, %d",
newBlock, newBlock->mX, newBlock->mY,
diff --git a/location/java/android/location/ILocationManager.aidl b/location/java/android/location/ILocationManager.aidl
index a2ce606..f663e0a 100644
--- a/location/java/android/location/ILocationManager.aidl
+++ b/location/java/android/location/ILocationManager.aidl
@@ -45,7 +45,7 @@ interface ILocationManager
in PendingIntent intent, String packageName);
void removeGeofence(in Geofence fence, in PendingIntent intent, String packageName);
- Location getLastLocation(in LocationRequest request);
+ Location getLastLocation(in LocationRequest request, String packageName);
boolean addGpsStatusListener(IGpsStatusListener listener);
void removeGpsStatusListener(IGpsStatusListener listener);
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index 25da208..bef363b 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -1174,8 +1174,10 @@ public class LocationManager {
* @throws SecurityException if no suitable permission is present
*/
public Location getLastLocation() {
+ String packageName = mContext.getPackageName();
+
try {
- return mService.getLastLocation(null);
+ return mService.getLastLocation(null, packageName);
} catch (RemoteException e) {
Log.e(TAG, "RemoteException", e);
return null;
@@ -1204,12 +1206,12 @@ public class LocationManager {
@Deprecated
public Location getLastKnownLocation(String provider) {
checkProvider(provider);
-
+ String packageName = mContext.getPackageName();
LocationRequest request = LocationRequest.createFromDeprecatedProvider(
provider, 0, 0, true);
try {
- return mService.getLastLocation(request);
+ return mService.getLastLocation(request, packageName);
} catch (RemoteException e) {
Log.e(TAG, "RemoteException", e);
return null;
diff --git a/media/jni/mediaeditor/VideoEditorClasses.cpp b/media/jni/mediaeditor/VideoEditorClasses.cpp
index 4e0e0f2..4982a47 100755
--- a/media/jni/mediaeditor/VideoEditorClasses.cpp
+++ b/media/jni/mediaeditor/VideoEditorClasses.cpp
@@ -1853,6 +1853,9 @@ videoEditClasses_getEditSettings(
// Get the clip settings.
videoEditClasses_getClipSettings(pResult, pEnv, clipSettings,
&pSettings->pClipList[i]);
+
+ // Free the local references to avoid memory leaks
+ pEnv->DeleteLocalRef(clipSettings);
}
}
}
@@ -1877,6 +1880,9 @@ videoEditClasses_getEditSettings(
// Get the transition settings.
videoEditClasses_getTransitionSettings(pResult, pEnv,
transitionSettings, &pSettings->pTransitionList[i]);
+
+ // Free the local references to avoid memory leaks
+ pEnv->DeleteLocalRef(transitionSettings);
}
}
}
@@ -1900,6 +1906,9 @@ videoEditClasses_getEditSettings(
// Get the effect settings.
videoEditClasses_getEffectSettings(pResult, pEnv, effectSettings,
&pSettings->Effects[i]);
+
+ // Free the local references to avoid memory leaks
+ pEnv->DeleteLocalRef(effectSettings);
}
}
}
diff --git a/media/jni/mediaeditor/VideoEditorJava.cpp b/media/jni/mediaeditor/VideoEditorJava.cpp
index ec8050f..bcf9099 100755
--- a/media/jni/mediaeditor/VideoEditorJava.cpp
+++ b/media/jni/mediaeditor/VideoEditorJava.cpp
@@ -387,6 +387,9 @@ videoEditJava_getString(
(*pLength) = length;
}
}
+
+ // Delete local references to avoid memory leaks
+ pEnv->DeleteLocalRef(string);
}
// Return the string.
diff --git a/media/jni/mediaeditor/VideoEditorMain.cpp b/media/jni/mediaeditor/VideoEditorMain.cpp
index 41ec120..41c28c0 100755
--- a/media/jni/mediaeditor/VideoEditorMain.cpp
+++ b/media/jni/mediaeditor/VideoEditorMain.cpp
@@ -380,6 +380,9 @@ getClipSetting(
pEnv->GetIntField(object,fid);
M4OSA_TRACE1_1("videoRotation = %d",
pSettings->ClipProperties.videoRotationDegrees);
+
+ // Free the local references to avoid memory leaks
+ pEnv->DeleteLocalRef(clazz);
}
static void jniPreviewProgressCallback (void* cookie, M4OSA_UInt32 msgType,
@@ -1849,7 +1852,9 @@ videoEditor_populateSettings(
"not initialized");
if (needToBeLoaded) {
getClipSetting(pEnv,properties, pContext->pEditSettings->pClipList[i]);
+ pEnv->DeleteLocalRef(properties);
} else {
+ pEnv->DeleteLocalRef(properties);
goto videoEditor_populateSettings_cleanup;
}
}
diff --git a/packages/FakeOemFeatures/src/com/android/fakeoemfeatures/FakeApp.java b/packages/FakeOemFeatures/src/com/android/fakeoemfeatures/FakeApp.java
index 436e579..f11b499 100644
--- a/packages/FakeOemFeatures/src/com/android/fakeoemfeatures/FakeApp.java
+++ b/packages/FakeOemFeatures/src/com/android/fakeoemfeatures/FakeApp.java
@@ -119,7 +119,7 @@ public class FakeApp extends Application {
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
| WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
- if (ActivityManager.isHighEndGfx(display)) {
+ if (ActivityManager.isHighEndGfx()) {
lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
}
lp.width = ViewGroup.LayoutParams.MATCH_PARENT;
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index e13378f..2eee31d 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -132,6 +132,14 @@
android:excludeFromRecents="true">
</activity>
+ <!-- started from UsbDebuggingManager -->
+ <activity android:name=".usb.UsbDebuggingActivity"
+ android:permission="android.permission.MANAGE_USB"
+ android:theme="@*android:style/Theme.Holo.Dialog.Alert"
+ android:finishOnCloseSystemDialogs="true"
+ android:excludeFromRecents="true">
+ </activity>
+
<!-- started from NetworkPolicyManagerService -->
<activity
android:name=".net.NetworkOverLimitActivity"
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 2ce950f..5747f22 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -154,6 +154,15 @@
<!-- Checkbox label for USB accessory dialogs. [CHAR LIMIT=50] -->
<string name="always_use_accessory">Use by default for this USB accessory</string>
+ <!-- Title of confirmation dialog for USB debugging -->
+ <string name="usb_debugging_title">Allow USB Debugging?</string>
+
+ <!-- Message of confirmation dialog for USB debugging -->
+ <string name="usb_debugging_message">Allow USB Debugging from this computer?\nYour RSA key fingerprint is\n<xliff:g id="fingerprint">%1$s</xliff:g></string>
+
+ <!-- Option to always allow USB debugging from the attached computer -->
+ <string name="usb_debugging_always">Always allow this computer</string>
+
<!-- Checkbox label for application compatibility mode ON (zooming app to look like it's running
on a phone). [CHAR LIMIT=25] -->
<string name="compat_mode_on">Zoom to fill screen</string>
diff --git a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
index a72074e..2512c02 100644
--- a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
@@ -74,10 +74,7 @@ public class ImageWallpaper extends WallpaperService {
//noinspection PointlessBooleanExpression,ConstantConditions
if (FIXED_SIZED_SURFACE && USE_OPENGL) {
if (!isEmulator()) {
- WindowManager windowManager =
- (WindowManager) getSystemService(Context.WINDOW_SERVICE);
- Display display = windowManager.getDefaultDisplay();
- mIsHwAccelerated = ActivityManager.isHighEndGfx(display);
+ mIsHwAccelerated = ActivityManager.isHighEndGfx();
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIService.java b/packages/SystemUI/src/com/android/systemui/SystemUIService.java
index 0a57499..1bde949 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIService.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIService.java
@@ -31,6 +31,7 @@ import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.Slog;
import android.view.IWindowManager;
+import android.view.WindowManagerGlobal;
public class SystemUIService extends Service {
static final String TAG = "SystemUIService";
@@ -67,8 +68,7 @@ public class SystemUIService extends Service {
@Override
public void onCreate() {
// Pick status bar or system bar.
- IWindowManager wm = IWindowManager.Stub.asInterface(
- ServiceManager.getService(Context.WINDOW_SERVICE));
+ IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
try {
SERVICES[0] = wm.hasSystemNavBar()
? R.string.config_systemBarComponent
diff --git a/packages/SystemUI/src/com/android/systemui/UniverseBackground.java b/packages/SystemUI/src/com/android/systemui/UniverseBackground.java
index 4852a3e..7628754 100644
--- a/packages/SystemUI/src/com/android/systemui/UniverseBackground.java
+++ b/packages/SystemUI/src/com/android/systemui/UniverseBackground.java
@@ -33,6 +33,7 @@ import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewRootImpl;
import android.view.WindowManager;
+import android.view.WindowManagerGlobal;
import android.view.animation.Transformation;
import android.widget.FrameLayout;
@@ -96,7 +97,7 @@ public class UniverseBackground extends FrameLayout {
public UniverseBackground(Context context) {
super(context);
setBackgroundColor(0xff000000);
- mSession = ViewRootImpl.getWindowSession(context.getMainLooper());
+ mSession = WindowManagerGlobal.getWindowSession(context.getMainLooper());
mContent = View.inflate(context, R.layout.universe, null);
addView(mContent);
mContent.findViewById(R.id.close).setOnClickListener(new View.OnClickListener() {
@@ -155,7 +156,7 @@ public class UniverseBackground extends FrameLayout {
}
}
- public WindowManager.LayoutParams getLayoutParams(Display display) {
+ public WindowManager.LayoutParams getLayoutParams() {
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_UNIVERSE_BACKGROUND,
@@ -165,7 +166,7 @@ public class UniverseBackground extends FrameLayout {
| WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
PixelFormat.OPAQUE);
// this will allow the window to run in an overlay on devices that support this
- if (ActivityManager.isHighEndGfx(display)) {
+ if (ActivityManager.isHighEndGfx()) {
lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
}
lp.setTitle("UniverseBackground");
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
index d5a76bc..b407078 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
@@ -49,6 +49,7 @@ import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
+import android.view.WindowManagerGlobal;
import android.view.accessibility.AccessibilityEvent;
import android.view.animation.AnimationUtils;
import android.widget.AdapterView;
@@ -488,9 +489,7 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
mChoreo = new Choreographer(this, mRecentsScrim, mRecentsContainer, mRecentsNoApps, this);
if (mRecentsScrim != null) {
- Display d = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
- .getDefaultDisplay();
- mHighEndGfx = ActivityManager.isHighEndGfx(d);
+ mHighEndGfx = ActivityManager.isHighEndGfx();
if (!mHighEndGfx) {
mRecentsScrim.setBackground(null);
} else if (mRecentsScrim.getBackground() instanceof BitmapDrawable) {
@@ -733,8 +732,7 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
if (mTransitionBg == null) {
mTransitionBg = (View) findViewById(R.id.recents_transition_background);
- IWindowManager wm = IWindowManager.Stub.asInterface(
- ServiceManager.getService(Context.WINDOW_SERVICE));
+ IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
try {
if (!wm.hasSystemNavBar()) {
FrameLayout.LayoutParams lp =
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 646f98a..e9e043e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -61,9 +61,9 @@ import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
+import android.view.WindowManagerGlobal;
import android.view.ViewGroup.LayoutParams;
import android.view.WindowManager;
-import android.view.WindowManagerImpl;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.PopupMenu;
@@ -127,17 +127,11 @@ public abstract class BaseStatusBar extends SystemUI implements
*/
protected abstract void createAndAddWindows();
+ protected WindowManager mWindowManager;
+ protected IWindowManager mWindowManagerService;
protected Display mDisplay;
- private IWindowManager mWindowManager;
- private boolean mDeviceProvisioned = false;
-
- public IWindowManager getWindowManager() {
- return mWindowManager;
- }
- public Display getDisplay() {
- return mDisplay;
- }
+ private boolean mDeviceProvisioned = false;
public IStatusBarService getStatusBarService() {
return mBarService;
@@ -189,17 +183,15 @@ public abstract class BaseStatusBar extends SystemUI implements
};
public void start() {
- mDisplay = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
- .getDefaultDisplay();
+ mWindowManager = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
+ mWindowManagerService = WindowManagerGlobal.getWindowManagerService();
+ mDisplay = mWindowManager.getDefaultDisplay();
mProvisioningObserver.onChange(false); // set up
mContext.getContentResolver().registerContentObserver(
Settings.Secure.getUriFor(Settings.Secure.DEVICE_PROVISIONED), true,
mProvisioningObserver);
- mWindowManager = IWindowManager.Stub.asInterface(
- ServiceManager.getService(Context.WINDOW_SERVICE));
-
mBarService = IStatusBarService.Stub.asInterface(
ServiceManager.getService(Context.STATUS_BAR_SERVICE));
@@ -436,7 +428,7 @@ public abstract class BaseStatusBar extends SystemUI implements
boolean firstScreenful = false;
if (mRecentsPanel != null) {
visible = mRecentsPanel.isShowing();
- WindowManagerImpl.getDefault().removeView(mRecentsPanel);
+ mWindowManager.removeView(mRecentsPanel);
if (visible) {
recentTasksList = mRecentsPanel.getRecentTasksList();
firstScreenful = mRecentsPanel.getFirstScreenful();
@@ -456,7 +448,7 @@ public abstract class BaseStatusBar extends SystemUI implements
WindowManager.LayoutParams lp = getRecentsLayoutParams(mRecentsPanel.getLayoutParams());
- WindowManagerImpl.getDefault().addView(mRecentsPanel, lp);
+ mWindowManager.addView(mRecentsPanel, lp);
mRecentsPanel.setBar(this);
if (visible) {
mRecentsPanel.show(true, false, recentTasksList, firstScreenful);
@@ -469,7 +461,7 @@ public abstract class BaseStatusBar extends SystemUI implements
boolean visible = false;
if (mSearchPanelView != null) {
visible = mSearchPanelView.isShowing();
- WindowManagerImpl.getDefault().removeView(mSearchPanelView);
+ mWindowManager.removeView(mSearchPanelView);
}
// Provide SearchPanel with a temporary parent to allow layout params to work.
@@ -482,7 +474,7 @@ public abstract class BaseStatusBar extends SystemUI implements
WindowManager.LayoutParams lp = getSearchLayoutParams(mSearchPanelView.getLayoutParams());
- WindowManagerImpl.getDefault().addView(mSearchPanelView, lp);
+ mWindowManager.addView(mSearchPanelView, lp);
mSearchPanelView.setBar(this);
if (visible) {
mSearchPanelView.show(true, false);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index 63c9b79..33973b6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -18,13 +18,11 @@ package com.android.systemui.statusbar.phone;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
-import android.animation.ObjectAnimator;
import android.app.StatusBarManager;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Point;
import android.graphics.Rect;
-import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;
@@ -34,19 +32,14 @@ import android.util.Slog;
import android.view.animation.AccelerateInterpolator;
import android.view.Display;
import android.view.MotionEvent;
-import android.view.VelocityTracker;
import android.view.View;
-import android.view.ViewGroup;
import android.view.Surface;
-import android.view.Window;
import android.view.WindowManager;
-import android.view.WindowManagerImpl;
import android.widget.ImageView;
import android.widget.LinearLayout;
import java.io.FileDescriptor;
import java.io.PrintWriter;
-import java.lang.StringBuilder;
import com.android.internal.statusbar.IStatusBarService;
import com.android.systemui.R;
@@ -244,7 +237,8 @@ public class NavigationBarView extends LinearLayout {
} else {
return;
}
- WindowManagerImpl.getDefault().updateViewLayout(this, lp);
+ WindowManager wm = (WindowManager)getContext().getSystemService(Context.WINDOW_SERVICE);
+ wm.updateViewLayout(this, lp);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 49e4760..2886441 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -60,9 +60,9 @@ import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewGroup;
+import android.view.WindowManagerGlobal;
import android.view.ViewGroup.LayoutParams;
import android.view.WindowManager;
-import android.view.WindowManagerImpl;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
@@ -150,7 +150,6 @@ public class PhoneStatusBar extends BaseStatusBar {
int mIconHPadding = -1;
Display mDisplay;
- IWindowManager mWindowManager;
IDreamManager mDreamManager;
StatusBarWindowView mStatusBarWindow;
@@ -261,9 +260,6 @@ public class PhoneStatusBar extends BaseStatusBar {
mDisplay = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
.getDefaultDisplay();
- mWindowManager = IWindowManager.Stub.asInterface(
- ServiceManager.getService(Context.WINDOW_SERVICE));
-
mDreamManager = IDreamManager.Stub.asInterface(
ServiceManager.checkService("dreams"));
@@ -332,7 +328,7 @@ public class PhoneStatusBar extends BaseStatusBar {
mSettingsPanel = (PanelView) mStatusBarWindow.findViewById(R.id.settings_panel);
mSettingsPanel.setOnTouchListener(clickStopper);
- if (!ActivityManager.isHighEndGfx(mDisplay)) {
+ if (!ActivityManager.isHighEndGfx()) {
mStatusBarWindow.setBackground(null);
mNotificationPanel.setBackground(new FastColorDrawable(context.getResources().getColor(
R.color.notification_panel_solid_background)));
@@ -352,7 +348,7 @@ public class PhoneStatusBar extends BaseStatusBar {
updateShowSearchHoldoff();
try {
- boolean showNav = mWindowManager.hasNavigationBar();
+ boolean showNav = mWindowManagerService.hasNavigationBar();
if (DEBUG) Slog.v(TAG, "hasNavigationBar=" + showNav);
if (showNav) {
mNavigationBarView =
@@ -474,7 +470,7 @@ public class PhoneStatusBar extends BaseStatusBar {
| WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
| WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
(opaque ? PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT));
- if (ActivityManager.isHighEndGfx(mDisplay)) {
+ if (ActivityManager.isHighEndGfx()) {
lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
} else {
lp.flags |= WindowManager.LayoutParams.FLAG_DIM_BEHIND;
@@ -499,7 +495,7 @@ public class PhoneStatusBar extends BaseStatusBar {
| WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
| WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
(opaque ? PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT));
- if (ActivityManager.isHighEndGfx(mDisplay)) {
+ if (ActivityManager.isHighEndGfx()) {
lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
}
lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
@@ -535,7 +531,7 @@ public class PhoneStatusBar extends BaseStatusBar {
WindowManager.LayoutParams lp =
(android.view.WindowManager.LayoutParams) mNavigationBarView.getLayoutParams();
lp.flags &= ~WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
- WindowManagerImpl.getDefault().updateViewLayout(mNavigationBarView, lp);
+ mWindowManager.updateViewLayout(mNavigationBarView, lp);
}
@Override
@@ -544,7 +540,7 @@ public class PhoneStatusBar extends BaseStatusBar {
WindowManager.LayoutParams lp =
(android.view.WindowManager.LayoutParams) mNavigationBarView.getLayoutParams();
lp.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
- WindowManagerImpl.getDefault().updateViewLayout(mNavigationBarView, lp);
+ mWindowManager.updateViewLayout(mNavigationBarView, lp);
}
protected int getStatusBarGravity() {
@@ -620,8 +616,7 @@ public class PhoneStatusBar extends BaseStatusBar {
prepareNavigationBarView();
- WindowManagerImpl.getDefault().addView(
- mNavigationBarView, getNavigationBarLayoutParams());
+ mWindowManager.addView(mNavigationBarView, getNavigationBarLayoutParams());
}
private void repositionNavigationBar() {
@@ -629,8 +624,7 @@ public class PhoneStatusBar extends BaseStatusBar {
prepareNavigationBarView();
- WindowManagerImpl.getDefault().updateViewLayout(
- mNavigationBarView, getNavigationBarLayoutParams());
+ mWindowManager.updateViewLayout(mNavigationBarView, getNavigationBarLayoutParams());
}
private WindowManager.LayoutParams getNavigationBarLayoutParams() {
@@ -644,7 +638,7 @@ public class PhoneStatusBar extends BaseStatusBar {
| WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
PixelFormat.OPAQUE);
// this will allow the navbar to run in an overlay on devices that support this
- if (ActivityManager.isHighEndGfx(mDisplay)) {
+ if (ActivityManager.isHighEndGfx()) {
lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
}
@@ -671,7 +665,7 @@ public class PhoneStatusBar extends BaseStatusBar {
lp.packageName = mContext.getPackageName();
lp.windowAnimations = R.style.Animation_StatusBar_IntruderAlert;
- WindowManagerImpl.getDefault().addView(mIntruderAlertView, lp);
+ mWindowManager.addView(mIntruderAlertView, lp);
}
public void addIcon(String slot, int index, int viewIndex, StatusBarIcon icon) {
@@ -1157,8 +1151,7 @@ public class PhoneStatusBar extends BaseStatusBar {
lp.flags &= ~WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
lp.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
lp.height = ViewGroup.LayoutParams.MATCH_PARENT;
- final WindowManager wm = WindowManagerImpl.getDefault();
- wm.updateViewLayout(mStatusBarWindow, lp);
+ mWindowManager.updateViewLayout(mStatusBarWindow, lp);
// Updating the window layout will force an expensive traversal/redraw.
// Kick off the reveal animation after this is complete to avoid animation latency.
@@ -1231,8 +1224,7 @@ public class PhoneStatusBar extends BaseStatusBar {
lp.height = getStatusBarHeight();
lp.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
lp.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
- final WindowManager wm = WindowManagerImpl.getDefault();
- wm.updateViewLayout(mStatusBarWindow, lp);
+ mWindowManager.updateViewLayout(mStatusBarWindow, lp);
if ((mDisabled & StatusBarManager.DISABLE_NOTIFICATION_ICONS) == 0) {
setNotificationIconVisibility(true, com.android.internal.R.anim.fade_in);
@@ -1409,7 +1401,7 @@ public class PhoneStatusBar extends BaseStatusBar {
private void notifyUiVisibilityChanged() {
try {
- mWindowManager.statusBarVisibilityChanged(mSystemUiVisibility);
+ mWindowManagerService.statusBarVisibilityChanged(mSystemUiVisibility);
} catch (RemoteException ex) {
}
}
@@ -1615,7 +1607,7 @@ public class PhoneStatusBar extends BaseStatusBar {
lp.packageName = mContext.getPackageName();
makeStatusBarView();
- WindowManagerImpl.getDefault().addView(mStatusBarWindow, lp);
+ mWindowManager.addView(mStatusBarWindow, lp);
}
void setNotificationIconVisibility(boolean visible, int anim) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
index 2a96d6d..6d47493 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
@@ -140,7 +140,7 @@ public class PhoneStatusBarView extends PanelBar {
super.panelExpansionChanged(pv, frac);
if (mFadingPanel == pv
- && mScrimColor != 0 && ActivityManager.isHighEndGfx(mBar.mDisplay)) {
+ && mScrimColor != 0 && ActivityManager.isHighEndGfx()) {
// woo, special effects
final float k = (float)(1f-0.5f*(1f-Math.cos(3.14159f * Math.pow(1f-frac, 2.2f))));
// attenuate background color alpha by k
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/ShirtPocket.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/ShirtPocket.java
index ddb43b8..2924cc9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/ShirtPocket.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/ShirtPocket.java
@@ -34,7 +34,6 @@ import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
-import android.view.WindowManagerImpl;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
index cbd8831..84697e0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -53,7 +53,6 @@ import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.WindowManager;
-import android.view.WindowManagerImpl;
import android.view.accessibility.AccessibilityEvent;
import android.widget.ImageView;
import android.widget.LinearLayout;
@@ -124,8 +123,6 @@ public class TabletStatusBar extends BaseStatusBar implements
int mMenuNavIconWidth = -1;
private int mMaxNotificationIcons = 5;
- IWindowManager mWindowManager;
-
TabletStatusBarView mStatusBarView;
View mNotificationArea;
View mNotificationTrigger;
@@ -241,7 +238,7 @@ public class TabletStatusBar extends BaseStatusBar implements
lp.gravity = getStatusBarGravity();
lp.setTitle("SystemBar");
lp.packageName = mContext.getPackageName();
- WindowManagerImpl.getDefault().addView(sb, lp);
+ mWindowManager.addView(sb, lp);
}
protected void addPanelWindows() {
@@ -306,7 +303,7 @@ public class TabletStatusBar extends BaseStatusBar implements
lp.windowAnimations = com.android.internal.R.style.Animation; // == no animation
// lp.windowAnimations = com.android.internal.R.style.Animation_ZoomButtons; // simple fade
- WindowManagerImpl.getDefault().addView(mNotificationPanel, lp);
+ mWindowManager.addView(mNotificationPanel, lp);
// Recents Panel
mRecentTasksLoader = new RecentTasksLoader(context);
@@ -338,7 +335,7 @@ public class TabletStatusBar extends BaseStatusBar implements
lp.setTitle("InputMethodsPanel");
lp.windowAnimations = R.style.Animation_RecentPanel;
- WindowManagerImpl.getDefault().addView(mInputMethodsPanel, lp);
+ mWindowManager.addView(mInputMethodsPanel, lp);
// Compatibility mode selector panel
mCompatModePanel = (CompatModePanel) View.inflate(context,
@@ -361,7 +358,7 @@ public class TabletStatusBar extends BaseStatusBar implements
lp.setTitle("CompatModePanel");
lp.windowAnimations = android.R.style.Animation_Dialog;
- WindowManagerImpl.getDefault().addView(mCompatModePanel, lp);
+ mWindowManager.addView(mCompatModePanel, lp);
mRecentButton.setOnTouchListener(mRecentsPanel);
@@ -380,7 +377,7 @@ public class TabletStatusBar extends BaseStatusBar implements
private int getNotificationPanelHeight() {
final Resources res = mContext.getResources();
- final Display d = WindowManagerImpl.getDefault().getDefaultDisplay();
+ final Display d = mWindowManager.getDefaultDisplay();
final Point size = new Point();
d.getRealSize(size);
return Math.max(res.getDimensionPixelSize(R.dimen.notification_panel_min_height), size.y);
@@ -395,8 +392,7 @@ public class TabletStatusBar extends BaseStatusBar implements
protected void onConfigurationChanged(Configuration newConfig) {
loadDimens();
mNotificationPanelParams.height = getNotificationPanelHeight();
- WindowManagerImpl.getDefault().updateViewLayout(mNotificationPanel,
- mNotificationPanelParams);
+ mWindowManager.updateViewLayout(mNotificationPanel, mNotificationPanelParams);
mRecentsPanel.updateValuesFromResources();
mShowSearchHoldoff = mContext.getResources().getInteger(
R.integer.config_show_search_delay);
@@ -456,9 +452,6 @@ public class TabletStatusBar extends BaseStatusBar implements
protected View makeStatusBarView() {
final Context context = mContext;
- mWindowManager = IWindowManager.Stub.asInterface(
- ServiceManager.getService(Context.WINDOW_SERVICE));
-
loadDimens();
final TabletStatusBarView sb = (TabletStatusBarView)View.inflate(
@@ -470,7 +463,7 @@ public class TabletStatusBar extends BaseStatusBar implements
try {
// Sanity-check that someone hasn't set up the config wrong and asked for a navigation
// bar on a tablet that has only the system bar
- if (mWindowManager.hasNavigationBar()) {
+ if (mWindowManagerService.hasNavigationBar()) {
Slog.e(TAG, "Tablet device cannot show navigation bar and system bar");
}
} catch (RemoteException ex) {
@@ -648,7 +641,7 @@ public class TabletStatusBar extends BaseStatusBar implements
| WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
| WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
(opaque ? PixelFormat.OPAQUE : PixelFormat.TRANSLUCENT));
- if (ActivityManager.isHighEndGfx(mDisplay)) {
+ if (ActivityManager.isHighEndGfx()) {
lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
} else {
lp.flags |= WindowManager.LayoutParams.FLAG_DIM_BEHIND;
@@ -681,7 +674,7 @@ public class TabletStatusBar extends BaseStatusBar implements
WindowManager.LayoutParams lp =
(android.view.WindowManager.LayoutParams) mStatusBarView.getLayoutParams();
lp.flags &= ~WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
- WindowManagerImpl.getDefault().updateViewLayout(mStatusBarView, lp);
+ mWindowManager.updateViewLayout(mStatusBarView, lp);
}
@Override
@@ -690,7 +683,7 @@ public class TabletStatusBar extends BaseStatusBar implements
WindowManager.LayoutParams lp =
(android.view.WindowManager.LayoutParams) mStatusBarView.getLayoutParams();
lp.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
- WindowManagerImpl.getDefault().updateViewLayout(mStatusBarView, lp);
+ mWindowManager.updateViewLayout(mStatusBarView, lp);
}
public int getStatusBarHeight() {
@@ -712,8 +705,7 @@ public class TabletStatusBar extends BaseStatusBar implements
}
if (lp.height != height) {
lp.height = height;
- final WindowManager wm = WindowManagerImpl.getDefault();
- wm.updateViewLayout(mStatusBarView, lp);
+ mWindowManager.updateViewLayout(mStatusBarView, lp);
}
}
@@ -1068,7 +1060,7 @@ public class TabletStatusBar extends BaseStatusBar implements
private void notifyUiVisibilityChanged() {
try {
- mWindowManager.statusBarVisibilityChanged(mSystemUiVisibility);
+ mWindowManagerService.statusBarVisibilityChanged(mSystemUiVisibility);
} catch (RemoteException ex) {
}
}
@@ -1160,12 +1152,12 @@ public class TabletStatusBar extends BaseStatusBar implements
| WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
lp.windowAnimations = com.android.internal.R.style.Animation_ZoomButtons; // simple fade
- WindowManagerImpl.getDefault().addView(mCompatibilityHelpDialog, lp);
+ mWindowManager.addView(mCompatibilityHelpDialog, lp);
}
private void hideCompatibilityHelp() {
if (mCompatibilityHelpDialog != null) {
- WindowManagerImpl.getDefault().removeView(mCompatibilityHelpDialog);
+ mWindowManager.removeView(mCompatibilityHelpDialog);
mCompatibilityHelpDialog = null;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java
index d4ebe6d..932b035 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java
@@ -35,7 +35,6 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
-import android.view.WindowManagerImpl;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.FrameLayout;
@@ -62,7 +61,8 @@ public class TabletTicker
private static final int ADVANCE_DELAY = 5000; // 5 seconds
- private Context mContext;
+ private final Context mContext;
+ private final WindowManager mWindowManager;
private ViewGroup mWindow;
private IBinder mCurrentKey;
@@ -83,6 +83,7 @@ public class TabletTicker
public TabletTicker(TabletStatusBar bar) {
mBar = bar;
mContext = bar.getContext();
+ mWindowManager = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
final Resources res = mContext.getResources();
mLargeIconHeight = res.getDimensionPixelSize(
android.R.dimen.notification_large_icon_height);
@@ -178,7 +179,7 @@ public class TabletTicker
if (mCurrentView != null) {
if (mWindow == null) {
mWindow = makeWindow();
- WindowManagerImpl.getDefault().addView(mWindow, mWindow.getLayoutParams());
+ mWindowManager.addView(mWindow, mWindow.getLayoutParams());
}
mWindow.addView(mCurrentView);
@@ -242,7 +243,7 @@ public class TabletTicker
public void endTransition(LayoutTransition transition, ViewGroup container,
View view, int transitionType) {
if (mWindowShouldClose) {
- WindowManagerImpl.getDefault().removeView(mWindow);
+ mWindowManager.removeView(mWindow);
mWindow = null;
mWindowShouldClose = false;
mBar.doneTicking();
diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java
new file mode 100644
index 0000000..9146ccd
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.usb;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.graphics.Typeface;
+import android.hardware.usb.IUsbManager;
+import android.hardware.usb.UsbDevice;
+import android.hardware.usb.UsbManager;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.ServiceManager;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.CheckBox;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.android.internal.app.AlertActivity;
+import com.android.internal.app.AlertController;
+
+import com.android.systemui.R;
+
+public class UsbDebuggingActivity extends AlertActivity
+ implements DialogInterface.OnClickListener {
+ private static final String TAG = "UsbDebuggingActivity";
+
+ private CheckBox mAlwaysAllow;
+ private UsbDisconnectedReceiver mDisconnectedReceiver;
+ private String mKey;
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ mDisconnectedReceiver = new UsbDisconnectedReceiver(this);
+ Intent intent = getIntent();
+ String fingerprints = intent.getStringExtra("fingerprints");
+ mKey = intent.getStringExtra("key");
+
+ if (fingerprints == null || mKey == null) {
+ finish();
+ return;
+ }
+
+ final AlertController.AlertParams ap = mAlertParams;
+ ap.mTitle = getString(R.string.usb_debugging_title);
+ ap.mIconId = com.android.internal.R.drawable.ic_dialog_usb;
+ ap.mMessage = getString(R.string.usb_debugging_message, fingerprints);
+ ap.mPositiveButtonText = getString(android.R.string.ok);
+ ap.mNegativeButtonText = getString(android.R.string.cancel);
+ ap.mPositiveButtonListener = this;
+ ap.mNegativeButtonListener = this;
+
+ // add "always allow" checkbox
+ LayoutInflater inflater = LayoutInflater.from(ap.mContext);
+ View checkbox = inflater.inflate(com.android.internal.R.layout.always_use_checkbox, null);
+ mAlwaysAllow = (CheckBox)checkbox.findViewById(com.android.internal.R.id.alwaysUse);
+ mAlwaysAllow.setText(getString(R.string.usb_debugging_always));
+ ap.mView = checkbox;
+
+ setupAlert();
+ }
+
+ private class UsbDisconnectedReceiver extends BroadcastReceiver {
+ private final Activity mActivity;
+ public UsbDisconnectedReceiver(Activity activity) {
+ mActivity = activity;
+ }
+
+ @Override
+ public void onReceive(Context content, Intent intent) {
+ String action = intent.getAction();
+ if (!UsbManager.ACTION_USB_STATE.equals(action)) {
+ return;
+ }
+ boolean connected = intent.getBooleanExtra(UsbManager.USB_CONNECTED, false);
+ if (!connected) {
+ mActivity.finish();
+ }
+ }
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ IntentFilter filter = new IntentFilter(UsbManager.ACTION_USB_STATE);
+ registerReceiver(mDisconnectedReceiver, filter);
+ }
+
+ @Override
+ protected void onStop() {
+ if (mDisconnectedReceiver != null) {
+ unregisterReceiver(mDisconnectedReceiver);
+ }
+ super.onStop();
+ }
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ boolean allow = (which == AlertDialog.BUTTON_POSITIVE);
+ boolean alwaysAllow = allow && mAlwaysAllow.isChecked();
+ try {
+ IBinder b = ServiceManager.getService(USB_SERVICE);
+ IUsbManager service = IUsbManager.Stub.asInterface(b);
+ if (allow) {
+ service.allowUsbDebugging(alwaysAllow, mKey);
+ } else {
+ service.denyUsbDebugging();
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "Unable to notify Usb service", e);
+ }
+ finish();
+ }
+}
diff --git a/policy/src/com/android/internal/policy/impl/GlobalActions.java b/policy/src/com/android/internal/policy/impl/GlobalActions.java
index a0e3e3c..8d19f34 100644
--- a/policy/src/com/android/internal/policy/impl/GlobalActions.java
+++ b/policy/src/com/android/internal/policy/impl/GlobalActions.java
@@ -50,6 +50,7 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
+import android.view.WindowManagerGlobal;
import android.view.WindowManagerPolicy.WindowManagerFuncs;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
@@ -90,8 +91,6 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
private boolean mHasTelephony;
private boolean mHasVibrator;
- private IWindowManager mIWindowManager;
-
/**
* @param context everything needs a context :(
*/
@@ -210,11 +209,11 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
public void onPress() {
// shutdown by making sure radio and power are handled accordingly.
- mWindowManagerFuncs.shutdown();
+ mWindowManagerFuncs.shutdown(true);
}
public boolean onLongPress() {
- mWindowManagerFuncs.rebootSafeMode();
+ mWindowManagerFuncs.rebootSafeMode(true);
return true;
}
@@ -300,7 +299,7 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
public void onPress() {
try {
ActivityManagerNative.getDefault().switchUser(user.id);
- getWindowManager().lockNow();
+ WindowManagerGlobal.getWindowManagerService().lockNow();
} catch (RemoteException re) {
Log.e(TAG, "Couldn't switch user " + re);
}
@@ -873,12 +872,4 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac
mAirplaneState = on ? ToggleAction.State.On : ToggleAction.State.Off;
}
}
-
- private IWindowManager getWindowManager() {
- if (mIWindowManager == null) {
- IBinder b = ServiceManager.getService(Context.WINDOW_SERVICE);
- mIWindowManager = IWindowManager.Stub.asInterface(b);
- }
- return mIWindowManager;
- }
}
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
index 279314d..5c0cd4f 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
@@ -259,7 +259,8 @@ public class KeyguardUpdateMonitor {
*/
boolean isPluggedIn() {
return plugged == BatteryManager.BATTERY_PLUGGED_AC
- || plugged == BatteryManager.BATTERY_PLUGGED_USB;
+ || plugged == BatteryManager.BATTERY_PLUGGED_USB
+ || plugged == BatteryManager.BATTERY_PLUGGED_WIRELESS;
}
/**
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java b/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java
index fb6ff24..d521c05 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardViewManager.java
@@ -123,8 +123,7 @@ public class KeyguardViewManager implements KeyguardWindowController {
if (!mNeedsInput) {
flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
}
- if (ActivityManager.isHighEndGfx(((WindowManager)mContext.getSystemService(
- Context.WINDOW_SERVICE)).getDefaultDisplay())) {
+ if (ActivityManager.isHighEndGfx()) {
flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
}
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
@@ -132,8 +131,7 @@ public class KeyguardViewManager implements KeyguardWindowController {
flags, PixelFormat.TRANSLUCENT);
lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
lp.windowAnimations = com.android.internal.R.style.Animation_LockScreen;
- if (ActivityManager.isHighEndGfx(((WindowManager)mContext.getSystemService(
- Context.WINDOW_SERVICE)).getDefaultDisplay())) {
+ if (ActivityManager.isHighEndGfx()) {
lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
lp.privateFlags |=
WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_HARDWARE_ACCELERATED;
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
index 66ccdac..4d05a87 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
@@ -44,7 +44,7 @@ import android.telephony.TelephonyManager;
import android.util.EventLog;
import android.util.Log;
import android.view.KeyEvent;
-import android.view.WindowManagerImpl;
+import android.view.WindowManager;
import android.view.WindowManagerPolicy;
@@ -376,9 +376,9 @@ public class KeyguardViewMediator implements KeyguardViewCallback {
mKeyguardViewProperties
= new LockPatternKeyguardViewProperties(mLockPatternUtils, mUpdateMonitor);
+ WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
mKeyguardViewManager = new KeyguardViewManager(
- context, WindowManagerImpl.getDefault(), this,
- mKeyguardViewProperties, mUpdateMonitor);
+ context, wm, this, mKeyguardViewProperties, mUpdateMonitor);
mUserPresentIntent = new Intent(Intent.ACTION_USER_PRESENT);
mUserPresentIntent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 737df7f..209ad38 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -42,6 +42,7 @@ import android.media.AudioManager;
import android.media.IAudioService;
import android.os.BatteryManager;
import android.os.Bundle;
+import android.os.FactoryTest;
import android.os.Handler;
import android.os.IBinder;
import android.os.IRemoteCallback;
@@ -82,6 +83,7 @@ import android.view.InputEventReceiver;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.MotionEvent;
+import android.view.WindowManagerGlobal;
import android.view.WindowOrientationListener;
import android.view.Surface;
import android.view.View;
@@ -132,7 +134,6 @@ import static android.view.WindowManager.LayoutParams.TYPE_POINTER;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
import static android.view.WindowManager.LayoutParams.TYPE_BOOT_PROGRESS;
-import android.view.WindowManagerImpl;
import android.view.WindowManagerPolicy;
import static android.view.WindowManagerPolicy.WindowManagerFuncs.LID_ABSENT;
import static android.view.WindowManagerPolicy.WindowManagerFuncs.LID_OPEN;
@@ -172,6 +173,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
static final int LONG_PRESS_POWER_NOTHING = 0;
static final int LONG_PRESS_POWER_GLOBAL_ACTIONS = 1;
static final int LONG_PRESS_POWER_SHUT_OFF = 2;
+ static final int LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM = 3;
// These need to match the documentation/constant in
// core/res/res/values/config.xml
@@ -716,8 +718,12 @@ public class PhoneWindowManager implements WindowManagerPolicy {
public void run() {
// The context isn't read
if (mLongPressOnPowerBehavior < 0) {
- mLongPressOnPowerBehavior = mContext.getResources().getInteger(
- com.android.internal.R.integer.config_longPressOnPowerBehavior);
+ if (FactoryTest.isLongPressOnPowerOffEnabled()) {
+ mLongPressOnPowerBehavior = LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM;
+ } else {
+ mLongPressOnPowerBehavior = mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_longPressOnPowerBehavior);
+ }
}
switch (mLongPressOnPowerBehavior) {
case LONG_PRESS_POWER_NOTHING:
@@ -729,10 +735,12 @@ public class PhoneWindowManager implements WindowManagerPolicy {
showGlobalActionsDialog();
break;
case LONG_PRESS_POWER_SHUT_OFF:
+ case LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM:
mPowerKeyHandled = true;
performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);
- mWindowManagerFuncs.shutdown();
+ mWindowManagerFuncs.shutdown(
+ mLongPressOnPowerBehavior == LONG_PRESS_POWER_SHUT_OFF);
break;
}
}
@@ -1172,7 +1180,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
if (type < WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW
|| type > WindowManager.LayoutParams.LAST_SYSTEM_WINDOW) {
- return WindowManagerImpl.ADD_OKAY;
+ return WindowManagerGlobal.ADD_OKAY;
}
String permission = null;
switch (type) {
@@ -1199,10 +1207,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
if (permission != null) {
if (mContext.checkCallingOrSelfPermission(permission)
!= PackageManager.PERMISSION_GRANTED) {
- return WindowManagerImpl.ADD_PERMISSION_DENIED;
+ return WindowManagerGlobal.ADD_PERMISSION_DENIED;
}
}
- return WindowManagerImpl.ADD_OKAY;
+ return WindowManagerGlobal.ADD_OKAY;
}
public void adjustWindowParamsLw(WindowManager.LayoutParams attrs) {
@@ -1499,7 +1507,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// Only return the view if it was successfully added to the
// window manager... which we can tell by it having a parent.
return view.getParent() != null ? view : null;
- } catch (WindowManagerImpl.BadTokenException e) {
+ } catch (WindowManager.BadTokenException e) {
// ignore
Log.w(TAG, appToken + " already running, starting window not displayed");
} catch (RuntimeException e) {
@@ -1538,7 +1546,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
* @param win The window to be added
* @param attrs Information about the window to be added
*
- * @return If ok, WindowManagerImpl.ADD_OKAY. If too many singletons, WindowManagerImpl.ADD_MULTIPLE_SINGLETON
+ * @return If ok, WindowManagerImpl.ADD_OKAY. If too many singletons,
+ * WindowManagerImpl.ADD_MULTIPLE_SINGLETON
*/
public int prepareAddWindowLw(WindowState win, WindowManager.LayoutParams attrs) {
switch (attrs.type) {
@@ -1548,7 +1557,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
"PhoneWindowManager");
if (mStatusBar != null) {
if (mStatusBar.isAlive()) {
- return WindowManagerImpl.ADD_MULTIPLE_SINGLETON;
+ return WindowManagerGlobal.ADD_MULTIPLE_SINGLETON;
}
}
mStatusBar = win;
@@ -1559,7 +1568,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
"PhoneWindowManager");
if (mNavigationBar != null) {
if (mNavigationBar.isAlive()) {
- return WindowManagerImpl.ADD_MULTIPLE_SINGLETON;
+ return WindowManagerGlobal.ADD_MULTIPLE_SINGLETON;
}
}
mNavigationBar = win;
@@ -1582,12 +1591,12 @@ public class PhoneWindowManager implements WindowManagerPolicy {
break;
case TYPE_KEYGUARD:
if (mKeyguard != null) {
- return WindowManagerImpl.ADD_MULTIPLE_SINGLETON;
+ return WindowManagerGlobal.ADD_MULTIPLE_SINGLETON;
}
mKeyguard = win;
break;
}
- return WindowManagerImpl.ADD_OKAY;
+ return WindowManagerGlobal.ADD_OKAY;
}
/** {@inheritDoc} */
diff --git a/services/java/com/android/server/BatteryService.java b/services/java/com/android/server/BatteryService.java
index 0a6f23c..6ae16a4 100644
--- a/services/java/com/android/server/BatteryService.java
+++ b/services/java/com/android/server/BatteryService.java
@@ -93,6 +93,7 @@ public class BatteryService extends Binder {
private boolean mAcOnline;
private boolean mUsbOnline;
+ private boolean mWirelessOnline;
private int mBatteryStatus;
private int mBatteryHealth;
private boolean mBatteryPresent;
@@ -150,7 +151,8 @@ public class BatteryService extends Binder {
public final boolean isPowered() {
// assume we are powered if battery state is unknown so the "stay on while plugged in" option will work.
- return (mAcOnline || mUsbOnline || mBatteryStatus == BatteryManager.BATTERY_STATUS_UNKNOWN);
+ return (mAcOnline || mUsbOnline || mWirelessOnline
+ || mBatteryStatus == BatteryManager.BATTERY_STATUS_UNKNOWN);
}
public final boolean isPowered(int plugTypeSet) {
@@ -169,6 +171,9 @@ public class BatteryService extends Binder {
if (mUsbOnline) {
plugTypeBit |= BatteryManager.BATTERY_PLUGGED_USB;
}
+ if (mWirelessOnline) {
+ plugTypeBit |= BatteryManager.BATTERY_PLUGGED_WIRELESS;
+ }
return (plugTypeSet & plugTypeBit) != 0;
}
@@ -243,6 +248,8 @@ public class BatteryService extends Binder {
mPlugType = BatteryManager.BATTERY_PLUGGED_AC;
} else if (mUsbOnline) {
mPlugType = BatteryManager.BATTERY_PLUGGED_USB;
+ } else if (mWirelessOnline) {
+ mPlugType = BatteryManager.BATTERY_PLUGGED_WIRELESS;
} else {
mPlugType = BATTERY_PLUGGED_NONE;
}
@@ -398,6 +405,7 @@ public class BatteryService extends Binder {
" temperature: " + mBatteryTemperature +
" technology: " + mBatteryTechnology +
" AC powered:" + mAcOnline + " USB powered:" + mUsbOnline +
+ " Wireless powered:" + mWirelessOnline +
" icon:" + icon + " invalid charger:" + mInvalidCharger);
}
@@ -503,6 +511,7 @@ public class BatteryService extends Binder {
pw.println("Current Battery Service state:");
pw.println(" AC powered: " + mAcOnline);
pw.println(" USB powered: " + mUsbOnline);
+ pw.println(" Wireless powered: " + mWirelessOnline);
pw.println(" status: " + mBatteryStatus);
pw.println(" health: " + mBatteryHealth);
pw.println(" present: " + mBatteryPresent);
@@ -523,6 +532,8 @@ public class BatteryService extends Binder {
mAcOnline = Integer.parseInt(value) != 0;
} else if ("usb".equals(key)) {
mUsbOnline = Integer.parseInt(value) != 0;
+ } else if ("wireless".equals(key)) {
+ mWirelessOnline = Integer.parseInt(value) != 0;
} else if ("status".equals(key)) {
mBatteryStatus = Integer.parseInt(value);
} else if ("level".equals(key)) {
@@ -603,4 +614,3 @@ public class BatteryService extends Binder {
}
}
}
-
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index 375ba68..cb6ce4b 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -2592,6 +2592,11 @@ public class ConnectivityService extends IConnectivityManager.Stub {
// @see bug/4455071
handleConnectivityChange(info.getType(), false);
break;
+ case NetworkStateTracker.EVENT_NETWORK_SUBTYPE_CHANGED:
+ info = (NetworkInfo) msg.obj;
+ type = info.getType();
+ updateNetworkSettings(mNetTrackers[type]);
+ break;
}
}
}
diff --git a/services/java/com/android/server/DockObserver.java b/services/java/com/android/server/DockObserver.java
index 8bdd7be..ef09b01 100644
--- a/services/java/com/android/server/DockObserver.java
+++ b/services/java/com/android/server/DockObserver.java
@@ -18,10 +18,6 @@ package com.android.server;
import static android.provider.Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK;
-import com.android.server.power.PowerManagerService;
-
-import android.bluetooth.BluetoothAdapter;
-import android.bluetooth.BluetoothDevice;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
@@ -30,6 +26,7 @@ import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Handler;
+import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -47,7 +44,7 @@ import java.io.FileReader;
/**
* <p>DockObserver monitors for a docking station.
*/
-class DockObserver extends UEventObserver {
+final class DockObserver extends UEventObserver {
private static final String TAG = DockObserver.class.getSimpleName();
private static final boolean LOG = false;
@@ -56,7 +53,9 @@ class DockObserver extends UEventObserver {
private static final int DEFAULT_DOCK = 1;
- private static final int MSG_DOCK_STATE = 0;
+ private static final int MSG_DOCK_STATE_CHANGED = 0;
+
+ private final Object mLock = new Object();
private int mDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED;
private int mPreviousDockState = Intent.EXTRA_DOCK_STATE_UNDOCKED;
@@ -78,7 +77,7 @@ class DockObserver extends UEventObserver {
Slog.v(TAG, "Dock UEVENT: " + event.toString());
}
- synchronized (this) {
+ synchronized (mLock) {
try {
int newState = Integer.parseInt(event.get("SWITCH_STATE"));
if (newState != mDockState) {
@@ -96,7 +95,7 @@ class DockObserver extends UEventObserver {
(PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
pm.wakeUp(SystemClock.uptimeMillis());
}
- update();
+ updateLocked();
}
}
} catch (NumberFormatException e) {
@@ -105,132 +104,142 @@ class DockObserver extends UEventObserver {
}
}
- private final void init() {
- char[] buffer = new char[1024];
-
- try {
- FileReader file = new FileReader(DOCK_STATE_PATH);
- int len = file.read(buffer, 0, 1024);
- file.close();
- mPreviousDockState = mDockState = Integer.valueOf((new String(buffer, 0, len)).trim());
- } catch (FileNotFoundException e) {
- Slog.w(TAG, "This kernel does not have dock station support");
- } catch (Exception e) {
- Slog.e(TAG, "" , e);
+ private void init() {
+ synchronized (mLock) {
+ try {
+ char[] buffer = new char[1024];
+ FileReader file = new FileReader(DOCK_STATE_PATH);
+ try {
+ int len = file.read(buffer, 0, 1024);
+ mDockState = Integer.valueOf((new String(buffer, 0, len)).trim());
+ mPreviousDockState = mDockState;
+ } finally {
+ file.close();
+ }
+ } catch (FileNotFoundException e) {
+ Slog.w(TAG, "This kernel does not have dock station support");
+ } catch (Exception e) {
+ Slog.e(TAG, "" , e);
+ }
}
}
void systemReady() {
- synchronized (this) {
+ synchronized (mLock) {
// don't bother broadcasting undocked here
if (mDockState != Intent.EXTRA_DOCK_STATE_UNDOCKED) {
- update();
+ updateLocked();
}
mSystemReady = true;
}
}
- private final void update() {
- mHandler.sendEmptyMessage(MSG_DOCK_STATE);
+ private void updateLocked() {
+ mHandler.sendEmptyMessage(MSG_DOCK_STATE_CHANGED);
}
- private static boolean isScreenSaverActivatedOnDock(Context context) {
- return 0 != Settings.Secure.getInt(
- context.getContentResolver(), SCREENSAVER_ACTIVATE_ON_DOCK, DEFAULT_DOCK);
- }
+ private void handleDockStateChange() {
+ synchronized (mLock) {
+ Slog.i(TAG, "Dock state changed: " + mDockState);
- private final Handler mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case MSG_DOCK_STATE:
- synchronized (this) {
- Slog.i(TAG, "Dock state changed: " + mDockState);
+ final ContentResolver cr = mContext.getContentResolver();
- final ContentResolver cr = mContext.getContentResolver();
+ if (Settings.Secure.getInt(cr,
+ Settings.Secure.DEVICE_PROVISIONED, 0) == 0) {
+ Slog.i(TAG, "Device not provisioned, skipping dock broadcast");
+ return;
+ }
- if (Settings.Secure.getInt(cr,
- Settings.Secure.DEVICE_PROVISIONED, 0) == 0) {
- Slog.i(TAG, "Device not provisioned, skipping dock broadcast");
- return;
- }
- // Pack up the values and broadcast them to everyone
- Intent intent = new Intent(Intent.ACTION_DOCK_EVENT);
- intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
- intent.putExtra(Intent.EXTRA_DOCK_STATE, mDockState);
-
- // Check if this is Bluetooth Dock
- // TODO(BT): Get Dock address.
- String address = null;
- if (address != null)
- intent.putExtra(BluetoothDevice.EXTRA_DEVICE,
- BluetoothAdapter.getDefaultAdapter().getRemoteDevice(address));
-
- // User feedback to confirm dock connection. Particularly
- // useful for flaky contact pins...
- if (Settings.System.getInt(cr,
- Settings.System.DOCK_SOUNDS_ENABLED, 1) == 1)
- {
- String whichSound = null;
- if (mDockState == Intent.EXTRA_DOCK_STATE_UNDOCKED) {
- if ((mPreviousDockState == Intent.EXTRA_DOCK_STATE_DESK) ||
- (mPreviousDockState == Intent.EXTRA_DOCK_STATE_LE_DESK) ||
- (mPreviousDockState == Intent.EXTRA_DOCK_STATE_HE_DESK)) {
- whichSound = Settings.System.DESK_UNDOCK_SOUND;
- } else if (mPreviousDockState == Intent.EXTRA_DOCK_STATE_CAR) {
- whichSound = Settings.System.CAR_UNDOCK_SOUND;
- }
- } else {
- if ((mDockState == Intent.EXTRA_DOCK_STATE_DESK) ||
- (mDockState == Intent.EXTRA_DOCK_STATE_LE_DESK) ||
- (mDockState == Intent.EXTRA_DOCK_STATE_HE_DESK)) {
- whichSound = Settings.System.DESK_DOCK_SOUND;
- } else if (mDockState == Intent.EXTRA_DOCK_STATE_CAR) {
- whichSound = Settings.System.CAR_DOCK_SOUND;
- }
- }
+ // Pack up the values and broadcast them to everyone
+ Intent intent = new Intent(Intent.ACTION_DOCK_EVENT);
+ intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
+ intent.putExtra(Intent.EXTRA_DOCK_STATE, mDockState);
+
+ // Check if this is Bluetooth Dock
+ // TODO(BT): Get Dock address.
+ // String address = null;
+ // if (address != null) {
+ // intent.putExtra(BluetoothDevice.EXTRA_DEVICE,
+ // BluetoothAdapter.getDefaultAdapter().getRemoteDevice(address));
+ // }
+
+ // User feedback to confirm dock connection. Particularly
+ // useful for flaky contact pins...
+ if (Settings.System.getInt(cr,
+ Settings.System.DOCK_SOUNDS_ENABLED, 1) == 1) {
+ String whichSound = null;
+ if (mDockState == Intent.EXTRA_DOCK_STATE_UNDOCKED) {
+ if ((mPreviousDockState == Intent.EXTRA_DOCK_STATE_DESK) ||
+ (mPreviousDockState == Intent.EXTRA_DOCK_STATE_LE_DESK) ||
+ (mPreviousDockState == Intent.EXTRA_DOCK_STATE_HE_DESK)) {
+ whichSound = Settings.System.DESK_UNDOCK_SOUND;
+ } else if (mPreviousDockState == Intent.EXTRA_DOCK_STATE_CAR) {
+ whichSound = Settings.System.CAR_UNDOCK_SOUND;
+ }
+ } else {
+ if ((mDockState == Intent.EXTRA_DOCK_STATE_DESK) ||
+ (mDockState == Intent.EXTRA_DOCK_STATE_LE_DESK) ||
+ (mDockState == Intent.EXTRA_DOCK_STATE_HE_DESK)) {
+ whichSound = Settings.System.DESK_DOCK_SOUND;
+ } else if (mDockState == Intent.EXTRA_DOCK_STATE_CAR) {
+ whichSound = Settings.System.CAR_DOCK_SOUND;
+ }
+ }
- if (whichSound != null) {
- final String soundPath = Settings.System.getString(cr, whichSound);
- if (soundPath != null) {
- final Uri soundUri = Uri.parse("file://" + soundPath);
- if (soundUri != null) {
- final Ringtone sfx = RingtoneManager.getRingtone(mContext, soundUri);
- if (sfx != null) {
- sfx.setStreamType(AudioManager.STREAM_SYSTEM);
- sfx.play();
- }
- }
- }
+ if (whichSound != null) {
+ final String soundPath = Settings.System.getString(cr, whichSound);
+ if (soundPath != null) {
+ final Uri soundUri = Uri.parse("file://" + soundPath);
+ if (soundUri != null) {
+ final Ringtone sfx = RingtoneManager.getRingtone(mContext, soundUri);
+ if (sfx != null) {
+ sfx.setStreamType(AudioManager.STREAM_SYSTEM);
+ sfx.play();
}
}
+ }
+ }
+ }
- IDreamManager mgr = IDreamManager.Stub.asInterface(ServiceManager.getService("dreams"));
- if (mgr != null) {
- // dreams feature enabled
- boolean undocked = mDockState == Intent.EXTRA_DOCK_STATE_UNDOCKED;
- if (undocked) {
- try {
- if (mgr.isDreaming()) {
- mgr.awaken();
- }
- } catch (RemoteException e) {
- Slog.w(TAG, "Unable to awaken!", e);
- }
- } else {
- if (isScreenSaverActivatedOnDock(mContext)) {
- try {
- mgr.dream();
- } catch (RemoteException e) {
- Slog.w(TAG, "Unable to dream!", e);
- }
- }
- }
- } else {
- // dreams feature not enabled, send legacy intent
- mContext.sendStickyBroadcast(intent);
+ IDreamManager mgr = IDreamManager.Stub.asInterface(ServiceManager.getService("dreams"));
+ if (mgr != null) {
+ // dreams feature enabled
+ boolean undocked = mDockState == Intent.EXTRA_DOCK_STATE_UNDOCKED;
+ if (undocked) {
+ try {
+ if (mgr.isDreaming()) {
+ mgr.awaken();
}
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Unable to awaken!", e);
}
+ } else {
+ if (isScreenSaverActivatedOnDock(mContext)) {
+ try {
+ mgr.dream();
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Unable to dream!", e);
+ }
+ }
+ }
+ } else {
+ // dreams feature not enabled, send legacy intent
+ mContext.sendStickyBroadcast(intent);
+ }
+ }
+ }
+
+ private static boolean isScreenSaverActivatedOnDock(Context context) {
+ return Settings.Secure.getInt(context.getContentResolver(),
+ SCREENSAVER_ACTIVATE_ON_DOCK, DEFAULT_DOCK) != 0;
+ }
+
+ private final Handler mHandler = new Handler(Looper.myLooper(), null, true) {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_DOCK_STATE_CHANGED:
+ handleDockStateChange();
break;
}
}
diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java
index bb005d9..8a564f7 100644
--- a/services/java/com/android/server/LocationManagerService.java
+++ b/services/java/com/android/server/LocationManagerService.java
@@ -63,6 +63,7 @@ import com.android.internal.location.ProviderRequest;
import com.android.server.location.GeocoderProxy;
import com.android.server.location.GeofenceManager;
import com.android.server.location.GpsLocationProvider;
+import com.android.server.location.LocationBlacklist;
import com.android.server.location.LocationFudger;
import com.android.server.location.LocationProviderInterface;
import com.android.server.location.LocationProviderProxy;
@@ -132,8 +133,8 @@ public class LocationManagerService extends ILocationManager.Stub implements Obs
private IGpsStatusProvider mGpsStatusProvider;
private INetInitiatedListener mNetInitiatedListener;
private LocationWorkerHandler mLocationHandler;
- // track the passive provider for some special cases
- private PassiveProvider mPassiveProvider;
+ private PassiveProvider mPassiveProvider; // track passive provider for special cases
+ private LocationBlacklist mBlacklist;
// --- fields below are protected by mWakeLock ---
private int mPendingBroadcasts;
@@ -208,7 +209,9 @@ public class LocationManagerService extends ILocationManager.Stub implements Obs
synchronized (mLock) {
loadProvidersLocked();
}
- mGeofenceManager = new GeofenceManager(mContext);
+ mBlacklist = new LocationBlacklist(mContext, mLocationHandler);
+ mBlacklist.init();
+ mGeofenceManager = new GeofenceManager(mContext, mBlacklist);
mLocationFudger = new LocationFudger();
// Register for Network (Wifi or Mobile) updates
@@ -965,7 +968,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Obs
final int uid = Binder.getCallingUid();
Receiver recevier = checkListenerOrIntent(listener, intent, pid, uid, packageName);
- // so wakelock calls will succeed (not totally sure this is still needed)
+ // providers may use public location API's, need to clear identity
long identity = Binder.clearCallingIdentity();
try {
synchronized (mLock) {
@@ -1015,7 +1018,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Obs
final int uid = Binder.getCallingUid();
Receiver receiver = checkListenerOrIntent(listener, intent, pid, uid, packageName);
- // so wakelock calls will succeed (not totally sure this is still needed)
+ // providers may use public location API's, need to clear identity
long identity = Binder.clearCallingIdentity();
try {
synchronized (mLock) {
@@ -1063,10 +1066,17 @@ public class LocationManagerService extends ILocationManager.Stub implements Obs
}
@Override
- public Location getLastLocation(LocationRequest request) {
+ public Location getLastLocation(LocationRequest request, String packageName) {
if (D) Log.d(TAG, "getLastLocation: " + request);
if (request == null) request = DEFAULT_LOCATION_REQUEST;
String perm = checkPermissionAndRequest(request);
+ checkPackageName(packageName);
+
+ if (mBlacklist.isBlacklisted(packageName)) {
+ if (D) Log.d(TAG, "not returning last loc for blacklisted app: " +
+ packageName);
+ return null;
+ }
synchronized (mLock) {
// Figure out the provider. Either its explicitly request (deprecated API's),
@@ -1097,7 +1107,14 @@ public class LocationManagerService extends ILocationManager.Stub implements Obs
if (D) Log.d(TAG, "requestGeofence: " + request + " " + geofence + " " + intent);
- mGeofenceManager.addFence(request, geofence, intent, Binder.getCallingUid(), packageName);
+ // geo-fence manager uses the public location API, need to clear identity
+ int uid = Binder.getCallingUid();
+ long identity = Binder.clearCallingIdentity();
+ try {
+ mGeofenceManager.addFence(request, geofence, intent, uid, packageName);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
@Override
@@ -1108,7 +1125,13 @@ public class LocationManagerService extends ILocationManager.Stub implements Obs
if (D) Log.d(TAG, "removeGeofence: " + geofence + " " + intent);
- mGeofenceManager.removeFence(geofence, intent);
+ // geo-fence manager uses the public location API, need to clear identity
+ long identity = Binder.clearCallingIdentity();
+ try {
+ mGeofenceManager.removeFence(geofence, intent);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
@@ -1325,6 +1348,13 @@ public class LocationManagerService extends ILocationManager.Stub implements Obs
for (UpdateRecord r : records) {
Receiver receiver = r.mReceiver;
boolean receiverDead = false;
+
+ if (mBlacklist.isBlacklisted(receiver.mPackageName)) {
+ if (D) Log.d(TAG, "skipping loc update for blacklisted app: " +
+ receiver.mPackageName);
+ continue;
+ }
+
if (ACCESS_FINE_LOCATION.equals(receiver.mPermission)) {
location = lastLocation; // use fine location
} else {
@@ -1716,8 +1746,9 @@ public class LocationManagerService extends ILocationManager.Stub implements Obs
for (String i : mDisabledProviders) {
pw.println(" " + i);
}
-
}
+ pw.append(" ");
+ mBlacklist.dump(pw);
if (mMockProviders.size() > 0) {
pw.println(" Mock Providers:");
for (Map.Entry<String, MockProvider> i : mMockProviders.entrySet()) {
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index c471dd2..a117b06 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -155,13 +155,12 @@ class ServerThread extends Thread {
power = new PowerManagerService();
ServiceManager.addService(Context.POWER_SERVICE, power);
- Slog.i(TAG, "Display Manager");
- display = new DisplayManagerService();
- ServiceManager.addService(Context.DISPLAY_SERVICE, display, true);
-
Slog.i(TAG, "Activity Manager");
context = ActivityManagerService.main(factoryTest);
- display.setContext(context);
+
+ Slog.i(TAG, "Display Manager");
+ display = new DisplayManagerService(context);
+ ServiceManager.addService(Context.DISPLAY_SERVICE, display, true);
Slog.i(TAG, "Telephony Registry");
ServiceManager.addService("telephony.registry", new TelephonyRegistry(context));
diff --git a/services/java/com/android/server/WallpaperManagerService.java b/services/java/com/android/server/WallpaperManagerService.java
index 1d248b2..afd7d0e 100644
--- a/services/java/com/android/server/WallpaperManagerService.java
+++ b/services/java/com/android/server/WallpaperManagerService.java
@@ -768,10 +768,6 @@ class WallpaperManagerService extends IWallpaperManager.Stub {
WallpaperConnection newConn = new WallpaperConnection(wi, wallpaper);
intent.setComponent(componentName);
int serviceUserId = wallpaper.userId;
- // Because the image wallpaper is running in the system ui
- if (componentName.equals(wallpaper.imageWallpaperComponent)) {
- serviceUserId = 0;
- }
intent.putExtra(Intent.EXTRA_CLIENT_LABEL,
com.android.internal.R.string.wallpaper_binding_label);
intent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivity(
diff --git a/services/java/com/android/server/WiredAccessoryObserver.java b/services/java/com/android/server/WiredAccessoryObserver.java
index 96ac493..56c0fdf 100644
--- a/services/java/com/android/server/WiredAccessoryObserver.java
+++ b/services/java/com/android/server/WiredAccessoryObserver.java
@@ -16,12 +16,12 @@
package com.android.server;
-import android.app.ActivityManagerNative;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Handler;
+import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
@@ -39,7 +39,7 @@ import java.util.List;
/**
* <p>WiredAccessoryObserver monitors for a wired headset on the main board or dock.
*/
-class WiredAccessoryObserver extends UEventObserver {
+final class WiredAccessoryObserver extends UEventObserver {
private static final String TAG = WiredAccessoryObserver.class.getSimpleName();
private static final boolean LOG = true;
private static final int BIT_HEADSET = (1 << 0);
@@ -50,122 +50,32 @@ class WiredAccessoryObserver extends UEventObserver {
private static final int SUPPORTED_HEADSETS = (BIT_HEADSET|BIT_HEADSET_NO_MIC|
BIT_USB_HEADSET_ANLG|BIT_USB_HEADSET_DGTL|
BIT_HDMI_AUDIO);
- private static final int HEADSETS_WITH_MIC = BIT_HEADSET;
- private static class UEventInfo {
- private final String mDevName;
- private final int mState1Bits;
- private final int mState2Bits;
-
- public UEventInfo(String devName, int state1Bits, int state2Bits) {
- mDevName = devName;
- mState1Bits = state1Bits;
- mState2Bits = state2Bits;
- }
-
- public String getDevName() { return mDevName; }
-
- public String getDevPath() {
- return String.format("/devices/virtual/switch/%s", mDevName);
- }
-
- public String getSwitchStatePath() {
- return String.format("/sys/class/switch/%s/state", mDevName);
- }
-
- public boolean checkSwitchExists() {
- File f = new File(getSwitchStatePath());
- return ((null != f) && f.exists());
- }
-
- public int computeNewHeadsetState(int headsetState, int switchState) {
- int preserveMask = ~(mState1Bits | mState2Bits);
- int setBits = ((switchState == 1) ? mState1Bits :
- ((switchState == 2) ? mState2Bits : 0));
-
- return ((headsetState & preserveMask) | setBits);
- }
- }
-
- private static List<UEventInfo> makeObservedUEventList() {
- List<UEventInfo> retVal = new ArrayList<UEventInfo>();
- UEventInfo uei;
-
- // Monitor h2w
- uei = new UEventInfo("h2w", BIT_HEADSET, BIT_HEADSET_NO_MIC);
- if (uei.checkSwitchExists()) {
- retVal.add(uei);
- } else {
- Slog.w(TAG, "This kernel does not have wired headset support");
- }
-
- // Monitor USB
- uei = new UEventInfo("usb_audio", BIT_USB_HEADSET_ANLG, BIT_USB_HEADSET_DGTL);
- if (uei.checkSwitchExists()) {
- retVal.add(uei);
- } else {
- Slog.w(TAG, "This kernel does not have usb audio support");
- }
+ private final Object mLock = new Object();
- // Monitor HDMI
- //
- // If the kernel has support for the "hdmi_audio" switch, use that. It will be signalled
- // only when the HDMI driver has a video mode configured, and the downstream sink indicates
- // support for audio in its EDID.
- //
- // If the kernel does not have an "hdmi_audio" switch, just fall back on the older "hdmi"
- // switch instead.
- uei = new UEventInfo("hdmi_audio", BIT_HDMI_AUDIO, 0);
- if (uei.checkSwitchExists()) {
- retVal.add(uei);
- } else {
- uei = new UEventInfo("hdmi", BIT_HDMI_AUDIO, 0);
- if (uei.checkSwitchExists()) {
- retVal.add(uei);
- } else {
- Slog.w(TAG, "This kernel does not have HDMI audio support");
- }
- }
-
- return retVal;
- }
-
- private static List<UEventInfo> uEventInfo = makeObservedUEventList();
+ private final Context mContext;
+ private final WakeLock mWakeLock; // held while there is a pending route change
+ private final AudioManager mAudioManager;
+ private final List<UEventInfo> mUEventInfo;
private int mHeadsetState;
private int mPrevHeadsetState;
private String mHeadsetName;
- private final Context mContext;
- private final WakeLock mWakeLock; // held while there is a pending route change
-
- private final AudioManager mAudioManager;
-
public WiredAccessoryObserver(Context context) {
mContext = context;
+
PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "WiredAccessoryObserver");
mWakeLock.setReferenceCounted(false);
mAudioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
+ mUEventInfo = makeObservedUEventList();
+
context.registerReceiver(new BootCompletedReceiver(),
new IntentFilter(Intent.ACTION_BOOT_COMPLETED), null, null);
}
- private final class BootCompletedReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- // At any given time accessories could be inserted
- // one on the board, one on the dock and one on HDMI:
- // observe three UEVENTs
- init(); // set initial status
- for (int i = 0; i < uEventInfo.size(); ++i) {
- UEventInfo uei = uEventInfo.get(i);
- startObserving("DEVPATH="+uei.getDevPath());
- }
- }
- }
-
@Override
public void onUEvent(UEventObserver.UEvent event) {
if (LOG) Slog.v(TAG, "Headset UEVENT: " + event.toString());
@@ -174,56 +84,64 @@ class WiredAccessoryObserver extends UEventObserver {
String devPath = event.get("DEVPATH");
String name = event.get("SWITCH_NAME");
int state = Integer.parseInt(event.get("SWITCH_STATE"));
- updateState(devPath, name, state);
+ synchronized (mLock) {
+ updateStateLocked(devPath, name, state);
+ }
} catch (NumberFormatException e) {
Slog.e(TAG, "Could not parse switch state from event " + event);
}
}
- private synchronized final void updateState(String devPath, String name, int state)
- {
- for (int i = 0; i < uEventInfo.size(); ++i) {
- UEventInfo uei = uEventInfo.get(i);
- if (devPath.equals(uei.getDevPath())) {
- update(name, uei.computeNewHeadsetState(mHeadsetState, state));
- return;
+ private void bootCompleted() {
+ synchronized (mLock) {
+ char[] buffer = new char[1024];
+ mPrevHeadsetState = mHeadsetState;
+
+ if (LOG) Slog.v(TAG, "init()");
+
+ for (int i = 0; i < mUEventInfo.size(); ++i) {
+ UEventInfo uei = mUEventInfo.get(i);
+ try {
+ int curState;
+ FileReader file = new FileReader(uei.getSwitchStatePath());
+ int len = file.read(buffer, 0, 1024);
+ file.close();
+ curState = Integer.valueOf((new String(buffer, 0, len)).trim());
+
+ if (curState > 0) {
+ updateStateLocked(uei.getDevPath(), uei.getDevName(), curState);
+ }
+ } catch (FileNotFoundException e) {
+ Slog.w(TAG, uei.getSwitchStatePath() +
+ " not found while attempting to determine initial switch state");
+ } catch (Exception e) {
+ Slog.e(TAG, "" , e);
+ }
}
}
- }
-
- private synchronized final void init() {
- char[] buffer = new char[1024];
- mPrevHeadsetState = mHeadsetState;
-
- if (LOG) Slog.v(TAG, "init()");
- for (int i = 0; i < uEventInfo.size(); ++i) {
- UEventInfo uei = uEventInfo.get(i);
- try {
- int curState;
- FileReader file = new FileReader(uei.getSwitchStatePath());
- int len = file.read(buffer, 0, 1024);
- file.close();
- curState = Integer.valueOf((new String(buffer, 0, len)).trim());
-
- if (curState > 0) {
- updateState(uei.getDevPath(), uei.getDevName(), curState);
- }
+ // At any given time accessories could be inserted
+ // one on the board, one on the dock and one on HDMI:
+ // observe three UEVENTs
+ for (int i = 0; i < mUEventInfo.size(); ++i) {
+ UEventInfo uei = mUEventInfo.get(i);
+ startObserving("DEVPATH="+uei.getDevPath());
+ }
+ }
- } catch (FileNotFoundException e) {
- Slog.w(TAG, uei.getSwitchStatePath() +
- " not found while attempting to determine initial switch state");
- } catch (Exception e) {
- Slog.e(TAG, "" , e);
+ private void updateStateLocked(String devPath, String name, int state) {
+ for (int i = 0; i < mUEventInfo.size(); ++i) {
+ UEventInfo uei = mUEventInfo.get(i);
+ if (devPath.equals(uei.getDevPath())) {
+ updateLocked(name, uei.computeNewHeadsetState(mHeadsetState, state));
+ return;
}
}
}
- private synchronized final void update(String newName, int newState) {
+ private void updateLocked(String newName, int newState) {
// Retain only relevant bits
int headsetState = newState & SUPPORTED_HEADSETS;
- int newOrOld = headsetState | mHeadsetState;
- int delay = 0;
int usb_headset_anlg = headsetState & BIT_USB_HEADSET_ANLG;
int usb_headset_dgtl = headsetState & BIT_USB_HEADSET_DGTL;
int h2w_headset = headsetState & (BIT_HEADSET | BIT_HEADSET_NO_MIC);
@@ -254,28 +172,26 @@ class WiredAccessoryObserver extends UEventObserver {
mHeadsetState = headsetState;
mWakeLock.acquire();
- mHandler.sendMessage(mHandler.obtainMessage(0,
- mHeadsetState,
- mPrevHeadsetState,
- mHeadsetName));
+
+ Message msg = mHandler.obtainMessage(0, mHeadsetState, mPrevHeadsetState, mHeadsetName);
+ mHandler.sendMessage(msg);
}
- private synchronized final void setDevicesState(int headsetState,
- int prevHeadsetState,
- String headsetName) {
- int allHeadsets = SUPPORTED_HEADSETS;
- for (int curHeadset = 1; allHeadsets != 0; curHeadset <<= 1) {
- if ((curHeadset & allHeadsets) != 0) {
- setDeviceState(curHeadset, headsetState, prevHeadsetState, headsetName);
- allHeadsets &= ~curHeadset;
+ private void setDevicesState(
+ int headsetState, int prevHeadsetState, String headsetName) {
+ synchronized (mLock) {
+ int allHeadsets = SUPPORTED_HEADSETS;
+ for (int curHeadset = 1; allHeadsets != 0; curHeadset <<= 1) {
+ if ((curHeadset & allHeadsets) != 0) {
+ setDeviceStateLocked(curHeadset, headsetState, prevHeadsetState, headsetName);
+ allHeadsets &= ~curHeadset;
+ }
}
}
}
- private final void setDeviceState(int headset,
- int headsetState,
- int prevHeadsetState,
- String headsetName) {
+ private void setDeviceStateLocked(int headset,
+ int headsetState, int prevHeadsetState, String headsetName) {
if ((headsetState & headset) != (prevHeadsetState & headset)) {
int device;
int state;
@@ -308,11 +224,96 @@ class WiredAccessoryObserver extends UEventObserver {
}
}
- private final Handler mHandler = new Handler() {
+ private static List<UEventInfo> makeObservedUEventList() {
+ List<UEventInfo> retVal = new ArrayList<UEventInfo>();
+ UEventInfo uei;
+
+ // Monitor h2w
+ uei = new UEventInfo("h2w", BIT_HEADSET, BIT_HEADSET_NO_MIC);
+ if (uei.checkSwitchExists()) {
+ retVal.add(uei);
+ } else {
+ Slog.w(TAG, "This kernel does not have wired headset support");
+ }
+
+ // Monitor USB
+ uei = new UEventInfo("usb_audio", BIT_USB_HEADSET_ANLG, BIT_USB_HEADSET_DGTL);
+ if (uei.checkSwitchExists()) {
+ retVal.add(uei);
+ } else {
+ Slog.w(TAG, "This kernel does not have usb audio support");
+ }
+
+ // Monitor HDMI
+ //
+ // If the kernel has support for the "hdmi_audio" switch, use that. It will be signalled
+ // only when the HDMI driver has a video mode configured, and the downstream sink indicates
+ // support for audio in its EDID.
+ //
+ // If the kernel does not have an "hdmi_audio" switch, just fall back on the older "hdmi"
+ // switch instead.
+ uei = new UEventInfo("hdmi_audio", BIT_HDMI_AUDIO, 0);
+ if (uei.checkSwitchExists()) {
+ retVal.add(uei);
+ } else {
+ uei = new UEventInfo("hdmi", BIT_HDMI_AUDIO, 0);
+ if (uei.checkSwitchExists()) {
+ retVal.add(uei);
+ } else {
+ Slog.w(TAG, "This kernel does not have HDMI audio support");
+ }
+ }
+
+ return retVal;
+ }
+
+ private final Handler mHandler = new Handler(Looper.myLooper(), null, true) {
@Override
public void handleMessage(Message msg) {
setDevicesState(msg.arg1, msg.arg2, (String)msg.obj);
mWakeLock.release();
}
};
+
+ private static final class UEventInfo {
+ private final String mDevName;
+ private final int mState1Bits;
+ private final int mState2Bits;
+
+ public UEventInfo(String devName, int state1Bits, int state2Bits) {
+ mDevName = devName;
+ mState1Bits = state1Bits;
+ mState2Bits = state2Bits;
+ }
+
+ public String getDevName() { return mDevName; }
+
+ public String getDevPath() {
+ return String.format("/devices/virtual/switch/%s", mDevName);
+ }
+
+ public String getSwitchStatePath() {
+ return String.format("/sys/class/switch/%s/state", mDevName);
+ }
+
+ public boolean checkSwitchExists() {
+ File f = new File(getSwitchStatePath());
+ return ((null != f) && f.exists());
+ }
+
+ public int computeNewHeadsetState(int headsetState, int switchState) {
+ int preserveMask = ~(mState1Bits | mState2Bits);
+ int setBits = ((switchState == 1) ? mState1Bits :
+ ((switchState == 2) ? mState2Bits : 0));
+
+ return ((headsetState & preserveMask) | setBits);
+ }
+ }
+
+ private final class BootCompletedReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ bootCompleted();
+ }
+ }
}
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 5e85e1a..944fd6b 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -2539,7 +2539,6 @@ public final class ActivityManagerService extends ActivityManagerNative
// This is so super not safe, that only the system (or okay root)
// can do it.
- int userId = Binder.getOrigCallingUser();
final int callingUid = Binder.getCallingUid();
if (callingUid != 0 && callingUid != Process.myUid()) {
throw new SecurityException(
@@ -2548,7 +2547,7 @@ public final class ActivityManagerService extends ActivityManagerNative
int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
resultTo, resultWho, requestCode, startFlags,
- null, null, null, null, options, userId);
+ null, null, null, null, options, UserHandle.getUserId(uid));
return ret;
}
diff --git a/services/java/com/android/server/am/ProviderMap.java b/services/java/com/android/server/am/ProviderMap.java
index ab2e428..15fbb98 100644
--- a/services/java/com/android/server/am/ProviderMap.java
+++ b/services/java/com/android/server/am/ProviderMap.java
@@ -127,7 +127,12 @@ public class ProviderMap {
Slog.i(TAG,
"Removing from providersByName name=" + name + " user="
+ (optionalUserId == -1 ? Binder.getOrigCallingUser() : optionalUserId));
- getProvidersByName(optionalUserId).remove(name);
+ HashMap<String, ContentProviderRecord> map = getProvidersByName(optionalUserId);
+ // map returned by getProvidersByName wouldn't be null
+ map.remove(name);
+ if (map.size() == 0) {
+ mProvidersByNamePerUser.remove(optionalUserId);
+ }
}
}
@@ -141,7 +146,12 @@ public class ProviderMap {
Slog.i(TAG,
"Removing from providersByClass name=" + name + " user="
+ (optionalUserId == -1 ? Binder.getOrigCallingUser() : optionalUserId));
- getProvidersByClass(optionalUserId).remove(name);
+ HashMap<ComponentName, ContentProviderRecord> map = getProvidersByClass(optionalUserId);
+ // map returned by getProvidersByClass wouldn't be null
+ map.remove(name);
+ if (map.size() == 0) {
+ mProvidersByClassPerUser.remove(optionalUserId);
+ }
}
}
diff --git a/services/java/com/android/server/display/DisplayAdapter.java b/services/java/com/android/server/display/DisplayAdapter.java
index b623906..f9fa7a8 100644
--- a/services/java/com/android/server/display/DisplayAdapter.java
+++ b/services/java/com/android/server/display/DisplayAdapter.java
@@ -16,38 +16,33 @@
package com.android.server.display;
-import android.view.Display;
-
/**
- * A display adapter makes a single display devices available to the system.
+ * A display adapter makes zero or more display devices available to the system
+ * and provides facilities for discovering when displays are connected or disconnected.
* <p>
* For now, all display adapters are registered in the system server but
* in principle it could be done from other processes.
* </p>
*/
public abstract class DisplayAdapter {
- /** The current logical Display assignment for this adapter. Will change if other logical
- * display is assigned to this adapter */
- private int mDisplayId = Display.NO_DISPLAY;
-
- /** Assign the displayId
- * @hide */
- public void setDisplayId(int displayId) {
- mDisplayId = displayId;
- }
-
- /** Retrieve the displayId
- * @hide */
- public int getDisplayId() {
- return mDisplayId;
- }
-
/**
- * Gets the display adapter name.
+ * Gets the display adapter name for debugging purposes.
+ *
* @return The display adapter name.
*/
public abstract String getName();
- // TODO: dynamically register display devices
- public abstract DisplayDevice getDisplayDevice();
+ /**
+ * Registers the display adapter with the display manager.
+ * The display adapter should register any built-in display devices now.
+ * Other display devices can be registered dynamically later.
+ *
+ * @param listener The listener for callbacks.
+ */
+ public abstract void register(Listener listener);
+
+ public interface Listener {
+ public void onDisplayDeviceAdded(DisplayDevice device);
+ public void onDisplayDeviceRemoved(DisplayDevice device);
+ }
}
diff --git a/services/java/com/android/server/display/DisplayDevice.java b/services/java/com/android/server/display/DisplayDevice.java
index 6d723f2..57002ff 100644
--- a/services/java/com/android/server/display/DisplayDevice.java
+++ b/services/java/com/android/server/display/DisplayDevice.java
@@ -18,8 +18,20 @@ package com.android.server.display;
/**
* Represents a physical display device such as the built-in display
- * or an external monitor.
+ * an external monitor, or a WiFi display.
*/
public abstract class DisplayDevice {
+ /**
+ * Gets the display adapter that makes the display device available.
+ *
+ * @return The display adapter.
+ */
+ public abstract DisplayAdapter getAdapter();
+
+ /**
+ * Gets information about the display device.
+ *
+ * @param outInfo The object to populate with the information.
+ */
public abstract void getInfo(DisplayDeviceInfo outInfo);
}
diff --git a/services/java/com/android/server/display/DisplayDeviceInfo.java b/services/java/com/android/server/display/DisplayDeviceInfo.java
index c60c2e9..9c0f964 100644
--- a/services/java/com/android/server/display/DisplayDeviceInfo.java
+++ b/services/java/com/android/server/display/DisplayDeviceInfo.java
@@ -21,6 +21,12 @@ package com.android.server.display;
*/
public final class DisplayDeviceInfo {
/**
+ * Gets the name of the display device, which may be derived from
+ * EDID or other sources. The name may be displayed to the user.
+ */
+ public String name;
+
+ /**
* The width of the display in its natural orientation, in pixels.
* This value is not affected by display rotation.
*/
@@ -38,6 +44,7 @@ public final class DisplayDeviceInfo {
public float yDpi;
public void copyFrom(DisplayDeviceInfo other) {
+ name = other.name;
width = other.width;
height = other.height;
refreshRate = other.refreshRate;
@@ -46,9 +53,10 @@ public final class DisplayDeviceInfo {
yDpi = other.yDpi;
}
+ // For debugging purposes
@Override
public String toString() {
- return width + " x " + height + ", " + refreshRate + " fps, "
+ return "\"" + name + "\": " + width + " x " + height + ", " + refreshRate + " fps, "
+ "density " + densityDpi + ", " + xDpi + " x " + yDpi + " dpi";
}
}
diff --git a/services/java/com/android/server/display/DisplayManagerService.java b/services/java/com/android/server/display/DisplayManagerService.java
index 468bf21..2ebad1d 100644
--- a/services/java/com/android/server/display/DisplayManagerService.java
+++ b/services/java/com/android/server/display/DisplayManagerService.java
@@ -19,11 +19,10 @@ package com.android.server.display;
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
+import android.hardware.display.DisplayManager;
import android.hardware.display.IDisplayManager;
import android.os.Binder;
import android.os.SystemProperties;
-import android.util.Slog;
-import android.util.SparseArray;
import android.view.Display;
import android.view.DisplayInfo;
import android.view.Surface;
@@ -47,41 +46,27 @@ public final class DisplayManagerService extends IDisplayManager.Stub {
private final Object mLock = new Object();
- private Context mContext;
+ private final Context mContext;
private final boolean mHeadless;
- private int mDisplayIdSeq = Display.DEFAULT_DISPLAY;
-
- /** All registered DisplayAdapters. */
private final ArrayList<DisplayAdapter> mDisplayAdapters = new ArrayList<DisplayAdapter>();
+ private final DisplayInfo mDefaultDisplayInfo = new DisplayInfo();
- /** All the DisplayAdapters showing the given displayId. */
- private final SparseArray<ArrayList<DisplayAdapter>> mLogicalToPhysicals =
- new SparseArray<ArrayList<DisplayAdapter>>();
-
- /** All the DisplayInfos in the system indexed by deviceId */
- private final SparseArray<DisplayInfo> mDisplayInfos = new SparseArray<DisplayInfo>();
-
- private final ArrayList<DisplayCallback> mCallbacks =
- new ArrayList<DisplayManagerService.DisplayCallback>();
-
- public DisplayManagerService() {
+ public DisplayManagerService(Context context) {
+ mContext = context;
mHeadless = SystemProperties.get(SYSTEM_HEADLESS).equals("1");
+
registerDefaultDisplayAdapter();
}
private void registerDefaultDisplayAdapter() {
if (mHeadless) {
- registerDisplayAdapter(new HeadlessDisplayAdapter());
+ registerDisplayAdapter(new HeadlessDisplayAdapter(mContext));
} else {
- registerDisplayAdapter(new SurfaceFlingerDisplayAdapter());
+ registerDisplayAdapter(new SurfaceFlingerDisplayAdapter(mContext));
}
}
- public void setContext(Context context) {
- mContext = context;
- }
-
// FIXME: this isn't the right API for the long term
public void getDefaultExternalDisplayDeviceInfo(DisplayDeviceInfo info) {
// hardcoded assuming 720p touch screen plugged into HDMI and USB
@@ -90,6 +75,11 @@ public final class DisplayManagerService extends IDisplayManager.Stub {
info.height = 720;
}
+ /**
+ * Returns true if the device is headless.
+ *
+ * @return True if the device is headless.
+ */
public boolean isHeadless() {
return mHeadless;
}
@@ -101,12 +91,10 @@ public final class DisplayManagerService extends IDisplayManager.Stub {
*/
public void setDisplayInfo(int displayId, DisplayInfo info) {
synchronized (mLock) {
- DisplayInfo localInfo = mDisplayInfos.get(displayId);
- if (localInfo == null) {
- localInfo = new DisplayInfo();
- mDisplayInfos.put(displayId, localInfo);
+ if (displayId != Display.DEFAULT_DISPLAY) {
+ throw new UnsupportedOperationException();
}
- localInfo.copyFrom(info);
+ mDefaultDisplayInfo.copyFrom(info);
}
}
@@ -118,177 +106,32 @@ public final class DisplayManagerService extends IDisplayManager.Stub {
@Override // Binder call
public boolean getDisplayInfo(int displayId, DisplayInfo outInfo) {
synchronized (mLock) {
- DisplayInfo localInfo = mDisplayInfos.get(displayId);
- if (localInfo == null) {
+ if (displayId != Display.DEFAULT_DISPLAY) {
return false;
}
- outInfo.copyFrom(localInfo);
+ outInfo.copyFrom(mDefaultDisplayInfo);
return true;
}
}
- /**
- * Inform the service of a new physical display. A new logical displayId is created and the new
- * physical display is immediately bound to it. Use removeAdapterFromDisplay to disconnect it.
- *
- * @param adapter The wrapper for information associated with the physical display.
- */
- public void registerDisplayAdapter(DisplayAdapter adapter) {
-
- int displayId;
- DisplayCallback[] callbacks;
-
- synchronized (mLock) {
- displayId = mDisplayIdSeq;
- do {
- // Find the next unused displayId. (Pretend like it might ever wrap around).
- mDisplayIdSeq++;
- if (mDisplayIdSeq < 0) {
- mDisplayIdSeq = Display.DEFAULT_DISPLAY + 1;
- }
- } while (mDisplayInfos.get(mDisplayIdSeq) != null);
-
- adapter.setDisplayId(displayId);
-
- createDisplayInfoLocked(displayId, adapter);
-
- ArrayList<DisplayAdapter> list = new ArrayList<DisplayAdapter>();
- list.add(adapter);
- mLogicalToPhysicals.put(displayId, list);
-
- mDisplayAdapters.add(adapter);
- callbacks = mCallbacks.toArray(new DisplayCallback[mCallbacks.size()]);
- }
-
- for (int i = callbacks.length - 1; i >= 0; i--) {
- callbacks[i].displayAdded(displayId);
- }
-
- // TODO: Notify SurfaceFlinger of new addition.
- }
-
- /**
- * Connect a logical display to a physical display. Will remove the physical display from any
- * logical display it is currently attached to.
- *
- * @param displayId The logical display. Will be created if it does not already exist.
- * @param adapter The physical display.
- */
- public void addAdapterToDisplay(int displayId, DisplayAdapter adapter) {
- if (adapter == null) {
- // TODO: Or throw NPE?
- Slog.e(TAG, "addDeviceToDisplay: Attempt to add null adapter");
- return;
- }
-
- synchronized (mLock) {
- if (!mDisplayAdapters.contains(adapter)) {
- // TOOD: Handle unregistered adapter with exception or return value.
- Slog.e(TAG, "addDeviceToDisplay: Attempt to add an unregistered adapter");
- return;
- }
-
- DisplayInfo displayInfo = mDisplayInfos.get(displayId);
- if (displayInfo == null) {
- createDisplayInfoLocked(displayId, adapter);
- }
-
- Integer oldDisplayId = adapter.getDisplayId();
- if (oldDisplayId != Display.NO_DISPLAY) {
- if (oldDisplayId == displayId) {
- // adapter already added to displayId.
- return;
- }
-
- removeAdapterLocked(adapter);
- }
-
- ArrayList<DisplayAdapter> list = mLogicalToPhysicals.get(displayId);
- if (list == null) {
- list = new ArrayList<DisplayAdapter>();
- mLogicalToPhysicals.put(displayId, list);
- }
- list.add(adapter);
- adapter.setDisplayId(displayId);
- }
-
- // TODO: Notify SurfaceFlinger of new addition.
- }
-
- /**
- * Disconnect the physical display from whichever logical display it is attached to.
- * @param adapter The physical display to detach.
- */
- public void removeAdapterFromDisplay(DisplayAdapter adapter) {
- if (adapter == null) {
- // TODO: Or throw NPE?
- return;
- }
-
- synchronized (mLock) {
- if (!mDisplayAdapters.contains(adapter)) {
- // TOOD: Handle unregistered adapter with exception or return value.
- Slog.e(TAG, "removeDeviceFromDisplay: Attempt to remove an unregistered adapter");
- return;
+ private void registerDisplayAdapter(DisplayAdapter adapter) {
+ mDisplayAdapters.add(adapter);
+ adapter.register(new DisplayAdapter.Listener() {
+ @Override
+ public void onDisplayDeviceAdded(DisplayDevice device) {
+ DisplayDeviceInfo deviceInfo = new DisplayDeviceInfo();
+ device.getInfo(deviceInfo);
+ copyDisplayInfoFromDeviceInfo(mDefaultDisplayInfo, deviceInfo);
}
- removeAdapterLocked(adapter);
- }
-
- // TODO: Notify SurfaceFlinger of removal.
- }
-
- public void registerDisplayCallback(final DisplayCallback callback) {
- synchronized (mLock) {
- if (!mCallbacks.contains(callback)) {
- mCallbacks.add(callback);
+ @Override
+ public void onDisplayDeviceRemoved(DisplayDevice device) {
}
- }
+ });
}
- public void unregisterDisplayCallback(final DisplayCallback callback) {
- synchronized (mLock) {
- mCallbacks.remove(callback);
- }
- }
-
- /**
- * Create a new logical DisplayInfo and fill it in with information from the physical display.
- * @param displayId The logical identifier.
- * @param adapter The physical display for initial values.
- */
- private void createDisplayInfoLocked(int displayId, DisplayAdapter adapter) {
- DisplayInfo displayInfo = new DisplayInfo();
- DisplayDeviceInfo deviceInfo = new DisplayDeviceInfo();
- adapter.getDisplayDevice().getInfo(deviceInfo);
- copyDisplayInfoFromDeviceInfo(displayInfo, deviceInfo);
- mDisplayInfos.put(displayId, displayInfo);
- }
-
- /**
- * Disconnect a physical display from its logical display. If there are no more physical
- * displays attached to the logical display, delete the logical display.
- * @param adapter The physical display to detach.
- */
- void removeAdapterLocked(DisplayAdapter adapter) {
- int displayId = adapter.getDisplayId();
- adapter.setDisplayId(Display.NO_DISPLAY);
-
- ArrayList<DisplayAdapter> list = mLogicalToPhysicals.get(displayId);
- if (list != null) {
- list.remove(adapter);
- if (list.isEmpty()) {
- mLogicalToPhysicals.remove(displayId);
- // TODO: Keep count of Windows attached to logical display and don't delete if
- // there are any outstanding. Also, what keeps the WindowManager from continuing
- // to use the logical display?
- mDisplayInfos.remove(displayId);
- }
- }
- }
-
- private void copyDisplayInfoFromDeviceInfo(DisplayInfo displayInfo,
- DisplayDeviceInfo deviceInfo) {
+ private void copyDisplayInfoFromDeviceInfo(
+ DisplayInfo displayInfo, DisplayDeviceInfo deviceInfo) {
// Bootstrap the logical display using the physical display.
displayInfo.appWidth = deviceInfo.width;
displayInfo.appHeight = deviceInfo.height;
@@ -319,19 +162,15 @@ public final class DisplayManagerService extends IDisplayManager.Stub {
pw.println("Headless: " + mHeadless);
- DisplayDeviceInfo info = new DisplayDeviceInfo();
- for (DisplayAdapter adapter : mDisplayAdapters) {
- pw.println("Display for adapter " + adapter.getName()
- + " assigned to Display " + adapter.getDisplayId());
- DisplayDevice device = adapter.getDisplayDevice();
- pw.print(" ");
- device.getInfo(info);
- pw.println(info);
+ synchronized (mLock) {
+ for (DisplayAdapter adapter : mDisplayAdapters) {
+ pw.println("Adapter: " + adapter.getName());
+ }
+
+ pw.println("Default display info: " + mDefaultDisplayInfo);
}
- }
- public interface DisplayCallback {
- public void displayAdded(int displayId);
- public void displayRemoved(int displayId);
+ pw.println("Default display: "
+ + DisplayManager.getInstance().getRealDisplay(Display.DEFAULT_DISPLAY));
}
}
diff --git a/services/java/com/android/server/display/HeadlessDisplayAdapter.java b/services/java/com/android/server/display/HeadlessDisplayAdapter.java
index 3eaf40f..17c2360 100644
--- a/services/java/com/android/server/display/HeadlessDisplayAdapter.java
+++ b/services/java/com/android/server/display/HeadlessDisplayAdapter.java
@@ -16,15 +16,41 @@
package com.android.server.display;
+import android.content.Context;
import android.util.DisplayMetrics;
/**
* Provides a fake default display for headless systems.
*/
public final class HeadlessDisplayAdapter extends DisplayAdapter {
- private final DisplayDevice mDefaultDisplay = new DisplayDevice() {
+ private final Context mContext;
+ private final HeadlessDisplayDevice mDefaultDisplayDevice;
+
+ public HeadlessDisplayAdapter(Context context) {
+ mContext = context;
+ mDefaultDisplayDevice = new HeadlessDisplayDevice();
+ }
+
+ @Override
+ public String getName() {
+ return "HeadlessDisplayAdapter";
+ }
+
+ @Override
+ public void register(Listener listener) {
+ listener.onDisplayDeviceAdded(mDefaultDisplayDevice);
+ }
+
+ private final class HeadlessDisplayDevice extends DisplayDevice {
+ @Override
+ public DisplayAdapter getAdapter() {
+ return HeadlessDisplayAdapter.this;
+ }
+
@Override
public void getInfo(DisplayDeviceInfo outInfo) {
+ outInfo.name = mContext.getResources().getString(
+ com.android.internal.R.string.display_manager_built_in_display);
outInfo.width = 640;
outInfo.height = 480;
outInfo.refreshRate = 60;
@@ -32,15 +58,5 @@ public final class HeadlessDisplayAdapter extends DisplayAdapter {
outInfo.xDpi = 160;
outInfo.yDpi = 160;
}
- };
-
- @Override
- public String getName() {
- return "HeadlessDisplayAdapter";
- }
-
- @Override
- public DisplayDevice getDisplayDevice() {
- return mDefaultDisplay;
}
}
diff --git a/services/java/com/android/server/display/SurfaceFlingerDisplayAdapter.java b/services/java/com/android/server/display/SurfaceFlingerDisplayAdapter.java
index 539f7c1..9531acb 100644
--- a/services/java/com/android/server/display/SurfaceFlingerDisplayAdapter.java
+++ b/services/java/com/android/server/display/SurfaceFlingerDisplayAdapter.java
@@ -16,18 +16,21 @@
package com.android.server.display;
+import android.content.Context;
+
/**
* A display adapter for the displays managed by Surface Flinger.
*/
public final class SurfaceFlingerDisplayAdapter extends DisplayAdapter {
+ private final Context mContext;
+ private final SurfaceFlingerDisplayDevice mDefaultDisplayDevice;
+
private static native void nativeGetDefaultDisplayDeviceInfo(DisplayDeviceInfo outInfo);
- private final DisplayDevice mDefaultDisplay = new DisplayDevice() {
- @Override
- public void getInfo(DisplayDeviceInfo outInfo) {
- nativeGetDefaultDisplayDeviceInfo(outInfo);
- }
- };
+ public SurfaceFlingerDisplayAdapter(Context context) {
+ mContext = context;
+ mDefaultDisplayDevice = new SurfaceFlingerDisplayDevice();
+ }
@Override
public String getName() {
@@ -35,7 +38,21 @@ public final class SurfaceFlingerDisplayAdapter extends DisplayAdapter {
}
@Override
- public DisplayDevice getDisplayDevice() {
- return mDefaultDisplay;
+ public void register(Listener listener) {
+ listener.onDisplayDeviceAdded(mDefaultDisplayDevice);
+ }
+
+ private final class SurfaceFlingerDisplayDevice extends DisplayDevice {
+ @Override
+ public DisplayAdapter getAdapter() {
+ return SurfaceFlingerDisplayAdapter.this;
+ }
+
+ @Override
+ public void getInfo(DisplayDeviceInfo outInfo) {
+ outInfo.name = mContext.getResources().getString(
+ com.android.internal.R.string.display_manager_built_in_display);
+ nativeGetDefaultDisplayDeviceInfo(outInfo);
+ }
}
}
diff --git a/services/java/com/android/server/input/InputManagerService.java b/services/java/com/android/server/input/InputManagerService.java
index 21100e2..0b8ff62 100644
--- a/services/java/com/android/server/input/InputManagerService.java
+++ b/services/java/com/android/server/input/InputManagerService.java
@@ -1218,8 +1218,12 @@ public class InputManagerService extends IInputManager.Stub implements Watchdog.
}
// Native callback.
- private void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) {
- mCallbacks.notifyLidSwitchChanged(whenNanos, lidOpen);
+ private void notifySwitch(long whenNanos, int switchCode, int switchValue) {
+ switch (switchCode) {
+ case SW_LID:
+ mCallbacks.notifyLidSwitchChanged(whenNanos, switchValue == 0);
+ break;
+ }
}
// Native callback.
diff --git a/services/java/com/android/server/location/GeofenceManager.java b/services/java/com/android/server/location/GeofenceManager.java
index 338cd5d..26d9c15 100644
--- a/services/java/com/android/server/location/GeofenceManager.java
+++ b/services/java/com/android/server/location/GeofenceManager.java
@@ -34,9 +34,13 @@ import android.os.Bundle;
import android.os.Looper;
import android.os.PowerManager;
import android.os.SystemClock;
+import android.util.Log;
+
+import com.android.server.LocationManagerService;
public class GeofenceManager implements LocationListener, PendingIntent.OnFinished {
private static final String TAG = "GeofenceManager";
+ private static final boolean D = LocationManagerService.D;
/**
* Assume a maximum land speed, as a heuristic to throttle location updates.
@@ -49,6 +53,7 @@ public class GeofenceManager implements LocationListener, PendingIntent.OnFinish
private final LocationManager mLocationManager;
private final PowerManager.WakeLock mWakeLock;
private final Looper mLooper; // looper thread to take location updates on
+ private final LocationBlacklist mBlacklist;
private Object mLock = new Object();
@@ -56,12 +61,13 @@ public class GeofenceManager implements LocationListener, PendingIntent.OnFinish
private Location mLastLocation;
private List<GeofenceState> mFences = new LinkedList<GeofenceState>();
- public GeofenceManager(Context context) {
+ public GeofenceManager(Context context, LocationBlacklist blacklist) {
mContext = context;
mLocationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
mLooper = Looper.myLooper();
+ mBlacklist = blacklist;
LocationRequest request = new LocationRequest()
.setQuality(LocationRequest.POWER_NONE)
@@ -145,6 +151,12 @@ public class GeofenceManager implements LocationListener, PendingIntent.OnFinish
removeExpiredFencesLocked();
for (GeofenceState state : mFences) {
+ if (mBlacklist.isBlacklisted(state.mPackageName)) {
+ if (D) Log.d(TAG, "skipping geofence processing for blacklisted app: " +
+ state.mPackageName);
+ continue;
+ }
+
int event = state.processLocation(location);
if ((event & GeofenceState.FLAG_ENTER) != 0) {
enterIntents.add(state.mIntent);
diff --git a/services/java/com/android/server/location/LocationBlacklist.java b/services/java/com/android/server/location/LocationBlacklist.java
new file mode 100644
index 0000000..71fa9f9
--- /dev/null
+++ b/services/java/com/android/server/location/LocationBlacklist.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package com.android.server.location;
+
+import android.content.Context;
+import android.database.ContentObserver;
+import android.os.Handler;
+import android.provider.Settings;
+import android.util.Log;
+import android.util.Slog;
+
+import com.android.server.LocationManagerService;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+/**
+ * Allows applications to be blacklisted from location updates at run-time.
+ *
+ * This is a silent blacklist. Applications can still call Location Manager
+ * API's, but they just won't receive any locations.
+ */
+public final class LocationBlacklist extends ContentObserver {
+ private static final String TAG = "LocationBlacklist";
+ private static final boolean D = LocationManagerService.D;
+ private static final String BLACKLIST_CONFIG_NAME = "locationPackagePrefixBlacklist";
+ private static final String WHITELIST_CONFIG_NAME = "locationPackagePrefixWhitelist";
+
+ private final Context mContext;
+ private final Object mLock = new Object();
+
+ // all fields below synchronized on mLock
+ private String[] mWhitelist = new String[0];
+ private String[] mBlacklist = new String[0];
+
+ public LocationBlacklist(Context context, Handler handler) {
+ super(handler);
+ mContext = context;
+ }
+
+ public void init() {
+ mContext.getContentResolver().registerContentObserver(Settings.Secure.getUriFor(
+ BLACKLIST_CONFIG_NAME), false, this);
+// mContext.getContentResolver().registerContentObserver(Settings.Secure.getUriFor(
+// WHITELIST_CONFIG_NAME), false, this);
+ reloadBlacklist();
+ }
+
+ private void reloadBlacklist() {
+ String blacklist[] = getStringArray(BLACKLIST_CONFIG_NAME);
+ String whitelist[] = getStringArray(WHITELIST_CONFIG_NAME);
+ synchronized (mLock) {
+ mWhitelist = whitelist;
+ Slog.i(TAG, "whitelist: " + Arrays.toString(mWhitelist));
+ mBlacklist = blacklist;
+ Slog.i(TAG, "blacklist: " + Arrays.toString(mBlacklist));
+ }
+ }
+
+ /**
+ * Return true if in blacklist
+ * (package name matches blacklist, and does not match whitelist)
+ */
+ public boolean isBlacklisted(String packageName) {
+ synchronized (mLock) {
+ for (String black : mBlacklist) {
+ if (packageName.startsWith(black)) {
+ if (inWhitelist(packageName)) {
+ continue;
+ } else {
+ if (D) Log.d(TAG, "dropping location (blacklisted): "
+ + packageName + " matches " + black);
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Return true if any of packages are in whitelist
+ */
+ private boolean inWhitelist(String pkg) {
+ synchronized (mLock) {
+ for (String white : mWhitelist) {
+ if (pkg.startsWith(white)) return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public void onChange(boolean selfChange) {
+ reloadBlacklist();
+ }
+
+ private String[] getStringArray(String key) {
+ String flatString = Settings.Secure.getString(mContext.getContentResolver(), key);
+ if (flatString == null) {
+ return new String[0];
+ }
+ String[] splitStrings = flatString.split(",");
+ ArrayList<String> result = new ArrayList<String>();
+ for (String pkg : splitStrings) {
+ pkg = pkg.trim();
+ if (pkg.isEmpty()) {
+ continue;
+ }
+ result.add(pkg);
+ }
+ return result.toArray(new String[result.size()]);
+ }
+
+ public void dump(PrintWriter pw) {
+ pw.println("mWhitelist=" + Arrays.toString(mWhitelist) + " mBlacklist=" +
+ Arrays.toString(mBlacklist));
+ }
+}
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 0d6e08d..be82b34 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -79,6 +79,7 @@ import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.pm.Signature;
import android.content.pm.ManifestDigest;
+import android.content.pm.VerificationParams;
import android.content.pm.VerifierDeviceIdentity;
import android.content.pm.VerifierInfo;
import android.net.Uri;
@@ -2422,6 +2423,9 @@ public class PackageManagerService extends IPackageManager.Stub {
final int M = prefs.size();
for (int i=0; i<M; i++) {
final PreferredActivity pa = prefs.get(i);
+ if (pa.mUserId != userId) {
+ continue;
+ }
if (pa.mPref.mMatch != match) {
continue;
}
@@ -5348,7 +5352,17 @@ public class PackageManagerService extends IPackageManager.Stub {
public void installPackageWithVerification(Uri packageURI, IPackageInstallObserver observer,
int flags, String installerPackageName, Uri verificationURI,
ManifestDigest manifestDigest, ContainerEncryptionParams encryptionParams) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
+ VerificationParams verificationParams = new VerificationParams(verificationURI, null, null,
+ manifestDigest);
+ installPackageWithVerificationAndEncryption(packageURI, observer, flags,
+ installerPackageName, verificationParams, encryptionParams);
+ }
+
+ public void installPackageWithVerificationAndEncryption(Uri packageURI,
+ IPackageInstallObserver observer, int flags, String installerPackageName,
+ VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) {
+ mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
+ null);
final int uid = Binder.getCallingUid();
@@ -5365,7 +5379,7 @@ public class PackageManagerService extends IPackageManager.Stub {
final Message msg = mHandler.obtainMessage(INIT_COPY);
msg.obj = new InstallParams(packageURI, observer, filteredFlags, installerPackageName,
- verificationURI, manifestDigest, encryptionParams);
+ verificationParams, encryptionParams);
mHandler.sendMessage(msg);
}
@@ -5795,8 +5809,7 @@ public class PackageManagerService extends IPackageManager.Stub {
private final Uri mPackageURI;
final String installerPackageName;
- final Uri verificationURI;
- final ManifestDigest manifestDigest;
+ final VerificationParams verificationParams;
private InstallArgs mArgs;
private int mRet;
private File mTempPackage;
@@ -5804,17 +5817,23 @@ public class PackageManagerService extends IPackageManager.Stub {
InstallParams(Uri packageURI,
IPackageInstallObserver observer, int flags,
- String installerPackageName, Uri verificationURI, ManifestDigest manifestDigest,
+ String installerPackageName, VerificationParams verificationParams,
ContainerEncryptionParams encryptionParams) {
this.mPackageURI = packageURI;
this.flags = flags;
this.observer = observer;
this.installerPackageName = installerPackageName;
- this.verificationURI = verificationURI;
- this.manifestDigest = manifestDigest;
+ this.verificationParams = verificationParams;
this.encryptionParams = encryptionParams;
}
+ public ManifestDigest getManifestDigest() {
+ if (verificationParams == null) {
+ return null;
+ }
+ return verificationParams.getManifestDigest();
+ }
+
private int installLocationPolicy(PackageInfoLite pkgLite, int flags) {
String packageName = pkgLite.packageName;
int installLocation = pkgLite.installLocation;
@@ -6003,9 +6022,19 @@ public class PackageManagerService extends IPackageManager.Stub {
verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS, flags);
- if (verificationURI != null) {
- verification.putExtra(PackageManager.EXTRA_VERIFICATION_URI,
- verificationURI);
+ if (verificationParams != null) {
+ if (verificationParams.getVerificationURI() != null) {
+ verification.putExtra(PackageManager.EXTRA_VERIFICATION_URI,
+ verificationParams.getVerificationURI());
+ }
+ if (verificationParams.getOriginatingURI() != null) {
+ verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
+ verificationParams.getOriginatingURI());
+ }
+ if (verificationParams.getReferrer() != null) {
+ verification.putExtra(Intent.EXTRA_REFERRER,
+ verificationParams.getReferrer());
+ }
}
final PackageVerificationState verificationState = new PackageVerificationState(
@@ -6341,7 +6370,7 @@ public class PackageManagerService extends IPackageManager.Stub {
FileInstallArgs(InstallParams params) {
super(params.getPackageUri(), params.observer, params.flags,
- params.installerPackageName, params.manifestDigest);
+ params.installerPackageName, params.getManifestDigest());
}
FileInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath) {
@@ -6628,7 +6657,7 @@ public class PackageManagerService extends IPackageManager.Stub {
AsecInstallArgs(InstallParams params) {
super(params.getPackageUri(), params.observer, params.flags,
- params.installerPackageName, params.manifestDigest);
+ params.installerPackageName, params.getManifestDigest());
}
AsecInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath,
@@ -7645,7 +7674,7 @@ public class PackageManagerService extends IPackageManager.Stub {
mSettings.updateSharedUserPermsLPw(deletedPs, mGlobalGids);
}
}
- clearPackagePreferredActivitiesLPw(deletedPs.name);
+ clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
}
}
// can downgrade to reader
@@ -8112,26 +8141,28 @@ public class PackageManagerService extends IPackageManager.Stub {
}
public void addPreferredActivity(IntentFilter filter, int match,
- ComponentName[] set, ComponentName activity) {
+ ComponentName[] set, ComponentName activity, int userId) {
// writer
+ int callingUid = Binder.getCallingUid();
+ checkValidCaller(callingUid, userId);
synchronized (mPackages) {
if (mContext.checkCallingOrSelfPermission(
android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
!= PackageManager.PERMISSION_GRANTED) {
- if (getUidTargetSdkVersionLockedLPr(Binder.getCallingUid())
+ if (getUidTargetSdkVersionLockedLPr(callingUid)
< Build.VERSION_CODES.FROYO) {
Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
- + Binder.getCallingUid());
+ + callingUid);
return;
}
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
}
-
- Slog.i(TAG, "Adding preferred activity " + activity + ":");
+
+ Slog.i(TAG, "Adding preferred activity " + activity + " for user " + userId + " :");
filter.dump(new LogPrinter(Log.INFO, TAG), " ");
mSettings.mPreferredActivities.addFilter(
- new PreferredActivity(filter, match, set, activity));
+ new PreferredActivity(filter, match, set, activity, userId));
scheduleWriteSettingsLocked();
}
}
@@ -8167,13 +8198,15 @@ public class PackageManagerService extends IPackageManager.Stub {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
}
-
+
+ final int callingUserId = UserHandle.getCallingUserId();
ArrayList<PreferredActivity> removed = null;
Iterator<PreferredActivity> it = mSettings.mPreferredActivities.filterIterator();
String action = filter.getAction(0);
String category = filter.getCategory(0);
while (it.hasNext()) {
PreferredActivity pa = it.next();
+ if (pa.mUserId != callingUserId) continue;
if (pa.getAction(0).equals(action) && pa.getCategory(0).equals(category)) {
if (removed == null) {
removed = new ArrayList<PreferredActivity>();
@@ -8189,7 +8222,7 @@ public class PackageManagerService extends IPackageManager.Stub {
mSettings.mPreferredActivities.removeFilter(pa);
}
}
- addPreferredActivity(filter, match, set, activity);
+ addPreferredActivity(filter, match, set, activity, callingUserId);
}
}
@@ -8213,17 +8246,21 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
- if (clearPackagePreferredActivitiesLPw(packageName)) {
+ if (clearPackagePreferredActivitiesLPw(packageName, UserHandle.getCallingUserId())) {
scheduleWriteSettingsLocked();
}
}
}
- boolean clearPackagePreferredActivitiesLPw(String packageName) {
+ /** This method takes a specific user id as well as UserHandle.USER_ALL. */
+ boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
ArrayList<PreferredActivity> removed = null;
Iterator<PreferredActivity> it = mSettings.mPreferredActivities.filterIterator();
while (it.hasNext()) {
PreferredActivity pa = it.next();
+ if (userId != UserHandle.USER_ALL && pa.mUserId != userId) {
+ continue;
+ }
if (pa.mPref.mComponent.getPackageName().equals(packageName)) {
if (removed == null) {
removed = new ArrayList<PreferredActivity>();
@@ -8245,11 +8282,15 @@ public class PackageManagerService extends IPackageManager.Stub {
List<ComponentName> outActivities, String packageName) {
int num = 0;
+ final int userId = UserHandle.getCallingUserId();
// reader
synchronized (mPackages) {
final Iterator<PreferredActivity> it = mSettings.mPreferredActivities.filterIterator();
while (it.hasNext()) {
final PreferredActivity pa = it.next();
+ if (pa.mUserId != userId) {
+ continue;
+ }
if (packageName == null
|| pa.mPref.mComponent.getPackageName().equals(packageName)) {
if (outFilters != null) {
diff --git a/services/java/com/android/server/pm/PreferredActivity.java b/services/java/com/android/server/pm/PreferredActivity.java
index b100eb1..5539e84 100644
--- a/services/java/com/android/server/pm/PreferredActivity.java
+++ b/services/java/com/android/server/pm/PreferredActivity.java
@@ -33,22 +33,38 @@ class PreferredActivity extends IntentFilter implements PreferredComponent.Callb
private static final String TAG = "PreferredActivity";
private static final boolean DEBUG_FILTERS = false;
+ static final String ATTR_USER_ID = "userId";
final PreferredComponent mPref;
+ final int mUserId;
PreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity) {
+ this(filter, match, set, activity, 0);
+ }
+
+ PreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity,
+ int userId) {
super(filter);
+ mUserId = userId;
mPref = new PreferredComponent(this, match, set, activity);
}
PreferredActivity(XmlPullParser parser) throws XmlPullParserException, IOException {
+ String userIdString = parser.getAttributeValue(null, ATTR_USER_ID);
+ if (userIdString != null && userIdString.length() > 0) {
+ mUserId = Integer.parseInt(userIdString);
+ } else {
+ // Old format with no userId specified - assume primary user
+ mUserId = 0;
+ }
mPref = new PreferredComponent(this, parser);
}
public void writeToXml(XmlSerializer serializer) throws IOException {
+ serializer.attribute(null, ATTR_USER_ID, Integer.toString(mUserId));
mPref.writeToXml(serializer);
serializer.startTag(null, "filter");
- super.writeToXml(serializer);
+ super.writeToXml(serializer);
serializer.endTag(null, "filter");
}
diff --git a/services/java/com/android/server/pm/UserManagerService.java b/services/java/com/android/server/pm/UserManagerService.java
index a828864..c292bbc 100644
--- a/services/java/com/android/server/pm/UserManagerService.java
+++ b/services/java/com/android/server/pm/UserManagerService.java
@@ -506,6 +506,8 @@ public class UserManagerService extends IUserManager.Stub {
Intent addedIntent = new Intent(Intent.ACTION_USER_ADDED);
addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userInfo.id);
mContext.sendBroadcast(addedIntent, android.Manifest.permission.MANAGE_USERS);
+ mContext.sendBroadcastAsUser(new Intent(Intent.ACTION_BOOT_COMPLETED),
+ new UserHandle(userInfo.id));
}
return userInfo;
}
diff --git a/services/java/com/android/server/power/DisplayPowerController.java b/services/java/com/android/server/power/DisplayPowerController.java
index f3183f8..cf12b20 100644
--- a/services/java/com/android/server/power/DisplayPowerController.java
+++ b/services/java/com/android/server/power/DisplayPowerController.java
@@ -27,6 +27,7 @@ import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.hardware.SystemSensorManager;
+import android.hardware.display.DisplayManager;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Looper;
@@ -35,6 +36,7 @@ import android.os.SystemClock;
import android.util.Slog;
import android.util.Spline;
import android.util.TimeUtils;
+import android.view.Display;
import java.io.PrintWriter;
import java.io.StringWriter;
@@ -73,8 +75,8 @@ final class DisplayPowerController {
// If true, uses the electron beam on animation.
// We might want to turn this off if we cannot get a guarantee that the screen
// actually turns on and starts showing new content after the call to set the
- // screen state returns.
- private static final boolean USE_ELECTRON_BEAM_ON_ANIMATION = true;
+ // screen state returns. Playing the animation can also be somewhat slow.
+ private static final boolean USE_ELECTRON_BEAM_ON_ANIMATION = false;
private static final int ELECTRON_BEAM_ON_ANIMATION_DURATION_MILLIS = 300;
private static final int ELECTRON_BEAM_OFF_ANIMATION_DURATION_MILLIS = 600;
@@ -98,15 +100,15 @@ final class DisplayPowerController {
// Brightness animation ramp rate in brightness units per second.
private static final int BRIGHTNESS_RAMP_RATE_FAST = 200;
- private static final int BRIGHTNESS_RAMP_RATE_SLOW = 50;
+ private static final int BRIGHTNESS_RAMP_RATE_SLOW = 40;
// Filter time constant in milliseconds for computing a moving
// average of light samples. Different constants are used
// to calculate the average light level when adapting to brighter or
// dimmer environments.
// This parameter only controls the filtering of light samples.
- private static final long BRIGHTENING_LIGHT_TIME_CONSTANT = 500;
- private static final long DIMMING_LIGHT_TIME_CONSTANT = 2000;
+ private static final long BRIGHTENING_LIGHT_TIME_CONSTANT = 600;
+ private static final long DIMMING_LIGHT_TIME_CONSTANT = 4000;
// Stability requirements in milliseconds for accepting a new brightness
// level. This is used for debouncing the light sensor. Different constants
@@ -428,7 +430,8 @@ final class DisplayPowerController {
private void initialize() {
final Executor executor = AsyncTask.THREAD_POOL_EXECUTOR;
- mPowerState = new DisplayPowerState(new ElectronBeam(),
+ Display display = DisplayManager.getInstance().getRealDisplay(Display.DEFAULT_DISPLAY);
+ mPowerState = new DisplayPowerState(new ElectronBeam(display),
new PhotonicModulator(executor,
mLights.getLight(LightsService.LIGHT_ID_BACKLIGHT),
mSuspendBlocker));
@@ -476,11 +479,13 @@ final class DisplayPowerController {
if (mPowerRequest == null) {
mPowerRequest = new DisplayPowerRequest(mPendingRequestLocked);
mWaitingForNegativeProximity = mPendingWaitForNegativeProximityLocked;
+ mPendingWaitForNegativeProximityLocked = false;
mPendingRequestChangedLocked = false;
mustInitialize = true;
} else if (mPendingRequestChangedLocked) {
mPowerRequest.copyFrom(mPendingRequestLocked);
mWaitingForNegativeProximity |= mPendingWaitForNegativeProximityLocked;
+ mPendingWaitForNegativeProximityLocked = false;
mPendingRequestChangedLocked = false;
mDisplayReadyLocked = false;
}
@@ -493,24 +498,33 @@ final class DisplayPowerController {
initialize();
}
- // Clear a request to wait for negative proximity if needed.
- if (mPowerRequest.screenState == DisplayPowerRequest.SCREEN_STATE_OFF
- || mProximity == PROXIMITY_NEGATIVE
- || mProximitySensor == null) {
- mWaitingForNegativeProximity = false;
- }
-
- // Turn on the proximity sensor if needed.
+ // Apply the proximity sensor.
if (mProximitySensor != null) {
- setProximitySensorEnabled(mPowerRequest.useProximitySensor
- || mWaitingForNegativeProximity);
- if (mProximitySensorEnabled && mProximity == PROXIMITY_POSITIVE) {
- mScreenOffBecauseOfProximity = true;
- setScreenOn(false);
- } else if (mScreenOffBecauseOfProximity) {
+ if (mPowerRequest.useProximitySensor
+ && mPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF) {
+ setProximitySensorEnabled(true);
+ if (!mScreenOffBecauseOfProximity
+ && mProximity == PROXIMITY_POSITIVE) {
+ mScreenOffBecauseOfProximity = true;
+ setScreenOn(false);
+ }
+ } else if (mWaitingForNegativeProximity
+ && mScreenOffBecauseOfProximity
+ && mProximity == PROXIMITY_POSITIVE
+ && mPowerRequest.screenState != DisplayPowerRequest.SCREEN_STATE_OFF) {
+ setProximitySensorEnabled(true);
+ } else {
+ setProximitySensorEnabled(false);
+ mWaitingForNegativeProximity = false;
+ }
+ if (mScreenOffBecauseOfProximity
+ && mProximity != PROXIMITY_POSITIVE) {
mScreenOffBecauseOfProximity = false;
+ setScreenOn(true);
sendOnProximityNegative();
}
+ } else {
+ mWaitingForNegativeProximity = false;
}
// Turn on the light sensor if needed.
diff --git a/services/java/com/android/server/power/ElectronBeam.java b/services/java/com/android/server/power/ElectronBeam.java
index 5472148..2d24249 100644
--- a/services/java/com/android/server/power/ElectronBeam.java
+++ b/services/java/com/android/server/power/ElectronBeam.java
@@ -33,7 +33,6 @@ import android.view.Display;
import android.view.DisplayInfo;
import android.view.Surface;
import android.view.SurfaceSession;
-import android.view.WindowManagerImpl;
import java.io.PrintWriter;
import java.nio.ByteBuffer;
@@ -68,6 +67,7 @@ final class ElectronBeam {
private boolean mPrepared;
private boolean mWarmUp;
+ private final Display mDisplay;
private final DisplayInfo mDisplayInfo = new DisplayInfo();
private int mDisplayLayerStack; // layer stack associated with primary display
private int mDisplayRotation;
@@ -90,7 +90,8 @@ final class ElectronBeam {
private final FloatBuffer mVertexBuffer = createNativeFloatBuffer(8);
private final FloatBuffer mTexCoordBuffer = createNativeFloatBuffer(8);
- public ElectronBeam() {
+ public ElectronBeam(Display display) {
+ mDisplay = display;
}
/**
@@ -109,9 +110,8 @@ final class ElectronBeam {
mWarmUp = warmUp;
// Get the display size and adjust it for rotation.
- Display display = WindowManagerImpl.getDefault().getDefaultDisplay();
- display.getDisplayInfo(mDisplayInfo);
- mDisplayLayerStack = display.getDisplayId();
+ mDisplay.getDisplayInfo(mDisplayInfo);
+ mDisplayLayerStack = mDisplay.getLayerStack();
mDisplayRotation = mDisplayInfo.rotation;
if (mDisplayRotation == Surface.ROTATION_90
|| mDisplayRotation == Surface.ROTATION_270) {
diff --git a/services/java/com/android/server/usb/UsbDebuggingManager.java b/services/java/com/android/server/usb/UsbDebuggingManager.java
new file mode 100644
index 0000000..a3b45c7
--- /dev/null
+++ b/services/java/com/android/server/usb/UsbDebuggingManager.java
@@ -0,0 +1,322 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions an
+ * limitations under the License.
+ */
+
+package com.android.server.usb;
+
+import android.content.ActivityNotFoundException;
+import android.content.Context;
+import android.content.Intent;
+import android.net.LocalSocket;
+import android.net.LocalSocketAddress;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Environment;
+import android.os.FileUtils;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Process;
+import android.os.SystemClock;
+import android.util.Slog;
+import android.util.Base64;
+
+import java.lang.Thread;
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.security.MessageDigest;
+import java.util.Arrays;
+
+public class UsbDebuggingManager implements Runnable {
+ private static final String TAG = "UsbDebuggingManager";
+ private static final boolean DEBUG = false;
+
+ private final String ADBD_SOCKET = "adbd";
+ private final String ADB_DIRECTORY = "misc/adb";
+ private final String ADB_KEYS_FILE = "adb_keys";
+ private final int BUFFER_SIZE = 4096;
+
+ private final Context mContext;
+ private final Thread mThread;
+ private final Handler mHandler;
+ private final HandlerThread mHandlerThread;
+ private boolean mAdbEnabled = false;
+ private String mFingerprints;
+ private LocalSocket mSocket = null;
+ private OutputStream mOutputStream = null;
+
+ public UsbDebuggingManager(Context context) {
+ mThread = new Thread(this);
+ mHandlerThread = new HandlerThread("UsbDebuggingHandler");
+ mHandlerThread.start();
+ mHandler = new UsbDebuggingHandler(mHandlerThread.getLooper());
+ mContext = context;
+ }
+
+ private void listenToSocket() throws IOException {
+ try {
+ byte[] buffer = new byte[BUFFER_SIZE];
+ LocalSocketAddress address = new LocalSocketAddress(ADBD_SOCKET,
+ LocalSocketAddress.Namespace.RESERVED);
+ InputStream inputStream = null;
+
+ mSocket = new LocalSocket();
+ mSocket.connect(address);
+
+ mOutputStream = mSocket.getOutputStream();
+ inputStream = mSocket.getInputStream();
+
+ while (true) {
+ int count = inputStream.read(buffer);
+ if (count < 0) {
+ Slog.e(TAG, "got " + count + " reading");
+ break;
+ }
+
+ if (buffer[0] == 'P' && buffer[1] == 'K') {
+ String key = new String(Arrays.copyOfRange(buffer, 2, count));
+ Slog.d(TAG, "Received public key: " + key);
+ Message msg = mHandler.obtainMessage(UsbDebuggingHandler.MESSAGE_ADB_CONFIRM);
+ msg.obj = key;
+ mHandler.sendMessage(msg);
+ }
+ else {
+ Slog.e(TAG, "Wrong message: " + (new String(Arrays.copyOfRange(buffer, 0, 2))));
+ break;
+ }
+ }
+ } catch (IOException ex) {
+ Slog.e(TAG, "Communication error: ", ex);
+ throw ex;
+ } finally {
+ closeSocket();
+ }
+ }
+
+ @Override
+ public void run() {
+ while (mAdbEnabled) {
+ try {
+ listenToSocket();
+ } catch (Exception e) {
+ /* Don't loop too fast if adbd dies, before init restarts it */
+ SystemClock.sleep(1000);
+ }
+ }
+ }
+
+ private void closeSocket() {
+ try {
+ mOutputStream.close();
+ } catch (IOException e) {
+ Slog.e(TAG, "Failed closing output stream: " + e);
+ }
+
+ try {
+ mSocket.close();
+ } catch (IOException ex) {
+ Slog.e(TAG, "Failed closing socket: " + ex);
+ }
+ }
+
+ private void sendResponse(String msg) {
+ if (mOutputStream != null) {
+ try {
+ mOutputStream.write(msg.getBytes());
+ }
+ catch (IOException ex) {
+ Slog.e(TAG, "Failed to write response:", ex);
+ }
+ }
+ }
+
+ class UsbDebuggingHandler extends Handler {
+ private static final int MESSAGE_ADB_ENABLED = 1;
+ private static final int MESSAGE_ADB_DISABLED = 2;
+ private static final int MESSAGE_ADB_ALLOW = 3;
+ private static final int MESSAGE_ADB_DENY = 4;
+ private static final int MESSAGE_ADB_CONFIRM = 5;
+
+ public UsbDebuggingHandler(Looper looper) {
+ super(looper);
+ }
+
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MESSAGE_ADB_ENABLED:
+ if (mAdbEnabled)
+ break;
+
+ mAdbEnabled = true;
+
+ mThread.start();
+
+ break;
+
+ case MESSAGE_ADB_DISABLED:
+ if (!mAdbEnabled)
+ break;
+
+ mAdbEnabled = false;
+ closeSocket();
+
+ try {
+ mThread.join();
+ } catch (Exception ex) {
+ }
+
+ mOutputStream = null;
+ mSocket = null;
+
+ case MESSAGE_ADB_ALLOW: {
+ String key = (String)msg.obj;
+ String fingerprints = getFingerprints(key);
+
+ if (!fingerprints.equals(mFingerprints)) {
+ Slog.e(TAG, "Fingerprints do not match. Got "
+ + fingerprints + ", expected " + mFingerprints);
+ break;
+ }
+
+ if (msg.arg1 == 1) {
+ writeKey(key);
+ }
+
+ sendResponse("OK");
+ break;
+ }
+
+ case MESSAGE_ADB_DENY:
+ sendResponse("NO");
+ break;
+
+ case MESSAGE_ADB_CONFIRM: {
+ String key = (String)msg.obj;
+ mFingerprints = getFingerprints(key);
+ showConfirmationDialog(key, mFingerprints);
+ break;
+ }
+ }
+ }
+ }
+
+ private String getFingerprints(String key) {
+ String hex = "0123456789ABCDEF";
+ StringBuilder sb = new StringBuilder();
+ MessageDigest digester;
+
+ try {
+ digester = MessageDigest.getInstance("MD5");
+ } catch (Exception ex) {
+ Slog.e(TAG, "Error getting digester: " + ex);
+ return "";
+ }
+
+ byte[] base64_data = key.split("\\s+")[0].getBytes();
+ byte[] digest = digester.digest(Base64.decode(base64_data, Base64.DEFAULT));
+
+ for (int i = 0; i < digest.length; i++) {
+ sb.append(hex.charAt((digest[i] >> 4) & 0xf));
+ sb.append(hex.charAt(digest[i] & 0xf));
+ if (i < digest.length - 1)
+ sb.append(":");
+ }
+ return sb.toString();
+ }
+
+ private void showConfirmationDialog(String key, String fingerprints) {
+ Intent dialogIntent = new Intent();
+
+ dialogIntent.setClassName("com.android.systemui",
+ "com.android.systemui.usb.UsbDebuggingActivity");
+ dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ dialogIntent.putExtra("key", key);
+ dialogIntent.putExtra("fingerprints", fingerprints);
+ try {
+ mContext.startActivity(dialogIntent);
+ } catch (ActivityNotFoundException e) {
+ Slog.e(TAG, "unable to start UsbDebuggingActivity");
+ }
+ }
+
+ private void writeKey(String key) {
+ File dataDir = Environment.getDataDirectory();
+ File adbDir = new File(dataDir, ADB_DIRECTORY);
+
+ if (!adbDir.exists()) {
+ Slog.e(TAG, "ADB data directory does not exist");
+ return;
+ }
+
+ try {
+ File keyFile = new File(adbDir, ADB_KEYS_FILE);
+
+ if (!keyFile.exists()) {
+ keyFile.createNewFile();
+ FileUtils.setPermissions(keyFile.toString(),
+ FileUtils.S_IRUSR | FileUtils.S_IWUSR |
+ FileUtils.S_IRGRP, -1, -1);
+ }
+
+ FileOutputStream fo = new FileOutputStream(keyFile, true);
+ fo.write(key.getBytes());
+ fo.write('\n');
+ fo.close();
+ }
+ catch (IOException ex) {
+ Slog.e(TAG, "Error writing key:" + ex);
+ }
+ }
+
+
+ public void setAdbEnabled(boolean enabled) {
+ mHandler.sendEmptyMessage(enabled ? UsbDebuggingHandler.MESSAGE_ADB_ENABLED
+ : UsbDebuggingHandler.MESSAGE_ADB_DISABLED);
+ }
+
+ public void allowUsbDebugging(boolean alwaysAllow, String publicKey) {
+ Message msg = mHandler.obtainMessage(UsbDebuggingHandler.MESSAGE_ADB_ALLOW);
+ msg.arg1 = alwaysAllow ? 1 : 0;
+ msg.obj = publicKey;
+ mHandler.sendMessage(msg);
+ }
+
+ public void denyUsbDebugging() {
+ mHandler.sendEmptyMessage(UsbDebuggingHandler.MESSAGE_ADB_DENY);
+ }
+
+
+ public void dump(FileDescriptor fd, PrintWriter pw) {
+ pw.println(" USB Debugging State:");
+ pw.println(" Connected to adbd: " + (mOutputStream != null));
+ pw.println(" Last key received: " + mFingerprints);
+ pw.println(" User keys:");
+ try {
+ pw.println(FileUtils.readTextFile(new File("/data/misc/adb/adb_keys"), 0, null));
+ } catch (IOException e) {
+ pw.println("IOException: " + e);
+ }
+ pw.println(" System keys:");
+ try {
+ pw.println(FileUtils.readTextFile(new File("/adb_keys"), 0, null));
+ } catch (IOException e) {
+ pw.println("IOException: " + e);
+ }
+ }
+}
diff --git a/services/java/com/android/server/usb/UsbDeviceManager.java b/services/java/com/android/server/usb/UsbDeviceManager.java
index a115345..ddecf14 100644
--- a/services/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/java/com/android/server/usb/UsbDeviceManager.java
@@ -114,6 +114,7 @@ public class UsbDeviceManager {
private boolean mAudioSourceEnabled;
private Map<String, List<Pair<String, String>>> mOemModeMap;
private String[] mAccessoryStrings;
+ private UsbDebuggingManager mDebuggingManager;
private class AdbSettingsObserver extends ContentObserver {
public AdbSettingsObserver() {
@@ -166,6 +167,10 @@ public class UsbDeviceManager {
if (DEBUG) Slog.d(TAG, "accessory attached at boot");
startAccessoryMode();
}
+
+ if ("1".equals(SystemProperties.get("ro.adb.secure"))) {
+ mDebuggingManager = new UsbDebuggingManager(context);
+ }
}
public void systemReady() {
@@ -425,6 +430,9 @@ public class UsbDeviceManager {
setEnabledFunctions(mDefaultFunctions, true);
updateAdbNotification();
}
+ if (mDebuggingManager != null) {
+ mDebuggingManager.setAdbEnabled(mAdbEnabled);
+ }
}
private void setEnabledFunctions(String functions, boolean makeDefault) {
@@ -601,6 +609,9 @@ public class UsbDeviceManager {
if (mCurrentAccessory != null) {
mSettingsManager.accessoryAttached(mCurrentAccessory);
}
+ if (mDebuggingManager != null) {
+ mDebuggingManager.setAdbEnabled(mAdbEnabled);
+ }
break;
}
}
@@ -802,10 +813,25 @@ public class UsbDeviceManager {
return usbFunctions;
}
+ public void allowUsbDebugging(boolean alwaysAllow, String publicKey) {
+ if (mDebuggingManager != null) {
+ mDebuggingManager.allowUsbDebugging(alwaysAllow, publicKey);
+ }
+ }
+
+ public void denyUsbDebugging() {
+ if (mDebuggingManager != null) {
+ mDebuggingManager.denyUsbDebugging();
+ }
+ }
+
public void dump(FileDescriptor fd, PrintWriter pw) {
if (mHandler != null) {
mHandler.dump(fd, pw);
}
+ if (mDebuggingManager != null) {
+ mDebuggingManager.dump(fd, pw);
+ }
}
private native String[] nativeGetAccessoryStrings();
diff --git a/services/java/com/android/server/usb/UsbService.java b/services/java/com/android/server/usb/UsbService.java
index 0205ef8..bebcd56 100644
--- a/services/java/com/android/server/usb/UsbService.java
+++ b/services/java/com/android/server/usb/UsbService.java
@@ -164,6 +164,16 @@ public class UsbService extends IUsbManager.Stub {
}
}
+ public void allowUsbDebugging(boolean alwaysAllow, String publicKey) {
+ mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
+ mDeviceManager.allowUsbDebugging(alwaysAllow, publicKey);
+ }
+
+ public void denyUsbDebugging() {
+ mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
+ mDeviceManager.denyUsbDebugging();
+ }
+
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
diff --git a/services/java/com/android/server/wm/AppWindowAnimator.java b/services/java/com/android/server/wm/AppWindowAnimator.java
index 691e2aa..c25f010 100644
--- a/services/java/com/android/server/wm/AppWindowAnimator.java
+++ b/services/java/com/android/server/wm/AppWindowAnimator.java
@@ -47,7 +47,7 @@ public class AppWindowAnimator {
final Transformation thumbnailTransformation = new Transformation();
/** WindowStateAnimator from mAppAnimator.allAppWindows as of last performLayout */
- ArrayList<WindowStateAnimator> mAllAppWinAnimators;
+ ArrayList<WindowStateAnimator> mAllAppWinAnimators = new ArrayList<WindowStateAnimator>();
static final Animation sDummyAnimation = new DummyAnimation();
diff --git a/services/java/com/android/server/wm/ScreenRotationAnimation.java b/services/java/com/android/server/wm/ScreenRotationAnimation.java
index 142c60d..7d85d89 100644
--- a/services/java/com/android/server/wm/ScreenRotationAnimation.java
+++ b/services/java/com/android/server/wm/ScreenRotationAnimation.java
@@ -42,6 +42,7 @@ class ScreenRotationAnimation {
static final int FREEZE_LAYER = WindowManagerService.TYPE_LAYER_MULTIPLIER * 200;
final Context mContext;
+ final Display mDisplay;
Surface mSurface;
BlackFrame mCustomBlackFrame;
BlackFrame mExitingBlackFrame;
@@ -186,9 +187,10 @@ class ScreenRotationAnimation {
pw.println();
}
- public ScreenRotationAnimation(Context context, SurfaceSession session,
+ public ScreenRotationAnimation(Context context, Display display, SurfaceSession session,
boolean inTransaction, int originalWidth, int originalHeight, int originalRotation) {
mContext = context;
+ mDisplay = display;
// Screenshot does NOT include rotation!
if (originalRotation == Surface.ROTATION_90
@@ -213,13 +215,13 @@ class ScreenRotationAnimation {
try {
try {
if (WindowManagerService.DEBUG_SURFACE_TRACE) {
- mSurface = new SurfaceTrace(session, 0, "FreezeSurface", Display.DEFAULT_DISPLAY,
- mWidth, mHeight,
- PixelFormat.OPAQUE, Surface.FX_SURFACE_SCREENSHOT | Surface.HIDDEN);
+ mSurface = new SurfaceTrace(session, 0, "FreezeSurface",
+ mDisplay.getLayerStack(), mWidth, mHeight,
+ PixelFormat.OPAQUE, Surface.FX_SURFACE_SCREENSHOT | Surface.HIDDEN);
} else {
- mSurface = new Surface(session, 0, "FreezeSurface", Display.DEFAULT_DISPLAY,
- mWidth, mHeight,
- PixelFormat.OPAQUE, Surface.FX_SURFACE_SCREENSHOT | Surface.HIDDEN);
+ mSurface = new Surface(session, 0, "FreezeSurface",
+ mDisplay.getLayerStack(), mWidth, mHeight,
+ PixelFormat.OPAQUE, Surface.FX_SURFACE_SCREENSHOT | Surface.HIDDEN);
}
if (!mSurface.isValid()) {
// Screenshot failed, punt.
diff --git a/services/java/com/android/server/wm/StrictModeFlash.java b/services/java/com/android/server/wm/StrictModeFlash.java
index 4b072c3..775aa0f 100644
--- a/services/java/com/android/server/wm/StrictModeFlash.java
+++ b/services/java/com/android/server/wm/StrictModeFlash.java
@@ -22,8 +22,6 @@ import android.graphics.Color;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.Region;
-import android.util.DisplayMetrics;
-import android.util.Slog;
import android.view.Display;
import android.view.Surface;
import android.view.SurfaceSession;
@@ -39,7 +37,7 @@ class StrictModeFlash {
public StrictModeFlash(Display display, SurfaceSession session) {
try {
- mSurface = new Surface(session, 0, "StrictModeFlash", Display.DEFAULT_DISPLAY,
+ mSurface = new Surface(session, 0, "StrictModeFlash", display.getLayerStack(),
1, 1, PixelFormat.TRANSLUCENT, 0);
} catch (Surface.OutOfResourcesException e) {
return;
diff --git a/services/java/com/android/server/wm/Watermark.java b/services/java/com/android/server/wm/Watermark.java
index 12076d8..5901cc8 100644
--- a/services/java/com/android/server/wm/Watermark.java
+++ b/services/java/com/android/server/wm/Watermark.java
@@ -35,6 +35,7 @@ import android.view.Surface.OutOfResourcesException;
* Displays a watermark on top of the window manager's windows.
*/
class Watermark {
+ final Display mDisplay;
final String[] mTokens;
final String mText;
final Paint mTextPaint;
@@ -50,7 +51,7 @@ class Watermark {
int mLastDH;
boolean mDrawNeeded;
- Watermark(DisplayMetrics dm, SurfaceSession session, String[] tokens) {
+ Watermark(Display display, DisplayMetrics dm, SurfaceSession session, String[] tokens) {
if (false) {
Log.i(WindowManagerService.TAG, "*********************** WATERMARK");
for (int i=0; i<tokens.length; i++) {
@@ -58,6 +59,7 @@ class Watermark {
}
}
+ mDisplay = display;
mTokens = tokens;
StringBuilder builder = new StringBuilder(32);
@@ -112,7 +114,7 @@ class Watermark {
try {
mSurface = new Surface(session, 0,
- "WatermarkSurface", Display.DEFAULT_DISPLAY,
+ "WatermarkSurface", mDisplay.getLayerStack(),
1, 1, PixelFormat.TRANSLUCENT, 0);
mSurface.setLayer(WindowManagerService.TYPE_LAYER_MULTIPLIER*100);
mSurface.setPosition(0, 0);
diff --git a/services/java/com/android/server/wm/WindowAnimator.java b/services/java/com/android/server/wm/WindowAnimator.java
index 0dbe692..1defa49 100644
--- a/services/java/com/android/server/wm/WindowAnimator.java
+++ b/services/java/com/android/server/wm/WindowAnimator.java
@@ -190,8 +190,8 @@ public class WindowAnimator {
for (int i = 0; i < N; i++) {
final AppWindowAnimParams params = layoutToAnim.mAppWindowAnimParams.get(i);
AppWindowAnimator appAnimator = params.mAppAnimator;
- appAnimator.mAllAppWinAnimators =
- new ArrayList<WindowStateAnimator>(params.mWinAnimators);
+ appAnimator.mAllAppWinAnimators.clear();
+ appAnimator.mAllAppWinAnimators.addAll(params.mWinAnimators);
mAppAnimators.add(appAnimator);
}
}
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index c1884da..98adf38 100755
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -127,7 +127,7 @@ import android.view.SurfaceSession;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
-import android.view.WindowManagerImpl;
+import android.view.WindowManagerGlobal;
import android.view.WindowManagerPolicy;
import android.view.WindowManager.LayoutParams;
import android.view.WindowManagerPolicy.FakeWindow;
@@ -2141,7 +2141,7 @@ public class WindowManagerService extends IWindowManager.Stub
WindowManager.LayoutParams attrs, int viewVisibility, int displayId,
Rect outContentInsets, InputChannel outInputChannel) {
int res = mPolicy.checkAddPermission(attrs);
- if (res != WindowManagerImpl.ADD_OKAY) {
+ if (res != WindowManagerGlobal.ADD_OKAY) {
return res;
}
@@ -2157,7 +2157,7 @@ public class WindowManagerService extends IWindowManager.Stub
if (mWindowMap.containsKey(client.asBinder())) {
Slog.w(TAG, "Window " + client + " is already added");
- return WindowManagerImpl.ADD_DUPLICATE_ADD;
+ return WindowManagerGlobal.ADD_DUPLICATE_ADD;
}
if (attrs.type >= FIRST_SUB_WINDOW && attrs.type <= LAST_SUB_WINDOW) {
@@ -2165,13 +2165,13 @@ public class WindowManagerService extends IWindowManager.Stub
if (attachedWindow == null) {
Slog.w(TAG, "Attempted to add window with token that is not a window: "
+ attrs.token + ". Aborting.");
- return WindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN;
+ return WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN;
}
if (attachedWindow.mAttrs.type >= FIRST_SUB_WINDOW
&& attachedWindow.mAttrs.type <= LAST_SUB_WINDOW) {
Slog.w(TAG, "Attempted to add window with token that is a sub-window: "
+ attrs.token + ". Aborting.");
- return WindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN;
+ return WindowManagerGlobal.ADD_BAD_SUBWINDOW_TOKEN;
}
}
@@ -2182,22 +2182,22 @@ public class WindowManagerService extends IWindowManager.Stub
&& attrs.type <= LAST_APPLICATION_WINDOW) {
Slog.w(TAG, "Attempted to add application window with unknown token "
+ attrs.token + ". Aborting.");
- return WindowManagerImpl.ADD_BAD_APP_TOKEN;
+ return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
if (attrs.type == TYPE_INPUT_METHOD) {
Slog.w(TAG, "Attempted to add input method window with unknown token "
+ attrs.token + ". Aborting.");
- return WindowManagerImpl.ADD_BAD_APP_TOKEN;
+ return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
if (attrs.type == TYPE_WALLPAPER) {
Slog.w(TAG, "Attempted to add wallpaper window with unknown token "
+ attrs.token + ". Aborting.");
- return WindowManagerImpl.ADD_BAD_APP_TOKEN;
+ return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
if (attrs.type == TYPE_DREAM) {
Slog.w(TAG, "Attempted to add Dream window with unknown token "
+ attrs.token + ". Aborting.");
- return WindowManagerImpl.ADD_BAD_APP_TOKEN;
+ return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
token = new WindowToken(this, attrs.token, -1, false);
addToken = true;
@@ -2207,35 +2207,35 @@ public class WindowManagerService extends IWindowManager.Stub
if (atoken == null) {
Slog.w(TAG, "Attempted to add window with non-application token "
+ token + ". Aborting.");
- return WindowManagerImpl.ADD_NOT_APP_TOKEN;
+ return WindowManagerGlobal.ADD_NOT_APP_TOKEN;
} else if (atoken.removed) {
Slog.w(TAG, "Attempted to add window with exiting application token "
+ token + ". Aborting.");
- return WindowManagerImpl.ADD_APP_EXITING;
+ return WindowManagerGlobal.ADD_APP_EXITING;
}
if (attrs.type == TYPE_APPLICATION_STARTING && atoken.firstWindowDrawn) {
// No need for this guy!
if (localLOGV) Slog.v(
TAG, "**** NO NEED TO START: " + attrs.getTitle());
- return WindowManagerImpl.ADD_STARTING_NOT_NEEDED;
+ return WindowManagerGlobal.ADD_STARTING_NOT_NEEDED;
}
} else if (attrs.type == TYPE_INPUT_METHOD) {
if (token.windowType != TYPE_INPUT_METHOD) {
Slog.w(TAG, "Attempted to add input method window with bad token "
+ attrs.token + ". Aborting.");
- return WindowManagerImpl.ADD_BAD_APP_TOKEN;
+ return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
} else if (attrs.type == TYPE_WALLPAPER) {
if (token.windowType != TYPE_WALLPAPER) {
Slog.w(TAG, "Attempted to add wallpaper window with bad token "
+ attrs.token + ". Aborting.");
- return WindowManagerImpl.ADD_BAD_APP_TOKEN;
+ return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
} else if (attrs.type == TYPE_DREAM) {
if (token.windowType != TYPE_DREAM) {
Slog.w(TAG, "Attempted to add Dream window with bad token "
+ attrs.token + ". Aborting.");
- return WindowManagerImpl.ADD_BAD_APP_TOKEN;
+ return WindowManagerGlobal.ADD_BAD_APP_TOKEN;
}
}
@@ -2247,13 +2247,13 @@ public class WindowManagerService extends IWindowManager.Stub
// continue.
Slog.w(TAG, "Adding window client " + client.asBinder()
+ " that is dead, aborting.");
- return WindowManagerImpl.ADD_APP_EXITING;
+ return WindowManagerGlobal.ADD_APP_EXITING;
}
mPolicy.adjustWindowParamsLw(win.mAttrs);
res = mPolicy.prepareAddWindowLw(win, attrs);
- if (res != WindowManagerImpl.ADD_OKAY) {
+ if (res != WindowManagerGlobal.ADD_OKAY) {
return res;
}
@@ -2269,7 +2269,7 @@ public class WindowManagerService extends IWindowManager.Stub
// From now on, no exceptions or errors allowed!
- res = WindowManagerImpl.ADD_OKAY;
+ res = WindowManagerGlobal.ADD_OKAY;
origId = Binder.clearCallingIdentity();
@@ -2313,10 +2313,10 @@ public class WindowManagerService extends IWindowManager.Stub
mPolicy.getContentInsetHintLw(attrs, outContentInsets);
if (mInTouchMode) {
- res |= WindowManagerImpl.ADD_FLAG_IN_TOUCH_MODE;
+ res |= WindowManagerGlobal.ADD_FLAG_IN_TOUCH_MODE;
}
if (win.mAppToken == null || !win.mAppToken.clientHidden) {
- res |= WindowManagerImpl.ADD_FLAG_APP_VISIBLE;
+ res |= WindowManagerGlobal.ADD_FLAG_APP_VISIBLE;
}
mInputMonitor.setUpdateInputWindowsNeededLw();
@@ -2748,7 +2748,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
winAnimator.mSurfaceDestroyDeferred =
- (flags&WindowManagerImpl.RELAYOUT_DEFER_SURFACE_DESTROY) != 0;
+ (flags&WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY) != 0;
int attrChanges = 0;
int flagChanges = 0;
@@ -2967,7 +2967,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
mLayoutNeeded = true;
- win.mGivenInsetsPending = (flags&WindowManagerImpl.RELAYOUT_INSETS_PENDING) != 0;
+ win.mGivenInsetsPending = (flags&WindowManagerGlobal.RELAYOUT_INSETS_PENDING) != 0;
if (assignLayers) {
assignLayersLocked(win.getWindowList());
}
@@ -3010,10 +3010,10 @@ public class WindowManagerService extends IWindowManager.Stub
Binder.restoreCallingIdentity(origId);
- return (inTouchMode ? WindowManagerImpl.RELAYOUT_RES_IN_TOUCH_MODE : 0)
- | (toBeDisplayed ? WindowManagerImpl.RELAYOUT_RES_FIRST_TIME : 0)
- | (surfaceChanged ? WindowManagerImpl.RELAYOUT_RES_SURFACE_CHANGED : 0)
- | (animating ? WindowManagerImpl.RELAYOUT_RES_ANIMATING : 0);
+ return (inTouchMode ? WindowManagerGlobal.RELAYOUT_RES_IN_TOUCH_MODE : 0)
+ | (toBeDisplayed ? WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME : 0)
+ | (surfaceChanged ? WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED : 0)
+ | (animating ? WindowManagerGlobal.RELAYOUT_RES_ANIMATING : 0);
}
public void performDeferredDestroyWindow(Session session, IWindow client) {
@@ -5257,14 +5257,14 @@ public class WindowManagerService extends IWindowManager.Stub
// Called by window manager policy. Not exposed externally.
@Override
- public void shutdown() {
- ShutdownThread.shutdown(mContext, true);
+ public void shutdown(boolean confirm) {
+ ShutdownThread.shutdown(mContext, confirm);
}
// Called by window manager policy. Not exposed externally.
@Override
- public void rebootSafeMode() {
- ShutdownThread.rebootSafeMode(mContext, true);
+ public void rebootSafeMode(boolean confirm) {
+ ShutdownThread.rebootSafeMode(mContext, confirm);
}
public void setInputFilter(IInputFilter filter) {
@@ -8367,15 +8367,23 @@ public class WindowManagerService extends IWindowManager.Stub
NN = mOpeningApps.size();
for (i=0; i<NN; i++) {
AppWindowToken wtoken = mOpeningApps.get(i);
+ final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now opening app" + wtoken);
- wtoken.mAppAnimator.clearThumbnail();
+ appAnimator.clearThumbnail();
wtoken.reportedVisible = false;
wtoken.inPendingTransaction = false;
- wtoken.mAppAnimator.animation = null;
+ appAnimator.animation = null;
setTokenVisibilityLocked(wtoken, animLp, true, transit, false);
wtoken.updateReportedVisibilityLocked();
wtoken.waitingToShow = false;
- mAnimator.mAnimating |= wtoken.mAppAnimator.showAllWindowsLocked();
+
+ appAnimator.mAllAppWinAnimators.clear();
+ final int N = wtoken.allAppWindows.size();
+ for (int j = 0; j < N; j++) {
+ appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
+ }
+ mAnimator.mAnimating |= appAnimator.showAllWindowsLocked();
+
if (animLp != null) {
int layer = -1;
for (int j=0; j<wtoken.windows.size(); j++) {
@@ -9629,7 +9637,7 @@ public class WindowManagerService extends IWindowManager.Stub
// TODO(multidisplay): rotation on main screen only.
DisplayInfo displayInfo = getDefaultDisplayContent().getDisplayInfo();
- mAnimator.mScreenRotationAnimation = new ScreenRotationAnimation(mContext,
+ mAnimator.mScreenRotationAnimation = new ScreenRotationAnimation(mContext, mDisplay,
mFxSession, inTransaction, displayInfo.logicalWidth, displayInfo.logicalHeight,
mDisplay.getRotation());
}
@@ -9742,7 +9750,7 @@ public class WindowManagerService extends IWindowManager.Stub
if (line != null) {
String[] toks = line.split("%");
if (toks != null && toks.length > 0) {
- mWatermark = new Watermark(mRealDisplayMetrics, mFxSession, toks);
+ mWatermark = new Watermark(mDisplay, mRealDisplayMetrics, mFxSession, toks);
}
}
} catch (FileNotFoundException e) {
diff --git a/services/java/com/android/server/wm/WindowStateAnimator.java b/services/java/com/android/server/wm/WindowStateAnimator.java
index d931426..899610f 100644
--- a/services/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/java/com/android/server/wm/WindowStateAnimator.java
@@ -474,24 +474,14 @@ class WindowStateAnimator {
private final Point mSize = new Point();
private final Rect mWindowCrop = new Rect();
private boolean mShown = false;
- private int mDisplayId;
- private String mName = "Not named";
+ private int mLayerStack;
+ private String mName;
public SurfaceTrace(SurfaceSession s,
- int pid, int displayId, int w, int h, int format, int flags) throws
- OutOfResourcesException {
- super(s, pid, displayId, w, h, format, flags);
- mSize.set(w, h);
- mDisplayId = displayId;
- Slog.v(SURFACE_TAG, "ctor: " + this + ". Called by "
- + Debug.getCallers(3));
- }
-
- public SurfaceTrace(SurfaceSession s,
- int pid, String name, int displayId, int w, int h, int format, int flags)
+ int pid, String name, int layerStack, int w, int h, int format, int flags)
throws OutOfResourcesException {
- super(s, pid, name, displayId, w, h, format, flags);
- mName = name;
+ super(s, pid, name, layerStack, w, h, format, flags);
+ mName = name != null ? name : "Not named";
mSize.set(w, h);
Slog.v(SURFACE_TAG, "ctor: " + this + ". Called by "
+ Debug.getCallers(3));
@@ -550,10 +540,10 @@ class WindowStateAnimator {
}
@Override
- public void setDisplayId(int displayId) {
- super.setDisplayId(displayId);
- mDisplayId = displayId;
- Slog.v(SURFACE_TAG, "setDisplayId: " + this + ". Called by " + Debug.getCallers(3));
+ public void setLayerStack(int layerStack) {
+ super.setLayerStack(layerStack);
+ mLayerStack = layerStack;
+ Slog.v(SURFACE_TAG, "setLayerStack: " + this + ". Called by " + Debug.getCallers(3));
}
@Override
@@ -597,7 +587,7 @@ class WindowStateAnimator {
@Override
public String toString() {
return "Surface " + Integer.toHexString(System.identityHashCode(this)) + " "
- + mName + " (" + mDisplayId + "): shown=" + mShown + " layer=" + mLayer
+ + mName + " (" + mLayerStack + "): shown=" + mShown + " layer=" + mLayer
+ " alpha=" + mSurfaceTraceAlpha + " " + mPosition.x + "," + mPosition.y
+ " " + mSize.x + "x" + mSize.y
+ " crop=" + mWindowCrop.toShortString();
diff --git a/services/jni/com_android_server_BatteryService.cpp b/services/jni/com_android_server_BatteryService.cpp
index ca6f206..8ebc6ea 100644
--- a/services/jni/com_android_server_BatteryService.cpp
+++ b/services/jni/com_android_server_BatteryService.cpp
@@ -42,6 +42,7 @@ struct FieldIds {
// members
jfieldID mAcOnline;
jfieldID mUsbOnline;
+ jfieldID mWirelessOnline;
jfieldID mBatteryStatus;
jfieldID mBatteryHealth;
jfieldID mBatteryPresent;
@@ -71,6 +72,7 @@ static BatteryManagerConstants gConstants;
struct PowerSupplyPaths {
char* acOnlinePath;
char* usbOnlinePath;
+ char* wirelessOnlinePath;
char* batteryStatusPath;
char* batteryHealthPath;
char* batteryPresentPath;
@@ -198,6 +200,7 @@ static void android_server_BatteryService_update(JNIEnv* env, jobject obj)
{
setBooleanField(env, obj, gPaths.acOnlinePath, gFieldIds.mAcOnline);
setBooleanField(env, obj, gPaths.usbOnlinePath, gFieldIds.mUsbOnline);
+ setBooleanField(env, obj, gPaths.wirelessOnlinePath, gFieldIds.mWirelessOnline);
setBooleanField(env, obj, gPaths.batteryPresentPath, gFieldIds.mBatteryPresent);
setIntField(env, obj, gPaths.batteryCapacityPath, gFieldIds.mBatteryLevel);
@@ -260,6 +263,11 @@ int register_android_server_BatteryService(JNIEnv* env)
if (access(path, R_OK) == 0)
gPaths.usbOnlinePath = strdup(path);
}
+ else if (strcmp(buf, "Wireless") == 0) {
+ snprintf(path, sizeof(path), "%s/%s/online", POWER_SUPPLY_PATH, name);
+ if (access(path, R_OK) == 0)
+ gPaths.wirelessOnlinePath = strdup(path);
+ }
else if (strcmp(buf, "Battery") == 0) {
snprintf(path, sizeof(path), "%s/%s/status", POWER_SUPPLY_PATH, name);
if (access(path, R_OK) == 0)
@@ -307,6 +315,8 @@ int register_android_server_BatteryService(JNIEnv* env)
ALOGE("acOnlinePath not found");
if (!gPaths.usbOnlinePath)
ALOGE("usbOnlinePath not found");
+ if (!gPaths.wirelessOnlinePath)
+ ALOGE("wirelessOnlinePath not found");
if (!gPaths.batteryStatusPath)
ALOGE("batteryStatusPath not found");
if (!gPaths.batteryHealthPath)
@@ -331,6 +341,7 @@ int register_android_server_BatteryService(JNIEnv* env)
gFieldIds.mAcOnline = env->GetFieldID(clazz, "mAcOnline", "Z");
gFieldIds.mUsbOnline = env->GetFieldID(clazz, "mUsbOnline", "Z");
+ gFieldIds.mWirelessOnline = env->GetFieldID(clazz, "mWirelessOnline", "Z");
gFieldIds.mBatteryStatus = env->GetFieldID(clazz, "mBatteryStatus", "I");
gFieldIds.mBatteryHealth = env->GetFieldID(clazz, "mBatteryHealth", "I");
gFieldIds.mBatteryPresent = env->GetFieldID(clazz, "mBatteryPresent", "Z");
@@ -341,6 +352,7 @@ int register_android_server_BatteryService(JNIEnv* env)
LOG_FATAL_IF(gFieldIds.mAcOnline == NULL, "Unable to find BatteryService.AC_ONLINE_PATH");
LOG_FATAL_IF(gFieldIds.mUsbOnline == NULL, "Unable to find BatteryService.USB_ONLINE_PATH");
+ LOG_FATAL_IF(gFieldIds.mWirelessOnline == NULL, "Unable to find BatteryService.WIRELESS_ONLINE_PATH");
LOG_FATAL_IF(gFieldIds.mBatteryStatus == NULL, "Unable to find BatteryService.BATTERY_STATUS_PATH");
LOG_FATAL_IF(gFieldIds.mBatteryHealth == NULL, "Unable to find BatteryService.BATTERY_HEALTH_PATH");
LOG_FATAL_IF(gFieldIds.mBatteryPresent == NULL, "Unable to find BatteryService.BATTERY_PRESENT_PATH");
diff --git a/services/jni/com_android_server_input_InputManagerService.cpp b/services/jni/com_android_server_input_InputManagerService.cpp
index 701b15a..495d4ab 100644
--- a/services/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/jni/com_android_server_input_InputManagerService.cpp
@@ -63,7 +63,7 @@ static const float POINTER_SPEED_EXPONENT = 1.0f / 4;
static struct {
jmethodID notifyConfigurationChanged;
jmethodID notifyInputDevicesChanged;
- jmethodID notifyLidSwitchChanged;
+ jmethodID notifySwitch;
jmethodID notifyInputChannelBroken;
jmethodID notifyANR;
jmethodID filterInputEvent;
@@ -578,14 +578,9 @@ void NativeInputManager::notifySwitch(nsecs_t when, int32_t switchCode,
JNIEnv* env = jniEnv();
- switch (switchCode) {
- case SW_LID:
- // When switch value is set indicates lid is closed.
- env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifyLidSwitchChanged,
- when, switchValue == 0 /*lidOpen*/);
- checkAndClearExceptionFromCallback(env, "notifyLidSwitchChanged");
- break;
- }
+ env->CallVoidMethod(mServiceObj, gServiceClassInfo.notifySwitch,
+ when, switchCode, switchValue);
+ checkAndClearExceptionFromCallback(env, "notifySwitch");
}
void NativeInputManager::notifyConfigurationChanged(nsecs_t when) {
@@ -1410,8 +1405,8 @@ int register_android_server_InputManager(JNIEnv* env) {
GET_METHOD_ID(gServiceClassInfo.notifyInputDevicesChanged, clazz,
"notifyInputDevicesChanged", "([Landroid/view/InputDevice;)V");
- GET_METHOD_ID(gServiceClassInfo.notifyLidSwitchChanged, clazz,
- "notifyLidSwitchChanged", "(JZ)V");
+ GET_METHOD_ID(gServiceClassInfo.notifySwitch, clazz,
+ "notifySwitch", "(JII)V");
GET_METHOD_ID(gServiceClassInfo.notifyInputChannelBroken, clazz,
"notifyInputChannelBroken", "(Lcom/android/server/input/InputWindowHandle;)V");
diff --git a/test-runner/src/android/test/mock/MockContext.java b/test-runner/src/android/test/mock/MockContext.java
index 02d0b45..12ad4fe 100644
--- a/test-runner/src/android/test/mock/MockContext.java
+++ b/test-runner/src/android/test/mock/MockContext.java
@@ -39,6 +39,7 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.UserHandle;
+import android.view.CompatibilityInfoHolder;
import java.io.File;
import java.io.FileInputStream;
@@ -487,4 +488,10 @@ public class MockContext extends Context {
public boolean isRestricted() {
throw new UnsupportedOperationException();
}
+
+ /** @hide */
+ @Override
+ public CompatibilityInfoHolder getCompatibilityInfo() {
+ throw new UnsupportedOperationException();
+ }
}
diff --git a/test-runner/src/android/test/mock/MockPackageManager.java b/test-runner/src/android/test/mock/MockPackageManager.java
index ef14404..a85c8b5 100644
--- a/test-runner/src/android/test/mock/MockPackageManager.java
+++ b/test-runner/src/android/test/mock/MockPackageManager.java
@@ -39,6 +39,7 @@ import android.content.pm.ProviderInfo;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.pm.UserInfo;
+import android.content.pm.VerificationParams;
import android.content.pm.VerifierDeviceIdentity;
import android.content.res.Resources;
import android.content.res.XmlResourceParser;
@@ -519,6 +520,16 @@ public class MockPackageManager extends PackageManager {
throw new UnsupportedOperationException();
}
+ /**
+ * @hide
+ */
+ @Override
+ public void installPackageWithVerificationAndEncryption(Uri packageURI,
+ IPackageInstallObserver observer, int flags, String installerPackageName,
+ VerificationParams verificationParams, ContainerEncryptionParams encryptionParams) {
+ throw new UnsupportedOperationException();
+ }
+
@Override
public void verifyPendingInstall(int id, int verificationCode) {
throw new UnsupportedOperationException();
diff --git a/tools/layoutlib/bridge/src/android/view/AttachInfo_Accessor.java b/tools/layoutlib/bridge/src/android/view/AttachInfo_Accessor.java
index 97d9969..4901f72 100644
--- a/tools/layoutlib/bridge/src/android/view/AttachInfo_Accessor.java
+++ b/tools/layoutlib/bridge/src/android/view/AttachInfo_Accessor.java
@@ -19,6 +19,7 @@ package android.view;
import com.android.layoutlib.bridge.android.BridgeWindow;
import com.android.layoutlib.bridge.android.BridgeWindowSession;
+import android.content.Context;
import android.os.Handler;
import android.view.View.AttachInfo;
@@ -28,8 +29,12 @@ import android.view.View.AttachInfo;
public class AttachInfo_Accessor {
public static void setAttachInfo(View view) {
+ Context context = view.getContext();
+ WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
+ Display display = wm.getDefaultDisplay();
+ ViewRootImpl root = new ViewRootImpl(context, display);
AttachInfo info = new AttachInfo(new BridgeWindowSession(), new BridgeWindow(),
- new ViewRootImpl(view.getContext()), new Handler(), null);
+ display, root, new Handler(), null);
info.mHasWindowFocus = true;
info.mWindowVisibility = View.VISIBLE;
info.mInTouchMode = false; // this is so that we can display selections.
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index 943357a..3d45bff 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -66,6 +66,7 @@ import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.BridgeInflater;
+import android.view.CompatibilityInfoHolder;
import android.view.Surface;
import android.view.View;
import android.view.ViewGroup;
@@ -1318,4 +1319,10 @@ public final class BridgeContext extends Context {
Bridge.getLog().error(LayoutLog.TAG_UNSUPPORTED, "OBB not supported", null);
return null;
}
+
+ @Override
+ public CompatibilityInfoHolder getCompatibilityInfo() {
+ // pass
+ return null;
+ }
}
diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java
index 32261de..3e20756 100644
--- a/wifi/java/android/net/wifi/ScanResult.java
+++ b/wifi/java/android/net/wifi/ScanResult.java
@@ -47,19 +47,37 @@ public class ScanResult implements Parcelable {
public int frequency;
/**
+ * Time Synchronization Function (tsf) timestamp in microseconds when
+ * this result was last seen.
+ */
+ public long timestamp;
+
+ /**
* We'd like to obtain the following attributes,
* but they are not reported via the socket
* interface, even though they are known
* internally by wpa_supplicant.
* {@hide}
*/
- public ScanResult(String SSID, String BSSID, String caps, int level, int frequency) {
+ public ScanResult(String SSID, String BSSID, String caps, int level, int frequency, long tsf) {
this.SSID = SSID;
this.BSSID = BSSID;
this.capabilities = caps;
this.level = level;
this.frequency = frequency;
- //networkConfig = null;
+ this.timestamp = tsf;
+ }
+
+ /** copy constructor {@hide} */
+ public ScanResult(ScanResult source) {
+ if (source != null) {
+ SSID = source.SSID;
+ BSSID = source.BSSID;
+ capabilities = source.capabilities;
+ level = source.level;
+ frequency = source.frequency;
+ timestamp = source.timestamp;
+ }
}
@Override
@@ -76,7 +94,9 @@ public class ScanResult implements Parcelable {
append(", level: ").
append(level).
append(", frequency: ").
- append(frequency);
+ append(frequency).
+ append(", timestamp: ").
+ append(timestamp);
return sb.toString();
}
@@ -93,6 +113,7 @@ public class ScanResult implements Parcelable {
dest.writeString(capabilities);
dest.writeInt(level);
dest.writeInt(frequency);
+ dest.writeLong(timestamp);
}
/** Implement the Parcelable interface {@hide} */
@@ -104,7 +125,8 @@ public class ScanResult implements Parcelable {
in.readString(),
in.readString(),
in.readInt(),
- in.readInt()
+ in.readInt(),
+ in.readLong()
);
}
diff --git a/wifi/java/android/net/wifi/WifiNative.java b/wifi/java/android/net/wifi/WifiNative.java
index 84c565b..1b7e378 100644
--- a/wifi/java/android/net/wifi/WifiNative.java
+++ b/wifi/java/android/net/wifi/WifiNative.java
@@ -197,8 +197,22 @@ public class WifiNative {
return null;
}
+ /**
+ * Format of results:
+ * =================
+ * bssid=68:7f:74:d7:1b:6e
+ * freq=2412
+ * level=-43
+ * tsf=1344621975160944
+ * age=2623
+ * flags=[WPA2-PSK-CCMP][WPS][ESS]
+ * ssid=zubyb
+ *
+ * RANGE=ALL gets all scan results
+ * MASK=<N> see wpa_supplicant/src/common/wpa_ctrl.h for details
+ */
public String scanResults() {
- return doStringCommand("SCAN_RESULTS");
+ return doStringCommand("BSS RANGE=ALL MASK=0x1986");
}
public boolean startDriver() {
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 6abca65..9f506aa 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -891,7 +891,13 @@ public class WifiStateMachine extends StateMachine {
* TODO: doc
*/
public List<ScanResult> syncGetScanResultsList() {
- return mScanResults;
+ synchronized (mScanResultCache) {
+ List<ScanResult> scanList = new ArrayList<ScanResult>();
+ for(ScanResult result: mScanResults) {
+ scanList.add(new ScanResult(result));
+ }
+ return scanList;
+ }
}
/**
@@ -1357,131 +1363,103 @@ public class WifiStateMachine extends StateMachine {
mContext.sendStickyBroadcast(intent);
}
+ private static final String BSSID_STR = "bssid=";
+ private static final String FREQ_STR = "freq=";
+ private static final String LEVEL_STR = "level=";
+ private static final String TSF_STR = "tsf=";
+ private static final String FLAGS_STR = "flags=";
+ private static final String SSID_STR = "ssid=";
+ private static final String DELIMITER_STR = "====";
/**
- * Parse the scan result line passed to us by wpa_supplicant (helper).
- * @param line the line to parse
- * @return the {@link ScanResult} object
+ * Format:
+ * bssid=68:7f:76:d7:1a:6e
+ * freq=2412
+ * level=-44
+ * tsf=1344626243700342
+ * flags=[WPA2-PSK-CCMP][WPS][ESS]
+ * ssid=zfdy
+ * ====
+ * bssid=68:5f:74:d7:1a:6f
+ * freq=5180
+ * level=-73
+ * tsf=1344626243700373
+ * flags=[WPA2-PSK-CCMP][WPS][ESS]
+ * ssid=zuby
+ * ====
*/
- private ScanResult parseScanResult(String line) {
- ScanResult scanResult = null;
- if (line != null) {
- /*
- * Cache implementation (LinkedHashMap) is not synchronized, thus,
- * must synchronized here!
- */
- synchronized (mScanResultCache) {
- String[] result = scanResultPattern.split(line);
- if (3 <= result.length && result.length <= 5) {
- String bssid = result[0];
- // bssid | frequency | level | flags | ssid
- int frequency;
- int level;
+ private void setScanResults(String scanResults) {
+ String bssid = "";
+ int level = 0;
+ int freq = 0;
+ long tsf = 0;
+ String flags = "";
+ String ssid = "";
+
+ if (scanResults == null) {
+ return;
+ }
+
+ synchronized(mScanResultCache) {
+ mScanResults = new ArrayList<ScanResult>();
+ String[] lines = scanResults.split("\n");
+
+ for (String line : lines) {
+ if (line.startsWith(BSSID_STR)) {
+ bssid = line.substring(BSSID_STR.length());
+ } else if (line.startsWith(FREQ_STR)) {
try {
- frequency = Integer.parseInt(result[1]);
- level = Integer.parseInt(result[2]);
+ freq = Integer.parseInt(line.substring(FREQ_STR.length()));
+ } catch (NumberFormatException e) {
+ freq = 0;
+ }
+ } else if (line.startsWith(LEVEL_STR)) {
+ try {
+ level = Integer.parseInt(line.substring(LEVEL_STR.length()));
/* some implementations avoid negative values by adding 256
* so we need to adjust for that here.
*/
if (level > 0) level -= 256;
- } catch (NumberFormatException e) {
- frequency = 0;
+ } catch(NumberFormatException e) {
level = 0;
}
-
- /*
- * The formatting of the results returned by
- * wpa_supplicant is intended to make the fields
- * line up nicely when printed,
- * not to make them easy to parse. So we have to
- * apply some heuristics to figure out which field
- * is the SSID and which field is the flags.
- */
- String ssid;
- String flags;
- if (result.length == 4) {
- if (result[3].charAt(0) == '[') {
- flags = result[3];
- ssid = "";
+ } else if (line.startsWith(TSF_STR)) {
+ try {
+ tsf = Long.parseLong(line.substring(TSF_STR.length()));
+ } catch (NumberFormatException e) {
+ tsf = 0;
+ }
+ } else if (line.startsWith(FLAGS_STR)) {
+ flags = line.substring(FLAGS_STR.length());
+ } else if (line.startsWith(SSID_STR)) {
+ ssid = line.substring(SSID_STR.length());
+ if (ssid == null) ssid = "";
+ } else if (line.startsWith(DELIMITER_STR)) {
+ if (bssid != null) {
+ String key = bssid + ssid;
+ ScanResult scanResult = mScanResultCache.get(key);
+ if (scanResult != null) {
+ scanResult.level = level;
+ scanResult.SSID = ssid;
+ scanResult.capabilities = flags;
+ scanResult.frequency = freq;
+ scanResult.timestamp = tsf;
} else {
- flags = "";
- ssid = result[3];
- }
- } else if (result.length == 5) {
- flags = result[3];
- ssid = result[4];
- } else {
- // Here, we must have 3 fields: no flags and ssid
- // set
- flags = "";
- ssid = "";
- }
-
- // bssid + ssid is the hash key
- String key = bssid + ssid;
- scanResult = mScanResultCache.get(key);
- if (scanResult != null) {
- scanResult.level = level;
- scanResult.SSID = ssid;
- scanResult.capabilities = flags;
- scanResult.frequency = frequency;
- } else {
- // Do not add scan results that have no SSID set
- if (0 < ssid.trim().length()) {
scanResult =
new ScanResult(
- ssid, bssid, flags, level, frequency);
+ ssid, bssid, flags, level, freq, tsf);
mScanResultCache.put(key, scanResult);
}
- }
- } else {
- loge("Misformatted scan result text with " +
- result.length + " fields: " + line);
- }
- }
- }
-
- return scanResult;
- }
-
- /**
- * scanResults input format
- * 00:bb:cc:dd:cc:ee 2427 166 [WPA-EAP-TKIP][WPA2-EAP-CCMP] Net1
- * 00:bb:cc:dd:cc:ff 2412 165 [WPA-EAP-TKIP][WPA2-EAP-CCMP] Net2
- */
- private void setScanResults(String scanResults) {
- if (scanResults == null) {
- return;
- }
-
- List<ScanResult> scanList = new ArrayList<ScanResult>();
-
- int lineCount = 0;
-
- int scanResultsLen = scanResults.length();
- // Parse the result string, keeping in mind that the last line does
- // not end with a newline.
- for (int lineBeg = 0, lineEnd = 0; lineEnd <= scanResultsLen; ++lineEnd) {
- if (lineEnd == scanResultsLen || scanResults.charAt(lineEnd) == '\n') {
- ++lineCount;
-
- if (lineCount == 1) {
- lineBeg = lineEnd + 1;
- continue;
+ mScanResults.add(scanResult);
+ }
+ bssid = null;
+ level = 0;
+ freq = 0;
+ tsf = 0;
+ flags = "";
+ ssid = "";
}
- if (lineEnd > lineBeg) {
- String line = scanResults.substring(lineBeg, lineEnd);
- ScanResult scanResult = parseScanResult(line);
- if (scanResult != null) {
- scanList.add(scanResult);
- } else {
- //TODO: hidden network handling
- }
- }
- lineBeg = lineEnd + 1;
}
}
-
- mScanResults = scanList;
}
/*
@@ -2828,7 +2806,7 @@ public class WifiStateMachine extends StateMachine {
if (DBG) log(getName() + "\n");
mIsRunning = false;
updateBatteryWorkSource(null);
- mScanResults = null;
+ mScanResults = new ArrayList<ScanResult>();
if (mP2pSupported) mWifiP2pChannel.sendMessage(WifiStateMachine.CMD_DISABLE_P2P);
mContext.unregisterReceiver(mScreenReceiver);