OSDN Git Service

Merge tag 'android-9.0.0_r53' into pie-x86 android-x86-9.0-r1
authorChih-Wei Huang <cwhuang@linux.org.tw>
Tue, 11 Feb 2020 02:50:54 +0000 (10:50 +0800)
committerChih-Wei Huang <cwhuang@linux.org.tw>
Tue, 11 Feb 2020 02:50:54 +0000 (10:50 +0800)
Android 9.0.0 Release 53 (6107734)

39 files changed:
Android.bp
cmds/incident_helper/src/parsers/PageTypeInfoParser.cpp
cmds/input/src/com/android/commands/input/Input.java
core/java/android/app/Activity.java
core/java/android/hardware/Camera.java
core/java/android/hardware/camera2/legacy/LegacyMetadataMapper.java
core/java/android/os/storage/DiskInfo.java
core/java/com/android/internal/content/NativeLibraryHelper.java
core/java/com/android/internal/os/RuntimeInit.java
core/jni/Android.bp
core/jni/abipicker/ABIPicker.cpp [new file with mode: 0644]
core/jni/abipicker/ABIPicker.h [new file with mode: 0644]
core/jni/abipicker/ELFLite.h [new file with mode: 0644]
core/jni/android/graphics/YuvToJpegEncoder.cpp
core/jni/android_view_ThreadedRenderer.cpp
core/jni/com_android_internal_content_NativeLibraryHelper.cpp
core/jni/fd_utils.cpp
core/res/res/values-zh-rCN/strings.xml
core/res/res/values-zh-rHK/strings.xml
core/res/res/values-zh-rTW/strings.xml
core/res/res/values/config.xml
core/res/res/values/strings.xml
core/res/res/values/symbols.xml
data/keyboards/Generic.kl
media/java/android/media/MediaFile.java
opengl/java/android/opengl/GLSurfaceView.java
packages/SystemUI/res/values/dimens.xml
packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
services/accessibility/java/com/android/server/accessibility/DisplayAdjustmentUtils.java
services/core/java/com/android/server/WiredAccessoryManager.java
services/core/java/com/android/server/input/InputManagerService.java
services/core/java/com/android/server/pm/PackageInstallerService.java
services/core/java/com/android/server/pm/PackageManagerService.java
services/core/java/com/android/server/policy/ImmersiveModeConfirmation.java
services/core/java/com/android/server/policy/PhoneWindowManager.java
services/core/java/com/android/server/power/PowerManagerService.java
services/core/java/com/android/server/wm/DisplayContent.java
services/core/jni/com_android_server_AlarmManagerService.cpp

