From f8c9c95154d688b272ad7161a8593f6f3c33a4b7 Mon Sep 17 00:00:00 2001
From: Yamil Ghazi
Date: Tue, 19 Feb 2013 06:26:23 +0100
Subject: [PATCH 01/14] PA's hybrid engine
Change-Id: I1aef85f92c67019045d0fd3322a0b529168d9d9f
---
core/java/android/app/ActivityThread.java | 7 +
.../android/app/ApplicationThreadNative.java | 1 -
core/java/android/app/ContextImpl.java | 89 ++++
core/java/android/app/IApplicationThread.java | 1 -
.../android/app/IInstrumentationWatcher.aidl | 1 -
core/java/android/app/ResultInfo.java | 3 -
.../java/android/content/IIntentReceiver.aidl | 1 -
core/java/android/content/IIntentSender.aidl | 1 -
.../android/content/res/AssetManager.java | 3 +-
.../content/res/CompatibilityInfo.java | 2 -
.../android/content/res/Configuration.java | 33 +-
core/java/android/content/res/Resources.java | 22 +-
core/java/android/util/DisplayMetrics.java | 35 +-
.../android/util/ExtendedPropertiesUtils.java | 478 ++++++++++++++++++
.../android/view/CompatibilityInfoHolder.java | 1 -
core/java/android/view/DisplayInfo.java | 2 +
core/jni/Android.mk | 1 +
core/jni/AndroidRuntime.cpp | 2 +
.../android_util_ExtendedPropertiesUtils.cpp | 72 +++
...tus_bar_latest_event_ticker_large_icon.xml | 15 +-
core/res/res/values-sw600dp/dimens.xml | 8 +-
core/res/res/values-sw720dp/dimens.xml | 17 +-
core/res/res/values/dimens.xml | 4 +-
graphics/java/android/graphics/Bitmap.java | 5 +-
.../android/graphics/drawable/Drawable.java | 2 +-
.../SystemUI/res/values-sw600dp/config.xml | 8 +
.../SystemUI/res/values-sw600dp/dimens.xml | 4 -
.../SystemUI/res/values-sw720dp/config.xml | 6 +-
packages/SystemUI/res/values/dimens.xml | 4 +-
.../systemui/recent/RecentsPanelView.java | 15 +-
.../policy/impl/PhoneWindowManager.java | 102 ++--
preloaded-classes | 1 +
.../com/android/server/am/ActivityStack.java | 9 +-
33 files changed, 831 insertions(+), 124 deletions(-)
create mode 100644 core/java/android/util/ExtendedPropertiesUtils.java
create mode 100644 core/jni/android_util_ExtendedPropertiesUtils.cpp
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 41aad8152c6..1719f5c1286 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -79,6 +79,7 @@
import android.util.AndroidRuntimeException;
import android.util.DisplayMetrics;
import android.util.EventLog;
+import android.util.ExtendedPropertiesUtils;
import android.util.Log;
import android.util.LogPrinter;
import android.util.PrintWriterPrinter;
@@ -1712,6 +1713,7 @@ Resources getTopLevelResources(String resDir,
AssetManager assets = new AssetManager();
assets.setThemeSupport(compInfo.isThemeable);
+ assets.overrideHook(resDir, ExtendedPropertiesUtils.OverrideMode.FullNameExclude);
if (assets.addAssetPath(resDir) == 0) {
return null;
}
@@ -1730,6 +1732,7 @@ Resources getTopLevelResources(String resDir,
//Slog.i(TAG, "Resource: key=" + key + ", display metrics=" + metrics);
DisplayMetrics dm = getDisplayMetricsLocked(displayId, null);
+ dm.overrideHook(assets, ExtendedPropertiesUtils.OverrideMode.ExtendedProperties);
Configuration config;
boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
if (!isDefaultDisplay || key.mOverrideConfiguration != null) {
@@ -4301,6 +4304,8 @@ private void updateDefaultDensity() {
private void handleBindApplication(AppBindData data) {
mBoundApplication = data;
mConfiguration = new Configuration(data.config);
+ mConfiguration.active = true;
+ mConfiguration.overrideHook(data.processName, ExtendedPropertiesUtils.OverrideMode.PackageName);
mCompatConfiguration = new Configuration(data.config);
mProfiler = new Profiler();
@@ -5116,6 +5121,7 @@ public static ActivityThread systemMain() {
HardwareRenderer.disable(true);
ActivityThread thread = new ActivityThread();
thread.attach(true);
+ ContextImpl.init(thread);
return thread;
}
@@ -5180,6 +5186,7 @@ public static void main(String[] args) {
ActivityThread thread = new ActivityThread();
thread.attach(false);
+ ContextImpl.init(thread);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java
index 63aa5f9b5f3..0a30808bdab 100644
--- a/core/java/android/app/ApplicationThreadNative.java
+++ b/core/java/android/app/ApplicationThreadNative.java
@@ -40,7 +40,6 @@
import java.util.List;
import java.util.Map;
-/** {@hide} */
public abstract class ApplicationThreadNative extends Binder
implements IApplicationThread {
/**
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 4d9f11e0510..804ea83f890 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -96,6 +96,7 @@
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.SystemVibrator;
import android.os.UserManager;
@@ -103,11 +104,14 @@
import android.telephony.TelephonyManager;
import android.content.ClipboardManager;
import android.util.AndroidRuntimeException;
+import android.util.DisplayMetrics;
+import android.util.ExtendedPropertiesUtils;
import android.util.Log;
import android.util.Slog;
import android.view.CompatibilityInfoHolder;
import android.view.ContextThemeWrapper;
import android.view.Display;
+import android.view.WindowManager;
import android.view.WindowManagerImpl;
import android.view.accessibility.AccessibilityManager;
import android.view.inputmethod.InputMethodManager;
@@ -1905,6 +1909,89 @@ public ContextImpl(ContextImpl context) {
mDisplay = context.mDisplay;
mOuterContext = this;
}
+
+ static void init(ActivityThread thread) {
+ if (ExtendedPropertiesUtils.mMainThread == null) {
+ try {
+ // If hybrid is not enabled, we cannot block the rest of the proccess,
+ // because it may cause a lot of misbehaviours, and avoiding initialization
+ // of vital variables used on ExtendedPropertiesUtils, may lead to crashes.
+ // Then we just set all applications to stock configuration. They will be
+ // still runned under hybrid engine.
+ if (ExtendedPropertiesUtils.getProperty(ExtendedPropertiesUtils.BEERBONG_PREFIX
+ + "hybrid_mode").equals("1")) {
+ ExtendedPropertiesUtils.sIsHybridModeEnabled = true;
+ }
+
+ // Save current thread into global context
+ ExtendedPropertiesUtils.mMainThread = thread;
+
+ // Load hashmap, in order to get latest properties
+ ExtendedPropertiesUtils.refreshProperties();
+
+ // Try to get the context for the current thread. If something
+ // goes wrong, we throw an exception.
+ ContextImpl context = createSystemContext(thread);
+ if (context == null) {
+ throw new NullPointerException();
+ }
+
+ // If we sucessfully created the context, bind it to framework
+ LoadedApk info = new LoadedApk(thread, "android", context, null,
+ CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO);
+ if (info == null) {
+ throw new NullPointerException();
+ }
+
+ context.init(info, null, thread);
+ ExtendedPropertiesUtils.mContext = context;
+
+ // Get default display
+ WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
+ ExtendedPropertiesUtils.mDisplay = wm.getDefaultDisplay();
+ if (ExtendedPropertiesUtils.mDisplay == null) {
+ throw new NullPointerException();
+ }
+
+ // Load package manager, so it's accessible system wide
+ ExtendedPropertiesUtils.mPackageManager =
+ ExtendedPropertiesUtils.mContext.getPackageManager();
+ if (ExtendedPropertiesUtils.mPackageManager == null) {
+ throw new NullPointerException();
+ }
+
+ // Get package list and fetch PID
+ ExtendedPropertiesUtils.mPackageList =
+ ExtendedPropertiesUtils.mPackageManager.getInstalledPackages(0);
+ ExtendedPropertiesUtils.mGlobalHook.pid = android.os.Process.myPid();
+ ExtendedPropertiesUtils.mRomLcdDensity = SystemProperties.getInt("qemu.sf.lcd_density",
+ SystemProperties.getInt("ro.sf.lcd_density", DisplayMetrics.DENSITY_DEFAULT));
+
+ // After we have PID, we get app info using it
+ ExtendedPropertiesUtils.mGlobalHook.info =
+ ExtendedPropertiesUtils.getAppInfoFromPID(ExtendedPropertiesUtils.mGlobalHook.pid);
+ if (ExtendedPropertiesUtils.mGlobalHook.info != null) {
+ // If the global hook info isn't null, we load the name, package name
+ // and path for the global hook
+ ExtendedPropertiesUtils.mGlobalHook.name =
+ ExtendedPropertiesUtils.mGlobalHook.info.packageName;
+ ExtendedPropertiesUtils.mGlobalHook.path =
+ ExtendedPropertiesUtils.mGlobalHook.info.sourceDir.substring(0,
+ ExtendedPropertiesUtils.mGlobalHook.info.sourceDir.lastIndexOf("/"));
+ ExtendedPropertiesUtils.setAppConfiguration(ExtendedPropertiesUtils.mGlobalHook);
+ } else {
+ // We're dealing with "android" package. This is framework itself
+ ExtendedPropertiesUtils.mGlobalHook.name = "android";
+ ExtendedPropertiesUtils.mGlobalHook.path = "";
+ ExtendedPropertiesUtils.setAppConfiguration(ExtendedPropertiesUtils.mGlobalHook);
+ }
+ } catch (Exception e) {
+ // We use global exception to catch a lot of possible crashes.
+ // This is not a dirty workaround, but an expected behaviour
+ ExtendedPropertiesUtils.mMainThread = null;
+ }
+ }
+ }
final void init(LoadedApk packageInfo, IBinder activityToken, ActivityThread mainThread) {
init(packageInfo, activityToken, mainThread, null, null, Process.myUserHandle());
@@ -1912,6 +1999,7 @@ final void init(LoadedApk packageInfo, IBinder activityToken, ActivityThread mai
final void init(LoadedApk packageInfo, IBinder activityToken, ActivityThread mainThread,
Resources container, String basePackageName, UserHandle user) {
+ init(mainThread);
mPackageInfo = packageInfo;
mBasePackageName = basePackageName != null ? basePackageName : packageInfo.mPackageName;
mResources = mPackageInfo.getResources(mainThread);
@@ -1934,6 +2022,7 @@ final void init(LoadedApk packageInfo, IBinder activityToken, ActivityThread mai
}
final void init(Resources resources, ActivityThread mainThread, UserHandle user) {
+ init(mainThread);
mPackageInfo = null;
mBasePackageName = null;
mResources = resources;
diff --git a/core/java/android/app/IApplicationThread.java b/core/java/android/app/IApplicationThread.java
index 03a26d4274c..b4e37152d3b 100644
--- a/core/java/android/app/IApplicationThread.java
+++ b/core/java/android/app/IApplicationThread.java
@@ -41,7 +41,6 @@
* the activity manager by an application when it starts up, for the activity
* manager to tell the application about things it needs to do.
*
- * {@hide}
*/
public interface IApplicationThread extends IInterface {
void schedulePauseActivity(IBinder token, boolean finished, boolean userLeaving,
diff --git a/core/java/android/app/IInstrumentationWatcher.aidl b/core/java/android/app/IInstrumentationWatcher.aidl
index 6c8c4d6e03e..854442115c8 100644
--- a/core/java/android/app/IInstrumentationWatcher.aidl
+++ b/core/java/android/app/IInstrumentationWatcher.aidl
@@ -20,7 +20,6 @@ package android.app;
import android.content.ComponentName;
import android.os.Bundle;
-/** @hide */
interface IInstrumentationWatcher
{
void instrumentationStatus(in ComponentName name, int resultCode,
diff --git a/core/java/android/app/ResultInfo.java b/core/java/android/app/ResultInfo.java
index 48a0fc2810c..b0aeac15965 100644
--- a/core/java/android/app/ResultInfo.java
+++ b/core/java/android/app/ResultInfo.java
@@ -24,9 +24,6 @@
import java.util.Map;
-/**
- * {@hide}
- */
public class ResultInfo implements Parcelable {
public final String mResultWho;
public final int mRequestCode;
diff --git a/core/java/android/content/IIntentReceiver.aidl b/core/java/android/content/IIntentReceiver.aidl
index 3d9272388e0..93cebf44c07 100755
--- a/core/java/android/content/IIntentReceiver.aidl
+++ b/core/java/android/content/IIntentReceiver.aidl
@@ -24,7 +24,6 @@ import android.os.Bundle;
* activity manager as part of registering for an intent broadcasts, and is
* called when it receives intents.
*
- * {@hide}
*/
oneway interface IIntentReceiver {
void performReceive(in Intent intent, int resultCode, String data,
diff --git a/core/java/android/content/IIntentSender.aidl b/core/java/android/content/IIntentSender.aidl
index 7dbd6f2ab92..223f434ba8b 100644
--- a/core/java/android/content/IIntentSender.aidl
+++ b/core/java/android/content/IIntentSender.aidl
@@ -19,7 +19,6 @@ package android.content;
import android.content.IIntentReceiver;
import android.content.Intent;
-/** @hide */
interface IIntentSender {
int send(int code, in Intent intent, String resolvedType,
IIntentReceiver finishedReceiver, String requiredPermission);
diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java
index 80d09466af1..44919cc35ed 100644
--- a/core/java/android/content/res/AssetManager.java
+++ b/core/java/android/content/res/AssetManager.java
@@ -18,6 +18,7 @@
package android.content.res;
import android.os.ParcelFileDescriptor;
+import android.util.ExtendedPropertiesUtils;
import android.util.Log;
import android.util.SparseArray;
import android.util.TypedValue;
@@ -34,7 +35,7 @@
* files that have been bundled with the application as a simple stream of
* bytes.
*/
-public final class AssetManager {
+public final class AssetManager extends ExtendedPropertiesUtils {
/* modes used when opening an asset */
/**
diff --git a/core/java/android/content/res/CompatibilityInfo.java b/core/java/android/content/res/CompatibilityInfo.java
index 789d25e914c..1be2fd2e854 100644
--- a/core/java/android/content/res/CompatibilityInfo.java
+++ b/core/java/android/content/res/CompatibilityInfo.java
@@ -32,7 +32,6 @@
* CompatibilityInfo class keeps the information about compatibility mode that the application is
* running under.
*
- * {@hide}
*/
public class CompatibilityInfo implements Parcelable {
/** default compatibility info object for compatible applications */
@@ -292,7 +291,6 @@ public Translator getTranslator() {
/**
* A helper object to translate the screen and window coordinates back and forth.
- * @hide
*/
public class Translator {
final public float applicationScale;
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
index b6aeab09a0f..1f9db20c859 100644
--- a/core/java/android/content/res/Configuration.java
+++ b/core/java/android/content/res/Configuration.java
@@ -18,10 +18,13 @@
package android.content.res;
import android.content.pm.ActivityInfo;
+import android.graphics.Point;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
+import android.view.Surface;
import android.view.View;
+import android.util.ExtendedPropertiesUtils;
import android.util.Log;
import android.os.SystemProperties;
import android.text.TextUtils;
@@ -38,7 +41,7 @@
* with {@link android.app.Activity#getResources}:
* Configuration config = getResources().getConfiguration();
*/
-public final class Configuration implements Parcelable, Comparable {
+public final class Configuration extends ExtendedPropertiesUtils implements Parcelable, Comparable {
/** @hide */
public static final Configuration EMPTY = new Configuration();
@@ -568,6 +571,33 @@ public boolean isLayoutSizeAtLeast(int size) {
*/
public int seq;
+ public boolean active;
+
+ /**
+ * Process layout changes for current hook
+ */
+ public void paranoidHook() {
+ if (active) {
+
+ int dpi = getDpi(), layout = 600;
+ if (dpi <= 213) {
+ layout = 720;
+ } else if (layout > 213) {
+ layout = 360;
+ }
+ if (mDisplay == null) return;
+ Point size = new Point();
+ mDisplay.getSize(size);
+ float factor = (float)Math.max(size.x, size.y) / (float)Math.min(size.x, size.y);
+ screenWidthDp = layout;
+ screenHeightDp = (int)(screenWidthDp * factor);
+ smallestScreenWidthDp = layout;
+ compatScreenWidthDp = screenWidthDp;
+ compatScreenHeightDp = screenHeightDp;
+ compatSmallestScreenWidthDp = smallestScreenWidthDp;
+ }
+ }
+
/**
* Construct an invalid Configuration. You must call {@link #setToDefaults}
* for this object to be valid. {@more}
@@ -608,6 +638,7 @@ public void setTo(Configuration o) {
compatScreenHeightDp = o.compatScreenHeightDp;
compatSmallestScreenWidthDp = o.compatSmallestScreenWidthDp;
seq = o.seq;
+ paranoidHook();
if (o.customTheme != null) {
customTheme = (CustomTheme) o.customTheme.clone();
}
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index 50721336619..d2110810819 100755
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -30,6 +30,7 @@
import android.os.Bundle;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
+import android.util.ExtendedPropertiesUtils;
import android.util.Log;
import android.util.Slog;
import android.util.TypedValue;
@@ -67,7 +68,7 @@
* For more information about using resources, see the documentation about Application Resources.
*/
-public class Resources {
+public class Resources extends ExtendedPropertiesUtils {
static final String TAG = "Resources";
private static final boolean DEBUG_LOAD = false;
private static final boolean DEBUG_CONFIG = false;
@@ -118,6 +119,22 @@ public class Resources {
private CompatibilityInfo mCompatibilityInfo;
+ /**
+ * Override current object with temp properties stored in enum interface
+ */
+ public void paranoidHook() {
+ mConfiguration.active = true;
+ mConfiguration.overrideHook(this, OverrideMode.ExtendedProperties);
+ mConfiguration.paranoidHook();
+
+ mTmpConfig.active = true;
+ mTmpConfig.overrideHook(this, OverrideMode.ExtendedProperties);
+ mTmpConfig.paranoidHook();
+
+ mMetrics.overrideHook(this, OverrideMode.ExtendedProperties);
+ mMetrics.paranoidHook();
+ }
+
/** @hide */
public static int selectDefaultTheme(int curTheme, int targetSdkVersion) {
return selectSystemTheme(curTheme, targetSdkVersion,
@@ -184,6 +201,8 @@ public Resources(AssetManager assets, DisplayMetrics metrics,
Configuration config, CompatibilityInfo compInfo) {
mAssets = assets;
mMetrics.setToDefaults();
+ overrideHook(assets, OverrideMode.ExtendedProperties);
+ paranoidHook();
mCompatibilityInfo = compInfo;
updateConfiguration(config, metrics);
assets.ensureStringBlocks();
@@ -1464,6 +1483,7 @@ public void updateConfiguration(Configuration config,
if (mConfiguration.densityDpi != Configuration.DENSITY_DPI_UNDEFINED) {
mMetrics.densityDpi = mConfiguration.densityDpi;
mMetrics.density = mConfiguration.densityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE;
+ mMetrics.paranoidHook();
}
mMetrics.scaledDensity = mMetrics.density * mConfiguration.fontScale;
diff --git a/core/java/android/util/DisplayMetrics.java b/core/java/android/util/DisplayMetrics.java
index e856501e54b..bd6787caf7c 100644
--- a/core/java/android/util/DisplayMetrics.java
+++ b/core/java/android/util/DisplayMetrics.java
@@ -26,7 +26,7 @@
* DisplayMetrics metrics = new DisplayMetrics();
* getWindowManager().getDefaultDisplay().getMetrics(metrics);
*/
-public class DisplayMetrics {
+public class DisplayMetrics extends ExtendedPropertiesUtils {
/**
* Standard quantized DPI for low-density screens.
*/
@@ -92,7 +92,12 @@ public class DisplayMetrics {
* density for a display in {@link #densityDpi}.
*/
@Deprecated
- public static int DENSITY_DEVICE = getDeviceDensity();
+ public static int DENSITY_DEVICE;
+
+ static {
+ DENSITY_DEVICE = SystemProperties.getInt("qemu.sf.lcd_density", SystemProperties
+ .getInt("ro.sf.lcd_density", DENSITY_DEFAULT));
+ }
/**
* The absolute width of the display in pixels.
@@ -183,6 +188,21 @@ public class DisplayMetrics {
*/
public float noncompatYdpi;
+ /**
+ * Process DPI for current hook.
+ */
+ public void paranoidHook() {
+ if (getActive()) {
+
+ density = getDensity() == 0 ? density : getDensity();
+ scaledDensity = getScaledDensity() == 0 ? scaledDensity : getScaledDensity();
+ densityDpi = getDpi() == 0 ? densityDpi : getDpi();
+ noncompatDensity = densityDpi;
+ noncompatDensityDpi = densityDpi;
+ noncompatScaledDensity = scaledDensity;
+ }
+ }
+
public DisplayMetrics() {
}
@@ -201,6 +221,7 @@ public void setTo(DisplayMetrics o) {
noncompatScaledDensity = o.noncompatScaledDensity;
noncompatXdpi = o.noncompatXdpi;
noncompatYdpi = o.noncompatYdpi;
+ paranoidHook();
}
public void setToDefaults() {
@@ -273,13 +294,7 @@ public String toString() {
", height=" + heightPixels + ", scaledDensity=" + scaledDensity +
", xdpi=" + xdpi + ", ydpi=" + ydpi + "}";
}
-
- private static int getDeviceDensity() {
- // qemu.sf.lcd_density can be used to override ro.sf.lcd_density
- // when running in the emulator, allowing for dynamic configurations.
- // The reason for this is that ro.sf.lcd_density is write-once and is
- // set by the init process when it parses build.prop before anything else.
- return SystemProperties.getInt("qemu.sf.lcd_density",
- SystemProperties.getInt("ro.sf.lcd_density", DENSITY_DEFAULT));
+ public static int getDeviceDensity() {
+ return mGlobalHook.dpi == 0 ? DENSITY_DEVICE : mGlobalHook.dpi;
}
}
diff --git a/core/java/android/util/ExtendedPropertiesUtils.java b/core/java/android/util/ExtendedPropertiesUtils.java
new file mode 100644
index 00000000000..b4db1ec1521
--- /dev/null
+++ b/core/java/android/util/ExtendedPropertiesUtils.java
@@ -0,0 +1,478 @@
+/*
+ * Copyright (C) 2012 ParanoidAndroid 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.util;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+
+import android.app.ActivityManager;
+import android.app.ActivityThread;
+import android.app.ActivityManager.RunningAppProcessInfo;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.view.Display;
+
+public class ExtendedPropertiesUtils {
+
+ private static final String TAG = "ExtendedPropertiesUtils";
+
+ /**
+ * Public variables
+ */
+ public static final String BEERBONG_MAINCONF = "properties.conf";
+ public static final String BEERBONG_BACKUPCONF = "backup.conf";
+ public static final String BEERBONG_PROPERTIES = "/system/etc/beerbong/" + BEERBONG_MAINCONF;
+ public static final String BEERBONG_DIR = "/system/etc/beerbong/";
+ public static final String BEERBONG_PREFIX = "%";
+ public static final String BEERBONG_SEPARATOR = ".";
+ public static final String BEERBONG_STRING_DELIMITER = "\\|";
+ public static final String BEERBONG_DPI_SUFFIX = ".dpi";
+ public static final String BEERBONG_DENSITY_SUFFIX = ".den";
+ public static final String BEERBONG_SCALEDDENSITY_SUFFIX = ".sden";
+
+ public static HashMap mPropertyMap = new HashMap();
+ public static ActivityThread mMainThread;
+ public static Context mContext;
+ public static PackageManager mPackageManager;
+ public static Display mDisplay;
+ public static List mPackageList;
+
+ public static BeerbongAppInfo mGlobalHook = new BeerbongAppInfo();
+ public BeerbongAppInfo mLocalHook = new BeerbongAppInfo();
+
+ public static boolean sIsHybridModeEnabled;
+
+ public static int mRomLcdDensity = DisplayMetrics.DENSITY_DEFAULT;
+
+ // Native methods
+ public static native String readFile(String s);
+
+ /**
+ * Contains all the details for an application
+ */
+ public static class BeerbongAppInfo {
+
+ public String name = "";
+ public String path = "";
+ public boolean active;
+ public int pid;
+ public ApplicationInfo info;
+ public int dpi;
+ public int firstRun;
+ public float scaledDensity;
+ public float density;
+ }
+
+ /**
+ * Enum interface to allow different override modes
+ */
+ public static enum OverrideMode {
+ ExtendedProperties, AppInfo, FullName, FullNameExclude, PackageName
+ }
+
+ /**
+ * Set app configuration for the input argument info. This is
+ * done by fetching properties.conf or our stored {@link HashMap}.
+ *
+ * @param info
+ * instance containing app details
+ */
+ public static void setAppConfiguration(BeerbongAppInfo info) {
+ if (sIsHybridModeEnabled) {
+ // Load default values to be used in case that property is
+ // missing from configuration.
+ boolean isSystemApp = info.path.contains("system/app");
+ int defaultDpi = Integer.parseInt(getProperty(BEERBONG_PREFIX + (isSystemApp ?
+ "system_default_dpi" : (info.path.length() == 0 ? "0" : "user_default_dpi"))));
+
+ // DPI fetching.
+ info.dpi = Integer.parseInt(getProperty(info.name + BEERBONG_DPI_SUFFIX, String.valueOf(defaultDpi)));
+
+ // Extra density fetching.
+ info.density = Float.parseFloat(getProperty(info.name + BEERBONG_DENSITY_SUFFIX));
+ info.scaledDensity = Float.parseFloat(getProperty(info.name + BEERBONG_SCALEDDENSITY_SUFFIX));
+
+ // In case that densities aren't determined in previous step
+ // we calculate it by dividing DPI by default density (160).
+ if (info.dpi != 0) {
+ info.density = info.density == 0 ? info.dpi / (float) DisplayMetrics.DENSITY_DEFAULT : info.density;
+ info.scaledDensity = info.scaledDensity == 0 ? info.dpi / (float) DisplayMetrics.DENSITY_DEFAULT
+ : info.scaledDensity;
+ }
+
+ info.firstRun = 0;
+
+ // If everything went nice, stop parsing.
+ info.active = true;
+ }
+ }
+
+ /**
+ * Overrides current hook with input parameter mode, wich is an
+ * enum interface that stores basic override possibilities.
+ *
+ * @param input
+ * object to be overriden
+ * @param mode
+ * enum interface
+ */
+ public void overrideHook(Object input, OverrideMode mode) {
+ if (isInitialized() && input != null) {
+
+ ApplicationInfo tempInfo;
+ ExtendedPropertiesUtils tempProps;
+
+ switch (mode) {
+ case ExtendedProperties:
+ tempProps = (ExtendedPropertiesUtils) input;
+ if (tempProps.mLocalHook.active) {
+ mLocalHook.active = tempProps.mLocalHook.active;
+ mLocalHook.pid = tempProps.mLocalHook.pid;
+ mLocalHook.info = tempProps.mLocalHook.info;
+ mLocalHook.name = tempProps.mLocalHook.name;
+ mLocalHook.path = tempProps.mLocalHook.path;
+ mLocalHook.dpi = tempProps.mLocalHook.dpi;
+ mLocalHook.scaledDensity = tempProps.mLocalHook.scaledDensity;
+ mLocalHook.density = tempProps.mLocalHook.density;
+ }
+ return;
+ case AppInfo:
+ mLocalHook.info = (ApplicationInfo) input;
+ break;
+ case FullName:
+ mLocalHook.info = getAppInfoFromPath((String) input);
+ break;
+ case FullNameExclude:
+ tempInfo = getAppInfoFromPath((String) input);
+ if (tempInfo != null && !isHooked()) {
+ mLocalHook.info = tempInfo;
+ }
+ break;
+ case PackageName:
+ mLocalHook.info = getAppInfoFromPackageName((String) input);
+ break;
+ }
+
+ if (mLocalHook.info != null) {
+ mLocalHook.pid = android.os.Process.myPid();
+ mLocalHook.name = mLocalHook.info.packageName;
+ mLocalHook.path = mLocalHook.info.sourceDir.substring(0,
+ mLocalHook.info.sourceDir.lastIndexOf("/"));
+
+ setAppConfiguration(mLocalHook);
+ }
+ }
+ }
+
+ /**
+ * This methods are used to retrieve specific information for a hook.
+ */
+ public static boolean isInitialized() {
+ return (mContext != null);
+ }
+
+ public static boolean isHooked() {
+ return (isInitialized() && !mGlobalHook.name.equals("android") && !mGlobalHook.name.equals(""));
+ }
+
+ public boolean getActive() {
+ return mLocalHook.active ? mLocalHook.active : mGlobalHook.active;
+ }
+
+ public int getPid() {
+ return mLocalHook.active ? mLocalHook.pid : mGlobalHook.pid;
+ }
+
+ public ApplicationInfo getInfo() {
+ return mLocalHook.active ? mLocalHook.info : mGlobalHook.info;
+ }
+
+ public String getName() {
+ return mLocalHook.active ? mLocalHook.name : mGlobalHook.name;
+ }
+
+ public String getPath() {
+ return mLocalHook.active ? mLocalHook.path : mGlobalHook.path;
+ }
+
+ public int getDpi() {
+ return mLocalHook.active ? mLocalHook.dpi : mGlobalHook.dpi;
+ }
+
+ public float getScaledDensity() {
+ return mLocalHook.active ? mLocalHook.scaledDensity : mGlobalHook.scaledDensity;
+ }
+
+ public float getDensity() {
+ return mLocalHook.active ? mLocalHook.density : mGlobalHook.density;
+ }
+
+ /**
+ * Returns whether if device is running hybrid mode
+ *
+ * @return hybrid mode enabled
+ */
+ public static boolean isHybridModeEnabled() {
+ return sIsHybridModeEnabled;
+ }
+
+ /**
+ * Returns whether if device is on tablet UI or not
+ *
+ * @return device is tablet
+ */
+ public static boolean isTablet() {
+ int dpi;
+ String prop = readProperty("com.android.systemui.dpi", "0");
+ if (isParsableToInt(prop)) {
+ dpi = Integer.parseInt(prop);
+ } else {
+ dpi = getActualProperty(prop);
+ }
+ return dpi < 213;
+ }
+
+ /**
+ * Returns an {@link ApplicationInfo}, with the given path.
+ *
+ * @param path
+ * the apk path
+ * @return application info
+ */
+ public static ApplicationInfo getAppInfoFromPath(String path) {
+ if (isInitialized()) {
+ for (int i = 0; mPackageList != null && i < mPackageList.size(); i++) {
+ PackageInfo p = mPackageList.get(i);
+ if (p.applicationInfo != null && p.applicationInfo.sourceDir.equals(path)) {
+ return p.applicationInfo;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns an {@link ApplicationInfo}, with the given package name.
+ *
+ * @param packageName
+ * the application package name
+ * @return application info
+ */
+ public static ApplicationInfo getAppInfoFromPackageName(String packageName) {
+ if (isInitialized()) {
+ for (int i = 0; mPackageList != null && i < mPackageList.size(); i++) {
+ PackageInfo p = mPackageList.get(i);
+ if (p.applicationInfo != null && p.applicationInfo.packageName.equals(packageName)) {
+ return p.applicationInfo;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns an {@link ApplicationInfo}, with the given PID.
+ *
+ * @param pid
+ * the application PID
+ * @return application info
+ */
+ public static ApplicationInfo getAppInfoFromPID(int pid) {
+ if (isInitialized()) {
+ List mProcessList = ((ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE))
+ .getRunningAppProcesses();
+ Iterator mProcessListIt = mProcessList.iterator();
+ while (mProcessListIt.hasNext()) {
+ ActivityManager.RunningAppProcessInfo mAppInfo = (ActivityManager.RunningAppProcessInfo) (mProcessListIt
+ .next());
+ if (mAppInfo.pid == pid) {
+ return getAppInfoFromPackageName(mAppInfo.processName);
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Traces the input argument msg as a log. Used for debugging.
+ * Should not be used on public classes.
+ *
+ * @param msg
+ * the message to log
+ */
+ public static void traceMsg(String msg) {
+ StringWriter sw = new StringWriter();
+ new Throwable("").printStackTrace(new PrintWriter(sw));
+ String stackTrace = sw.toString();
+ Log.i(TAG + ":" + msg, "Trace=" + stackTrace);
+ }
+
+ /**
+ * Updates the {@link HashMap} that contains all the properties.
+ */
+ public static void refreshProperties() {
+ mPropertyMap.clear();
+ String[] props = readFile(BEERBONG_PROPERTIES).split("\n");
+ for (int i = 0; i < props.length; i++) {
+ if (!props[i].startsWith("#")) {
+ String[] pair = props[i].split("=");
+ if (pair.length == 2) {
+ mPropertyMap.put(pair[0].trim(), pair[1].trim());
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns a {@link String}, containing the result of the configuration for
+ * the input argument prop. If the property is not found it
+ * returns zero.
+ *
+ * @param prop
+ * a string containing the property to checkout
+ * @return current stored value of property
+ */
+ public static String getProperty(String prop) {
+ return getProperty(prop, String.valueOf(0));
+ }
+
+ /**
+ * Returns a {@link String}, containing the result of the configuration for
+ * the input argument prop. If the property is not found it
+ * returns the input argument def.
+ *
+ * @param prop
+ * a string containing the property to checkout
+ * @param def
+ * default value to be returned in case that property is missing
+ * @return current stored value of property
+ */
+ public static String getProperty(String prop, String def) {
+ try {
+ if (isInitialized()) {
+ String result = mPropertyMap.get(prop);
+ if (result == null)
+ return def;
+ if (result.startsWith(BEERBONG_PREFIX)) {
+ result = getProperty(result, def);
+ }
+ return result;
+ } else {
+ return readProperty(prop, def);
+ }
+ } catch (NullPointerException e) {
+ e.printStackTrace();
+ }
+ return def;
+ }
+
+ /**
+ * Returns a {@link String}, containing the result of the configuration for
+ * the input argument prop. If the property is not found it
+ * returns the input argument def. This property is directly
+ * read from the configuration file.
+ *
+ * @param prop
+ * a string containing the property to checkout
+ * @param def
+ * default value to be returned in case that property is missing
+ * @return current stored value of property
+ */
+ public static String readProperty(String prop, String def) {
+ String[] props = readFile(BEERBONG_PROPERTIES).split("\n");
+ for (int i = 0; i < props.length; i++) {
+ if (props[i].contains("=")) {
+ if (props[i].substring(0, props[i].lastIndexOf("=")).equals(prop)) {
+ String result = props[i].replace(prop + "=", "").trim();
+ if (result.startsWith(BEERBONG_PREFIX)) {
+ result = getProperty(result, def);
+ }
+ return result;
+ }
+ }
+ }
+ return def;
+ }
+
+ /**
+ * Returns an {@link Integer}, equivalent to what other classes will
+ * actually load for the input argument property. it differs
+ * from {@link #getProperty(String, String) getProperty}, because the values
+ * returned will never be zero.
+ *
+ * @param property
+ * a string containing the property to checkout
+ * @return the actual integer value of the selected property
+ * @see getProperty
+ */
+ public static int getActualProperty(String property) {
+ int result = 0;
+ boolean getProp = false;
+
+ if (property.endsWith(BEERBONG_DPI_SUFFIX)) {
+ ApplicationInfo appInfo = getAppInfoFromPackageName(property.substring(0, property.length()
+ - BEERBONG_DPI_SUFFIX.length()));
+ if (appInfo != null) {
+ boolean isSystemApp =
+ appInfo.sourceDir.substring(0, appInfo.sourceDir.lastIndexOf("/")).contains("system/app");
+ result = Integer.parseInt(getProperty(property, getProperty(BEERBONG_PREFIX + (isSystemApp ?
+ "system_default_dpi" : "user_default_dpi"))));
+ } else {
+ getProp = true;
+ }
+ } else if (property.endsWith("_dpi") || property.endsWith("_layout")) {
+ getProp = true;
+ }
+
+ if (getProp)
+ result = Integer.parseInt(getProperty(property));
+
+ if (result == 0) {
+ result = Integer.parseInt(property.endsWith("dpi") ? getProperty(BEERBONG_PREFIX + "rom_default_dpi")
+ : getProperty(BEERBONG_PREFIX + "rom_default_layout"));
+ }
+
+ return result;
+ }
+
+ /**
+ * Returns a {@link Boolean}, meaning if the input argument is an integer
+ * number.
+ *
+ * @param str
+ * the string to be tested
+ * @return the string is an integer number
+ */
+ public static boolean isParsableToInt(String str) {
+ try {
+ Integer.parseInt(str);
+ return true;
+ } catch (NumberFormatException nfe) {
+ return false;
+ }
+ }
+
+ public void debugOut(String msg) {
+ Log.i(TAG + ":" + msg, "Init=" + (mMainThread != null && mContext != null &&
+ mPackageManager != null) + " App=" + getName() + " Dpi=" + getDpi());
+ }
+}
diff --git a/core/java/android/view/CompatibilityInfoHolder.java b/core/java/android/view/CompatibilityInfoHolder.java
index fc8d6841ac8..6bab08deef8 100644
--- a/core/java/android/view/CompatibilityInfoHolder.java
+++ b/core/java/android/view/CompatibilityInfoHolder.java
@@ -18,7 +18,6 @@
import android.content.res.CompatibilityInfo;
-/** @hide */
public class CompatibilityInfoHolder {
private volatile CompatibilityInfo mCompatInfo = CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java
index 305fd5c8b89..15f6a5b97a4 100644
--- a/core/java/android/view/DisplayInfo.java
+++ b/core/java/android/view/DisplayInfo.java
@@ -306,6 +306,8 @@ private void getMetricsWithSize(DisplayMetrics outMetrics, CompatibilityInfoHold
outMetrics.scaledDensity = outMetrics.noncompatScaledDensity = outMetrics.density;
outMetrics.xdpi = outMetrics.noncompatXdpi = physicalXDpi;
outMetrics.ydpi = outMetrics.noncompatYdpi = physicalYDpi;
+ if (outMetrics.isHooked())
+ outMetrics.paranoidHook();
if (cih != null) {
CompatibilityInfo ci = cih.getIfNeeded();
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index c86f949a795..ff4325c52a2 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -81,6 +81,7 @@ LOCAL_SRC_FILES:= \
android_util_AssetManager.cpp \
android_util_Binder.cpp \
android_util_EventLog.cpp \
+ android_util_ExtendedPropertiesUtils.cpp \
android_util_Log.cpp \
android_util_FloatMath.cpp \
android_util_Process.cpp \
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 01ad2f0e65e..00fce25a4ff 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -98,6 +98,7 @@ namespace android {
*/
extern int register_android_content_AssetManager(JNIEnv* env);
extern int register_android_util_EventLog(JNIEnv* env);
+extern int register_android_util_ExtendedPropertiesUtils(JNIEnv* env);
extern int register_android_util_Log(JNIEnv* env);
extern int register_android_content_StringBlock(JNIEnv* env);
extern int register_android_content_XmlBlock(JNIEnv* env);
@@ -1103,6 +1104,7 @@ static const RegJNIRec gRegJNI[] = {
REG_JNI(register_android_util_EventLog),
REG_JNI(register_android_util_Log),
REG_JNI(register_android_util_FloatMath),
+ REG_JNI(register_android_util_ExtendedPropertiesUtils),
REG_JNI(register_android_text_format_Time),
REG_JNI(register_android_content_AssetManager),
REG_JNI(register_android_content_StringBlock),
diff --git a/core/jni/android_util_ExtendedPropertiesUtils.cpp b/core/jni/android_util_ExtendedPropertiesUtils.cpp
new file mode 100644
index 00000000000..d76c6419884
--- /dev/null
+++ b/core/jni/android_util_ExtendedPropertiesUtils.cpp
@@ -0,0 +1,72 @@
+/*
+**
+** Copyright 2012, ParanoidAndroid 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.
+*/
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace android {
+
+/*
+ * In class android.util.ExtendedPropertiesUtils:
+ * public static native String readFile(String msg)
+ */
+static jstring android_util_ExtendedPropertiesUtils_readFile(JNIEnv* env, jobject clazz, jstring msgObj)
+{
+ const char* msgString = env->GetStringUTFChars(msgObj, NULL);
+ FILE* file = fopen(msgString, "r");
+ if(file == NULL)
+ return NULL;
+
+ fseek(file, 0, SEEK_END);
+ long int size = ftell(file);
+ rewind(file);
+
+ char* content = (char*) calloc(size + 1, 1);
+
+ fread(content,1,size,file);
+
+ return env->NewStringUTF(content);
+}
+
+/*
+ * JNI registration.
+ */
+static JNINativeMethod gMethods[] = {
+ /* name, signature, funcPtr */
+ { "readFile", "(Ljava/lang/String;)Ljava/lang/String;", (void*) android_util_ExtendedPropertiesUtils_readFile },
+};
+
+int register_android_util_ExtendedPropertiesUtils(JNIEnv* env)
+{
+ jclass clazz = env->FindClass("android/util/ExtendedPropertiesUtils");
+
+ if (clazz == NULL) {
+ return -1;
+ }
+
+ return AndroidRuntime::registerNativeMethods(env, "android/util/ExtendedPropertiesUtils", gMethods, NELEM(gMethods));
+}
+
+}; // namespace android
diff --git a/core/res/res/layout/status_bar_latest_event_ticker_large_icon.xml b/core/res/res/layout/status_bar_latest_event_ticker_large_icon.xml
index 09ff1c89f8d..52835b07c5d 100644
--- a/core/res/res/layout/status_bar_latest_event_ticker_large_icon.xml
+++ b/core/res/res/layout/status_bar_latest_event_ticker_large_icon.xml
@@ -37,14 +37,13 @@
android:gravity="bottom"
android:singleLine="true"
/>
-
diff --git a/core/res/res/values-sw600dp/dimens.xml b/core/res/res/values-sw600dp/dimens.xml
index 52c230b16b3..a91b0d8d7a1 100644
--- a/core/res/res/values-sw600dp/dimens.xml
+++ b/core/res/res/values-sw600dp/dimens.xml
@@ -18,10 +18,6 @@
*/
-->
-
- 200dp
-
- 177dp
@@ -75,8 +71,8 @@
56dp
- 24dp
- 24dip
+ 10dp
+ 10dip
diff --git a/core/res/res/values-sw720dp/dimens.xml b/core/res/res/values-sw720dp/dimens.xml
index 654fdd5f7dc..6baac367091 100644
--- a/core/res/res/values-sw720dp/dimens.xml
+++ b/core/res/res/values-sw720dp/dimens.xml
@@ -34,11 +34,6 @@
(the screen is in landscape). This may be either a fraction or a dimension.-->
- 90%
-
- 230dp
-
- 135dp
-
32dp
0dp
@@ -57,19 +52,19 @@
20dp
- 32dp
+ 10dp
- 32dp
+ 10dp
- 32dp
+ 10dp
- 1
+ 3
- 2
+ 5
- 56dp
+ 0dp
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index d3a4aa73436..51baf29eb1b 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -19,9 +19,9 @@
-->
- 164dp
+ 170dp
- 145dp
+ 150dp
48dip
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index 688fd7aa535..04f629c5fc4 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -19,6 +19,7 @@
import android.os.Parcel;
import android.os.Parcelable;
import android.util.DisplayMetrics;
+import android.util.ExtendedPropertiesUtils;
import java.io.OutputStream;
import java.nio.Buffer;
@@ -80,9 +81,9 @@ public static void setDefaultDensity(int density) {
static int getDefaultDensity() {
if (sDefaultDensity >= 0) {
- return sDefaultDensity;
+ return ExtendedPropertiesUtils.mGlobalHook.dpi == 0 ? sDefaultDensity : ExtendedPropertiesUtils.mGlobalHook.dpi;
}
- sDefaultDensity = DisplayMetrics.DENSITY_DEVICE;
+ sDefaultDensity = DisplayMetrics.getDeviceDensity();
return sDefaultDensity;
}
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index f9392e46222..4e61efddf82 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -781,7 +781,7 @@ public static Drawable createFromResourceStream(Resources res, TypedValue value,
// drawn to the screen.
if (opts == null) opts = new BitmapFactory.Options();
opts.inScreenDensity = res != null
- ? res.getDisplayMetrics().noncompatDensityDpi : DisplayMetrics.DENSITY_DEVICE;
+ ? res.getDisplayMetrics().noncompatDensityDpi : DisplayMetrics.getDeviceDensity();
Bitmap bm = BitmapFactory.decodeResourceStream(res, value, is, pad, opts);
if (bm != null) {
byte[] np = bm.getNinePatchChunk();
diff --git a/packages/SystemUI/res/values-sw600dp/config.xml b/packages/SystemUI/res/values-sw600dp/config.xml
index 48a02ab2ad4..5fd3b7fed43 100644
--- a/packages/SystemUI/res/values-sw600dp/config.xml
+++ b/packages/SystemUI/res/values-sw600dp/config.xml
@@ -34,4 +34,12 @@
false
+
+
+ false
+
+
+ false
diff --git a/packages/SystemUI/res/values-sw600dp/dimens.xml b/packages/SystemUI/res/values-sw600dp/dimens.xml
index fc80f5cc727..f392a200d57 100644
--- a/packages/SystemUI/res/values-sw600dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp/dimens.xml
@@ -37,10 +37,6 @@
280dip
-
- 200dp
- 177dp
-
- 35%
diff --git a/packages/SystemUI/res/values-sw720dp/config.xml b/packages/SystemUI/res/values-sw720dp/config.xml
index bf01a8d5ae5..dc025a18d32 100644
--- a/packages/SystemUI/res/values-sw720dp/config.xml
+++ b/packages/SystemUI/res/values-sw720dp/config.xml
@@ -20,15 +20,15 @@
- 5
+ 2
- true
+ false
- true
+ false
0
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index e25400acae7..3b85f67cb80 100755
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -26,8 +26,8 @@
48dp
- 164dp
- 145dp
+ 170dp
+ 150dp
4dp
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
index 6583a558cb3..9fe18611e1b 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
@@ -43,6 +43,8 @@
import android.provider.Settings;
import android.text.format.Formatter;
import android.util.AttributeSet;
+import android.util.DisplayMetrics;
+import android.util.ExtendedPropertiesUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MenuItem;
@@ -96,11 +98,13 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
private ArrayList mRecentTaskDescriptions;
private TaskDescriptionAdapter mListAdapter;
private int mThumbnailWidth;
+ private int mThumbnailHeight;
private boolean mFitThumbnailToXY;
private int mRecentItemLayoutId;
private boolean mHighEndGfx;
boolean ramBarEnabled;
boolean mRecentsKillAllEnabled;
+ private int mAndroidDpi = DisplayMetrics.DENSITY_DEVICE;
TextView mBackgroundProcessText;
TextView mForegroundProcessText;
@@ -171,6 +175,10 @@ public View createView(ViewGroup parent) {
holder.thumbnailView = convertView.findViewById(R.id.app_thumbnail);
holder.thumbnailViewImage =
(ImageView) convertView.findViewById(R.id.app_thumbnail_image);
+
+ holder.thumbnailViewImage.getLayoutParams().width = mThumbnailWidth;
+ holder.thumbnailViewImage.getLayoutParams().height = mThumbnailHeight;
+
// If we set the default thumbnail now, we avoid an onLayout when we update
// the thumbnail later (if they both have the same dimensions)
updateThumbnail(holder, mRecentTasksLoader.getDefaultThumbnail(), false, false);
@@ -462,7 +470,11 @@ public void setRecentTasksLoader(RecentTasksLoader loader) {
public void updateValuesFromResources() {
final Resources res = mContext.getResources();
- mThumbnailWidth = Math.round(res.getDimension(R.dimen.status_bar_recents_thumbnail_width));
+ mAndroidDpi = ExtendedPropertiesUtils.getActualProperty("com.android.systemui.dpi");
+ mThumbnailWidth = Math.round((float)res.getDimension(R.dimen.status_bar_recents_thumbnail_width) *
+ DisplayMetrics.DENSITY_DEVICE / mAndroidDpi);
+ mThumbnailHeight = Math.round((float)res.getDimension(R.dimen.status_bar_recents_thumbnail_height) *
+ DisplayMetrics.DENSITY_DEVICE / mAndroidDpi);
mFitThumbnailToXY = res.getBoolean(R.bool.config_recents_thumbnail_image_fits_to_xy);
}
@@ -530,6 +542,7 @@ private void updateThumbnail(ViewHolder h, Bitmap thumbnail, boolean show, boole
// Should remove the default image in the frame
// that this now covers, to improve scrolling speed.
// That can't be done until the anim is complete though.
+ thumbnail.setDensity(mAndroidDpi);
h.thumbnailViewImage.setImageBitmap(thumbnail);
// scale the image to fill the full width of the ImageView. do this only if
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index a8845faf12c..4e6659c509b 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -77,6 +77,7 @@
import android.util.DisplayMetrics;
import android.util.EventLog;
+import android.util.ExtendedPropertiesUtils;
import android.util.Log;
import android.util.Slog;
import android.util.SparseArray;
@@ -1308,69 +1309,54 @@ public void setInitialDisplaySize(Display display, int width, int height, int de
}
}
- mStatusBarHeight = mContext.getResources().getDimensionPixelSize(
- com.android.internal.R.dimen.status_bar_height);
+ // SystemUI (status bar) layout policy
+ int sysLayout = ExtendedPropertiesUtils.getActualProperty("com.android.systemui.layout");
+ int sysDpi = ExtendedPropertiesUtils.getActualProperty("android.dpi");
+ int sysUIDpi = ExtendedPropertiesUtils.getActualProperty("com.android.systemui.dpi");
+
+ float statusBarHeight = ((float)mContext.getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.status_bar_height) *
+ DisplayMetrics.DENSITY_DEVICE / sysDpi) /
+ DisplayMetrics.DENSITY_DEVICE * sysUIDpi;
+
+ float navigationBarHeight = ((float)mContext.getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.navigation_bar_height) *
+ DisplayMetrics.DENSITY_DEVICE / sysDpi) /
+ DisplayMetrics.DENSITY_DEVICE * sysUIDpi;
+
+ float navigationBarWidth = ((float)mContext.getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.navigation_bar_width) *
+ DisplayMetrics.DENSITY_DEVICE / sysDpi) /
+ DisplayMetrics.DENSITY_DEVICE * sysUIDpi;
+
+ float navigationBarHeightLandscape = ((float)mContext.getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.navigation_bar_height_landscape) *
+ DisplayMetrics.DENSITY_DEVICE / sysDpi) /
+ DisplayMetrics.DENSITY_DEVICE * sysUIDpi;
+
+ mStatusBarHeight = Math.round(statusBarHeight);
// Height of the navigation bar when presented horizontally at bottom
- mNavigationBarHeightForRotation[mPortraitRotation] =
- mNavigationBarHeightForRotation[mUpsideDownRotation] =
- Settings.System.getInt(
- mContext.getContentResolver(),
- Settings.System.NAVIGATION_BAR_HEIGHT,
- mContext.getResources()
- .getDimensionPixelSize(
- com.android.internal.R.dimen.navigation_bar_height));
+ mNavigationBarHeightForRotation[mPortraitRotation] =
+ mNavigationBarHeightForRotation[mUpsideDownRotation] = Math.round(navigationBarHeight);
mNavigationBarHeightForRotation[mLandscapeRotation] =
- mNavigationBarHeightForRotation[mSeascapeRotation] =
- Settings.System.getInt(
- mContext.getContentResolver(),
- Settings.System.NAVIGATION_BAR_HEIGHT_LANDSCAPE,
- mContext.getResources()
- .getDimensionPixelSize(
- com.android.internal.R.dimen.navigation_bar_height_landscape));
+ mNavigationBarHeightForRotation[mSeascapeRotation] = Math.round(navigationBarHeightLandscape);
// Width of the navigation bar when presented vertically along one side
- mNavigationBarWidthForRotation[mPortraitRotation] =
- mNavigationBarWidthForRotation[mUpsideDownRotation] =
- mNavigationBarWidthForRotation[mLandscapeRotation] =
- mNavigationBarWidthForRotation[mSeascapeRotation] =
- Settings.System.getInt(
- mContext.getContentResolver(),
- Settings.System.NAVIGATION_BAR_WIDTH,
- mContext.getResources()
- .getDimensionPixelSize(
- com.android.internal.R.dimen.navigation_bar_width));
-
- // SystemUI (status bar) layout policy
- int shortSizeDp = shortSize * DisplayMetrics.DENSITY_DEFAULT / density;
-
- if (shortSizeDp < 600) {
- mStockUIMode = 0; // Phone Mode
- } else {
- mStockUIMode = 2; // Phablet Mode
- } // Tablet Mode will be mode ==1 but no devices default to Tablet mode since 4.2
-
- mUserUIMode = Settings.System.getInt(mContext.getContentResolver(),
- Settings.System.USER_UI_MODE,mStockUIMode);
- switch (mUserUIMode) {
- case 0 :
- // "phone" UI with a separate status & navigation bar
- mHasSystemNavBar = false;
- mNavigationBarCanMove = true;
- break;
- case 1 :
- // "tablet" UI with a single combined status & navigation bar
- mHasSystemNavBar = true;
- mNavigationBarCanMove = false;
- break;
- case 2 :
- // "phone" UI with modifications for larger screens
- mHasSystemNavBar = false;
- mNavigationBarCanMove = false;
- break;
+ mNavigationBarWidthForRotation[mPortraitRotation] = mNavigationBarWidthForRotation[mUpsideDownRotation] =
+ mNavigationBarWidthForRotation[mLandscapeRotation] = mNavigationBarWidthForRotation[mSeascapeRotation] =
+ Math.round(navigationBarWidth);
+
+ if (sysLayout < 600) {
+ // 0-599dp: "phone" UI with a separate status & navigation bar
+ mHasSystemNavBar = false;
+ mNavigationBarCanMove = true;
+ } else if (sysLayout < 720) {
+ // 600+dp: "phone" UI with modifications for larger screens
+ mHasSystemNavBar = false;
+ mNavigationBarCanMove = false;
}
- Settings.System.putInt(mContext.getContentResolver(),
- Settings.System.CURRENT_UI_MODE, mUserUIMode);
+
if (!mHasSystemNavBar) {
final boolean showByDefault = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_showNavigationBar);
@@ -1420,7 +1406,7 @@ else if (navBarOverride.equals("0"))
int longSizeDp = longSize * DisplayMetrics.DENSITY_DEFAULT / density;
int barHeightDp = mNavigationBarHeightForRotation[mLandscapeRotation]
* DisplayMetrics.DENSITY_DEFAULT / density;
- int aspect = ((shortSizeDp-barHeightDp) * 16) / longSizeDp;
+ int aspect = ((sysLayout-barHeightDp) * 16) / longSizeDp;
// We have computed the aspect ratio with the bar height taken
// out to be 16:aspect. If this is less than 9, then hiding
// the navigation bar will provide more useful space for wide
diff --git a/preloaded-classes b/preloaded-classes
index 80688752805..0bb9b664923 100644
--- a/preloaded-classes
+++ b/preloaded-classes
@@ -836,6 +836,7 @@ android.util.Base64$Coder
android.util.DisplayMetrics
android.util.EventLog
android.util.EventLog$Event
+android.util.ExtendedPropertiesUtils
android.util.FinitePool
android.util.FloatMath
android.util.FloatProperty
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index 885ec890dd2..5c4ffbe3c22 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -58,7 +58,9 @@
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.UserHandle;
+import android.util.DisplayMetrics;
import android.util.EventLog;
+import android.util.ExtendedPropertiesUtils;
import android.util.Log;
import android.util.Slog;
import android.view.Display;
@@ -933,10 +935,13 @@ public final Bitmap screenshotActivities(ActivityRecord who) {
int w = mThumbnailWidth;
int h = mThumbnailHeight;
if (w < 0) {
+ int mAndroidDpi = ExtendedPropertiesUtils.getActualProperty("android.dpi");
mThumbnailWidth = w =
- res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
+ Math.round((float)res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width) *
+ DisplayMetrics.DENSITY_DEVICE / mAndroidDpi);
mThumbnailHeight = h =
- res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
+ Math.round((float)res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height) *
+ DisplayMetrics.DENSITY_DEVICE / mAndroidDpi);
}
if (w > 0) {
From 737e6102a15d15f139cc27651ea0341fb1fc212d Mon Sep 17 00:00:00 2001
From: YamilGhazi
Date: Wed, 20 Feb 2013 06:57:41 +0100
Subject: [PATCH 02/14] UI change w/o reboot and navbar height
Change-Id: I017c1ccb1d4c87fb166f1e744a36690a2150468f
---
core/java/android/provider/Settings.java | 7 +
.../policy/impl/PhoneWindowManager.java | 268 ++++++++++--------
2 files changed, 162 insertions(+), 113 deletions(-)
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index bf28bc18169..4a529a27aae 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3263,6 +3263,13 @@ public static void setShowGTalkServiceStatusForUser(ContentResolver cr, boolean
*/
public static final String PIE_CENTER = "pie_center";
+ /**
+ * User Interface State
+ * 1 = Rebuild UI, resets to 0 automatically
+ * @hide
+ */
+ public static final String USER_INTERFACE_STATE = "user_interface_state";
+
/**
* Swap volume buttons when the screen is rotated by 90 or 180 degrees
* @hide
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 4e6659c509b..d3299c13250 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -592,7 +592,14 @@ public void onInputEvent(InputEvent event) {
private boolean mVolBtnMusicControls;
private boolean mIsLongPress;
+ private int mSystemDpi = 0;
+ private int mSystemUiDpi = 0;
+ private int mSystemUiLayout = 0;
+ private int mNavBarDpi = 0;
+ private int mStatusBarDpi = 0;
+
SettingsObserver mSettingsObserver;
+ UserInterfaceObserver mUserInterfaceObserver;
ShortcutManager mShortcutManager;
PowerManager.WakeLock mBroadcastWakeLock;
boolean mHavePendingMediaKeyRepeatWithWakeLock;
@@ -721,9 +728,36 @@ void observe() {
updateSettings();
}
- @Override public void onChange(boolean selfChange) {
- updateSettings();
- updateRotation(false);
+ @Override
+ public void onChange(boolean selfChange) {
+ update(false);
+ }
+ }
+
+ class UserInterfaceObserver extends ContentObserver {
+ UserInterfaceObserver(Handler handler) {
+ super(handler);
+ }
+
+ void observe() {
+ ContentResolver resolver = mContext.getContentResolver();
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.USER_INTERFACE_STATE), false, this);
+ }
+
+ @Override
+ public void onChange(boolean selfChange) {
+ // Return for reset triggers
+ if (Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.USER_INTERFACE_STATE, 0) == 0) {
+ return;
+ }
+
+ // Update layout
+ update(true);
+
+ // Reset trigger
+ Settings.System.putInt(mContext.getContentResolver(), Settings.System.USER_INTERFACE_STATE, 0);
}
}
@@ -1139,6 +1173,7 @@ public void init(Context context, IWindowManager windowManager,
try {
mOrientationListener.setCurrentRotation(windowManager.getRotation());
} catch (RemoteException ex) { }
+ updateHybridLayout();
mSettingsObserver = new SettingsObserver(mHandler);
mSettingsObserver.observe();
@@ -1171,6 +1206,8 @@ public void onChange(boolean selfChange) {
}
});
+ mUserInterfaceObserver = new UserInterfaceObserver(mHandler);
+ mUserInterfaceObserver.observe();
mShortcutManager = new ShortcutManager(context, mHandler);
mShortcutManager.observe();
mUiMode = context.getResources().getInteger(
@@ -1309,116 +1346,7 @@ public void setInitialDisplaySize(Display display, int width, int height, int de
}
}
- // SystemUI (status bar) layout policy
- int sysLayout = ExtendedPropertiesUtils.getActualProperty("com.android.systemui.layout");
- int sysDpi = ExtendedPropertiesUtils.getActualProperty("android.dpi");
- int sysUIDpi = ExtendedPropertiesUtils.getActualProperty("com.android.systemui.dpi");
-
- float statusBarHeight = ((float)mContext.getResources().getDimensionPixelSize(
- com.android.internal.R.dimen.status_bar_height) *
- DisplayMetrics.DENSITY_DEVICE / sysDpi) /
- DisplayMetrics.DENSITY_DEVICE * sysUIDpi;
-
- float navigationBarHeight = ((float)mContext.getResources().getDimensionPixelSize(
- com.android.internal.R.dimen.navigation_bar_height) *
- DisplayMetrics.DENSITY_DEVICE / sysDpi) /
- DisplayMetrics.DENSITY_DEVICE * sysUIDpi;
-
- float navigationBarWidth = ((float)mContext.getResources().getDimensionPixelSize(
- com.android.internal.R.dimen.navigation_bar_width) *
- DisplayMetrics.DENSITY_DEVICE / sysDpi) /
- DisplayMetrics.DENSITY_DEVICE * sysUIDpi;
-
- float navigationBarHeightLandscape = ((float)mContext.getResources().getDimensionPixelSize(
- com.android.internal.R.dimen.navigation_bar_height_landscape) *
- DisplayMetrics.DENSITY_DEVICE / sysDpi) /
- DisplayMetrics.DENSITY_DEVICE * sysUIDpi;
-
- mStatusBarHeight = Math.round(statusBarHeight);
-
- // Height of the navigation bar when presented horizontally at bottom
- mNavigationBarHeightForRotation[mPortraitRotation] =
- mNavigationBarHeightForRotation[mUpsideDownRotation] = Math.round(navigationBarHeight);
- mNavigationBarHeightForRotation[mLandscapeRotation] =
- mNavigationBarHeightForRotation[mSeascapeRotation] = Math.round(navigationBarHeightLandscape);
-
- // Width of the navigation bar when presented vertically along one side
- mNavigationBarWidthForRotation[mPortraitRotation] = mNavigationBarWidthForRotation[mUpsideDownRotation] =
- mNavigationBarWidthForRotation[mLandscapeRotation] = mNavigationBarWidthForRotation[mSeascapeRotation] =
- Math.round(navigationBarWidth);
-
- if (sysLayout < 600) {
- // 0-599dp: "phone" UI with a separate status & navigation bar
- mHasSystemNavBar = false;
- mNavigationBarCanMove = true;
- } else if (sysLayout < 720) {
- // 600+dp: "phone" UI with modifications for larger screens
- mHasSystemNavBar = false;
- mNavigationBarCanMove = false;
- }
-
- if (!mHasSystemNavBar) {
- final boolean showByDefault = mContext.getResources().getBoolean(
- com.android.internal.R.bool.config_showNavigationBar);
- mHasNavigationBar = Settings.System.getBoolean(mContext.getContentResolver(),
- Settings.System.NAVIGATION_BAR_SHOW, showByDefault);
-
- /*
- * at first boot up, we need to make sure navbar gets created
- * (or obey framework setting).
- * this should quickly get over-ridden by the settings observer
- * if it was disabled by the user.
- */
- if (mNavBarFirstBootFlag) {
- mNavBarFirstBootFlag = false;
- } else {
- mHasNavigationBar = mHasNavigationBar &&
- Settings.System.getBoolean(mContext.getContentResolver(),
- Settings.System.NAVIGATION_BAR_SHOW_NOW, mHasNavigationBar);
-
- }
- // Allow a system property to override this. Used by the emulator.
- // See also hasNavigationBar().
- String navBarOverride = SystemProperties.get("qemu.hw.mainkeys");
- if (!"".equals(navBarOverride)) {
- if (navBarOverride.equals("1"))
- mHasNavigationBar = false;
- else if (navBarOverride.equals("0"))
- mHasNavigationBar = true;
- }
- }
-
- if (!mHasNavigationBar) {
- mNavigationBarWidthForRotation[mPortraitRotation] =
- mNavigationBarWidthForRotation[mUpsideDownRotation] =
- mNavigationBarWidthForRotation[mLandscapeRotation] =
- mNavigationBarWidthForRotation[mSeascapeRotation] = 0;
- mNavigationBarHeightForRotation[mPortraitRotation] =
- mNavigationBarHeightForRotation[mUpsideDownRotation] =
- mNavigationBarHeightForRotation[mLandscapeRotation] =
- mNavigationBarHeightForRotation[mSeascapeRotation] = 0;
- }
-
- if (mHasSystemNavBar) {
- // The system bar is always at the bottom. If you are watching
- // a video in landscape, we don't need to hide it if we can still
- // show a 16:9 aspect ratio with it.
- int longSizeDp = longSize * DisplayMetrics.DENSITY_DEFAULT / density;
- int barHeightDp = mNavigationBarHeightForRotation[mLandscapeRotation]
- * DisplayMetrics.DENSITY_DEFAULT / density;
- int aspect = ((sysLayout-barHeightDp) * 16) / longSizeDp;
- // We have computed the aspect ratio with the bar height taken
- // out to be 16:aspect. If this is less than 9, then hiding
- // the navigation bar will provide more useful space for wide
- // screen movies.
- mCanHideNavigationBar = aspect < 9;
- } else if (mHasNavigationBar) {
- // The navigation bar is at the right in landscape; it seems always
- // useful to hide it for showing a video.
- mCanHideNavigationBar = true;
- } else {
- mCanHideNavigationBar = false;
- }
+ getDimensions();
// For demo purposes, allow the rotation of the HDMI display to be controlled.
// By default, HDMI locks rotation to landscape.
@@ -1429,6 +1357,42 @@ else if (navBarOverride.equals("0"))
}
mHdmiRotationLock = SystemProperties.getBoolean("persist.demo.hdmirotationlock", true);
}
+
+ private void update(boolean updateUi) {
+ if (updateUi) {
+ updateHybridLayout();
+ }
+
+ updateSettings();
+ updateRotation(false);
+
+ // Bring down SystemUI
+ if (updateUi) {
+ // Restart UI if necessary
+ String packageName = "com.android.systemui";
+ try {
+ ActivityManagerNative.getDefault().killApplicationProcess(
+ packageName, AppGlobals.getPackageManager().getPackageUid(
+ packageName, UserHandle.myUserId()));
+ } catch (RemoteException e) {
+ // Good luck next time!
+ }
+ }
+ }
+
+ private int updateHybridLayout() {
+ int oldSystemUILayout = mSystemUiLayout == 0 ?
+ ExtendedPropertiesUtils.getActualProperty("com.android.systemui.layout") : mSystemUiLayout;
+ ExtendedPropertiesUtils.refreshProperties();
+ mSystemDpi = ExtendedPropertiesUtils.getActualProperty("android.dpi");
+ mSystemUiDpi = ExtendedPropertiesUtils.getActualProperty("com.android.systemui.dpi");
+ mSystemUiLayout = ExtendedPropertiesUtils.getActualProperty("com.android.systemui.layout");
+ int mNavigationBarPercent = Integer.parseInt(ExtendedPropertiesUtils.getProperty("com.android.systemui.navbar.dpi", "100"));
+ mNavBarDpi = mNavigationBarPercent * mSystemUiDpi / 100;
+ int mStatusBarPercent = Integer.parseInt(ExtendedPropertiesUtils.getProperty("com.android.systemui.statusbar.dpi", "100"));
+ mStatusBarDpi = mStatusBarPercent * mSystemUiDpi / 100;
+ return oldSystemUILayout;
+ }
private void closeApplication(String packageName) {
try {
@@ -1614,6 +1578,83 @@ private void resetScreenHelper() {
if(mDisplay != null)
setInitialDisplaySize(mDisplay, mUnrestrictedScreenWidth, mUnrestrictedScreenHeight, density);
}
+
+ public void getDimensions(){
+ float statusBarHeight = ((float)mContext.getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.status_bar_height) *
+ DisplayMetrics.DENSITY_DEVICE / mSystemDpi) /
+ DisplayMetrics.DENSITY_DEVICE * mStatusBarDpi;
+
+ float navigationBarHeight = ((float)mContext.getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.navigation_bar_height) *
+ DisplayMetrics.DENSITY_DEVICE / mSystemDpi) /
+ DisplayMetrics.DENSITY_DEVICE * mNavBarDpi;
+
+ float navigationBarWidth = ((float)mContext.getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.navigation_bar_width) *
+ DisplayMetrics.DENSITY_DEVICE / mSystemDpi) /
+ DisplayMetrics.DENSITY_DEVICE * mNavBarDpi;
+
+ float navigationBarHeightLandscape = ((float)mContext.getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.navigation_bar_height_landscape) *
+ DisplayMetrics.DENSITY_DEVICE / mSystemDpi) /
+ DisplayMetrics.DENSITY_DEVICE * mNavBarDpi;
+
+ mStatusBarHeight = Math.round(statusBarHeight);
+
+ // Height of the navigation bar when presented horizontally at bottom
+ mNavigationBarHeightForRotation[mPortraitRotation] =
+ mNavigationBarHeightForRotation[mUpsideDownRotation] = Math.round(navigationBarHeight);
+
+ mNavigationBarHeightForRotation[mLandscapeRotation] =
+ mNavigationBarHeightForRotation[mSeascapeRotation] = Math.round(navigationBarHeightLandscape);
+
+ // Width of the navigation bar when presented vertically along one side
+ mNavigationBarWidthForRotation[mPortraitRotation] = mNavigationBarWidthForRotation[mUpsideDownRotation] =
+ mNavigationBarWidthForRotation[mLandscapeRotation] = mNavigationBarWidthForRotation[mSeascapeRotation] =
+ Math.round(navigationBarWidth);
+
+ if (mSystemUiLayout < 600) {
+ // 0-599dp: "phone" UI with a separate status & navigation bar
+ mHasSystemNavBar = false;
+ mNavigationBarCanMove = true;
+ } else if (mSystemUiLayout < 720) {
+ // 600+dp: "phone" UI with modifications for larger screens
+ mHasSystemNavBar = false;
+ mNavigationBarCanMove = false;
+ } else if (mSystemUiLayout == 1000) {
+ // 1000dp: "tablet" UI with a single combined status & navigation bar
+ mHasSystemNavBar = true;
+ mNavigationBarCanMove = false;
+ }
+
+ mHasNavigationBar = !mHasSystemNavBar;
+
+ if (mHasSystemNavBar) {
+ mCanHideNavigationBar = true;
+ } else if (mHasNavigationBar) {
+ // The navigation bar is at the right in landscape; it seems always
+ // useful to hide it for showing a video.
+ mCanHideNavigationBar = true;
+ } else {
+ mCanHideNavigationBar = false;
+ }
+
+ // In case that we removed nav bar, set all sizes to 0 again
+ if(!mHasNavigationBar){
+ if(!mHasSystemNavBar || Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.EXPANDED_DESKTOP_STATE, 0) == 1){
+ mNavigationBarWidthForRotation[mPortraitRotation]
+ = mNavigationBarWidthForRotation[mUpsideDownRotation]
+ = mNavigationBarWidthForRotation[mLandscapeRotation]
+ = mNavigationBarWidthForRotation[mSeascapeRotation]
+ = mNavigationBarHeightForRotation[mPortraitRotation]
+ = mNavigationBarHeightForRotation[mUpsideDownRotation]
+ = mNavigationBarHeightForRotation[mLandscapeRotation]
+ = mNavigationBarHeightForRotation[mSeascapeRotation] = 0;
+ }
+ }
+ }
private void enablePointerLocation() {
if (mPointerLocationView == null) {
@@ -4461,6 +4502,7 @@ public void onReceive(Context context, Intent intent) {
// and then updates our own bookkeeping based on the now-
// current user.
mSettingsObserver.onChange(false);
+ mUserInterfaceObserver.onChange(false);
// force a re-application of focused window sysui visibility.
// the window may never have been shown for this user
From 407a4a0824b39e7954609d915f9d48f769528398 Mon Sep 17 00:00:00 2001
From: YamilGhazi
Date: Wed, 20 Feb 2013 18:10:21 +0100
Subject: [PATCH 03/14] Navbar height fix
Change-Id: I1fc9f1af7ed4aedee0929f8e8be1ddde71698ae6
---
.../com/android/internal/policy/impl/PhoneWindowManager.java | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index d3299c13250..dc3e4867d5e 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -1421,6 +1421,10 @@ public void updateSettings() {
Settings.Secure.RING_HOME_BUTTON_BEHAVIOR_DEFAULT,
UserHandle.USER_CURRENT);
+ mHasNavigationBar = !mHasSystemNavBar;
+
+ getDimensions();
+
boolean keyRebindingEnabled = Settings.System.getInt(resolver,
Settings.System.HARDWARE_KEY_REBINDING, 0) == 1;
From 6a24df2b3952362a5d4d0e153e33463ba535fe76 Mon Sep 17 00:00:00 2001
From: YamilGhazi
Date: Wed, 27 Feb 2013 06:50:12 +0100
Subject: [PATCH 04/14] Be sure to get default dpi
Change-Id: Ia9cb33b81827af7e46670f76db7e34aac78602cf
---
core/java/android/util/ExtendedPropertiesUtils.java | 3 +++
1 file changed, 3 insertions(+)
diff --git a/core/java/android/util/ExtendedPropertiesUtils.java b/core/java/android/util/ExtendedPropertiesUtils.java
index b4db1ec1521..56adbd7449b 100644
--- a/core/java/android/util/ExtendedPropertiesUtils.java
+++ b/core/java/android/util/ExtendedPropertiesUtils.java
@@ -106,6 +106,9 @@ public static void setAppConfiguration(BeerbongAppInfo info) {
// DPI fetching.
info.dpi = Integer.parseInt(getProperty(info.name + BEERBONG_DPI_SUFFIX, String.valueOf(defaultDpi)));
+ if (info.dpi == 0) {
+ info.dpi = defaultDpi;
+ }
// Extra density fetching.
info.density = Float.parseFloat(getProperty(info.name + BEERBONG_DENSITY_SUFFIX));
From 8d3e1ffe945caf93cebf49e1b76f643ee9faa94b Mon Sep 17 00:00:00 2001
From: YamilGhazi
Date: Fri, 22 Feb 2013 06:54:26 +0100
Subject: [PATCH 05/14] Switch UIMode without reboot
Change-Id: I8fb10f8d81e3400b2050062e07e1b074aea359c6
---
.../android/content/res/Configuration.java | 15 ++--
.../android/util/ExtendedPropertiesUtils.java | 24 ++++++
.../policy/impl/PhoneWindowManager.java | 83 +++++++++----------
3 files changed, 71 insertions(+), 51 deletions(-)
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
index 1f9db20c859..660002ed28b 100644
--- a/core/java/android/content/res/Configuration.java
+++ b/core/java/android/content/res/Configuration.java
@@ -577,21 +577,24 @@ public boolean isLayoutSizeAtLeast(int size) {
* Process layout changes for current hook
*/
public void paranoidHook() {
- if (active) {
+ if (getLayout() != 0 && active) {
- int dpi = getDpi(), layout = 600;
+ /*int dpi = getDpi(), layout = 600;
if (dpi <= 213) {
layout = 720;
- } else if (layout > 213) {
+ } else if (dpi > 213) {
layout = 360;
- }
+ }*/
if (mDisplay == null) return;
Point size = new Point();
mDisplay.getSize(size);
float factor = (float)Math.max(size.x, size.y) / (float)Math.min(size.x, size.y);
- screenWidthDp = layout;
+ screenWidthDp = getLayout();
screenHeightDp = (int)(screenWidthDp * factor);
- smallestScreenWidthDp = layout;
+ smallestScreenWidthDp = getLayout();
+ /*if (getLarge()) {
+ screenLayout |= SCREENLAYOUT_SIZE_XLARGE;
+ }*/
compatScreenWidthDp = screenWidthDp;
compatScreenHeightDp = screenHeightDp;
compatSmallestScreenWidthDp = smallestScreenWidthDp;
diff --git a/core/java/android/util/ExtendedPropertiesUtils.java b/core/java/android/util/ExtendedPropertiesUtils.java
index 56adbd7449b..1d329b7ae29 100644
--- a/core/java/android/util/ExtendedPropertiesUtils.java
+++ b/core/java/android/util/ExtendedPropertiesUtils.java
@@ -46,6 +46,7 @@ public class ExtendedPropertiesUtils {
public static final String BEERBONG_SEPARATOR = ".";
public static final String BEERBONG_STRING_DELIMITER = "\\|";
public static final String BEERBONG_DPI_SUFFIX = ".dpi";
+ public static final String BEERBONG_LAYOUT_SUFFIX = ".layout";
public static final String BEERBONG_DENSITY_SUFFIX = ".den";
public static final String BEERBONG_SCALEDDENSITY_SUFFIX = ".sden";
@@ -77,6 +78,7 @@ public static class BeerbongAppInfo {
public int pid;
public ApplicationInfo info;
public int dpi;
+ public int layout;
public int firstRun;
public float scaledDensity;
public float density;
@@ -103,6 +105,12 @@ public static void setAppConfiguration(BeerbongAppInfo info) {
boolean isSystemApp = info.path.contains("system/app");
int defaultDpi = Integer.parseInt(getProperty(BEERBONG_PREFIX + (isSystemApp ?
"system_default_dpi" : (info.path.length() == 0 ? "0" : "user_default_dpi"))));
+ /*int defaultLayout = Integer.parseInt(getProperty(BEERBONG_PREFIX + (isSystemApp ?
+ "system_default_layout" : (info.path.length() == 0 ? "0" : "user_default_layout"))));*/
+ int defaultLayout = getActualProperty("com.android.systemui.layout");
+
+ // Layout fetching.
+ info.layout = Integer.parseInt(getProperty(info.name + BEERBONG_LAYOUT_SUFFIX, String.valueOf(defaultLayout)));
// DPI fetching.
info.dpi = Integer.parseInt(getProperty(info.name + BEERBONG_DPI_SUFFIX, String.valueOf(defaultDpi)));
@@ -154,6 +162,7 @@ public void overrideHook(Object input, OverrideMode mode) {
mLocalHook.name = tempProps.mLocalHook.name;
mLocalHook.path = tempProps.mLocalHook.path;
mLocalHook.dpi = tempProps.mLocalHook.dpi;
+ mLocalHook.layout = tempProps.mLocalHook.layout;
mLocalHook.scaledDensity = tempProps.mLocalHook.scaledDensity;
mLocalHook.density = tempProps.mLocalHook.density;
}
@@ -221,6 +230,10 @@ public int getDpi() {
return mLocalHook.active ? mLocalHook.dpi : mGlobalHook.dpi;
}
+ public int getLayout() {
+ return mLocalHook.active ? mLocalHook.layout : mGlobalHook.layout;
+ }
+
public float getScaledDensity() {
return mLocalHook.active ? mLocalHook.scaledDensity : mGlobalHook.scaledDensity;
}
@@ -442,6 +455,17 @@ public static int getActualProperty(String property) {
} else {
getProp = true;
}
+ } else if (property.endsWith(BEERBONG_LAYOUT_SUFFIX)) {
+ ApplicationInfo appInfo = getAppInfoFromPackageName(property.substring(0, property.length()
+ - BEERBONG_LAYOUT_SUFFIX.length()));
+ if(appInfo != null) {
+ boolean isSystemApp =
+ appInfo.sourceDir.substring(0, appInfo.sourceDir.lastIndexOf("/")).contains("system/app");
+ result = Integer.parseInt(getProperty(property, getProperty(BEERBONG_PREFIX + (isSystemApp ?
+ "system_default_layout" : "user_default_layout"))));
+ } else {
+ getProp = true;
+ }
} else if (property.endsWith("_dpi") || property.endsWith("_layout")) {
getProp = true;
}
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index dc3e4867d5e..b6e2d2a327b 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -599,7 +599,6 @@ public void onInputEvent(InputEvent event) {
private int mStatusBarDpi = 0;
SettingsObserver mSettingsObserver;
- UserInterfaceObserver mUserInterfaceObserver;
ShortcutManager mShortcutManager;
PowerManager.WakeLock mBroadcastWakeLock;
boolean mHavePendingMediaKeyRepeatWithWakeLock;
@@ -734,33 +733,6 @@ public void onChange(boolean selfChange) {
}
}
- class UserInterfaceObserver extends ContentObserver {
- UserInterfaceObserver(Handler handler) {
- super(handler);
- }
-
- void observe() {
- ContentResolver resolver = mContext.getContentResolver();
- resolver.registerContentObserver(Settings.System.getUriFor(
- Settings.System.USER_INTERFACE_STATE), false, this);
- }
-
- @Override
- public void onChange(boolean selfChange) {
- // Return for reset triggers
- if (Settings.System.getInt(mContext.getContentResolver(),
- Settings.System.USER_INTERFACE_STATE, 0) == 0) {
- return;
- }
-
- // Update layout
- update(true);
-
- // Reset trigger
- Settings.System.putInt(mContext.getContentResolver(), Settings.System.USER_INTERFACE_STATE, 0);
- }
- }
-
class MyOrientationListener extends WindowOrientationListener {
MyOrientationListener(Context context) {
super(context);
@@ -1173,16 +1145,38 @@ public void init(Context context, IWindowManager windowManager,
try {
mOrientationListener.setCurrentRotation(windowManager.getRotation());
} catch (RemoteException ex) { }
+
updateHybridLayout();
+
mSettingsObserver = new SettingsObserver(mHandler);
mSettingsObserver.observe();
+ // SystemUI reboot
+ mContext.getContentResolver().registerContentObserver(
+ Settings.System.getUriFor(Settings.System.USER_INTERFACE_STATE), false, new ContentObserver(new Handler()) {
+ @Override
+ public void onChange(boolean selfChange) {
+ // Return for reset triggers
+ if (Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.USER_INTERFACE_STATE, 0) == 0) {
+ return;
+ }
+
+ // Update layout
+ update(true);
+
+ // Reset trigger
+ Settings.System.putInt(mContext.getContentResolver(), Settings.System.USER_INTERFACE_STATE, 0);
+ }});
+
// Expanded desktop
mContext.getContentResolver().registerContentObserver(
Settings.System.getUriFor(Settings.System.EXPANDED_DESKTOP_STATE),
false, new ContentObserver(new Handler()) {
@Override
public void onChange(boolean selfChange) {
+ updateHybridLayout();
+ update(false);
// Restart default launcher activity
final PackageManager mPm = mContext.getPackageManager();
@@ -1206,8 +1200,6 @@ public void onChange(boolean selfChange) {
}
});
- mUserInterfaceObserver = new UserInterfaceObserver(mHandler);
- mUserInterfaceObserver.observe();
mShortcutManager = new ShortcutManager(context, mHandler);
mShortcutManager.observe();
mUiMode = context.getResources().getInteger(
@@ -1357,6 +1349,16 @@ public void setInitialDisplaySize(Display display, int width, int height, int de
}
mHdmiRotationLock = SystemProperties.getBoolean("persist.demo.hdmirotationlock", true);
}
+
+ private void closeApplication(String packageName) {
+ try {
+ ActivityManagerNative.getDefault().killApplicationProcess(
+ packageName, AppGlobals.getPackageManager().getPackageUid(
+ packageName, UserHandle.myUserId()));
+ } catch (RemoteException e) {
+ // Good luck next time!
+ }
+ }
private void update(boolean updateUi) {
if (updateUi) {
@@ -1366,28 +1368,20 @@ private void update(boolean updateUi) {
updateSettings();
updateRotation(false);
- // Bring down SystemUI
- if (updateUi) {
- // Restart UI if necessary
- String packageName = "com.android.systemui";
- try {
- ActivityManagerNative.getDefault().killApplicationProcess(
- packageName, AppGlobals.getPackageManager().getPackageUid(
- packageName, UserHandle.myUserId()));
- } catch (RemoteException e) {
- // Good luck next time!
- }
- }
+ if (updateUi) closeApplication("com.android.systemui");
}
private int updateHybridLayout() {
+ boolean expDesktop = Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.EXPANDED_DESKTOP_STATE, 0) == 1;
int oldSystemUILayout = mSystemUiLayout == 0 ?
ExtendedPropertiesUtils.getActualProperty("com.android.systemui.layout") : mSystemUiLayout;
ExtendedPropertiesUtils.refreshProperties();
mSystemDpi = ExtendedPropertiesUtils.getActualProperty("android.dpi");
mSystemUiDpi = ExtendedPropertiesUtils.getActualProperty("com.android.systemui.dpi");
mSystemUiLayout = ExtendedPropertiesUtils.getActualProperty("com.android.systemui.layout");
- int mNavigationBarPercent = Integer.parseInt(ExtendedPropertiesUtils.getProperty("com.android.systemui.navbar.dpi", "100"));
+android.util.Log.d("*********************************************", "UPDATE mSystemUiLayout=" + mSystemUiLayout);
+ int mNavigationBarPercent = expDesktop ? 0 : Integer.parseInt(ExtendedPropertiesUtils.getProperty("com.android.systemui.navbar.dpi", "100"));
mNavBarDpi = mNavigationBarPercent * mSystemUiDpi / 100;
int mStatusBarPercent = Integer.parseInt(ExtendedPropertiesUtils.getProperty("com.android.systemui.statusbar.dpi", "100"));
mStatusBarDpi = mStatusBarPercent * mSystemUiDpi / 100;
@@ -1618,6 +1612,7 @@ public void getDimensions(){
mNavigationBarWidthForRotation[mLandscapeRotation] = mNavigationBarWidthForRotation[mSeascapeRotation] =
Math.round(navigationBarWidth);
+android.util.Log.d("*********************************************", "mSystemUiLayout=" + mSystemUiLayout);
if (mSystemUiLayout < 600) {
// 0-599dp: "phone" UI with a separate status & navigation bar
mHasSystemNavBar = false;
@@ -4505,8 +4500,6 @@ public void onReceive(Context context, Intent intent) {
// observing the relevant settings for the newly-active user,
// and then updates our own bookkeeping based on the now-
// current user.
- mSettingsObserver.onChange(false);
- mUserInterfaceObserver.onChange(false);
// force a re-application of focused window sysui visibility.
// the window may never have been shown for this user
From bcbcc9a10bc06e7402f07e259dce8bc13e0858f5 Mon Sep 17 00:00:00 2001
From: YamilGhazi
Date: Thu, 28 Feb 2013 09:02:37 +0100
Subject: [PATCH 06/14] Get proper values
Change-Id: I406c5ff046bc766ad8145b5cbc4bd9af92c3a681
---
.../android/util/ExtendedPropertiesUtils.java | 15 ++++++++++-----
.../internal/policy/impl/PhoneWindowManager.java | 10 ----------
2 files changed, 10 insertions(+), 15 deletions(-)
diff --git a/core/java/android/util/ExtendedPropertiesUtils.java b/core/java/android/util/ExtendedPropertiesUtils.java
index 1d329b7ae29..616ffd3c5a6 100644
--- a/core/java/android/util/ExtendedPropertiesUtils.java
+++ b/core/java/android/util/ExtendedPropertiesUtils.java
@@ -103,11 +103,16 @@ public static void setAppConfiguration(BeerbongAppInfo info) {
// Load default values to be used in case that property is
// missing from configuration.
boolean isSystemApp = info.path.contains("system/app");
- int defaultDpi = Integer.parseInt(getProperty(BEERBONG_PREFIX + (isSystemApp ?
- "system_default_dpi" : (info.path.length() == 0 ? "0" : "user_default_dpi"))));
- /*int defaultLayout = Integer.parseInt(getProperty(BEERBONG_PREFIX + (isSystemApp ?
- "system_default_layout" : (info.path.length() == 0 ? "0" : "user_default_layout"))));*/
- int defaultLayout = getActualProperty("com.android.systemui.layout");
+ int defaultDpi = getActualProperty(BEERBONG_PREFIX + (isSystemApp ?
+ "system_default_dpi" : (info.path.length() == 0 ? "0" : "user_default_dpi")));
+ int defaultLayout = getActualProperty(BEERBONG_PREFIX + "user_default_layout");
+
+ if (defaultLayout == 0) {
+ defaultLayout = getActualProperty("com.android.systemui.layout");
+ }
+ if (defaultDpi == 0) {
+ defaultDpi = getActualProperty("com.android.systemui.dpi");
+ }
// Layout fetching.
info.layout = Integer.parseInt(getProperty(info.name + BEERBONG_LAYOUT_SUFFIX, String.valueOf(defaultLayout)));
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index b6e2d2a327b..3e9e5504ff4 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -1388,16 +1388,6 @@ private int updateHybridLayout() {
return oldSystemUILayout;
}
- private void closeApplication(String packageName) {
- try {
- ActivityManagerNative.getDefault().killApplicationProcess(
- packageName, AppGlobals.getPackageManager().getPackageUid(
- packageName, UserHandle.myUserId()));
- } catch (RemoteException e) {
- // Good luck next time!
- }
- }
-
public void updateSettings() {
ContentResolver resolver = mContext.getContentResolver();
boolean updateRotation = false;
From 5f153bbf5f12173c2b2abf3594b5cca257b09adb Mon Sep 17 00:00:00 2001
From: Grigori Goronzy
Date: Sat, 2 Mar 2013 17:49:51 +0100
Subject: [PATCH 07/14] FM Radio: avoid deadlock when disabling RDS
When RDS is being configured, the session mutex is hold. However,
when it is being disabled, RDS callbacks might still fire, and these
also try to hold the mutex, leading to a deadlock.
Temporary unlock the mutex while the vendor library is called to
work around.
Change-Id: Ic9751c7185fd8de4a7510225f54d23a22f042321
---
fmradio/jni/android_fmradio_Receiver.cpp | 3 +++
1 file changed, 3 insertions(+)
diff --git a/fmradio/jni/android_fmradio_Receiver.cpp b/fmradio/jni/android_fmradio_Receiver.cpp
index 78e3e1667ca..10a04669a96 100755
--- a/fmradio/jni/android_fmradio_Receiver.cpp
+++ b/fmradio/jni/android_fmradio_Receiver.cpp
@@ -1362,8 +1362,11 @@ static void androidFmRadioRxSetRDS(JNIEnv * env, jobject obj,
/* if in pause state temporary resume */
androidFmRadioTempResumeIfPaused(&fmReceiverSession);
+ /* temporary unlock to avoid deadlock with RDS callback */
+ pthread_mutex_unlock(fmReceiverSession.dataMutex_p);
retval = fmReceiverSession.vendorMethods_p->
set_rds_reception(&fmReceiverSession.vendorData_p, receiveRDS);
+ pthread_mutex_lock(fmReceiverSession.dataMutex_p);
androidFmRadioPauseIfTempResumed(&fmReceiverSession);
} else {
From d44c7d9ba8b925b616a2e57044c5c2ca1101c3dd Mon Sep 17 00:00:00 2001
From: Carrie Xu
Date: Tue, 30 Oct 2012 17:28:39 +0800
Subject: [PATCH 08/14] Correct the target app token for input method window
The root cause is:
There is a defect in window manager service: When a new
activity that can be ime target is added into window manager
but the Z order of input method window don't need to be
changed, then the target app token of input method window
would not be updated to new one. This defect may cause that
the layer of input method window is calculated incorrectly.
The solution:
Correct the target app token for input method window.
Change-Id: I008311e3c9b1cf5fc320b614d8675c183c506d50
---
.../java/com/android/server/wm/WindowManagerService.java | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index d414797991d..d9d2050579e 100755
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -1537,7 +1537,11 @@ boolean moveInputMethodWindowsIfNeededLocked(boolean needAssignLayers) {
pos++;
}
if (pos >= N) {
- // All is good!
+ // Z order is good.
+ // The IM target window may be changed, so update the mTargetAppToken.
+ if (imWin != null) {
+ imWin.mTargetAppToken = mInputMethodTarget.mAppToken;
+ }
return false;
}
}
From 065c74c6d32e3b8011efd86881265a0dbc85d7f9 Mon Sep 17 00:00:00 2001
From: Matthew Redman
Date: Fri, 1 Feb 2013 03:22:55 +0000
Subject: [PATCH 09/14] enable usb audio hot plugging
Change-Id: I527e0976b6cadacb67084348ffe2de192247529a
---
.../android/server/WiredAccessoryManager.java | 92 +++++++++++++++++++
1 file changed, 92 insertions(+)
diff --git a/services/java/com/android/server/WiredAccessoryManager.java b/services/java/com/android/server/WiredAccessoryManager.java
index 6e7dc679cd2..23271cb4772 100644
--- a/services/java/com/android/server/WiredAccessoryManager.java
+++ b/services/java/com/android/server/WiredAccessoryManager.java
@@ -85,8 +85,11 @@ final class WiredAccessoryManager implements WiredAccessoryCallbacks {
private final InputManagerService mInputManager;
private final boolean mUseDevInputEventForAudioJack;
+
+ private final Context mContext;
public WiredAccessoryManager(Context context, InputManagerService inputManager) {
+ mContext = context;
PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "WiredAccessoryManager");
mWakeLock.setReferenceCounted(false);
@@ -111,6 +114,9 @@ public void onReceive(Context ctx, Intent intent) {
}
},
new IntentFilter(Intent.ACTION_BOOT_COMPLETED), null, null);
+
+ // Observe ALSA uevents
+ this.UsbAudioObserver.startObserving("MAJOR=116");
}
private final class SettingsChangedReceiver extends BroadcastReceiver {
@@ -474,4 +480,90 @@ public int computeNewHeadsetState(int headsetState, int switchState) {
}
}
}
+
+ private final UEventObserver UsbAudioObserver = new UEventObserver() {
+ public void onUEvent(UEventObserver.UEvent event) {
+ if(LOG) Slog.v(WiredAccessoryManager.TAG, "USB AUDIO UEVENT: " + event.toString());
+
+ String action = event.get("ACTION");
+ String devName = event.get("DEVNAME");
+ String devPath = event.get("DEVPATH");
+ String major = event.get("MAJOR");
+ String minor = event.get("MINOR");
+
+ if(LOG){
+ Slog.v(WiredAccessoryManager.TAG,
+ "ACTION = " + action +
+ ", DEVNAME=" + devName +
+ ", MAJOR = " + major +
+ ", MINOR = " + minor +
+ ", DEVPATH = " + devPath);
+ }
+
+ // Is alsa device?
+ if (major.equals("116")) {
+ String devPathLower = devPath.toLowerCase();
+
+ if ((devPathLower.contains("usb")) && (!devPathLower.contains("gadget")) && (devPathLower.endsWith("p"))) {
+ // Get state (enabled/disabled)
+ int state = (action.equals("add") ? 1 : 0);
+
+ // Create data class
+ UsbAudioData usbAudioData = new UsbAudioData(state, Character.toString(devName.charAt(8)), Character.toString(devName.charAt(10)));
+
+ if(LOG) {
+ Slog.v(WiredAccessoryManager.TAG,
+ "cardNumber = " + usbAudioData.cardNumber +
+ ", deviceNumber = " + usbAudioData.deviceNumber +
+ ", channels = " + Integer.toString(usbAudioData.channels));
+ }
+
+ // Notify applications that the audio output is going to change
+ Intent noisyIntent = new Intent("android.media.AUDIO_BECOMING_NOISY");
+ WiredAccessoryManager.this.mContext.sendBroadcast(noisyIntent);
+
+ // Aquire wake lock before route change
+ WiredAccessoryManager.this.mWakeLock.acquire();
+
+ // Queue the route change
+ this.mHandler.sendMessageDelayed(this.mHandler.obtainMessage(0, usbAudioData), 500);
+ }
+ }
+ }
+
+ private final Handler mHandler = new Handler() {
+ public void handleMessage(Message message) {
+ UsbAudioData usbAudioData = (UsbAudioData)message.obj;
+
+ // Send USB_AUDIO_ACCESSORY_PLUG intent to notify that an USB audio device has been connected.
+ Intent usbAudioIntent = new Intent("android.intent.action.USB_AUDIO_ACCESSORY_PLUG");
+ usbAudioIntent.putExtra("state", usbAudioData.state);
+ usbAudioIntent.putExtra("card", Integer.parseInt(usbAudioData.cardNumber));
+ usbAudioIntent.putExtra("device", Integer.parseInt(usbAudioData.deviceNumber));
+ usbAudioIntent.putExtra("channels", usbAudioData.channels);
+
+ try {
+ WiredAccessoryManager.this.mContext.sendStickyBroadcast(usbAudioIntent);
+ } catch(Exception e) {
+ Slog.e(WiredAccessoryManager.TAG, "Unable to send intent: android.intent.action.USB_AUDIO_ACCESSORY_PLUG");
+ }
+
+ // Route change complete, release the wake lock
+ WiredAccessoryManager.this.mWakeLock.release();
+ }
+ };
+
+ final class UsbAudioData {
+ public int state;
+ public String cardNumber;
+ public String deviceNumber;
+ public int channels = 2;
+
+ public UsbAudioData(int state, String cardNumber, String deviceNumber) {
+ this.state = state;
+ this.cardNumber = cardNumber;
+ this.deviceNumber = deviceNumber;
+ }
+ };
+ };
}
From 01d6a286a88d239754b3a1641a9850bc94328c89 Mon Sep 17 00:00:00 2001
From: drcmda
Date: Wed, 6 Mar 2013 23:00:00 +0000
Subject: [PATCH 10/14] PWM: disable HW overlays for PIE
SurfaceFlinger wont wake up the GPU in SysUI's fullscreen state,
probably because it does not occupy any tangible region. That sets poor
PIE into software rendering, which has bad effects on transparency and
mdp compositioning. Disabling HW overlays as long as PIE is active seems
like a good alternative for now.
Change-Id: Ie7ed720edc5bbdd0cfb79c34a22996cf15fcd79b
---
.../policy/impl/PhoneWindowManager.java | 55 +++++++++++++++++++
1 file changed, 55 insertions(+)
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 3e9e5504ff4..c6d45c89382 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -56,6 +56,7 @@
import android.os.Looper;
import android.os.Message;
import android.os.Messenger;
+import android.os.Parcel;
import android.os.PowerManager;
import android.os.Process;
import android.os.RemoteException;
@@ -420,6 +421,9 @@ private void unregisterSelf() {
}
}
+ // HW overlays state
+ int mDisableOverlays = 0;
+
private static final class PointerLocationInputEventReceiver extends InputEventReceiver {
private final PointerLocationView mView;
@@ -1129,6 +1133,42 @@ public void run() {
});
}
+ private int updateFlingerOptions() {
+ int disableOverlays = 0;
+ try {
+ IBinder flinger = ServiceManager.getService("SurfaceFlinger");
+ if (flinger != null) {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken("android.ui.ISurfaceComposer");
+ flinger.transact(1010, data, reply, 0);
+ reply.readInt();
+ reply.readInt();
+ reply.readInt();
+ reply.readInt();
+ disableOverlays = reply.readInt();
+ reply.recycle();
+ data.recycle();
+ }
+ } catch (RemoteException ex) {
+ }
+ return disableOverlays;
+ }
+
+ private void writeDisableOverlaysOption(int state) {
+ try {
+ IBinder flinger = ServiceManager.getService("SurfaceFlinger");
+ if (flinger != null) {
+ Parcel data = Parcel.obtain();
+ data.writeInterfaceToken("android.ui.ISurfaceComposer");
+ data.writeInt(state);
+ flinger.transact(1008, data, null, 0);
+ data.recycle();
+ }
+ } catch (RemoteException ex) {
+ }
+ }
+
/** {@inheritDoc} */
public void init(Context context, IWindowManager windowManager,
WindowManagerFuncs windowManagerFuncs) {
@@ -1146,6 +1186,7 @@ public void init(Context context, IWindowManager windowManager,
mOrientationListener.setCurrentRotation(windowManager.getRotation());
} catch (RemoteException ex) { }
+ mDisableOverlays = updateFlingerOptions();
updateHybridLayout();
mSettingsObserver = new SettingsObserver(mHandler);
@@ -1175,6 +1216,20 @@ public void onChange(boolean selfChange) {
false, new ContentObserver(new Handler()) {
@Override
public void onChange(boolean selfChange) {
+
+ boolean expDesktop = Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.EXPANDED_DESKTOP_STATE, 0) == 1;
+
+ if (!expDesktop) {
+ // When leaving fullscreen switch back to original HW state
+ int disableOverlays = updateFlingerOptions();
+ if (disableOverlays != mDisableOverlays) writeDisableOverlaysOption(mDisableOverlays);
+ } else {
+ // Before switching to fullscreen safe current HW state, then disable
+ mDisableOverlays = updateFlingerOptions();
+ writeDisableOverlaysOption(1);
+ }
+
updateHybridLayout();
update(false);
From 32fc06c9ebd105d62005615c98b06255eb687703 Mon Sep 17 00:00:00 2001
From: drcmda
Date: Thu, 7 Mar 2013 17:12:52 +0000
Subject: [PATCH 11/14] add tabUI to HW overlays
Change-Id: Ib352cb05c0dca1155b3d1c8fe3da4b16de898e44
---
.../policy/impl/PhoneWindowManager.java | 30 +++++++++++--------
1 file changed, 17 insertions(+), 13 deletions(-)
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index c6d45c89382..7310d558209 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -1169,6 +1169,21 @@ private void writeDisableOverlaysOption(int state) {
}
}
+ private void updateHWOverlays() {
+ final boolean expDesktop = Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.EXPANDED_DESKTOP_STATE, 0) == 1;
+ if (expDesktop || mSystemUiLayout == 1000) {
+ // Before switching to fullscreen safe current HW state, then disable
+ mDisableOverlays = updateFlingerOptions();
+ writeDisableOverlaysOption(1);
+ }
+ else {
+ // When leaving fullscreen switch back to original HW state
+ int disableOverlays = updateFlingerOptions();
+ if (disableOverlays != mDisableOverlays) writeDisableOverlaysOption(mDisableOverlays);
+ }
+ }
+
/** {@inheritDoc} */
public void init(Context context, IWindowManager windowManager,
WindowManagerFuncs windowManagerFuncs) {
@@ -1205,6 +1220,7 @@ public void onChange(boolean selfChange) {
// Update layout
update(true);
+ updateHWOverlays();
// Reset trigger
Settings.System.putInt(mContext.getContentResolver(), Settings.System.USER_INTERFACE_STATE, 0);
@@ -1217,21 +1233,9 @@ false, new ContentObserver(new Handler()) {
@Override
public void onChange(boolean selfChange) {
- boolean expDesktop = Settings.System.getInt(mContext.getContentResolver(),
- Settings.System.EXPANDED_DESKTOP_STATE, 0) == 1;
-
- if (!expDesktop) {
- // When leaving fullscreen switch back to original HW state
- int disableOverlays = updateFlingerOptions();
- if (disableOverlays != mDisableOverlays) writeDisableOverlaysOption(mDisableOverlays);
- } else {
- // Before switching to fullscreen safe current HW state, then disable
- mDisableOverlays = updateFlingerOptions();
- writeDisableOverlaysOption(1);
- }
-
updateHybridLayout();
update(false);
+ updateHWOverlays();
// Restart default launcher activity
final PackageManager mPm = mContext.getPackageManager();
From 15f0604f2a274458035bd1cd13aefe81182deed5 Mon Sep 17 00:00:00 2001
From: aaronpoweruser
Date: Thu, 7 Mar 2013 10:14:49 -0800
Subject: [PATCH 12/14] PWM: check for expanded desktop on boot
Change-Id: I8f3883019b60138d8937bd85adc9231b0e18c595
---
.../src/com/android/internal/policy/impl/PhoneWindowManager.java | 1 +
1 file changed, 1 insertion(+)
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 7310d558209..24b5c31aa8f 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -1202,6 +1202,7 @@ public void init(Context context, IWindowManager windowManager,
} catch (RemoteException ex) { }
mDisableOverlays = updateFlingerOptions();
+ updateHWOverlays();
updateHybridLayout();
mSettingsObserver = new SettingsObserver(mHandler);
From 7046e38c5cb5335a33363e7509f9192c0dafa0a5 Mon Sep 17 00:00:00 2001
From: aaronpoweruser
Date: Fri, 22 Mar 2013 13:43:32 -0700
Subject: [PATCH 13/14] PIE: fix stuck pixel on screen redraw
Reverts: PWM: disable HW overlays for PIE de1cb4e
Uses a dummmy view to force the screen to be redrawn on screen update
Change-Id: Ia12e596f81583a3b6be1bef64ae9d46b32d410d2
---
.../systemui/statusbar/BaseStatusBar.java | 5 +-
.../policy/impl/PhoneWindowManager.java | 55 -------------------
2 files changed, 4 insertions(+), 56 deletions(-)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 1d4798bb39f..c666386eaf4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -524,13 +524,16 @@ private void addPieInLocation(int gravity) {
// Quick navigation bar trigger area
View pieControlsTrigger = new View(mContext);
-
+ // Create a dummy view to force the screen to redraw
+ View pieDummytrigger = new View(mContext);
// Store our views for removing / adding
mPieControlPanel = panel;
mPieControlsTrigger = pieControlsTrigger;
pieControlsTrigger.setOnTouchListener(new PieControlsTouchListener());
mWindowManager.addView(pieControlsTrigger, getPieTriggerLayoutParams(mContext, gravity));
+ mWindowManager.addView(pieDummytrigger, getPieTriggerLayoutParams(mContext,
+ gravity==Gravity.BOTTOM ? Gravity.TOP : Gravity.BOTTOM));
panel.init(mHandler, this, pieControlsTrigger, gravity);
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 24b5c31aa8f..19caf590230 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -1133,57 +1133,6 @@ public void run() {
});
}
- private int updateFlingerOptions() {
- int disableOverlays = 0;
- try {
- IBinder flinger = ServiceManager.getService("SurfaceFlinger");
- if (flinger != null) {
- Parcel data = Parcel.obtain();
- Parcel reply = Parcel.obtain();
- data.writeInterfaceToken("android.ui.ISurfaceComposer");
- flinger.transact(1010, data, reply, 0);
- reply.readInt();
- reply.readInt();
- reply.readInt();
- reply.readInt();
- disableOverlays = reply.readInt();
- reply.recycle();
- data.recycle();
- }
- } catch (RemoteException ex) {
- }
- return disableOverlays;
- }
-
- private void writeDisableOverlaysOption(int state) {
- try {
- IBinder flinger = ServiceManager.getService("SurfaceFlinger");
- if (flinger != null) {
- Parcel data = Parcel.obtain();
- data.writeInterfaceToken("android.ui.ISurfaceComposer");
- data.writeInt(state);
- flinger.transact(1008, data, null, 0);
- data.recycle();
- }
- } catch (RemoteException ex) {
- }
- }
-
- private void updateHWOverlays() {
- final boolean expDesktop = Settings.System.getInt(mContext.getContentResolver(),
- Settings.System.EXPANDED_DESKTOP_STATE, 0) == 1;
- if (expDesktop || mSystemUiLayout == 1000) {
- // Before switching to fullscreen safe current HW state, then disable
- mDisableOverlays = updateFlingerOptions();
- writeDisableOverlaysOption(1);
- }
- else {
- // When leaving fullscreen switch back to original HW state
- int disableOverlays = updateFlingerOptions();
- if (disableOverlays != mDisableOverlays) writeDisableOverlaysOption(mDisableOverlays);
- }
- }
-
/** {@inheritDoc} */
public void init(Context context, IWindowManager windowManager,
WindowManagerFuncs windowManagerFuncs) {
@@ -1201,8 +1150,6 @@ public void init(Context context, IWindowManager windowManager,
mOrientationListener.setCurrentRotation(windowManager.getRotation());
} catch (RemoteException ex) { }
- mDisableOverlays = updateFlingerOptions();
- updateHWOverlays();
updateHybridLayout();
mSettingsObserver = new SettingsObserver(mHandler);
@@ -1221,7 +1168,6 @@ public void onChange(boolean selfChange) {
// Update layout
update(true);
- updateHWOverlays();
// Reset trigger
Settings.System.putInt(mContext.getContentResolver(), Settings.System.USER_INTERFACE_STATE, 0);
@@ -1236,7 +1182,6 @@ public void onChange(boolean selfChange) {
updateHybridLayout();
update(false);
- updateHWOverlays();
// Restart default launcher activity
final PackageManager mPm = mContext.getPackageManager();
From 8aed94c19bd00631725e90832dcc62a5c4cc96f0 Mon Sep 17 00:00:00 2001
From: OliverGeith
Date: Sun, 7 Apr 2013 11:35:00 +0100
Subject: [PATCH 14/14] Consistent Icons for Powerwidget and Toggle-Tiles
---
.../drawable-hdpi/ic_qs_wifi_tether_off.png | Bin 3796 -> 1397 bytes
.../ic_qs_wifi_tether_off_light.png | Bin 4037 -> 1330 bytes
.../drawable-hdpi/ic_qs_wifi_tether_on.png | Bin 4039 -> 1606 bytes
.../res/drawable-hdpi/stat_2g3g_off.png | Bin 3549 -> 2028 bytes
.../res/drawable-hdpi/stat_2g3g_on.png | Bin 3737 -> 1993 bytes
.../SystemUI/res/drawable-hdpi/stat_3g_on.png | Bin 3571 -> 1993 bytes
.../res/drawable-hdpi/stat_airplane_off.png | Bin 1713 -> 1536 bytes
.../res/drawable-hdpi/stat_airplane_on.png | Bin 3811 -> 1816 bytes
.../res/drawable-hdpi/stat_bluetooth_off.png | Bin 1001 -> 2007 bytes
.../res/drawable-hdpi/stat_bluetooth_on.png | Bin 4194 -> 2146 bytes
.../drawable-hdpi/stat_brightness_auto.png | Bin 4436 -> 2230 bytes
.../res/drawable-hdpi/stat_brightness_mid.png | Bin 4338 -> 2400 bytes
.../res/drawable-hdpi/stat_brightness_off.png | Bin 1247 -> 1832 bytes
.../res/drawable-hdpi/stat_brightness_on.png | Bin 4487 -> 2538 bytes
.../res/drawable-hdpi/stat_data_off.png | Bin 1492 -> 1551 bytes
.../res/drawable-hdpi/stat_data_on.png | Bin 3528 -> 1847 bytes
.../res/drawable-hdpi/stat_flashlight_off.png | Bin 3327 -> 730 bytes
.../res/drawable-hdpi/stat_flashlight_on.png | Bin 3579 -> 868 bytes
.../res/drawable-hdpi/stat_gps_off.png | Bin 1093 -> 1696 bytes
.../res/drawable-hdpi/stat_gps_on.png | Bin 4313 -> 2026 bytes
.../drawable-hdpi/stat_lock_screen_off.png | Bin 1309 -> 752 bytes
.../res/drawable-hdpi/stat_lock_screen_on.png | Bin 3211 -> 845 bytes
.../res/drawable-hdpi/stat_lte_off.png | Bin 3010 -> 1159 bytes
.../res/drawable-hdpi/stat_lte_on.png | Bin 3327 -> 1370 bytes
.../res/drawable-hdpi/stat_media_next.png | Bin 3237 -> 526 bytes
.../res/drawable-hdpi/stat_media_pause.png | Bin 2969 -> 152 bytes
.../res/drawable-hdpi/stat_media_play.png | Bin 3207 -> 523 bytes
.../res/drawable-hdpi/stat_media_previous.png | Bin 3257 -> 566 bytes
.../drawable-hdpi/stat_orientation_off.png | Bin 1886 -> 1437 bytes
.../res/drawable-hdpi/stat_orientation_on.png | Bin 3765 -> 1693 bytes
.../res/drawable-hdpi/stat_ring_off.png | Bin 3838 -> 1486 bytes
.../res/drawable-hdpi/stat_ring_on.png | Bin 3823 -> 1457 bytes
.../drawable-hdpi/stat_ring_vibrate_on.png | Bin 3955 -> 1558 bytes
.../drawable-hdpi/stat_screen_timeout_off.png | Bin 1876 -> 2111 bytes
.../drawable-hdpi/stat_screen_timeout_on.png | Bin 3717 -> 2009 bytes
.../res/drawable-hdpi/stat_silent.png | Bin 3884 -> 1615 bytes
.../SystemUI/res/drawable-hdpi/stat_sleep.png | Bin 3534 -> 728 bytes
.../res/drawable-hdpi/stat_sync_off.png | Bin 1153 -> 1125 bytes
.../res/drawable-hdpi/stat_sync_on.png | Bin 4375 -> 1318 bytes
.../res/drawable-hdpi/stat_vibrate_off.png | Bin 1309 -> 1924 bytes
.../res/drawable-hdpi/stat_vibrate_on.png | Bin 3868 -> 2418 bytes
.../res/drawable-hdpi/stat_wifi_ap_off.png | Bin 3476 -> 1397 bytes
.../res/drawable-hdpi/stat_wifi_ap_on.png | Bin 4036 -> 1606 bytes
.../res/drawable-hdpi/stat_wifi_off.png | Bin 1140 -> 1301 bytes
.../res/drawable-hdpi/stat_wifi_on.png | Bin 4373 -> 1905 bytes
.../res/drawable-hdpi/stat_wimax_off.png | Bin 3169 -> 1390 bytes
.../res/drawable-hdpi/stat_wimax_on.png | Bin 3515 -> 1617 bytes
.../drawable-xhdpi/ic_qs_wifi_tether_off.png | Bin 3895 -> 1279 bytes
.../ic_qs_wifi_tether_off_light.png | Bin 4156 -> 1325 bytes
.../drawable-xhdpi/ic_qs_wifi_tether_on.png | Bin 3940 -> 1587 bytes
.../res/drawable-xhdpi/stat_2g3g_off.png | Bin 3237 -> 2587 bytes
.../res/drawable-xhdpi/stat_2g3g_on.png | Bin 3284 -> 2515 bytes
.../res/drawable-xhdpi/stat_3g_on.png | Bin 3244 -> 2586 bytes
.../res/drawable-xhdpi/stat_airplane_off.png | Bin 2046 -> 2957 bytes
.../res/drawable-xhdpi/stat_airplane_on.png | Bin 4157 -> 3248 bytes
.../res/drawable-xhdpi/stat_bluetooth_off.png | Bin 1314 -> 3474 bytes
.../res/drawable-xhdpi/stat_bluetooth_on.png | Bin 4774 -> 3513 bytes
.../drawable-xhdpi/stat_brightness_auto.png | Bin 5230 -> 2909 bytes
.../drawable-xhdpi/stat_brightness_mid.png | Bin 5123 -> 3107 bytes
.../drawable-xhdpi/stat_brightness_off.png | Bin 1711 -> 2987 bytes
.../res/drawable-xhdpi/stat_brightness_on.png | Bin 5385 -> 3237 bytes
.../res/drawable-xhdpi/stat_data_off.png | Bin 1691 -> 2056 bytes
.../res/drawable-xhdpi/stat_data_on.png | Bin 3525 -> 2863 bytes
.../drawable-xhdpi/stat_flashlight_off.png | Bin 3507 -> 960 bytes
.../res/drawable-xhdpi/stat_flashlight_on.png | Bin 3332 -> 1281 bytes
.../res/drawable-xhdpi/stat_gps_off.png | Bin 1497 -> 2515 bytes
.../res/drawable-xhdpi/stat_gps_on.png | Bin 5007 -> 3387 bytes
.../drawable-xhdpi/stat_lock_screen_off.png | Bin 1413 -> 1065 bytes
.../drawable-xhdpi/stat_lock_screen_on.png | Bin 3341 -> 1403 bytes
.../res/drawable-xhdpi/stat_lte_off.png | Bin 3053 -> 1488 bytes
.../res/drawable-xhdpi/stat_lte_on.png | Bin 3020 -> 2053 bytes
.../res/drawable-xhdpi/stat_media_next.png | Bin 3139 -> 614 bytes
.../res/drawable-xhdpi/stat_media_pause.png | Bin 2895 -> 268 bytes
.../res/drawable-xhdpi/stat_media_play.png | Bin 3139 -> 652 bytes
.../drawable-xhdpi/stat_media_previous.png | Bin 3164 -> 596 bytes
.../drawable-xhdpi/stat_orientation_off.png | Bin 2271 -> 2741 bytes
.../drawable-xhdpi/stat_orientation_on.png | Bin 4855 -> 2248 bytes
.../res/drawable-xhdpi/stat_ring_off.png | Bin 4441 -> 1939 bytes
.../res/drawable-xhdpi/stat_ring_on.png | Bin 4143 -> 2169 bytes
.../drawable-xhdpi/stat_ring_vibrate_on.png | Bin 4616 -> 2226 bytes
.../stat_screen_timeout_off.png | Bin 2296 -> 2972 bytes
.../drawable-xhdpi/stat_screen_timeout_on.png | Bin 4600 -> 2270 bytes
.../res/drawable-xhdpi/stat_silent.png | Bin 4441 -> 2038 bytes
.../res/drawable-xhdpi/stat_sleep.png | Bin 3607 -> 713 bytes
.../res/drawable-xhdpi/stat_sync_off.png | Bin 1521 -> 1543 bytes
.../res/drawable-xhdpi/stat_sync_on.png | Bin 5176 -> 2076 bytes
.../res/drawable-xhdpi/stat_vibrate_off.png | Bin 1840 -> 2927 bytes
.../res/drawable-xhdpi/stat_vibrate_on.png | Bin 4661 -> 4502 bytes
.../res/drawable-xhdpi/stat_wifi_ap_off.png | Bin 3776 -> 1279 bytes
.../res/drawable-xhdpi/stat_wifi_ap_on.png | Bin 3546 -> 1587 bytes
.../res/drawable-xhdpi/stat_wifi_off.png | Bin 1538 -> 2256 bytes
.../res/drawable-xhdpi/stat_wifi_on.png | Bin 5064 -> 3122 bytes
.../res/drawable-xhdpi/stat_wimax_off.png | Bin 3306 -> 1781 bytes
.../res/drawable-xhdpi/stat_wimax_on.png | Bin 3209 -> 2334 bytes
94 files changed, 0 insertions(+), 0 deletions(-)
mode change 100755 => 100644 packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_tether_off_light.png
mode change 100755 => 100644 packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_tether_off.png
mode change 100755 => 100644 packages/SystemUI/res/drawable-xhdpi/ic_qs_wifi_tether_on.png
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_tether_off.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_tether_off.png
index 4e6000f13e4d69140e47b25f4dc7182354052e9e..62097dba131e82992a3db11f5b8855e6eb355a81 100644
GIT binary patch
delta 1389
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
KMNUMnLSTaGYdWj|
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_tether_off_light.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_wifi_tether_off_light.png
old mode 100755
new mode 100644
index 955b323f05743c17705c6fb3d93f96107deaad9b..7309a034976fbc6a78f1394a5b7eff7ab9808893
GIT binary patch
delta 1312
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
oStuaxbY#=MW}g~UIjJ*B#2(3jozY8L>bXL
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