index 22fe23d..eda4074 100644 (file)
@@ -665,6 +665,7 @@ java_library {
 
     static_libs: [
         "framework-protos",
+        "analytics-utils",
         "android.hidl.base-V1.0-java",
         "android.hardware.cas-V1.0-java",
         "android.hardware.contexthub-V1.0-java",
index 0615c74..bb587b5 100644 (file)
@@ -79,10 +79,10 @@ PageTypeInfoParser::Parse(const int in, const int out) const
                 // An example looks like:
                 // header line:      type    0   1   2 3 4 5 6 7 8 9 10
                 // record line: Unmovable  426 279 226 1 1 1 0 0 2 2  0
-                // The pageBlockOrder = 10 and it's zero-indexed. so total parts
-                // are 10 + 1(zero-indexed) + 1(the type part) = 12.
+                // The pageBlockOrder = 9 and it's zero-indexed. so total parts
+                // are 9 + 1(zero-indexed for pageBlockOrder) +1(zero-indexed) + 1(the type part) = 12.
                 record_t pageCounts = parseRecord(record[2]);
-                int pageCountsSize = pageBlockOrder + 2;
+                int pageCountsSize = pageBlockOrder + 3;
                 if ((int)pageCounts.size() != pageCountsSize) return BAD_VALUE;
 
                 proto.write(PageTypeInfoProto::MigrateType::TYPE, pageCounts[0]);
index d3ec320..96b230a 100644 (file)
@@ -198,9 +198,12 @@ public class Input {
         injectKeyEvent(new KeyEvent(now, now, KeyEvent.ACTION_DOWN, keyCode, 0, 0,
                 KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0, inputSource));
         if (longpress) {
-            injectKeyEvent(new KeyEvent(now, now, KeyEvent.ACTION_DOWN, keyCode, 1, 0,
-                    KeyCharacterMap.VIRTUAL_KEYBOARD, 0, KeyEvent.FLAG_LONG_PRESS,
-                    inputSource));
+            try {
+                Thread.sleep(1000);
+            } catch (InterruptedException e) {
+                throw new RuntimeException(e);
+            }
+            now = SystemClock.uptimeMillis();
         }
         injectKeyEvent(new KeyEvent(now, now, KeyEvent.ACTION_UP, keyCode, 0, 0,
                 KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0, inputSource));
index a6d2be0..1ea9d57 100644 (file)
@@ -132,6 +132,8 @@ import com.android.internal.policy.PhoneWindow;
 
 import dalvik.system.VMRuntime;
 
+import org.android_x86.analytics.AnalyticsHelper;
+
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.lang.annotation.Retention;
@@ -785,6 +787,7 @@ public class Activity extends ContextThemeWrapper
     boolean mFinished;
     boolean mStartedActivity;
     private boolean mDestroyed;
+    private boolean mAppsStatistics;
     private boolean mDoReportFullyDrawn = true;
     private boolean mRestoredFromBundle;
 
@@ -1051,6 +1054,7 @@ public class Activity extends ContextThemeWrapper
         }
         mRestoredFromBundle = savedInstanceState != null;
         mCalled = true;
+        mAppsStatistics = SystemProperties.getBoolean("persist.sys.apps_statistics", false);
     }
 
     /**
@@ -1275,6 +1279,12 @@ public class Activity extends ContextThemeWrapper
 
         mFragments.doLoaderStart();
 
+        // region @android-x86-analytics
+        // screen view
+        if (mAppsStatistics) {
+            AnalyticsHelper.hitScreen(this);
+        }
+        // endregion
         getApplication().dispatchActivityStarted(this);
 
         if (mAutoFillResetNeeded) {
index 9350aab..cabb691 100644 (file)
@@ -4337,6 +4337,8 @@ public class Camera {
                 return Float.parseFloat(mMap.get(key));
             } catch (NumberFormatException ex) {
                 return defaultValue;
+            } catch (NullPointerException ex) {
+                return defaultValue;
             }
         }
 
@@ -4346,6 +4348,8 @@ public class Camera {
                 return Integer.parseInt(mMap.get(key));
             } catch (NumberFormatException ex) {
                 return defaultValue;
+            } catch (NullPointerException ex) {
+                return defaultValue;
             }
         }
 
index 5423ca9..0063360 100644 (file)
@@ -405,7 +405,7 @@ public class LegacyMetadataMapper {
         /*
          * control.aeAvailableTargetFpsRanges
          */
-        {
+        try {
             List<int[]> fpsRanges = p.getSupportedPreviewFpsRange();
             if (fpsRanges == null) {
                 throw new AssertionError("Supported FPS ranges cannot be null.");
@@ -422,6 +422,8 @@ public class LegacyMetadataMapper {
                         (int) Math.ceil(r[Camera.Parameters.PREVIEW_FPS_MAX_INDEX] / 1000.0));
             }
             m.set(CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, ranges);
+        } catch (Exception e) {
+            Log.d(TAG, "ignore any error from getSupportedPreviewFpsRange: ", e);
         }
 
         /*
index d493cce..ae529ce 100644 (file)
@@ -48,6 +48,7 @@ public class DiskInfo implements Parcelable {
     public static final int FLAG_DEFAULT_PRIMARY = 1 << 1;
     public static final int FLAG_SD = 1 << 2;
     public static final int FLAG_USB = 1 << 3;
+    public static final int FLAG_CDROM = 1 << 6;
 
     public final String id;
     public final int flags;
@@ -108,6 +109,12 @@ public class DiskInfo implements Parcelable {
             } else {
                 return res.getString(com.android.internal.R.string.storage_usb_drive);
             }
+        } else if ((flags & FLAG_CDROM) != 0) {
+            if (isInteresting(label)) {
+                return res.getString(com.android.internal.R.string.storage_cdrom_label, label);
+            } else {
+                return res.getString(com.android.internal.R.string.storage_cdrom);
+            }
         } else {
             return null;
         }
index c388148..7a677fe 100644 (file)
@@ -78,6 +78,8 @@ public class NativeLibraryHelper {
         final boolean multiArch;
         final boolean extractNativeLibs;
         final boolean debuggable;
+        final String pkgName;
+        final String apkDir;
 
         public static Handle create(File packageFile) throws IOException {
             try {
@@ -89,19 +91,35 @@ public class NativeLibraryHelper {
         }
 
         public static Handle create(Package pkg) throws IOException {
+            String apkdir;
+            if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
+                apkdir = null;
+            } else {
+                apkdir = pkg.codePath;
+            }
             return create(pkg.getAllCodePaths(),
                     (pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) != 0,
                     (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTRACT_NATIVE_LIBS) != 0,
-                    (pkg.applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0);
+                    (pkg.applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0, pkg.packageName, apkdir);
+        }
+
+        private static String getApkDir(PackageLite lite) {
+            if (lite.codePath == null ||
+                lite.codePath.startsWith("/system/") ||
+                lite.codePath.startsWith("/vendor/") ||
+                lite.codePath.startsWith("/oem/")) {
+                return null;
+            }
+            return lite.codePath;
         }
 
         public static Handle create(PackageLite lite) throws IOException {
             return create(lite.getAllCodePaths(), lite.multiArch, lite.extractNativeLibs,
-                    lite.debuggable);
+                    lite.debuggable, lite.packageName, getApkDir(lite));
         }
 
         private static Handle create(List<String> codePaths, boolean multiArch,
-                boolean extractNativeLibs, boolean debuggable) throws IOException {
+                boolean extractNativeLibs, boolean debuggable, String pkgName, String apkdir) throws IOException {
             final int size = codePaths.size();
             final long[] apkHandles = new long[size];
             for (int i = 0; i < size; i++) {
@@ -116,7 +134,7 @@ public class NativeLibraryHelper {
                 }
             }
 
-            return new Handle(apkHandles, multiArch, extractNativeLibs, debuggable);
+            return new Handle(apkHandles, multiArch, extractNativeLibs, debuggable, pkgName, apkdir);
         }
 
         public static Handle createFd(PackageLite lite, FileDescriptor fd) throws IOException {
@@ -127,15 +145,17 @@ public class NativeLibraryHelper {
                 throw new IOException("Unable to open APK " + path + " from fd " + fd);
             }
 
-            return new Handle(apkHandles, lite.multiArch, lite.extractNativeLibs, lite.debuggable);
+            return new Handle(apkHandles, lite.multiArch, lite.extractNativeLibs, lite.debuggable, lite.packageName, getApkDir(lite));
         }
 
         Handle(long[] apkHandles, boolean multiArch, boolean extractNativeLibs,
-                boolean debuggable) {
+                boolean debuggable, String pkgName, String apkdir) {
             this.apkHandles = apkHandles;
             this.multiArch = multiArch;
             this.extractNativeLibs = extractNativeLibs;
             this.debuggable = debuggable;
+            this.pkgName = pkgName;
+            this.apkDir = apkdir;
             mGuard.open("close");
         }
 
@@ -211,7 +231,9 @@ public class NativeLibraryHelper {
     public static int findSupportedAbi(Handle handle, String[] supportedAbis) {
         int finalRes = NO_NATIVE_LIBRARIES;
         for (long apkHandle : handle.apkHandles) {
-            final int res = nativeFindSupportedAbi(apkHandle, supportedAbis, handle.debuggable);
+            final int res = nativeFindSupportedAbiReplace(apkHandle, supportedAbis,
+                    handle.debuggable, handle.pkgName, handle.apkDir);
+
             if (res == NO_NATIVE_LIBRARIES) {
                 // No native code, keep looking through all APKs.
             } else if (res == INSTALL_FAILED_NO_MATCHING_ABIS) {
@@ -233,8 +255,8 @@ public class NativeLibraryHelper {
         return finalRes;
     }
 
-    private native static int nativeFindSupportedAbi(long handle, String[] supportedAbis,
-            boolean debuggable);
+    private native static int nativeFindSupportedAbiReplace(long handle, String[] supportedAbis,
+            boolean debuggable, String pkgName, String apkdir);
 
     // Convenience method to call removeNativeBinariesFromDirLI(File)
     public static void removeNativeBinariesLI(String nativeLibraryPath) {
index a9cd5c8..f8caeb7 100644 (file)
@@ -39,6 +39,8 @@ import java.util.TimeZone;
 import java.util.logging.LogManager;
 import org.apache.harmony.luni.internal.util.TimezoneGetter;
 
+import org.android_x86.analytics.AnalyticsHelper;
+
 /**
  * Main entry point for runtime initialization.  Not for
  * public consumption.
@@ -62,6 +64,12 @@ public class RuntimeInit {
         return Log.printlns(Log.LOG_ID_CRASH, Log.ERROR, tag, msg, tr);
     }
 
+    // region @android-x86-analytics
+    // delay 120 seconds if Analytics failed to capture exception
+    private static final long ANDROID_X86_ANALYTICS_FAILED_DELAY = 120 * 1000;
+    private static long mAnalyticsEnableTime = 0;
+    // endregion
+
     /**
      * Logs a message when a thread encounters an uncaught exception. By
      * default, {@link KillApplicationHandler} will terminate this process later,
@@ -132,6 +140,23 @@ public class RuntimeInit {
                 if (mCrashing) return;
                 mCrashing = true;
 
+                // region @android-x86-analytics
+                if (System.currentTimeMillis() > mAnalyticsEnableTime &&
+                        SystemProperties.getBoolean("persist.sys.apps_statistics", false)) {
+                    try {
+                        AnalyticsHelper.captureException(
+                                ActivityThread.currentActivityThread().getSystemContext(),
+                                e,
+                                t.getName(),
+                                ActivityThread.currentPackageName());
+                    } catch (Throwable ex) {
+                        // delay some time to avoid endless loop exception
+                        mAnalyticsEnableTime =
+                                System.currentTimeMillis() + ANDROID_X86_ANALYTICS_FAILED_DELAY;
+                    }
+                }
+                // endregion
+
                 // Try to end profiling. If a profiler is running at this point, and we kill the
                 // process (below), the in-memory buffer will be lost. So try to stop, which will
                 // flush the buffer. (This makes method trace profiling useful to debug crashes.)
index 302189f..3468657 100644 (file)
@@ -21,6 +21,7 @@ cc_library_shared {
         "-DEGL_EGLEXT_PROTOTYPES",
 
         "-DU_USING_ICU_NAMESPACE=0",
+        "-D_PRC_COMPATIBILITY_PACKAGE_",
 
         "-Wall",
         "-Werror",
@@ -41,6 +42,7 @@ cc_library_shared {
         "com_android_internal_content_NativeLibraryHelper.cpp",
         "com_google_android_gles_jni_EGLImpl.cpp",
         "com_google_android_gles_jni_GLImpl.cpp", // TODO: .arm
+        "abipicker/ABIPicker.cpp",
         "android_app_Activity.cpp",
         "android_app_NativeActivity.cpp",
         "android_app_admin_SecurityLog.cpp",
diff --git a/core/jni/abipicker/ABIPicker.cpp b/core/jni/abipicker/ABIPicker.cpp
new file mode 100644 (file)
index 0000000..b20f4cd
--- /dev/null
@@ -0,0 +1,759 @@
+#define LOG_TAG "ABIPicker"
+
+#include "abipicker/ABIPicker.h"
+#include "abipicker/ELFLite.h"
+
+#include <androidfw/ZipFileRO.h>
+#include <androidfw/ZipUtils.h>
+#include <fnmatch.h>
+
+namespace android {
+#define ARR_SIZE(x)     (sizeof(x)/sizeof(x[0]))
+
+#define SO_NAME_MAX (4096)
+
+#define IMPOSSIBLE_LIB_NAME    "/mixed/"
+#define IMPOSSIBLE_LIB_LEN  (sizeof(IMPOSSIBLE_LIB_NAME)-1)
+
+#define ARMABI      "armeabi"
+#define ARMV7ABI    "armeabi-v7a"
+#define ARM64ABI    "arm64-v8a"
+#define X86ABI      "x86"
+#define X8664ABI    "x86_64"
+
+#define APK_LIB "lib/"
+#define APK_LIB_LEN (sizeof(APK_LIB) - 1)
+//#define PICK_LOGGER //flag to debug
+#ifdef PICK_LOGGER
+#define P_LOG(...) ALOGI(__VA_ARGS__)
+#else
+#define P_LOG(...)
+#endif
+
+#define LISTPATH    "/vendor/etc/misc/"
+#define OEMWHITE    LISTPATH ".OEMWhiteList"
+#define OEMBLACK    LISTPATH ".OEMBlackList"
+#define THIRDPARTY  LISTPATH ".ThirdPartySO"
+
+// load once, hold until poweroff
+static Vector <char*> thirdPartySO;
+static Vector <char*> cfgWhite;
+static Vector <char*> cfgBlack;
+static bool thirdload = false;
+static bool whiteload = false;
+static bool blackload = false;
+
+static const char* iaRelated[] = {"intel", "intl", "atom", "x86", "x64"};
+
+void freeAllString(Vector<char*>& list) {
+    Vector<char*>::iterator it = list.begin();
+    while (it != list.end()) {
+        if (*it != NULL) {
+           P_LOG("freeAllSring  %p , %s", it, *it);
+           free(*it);
+           *it = NULL;
+        }
+        it++;
+    }
+}
+
+void getConfig(const char* cfgFile , Vector<char*>& cfgVec) {
+    int read = -1;
+    char *line = NULL;
+    size_t len = 0;
+
+    FILE* fp = fopen(cfgFile, "r");
+    if (fp == NULL) {
+        return;
+    }
+
+    freeAllString(cfgVec);
+    cfgVec.clear();
+
+    while ((read = getline(&line, &len, fp)) != -1) {
+        int i = 0 , j = 0;
+        char *cfgline = (char*)malloc(len);
+        if (cfgline == NULL) {
+           P_LOG("malloc error");
+           break;
+        }
+        for (i = 0; i < read; i++) {
+           if (!isspace(line[i])) {
+              cfgline[j++] = line[i];
+           }
+        }
+        cfgline[j] = '\0';
+        cfgVec.push_back(cfgline);
+        P_LOG("orignal %s , vec: %s ", line, cfgline);
+    }
+    free(line);
+    fclose(fp);
+}
+
+bool isInOEMWhiteList(const char* pkgName) {
+    bool result = false;
+    if (pkgName == NULL) {
+        return result;
+    }
+
+    if (!whiteload) {
+       getConfig(OEMWHITE, cfgWhite);
+       whiteload = true;
+    }
+
+    Vector<char*>::iterator it = cfgWhite.begin();
+    for (; it != cfgWhite.end(); it++) {
+       P_LOG("whitelist : %s", *it);
+       if (0 == fnmatch(*it, pkgName, 0)) {
+          ALOGI("whitelist %s by %s", pkgName, *it);
+          result = true;
+          break;
+       }
+    }
+    return result;
+}
+
+bool isInOEMBlackList(const char* pkgName) {
+    bool result = false;
+    if (pkgName == NULL) {
+        return result;
+    }
+
+    if (!blackload) {
+       getConfig(OEMBLACK,  cfgBlack);
+       blackload = true;
+    }
+
+    Vector<char*>::iterator it = cfgBlack.begin();
+    for (; it != cfgBlack.end(); it++) {
+       if (0 == fnmatch(*it, pkgName, 0)) {
+          ALOGI("blacklist %s by %s", pkgName, *it);
+          result = true;
+          break;
+       }
+    }
+    return result;
+}
+
+bool isReliableLib(Vector<char*>& libList) {
+    unsigned sz = libList.size();
+    int len = ARR_SIZE(iaRelated);
+    for (unsigned i = 0; i < sz; i++) {
+        for (int j=0; j < len; j++) {
+            char* p = NULL;
+            if (NULL != (p = strcasestr(libList[i], iaRelated[j]))) {
+                int lenIA = strlen(iaRelated[j]);
+                if (!isalpha(*(p+lenIA))) {
+                    if (!isalpha(*(p-1)) || (p == (libList[i] + 3))) {
+                        return true;
+                    }
+                }
+            }
+        }
+    }
+
+    return false;
+}
+
+static bool isValidELF(char* buffer) {
+    if (buffer[EI_MAG0] != ELFMAG0 &&
+        buffer[EI_MAG1] != ELFMAG1 &&
+        buffer[EI_MAG2] != ELFMAG2 &&
+        buffer[EI_MAG3] != ELFMAG3) {
+        return false;
+    }
+    return true;
+}
+
+// assume that x86 has the only machine-code 3, and x86_64 62
+static bool isMixedLib(char* libCur, char* buffer) {
+    bool isX86_64 = (0 == strcmp(libCur, X8664ABI)) ? true: false;
+    uint16_t machine_code = *((uint16_t*)(&buffer[ELF_MACHINE_OFFSET]));
+    bool mixed = false;
+    if (isX86_64) {
+        if (machine_code != EM_X86_64) {
+            mixed = true;
+        }
+    } else {
+        if (machine_code != EM_386) {
+            mixed = true;
+        }
+    }
+    return mixed;
+}
+
+// compare the given string with the length, igonre upper and lower
+// len must be less than the length of two string
+static bool ignoreCmp(const char* str1, const char* str2, int len){
+    assert (str1 != NULL && str2 != NULL);
+    assert ((len <= strlen(str1)) && (len <= strlen(str2)));
+    for (int i = 0 ; i < len; i++) {
+        if (str1[i] != str2[i]) {
+            if(isalpha(str1[i]) && isalpha(str2[i])
+                    && (abs((str1[i]-str2[i])) == 32)) {
+                continue;
+            }
+            return false;
+        }
+    }
+    return true;
+}
+
+static bool isInThirdPartySOList(char* libName) {
+    assert (libName != NULL);
+    size_t libLen = strlen(libName);
+    size_t sz = thirdPartySO.size();
+    for (size_t i = 0; i < sz; i++) {
+        // thirdPartySO[i] won't be NULL
+        assert(thirdPartySO[i] != NULL);
+        size_t n = strlen(thirdPartySO[i]);
+        // three char for ".so"
+        int j = libLen - 4;
+        // now only '-' '-' and '.'found
+        while((j >= 0) && (isdigit(libName[j]) || (libName[j] == '-')
+              || (libName[j] == '_') || (libName[j] == '.'))) {
+            j--;
+        }
+        // three char for "lib" and include the name with no letters
+        if ((j == 2) || ((size_t)j == (n+2))) {
+            if (ignoreCmp(libName+3, thirdPartySO[i], n)) {
+                P_LOG("ABIpicker libName %s,In Third", libName);
+                return true;
+            }
+        }
+
+    }
+    return false;
+}
+
+static void insertionSort(Vector<char*>& list) {
+    P_LOG("in insertionSort, list size = %d\n", list.size());
+
+    for (size_t i = 1; i < list.size(); i++) {
+        int j = i - 1;
+        char* x = list[i];
+        P_LOG("sort 1. x=%s, i=%d, j=%d\n", x, i, j);
+        while (j >= 0 && (strcmp(list[j], x) > 0)) {
+            list.replaceAt(list[j], j + 1);
+            j--;
+        }
+        list.replaceAt(x, j + 1);
+    }
+}
+
+// Use armRef as a reference, compare all libraries of iaRef with all
+// libraries of armRef.If the two are match or iaRef is more, iaRef
+// will be returned with *result and true is return value. Or else,
+// *result is rawResult and false is return value
+bool ABIPicker::compare(char* armRef, char* iaRef,
+                        char* rawResult, char** result) {
+    bool ret = true;
+    *result = rawResult;
+
+    do {
+        assert(armRef != NULL);
+        if (0 == strlen(armRef)) {
+            *result = strlen(iaRef) > 0 ? iaRef : rawResult;
+            ret = strlen(iaRef) > 0 ? true : false;
+            break;
+        }
+        assert(iaRef != NULL);
+        if (0 == strlen(iaRef)) {
+            *result = armRef;
+            ret = false;
+            break;
+        }
+
+        Vector<char*>* iaRefList = getLibList(iaRef);
+        Vector<char*>* armRefList = getLibList(armRef);
+        if (iaRefList == NULL || armRefList == NULL) {
+            break;
+        }
+
+        if (isReliableLib(*iaRefList)) {
+            *result = iaRef;
+            break;
+        }
+
+        if (compareLibList(*iaRefList, *armRefList)) {
+            *result = iaRef;
+            break;
+        }
+
+        size_t iaIsvLibCount = 0;
+        size_t armIsvLibCount = 0;
+        if (!compare3rdPartyLibList(iaRef, armRef,
+                    &iaIsvLibCount, &armIsvLibCount)) {
+            *result = armRef;
+            ret = false;
+            break;
+        }
+
+        if (iaIsvLibCount > 0) {
+            *result = iaRef;
+            break;
+        }
+
+        *result = armRef;
+        ret = false;
+    } while (0);
+
+    ALOGV("%s Vs. %s, return %s\n",
+            iaRef ? iaRef : "NULL",
+            armRef ? armRef : "NULL", *result);
+    return ret;
+}
+
+bool ABIPicker::compareLibList(Vector<char*>& iaRefList,
+        Vector<char*>& armRefList) {
+
+    unsigned iaSize = iaRefList.size();
+    unsigned armSize = armRefList.size();
+    if (iaSize < armSize) {
+        return false;
+    } else if (iaSize == 0 && armSize == 0) {
+        return true;
+    }
+
+    int iaNum = 0;
+    int armNum = 0;
+    Vector<char*>::iterator itIa = iaRefList.begin();
+    Vector<char*>::iterator itArm = armRefList.begin();
+    bool isEqual = false;
+    while (itIa != iaRefList.end() && itArm != armRefList.end()) {
+        if ((iaSize-iaNum) < (armSize-armNum)) {
+            return false;
+        }
+        isEqual = false ;
+        char* armLibName = *itArm;
+        int armLen = strlen (armLibName);
+        armNum++;
+
+        while (itIa != iaRefList.end() && !isEqual) {
+            char* iaLibName = *itIa;
+            iaNum++;
+            int iaLen = strlen (iaLibName);
+            if (iaLen == armLen) {
+                if (ignoreCmp(iaLibName, armLibName, iaLen)) {
+                    isEqual = true;
+                }
+            }
+            itIa++;
+        }
+        itArm++;
+    }
+    // till the end, and the last result is equal
+    if (itArm == armRefList.end() && isEqual){
+        return true;
+    }
+
+    return false;
+}
+
+bool ABIPicker::compare3rdPartyLibList(
+                char* iaRef, char* armRef,
+                size_t* iaIsvLibCount, size_t* armIsvLibCount) {
+    bool result = true;
+
+    Vector<char*>* iaRefList = getLibList(iaRef);
+    Vector<char*>* armRefList = getLibList(armRef);
+    if (iaRefList == NULL || armRefList == NULL) {
+        return result;
+    }
+
+    if (!thirdload) {
+        getConfig(THIRDPARTY, thirdPartySO);
+        thirdload = true;
+    }
+
+    Vector<char*>* armRef3rdPartyLibList = new Vector<char*>();
+    Vector<char*>::iterator itArm = armRefList->begin();
+    while (itArm != armRefList->end()) {
+        char* armLibName = *itArm;
+        if (isInThirdPartySOList(armLibName)) {
+            armRef3rdPartyLibList->push_back(armLibName);
+        } else {
+            (*armIsvLibCount)++;
+        }
+
+        itArm++;
+    }
+
+    Vector<char*>::iterator itIa = iaRefList->begin();
+    Vector<char*>* iaRef3rdPartyLibList = new Vector<char*>();
+    while (itIa != iaRefList->end()) {
+        char* iaLibName = *itIa;
+        if (isInThirdPartySOList(iaLibName)) {
+            iaRef3rdPartyLibList->push_back(iaLibName);
+        } else {
+            (*iaIsvLibCount)++;
+        }
+
+        itIa++;
+    }
+    result = compareLibList(*iaRef3rdPartyLibList, *armRef3rdPartyLibList);
+
+    armRef3rdPartyLibList->clear();
+    delete armRef3rdPartyLibList;
+    iaRef3rdPartyLibList->clear();
+    delete iaRef3rdPartyLibList;
+    return result;
+}
+
+char* ABIPicker::getAbiName(int abi) {
+    if (abi <  0 || (unsigned)abi >= mLibList->size()) {
+        return NULL;
+    }
+
+    char* ret = NULL;
+    int index = 0;
+    Vector<struct libInfo*>::iterator it = mLibList->begin();
+    while (it != mLibList->end()) {
+        if (index == abi) {
+            ret = (*it)->abiName;
+            break;
+        }
+
+        index++;
+        it++;
+    }
+
+    return ret;
+}
+
+int ABIPicker::getAbiIndex(const char* abiName) {
+    int ret = -1;
+
+    int index = 0;
+    Vector<struct libInfo*>::iterator it = mLibList->begin();
+    while (it != mLibList->end()) {
+        if (0 == strcmp(abiName, (*it)->abiName)) {
+            ret = index;
+            break;
+        }
+
+        index++;
+        it++;
+    }
+
+    return ret;
+}
+
+Vector<char*>* ABIPicker::getLibList(const char* abiName) {
+    Vector<char*>* ret = NULL;
+    Vector<struct libInfo*>::iterator it = mLibList->begin();
+    while (it != mLibList->end()) {
+        if (0 == strcmp(abiName, (*it)->abiName)) {
+            ret = (*it)->libNameList;
+            break;
+        }
+        it++;
+    }
+    P_LOG("getLibList of %s return %p\n", abiName, ret);
+    return ret;
+}
+
+
+bool ABIPicker::isABILibValid(const char* abiName) {
+    Vector<char*>* specificAbiLibList = getLibList(abiName);
+    return ((specificAbiLibList && specificAbiLibList->size()) > 0);
+}
+
+bool ABIPicker::foundMixedELF(const char* abiName) {
+    Vector<char*>* libNameList = getLibList(abiName);
+    if (!libNameList) {
+        return false;
+    }
+    if (libNameList->size() == 0) {
+        return false;
+    }
+
+    if (0 != strcasecmp(*(libNameList->begin()), IMPOSSIBLE_LIB_NAME)) {
+        return false;
+    }
+
+    return true;
+}
+
+ABIPicker::ABIPicker(const char* pkgName, Vector<ScopedUtfChars*> abiList) {
+    mLibList = new Vector<struct libInfo*>();
+    mpkgName = strdup(pkgName);
+    if (mpkgName == NULL) {
+        P_LOG("ABIPicker Construct Allocated space fails");
+    }
+    Vector<ScopedUtfChars*>::iterator it = abiList.begin();
+    while (it != abiList.end()) {
+        if (!(*it)) {
+            break;
+        }
+
+        struct libInfo* tmp = (struct libInfo*)calloc(1,
+                sizeof(struct libInfo));
+        if (tmp == NULL) {
+           P_LOG("ABIPicker Construct Allocated space fail %s", (*it)->c_str());
+           break;
+        }
+
+        snprintf(tmp->abiName, (*it)->size() + 1, "%s", (*it)->c_str());
+        tmp->libNameList = new Vector<char*>();
+        P_LOG("ABIPicker Construct %s , libNameList: %p",
+             tmp->abiName, tmp->libNameList);
+        mLibList->push_back(tmp);
+        it++;
+    }
+}
+
+ABIPicker::~ABIPicker(void) {
+    free(mpkgName);
+    mpkgName = NULL;
+    Vector<struct libInfo*>::iterator it = mLibList->begin();
+    while (it != mLibList->end()) {
+        freeAllString(*((*it)->libNameList));
+        (*it)->libNameList->clear();
+        delete (*it)->libNameList;
+        (*it)->libNameList = NULL;
+
+        free(*it);
+        *it = NULL;
+        it++;
+    }
+    mLibList->clear();
+    delete mLibList;
+}
+
+bool ABIPicker::buildNativeLibList(void* apkHandle) {
+    bool ret = false;
+
+    if (apkHandle == NULL) {
+        ALOGE("apkHandle is NULL\n");
+        return ret;
+    }
+
+    ZipFileRO* zipFile = reinterpret_cast<ZipFileRO*>(apkHandle);
+    void* cookie = NULL;
+    if (!zipFile->startIteration(&cookie)) {
+        ALOGE("apk file is broken\n");
+        return ret;
+    }
+
+    ZipEntryRO next = NULL;
+    char* unCompBuff = NULL;
+    char fileName[SO_NAME_MAX + 1];
+    while ((next = zipFile->nextEntry(cookie))) {
+        if (zipFile->getEntryFileName(next, fileName, SO_NAME_MAX)) {
+            ALOGE("apk file is broken, can not get entry name\n");
+            ret = false;
+            break;
+        }
+        fileName[SO_NAME_MAX] = '\0';
+
+        // Make sure we're in the lib directory of the ZIP.
+        // find out entries with such names: "lib/xxxxxxx" or "lib/"
+        if (strncmp(fileName, APK_LIB, APK_LIB_LEN)) {
+            continue;
+        }
+
+        // find out any invalid ELF file
+        uint32_t unCompLen = 0;
+        if (!zipFile->getEntryInfo(next, NULL, &unCompLen, NULL, NULL, NULL,
+                                    NULL)) {
+            ALOGE("apk file is broken, can not get entry info\n");
+            ret = false;
+            break;
+        }
+
+        if (unCompLen == 0) {
+            ALOGV("skip a empty file(%s)\n", fileName);
+            continue;
+        }
+
+        free(unCompBuff);
+        unCompBuff = NULL;
+
+        unCompBuff = (char*)malloc(unCompLen);
+        if (unCompBuff == NULL) {
+            ALOGE("malloc failed size %d\n", unCompLen);
+            ret = false;
+            break;
+        }
+        memset(unCompBuff, 0, unCompLen);
+        // THE MOST TIME COST OPERATION
+        if (!zipFile->uncompressEntry(next, unCompBuff, unCompLen)) {
+            ALOGE("%s: uncompress failed\n", fileName);
+            ret = false;
+            break;
+        }
+
+        if (!isValidELF(unCompBuff)) {
+            ALOGI("skip a fake .ELF file(%s)\n", fileName);
+            continue;
+        }
+
+        // It is a real .so file, prepare to record
+        // find abi name and focus on what we care: arm(s) and x86(s)
+        // at least lastSlash points to the end of "lib/"
+        const char* lastSlash = strrchr(fileName, '/');
+        const char* cpuAbiOffset = fileName + APK_LIB_LEN;
+        // just in case if fileName is in an abnormal format, like lib/libname,
+        // lib//libname
+        if (lastSlash <= cpuAbiOffset) {
+            ALOGI("skip a invalid lib file(%s)\n", fileName);
+            continue;
+        }
+
+        const size_t cpuAbiRegionSize = lastSlash - cpuAbiOffset;
+        char curAbiName[ABI_NAME_MAX_LENGTH];
+        if (cpuAbiRegionSize >= ABI_NAME_MAX_LENGTH) {
+            continue;
+        }
+        snprintf(curAbiName, cpuAbiRegionSize + 1, "%s", cpuAbiOffset);
+
+        Vector<char*>* libListOfCurAbi = getLibList(curAbiName);
+        if (!libListOfCurAbi) {
+            P_LOG("getLibList of %s return NULL\n", curAbiName);
+            continue;
+        }
+
+        // mixed arm elf in lib/x86 or lib/x86_64
+        // but we don't consider a compareable scenario in lib/arm*
+        if (0 == strcmp(curAbiName, X86ABI) ||
+                0 == strcmp(curAbiName, X8664ABI)) {
+            if (!libListOfCurAbi->empty()) {
+                char* firstElement = libListOfCurAbi->itemAt(0);
+                if (0 == strcmp(firstElement, IMPOSSIBLE_LIB_NAME)) {
+                    // won't add any new into the list if found mixed
+                    // lib before
+                    P_LOG("won't count count if found mixed lib before");
+                    continue;
+                }
+            }
+
+            if (isMixedLib(curAbiName, unCompBuff)) {
+                P_LOG("found mixed lib(%s) in lib/%s/", curAbiName, fileName);
+                freeAllString(*libListOfCurAbi);
+                libListOfCurAbi->clear();
+                char* mixedLib = (char*)malloc(IMPOSSIBLE_LIB_LEN+1);
+                if (!mixedLib) {
+                    ALOGE("malloc failed size %zu", IMPOSSIBLE_LIB_LEN + 1);
+                    ret = false;
+                    break;
+                }
+                snprintf(mixedLib, (IMPOSSIBLE_LIB_LEN+1), "%s", IMPOSSIBLE_LIB_NAME);
+                mixedLib[IMPOSSIBLE_LIB_LEN] ='\0';
+                libListOfCurAbi->push_back(mixedLib);
+                continue;
+            }
+        }
+
+        // now, lastSlash should point to lib name
+        lastSlash++;
+        const size_t libNameSize = strlen(lastSlash);
+        char* curLibName = (char*)malloc(libNameSize+1);
+        if (!curLibName) {
+            ALOGE("malloc failed size %zu\n", libNameSize+1);
+            ret = false;
+            break;
+        }
+        snprintf(curLibName,libNameSize+1, "%s", lastSlash);
+        curLibName[libNameSize] = '\0';
+
+        libListOfCurAbi->push_back(curLibName);
+
+        ret = true;
+    }
+
+    free(unCompBuff);
+    unCompBuff = NULL;
+
+    zipFile->endIteration(cookie);
+
+    for (unsigned i = 0; i < mLibList->size(); i++) {
+        struct libInfo* tmp = mLibList->itemAt(i);
+        insertionSort(*(tmp->libNameList));
+    }
+    return ret;
+}
+
+int ABIPicker::pickupRightABI(int sysPrefer) {
+    char* sysPreferAbiName = getAbiName(sysPrefer);
+    if (!sysPreferAbiName) {
+        return sysPrefer;
+    }
+
+    bool is64BitPrefer = (0 == strcmp(sysPreferAbiName, X8664ABI));
+    bool x8664HasMixedELF = foundMixedELF(X8664ABI);
+    bool x86HasMixedELF = foundMixedELF(X86ABI);
+
+    bool armv7LibValid = isABILibValid(ARMV7ABI);
+    bool armv5LibValid = isABILibValid(ARMABI);
+    bool armv8LibValid = isABILibValid(ARM64ABI);
+    bool x86LibValid = x86HasMixedELF ? 0 : isABILibValid(X86ABI);
+    bool x8664LibValid = x8664HasMixedELF ? 0 : isABILibValid(X8664ABI);
+
+    // in OEMBlackList, need to be supported by bt
+    // but in case of armlib doesn't exist, we choose x86 or x86_64
+    if (isInOEMBlackList(mpkgName)) {
+        if (armv7LibValid) {
+            return getAbiIndex(ARMV7ABI);
+        } else if (armv5LibValid) {
+            return getAbiIndex(ARMABI);
+        } else if (armv8LibValid) {
+            return getAbiIndex(ARM64ABI);
+        }
+    }
+
+    char arm64Ref[ABI_NAME_MAX_LENGTH];
+    if (armv8LibValid) {
+        snprintf(arm64Ref, sizeof(ARM64ABI), "%s", ARM64ABI);
+    } else {
+        arm64Ref[0] = '\0';
+    }
+
+    char arm32Ref[ABI_NAME_MAX_LENGTH];
+    if (armv7LibValid) {
+        snprintf(arm32Ref, sizeof(ARMV7ABI), "%s", ARMV7ABI);
+    } else if (armv5LibValid) {
+        snprintf(arm32Ref, sizeof(ARMABI), "%s", ARMABI);
+    } else {
+        arm32Ref[0] = '\0';
+    }
+
+    char ia32Ref[ABI_NAME_MAX_LENGTH];
+    if (x86LibValid) {
+        snprintf(ia32Ref, sizeof(X86ABI), "%s", X86ABI);
+    } else {
+        ia32Ref[0] = '\0';
+    }
+
+    char ia64Ref[ABI_NAME_MAX_LENGTH];
+    if (x8664LibValid) {
+        snprintf(ia64Ref, ABI_NAME_MAX_LENGTH, "%s", X8664ABI);
+    } else {
+        ia64Ref[0] = '\0';
+    }
+
+    char* retAbiName = sysPreferAbiName;
+    do {
+        // # The basic rule is:
+        // - on 32 bit system, compare ia32Ref native libraries with
+        // arm32Ref native libraries. If pass, return ia32Ref .
+        // If fail, return arm32Ref.
+        // - on 64 bit system, IA has two chances. if ia64Ref native
+        // libraries can't pass the comparation with arm64Ref, we should
+        // run the comparation again with ia32Ref
+        if (is64BitPrefer) {
+            if (!compare(arm64Ref, ia64Ref, sysPreferAbiName, &retAbiName)) {
+                char rawRes[ABI_NAME_MAX_LENGTH];
+                snprintf(rawRes, ABI_NAME_MAX_LENGTH, "%s", retAbiName);
+                compare(arm32Ref, ia32Ref, rawRes, &retAbiName);
+            }
+        } else {
+            compare(arm32Ref, ia32Ref, sysPreferAbiName, &retAbiName);
+        }
+    } while (0);
+    int ret = getAbiIndex(retAbiName);
+    ALOGI("selected abi %s(%d) for %s", retAbiName, ret, mpkgName);
+    return ret;
+}
+
+}  // namespace android
diff --git a/core/jni/abipicker/ABIPicker.h b/core/jni/abipicker/ABIPicker.h
new file mode 100644 (file)
index 0000000..dc5102c
--- /dev/null
@@ -0,0 +1,44 @@
+#ifndef _ABIPICKER_H_
+#define _ABIPICKER_H_
+
+#include <jni.h>
+#include <stdlib.h>
+#include <utils/Vector.h>
+#include <sys/types.h>
+
+#include <nativehelper/ScopedUtfChars.h>
+
+namespace android {
+//  assumption: the length of name of any abi type in abi list,
+//  like armeabi-v7a, armeabi, x86, is not longer than 64
+#define ABI_NAME_MAX_LENGTH     (64)
+
+class ABIPicker {
+ public:
+    explicit ABIPicker(const char* pkgName,Vector<ScopedUtfChars*> abiList);
+    ~ABIPicker(void);
+
+    bool buildNativeLibList(void* apkHandle);
+    int  pickupRightABI(int sysPrefer);
+ private:
+    struct libInfo{
+        char abiName[ABI_NAME_MAX_LENGTH];
+        Vector<char*>* libNameList;
+    };
+    Vector<struct libInfo*>* mLibList;
+    char* mpkgName;
+
+    bool foundMixedELF(const char* abiName);
+    bool compare(char* armRef, char* iaRef, char* rawResult, char** result);
+    bool compareLibList(Vector<char*>& iaRefList, Vector<char*>& armRefList);
+    bool compare3rdPartyLibList( char* iaRef, char* armRef,
+            size_t* iaIsvLibCount, size_t* armIsvLibCount);
+    char*  getAbiName(int abi);
+    int    getAbiIndex(const char* abiName);
+    bool isABILibValid(const char* abiName);
+    Vector<char*>* getLibList(const char* abiName);
+};
+
+bool isInOEMWhiteList(const char* pkgName);
+}  // namespace android
+#endif  // _ABIPICKER_H_
diff --git a/core/jni/abipicker/ELFLite.h b/core/jni/abipicker/ELFLite.h
new file mode 100644 (file)
index 0000000..e609e8a
--- /dev/null
@@ -0,0 +1,58 @@
+#ifndef _ELFLITE_H__
+#define _ELFLITE_H__
+
+#include <ctype.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+namespace android {
+#define EI_NIDENT   16   /* Size of e_ident[] */
+
+/*
+ * Fields in e_ident[]
+ */
+#define EI_MAG0     0    /* File identification byte 0 index */
+#define ELFMAG0     0x7F /* Magic number byte 0 */
+#define EI_MAG1     1    /* File identification byte 1 index */
+#define ELFMAG1     'E'  /* Magic number byte 1 */
+#define EI_MAG2     2    /* File identification byte 2 index */
+#define ELFMAG2     'L'  /* Magic number byte 2 */
+#define EI_MAG3     3    /* File identification byte 3 index */
+#define ELFMAG3     'F'  /* Magic number byte 3 */
+
+/*
+ * according to implementations of ELF Header
+ *     unsigned char e_ident[16];        // ELF "magic number"
+ *     unsigned char e_type[2];          // Identifies object file type
+ *     unsigned char e_machine[2];       // Specifies required architecture
+ */
+#define ELF_MACHINE_OFFSET  18
+
+/*
+ * Values for e_machine, which identifies the architecture.  These numbers
+ * are officially assigned by registry@sco.com.  See below for a list of
+ * ad-hoc numbers used during initial development.
+ * Please always sync them.
+ */
+#define EM_386        3 /* Intel 80386 */
+#define EM_486        6 /* Intel 80486 */
+#define EM_860        7 /* Intel 80860 */
+#define EM_960       19 /* Intel 80960 */
+#define EM_ARM       40 /* ARM */
+#define EM_IA_64     50 /* Intel IA-64 Processor */
+#define EM_X86_64    62 /* AMD x86-64 architecture */
+#define EM_8051     165 /* Intel 8051 and variants */
+#define EM_L1OM     180 /* Intel L1OM */
+#define EM_K1OM     181 /* Intel K1OM */
+#define EM_INTEL182 182 /* Reserved by Intel */
+#define EM_AARCH64  183 /* ARM 64-bit architecture */
+#define EM_ARM184   184 /* Reserved by ARM */
+#define EM_INTEL205 205 /* Reserved by Intel */
+#define EM_INTEL206 206 /* Reserved by Intel */
+#define EM_INTEL207 207 /* Reserved by Intel */
+#define EM_INTEL208 208 /* Reserved by Intel */
+#define EM_INTEL209 209 /* Reserved by Intel */
+}  // namespace android
+#endif  // _ELFLITE_H__
index 09adc82..2f5507d 100644 (file)
@@ -58,6 +58,7 @@ bool YuvToJpegEncoder::encode(SkWStream* stream, void* inYuv, int width,
     compress(&cinfo, (uint8_t*) inYuv, offsets);
 
     jpeg_finish_compress(&cinfo);
+    jpeg_destroy_compress(&cinfo);
 
     jpeg_destroy_compress(&cinfo);
 
@@ -96,13 +97,19 @@ void Yuv420SpToJpegEncoder::compress(jpeg_compress_struct* cinfo,
     planes[1] = cb;
     planes[2] = cr;
 
-    int width = cinfo->image_width;
-    int height = cinfo->image_height;
+    JDIMENSION width = cinfo->image_width;
+    JDIMENSION height = cinfo->image_height;
     uint8_t* yPlanar = yuv + offsets[0];
     uint8_t* vuPlanar = yuv + offsets[1]; //width * height;
-    uint8_t* uRows = new uint8_t [8 * (width >> 1)];
-    uint8_t* vRows = new uint8_t [8 * (width >> 1)];
-
+    uint8_t* uRows = new uint8_t [8 * (((width + 15) & ~15) >> 1)];
+    uint8_t* vRows = new uint8_t [8 * (((width + 15) & ~15) >> 1)];
+    uint8_t* yRows;
+    int lastLines;
+
+    if ((height & 0xf) != 0) {
+        lastLines = height & 0xf;
+        yRows = new uint8_t [16 * ((width + 15) & ~15)];
+    }
 
     // process 16 lines of Y and 8 lines of U/V each time.
     while (cinfo->next_scanline < cinfo->image_height) {
@@ -111,8 +118,11 @@ void Yuv420SpToJpegEncoder::compress(jpeg_compress_struct* cinfo,
 
         // Jpeg library ignores the rows whose indices are greater than height.
         for (int i = 0; i < 16; i++) {
-            // y row
-            y[i] = yPlanar + (cinfo->next_scanline + i) * fStrides[0];
+            // y row. Add padding if height isn't aligned to 16 pixels.
+            if ((height & 0xf) != 0 && (cinfo->next_scanline + i) > height)
+                y[i] = &yRows[(i - lastLines) * ((width + 15) & ~15)];
+            else
+                y[i] = yPlanar + (cinfo->next_scanline + i) * fStrides[0];
 
             // construct u row and v row
             if ((i & 1) == 0) {
@@ -124,6 +134,8 @@ void Yuv420SpToJpegEncoder::compress(jpeg_compress_struct* cinfo,
           }
         jpeg_write_raw_data(cinfo, planes, 16);
     }
+    if ((height & 0xf) != 0)
+        delete [] yRows;
     delete [] uRows;
     delete [] vRows;
 
@@ -131,9 +143,12 @@ void Yuv420SpToJpegEncoder::compress(jpeg_compress_struct* cinfo,
 
 void Yuv420SpToJpegEncoder::deinterleave(uint8_t* vuPlanar, uint8_t* uRows,
         uint8_t* vRows, int rowIndex, int width, int height) {
-    int numRows = (height - rowIndex) / 2;
-    if (numRows > 8) numRows = 8;
-    for (int row = 0; row < numRows; ++row) {
+    int lines = 16;
+    //In case there isn't enough lines to process
+    if ((rowIndex + lines) > height)
+        lines = (height - rowIndex);
+
+    for (int row = 0; row < (lines >> 1); ++row) {
         int offset = ((rowIndex >> 1) + row) * fStrides[1];
         uint8_t* vu = vuPlanar + offset;
         for (int i = 0; i < (width >> 1); ++i) {
index ee9a123..36a9b2a 100644 (file)
@@ -1030,6 +1030,10 @@ static jobject android_view_ThreadedRenderer_createHardwareBitmapFromRenderNode(
         // Continue I guess?
     }
     sk_sp<Bitmap> bitmap = Bitmap::createFrom(buffer);
+    if (!bitmap.get()) {
+        ALOGW("Failed to create hardware bitmap from graphic buffer");
+        return nullptr;
+    }
     return bitmap::createBitmap(env, bitmap.release(),
             android::bitmap::kBitmapCreateFlag_Premultiplied);
 }
index cc2646c..823b45f 100644 (file)
 
 #include <memory>
 
+#ifdef _PRC_COMPATIBILITY_PACKAGE_
+#include "abipicker/ABIPicker.h"
+#endif
+
 #define APK_LIB "lib/"
 #define APK_LIB_LEN (sizeof(APK_LIB) - 1)
 
 #define TMP_FILE_PATTERN "/tmp.XXXXXX"
 #define TMP_FILE_PATTERN_LEN (sizeof(TMP_FILE_PATTERN) - 1)
 
+#ifdef _PRC_COMPATIBILITY_PACKAGE_
+#define X86ABI     "x86"
+#define X8664ABI   "x86_64"
+#endif
+
 namespace android {
 
 // These match PackageManager.java install codes
@@ -507,10 +516,102 @@ com_android_internal_content_NativeLibraryHelper_sumNativeBinaries(JNIEnv *env,
 }
 
 static jint
-com_android_internal_content_NativeLibraryHelper_findSupportedAbi(JNIEnv *env, jclass clazz,
-        jlong apkHandle, jobjectArray javaCpuAbisToSearch, jboolean debuggable)
+com_android_internal_content_NativeLibraryHelper_findSupportedAbi_replace(
+        JNIEnv *env,
+        jclass clazz,
+        jlong apkHandle,
+        jobjectArray javaCpuAbisToSearch,
+        jboolean debuggable,
+        jstring apkPkgName,
+        jstring apkDir)
 {
-    return (jint) findSupportedAbi(env, apkHandle, javaCpuAbisToSearch, debuggable);
+#ifdef _PRC_COMPATIBILITY_PACKAGE_
+
+    int abiType = findSupportedAbi(env, apkHandle, javaCpuAbisToSearch, debuggable);
+    if (apkDir == NULL) {
+        return (jint)abiType;
+    }
+
+    char abiFlag[256] = {'\0'};
+    ScopedUtfChars apkdir(env, apkDir);
+    size_t apkdir_size = apkdir.size();
+    const int numAbis = env->GetArrayLength(javaCpuAbisToSearch);
+    Vector<ScopedUtfChars*> supportedAbis;
+
+    assert(apkdir_size < 256 - 15);
+    if (strlcpy(abiFlag, apkdir.c_str(), 256) != apkdir.size()) {
+        return (jint)abiType;
+    }
+
+    int abiIndex = 0;
+    abiFlag[apkdir_size] = '/';
+    abiFlag[apkdir_size + 1] = '.';
+    for (abiIndex = 0; abiIndex < numAbis; abiIndex++) {
+        ScopedUtfChars* abiName = new ScopedUtfChars(env,
+                 (jstring)env->GetObjectArrayElement(javaCpuAbisToSearch, abiIndex));
+        supportedAbis.push_back(abiName);
+        if (abiName == NULL || abiName->c_str() == NULL || abiName->size() <= 0) {
+            break;
+        }
+        if ((strlcpy(abiFlag + apkdir_size + 2, abiName->c_str(), 256 - apkdir_size - 2)
+                    == abiName->size()) && (access(abiFlag, F_OK) == 0)) {
+            abiType = abiIndex;
+            break;
+        }
+    }
+
+    if (abiIndex < numAbis) {
+        for (int j = 0; j < abiIndex; ++j) {
+            if (supportedAbis[j] != NULL) {
+                delete supportedAbis[j];
+            }
+        }
+        return (jint)abiType;
+    }
+
+    do {
+        if (abiType < 0 || abiType >= numAbis) {
+            break;
+        }
+
+        if (0 != strcmp(supportedAbis[abiType]->c_str(), X86ABI) &&
+                0 != strcmp(supportedAbis[abiType]->c_str(), X8664ABI)) {
+            break;
+        }
+
+        ScopedUtfChars name(env, apkPkgName);
+        if (NULL == name.c_str()) {
+            break;
+        }
+
+        if (isInOEMWhiteList(name.c_str())) {
+            break;
+        }
+
+        ABIPicker picker(name.c_str(),supportedAbis);
+        if (!picker.buildNativeLibList((void*)apkHandle)) {
+            break;
+        }
+
+        abiType = picker.pickupRightABI(abiType);
+        if (abiType >= 0 && abiType < numAbis &&
+                (strlcpy(abiFlag + apkdir_size + 2, supportedAbis[abiType]->c_str(),
+                         256 - apkdir_size - 2) == supportedAbis[abiType]->size())) {
+            int flagFp = creat(abiFlag, 0644);
+            if (flagFp != -1) {
+                close(flagFp);
+            }
+        }
+
+    } while(0);
+
+    for (int i = 0; i < numAbis; ++i) {
+        delete supportedAbis[i];
+    }
+    return (jint)abiType;
+#else
+    return (jint)findSupportedAbi(env, apkHandle, javaCpuAbisToSearch, debuggable);
+#endif
 }
 
 enum bitcode_scan_result_t {
@@ -594,9 +695,9 @@ static const JNINativeMethod gMethods[] = {
     {"nativeSumNativeBinaries",
             "(JLjava/lang/String;Z)J",
             (void *)com_android_internal_content_NativeLibraryHelper_sumNativeBinaries},
-    {"nativeFindSupportedAbi",
-            "(J[Ljava/lang/String;Z)I",
-            (void *)com_android_internal_content_NativeLibraryHelper_findSupportedAbi},
+    {"nativeFindSupportedAbiReplace",
+            "(J[Ljava/lang/String;ZLjava/lang/String;Ljava/lang/String;)I",
+            (void *)com_android_internal_content_NativeLibraryHelper_findSupportedAbi_replace},
     {"hasRenderscriptBitcode", "(J)I",
             (void *)com_android_internal_content_NativeLibraryHelper_hasRenderscriptBitcode},
 };
index c5904e0..c523c4c 100644 (file)
@@ -217,6 +217,8 @@ FileDescriptorInfo* FileDescriptorInfo::CreateFromFd(int fd, std::string* error_
                                              fd_path.c_str(),
                                              strerror(errno));
     return nullptr;
+  } else if (android::base::StartsWith(file_path, "/android/")) {
+    file_path = file_path.substr(8);
   }
 
   if (!whitelist->IsAllowed(file_path)) {
index 1fc9610..09f9d47 100644 (file)
     <string name="global_actions" product="default" msgid="2406416831541615258">"手机选项"</string>
     <string name="global_action_lock" msgid="2844945191792119712">"屏幕锁定"</string>
     <string name="global_action_power_off" msgid="4471879440839879722">"关机"</string>
+    <string name="global_action_sleep" msgid="4471879440839879723">"睡眠"</string>
     <string name="global_action_emergency" msgid="7112311161137421166">"紧急呼救"</string>
     <string name="global_action_bug_report" msgid="7934010578922304799">"错误报告"</string>
     <string name="global_action_logout" msgid="935179188218826050">"结束会话"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD 卡"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"U 盘"</string>
     <string name="storage_usb_drive_label" msgid="4501418548927759953">"<xliff:g id="MANUFACTURER">%s</xliff:g> U 盘"</string>
+    <string name="storage_cdrom">"CD/DVD 光盘"</string>
+    <string name="storage_cdrom_label">"<xliff:g id="MANUFACTURER">%s</xliff:g> CD/DVD 光盘"</string>
     <string name="storage_usb" msgid="3017954059538517278">"USB存储器"</string>
     <string name="extract_edit_menu_button" msgid="8940478730496610137">"修改"</string>
     <string name="data_usage_warning_title" msgid="6499834033204801605">"数据流量警告"</string>
index 9f3e7c2..cfdcaec 100644 (file)
     <string name="global_actions" product="default" msgid="2406416831541615258">"手機選項"</string>
     <string name="global_action_lock" msgid="2844945191792119712">"螢幕鎖定"</string>
     <string name="global_action_power_off" msgid="4471879440839879722">"關閉"</string>
+    <string name="global_action_sleep" msgid="4471879440839879723">"休眠"</string>
     <string name="global_action_emergency" msgid="7112311161137421166">"緊急"</string>
     <string name="global_action_bug_report" msgid="7934010578922304799">"錯誤報告"</string>
     <string name="global_action_logout" msgid="935179188218826050">"結束工作階段"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD 卡"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"USB 驅動器"</string>
     <string name="storage_usb_drive_label" msgid="4501418548927759953">"<xliff:g id="MANUFACTURER">%s</xliff:g> USB 驅動器"</string>
+    <string name="storage_cdrom">"CD/DVD 光碟機"</string>
+    <string name="storage_cdrom_label">"<xliff:g id="MANUFACTURER">%s</xliff:g> CD/DVD 光碟機"</string>
     <string name="storage_usb" msgid="3017954059538517278">"USB 儲存裝置"</string>
     <string name="extract_edit_menu_button" msgid="8940478730496610137">"編輯"</string>
     <string name="data_usage_warning_title" msgid="6499834033204801605">"數據用量警告"</string>
index e732817..4a72013 100644 (file)
     <string name="global_actions" product="default" msgid="2406416831541615258">"電話選項"</string>
     <string name="global_action_lock" msgid="2844945191792119712">"螢幕鎖定"</string>
     <string name="global_action_power_off" msgid="4471879440839879722">"關機"</string>
+    <string name="global_action_sleep" msgid="4471879440839879723">"休眠"</string>
     <string name="global_action_emergency" msgid="7112311161137421166">"緊急電話"</string>
     <string name="global_action_bug_report" msgid="7934010578922304799">"錯誤報告"</string>
     <string name="global_action_logout" msgid="935179188218826050">"結束"</string>
     <string name="storage_sd_card_label" msgid="6347111320774379257">"<xliff:g id="MANUFACTURER">%s</xliff:g> SD 卡"</string>
     <string name="storage_usb_drive" msgid="6261899683292244209">"USB 隨身碟"</string>
     <string name="storage_usb_drive_label" msgid="4501418548927759953">"<xliff:g id="MANUFACTURER">%s</xliff:g> USB 隨身碟"</string>
+    <string name="storage_cdrom">"CD/DVD 光碟機"</string>
+    <string name="storage_cdrom_label">"<xliff:g id="MANUFACTURER">%s</xliff:g> CD/DVD 光碟機"</string>
     <string name="storage_usb" msgid="3017954059538517278">"USB 儲存裝置"</string>
     <string name="extract_edit_menu_button" msgid="8940478730496610137">"編輯"</string>
     <string name="data_usage_warning_title" msgid="6499834033204801605">"數據用量警告"</string>
index da6b19d..330647b 100644 (file)
     <string-array translatable="false" name="config_globalActionsList">
         <item>power</item>
         <item>restart</item>
+        <item>sleep</item>
         <item>lockdown</item>
         <item>logout</item>
         <item>bugreport</item>
index 3c5159c..f0bf98c 100644 (file)
     <!-- TODO: promote to separate string-->
     <string name="global_action_restart" translatable="false">@string/sim_restart_button</string>
 
+    <string name="global_action_sleep">Sleep</string>
+
     <!-- label for item that starts emergency call -->
     <string name="global_action_emergency">Emergency</string>
 
     <!-- Storage description for a USB drive from a specific manufacturer. [CHAR LIMIT=NONE] -->
     <string name="storage_usb_drive_label"><xliff:g id="manufacturer" example="Seagate">%s</xliff:g> USB drive</string>
 
+    <!-- Storage description for a generic CDROM drive. [CHAR LIMIT=NONE] -->
+    <string name="storage_cdrom">CD/DVD drive</string>
+    <!-- Storage description for a CDROM drive from a specific manufacturer. [CHAR LIMIT=NONE] -->
+    <string name="storage_cdrom_label"><xliff:g id="manufacturer" example="ASUS">%s</xliff:g> CD/DVD drive</string>
+
     <!-- Storage description for USB storage. [CHAR LIMIT=NONE] -->
     <string name="storage_usb">USB storage</string>
 
index f80abc1..77ea947 100644 (file)
   <java-symbol type="string" name="global_actions" />
   <java-symbol type="string" name="global_action_power_off" />
   <java-symbol type="string" name="global_action_restart" />
+  <java-symbol type="string" name="global_action_sleep" />
   <java-symbol type="string" name="global_actions_airplane_mode_off_status" />
   <java-symbol type="string" name="global_actions_airplane_mode_on_status" />
   <java-symbol type="string" name="global_actions_toggle_airplane_mode" />
   <java-symbol type="string" name="storage_sd_card_label" />
   <java-symbol type="string" name="storage_usb_drive" />
   <java-symbol type="string" name="storage_usb_drive_label" />
+  <java-symbol type="string" name="storage_cdrom" />
+  <java-symbol type="string" name="storage_cdrom_label" />
   <java-symbol type="string" name="storage_usb" />
 
   <java-symbol type="drawable" name="ic_eject_24dp" />
index 8699cb4..cc5ea4b 100644 (file)
@@ -139,13 +139,13 @@ key 116   POWER
 key 117   NUMPAD_EQUALS
 # key 118 "KEY_KPPLUSMINUS"
 key 119   BREAK
-# key 120 (undefined)
+key 120   APP_SWITCH
 key 121   NUMPAD_COMMA
 key 122   KANA
 key 123   EISU
 key 124   YEN
-key 125   META_LEFT
-key 126   META_RIGHT
+key 125   HOME
+key 126   HOME
 key 127   MENU
 key 128   MEDIA_STOP
 # key 129 "KEY_AGAIN"
index 35937de..ee5804b 100644 (file)
@@ -43,13 +43,19 @@ public class MediaFile {
     public static final int FILE_TYPE_AAC     = 8;
     public static final int FILE_TYPE_MKA     = 9;
     public static final int FILE_TYPE_FLAC    = 10;
+    public static final int FILE_TYPE_3GPA    = 11;
+    public static final int FILE_TYPE_AC3     = 12;
+    public static final int FILE_TYPE_APE     = 13;
+    public static final int FILE_TYPE_WEBMA   = 14;
+    public static final int FILE_TYPE_PCM     = 15;
+    public static final int FILE_TYPE_DTS     = 16;
     private static final int FIRST_AUDIO_FILE_TYPE = FILE_TYPE_MP3;
-    private static final int LAST_AUDIO_FILE_TYPE = FILE_TYPE_FLAC;
+    private static final int LAST_AUDIO_FILE_TYPE = FILE_TYPE_DTS;
 
     // MIDI file types
-    public static final int FILE_TYPE_MID     = 11;
-    public static final int FILE_TYPE_SMF     = 12;
-    public static final int FILE_TYPE_IMY     = 13;
+    public static final int FILE_TYPE_MID     = 18;
+    public static final int FILE_TYPE_SMF     = 19;
+    public static final int FILE_TYPE_IMY     = 20;
     private static final int FIRST_MIDI_FILE_TYPE = FILE_TYPE_MID;
     private static final int LAST_MIDI_FILE_TYPE = FILE_TYPE_IMY;
 
@@ -64,8 +70,12 @@ public class MediaFile {
     public static final int FILE_TYPE_MP2TS   = 28;
     public static final int FILE_TYPE_AVI     = 29;
     public static final int FILE_TYPE_WEBM    = 30;
+    public static final int FILE_TYPE_DIVX    = 31;
+    public static final int FILE_TYPE_FLV     = 32;
+    public static final int FILE_TYPE_RV      = 33;
+    public static final int FILE_TYPE_VC1     = 34;
     private static final int FIRST_VIDEO_FILE_TYPE = FILE_TYPE_MP4;
-    private static final int LAST_VIDEO_FILE_TYPE = FILE_TYPE_WEBM;
+    private static final int LAST_VIDEO_FILE_TYPE = FILE_TYPE_VC1;
 
     // More video file types
     public static final int FILE_TYPE_MP2PS   = 200;
@@ -74,13 +84,13 @@ public class MediaFile {
     private static final int LAST_VIDEO_FILE_TYPE2 = FILE_TYPE_QT;
 
     // Image file types
-    public static final int FILE_TYPE_JPEG    = 31;
-    public static final int FILE_TYPE_GIF     = 32;
-    public static final int FILE_TYPE_PNG     = 33;
-    public static final int FILE_TYPE_BMP     = 34;
-    public static final int FILE_TYPE_WBMP    = 35;
-    public static final int FILE_TYPE_WEBP    = 36;
-    public static final int FILE_TYPE_HEIF    = 37;
+    public static final int FILE_TYPE_JPEG    = 61;
+    public static final int FILE_TYPE_GIF     = 62;
+    public static final int FILE_TYPE_PNG     = 63;
+    public static final int FILE_TYPE_BMP     = 64;
+    public static final int FILE_TYPE_WBMP    = 65;
+    public static final int FILE_TYPE_WEBP    = 66;
+    public static final int FILE_TYPE_HEIF    = 67;
     private static final int FIRST_IMAGE_FILE_TYPE = FILE_TYPE_JPEG;
     private static final int LAST_IMAGE_FILE_TYPE = FILE_TYPE_HEIF;
 
@@ -191,6 +201,7 @@ public class MediaFile {
         addFileType("MPGA", FILE_TYPE_MP3, "audio/mpeg", MtpConstants.FORMAT_MP3, false);
         addFileType("M4A", FILE_TYPE_M4A, "audio/mp4", MtpConstants.FORMAT_MPEG, false);
         addFileType("WAV", FILE_TYPE_WAV, "audio/x-wav", MtpConstants.FORMAT_WAV, true);
+        addFileType("WAV", FILE_TYPE_PCM, "audio/wav");
         addFileType("AMR", FILE_TYPE_AMR, "audio/amr");
         addFileType("AWB", FILE_TYPE_AWB, "audio/amr-wb");
         if (isWMAEnabled()) {
@@ -198,10 +209,13 @@ public class MediaFile {
         }
         addFileType("OGG", FILE_TYPE_OGG, "audio/ogg", MtpConstants.FORMAT_OGG, false);
         addFileType("OGG", FILE_TYPE_OGG, "application/ogg", MtpConstants.FORMAT_OGG, true);
+        addFileType("OGA", FILE_TYPE_OGG, "audio/ogg", MtpConstants.FORMAT_OGG, false);
         addFileType("OGA", FILE_TYPE_OGG, "application/ogg", MtpConstants.FORMAT_OGG, false);
         addFileType("AAC", FILE_TYPE_AAC, "audio/aac", MtpConstants.FORMAT_AAC, true);
         addFileType("AAC", FILE_TYPE_AAC, "audio/aac-adts", MtpConstants.FORMAT_AAC, false);
         addFileType("MKA", FILE_TYPE_MKA, "audio/x-matroska");
+        addFileType("AC3", FILE_TYPE_AC3, "audio/ac3");
+        addFileType("APE", FILE_TYPE_APE, "audio/x-ape");
 
         addFileType("MID", FILE_TYPE_MID, "audio/midi");
         addFileType("MIDI", FILE_TYPE_MID, "audio/midi");
@@ -226,7 +240,13 @@ public class MediaFile {
         addFileType("MKV", FILE_TYPE_MKV, "video/x-matroska");
         addFileType("WEBM", FILE_TYPE_WEBM, "video/webm");
         addFileType("TS", FILE_TYPE_MP2TS, "video/mp2ts");
+        addFileType("MPG", FILE_TYPE_MP2TS, "video/mp2ts");
         addFileType("AVI", FILE_TYPE_AVI, "video/avi");
+        addFileType("DIVX", FILE_TYPE_DIVX, "video/divx");
+        addFileType("FLV", FILE_TYPE_FLV, "video/x-flv");
+        addFileType("RM", FILE_TYPE_RV, "video/vnd.rn-realvideo");
+        addFileType("RMVB", FILE_TYPE_RV, "video/vnd.rn-realvideo");
+        addFileType("VC1", FILE_TYPE_VC1, "video/vc1");
 
         if (isWMVEnabled()) {
             addFileType("WMV", FILE_TYPE_WMV, "video/x-ms-wmv", MtpConstants.FORMAT_WMV, true);
index 0f0a7e9..d9bdf42 100644 (file)
@@ -969,7 +969,7 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback
                     int a = findConfigAttrib(egl, display, config,
                             EGL10.EGL_ALPHA_SIZE, 0);
                     if ((r == mRedSize) && (g == mGreenSize)
-                            && (b == mBlueSize) && (a == mAlphaSize)) {
+                            && (b == mBlueSize) && (a >= mAlphaSize)) {
                         return config;
                     }
                 }
index f00957a..87f63b1 100644 (file)
 
     <!-- Width for the notification panel and related windows -->
     <dimen name="match_parent">-1px</dimen>
-    <dimen name="standard_notification_panel_width">416dp</dimen>
+    <dimen name="standard_notification_panel_width">540dp</dimen>
 
     <!-- The top margin of the panel that holds the list of notifications. -->
     <dimen name="notification_panel_margin_top">0dp</dimen>
index b8a57bf..60d5d03 100644 (file)
@@ -137,7 +137,10 @@ public class ImageWallpaper extends WallpaperService {
         @Override
         public void onDestroy() {
             super.onDestroy();
-            mBackground = null;
+            if (mBackground != null) {
+                mBackground.recycle();
+                mBackground = null;
+            }
             unloadWallpaper(true /* forgetSize */);
         }
 
index d232108..4aad11b 100644 (file)
@@ -44,9 +44,11 @@ import android.os.Build;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Message;
+import android.os.PowerManager;
 import android.os.Messenger;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.UserManager;
@@ -126,6 +128,7 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
     private static final String GLOBAL_ACTION_KEY_VOICEASSIST = "voiceassist";
     private static final String GLOBAL_ACTION_KEY_ASSIST = "assist";
     private static final String GLOBAL_ACTION_KEY_RESTART = "restart";
+    private static final String GLOBAL_ACTION_KEY_SLEEP = "sleep";
     private static final String GLOBAL_ACTION_KEY_LOGOUT = "logout";
     private static final String GLOBAL_ACTION_KEY_SCREENSHOT = "screenshot";
 
@@ -357,6 +360,8 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
                 mItems.add(getAssistAction());
             } else if (GLOBAL_ACTION_KEY_RESTART.equals(actionKey)) {
                 mItems.add(new RestartAction());
+            } else if (GLOBAL_ACTION_KEY_SLEEP.equals(actionKey)) {
+                mItems.add(new SleepAction());
             } else if (GLOBAL_ACTION_KEY_SCREENSHOT.equals(actionKey)) {
                 mItems.add(new ScreenshotAction());
             } else if (GLOBAL_ACTION_KEY_LOGOUT.equals(actionKey)) {
@@ -472,6 +477,36 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
         }
     }
 
+    private final class SleepAction extends SinglePressAction implements LongPressAction {
+        private SleepAction() {
+            super(R.drawable.ic_restart, R.string.global_action_sleep);
+        }
+
+        @Override
+        public boolean onLongPress() {
+            PowerManager mPowerManager = (PowerManager)
+                   mContext.getSystemService(Context.POWER_SERVICE);
+            mPowerManager.goToSleep(SystemClock.uptimeMillis());
+            return true;
+        }
+
+        @Override
+        public boolean showDuringKeyguard() {
+            return true;
+        }
+
+        @Override
+        public boolean showBeforeProvisioning() {
+            return true;
+        }
+
+        @Override
+        public void onPress() {
+            PowerManager mPowerManager = (PowerManager)
+                   mContext.getSystemService(Context.POWER_SERVICE);
+            mPowerManager.goToSleep(SystemClock.uptimeMillis());
+        }
+    }
 
     private class ScreenshotAction extends SinglePressAction {
         public ScreenshotAction() {
index c81a876..f97d767 100644 (file)
@@ -50,10 +50,10 @@ class DisplayAdjustmentUtils {
      * for full implementation details.
      */
     private static final float[] MATRIX_INVERT_COLOR = new float[] {
-        0.402f, -0.598f, -0.599f, 0,
-       -1.174f, -0.174f, -1.175f, 0,
-       -0.228f, -0.228f,  0.772f, 0,
-             1,       1,       1, 1
+       0.0f, 0.0f, 1.0f, 0,
+       0.0f, 1.0f, 0.0f, 0,
+       1.0f, 0.0f, 0.0f, 0,
+          0,    0,    0, 1
     };
 
     public static void applyDaltonizerSetting(Context context, int userId) {
index fcda83d..3980bc6 100644 (file)
@@ -34,9 +34,11 @@ import com.android.server.input.InputManagerService.WiredAccessoryCallbacks;
 import static com.android.server.input.InputManagerService.SW_HEADPHONE_INSERT;
 import static com.android.server.input.InputManagerService.SW_MICROPHONE_INSERT;
 import static com.android.server.input.InputManagerService.SW_LINEOUT_INSERT;
+import static com.android.server.input.InputManagerService.SW_VIDEOOUT_INSERT;
 import static com.android.server.input.InputManagerService.SW_HEADPHONE_INSERT_BIT;
 import static com.android.server.input.InputManagerService.SW_MICROPHONE_INSERT_BIT;
 import static com.android.server.input.InputManagerService.SW_LINEOUT_INSERT_BIT;
+import static com.android.server.input.InputManagerService.SW_VIDEOOUT_INSERT_BIT;
 
 import java.io.File;
 import java.io.FileReader;
@@ -111,8 +113,11 @@ final class WiredAccessoryManager implements WiredAccessoryCallbacks {
             if (mInputManager.getSwitchState(-1, InputDevice.SOURCE_ANY, SW_LINEOUT_INSERT) == 1) {
                 switchValues |= SW_LINEOUT_INSERT_BIT;
             }
+            if (mInputManager.getSwitchState(-1, InputDevice.SOURCE_ANY, SW_VIDEOOUT_INSERT) == 1) {
+                switchValues |= SW_VIDEOOUT_INSERT_BIT;
+            }
             notifyWiredAccessoryChanged(0, switchValues,
-                    SW_HEADPHONE_INSERT_BIT | SW_MICROPHONE_INSERT_BIT | SW_LINEOUT_INSERT_BIT);
+                    SW_HEADPHONE_INSERT_BIT | SW_MICROPHONE_INSERT_BIT | SW_LINEOUT_INSERT_BIT | SW_VIDEOOUT_INSERT_BIT);
         }
 
         mObserver.init();
@@ -120,7 +125,7 @@ final class WiredAccessoryManager implements WiredAccessoryCallbacks {
 
     @Override
     public void notifyWiredAccessoryChanged(long whenNanos, int switchValues, int switchMask) {
-        if (LOG) Slog.v(TAG, "notifyWiredAccessoryChanged: when=" + whenNanos
+        if (LOG) Slog.i(TAG, "notifyWiredAccessoryChanged: when=" + whenNanos
                 + " bits=" + switchCodeToString(switchValues, switchMask)
                 + " mask=" + Integer.toHexString(switchMask));
 
@@ -128,7 +133,7 @@ final class WiredAccessoryManager implements WiredAccessoryCallbacks {
             int headset;
             mSwitchValues = (mSwitchValues & ~switchMask) | switchValues;
             switch (mSwitchValues &
-                (SW_HEADPHONE_INSERT_BIT | SW_MICROPHONE_INSERT_BIT | SW_LINEOUT_INSERT_BIT)) {
+                (SW_HEADPHONE_INSERT_BIT | SW_MICROPHONE_INSERT_BIT | SW_LINEOUT_INSERT_BIT | SW_VIDEOOUT_INSERT_BIT)) {
                 case 0:
                     headset = 0;
                     break;
@@ -141,6 +146,11 @@ final class WiredAccessoryManager implements WiredAccessoryCallbacks {
                     headset = BIT_LINEOUT;
                     break;
 
+                case SW_VIDEOOUT_INSERT_BIT:
+                case SW_VIDEOOUT_INSERT_BIT | SW_LINEOUT_INSERT_BIT:
+                    headset = BIT_HDMI_AUDIO;
+                    break;
+
                 case SW_HEADPHONE_INSERT_BIT | SW_MICROPHONE_INSERT_BIT:
                     headset = BIT_HEADSET;
                     break;
@@ -155,7 +165,7 @@ final class WiredAccessoryManager implements WiredAccessoryCallbacks {
             }
 
             updateLocked(NAME_H2W,
-                (mHeadsetState & ~(BIT_HEADSET | BIT_HEADSET_NO_MIC | BIT_LINEOUT)) | headset);
+                (mHeadsetState & ~(BIT_HEADSET | BIT_HEADSET_NO_MIC | BIT_LINEOUT | BIT_HDMI_AUDIO)) | headset);
         }
     }
 
@@ -285,7 +295,7 @@ final class WiredAccessoryManager implements WiredAccessoryCallbacks {
             }
 
             if (LOG) {
-                Slog.v(TAG, "headsetName: " + headsetName +
+                Slog.i(TAG, "headsetName: " + headsetName +
                         (state == 1 ? " connected" : " disconnected"));
             }
 
@@ -308,6 +318,14 @@ final class WiredAccessoryManager implements WiredAccessoryCallbacks {
                 (switchValues & SW_MICROPHONE_INSERT_BIT) != 0) {
             sb.append("SW_MICROPHONE_INSERT");
         }
+        if ((switchMask & SW_LINEOUT_INSERT_BIT) != 0 &&
+                (switchValues & SW_LINEOUT_INSERT_BIT) != 0) {
+            sb.append("SW_LINEOUT_INSERT ");
+        }
+        if ((switchMask & SW_VIDEOOUT_INSERT_BIT) != 0 &&
+                (switchValues & SW_VIDEOOUT_INSERT_BIT) != 0) {
+            sb.append("SW_VIDEOOUT_INSERT ");
+        }
         return sb.toString();
     }
 
index 451acf4..cb7c36b 100644 (file)
@@ -70,6 +70,7 @@ import android.hardware.input.TouchCalibration;
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.Environment;
+import android.os.FileObserver;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
@@ -289,6 +290,9 @@ public class InputManagerService extends IInputManager.Stub
     /** Switch code: Headphone/Microphone Jack.  When set, something is inserted. */
     public static final int SW_JACK_PHYSICAL_INSERT = 0x07;
 
+    /** Switch code: Video out jack.  When set, something is inserted. */
+    public static final int SW_VIDEOOUT_INSERT = 0x08;
+
     /** Switch code: Camera lens cover. When set the lens is covered. */
     public static final int SW_CAMERA_LENS_COVER = 0x09;
 
@@ -304,13 +308,27 @@ public class InputManagerService extends IInputManager.Stub
     public static final int SW_MICROPHONE_INSERT_BIT = 1 << SW_MICROPHONE_INSERT;
     public static final int SW_LINEOUT_INSERT_BIT = 1 << SW_LINEOUT_INSERT;
     public static final int SW_JACK_PHYSICAL_INSERT_BIT = 1 << SW_JACK_PHYSICAL_INSERT;
+    public static final int SW_VIDEOOUT_INSERT_BIT = 1 << SW_VIDEOOUT_INSERT;
     public static final int SW_JACK_BITS =
-            SW_HEADPHONE_INSERT_BIT | SW_MICROPHONE_INSERT_BIT | SW_JACK_PHYSICAL_INSERT_BIT | SW_LINEOUT_INSERT_BIT;
+            SW_HEADPHONE_INSERT_BIT | SW_MICROPHONE_INSERT_BIT | SW_JACK_PHYSICAL_INSERT_BIT | SW_LINEOUT_INSERT_BIT | SW_VIDEOOUT_INSERT_BIT;
     public static final int SW_CAMERA_LENS_COVER_BIT = 1 << SW_CAMERA_LENS_COVER;
 
     /** Whether to use the dev/input/event or uevent subsystem for the audio jack. */
     final boolean mUseDevInputEventForAudioJack;
 
+    private class TscalObserver extends FileObserver {
+        public TscalObserver() {
+            super("/data/misc/tscal/pointercal", CLOSE_WRITE);
+        }
+
+        @Override
+        public void onEvent(int event, String path) {
+            Slog.i(TAG, "detect pointercal changed");
+            reloadDeviceAliases();
+        }
+    }
+    private final TscalObserver mTscalObserver = new TscalObserver();
+
     public InputManagerService(Context context) {
         this.mContext = context;
         this.mHandler = new InputManagerHandler(DisplayThread.get().getLooper());
@@ -327,6 +345,7 @@ public class InputManagerService extends IInputManager.Stub
             new File(doubleTouchGestureEnablePath);
 
         LocalServices.addService(InputManagerInternal.class, new LocalService());
+        mTscalObserver.startWatching();
     }
 
     public void setWindowManagerCallbacks(WindowManagerCallbacks callbacks) {
index 7d8d41b..edf1d9d 100644 (file)
@@ -655,7 +655,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub {
         }
 
         if (!SELinux.restorecon(stageDir)) {
-            throw new IOException("Failed to restorecon session dir: " + stageDir);
+            Slog.e(TAG, "Failed to restorecon session dir: " + stageDir);
         }
     }
 
index f1f3a14..b82b324 100644 (file)
@@ -15921,7 +15921,6 @@ public class PackageManagerService extends IPackageManager.Stub
 
             if (!SELinux.restoreconRecursive(afterCodeFile)) {
                 Slog.w(TAG, "Failed to restorecon");
-                return false;
             }
 
             // Reflect the rename internally
index 4aa2446..d1df556 100644 (file)
@@ -354,6 +354,10 @@ public class ImmersiveModeConfirmation {
 
     private void handleShow() {
         if (DEBUG) Slog.d(TAG, "Showing immersive mode confirmation");
+        if (mClingWindow != null) {
+            if (DEBUG) Slog.d(TAG, "already shown");
+            return;
+        }
 
         mClingWindow = new ClingWindowView(mContext, mConfirm);
 
index 0275076..fb4655b 100644 (file)
@@ -2418,7 +2418,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
         // so if the orientation is forced, we need to respect that no matter what.
         final boolean isTv = mContext.getPackageManager().hasSystemFeature(
                 PackageManager.FEATURE_LEANBACK);
-        mForceDefaultOrientation = ((longSizeDp >= 960 && shortSizeDp >= 720) || isCar || isTv) &&
+        mForceDefaultOrientation = /* ((longSizeDp >= 960 && shortSizeDp >= 720) || isCar || isTv) && */
                 res.getBoolean(com.android.internal.R.bool.config_forceDefaultOrientation) &&
                 // For debug purposes the next line turns this feature off with:
                 // $ adb shell setprop config.override_forced_orient true
index 697801f..7c51add 100644 (file)
@@ -108,6 +108,8 @@ import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Objects;
+import java.io.IOException;
+import android.os.FileUtils;
 
 /**
  * The power manager service is responsible for coordinating power management
@@ -1429,6 +1431,12 @@ public final class PowerManagerService extends SystemService
                 default:
                     Slog.i(TAG, "Going to sleep by application request (uid " + uid +")...");
                     reason = PowerManager.GO_TO_SLEEP_REASON_APPLICATION;
+                    // Adding force suspend code to enter S3 after pressing sleep button
+                    try {
+                        FileUtils.stringToFile("/sys/power/state", "mem");
+                    } catch (IOException e) {
+                        Slog.v(TAG, "IOException: " + e);
+                    }
                     break;
             }
 
index cd8fdbf..03c4386 100644 (file)
@@ -2932,12 +2932,13 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
         // Uses same calculation as in LogicalDisplay#configureDisplayInTransactionLocked.
         final int orientation = mDisplayInfo.rotation;
         boolean rotated = (orientation == ROTATION_90 || orientation == ROTATION_270);
+        boolean forcedOrientation = mService.mPolicy.isDefaultOrientationForced();
         final int physWidth = rotated ? mBaseDisplayHeight : mBaseDisplayWidth;
         final int physHeight = rotated ? mBaseDisplayWidth : mBaseDisplayHeight;
         int width = mDisplayInfo.logicalWidth;
-        int left = (physWidth - width) / 2;
+        int left = forcedOrientation ? 0 : (physWidth - width) / 2;
         int height = mDisplayInfo.logicalHeight;
-        int top = (physHeight - height) / 2;
+        int top = forcedOrientation ? 0 : (physHeight - height) / 2;
         out.set(left, top, left + width, top + height);
     }
 
index 47350c1..052c4d1 100644 (file)
@@ -38,6 +38,7 @@
 #include <unistd.h>
 #include <linux/ioctl.h>
 #include <linux/rtc.h>
+#include <cutils/properties.h>
 
 #include <array>
 #include <memory>
@@ -121,7 +122,7 @@ int AlarmImpl::set(int type, struct timespec *ts)
 int AlarmImpl::setTime(struct timeval *tv)
 {
     struct rtc_time rtc;
-    struct tm tm, *gmtime_res;
+    struct tm tm, *localtime_res, *gmtime_res;
     int fd;
     int res;
 
@@ -144,11 +145,23 @@ int AlarmImpl::setTime(struct timeval *tv)
         return res;
     }
 
-    gmtime_res = gmtime_r(&tv->tv_sec, &tm);
-    if (!gmtime_res) {
-        ALOGV("gmtime_r() failed: %s\n", strerror(errno));
-        res = -1;
-        goto done;
+    // @jide when persist.rtc_local_time is set to 1, we store the localtime to rtc
+    //
+    bool rtc_local_time = property_get_bool("persist.rtc_local_time", false);
+    if (rtc_local_time) {
+        localtime_res = localtime_r(&tv->tv_sec, &tm);
+        if (!localtime_res) {
+            ALOGV("localtime_r() failed: %s\n", strerror(errno));
+            res = -1;
+            goto done;
+        }
+    } else {
+        gmtime_res = gmtime_r(&tv->tv_sec, &tm);
+        if (!gmtime_res) {
+            ALOGV("gmtime_r() failed: %s\n", strerror(errno));
+            res = -1;
+            goto done;
+        }
     }
 
     memset(&rtc, 0, sizeof(rtc));