summaryrefslogtreecommitdiffstats
path: root/core/java
diff options
context:
space:
mode:
authorWolfgang Wiedmeyer <wolfgit@wiedmeyer.de>2016-03-18 10:36:07 +0100
committerWolfgang Wiedmeyer <wolfgit@wiedmeyer.de>2016-03-18 10:36:07 +0100
commit813d4309fb2144b96ffcd644c71a30aadc50fd1e (patch)
tree532609cc34968f682701176114c484f5278b8349 /core/java
parent8bc386657e4bd582ea0897410523e27230a8e157 (diff)
parentdf301d4a64fe0dfc812b39e3f7e2c2ca4b93c305 (diff)
downloadframeworks_base-813d4309fb2144b96ffcd644c71a30aadc50fd1e.zip
frameworks_base-813d4309fb2144b96ffcd644c71a30aadc50fd1e.tar.gz
frameworks_base-813d4309fb2144b96ffcd644c71a30aadc50fd1e.tar.bz2
Merge branch 'cm-13.0' of https://github.com/CyanogenMod/android_frameworks_base into replicant-6.0
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/app/ActivityManager.java17
-rw-r--r--core/java/android/app/ActivityManagerNative.java21
-rw-r--r--core/java/android/app/ActivityThread.java15
-rw-r--r--core/java/android/app/ActivityView.java170
-rw-r--r--core/java/android/app/ContextImpl.java2
-rw-r--r--core/java/android/app/IActivityManager.java2
-rw-r--r--core/java/android/app/IBatteryService.aidl (renamed from core/java/android/content/res/IThemeChangeListener.aidl)20
-rw-r--r--core/java/android/app/IconPackHelper.java23
-rw-r--r--core/java/android/app/Notification.java28
-rw-r--r--core/java/android/app/ResourcesManager.java8
-rw-r--r--core/java/android/app/StatusBarManager.java1
-rw-r--r--core/java/android/app/SystemServiceRegistry.java15
-rw-r--r--core/java/android/app/backup/FullBackup.java15
-rw-r--r--core/java/android/app/usage/UsageStats.java8
-rw-r--r--core/java/android/bluetooth/BluetoothAdapter.java2
-rw-r--r--core/java/android/bluetooth/BluetoothDevice.java13
-rw-r--r--core/java/android/bluetooth/BluetoothHeadset.java45
-rw-r--r--core/java/android/bluetooth/BluetoothHeadsetClient.java35
-rw-r--r--core/java/android/bluetooth/BluetoothHeadsetClientCall.java34
-rwxr-xr-xcore/java/android/bluetooth/IBluetoothHeadset.aidl2
-rw-r--r--core/java/android/bluetooth/IBluetoothHeadsetClient.aidl2
-rw-r--r--core/java/android/content/Context.java10
-rw-r--r--core/java/android/content/Intent.java109
-rw-r--r--core/java/android/content/pm/ThemeUtils.java605
-rw-r--r--core/java/android/content/res/IThemeProcessingListener.aidl21
-rw-r--r--core/java/android/content/res/IThemeService.aidl43
-rw-r--r--core/java/android/content/res/Resources.java207
-rw-r--r--core/java/android/content/res/ThemeChangeRequest.aidl19
-rw-r--r--core/java/android/content/res/ThemeChangeRequest.java307
-rw-r--r--core/java/android/content/res/ThemeConfig.java52
-rw-r--r--core/java/android/content/res/ThemeManager.java316
-rw-r--r--core/java/android/hardware/Camera.java22
-rw-r--r--core/java/android/hardware/camera2/CameraCharacteristics.java17
-rw-r--r--core/java/android/hardware/camera2/CameraMetadata.java4
-rw-r--r--core/java/android/hardware/camera2/CaptureRequest.java4
-rw-r--r--core/java/android/net/INetworkPolicyManager.aidl3
-rw-r--r--core/java/android/net/NetworkPolicyManager.java49
-rw-r--r--core/java/android/net/NetworkScorerAppManager.java17
-rw-r--r--core/java/android/nfc/NfcActivityManager.java64
-rw-r--r--core/java/android/os/BatteryManager.java160
-rw-r--r--core/java/android/os/BatteryManagerInternal.java21
-rw-r--r--core/java/android/os/BatteryProperties.java54
-rw-r--r--core/java/android/os/Environment.java2
-rw-r--r--core/java/android/os/IBatteryPropertiesRegistrar.aidl2
-rw-r--r--core/java/android/os/PowerManagerInternal.java6
-rw-r--r--core/java/android/provider/Settings.java25
-rw-r--r--core/java/android/provider/ThemesContract.java731
-rw-r--r--core/java/android/service/gesture/EdgeGestureManager.java205
-rw-r--r--core/java/android/service/gesture/IEdgeGestureActivationListener.aidl14
-rw-r--r--core/java/android/service/gesture/IEdgeGestureHostCallback.aidl20
-rw-r--r--core/java/android/service/gesture/IEdgeGestureService.aidl20
-rw-r--r--core/java/android/service/gesture/package.html5
-rw-r--r--core/java/android/text/Layout.java56
-rw-r--r--core/java/android/text/TextLine.java18
-rw-r--r--core/java/android/util/Patterns.java40
-rw-r--r--core/java/android/view/DisplayInfo.java2
-rw-r--r--core/java/android/view/InputDevice.java23
-rw-r--r--core/java/android/view/KeyEvent.java21
-rw-r--r--core/java/android/view/MotionEvent.java17
-rw-r--r--core/java/android/view/View.java6
-rw-r--r--core/java/android/view/ViewRootImpl.java12
-rw-r--r--core/java/android/widget/LinearLayout.java22
-rw-r--r--core/java/android/widget/OverScroller.java5
-rw-r--r--core/java/android/widget/RemoteViews.java41
-rw-r--r--core/java/android/widget/Scroller.java7
-rw-r--r--core/java/android/widget/TableRow.java2
-rw-r--r--core/java/android/widget/Toast.java19
-rw-r--r--core/java/com/android/internal/app/IBatteryStats.aidl15
-rw-r--r--core/java/com/android/internal/os/BatteryStatsHelper.java89
-rw-r--r--core/java/com/android/internal/os/BatteryStatsImpl.java90
-rw-r--r--core/java/com/android/internal/os/DockBatteryStatsImpl.java56
-rw-r--r--core/java/com/android/internal/os/KernelCpuSpeedReader.java13
-rw-r--r--core/java/com/android/internal/os/ProcessCpuTracker.java4
-rw-r--r--core/java/com/android/internal/os/RuntimeInit.java5
-rw-r--r--core/java/com/android/internal/util/StateMachine.java27
-rw-r--r--core/java/com/android/internal/util/cm/ImageUtils.java332
-rw-r--r--core/java/com/android/internal/util/gesture/EdgeGesturePosition.java42
-rw-r--r--core/java/com/android/internal/util/gesture/EdgeServiceConstants.java82
-rw-r--r--core/java/com/android/internal/widget/LockPatternUtils.java18
-rw-r--r--core/java/com/android/internal/widget/SwipeDismissLayout.java19
80 files changed, 1444 insertions, 3251 deletions
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 8bada59..5fc3437 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -1327,6 +1327,23 @@ public class ActivityManager {
}
/**
+ * Check whether the current foreground tasks belongs to a given package.
+ *
+ * @param packageName Name of the package to check for
+ *
+ * @return Whether the current foreground tasks belongs to the given package
+ * @hide
+ */
+ public boolean isPackageInForeground(String packageName) {
+ try {
+ return ActivityManagerNative.getDefault().isPackageInForeground(packageName);
+ } catch (RemoteException e) {
+ // System dead, we will be dead too soon!
+ return false;
+ }
+ }
+
+ /**
* Completely remove the given task.
*
* @param taskId Identifier of the task to be removed.
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index d638de6..ff06b74 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -647,6 +647,15 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
return true;
}
+ case IS_PACKAGE_IN_FOREGROUND_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ String packageName = data.readString();
+ boolean result = isPackageInForeground(packageName);
+ reply.writeNoException();
+ reply.writeInt(result ? 1 : 0);
+ return true;
+ }
+
case GET_RECENT_TASKS_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
int maxNum = data.readInt();
@@ -3300,6 +3309,18 @@ class ActivityManagerProxy implements IActivityManager
reply.recycle();
return list;
}
+ public boolean isPackageInForeground(String packageName) throws RemoteException {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ data.writeString(packageName);
+ mRemote.transact(IS_PACKAGE_IN_FOREGROUND_TRANSACTION, data, reply, 0);
+ reply.readException();
+ boolean result = reply.readInt() != 0;
+ data.recycle();
+ reply.recycle();
+ return result;
+ }
public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
int flags, int userId) throws RemoteException {
Parcel data = Parcel.obtain();
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 7d3b572..782dc46 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -2456,16 +2456,6 @@ public final class ActivityThread {
return activity;
}
- private void sendAppLaunchFailureBroadcast(ActivityClientRecord r) {
- String pkg = null;
- if (r.packageInfo != null && !TextUtils.isEmpty(r.packageInfo.getPackageName())) {
- pkg = r.packageInfo.getPackageName();
- }
- Intent intent = new Intent(Intent.ACTION_APP_FAILURE,
- (pkg != null)? Uri.fromParts("package", pkg, null) : null);
- getSystemContext().sendBroadcast(intent);
- }
-
private Context createBaseContextForActivity(ActivityClientRecord r, final Activity activity) {
int displayId = Display.DEFAULT_DISPLAY;
try {
@@ -4279,6 +4269,11 @@ public final class ActivityThread {
configDiff = mConfiguration.updateFrom(config);
config = applyCompatConfiguration(mCurDefaultDisplayDpi);
+
+ final Theme systemTheme = getSystemContext().getTheme();
+ if ((systemTheme.getChangingConfigurations() & configDiff) != 0) {
+ systemTheme.rebase();
+ }
}
ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(false, config);
diff --git a/core/java/android/app/ActivityView.java b/core/java/android/app/ActivityView.java
index 9c0d931..c075ed6 100644
--- a/core/java/android/app/ActivityView.java
+++ b/core/java/android/app/ActivityView.java
@@ -24,8 +24,6 @@ import android.content.IIntentSender;
import android.content.Intent;
import android.content.IntentSender;
import android.graphics.SurfaceTexture;
-import android.os.Handler;
-import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Message;
import android.os.OperationCanceledException;
@@ -45,6 +43,17 @@ import android.view.WindowManager;
import dalvik.system.CloseGuard;
import java.lang.ref.WeakReference;
+import java.util.ArrayDeque;
+import java.util.concurrent.Executor;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import com.android.internal.annotations.GuardedBy;
+
/** @hide */
public class ActivityView extends ViewGroup {
@@ -53,9 +62,64 @@ public class ActivityView extends ViewGroup {
private static final int MSG_SET_SURFACE = 1;
- DisplayMetrics mMetrics = new DisplayMetrics();
+ private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
+ private static final int MINIMUM_POOL_SIZE = 1;
+ private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
+ private static final int KEEP_ALIVE = 1;
+
+ private static final ThreadFactory sThreadFactory = new ThreadFactory() {
+ private final AtomicInteger mCount = new AtomicInteger(1);
+
+ public Thread newThread(Runnable r) {
+ return new Thread(r, "ActivityView #" + mCount.getAndIncrement());
+ }
+ };
+
+ private static final BlockingQueue<Runnable> sPoolWorkQueue =
+ new LinkedBlockingQueue<Runnable>(128);
+
+ /**
+ * An {@link Executor} that can be used to execute tasks in parallel.
+ */
+ private static final Executor sExecutor = new ThreadPoolExecutor(MINIMUM_POOL_SIZE,
+ MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);
+
+
+ private static class SerialExecutor implements Executor {
+ private final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();
+ private Runnable mActive;
+
+ public synchronized void execute(final Runnable r) {
+ mTasks.offer(new Runnable() {
+ public void run() {
+ try {
+ r.run();
+ } finally {
+ scheduleNext();
+ }
+ }
+ });
+ if (mActive == null) {
+ scheduleNext();
+ }
+ }
+
+ protected synchronized void scheduleNext() {
+ if ((mActive = mTasks.poll()) != null) {
+ sExecutor.execute(mActive);
+ }
+ }
+ }
+
+ private final SerialExecutor mExecutor = new SerialExecutor();
+
+ private final int mDensityDpi;
private final TextureView mTextureView;
+
+ @GuardedBy("mActivityContainerLock")
private ActivityContainerWrapper mActivityContainer;
+ private Object mActivityContainerLock = new Object();
+
private Activity mActivity;
private int mWidth;
private int mHeight;
@@ -63,8 +127,6 @@ public class ActivityView extends ViewGroup {
private int mLastVisibility;
private ActivityViewCallback mActivityViewCallback;
- private HandlerThread mThread = new HandlerThread("ActivityViewThread");
- private Handler mHandler;
public ActivityView(Context context) {
this(context, null);
@@ -97,28 +159,14 @@ public class ActivityView extends ViewGroup {
+ e);
}
- mThread.start();
- mHandler = new Handler(mThread.getLooper()) {
- @Override
- public void handleMessage(Message msg) {
- super.handleMessage(msg);
- if (msg.what == MSG_SET_SURFACE) {
- try {
- mActivityContainer.setSurface((Surface) msg.obj, msg.arg1, msg.arg2,
- mMetrics.densityDpi);
- } catch (RemoteException e) {
- throw new RuntimeException(
- "ActivityView: Unable to set surface of ActivityContainer. " + e);
- }
- }
- }
- };
mTextureView = new TextureView(context);
mTextureView.setSurfaceTextureListener(new ActivityViewSurfaceTextureListener());
addView(mTextureView);
WindowManager wm = (WindowManager)mActivity.getSystemService(Context.WINDOW_SERVICE);
- wm.getDefaultDisplay().getMetrics(mMetrics);
+ DisplayMetrics metrics = new DisplayMetrics();
+ wm.getDefaultDisplay().getMetrics(metrics);
+ mDensityDpi = metrics.densityDpi;
mLastVisibility = getVisibility();
@@ -131,15 +179,13 @@ public class ActivityView extends ViewGroup {
}
@Override
- protected void onVisibilityChanged(View changedView, int visibility) {
+ protected void onVisibilityChanged(View changedView, final int visibility) {
super.onVisibilityChanged(changedView, visibility);
if (mSurface != null && (visibility == View.GONE || mLastVisibility == View.GONE)) {
- Message msg = Message.obtain(mHandler, MSG_SET_SURFACE);
- msg.obj = (visibility == View.GONE) ? null : mSurface;
- msg.arg1 = mWidth;
- msg.arg2 = mHeight;
- mHandler.sendMessage(msg);
+ if (DEBUG) Log.v(TAG, "visibility changed; enqueing runnable");
+ final Surface surface = (visibility == View.GONE) ? null : mSurface;
+ setSurfaceAsync(surface, mWidth, mHeight, mDensityDpi, false);
}
mLastVisibility = visibility;
}
@@ -230,8 +276,10 @@ public class ActivityView extends ViewGroup {
Log.e(TAG, "Duplicate call to release");
return;
}
- mActivityContainer.release();
- mActivityContainer = null;
+ synchronized (mActivityContainerLock) {
+ mActivityContainer.release();
+ mActivityContainer = null;
+ }
if (mSurface != null) {
mSurface.release();
@@ -241,21 +289,37 @@ public class ActivityView extends ViewGroup {
mTextureView.setSurfaceTextureListener(null);
}
- private void attachToSurfaceWhenReady() {
- final SurfaceTexture surfaceTexture = mTextureView.getSurfaceTexture();
- if (surfaceTexture == null || mSurface != null) {
- // Either not ready to attach, or already attached.
- return;
- }
-
- mSurface = new Surface(surfaceTexture);
- try {
- mActivityContainer.setSurface(mSurface, mWidth, mHeight, mMetrics.densityDpi);
- } catch (RemoteException e) {
- mSurface.release();
- mSurface = null;
- throw new RuntimeException("ActivityView: Unable to create ActivityContainer. " + e);
- }
+ private void setSurfaceAsync(final Surface surface, final int width, final int height,
+ final int densityDpi, final boolean callback) {
+ mExecutor.execute(new Runnable() {
+ public void run() {
+ try {
+ synchronized (mActivityContainerLock) {
+ if (mActivityContainer != null) {
+ mActivityContainer.setSurface(surface, width, height, densityDpi);
+ }
+ }
+ } catch (RemoteException e) {
+ throw new RuntimeException(
+ "ActivityView: Unable to set surface of ActivityContainer. ",
+ e);
+ }
+ if (callback) {
+ post(new Runnable() {
+ @Override
+ public void run() {
+ if (mActivityViewCallback != null) {
+ if (surface != null) {
+ mActivityViewCallback.onSurfaceAvailable(ActivityView.this);
+ } else {
+ mActivityViewCallback.onSurfaceDestroyed(ActivityView.this);
+ }
+ }
+ }
+ });
+ }
+ }
+ });
}
/**
@@ -306,10 +370,8 @@ public class ActivityView extends ViewGroup {
+ height);
mWidth = width;
mHeight = height;
- attachToSurfaceWhenReady();
- if (mActivityViewCallback != null) {
- mActivityViewCallback.onSurfaceAvailable(ActivityView.this);
- }
+ mSurface = new Surface(surfaceTexture);
+ setSurfaceAsync(mSurface, mWidth, mHeight, mDensityDpi, true);
}
@Override
@@ -329,15 +391,7 @@ public class ActivityView extends ViewGroup {
if (DEBUG) Log.d(TAG, "onSurfaceTextureDestroyed");
mSurface.release();
mSurface = null;
- try {
- mActivityContainer.setSurface(null, mWidth, mHeight, mMetrics.densityDpi);
- } catch (RemoteException e) {
- throw new RuntimeException(
- "ActivityView: Unable to set surface of ActivityContainer. " + e);
- }
- if (mActivityViewCallback != null) {
- mActivityViewCallback.onSurfaceDestroyed(ActivityView.this);
- }
+ setSurfaceAsync(null, mWidth, mHeight, mDensityDpi, true);
return true;
}
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 479010d..d443d80 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -40,8 +40,6 @@ import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.AssetManager;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
-import android.content.res.IThemeService;
-import android.content.res.ThemeManager;
import android.content.res.Resources;
import android.database.DatabaseErrorHandler;
import android.database.sqlite.SQLiteDatabase;
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index a27f9c8..6370268 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -129,6 +129,7 @@ public interface IActivityManager extends IInterface {
ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException;
public Point getAppTaskThumbnailSize() throws RemoteException;
public List<RunningTaskInfo> getTasks(int maxNum, int flags) throws RemoteException;
+ public boolean isPackageInForeground(String packageName) throws RemoteException;
public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
int flags, int userId) throws RemoteException;
public ActivityManager.TaskThumbnail getTaskThumbnail(int taskId) throws RemoteException;
@@ -870,4 +871,5 @@ public interface IActivityManager extends IInterface {
= IBinder.FIRST_CALL_TRANSACTION+299;
int SHOW_ASSIST_FROM_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+300;
int IS_ROOT_VOICE_INTERACTION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+301;
+ int IS_PACKAGE_IN_FOREGROUND_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+302;
}
diff --git a/core/java/android/content/res/IThemeChangeListener.aidl b/core/java/android/app/IBatteryService.aidl
index a2e2abd..196159b 100644
--- a/core/java/android/content/res/IThemeChangeListener.aidl
+++ b/core/java/android/app/IBatteryService.aidl
@@ -1,11 +1,11 @@
-/*
- * Copyright (C) 2014 The CyanogenMod Project
+/**
+ * Copyright (c) 2016, The CyanogenMod 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
+ * 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,
@@ -13,10 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package android.content.res;
-/** {@hide} */
-oneway interface IThemeChangeListener {
- void onProgress(int progress);
- void onFinish(boolean isSuccess);
+package android.app;
+
+/**
+ * System private API for talking with the battery service.
+ *
+ * {@hide}
+ */
+interface IBatteryService {
+ boolean isDockBatterySupported();
}
diff --git a/core/java/android/app/IconPackHelper.java b/core/java/android/app/IconPackHelper.java
index 627330f..80fb401 100644
--- a/core/java/android/app/IconPackHelper.java
+++ b/core/java/android/app/IconPackHelper.java
@@ -25,7 +25,6 @@ import java.util.Map;
import java.util.Random;
import android.content.pm.PackageInfo;
-import android.content.res.IThemeService;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
@@ -44,7 +43,10 @@ import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.Log;
import android.util.TypedValue;
+
import com.android.internal.util.cm.palette.Palette;
+
+import org.cyanogenmod.internal.themes.IIconCacheManager;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
@@ -103,6 +105,12 @@ public class IconPackHelper {
private static final float DEFAULT_SCALE = 1.0f;
private static final int COMPOSED_ICON_COOKIE = 128;
+ private static final String ICON_CACHE_SERVICE = "cmiconcache";
+
+ public static final String SYSTEM_THEME_PATH = "/data/system/theme";
+ public static final String SYSTEM_THEME_ICON_CACHE_DIR = SYSTEM_THEME_PATH
+ + File.separator + "icons";
+
private final Context mContext;
private Map<ComponentName, String> mIconPackResourceMap;
private String mLoadedIconPackName;
@@ -410,15 +418,12 @@ public class IconPackHelper {
String prefixPath;
String iconApkPath;
- String iconResPath;
if (info.isLegacyIconPackApk) {
- iconResPath = "";
iconApkPath = "";
prefixPath = "";
} else {
prefixPath = ThemeUtils.ICONS_PATH; //path inside APK
iconApkPath = ThemeUtils.getIconPackApkPath(packageName);
- iconResPath = ThemeUtils.getIconPackResPath(packageName);
}
AssetManager assets = new AssetManager();
@@ -587,11 +592,11 @@ public class IconPackHelper {
public static class IconCustomizer {
private static final Random sRandom = new Random();
- private static final IThemeService sThemeService;
+ private static final IIconCacheManager sIconCacheManager;
static {
- sThemeService = IThemeService.Stub.asInterface(
- ServiceManager.getService(Context.THEME_SERVICE));
+ sIconCacheManager = IIconCacheManager.Stub.asInterface(
+ ServiceManager.getService(ICON_CACHE_SERVICE));
}
public static Drawable getComposedIconDrawable(Drawable icon, Context context,
@@ -802,7 +807,7 @@ public class IconPackHelper {
private static boolean cacheComposedIcon(Bitmap bmp, String path) {
try {
- return sThemeService.cacheComposedIcon(bmp, path);
+ return sIconCacheManager.cacheComposedIcon(bmp, path);
} catch (RemoteException e) {
Log.e(TAG, "Unable to cache icon.", e);
}
@@ -811,7 +816,7 @@ public class IconPackHelper {
}
private static String getCachedIconPath(String pkgName, int resId, int density) {
- return String.format("%s/%s", ThemeUtils.SYSTEM_THEME_ICON_CACHE_DIR,
+ return String.format("%s/%s", SYSTEM_THEME_ICON_CACHE_DIR,
getCachedIconName(pkgName, resId, density));
}
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index cd07c9c..d8e01cd 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -45,6 +45,7 @@ import android.os.UserHandle;
import android.text.TextUtils;
import android.util.Log;
import android.util.MathUtils;
+import android.util.SparseArray;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
@@ -62,6 +63,8 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
+import java.util.Objects;
+import java.util.Set;
/**
* A class that represents how a persistent notification is to be presented to
@@ -960,6 +963,9 @@ public class Notification implements Parcelable
private Action(Icon icon, CharSequence title, PendingIntent intent, Bundle extras,
RemoteInput[] remoteInputs) {
this.mIcon = icon;
+ if (icon != null && icon.getType() == Icon.TYPE_RESOURCE) {
+ this.icon = icon.getResId();
+ }
this.title = title;
this.actionIntent = intent;
this.mExtras = extras != null ? extras : new Bundle();
@@ -1607,13 +1613,23 @@ public class Notification implements Parcelable
bigContentView = null;
headsUpContentView = null;
mLargeIcon = null;
- if (extras != null) {
- extras.remove(Notification.EXTRA_LARGE_ICON);
- extras.remove(Notification.EXTRA_LARGE_ICON_BIG);
- extras.remove(Notification.EXTRA_PICTURE);
- extras.remove(Notification.EXTRA_BIG_TEXT);
+ if (extras != null && !extras.isEmpty()) {
// Prevent light notifications from being rebuilt.
extras.remove(Builder.EXTRA_NEEDS_REBUILD);
+ final Set<String> keyset = extras.keySet();
+ final int N = keyset.size();
+ final String[] keys = keyset.toArray(new String[N]);
+ for (int i=0; i<N; i++) {
+ final String key = keys[i];
+ final Object obj = extras.get(key);
+ if (obj != null &&
+ ( obj instanceof Parcelable
+ || obj instanceof Parcelable[]
+ || obj instanceof SparseArray
+ || obj instanceof ArrayList)) {
+ extras.remove(key);
+ }
+ }
}
}
@@ -4619,7 +4635,7 @@ public class Notification implements Parcelable
* Size value for use with {@link #setCustomSizePreset} to show this notification with
* default sizing.
* <p>For custom display notifications created using {@link #setDisplayIntent},
- * the default is {@link #SIZE_LARGE}. All other notifications size automatically based
+ * the default is {@link #SIZE_MEDIUM}. All other notifications size automatically based
* on their content.
*/
public static final int SIZE_DEFAULT = 0;
diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java
index 7492cd0..e2d0537 100644
--- a/core/java/android/app/ResourcesManager.java
+++ b/core/java/android/app/ResourcesManager.java
@@ -625,7 +625,8 @@ public class ResourcesManager {
String targetPackagePath = piTarget.applicationInfo.sourceDir;
String prefixPath = ThemeUtils.getOverlayPathToTarget(basePackageName);
- String resCachePath = ThemeUtils.getTargetCacheDir(piTarget.packageName, piTheme);
+ String resCachePath = ThemeUtils.getTargetCacheDir(piTarget.packageName,
+ piTheme.packageName);
String resApkPath = resCachePath + "/resources.apk";
String idmapPath = ThemeUtils.getIdmapPath(piTarget.packageName, piTheme.packageName);
int cookie = assets.addOverlayPath(idmapPath, themePath, resApkPath,
@@ -639,7 +640,8 @@ public class ResourcesManager {
if (!piTarget.isThemeApk && !"android".equals(basePackageName) &&
piTheme.mOverlayTargets.contains("android")) {
- String resCachePath= ThemeUtils.getTargetCacheDir(piAndroid.packageName, piTheme);
+ String resCachePath= ThemeUtils.getTargetCacheDir(piAndroid.packageName,
+ piTheme.packageName);
String prefixPath = ThemeUtils.getOverlayPathToTarget(piAndroid.packageName);
String targetPackagePath = piAndroid.applicationInfo.publicSourceDir;
String resApkPath = resCachePath + "/resources.apk";
@@ -742,7 +744,7 @@ public class ResourcesManager {
String themePath = piTheme.applicationInfo.publicSourceDir;
String prefixPath = ThemeUtils.COMMON_RES_PATH;
String resCachePath =
- ThemeUtils.getTargetCacheDir(ThemeUtils.COMMON_RES_TARGET, piTheme);
+ ThemeUtils.getTargetCacheDir(ThemeUtils.COMMON_RES_TARGET, piTheme.packageName);
String resApkPath = resCachePath + "/resources.apk";
int cookie = assets.addCommonOverlayPath(themePath, resApkPath,
prefixPath);
diff --git a/core/java/android/app/StatusBarManager.java b/core/java/android/app/StatusBarManager.java
index 5e8ad68..fad3f62 100644
--- a/core/java/android/app/StatusBarManager.java
+++ b/core/java/android/app/StatusBarManager.java
@@ -92,6 +92,7 @@ public class StatusBarManager {
public static final int CAMERA_LAUNCH_SOURCE_WIGGLE = 0;
public static final int CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP = 1;
+ public static final int CAMERA_LAUNCH_SOURCE_SCREEN_GESTURE = 2;
private Context mContext;
private IStatusBarService mService;
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 08f4efd..34c967f 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -37,9 +37,7 @@ import android.content.IRestrictionsManager;
import android.content.RestrictionsManager;
import android.content.pm.ILauncherApps;
import android.content.pm.LauncherApps;
-import android.content.res.IThemeService;
import android.content.res.Resources;
-import android.content.res.ThemeManager;
import android.hardware.ConsumerIrManager;
import android.hardware.ISerialManager;
import android.hardware.SensorManager;
@@ -256,7 +254,9 @@ final class SystemServiceRegistry {
new StaticServiceFetcher<BatteryManager>() {
@Override
public BatteryManager createService() {
- return new BatteryManager();
+ IBinder b = ServiceManager.getService(Context.BATTERY_SERVICE);
+ IBatteryService service = IBatteryService.Stub.asInterface(b);
+ return new BatteryManager(service);
}});
registerService(Context.NFC_SERVICE, NfcManager.class,
@@ -706,15 +706,6 @@ final class SystemServiceRegistry {
public RadioManager createService(ContextImpl ctx) {
return new RadioManager(ctx);
}});
-
- registerService(Context.THEME_SERVICE, ThemeManager.class,
- new CachedServiceFetcher<ThemeManager>() {
- public ThemeManager createService(ContextImpl ctx) {
- IBinder b = ServiceManager.getService(Context.THEME_SERVICE);
- IThemeService service = IThemeService.Stub.asInterface(b);
- return new ThemeManager(ctx.getOuterContext(),
- service);
- }});
}
/**
diff --git a/core/java/android/app/backup/FullBackup.java b/core/java/android/app/backup/FullBackup.java
index 7718a36..0335e28 100644
--- a/core/java/android/app/backup/FullBackup.java
+++ b/core/java/android/app/backup/FullBackup.java
@@ -21,6 +21,8 @@ import android.content.pm.PackageManager;
import android.content.res.XmlResourceParser;
import android.os.*;
import android.os.Process;
+import android.os.storage.StorageManager;
+import android.os.storage.StorageVolume;
import android.system.ErrnoException;
import android.system.Os;
import android.text.TextUtils;
@@ -207,6 +209,8 @@ public class FullBackup {
final int mFullBackupContent;
final PackageManager mPackageManager;
+ final StorageManager mStorageManager;
+ final StorageVolume[] mVolumes;
final String mPackageName;
/**
@@ -230,6 +234,15 @@ public class FullBackup {
} else {
return null;
}
+ } else if (domainToken.startsWith(FullBackup.SHARED_PREFIX)) {
+ int slash = domainToken.indexOf('/');
+ int i = Integer.parseInt(domainToken.substring(slash + 1));
+
+ if (i < mVolumes.length) {
+ return mVolumes[i].getPath();
+ } else {
+ Log.e(TAG, "Could not find volume for " + domainToken);
+ }
} else if (domainToken.equals(FullBackup.NO_BACKUP_TREE_TOKEN)) {
return NOBACKUP_DIR.getCanonicalPath();
}
@@ -263,6 +276,8 @@ public class FullBackup {
SHAREDPREF_DIR = context.getSharedPrefsFile("foo").getParentFile();
CACHE_DIR = context.getCacheDir();
NOBACKUP_DIR = context.getNoBackupFilesDir();
+ mStorageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
+ mVolumes = mStorageManager.getVolumeList();
if (android.os.Process.myUid() != Process.SYSTEM_UID) {
EXTERNAL_DIR = context.getExternalFilesDir(null);
} else {
diff --git a/core/java/android/app/usage/UsageStats.java b/core/java/android/app/usage/UsageStats.java
index 0fce4e2..a88aa31 100644
--- a/core/java/android/app/usage/UsageStats.java
+++ b/core/java/android/app/usage/UsageStats.java
@@ -165,14 +165,18 @@ public final class UsageStats implements Parcelable {
mPackageName + "' with UsageStats for package '" + right.mPackageName + "'.");
}
- if (right.mEndTimeStamp > mEndTimeStamp) {
+ if (right.mBeginTimeStamp > mBeginTimeStamp) {
+ // The incoming UsageStat begins after this one, so use its last time used fields
+ // as the source of truth.
+ // We use the mBeginTimeStamp due to a bug where UsageStats files can overlap with
+ // regards to their mEndTimeStamp.
mLastEvent = right.mLastEvent;
- mEndTimeStamp = right.mEndTimeStamp;
mLastTimeUsed = right.mLastTimeUsed;
mBeginIdleTime = right.mBeginIdleTime;
mLastTimeSystemUsed = right.mLastTimeSystemUsed;
}
mBeginTimeStamp = Math.min(mBeginTimeStamp, right.mBeginTimeStamp);
+ mEndTimeStamp = Math.max(mEndTimeStamp, right.mEndTimeStamp);
mTotalTimeInForeground += right.mTotalTimeInForeground;
mLaunchCount += right.mLaunchCount;
}
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 24beba6..f924bc1 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -95,7 +95,7 @@ import java.util.UUID;
*/
public final class BluetoothAdapter {
private static final String TAG = "BluetoothAdapter";
- private static final boolean DBG = true;
+ private static final boolean DBG = false;
private static final boolean VDBG = false;
/**
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index e742b2b..b4006de 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -25,6 +25,7 @@ import android.content.Context;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.ParcelUuid;
+import android.os.Process;
import android.os.RemoteException;
import android.util.Log;
@@ -823,6 +824,9 @@ public final class BluetoothDevice implements Parcelable {
return false;
}
try {
+ Log.i(TAG, "createBond() for device " + getAddress() +
+ " called by pid: " + Process.myPid() +
+ " tid: " + Process.myTid());
return sService.createBond(this, TRANSPORT_AUTO);
} catch (RemoteException e) {Log.e(TAG, "", e);}
return false;
@@ -854,6 +858,9 @@ public final class BluetoothDevice implements Parcelable {
throw new IllegalArgumentException(transport + " is not a valid Bluetooth transport");
}
try {
+ Log.i(TAG, "createBond() for device " + getAddress() +
+ " called by pid: " + Process.myPid() +
+ " tid: " + Process.myTid());
return sService.createBond(this, transport);
} catch (RemoteException e) {Log.e(TAG, "", e);}
return false;
@@ -922,6 +929,9 @@ public final class BluetoothDevice implements Parcelable {
return false;
}
try {
+ Log.i(TAG, "cancelBondProcess() for device " + getAddress() +
+ " called by pid: " + Process.myPid() +
+ " tid: " + Process.myTid());
return sService.cancelBondProcess(this);
} catch (RemoteException e) {Log.e(TAG, "", e);}
return false;
@@ -943,6 +953,9 @@ public final class BluetoothDevice implements Parcelable {
return false;
}
try {
+ Log.i(TAG, "removeBond() for device " + getAddress() +
+ " called by pid: " + Process.myPid() +
+ " tid: " + Process.myTid());
return sService.removeBond(this);
} catch (RemoteException e) {Log.e(TAG, "", e);}
return false;
diff --git a/core/java/android/bluetooth/BluetoothHeadset.java b/core/java/android/bluetooth/BluetoothHeadset.java
index 8d4742b..da81032 100644
--- a/core/java/android/bluetooth/BluetoothHeadset.java
+++ b/core/java/android/bluetooth/BluetoothHeadset.java
@@ -24,6 +24,7 @@ import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;
+import android.os.UserHandle;
import android.util.Log;
import java.util.ArrayList;
@@ -302,7 +303,7 @@ public final class BluetoothHeadset implements BluetoothProfile {
ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
intent.setComponent(comp);
if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
- android.os.Process.myUserHandle())) {
+ UserHandle.CURRENT_OR_SELF)) {
Log.e(TAG, "Could not bind to Bluetooth Headset Service with " + intent);
return false;
}
@@ -709,6 +710,48 @@ public final class BluetoothHeadset implements BluetoothProfile {
}
/**
+ * Sets whether audio routing is allowed. When set to {@code false}, the AG will not route any
+ * audio to the HF unless explicitly told to.
+ * This method should be used in cases where the SCO channel is shared between multiple profiles
+ * and must be delegated by a source knowledgeable
+ * Note: This is an internal function and shouldn't be exposed
+ *
+ * @param allowed {@code true} if the profile can reroute audio, {@code false} otherwise.
+ *
+ * @hide
+ */
+ public void setAudioRouteAllowed(boolean allowed) {
+ if (VDBG) log("setAudioRouteAllowed");
+ if (mService != null && isEnabled()) {
+ try {
+ mService.setAudioRouteAllowed(allowed);
+ } catch (RemoteException e) {Log.e(TAG, e.toString());}
+ } else {
+ Log.w(TAG, "Proxy not attached to service");
+ if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
+ }
+ }
+
+ /**
+ * Returns whether audio routing is allowed. see {@link #setAudioRouteAllowed(boolean)}.
+ * Note: This is an internal function and shouldn't be exposed
+ *
+ * @hide
+ */
+ public boolean getAudioRouteAllowed() {
+ if (VDBG) log("getAudioRouteAllowed");
+ if (mService != null && isEnabled()) {
+ try {
+ return mService.getAudioRouteAllowed();
+ } catch (RemoteException e) {Log.e(TAG, e.toString());}
+ } else {
+ Log.w(TAG, "Proxy not attached to service");
+ if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
+ }
+ return false;
+ }
+
+ /**
* Check if Bluetooth SCO audio is connected.
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
diff --git a/core/java/android/bluetooth/BluetoothHeadsetClient.java b/core/java/android/bluetooth/BluetoothHeadsetClient.java
index 10d851f..484a856 100644
--- a/core/java/android/bluetooth/BluetoothHeadsetClient.java
+++ b/core/java/android/bluetooth/BluetoothHeadsetClient.java
@@ -1076,6 +1076,41 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
}
/**
+ * Sets whether audio routing is allowed.
+ *
+ * Note: This is an internal function and shouldn't be exposed
+ */
+ public void setAudioRouteAllowed(boolean allowed) {
+ if (VDBG) log("setAudioRouteAllowed");
+ if (mService != null && isEnabled()) {
+ try {
+ mService.setAudioRouteAllowed(allowed);
+ } catch (RemoteException e) {Log.e(TAG, e.toString());}
+ } else {
+ Log.w(TAG, "Proxy not attached to service");
+ if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
+ }
+ }
+
+ /**
+ * Returns whether audio routing is allowed.
+ *
+ * Note: This is an internal function and shouldn't be exposed
+ */
+ public boolean getAudioRouteAllowed() {
+ if (VDBG) log("getAudioRouteAllowed");
+ if (mService != null && isEnabled()) {
+ try {
+ return mService.getAudioRouteAllowed();
+ } catch (RemoteException e) {Log.e(TAG, e.toString());}
+ } else {
+ Log.w(TAG, "Proxy not attached to service");
+ if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
+ }
+ return false;
+ }
+
+ /**
* Initiates a connection of audio channel.
*
* It setup SCO channel with remote connected Handsfree AG device.
diff --git a/core/java/android/bluetooth/BluetoothHeadsetClientCall.java b/core/java/android/bluetooth/BluetoothHeadsetClientCall.java
index 7b5a045..002f63f 100644
--- a/core/java/android/bluetooth/BluetoothHeadsetClientCall.java
+++ b/core/java/android/bluetooth/BluetoothHeadsetClientCall.java
@@ -19,6 +19,8 @@ package android.bluetooth;
import android.os.Parcel;
import android.os.Parcelable;
+import java.util.UUID;
+
/**
* This class represents a single call, its state and properties.
* It implements {@link Parcelable} for inter-process message passing.
@@ -67,14 +69,21 @@ public final class BluetoothHeadsetClientCall implements Parcelable {
private String mNumber;
private boolean mMultiParty;
private final boolean mOutgoing;
+ private final UUID mUUID;
/**
* Creates BluetoothHeadsetClientCall instance.
*/
public BluetoothHeadsetClientCall(BluetoothDevice device, int id, int state, String number,
boolean multiParty, boolean outgoing) {
+ this(device, id, UUID.randomUUID(), state, number, multiParty, outgoing);
+ }
+
+ public BluetoothHeadsetClientCall(BluetoothDevice device, int id, UUID uuid, int state,
+ String number, boolean multiParty, boolean outgoing) {
mDevice = device;
mId = id;
+ mUUID = uuid;
mState = state;
mNumber = number != null ? number : "";
mMultiParty = multiParty;
@@ -134,6 +143,16 @@ public final class BluetoothHeadsetClientCall implements Parcelable {
}
/**
+ * Gets call's UUID.
+ *
+ * @return call uuid
+ * @hide
+ */
+ public UUID getUUID() {
+ return mUUID;
+ }
+
+ /**
* Gets call's current state.
*
* @return state of this particular phone call.
@@ -172,10 +191,16 @@ public final class BluetoothHeadsetClientCall implements Parcelable {
}
public String toString() {
+ return toString(false);
+ }
+
+ public String toString(boolean loggable) {
StringBuilder builder = new StringBuilder("BluetoothHeadsetClientCall{mDevice: ");
- builder.append(mDevice);
+ builder.append(loggable ? mDevice.hashCode() : mDevice);
builder.append(", mId: ");
builder.append(mId);
+ builder.append(", mUUID: ");
+ builder.append(mUUID);
builder.append(", mState: ");
switch (mState) {
case CALL_STATE_ACTIVE: builder.append("ACTIVE"); break;
@@ -189,7 +214,7 @@ public final class BluetoothHeadsetClientCall implements Parcelable {
default: builder.append(mState); break;
}
builder.append(", mNumber: ");
- builder.append(mNumber);
+ builder.append(loggable ? mNumber.hashCode() : mNumber);
builder.append(", mMultiParty: ");
builder.append(mMultiParty);
builder.append(", mOutgoing: ");
@@ -206,8 +231,8 @@ public final class BluetoothHeadsetClientCall implements Parcelable {
@Override
public BluetoothHeadsetClientCall createFromParcel(Parcel in) {
return new BluetoothHeadsetClientCall((BluetoothDevice)in.readParcelable(null),
- in.readInt(), in.readInt(), in.readString(),
- in.readInt() == 1, in.readInt() == 1);
+ in.readInt(), UUID.fromString(in.readString()), in.readInt(),
+ in.readString(), in.readInt() == 1, in.readInt() == 1);
}
@Override
@@ -220,6 +245,7 @@ public final class BluetoothHeadsetClientCall implements Parcelable {
public void writeToParcel(Parcel out, int flags) {
out.writeParcelable(mDevice, 0);
out.writeInt(mId);
+ out.writeString(mUUID.toString());
out.writeInt(mState);
out.writeString(mNumber);
out.writeInt(mMultiParty ? 1 : 0);
diff --git a/core/java/android/bluetooth/IBluetoothHeadset.aidl b/core/java/android/bluetooth/IBluetoothHeadset.aidl
index 0e23fad..0bb4088 100755
--- a/core/java/android/bluetooth/IBluetoothHeadset.aidl
+++ b/core/java/android/bluetooth/IBluetoothHeadset.aidl
@@ -50,6 +50,8 @@ interface IBluetoothHeadset {
boolean isAudioOn();
boolean connectAudio();
boolean disconnectAudio();
+ void setAudioRouteAllowed(boolean allowed);
+ boolean getAudioRouteAllowed();
boolean startScoUsingVirtualVoiceCall(in BluetoothDevice device);
boolean stopScoUsingVirtualVoiceCall(in BluetoothDevice device);
void phoneStateChanged(int numActive, int numHeld, int callState, String number, int type);
diff --git a/core/java/android/bluetooth/IBluetoothHeadsetClient.aidl b/core/java/android/bluetooth/IBluetoothHeadsetClient.aidl
index e518b7d..79ae4e4 100644
--- a/core/java/android/bluetooth/IBluetoothHeadsetClient.aidl
+++ b/core/java/android/bluetooth/IBluetoothHeadsetClient.aidl
@@ -62,6 +62,8 @@ interface IBluetoothHeadsetClient {
int getAudioState(in BluetoothDevice device);
boolean connectAudio();
boolean disconnectAudio();
+ void setAudioRouteAllowed(boolean allowed);
+ boolean getAudioRouteAllowed();
Bundle getCurrentAgFeatures(in BluetoothDevice device);
}
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index fc40a73..7ddda11 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -3152,16 +3152,6 @@ public abstract class Context {
/**
* Use with {@link #getSystemService} to retrieve a
- * {@link android.content.res.ThemeManager} for accessing theme service.
- *
- * @see #getSystemService
- * @see android.content.res.ThemeManager
- * @hide
- */
- public static final String THEME_SERVICE = "themes";
-
- /**
- * Use with {@link #getSystemService} to retrieve a
* {@link android.nfc.NfcManager} for using NFC.
*
* @see #getSystemService
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 2a24fe3..c06f98a 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1605,6 +1605,23 @@ public class Intent implements Parcelable, Cloneable {
= "android.intent.action.GET_PERMISSIONS_COUNT";
/**
+ * Broadcast action that requests list of all apps that have runtime permissions. It will
+ * respond to the request by sending a broadcast with action defined by
+ * {@link #EXTRA_GET_PERMISSIONS_PACKAGES_RESPONSE_INTENT}. The response will contain
+ * {@link #EXTRA_GET_PERMISSIONS_APP_LIST_RESULT}, as well as
+ * {@link #EXTRA_GET_PERMISSIONS_APP_LABEL_LIST_RESULT}, with contents described below or
+ * a null upon failure.
+ *
+ * <p>{@link #EXTRA_GET_PERMISSIONS_APP_LIST_RESULT} will contain a list of package names of
+ * apps that have runtime permissions. {@link #EXTRA_GET_PERMISSIONS_APP_LABEL_LIST_RESULT}
+ * will contain the list of app labels corresponding ot the apps in the first list.
+ *
+ * @hide
+ */
+ public static final String ACTION_GET_PERMISSIONS_PACKAGES
+ = "android.intent.action.GET_PERMISSIONS_PACKAGES";
+
+ /**
* Extra included in response to {@link #ACTION_GET_PERMISSIONS_COUNT}.
* @hide
*/
@@ -1619,6 +1636,28 @@ public class Intent implements Parcelable, Cloneable {
= "android.intent.extra.GET_PERMISSIONS_GROUP_LIST_RESULT";
/**
+ * String list of apps that have one or more runtime permissions.
+ * @hide
+ */
+ public static final String EXTRA_GET_PERMISSIONS_APP_LIST_RESULT
+ = "android.intent.extra.GET_PERMISSIONS_APP_LIST_RESULT";
+
+ /**
+ * String list of app labels for apps that have one or more runtime permissions.
+ * @hide
+ */
+ public static final String EXTRA_GET_PERMISSIONS_APP_LABEL_LIST_RESULT
+ = "android.intent.extra.GET_PERMISSIONS_APP_LABEL_LIST_RESULT";
+
+ /**
+ * Boolean list describing if the app is a system app for apps that have one or more runtime
+ * permissions.
+ * @hide
+ */
+ public static final String EXTRA_GET_PERMISSIONS_IS_SYSTEM_APP_LIST_RESULT
+ = "android.intent.extra.GET_PERMISSIONS_IS_SYSTEM_APP_LIST_RESULT";
+
+ /**
* Required extra to be sent with {@link #ACTION_GET_PERMISSIONS_COUNT} broadcasts.
* @hide
*/
@@ -1626,6 +1665,13 @@ public class Intent implements Parcelable, Cloneable {
= "android.intent.extra.GET_PERMISSIONS_RESONSE_INTENT";
/**
+ * Required extra to be sent with {@link #ACTION_GET_PERMISSIONS_PACKAGES} broadcasts.
+ * @hide
+ */
+ public static final String EXTRA_GET_PERMISSIONS_PACKAGES_RESPONSE_INTENT
+ = "android.intent.extra.GET_PERMISSIONS_PACKAGES_RESONSE_INTENT";
+
+ /**
* Activity action: Launch UI to manage which apps have a given permission.
* <p>
* Input: {@link #EXTRA_PERMISSION_NAME} specifies the permission access
@@ -2881,21 +2927,6 @@ public class Intent implements Parcelable, Cloneable {
"android.intent.action.QUICK_CLOCK";
/**
- * Broadcast Action: Indicate that unrecoverable error happened during app launch.
- * Could indicate that curently applied theme is malicious.
- * @hide
- */
- public static final String ACTION_APP_FAILURE =
- "com.tmobile.intent.action.APP_FAILURE";
-
- /**
- * Broadcast Action: Request to reset the unrecoverable errors count to 0.
- * @hide
- */
- public static final String ACTION_APP_FAILURE_RESET =
- "com.tmobile.intent.action.APP_FAILURE_RESET";
-
- /**
* Activity Action: Shows the brightness setting dialog.
* @hide
*/
@@ -3081,6 +3112,39 @@ public class Intent implements Parcelable, Cloneable {
public static final String ACTION_DOZE_PULSE_STARTING =
"android.intent.action.DOZE_PULSE_STARTING";
+ /**
+ * Broadcast action: reports when a new thermal event has been reached. When the device
+ * is reaching its maximum temperatue, the thermal level reported
+ * {@hide}
+ */
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String ACTION_THERMAL_EVENT = "android.intent.action.THERMAL_EVENT";
+
+ /** {@hide} */
+ public static final String EXTRA_THERMAL_STATE = "android.intent.extra.THERMAL_STATE";
+
+ /**
+ * Thermal state when the device is normal. This state is sent in the
+ * {@link ACTION_THERMAL_EVENT} broadcast as {@link EXTRA_THERMAL_STATE}.
+ * {@hide}
+ */
+ public static final int EXTRA_THERMAL_STATE_NORMAL = 0;
+
+ /**
+ * Thermal state where the device is approaching its maximum threshold. This state is sent in
+ * the {@link ACTION_THERMAL_EVENT} broadcast as {@link EXTRA_THERMAL_STATE}.
+ * {@hide}
+ */
+ public static final int EXTRA_THERMAL_STATE_WARNING = 1;
+
+ /**
+ * Thermal state where the device has reached its maximum threshold. This state is sent in the
+ * {@link ACTION_THERMAL_EVENT} broadcast as {@link EXTRA_THERMAL_STATE}.
+ * {@hide}
+ */
+ public static final int EXTRA_THERMAL_STATE_EXCEEDED = 2;
+
+
// ---------------------------------------------------------------------
// ---------------------------------------------------------------------
// Standard intent categories (see addCategory()).
@@ -3183,6 +3247,13 @@ public class Intent implements Parcelable, Cloneable {
@SdkConstant(SdkConstantType.INTENT_CATEGORY)
public static final String CATEGORY_HOME = "android.intent.category.HOME";
/**
+ * This is the home activity that is displayed when the device is finished setting up and ready
+ * for use.
+ * @hide
+ */
+ @SdkConstant(SdkConstantType.INTENT_CATEGORY)
+ public static final String CATEGORY_HOME_MAIN = "android.intent.category.HOME_MAIN";
+ /**
* This is the setup wizard activity, that is the first activity that is displayed
* when the user sets up the device for the first time.
* @hide
@@ -3282,14 +3353,6 @@ public class Intent implements Parcelable, Cloneable {
@SdkConstant(SdkConstantType.INTENT_CATEGORY)
public static final String CATEGORY_CAR_MODE = "android.intent.category.CAR_MODE";
- /**
- * Used to indicate that a theme package has been installed or un-installed.
- *
- * @hide
- */
- public static final String CATEGORY_THEME_PACKAGE_INSTALLED_STATE_CHANGE =
- "com.tmobile.intent.category.THEME_PACKAGE_INSTALL_STATE_CHANGE";
-
// ---------------------------------------------------------------------
// ---------------------------------------------------------------------
// Application launch intent categories (see addCategory()).
diff --git a/core/java/android/content/pm/ThemeUtils.java b/core/java/android/content/pm/ThemeUtils.java
index e41523c..07e73b5 100644
--- a/core/java/android/content/pm/ThemeUtils.java
+++ b/core/java/android/content/pm/ThemeUtils.java
@@ -15,112 +15,30 @@
*/
package android.content.pm;
-import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.ContextWrapper;
-import android.content.IntentFilter;
-import android.content.res.AssetManager;
-import android.content.res.Configuration;
import android.content.res.ThemeConfig;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.media.RingtoneManager;
-import android.net.Uri;
-import android.os.FileUtils;
-import android.os.SystemProperties;
-import android.provider.MediaStore;
-import android.provider.Settings;
-import android.provider.ThemesContract;
-import android.provider.ThemesContract.ThemesColumns;
import android.text.TextUtils;
-import android.util.DisplayMetrics;
-import android.util.Log;
-import android.view.WindowManager;
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
-import java.io.BufferedReader;
import java.io.File;
-import java.io.FileOutputStream;
import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.InputStreamReader;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
import java.util.jar.StrictJarFile;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.zip.CRC32;
import java.util.zip.ZipEntry;
-import java.util.zip.ZipInputStream;
-import java.util.zip.ZipOutputStream;
-
-import static android.content.res.ThemeConfig.SYSTEM_DEFAULT;
/**
* @hide
*/
public class ThemeUtils {
- private static final String TAG = "ThemeUtils";
+ private static final String TAG = ThemeUtils.class.getSimpleName();
/* Path inside a theme APK to the overlay folder */
public static final String OVERLAY_PATH = "assets/overlays/";
public static final String ICONS_PATH = "assets/icons/";
public static final String COMMON_RES_PATH = "assets/overlays/common/";
- public static final String FONT_XML = "fonts.xml";
public static final String RESOURCE_CACHE_DIR = "/data/resource-cache/";
- public static final String IDMAP_SUFFIX = "@idmap";
- public static final String COMMON_RES_SUFFIX = ".common";
public static final String COMMON_RES_TARGET = "common";
- public static final String ICON_HASH_FILENAME = "hash";
-
- // path to external theme resources, i.e. bootanimation.zip
- public static final String SYSTEM_THEME_PATH = "/data/system/theme";
- public static final String SYSTEM_THEME_FONT_PATH = SYSTEM_THEME_PATH + File.separator + "fonts";
- public static final String SYSTEM_THEME_RINGTONE_PATH = SYSTEM_THEME_PATH
- + File.separator + "ringtones";
- public static final String SYSTEM_THEME_NOTIFICATION_PATH = SYSTEM_THEME_PATH
- + File.separator + "notifications";
- public static final String SYSTEM_THEME_ALARM_PATH = SYSTEM_THEME_PATH
- + File.separator + "alarms";
- public static final String SYSTEM_THEME_ICON_CACHE_DIR = SYSTEM_THEME_PATH
- + File.separator + "icons";
- // internal path to bootanimation.zip inside theme apk
- public static final String THEME_BOOTANIMATION_PATH = "assets/bootanimation/bootanimation.zip";
-
- public static final String SYSTEM_MEDIA_PATH = "/system/media/audio";
- public static final String SYSTEM_ALARMS_PATH = SYSTEM_MEDIA_PATH + File.separator
- + "alarms";
- public static final String SYSTEM_RINGTONES_PATH = SYSTEM_MEDIA_PATH + File.separator
- + "ringtones";
- public static final String SYSTEM_NOTIFICATIONS_PATH = SYSTEM_MEDIA_PATH + File.separator
- + "notifications";
-
- // path to asset lockscreen and wallpapers directory
- public static final String LOCKSCREEN_WALLPAPER_PATH = "lockscreen";
- public static final String WALLPAPER_PATH = "wallpapers";
-
- private static final String MEDIA_CONTENT_URI = "content://media/internal/audio/media";
-
- // Constants for theme change broadcast
- public static final String ACTION_THEME_CHANGED = "org.cyanogenmod.intent.action.THEME_CHANGED";
- public static final String CATEGORY_THEME_COMPONENT_PREFIX = "org.cyanogenmod.intent.category.";
- public static final String EXTRA_COMPONENTS = "components";
- public static final String EXTRA_REQUEST_TYPE = "request_type";
- public static final String EXTRA_UPDATE_TIME = "update_time";
-
- public static final int SYSTEM_TARGET_API = 0;
// Package name for any app which does not have a specific theme applied
private static final String DEFAULT_PKG = "default";
- private static final String SETTINGS_DB =
- "/data/data/com.android.providers.settings/databases/settings.db";
- private static final String SETTINGS_SECURE_TABLE = "secure";
private static final String MANIFEST_NAME = "META-INF/MANIFEST.MF";
/**
@@ -156,18 +74,10 @@ public class ThemeUtils {
/**
* Get the path of the resource cache for the given target and theme
- * @param targetPkgName
- * @param themePkg
+ * @param targetPkgName Target app package name
+ * @param themePkgName Theme package name
* @return Path to the resource cache for this target and theme
*/
- public static String getTargetCacheDir(String targetPkgName, PackageInfo themePkg) {
- return getTargetCacheDir(targetPkgName, themePkg.packageName);
- }
-
- public static String getTargetCacheDir(String targetPkgName, PackageParser.Package themePkg) {
- return getTargetCacheDir(targetPkgName, themePkg.packageName);
- }
-
public static String getTargetCacheDir(String targetPkgName, String themePkgName) {
return getOverlayResourceCacheDir(themePkgName) + File.separator + targetPkgName;
}
@@ -181,18 +91,10 @@ public class ThemeUtils {
return getOverlayResourceCacheDir(pkgName) + File.separator + "icons";
}
- public static String getIconHashFile(String pkgName) {
- return getIconPackDir(pkgName) + File.separator + ICON_HASH_FILENAME;
- }
-
public static String getIconPackApkPath(String pkgName) {
return getIconPackDir(pkgName) + "/resources.apk";
}
- public static String getIconPackResPath(String pkgName) {
- return getIconPackDir(pkgName) + "/resources.arsc";
- }
-
public static String getIdmapPath(String targetPkgName, String overlayPkgName) {
return getTargetCacheDir(targetPkgName, overlayPkgName) + File.separator + "idmap";
}
@@ -211,507 +113,6 @@ public class ThemeUtils {
return COMMON_RES_TARGET;
}
- public static void createCacheDirIfNotExists() throws IOException {
- File file = new File(RESOURCE_CACHE_DIR);
- if (!file.exists() && !file.mkdir()) {
- throw new IOException("Could not create dir: " + file.toString());
- }
- FileUtils.setPermissions(file, FileUtils.S_IRWXU
- | FileUtils.S_IRWXG | FileUtils.S_IROTH | FileUtils.S_IXOTH, -1, -1);
- }
-
- public static void createResourcesDirIfNotExists(String targetPkgName, String overlayPkgName)
- throws IOException {
- createDirIfNotExists(getOverlayResourceCacheDir(overlayPkgName));
- File file = new File(getTargetCacheDir(targetPkgName, overlayPkgName));
- if (!file.exists() && !file.mkdir()) {
- throw new IOException("Could not create dir: " + file.toString());
- }
- FileUtils.setPermissions(file, FileUtils.S_IRWXU
- | FileUtils.S_IRWXG | FileUtils.S_IROTH | FileUtils.S_IXOTH, -1, -1);
- }
-
- public static void createIconDirIfNotExists(String pkgName) throws IOException {
- createDirIfNotExists(getOverlayResourceCacheDir(pkgName));
- File file = new File(getIconPackDir(pkgName));
- if (!file.exists() && !file.mkdir()) {
- throw new IOException("Could not create dir: " + file.toString());
- }
- FileUtils.setPermissions(file, FileUtils.S_IRWXU
- | FileUtils.S_IRWXG | FileUtils.S_IROTH | FileUtils.S_IXOTH, -1, -1);
- }
-
- private static boolean dirExists(String dirPath) {
- final File dir = new File(dirPath);
- return dir.exists() && dir.isDirectory();
- }
-
- private static void createDirIfNotExists(String dirPath) {
- if (!dirExists(dirPath)) {
- File dir = new File(dirPath);
- if (dir.mkdir()) {
- FileUtils.setPermissions(dir, FileUtils.S_IRWXU |
- FileUtils.S_IRWXG| FileUtils.S_IROTH | FileUtils.S_IXOTH, -1, -1);
- }
- }
- }
-
- /**
- * Create SYSTEM_THEME_PATH directory if it does not exist
- */
- public static void createThemeDirIfNotExists() {
- createDirIfNotExists(SYSTEM_THEME_PATH);
- }
-
- /**
- * Create SYSTEM_FONT_PATH directory if it does not exist
- */
- public static void createFontDirIfNotExists() {
- createDirIfNotExists(SYSTEM_THEME_FONT_PATH);
- }
-
- /**
- * Create SYSTEM_THEME_RINGTONE_PATH directory if it does not exist
- */
- public static void createRingtoneDirIfNotExists() {
- createDirIfNotExists(SYSTEM_THEME_RINGTONE_PATH);
- }
-
- /**
- * Create SYSTEM_THEME_NOTIFICATION_PATH directory if it does not exist
- */
- public static void createNotificationDirIfNotExists() {
- createDirIfNotExists(SYSTEM_THEME_NOTIFICATION_PATH);
- }
-
- /**
- * Create SYSTEM_THEME_ALARM_PATH directory if it does not exist
- */
- public static void createAlarmDirIfNotExists() {
- createDirIfNotExists(SYSTEM_THEME_ALARM_PATH);
- }
-
- /**
- * Create SYSTEM_THEME_ICON_CACHE_DIR directory if it does not exist
- */
- public static void createIconCacheDirIfNotExists() {
- createDirIfNotExists(SYSTEM_THEME_ICON_CACHE_DIR);
- }
-
- public static void clearIconCache() {
- FileUtils.deleteContents(new File(SYSTEM_THEME_ICON_CACHE_DIR));
- }
-
- public static InputStream getInputStreamFromAsset(Context ctx, String path) throws IOException {
- if (ctx == null || path == null)
- return null;
- InputStream is = null;
- String ASSET_BASE = "file:///android_asset/";
- path = path.substring(ASSET_BASE.length());
- AssetManager assets = ctx.getAssets();
- is = assets.open(path);
- return is;
- }
-
- public static void closeQuietly(InputStream stream) {
- if (stream == null)
- return;
- try {
- stream.close();
- } catch (IOException e) {
- }
- }
-
- public static void closeQuietly(OutputStream stream) {
- if (stream == null)
- return;
- try {
- stream.close();
- } catch (IOException e) {
- }
- }
-
- /**
- * Scale the boot animation to better fit the device by editing the desc.txt found
- * in the bootanimation.zip
- * @param context Context to use for getting an instance of the WindowManager
- * @param input InputStream of the original bootanimation.zip
- * @param dst Path to store the newly created bootanimation.zip
- * @throws IOException
- */
- public static void copyAndScaleBootAnimation(Context context, InputStream input, String dst)
- throws IOException {
- final OutputStream os = new FileOutputStream(dst);
- final ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(os));
- final ZipInputStream bootAni = new ZipInputStream(new BufferedInputStream(input));
- ZipEntry ze;
-
- zos.setMethod(ZipOutputStream.STORED);
- final byte[] bytes = new byte[4096];
- int len;
- while ((ze = bootAni.getNextEntry()) != null) {
- ZipEntry entry = new ZipEntry(ze.getName());
- entry.setMethod(ZipEntry.STORED);
- entry.setCrc(ze.getCrc());
- entry.setSize(ze.getSize());
- entry.setCompressedSize(ze.getSize());
- if (!ze.getName().equals("desc.txt")) {
- // just copy this entry straight over into the output zip
- zos.putNextEntry(entry);
- while ((len = bootAni.read(bytes)) > 0) {
- zos.write(bytes, 0, len);
- }
- } else {
- String line;
- BufferedReader reader = new BufferedReader(new InputStreamReader(bootAni));
- final String[] info = reader.readLine().split(" ");
-
- int scaledWidth;
- int scaledHeight;
- WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
- DisplayMetrics dm = new DisplayMetrics();
- wm.getDefaultDisplay().getRealMetrics(dm);
- // just in case the device is in landscape orientation we will
- // swap the values since most (if not all) animations are portrait
- if (dm.widthPixels > dm.heightPixels) {
- scaledWidth = dm.heightPixels;
- scaledHeight = dm.widthPixels;
- } else {
- scaledWidth = dm.widthPixels;
- scaledHeight = dm.heightPixels;
- }
-
- int width = Integer.parseInt(info[0]);
- int height = Integer.parseInt(info[1]);
-
- if (width == height)
- scaledHeight = scaledWidth;
- else {
- // adjust scaledHeight to retain original aspect ratio
- float scale = (float)scaledWidth / (float)width;
- int newHeight = (int)((float)height * scale);
- if (newHeight < scaledHeight)
- scaledHeight = newHeight;
- }
-
- CRC32 crc32 = new CRC32();
- int size = 0;
- ByteBuffer buffer = ByteBuffer.wrap(bytes);
- line = String.format("%d %d %s\n", scaledWidth, scaledHeight, info[2]);
- buffer.put(line.getBytes());
- size += line.getBytes().length;
- crc32.update(line.getBytes());
- while ((line = reader.readLine()) != null) {
- line = String.format("%s\n", line);
- buffer.put(line.getBytes());
- size += line.getBytes().length;
- crc32.update(line.getBytes());
- }
- entry.setCrc(crc32.getValue());
- entry.setSize(size);
- entry.setCompressedSize(size);
- zos.putNextEntry(entry);
- zos.write(buffer.array(), 0, size);
- }
- zos.closeEntry();
- }
- zos.close();
- }
-
- public static boolean isValidAudible(String fileName) {
- return (fileName != null &&
- (fileName.endsWith(".mp3") || fileName.endsWith(".ogg")));
- }
-
- public static boolean setAudible(Context context, File ringtone, int type, String name) {
- final String path = ringtone.getAbsolutePath();
- final String mimeType = name.endsWith(".ogg") ? "audio/ogg" : "audio/mp3";
- ContentValues values = new ContentValues();
- values.put(MediaStore.MediaColumns.DATA, path);
- values.put(MediaStore.MediaColumns.TITLE, name);
- values.put(MediaStore.MediaColumns.MIME_TYPE, mimeType);
- values.put(MediaStore.MediaColumns.SIZE, ringtone.length());
- values.put(MediaStore.Audio.Media.IS_RINGTONE, type == RingtoneManager.TYPE_RINGTONE);
- values.put(MediaStore.Audio.Media.IS_NOTIFICATION,
- type == RingtoneManager.TYPE_NOTIFICATION);
- values.put(MediaStore.Audio.Media.IS_ALARM, type == RingtoneManager.TYPE_ALARM);
- values.put(MediaStore.Audio.Media.IS_MUSIC, false);
-
- Uri uri = MediaStore.Audio.Media.getContentUriForPath(path);
- Uri newUri = null;
- Cursor c = context.getContentResolver().query(uri,
- new String[] {MediaStore.MediaColumns._ID},
- MediaStore.MediaColumns.DATA + "='" + path + "'",
- null, null);
- if (c != null && c.getCount() > 0) {
- c.moveToFirst();
- long id = c.getLong(0);
- c.close();
- newUri = Uri.withAppendedPath(Uri.parse(MEDIA_CONTENT_URI), "" + id);
- context.getContentResolver().update(uri, values,
- MediaStore.MediaColumns._ID + "=" + id, null);
- }
- if (newUri == null)
- newUri = context.getContentResolver().insert(uri, values);
- try {
- RingtoneManager.setActualDefaultRingtoneUri(context, type, newUri);
- } catch (Exception e) {
- return false;
- }
- return true;
- }
-
- public static boolean setDefaultAudible(Context context, int type) {
- final String audiblePath = getDefaultAudiblePath(type);
- if (audiblePath != null) {
- Uri uri = MediaStore.Audio.Media.getContentUriForPath(audiblePath);
- Cursor c = context.getContentResolver().query(uri,
- new String[] {MediaStore.MediaColumns._ID},
- MediaStore.MediaColumns.DATA + "='" + audiblePath + "'",
- null, null);
- if (c != null && c.getCount() > 0) {
- c.moveToFirst();
- long id = c.getLong(0);
- c.close();
- uri = Uri.withAppendedPath(
- Uri.parse(MEDIA_CONTENT_URI), "" + id);
- }
- if (uri != null)
- RingtoneManager.setActualDefaultRingtoneUri(context, type, uri);
- } else {
- return false;
- }
- return true;
- }
-
- public static String getDefaultAudiblePath(int type) {
- final String name;
- final String path;
- switch (type) {
- case RingtoneManager.TYPE_ALARM:
- name = SystemProperties.get("ro.config.alarm_alert", null);
- path = name != null ? SYSTEM_ALARMS_PATH + File.separator + name : null;
- break;
- case RingtoneManager.TYPE_NOTIFICATION:
- name = SystemProperties.get("ro.config.notification_sound", null);
- path = name != null ? SYSTEM_NOTIFICATIONS_PATH + File.separator + name : null;
- break;
- case RingtoneManager.TYPE_RINGTONE:
- name = SystemProperties.get("ro.config.ringtone", null);
- path = name != null ? SYSTEM_RINGTONES_PATH + File.separator + name : null;
- break;
- default:
- path = null;
- break;
- }
- return path;
- }
-
- public static void clearAudibles(Context context, String audiblePath) {
- final File audibleDir = new File(audiblePath);
- if (audibleDir.exists()) {
- String[] files = audibleDir.list();
- final ContentResolver resolver = context.getContentResolver();
- for (String s : files) {
- final String filePath = audiblePath + File.separator + s;
- Uri uri = MediaStore.Audio.Media.getContentUriForPath(filePath);
- resolver.delete(uri, MediaStore.MediaColumns.DATA + "=\""
- + filePath + "\"", null);
- (new File(filePath)).delete();
- }
- }
- }
-
- public static Context createUiContext(final Context context) {
- try {
- Context uiContext = context.createPackageContext("com.android.systemui",
- Context.CONTEXT_RESTRICTED);
- return new ThemedUiContext(uiContext, context.getApplicationContext());
- } catch (PackageManager.NameNotFoundException e) {
- }
-
- return null;
- }
-
- public static void registerThemeChangeReceiver(final Context context,
- final BroadcastReceiver receiver) {
- IntentFilter filter = new IntentFilter(ACTION_THEME_CHANGED);
-
- context.registerReceiver(receiver, filter);
- }
-
- public static String getLockscreenWallpaperPath(AssetManager assetManager) throws IOException {
- String[] assets = assetManager.list(LOCKSCREEN_WALLPAPER_PATH);
- String asset = getFirstNonEmptyAsset(assets);
- if (asset == null) return null;
- return LOCKSCREEN_WALLPAPER_PATH + File.separator + asset;
- }
-
- public static String getWallpaperPath(AssetManager assetManager) throws IOException {
- String[] assets = assetManager.list(WALLPAPER_PATH);
- String asset = getFirstNonEmptyAsset(assets);
- if (asset == null) return null;
- return WALLPAPER_PATH + File.separator + asset;
- }
-
- public static List<String> getWallpaperPathList(AssetManager assetManager)
- throws IOException {
- List<String> wallpaperList = new ArrayList<String>();
- String[] assets = assetManager.list(WALLPAPER_PATH);
- for (String asset : assets) {
- if (!TextUtils.isEmpty(asset)) {
- wallpaperList.add(WALLPAPER_PATH + File.separator + asset);
- }
- }
- return wallpaperList;
- }
-
- // Returns the first non-empty asset name. Empty assets can occur if the APK is built
- // with folders included as zip entries in the APK. Searching for files inside "folderName" via
- // assetManager.list("folderName") can cause these entries to be included as empty strings.
- private static String getFirstNonEmptyAsset(String[] assets) {
- if (assets == null) return null;
- String filename = null;
- for(String asset : assets) {
- if (!TextUtils.isEmpty(asset)) {
- filename = asset;
- break;
- }
- }
- return filename;
- }
-
- public static String getDefaultThemePackageName(Context context) {
- final String defaultThemePkg = Settings.Secure.getString(context.getContentResolver(),
- Settings.Secure.DEFAULT_THEME_PACKAGE);
- if (!TextUtils.isEmpty(defaultThemePkg)) {
- PackageManager pm = context.getPackageManager();
- try {
- if (pm.getPackageInfo(defaultThemePkg, 0) != null) {
- return defaultThemePkg;
- }
- } catch (PackageManager.NameNotFoundException e) {
- // doesn't exist so system will be default
- Log.w(TAG, "Default theme " + defaultThemePkg + " not found", e);
- }
- }
-
- return SYSTEM_DEFAULT;
- }
-
- private static class ThemedUiContext extends ContextWrapper {
- private Context mAppContext;
-
- public ThemedUiContext(Context context, Context appContext) {
- super(context);
- mAppContext = appContext;
- }
-
- @Override
- public Context getApplicationContext() {
- return mAppContext;
- }
-
- @Override
- public String getPackageName() {
- return mAppContext.getPackageName();
- }
- }
-
- // Returns a mutable list of all theme components
- public static List<String> getAllComponents() {
- List<String> components = new ArrayList<String>(9);
- components.add(ThemesColumns.MODIFIES_FONTS);
- components.add(ThemesColumns.MODIFIES_LAUNCHER);
- components.add(ThemesColumns.MODIFIES_ALARMS);
- components.add(ThemesColumns.MODIFIES_BOOT_ANIM);
- components.add(ThemesColumns.MODIFIES_ICONS);
- components.add(ThemesColumns.MODIFIES_LOCKSCREEN);
- components.add(ThemesColumns.MODIFIES_NOTIFICATIONS);
- components.add(ThemesColumns.MODIFIES_OVERLAYS);
- components.add(ThemesColumns.MODIFIES_RINGTONES);
- components.add(ThemesColumns.MODIFIES_STATUS_BAR);
- components.add(ThemesColumns.MODIFIES_NAVIGATION_BAR);
- components.add(ThemesColumns.MODIFIES_LIVE_LOCK_SCREEN);
- return components;
- }
-
- /**
- * Returns a mutable list of all the theme components supported by a given package
- * NOTE: This queries the themes content provider. If there isn't a provider installed
- * or if it is too early in the boot process this method will not work.
- */
- public static List<String> getSupportedComponents(Context context, String pkgName) {
- List<String> supportedComponents = new ArrayList<String>();
-
- String selection = ThemesContract.ThemesColumns.PKG_NAME + "= ?";
- String[] selectionArgs = new String[]{ pkgName };
- Cursor c = context.getContentResolver().query(ThemesContract.ThemesColumns.CONTENT_URI,
- null, selection, selectionArgs, null);
-
- if (c != null) {
- if (c.moveToFirst()) {
- List<String> allComponents = getAllComponents();
- for (String component : allComponents) {
- int index = c.getColumnIndex(component);
- if (c.getInt(index) == 1) {
- supportedComponents.add(component);
- }
- }
- }
- c.close();
- }
- return supportedComponents;
- }
-
- /**
- * Get the components from the default theme. If the default theme is not SYSTEM then any
- * components that are not in the default theme will come from SYSTEM to create a complete
- * component map.
- * @param context
- * @return
- */
- public static Map<String, String> getDefaultComponents(Context context) {
- String defaultThemePkg = getDefaultThemePackageName(context);
- List<String> defaultComponents = null;
- List<String> systemComponents = getSupportedComponents(context, SYSTEM_DEFAULT);
- if (!SYSTEM_DEFAULT.equals(defaultThemePkg)) {
- defaultComponents = getSupportedComponents(context, defaultThemePkg);
- }
-
- Map<String, String> componentMap = new HashMap<String, String>(systemComponents.size());
- if (defaultComponents != null) {
- for (String component : defaultComponents) {
- componentMap.put(component, defaultThemePkg);
- }
- }
- for (String component : systemComponents) {
- if (!componentMap.containsKey(component)) {
- componentMap.put(component, SYSTEM_DEFAULT);
- }
- }
-
- return componentMap;
- }
-
- /**
- * Takes an existing component map and adds any missing components from the default
- * map of components.
- * @param context
- * @param componentMap An existing component map
- */
- public static void completeComponentMap(Context context,
- Map<String, String> componentMap) {
- if (componentMap == null) return;
-
- Map<String, String> defaultComponents = getDefaultComponents(context);
- for (String component : defaultComponents.keySet()) {
- if (!componentMap.containsKey(component)) {
- componentMap.put(component, defaultComponents.get(component));
- }
- }
- }
-
/**
* Convenience method to determine if a theme component is a per app theme and not a standard
* component.
diff --git a/core/java/android/content/res/IThemeProcessingListener.aidl b/core/java/android/content/res/IThemeProcessingListener.aidl
deleted file mode 100644
index 2e1c16e..0000000
--- a/core/java/android/content/res/IThemeProcessingListener.aidl
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 2014 The CyanogenMod Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.content.res;
-
-/** {@hide} */
-oneway interface IThemeProcessingListener {
- void onFinishedProcessing(String pkgName);
-}
diff --git a/core/java/android/content/res/IThemeService.aidl b/core/java/android/content/res/IThemeService.aidl
deleted file mode 100644
index 90cb9fb..0000000
--- a/core/java/android/content/res/IThemeService.aidl
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2014 The CyanogenMod Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.content.res;
-
-import android.content.res.IThemeChangeListener;
-import android.content.res.IThemeProcessingListener;
-import android.content.res.ThemeChangeRequest;
-import android.graphics.Bitmap;
-
-import java.util.Map;
-
-/** {@hide} */
-interface IThemeService {
- void requestThemeChangeUpdates(in IThemeChangeListener listener);
- void removeUpdates(in IThemeChangeListener listener);
-
- void requestThemeChange(in ThemeChangeRequest request, boolean removePerAppThemes);
- void applyDefaultTheme();
- boolean isThemeApplying();
- int getProgress();
-
- boolean cacheComposedIcon(in Bitmap icon, String path);
-
- boolean processThemeResources(String themePkgName);
- boolean isThemeBeingProcessed(String themePkgName);
- void registerThemeProcessingListener(in IThemeProcessingListener listener);
- void unregisterThemeProcessingListener(in IThemeProcessingListener listener);
-
- void rebuildResourceCache();
-}
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index 85ecc0a..6a404e2 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -1554,10 +1554,12 @@ public class Resources {
* if not already defined in the theme.
*/
public void applyStyle(int resId, boolean force) {
- AssetManager.applyThemeStyle(mTheme, resId, force);
+ synchronized (mKey) {
+ AssetManager.applyThemeStyle(mTheme, resId, force);
- mThemeResId = resId;
- mKey.append(resId, force);
+ mThemeResId = resId;
+ mKey.append(resId, force);
+ }
}
/**
@@ -1570,10 +1572,14 @@ public class Resources {
* @param other The existing Theme to copy from.
*/
public void setTo(Theme other) {
- AssetManager.copyTheme(mTheme, other.mTheme);
+ synchronized (mKey) {
+ synchronized (other.mKey) {
+ AssetManager.copyTheme(mTheme, other.mTheme);
- mThemeResId = other.mThemeResId;
- mKey.setTo(other.getKey());
+ mThemeResId = other.mThemeResId;
+ mKey.setTo(other.getKey());
+ }
+ }
}
/**
@@ -1596,11 +1602,13 @@ public class Resources {
* @see #obtainStyledAttributes(AttributeSet, int[], int, int)
*/
public TypedArray obtainStyledAttributes(@StyleableRes int[] attrs) {
- final int len = attrs.length;
- final TypedArray array = TypedArray.obtain(Resources.this, len);
- array.mTheme = this;
- AssetManager.applyStyle(mTheme, 0, 0, 0, attrs, array.mData, array.mIndices);
- return array;
+ synchronized (mKey) {
+ final int len = attrs.length;
+ final TypedArray array = TypedArray.obtain(Resources.this, len);
+ array.mTheme = this;
+ AssetManager.applyStyle(mTheme, 0, 0, 0, attrs, array.mData, array.mIndices);
+ return array;
+ }
}
/**
@@ -1610,7 +1618,7 @@ public class Resources {
* <p>Be sure to call {@link TypedArray#recycle() TypedArray.recycle()} when you are done
* with the array.
*
- * @param resid The desired style resource.
+ * @param resId The desired style resource.
* @param attrs The desired attributes in the style.
*
* @throws NotFoundException Throws NotFoundException if the given ID does not exist.
@@ -1623,39 +1631,15 @@ public class Resources {
* @see #obtainStyledAttributes(int[])
* @see #obtainStyledAttributes(AttributeSet, int[], int, int)
*/
- public TypedArray obtainStyledAttributes(@StyleRes int resid, @StyleableRes int[] attrs)
+ public TypedArray obtainStyledAttributes(@StyleRes int resId, @StyleableRes int[] attrs)
throws NotFoundException {
- final int len = attrs.length;
- final TypedArray array = TypedArray.obtain(Resources.this, len);
- array.mTheme = this;
- if (false) {
- int[] data = array.mData;
-
- System.out.println("**********************************************************");
- System.out.println("**********************************************************");
- System.out.println("**********************************************************");
- System.out.println("Attributes:");
- String s = " Attrs:";
- int i;
- for (i=0; i<attrs.length; i++) {
- s = s + " 0x" + Integer.toHexString(attrs[i]);
- }
- System.out.println(s);
- s = " Found:";
- TypedValue value = new TypedValue();
- for (i=0; i<attrs.length; i++) {
- int d = i*AssetManager.STYLE_NUM_ENTRIES;
- value.type = data[d+AssetManager.STYLE_TYPE];
- value.data = data[d+AssetManager.STYLE_DATA];
- value.assetCookie = data[d+AssetManager.STYLE_ASSET_COOKIE];
- value.resourceId = data[d+AssetManager.STYLE_RESOURCE_ID];
- s = s + " 0x" + Integer.toHexString(attrs[i])
- + "=" + value;
- }
- System.out.println(s);
+ synchronized (mKey) {
+ final int len = attrs.length;
+ final TypedArray array = TypedArray.obtain(Resources.this, len);
+ array.mTheme = this;
+ AssetManager.applyStyle(mTheme, 0, resId, 0, attrs, array.mData, array.mIndices);
+ return array;
}
- AssetManager.applyStyle(mTheme, 0, resid, 0, attrs, array.mData, array.mIndices);
- return array;
}
/**
@@ -1708,50 +1692,23 @@ public class Resources {
*/
public TypedArray obtainStyledAttributes(AttributeSet set,
@StyleableRes int[] attrs, @AttrRes int defStyleAttr, @StyleRes int defStyleRes) {
- final int len = attrs.length;
- final TypedArray array = TypedArray.obtain(Resources.this, len);
-
- // XXX note that for now we only work with compiled XML files.
- // To support generic XML files we will need to manually parse
- // out the attributes from the XML file (applying type information
- // contained in the resources and such).
- final XmlBlock.Parser parser = (XmlBlock.Parser)set;
- AssetManager.applyStyle(mTheme, defStyleAttr, defStyleRes,
- parser != null ? parser.mParseState : 0, attrs, array.mData, array.mIndices);
+ synchronized (mKey) {
+ final int len = attrs.length;
+ final TypedArray array = TypedArray.obtain(Resources.this, len);
- array.mTheme = this;
- array.mXml = parser;
+ // XXX note that for now we only work with compiled XML files.
+ // To support generic XML files we will need to manually parse
+ // out the attributes from the XML file (applying type information
+ // contained in the resources and such).
+ final XmlBlock.Parser parser = (XmlBlock.Parser) set;
+ AssetManager.applyStyle(mTheme, defStyleAttr, defStyleRes,
+ parser != null ? parser.mParseState : 0,
+ attrs, array.mData, array.mIndices);
+ array.mTheme = this;
+ array.mXml = parser;
- if (false) {
- int[] data = array.mData;
-
- System.out.println("Attributes:");
- String s = " Attrs:";
- int i;
- for (i=0; i<set.getAttributeCount(); i++) {
- s = s + " " + set.getAttributeName(i);
- int id = set.getAttributeNameResource(i);
- if (id != 0) {
- s = s + "(0x" + Integer.toHexString(id) + ")";
- }
- s = s + "=" + set.getAttributeValue(i);
- }
- System.out.println(s);
- s = " Found:";
- TypedValue value = new TypedValue();
- for (i=0; i<attrs.length; i++) {
- int d = i*AssetManager.STYLE_NUM_ENTRIES;
- value.type = data[d+AssetManager.STYLE_TYPE];
- value.data = data[d+AssetManager.STYLE_DATA];
- value.assetCookie = data[d+AssetManager.STYLE_ASSET_COOKIE];
- value.resourceId = data[d+AssetManager.STYLE_RESOURCE_ID];
- s = s + " 0x" + Integer.toHexString(attrs[i])
- + "=" + value;
- }
- System.out.println(s);
+ return array;
}
-
- return array;
}
/**
@@ -1770,18 +1727,20 @@ public class Resources {
*/
@NonNull
public TypedArray resolveAttributes(@NonNull int[] values, @NonNull int[] attrs) {
- final int len = attrs.length;
- if (values == null || len != values.length) {
- throw new IllegalArgumentException(
- "Base attribute values must the same length as attrs");
- }
+ synchronized (mKey) {
+ final int len = attrs.length;
+ if (values == null || len != values.length) {
+ throw new IllegalArgumentException(
+ "Base attribute values must the same length as attrs");
+ }
- final TypedArray array = TypedArray.obtain(Resources.this, len);
- AssetManager.resolveAttrs(mTheme, 0, 0, values, attrs, array.mData, array.mIndices);
- array.mTheme = this;
- array.mXml = null;
+ final TypedArray array = TypedArray.obtain(Resources.this, len);
+ AssetManager.resolveAttrs(mTheme, 0, 0, values, attrs, array.mData, array.mIndices);
+ array.mTheme = this;
+ array.mXml = null;
- return array;
+ return array;
+ }
}
/**
@@ -1802,14 +1761,9 @@ public class Resources {
* <var>outValue</var> is valid, else false.
*/
public boolean resolveAttribute(int resid, TypedValue outValue, boolean resolveRefs) {
- boolean got = mAssets.getThemeValue(mTheme, resid, outValue, resolveRefs);
- if (false) {
- System.out.println(
- "resolveAttribute #" + Integer.toHexString(resid)
- + " got=" + got + ", type=0x" + Integer.toHexString(outValue.type)
- + ", data=0x" + Integer.toHexString(outValue.data));
+ synchronized (mKey) {
+ return mAssets.getThemeValue(mTheme, resid, outValue, resolveRefs);
}
- return got;
}
/**
@@ -1855,8 +1809,11 @@ public class Resources {
* @see ActivityInfo
*/
public int getChangingConfigurations() {
- final int nativeChangingConfig = AssetManager.getThemeChangingConfigurations(mTheme);
- return ActivityInfo.activityInfoConfigNativeToJava(nativeChangingConfig);
+ synchronized (mKey) {
+ final int nativeChangingConfig =
+ AssetManager.getThemeChangingConfigurations(mTheme);
+ return ActivityInfo.activityInfoConfigNativeToJava(nativeChangingConfig);
+ }
}
/**
@@ -1867,7 +1824,9 @@ public class Resources {
* @param prefix Text to prefix each line printed.
*/
public void dump(int priority, String tag, String prefix) {
- AssetManager.dumpTheme(mTheme, priority, tag, prefix);
+ synchronized (mKey) {
+ AssetManager.dumpTheme(mTheme, priority, tag, prefix);
+ }
}
@Override
@@ -1917,19 +1876,21 @@ public class Resources {
*/
@ViewDebug.ExportedProperty(category = "theme", hasAdjacentMapping = true)
public String[] getTheme() {
- final int N = mKey.mCount;
- final String[] themes = new String[N * 2];
- for (int i = 0, j = N - 1; i < themes.length; i += 2, --j) {
- final int resId = mKey.mResId[j];
- final boolean forced = mKey.mForce[j];
- try {
- themes[i] = getResourceName(resId);
- } catch (NotFoundException e) {
- themes[i] = Integer.toHexString(i);
+ synchronized (mKey) {
+ final int N = mKey.mCount;
+ final String[] themes = new String[N * 2];
+ for (int i = 0, j = N - 1; i < themes.length; i += 2, --j) {
+ final int resId = mKey.mResId[j];
+ final boolean forced = mKey.mForce[j];
+ try {
+ themes[i] = getResourceName(resId);
+ } catch (NotFoundException e) {
+ themes[i] = Integer.toHexString(i);
+ }
+ themes[i + 1] = forced ? "forced" : "not forced";
}
- themes[i + 1] = forced ? "forced" : "not forced";
+ return themes;
}
- return themes;
}
/** @hide */
@@ -1950,13 +1911,15 @@ public class Resources {
* @hide
*/
public void rebase() {
- AssetManager.clearTheme(mTheme);
-
- // Reapply the same styles in the same order.
- for (int i = 0; i < mKey.mCount; i++) {
- final int resId = mKey.mResId[i];
- final boolean force = mKey.mForce[i];
- AssetManager.applyThemeStyle(mTheme, resId, force);
+ synchronized (mKey) {
+ AssetManager.clearTheme(mTheme);
+
+ // Reapply the same styles in the same order.
+ for (int i = 0; i < mKey.mCount; i++) {
+ final int resId = mKey.mResId[i];
+ final boolean force = mKey.mForce[i];
+ AssetManager.applyThemeStyle(mTheme, resId, force);
+ }
}
}
}
diff --git a/core/java/android/content/res/ThemeChangeRequest.aidl b/core/java/android/content/res/ThemeChangeRequest.aidl
deleted file mode 100644
index e6cf115..0000000
--- a/core/java/android/content/res/ThemeChangeRequest.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2015 The CyanogenMod Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.content.res;
-
-/** @hide */
-parcelable ThemeChangeRequest;
diff --git a/core/java/android/content/res/ThemeChangeRequest.java b/core/java/android/content/res/ThemeChangeRequest.java
deleted file mode 100644
index 1d13bb0..0000000
--- a/core/java/android/content/res/ThemeChangeRequest.java
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- * Copyright (C) 2015 The CyanogenMod Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.content.res;
-
-import android.content.pm.ThemeUtils;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-
-import static android.provider.ThemesContract.ThemesColumns.*;
-
-/** @hide */
-public final class ThemeChangeRequest implements Parcelable {
- public static final int DEFAULT_WALLPAPER_ID = -1;
-
- private final Map<String, String> mThemeComponents = new HashMap<String, String>();
- private final Map<String, String> mPerAppOverlays = new HashMap<String, String>();
- private RequestType mRequestType;
- private long mWallpaperId = -1;
-
- public String getOverlayThemePackageName() {
- return getThemePackageNameForComponent(MODIFIES_OVERLAYS);
- }
-
- public String getStatusBarThemePackageName() {
- return getThemePackageNameForComponent(MODIFIES_STATUS_BAR);
- }
-
- public String getNavBarThemePackageName() {
- return getThemePackageNameForComponent(MODIFIES_NAVIGATION_BAR);
- }
-
- public String getFontThemePackageName() {
- return getThemePackageNameForComponent(MODIFIES_FONTS);
- }
-
- public String getIconsThemePackageName() {
- return getThemePackageNameForComponent(MODIFIES_ICONS);
- }
-
- public String getBootanimationThemePackageName() {
- return getThemePackageNameForComponent(MODIFIES_BOOT_ANIM);
- }
-
- public String getWallpaperThemePackageName() {
- return getThemePackageNameForComponent(MODIFIES_LAUNCHER);
- }
-
- public String getLockWallpaperThemePackageName() {
- return getThemePackageNameForComponent(MODIFIES_LOCKSCREEN);
- }
-
- public String getAlarmThemePackageName() {
- return getThemePackageNameForComponent(MODIFIES_ALARMS);
- }
-
- public String getNotificationThemePackageName() {
- return getThemePackageNameForComponent(MODIFIES_NOTIFICATIONS);
- }
-
- public String getRingtoneThemePackageName() {
- return getThemePackageNameForComponent(MODIFIES_RINGTONES);
- }
-
- public String getLiveLockScreenThemePackageName() {
- return getThemePackageNameForComponent(MODIFIES_LIVE_LOCK_SCREEN);
- }
-
- public final Map<String, String> getThemeComponentsMap() {
- return Collections.unmodifiableMap(mThemeComponents);
- }
-
- public long getWallpaperId() {
- return mWallpaperId;
- }
-
- /**
- * Get the mapping for per app themes
- * @return A mapping of apps and the theme to apply for each one. or null if none set.
- */
- public final Map<String, String> getPerAppOverlays() {
- return Collections.unmodifiableMap(mPerAppOverlays);
- }
-
- public int getNumChangesRequested() {
- return mThemeComponents.size() + mPerAppOverlays.size();
- }
-
- public RequestType getReqeustType() {
- return mRequestType;
- }
-
- private String getThemePackageNameForComponent(String componentName) {
- return mThemeComponents.get(componentName);
- }
-
- private ThemeChangeRequest(Map<String, String> components, Map<String, String> perAppThemes,
- RequestType requestType, long wallpaperId) {
- if (components != null) {
- mThemeComponents.putAll(components);
- }
- if (perAppThemes != null) {
- mPerAppOverlays.putAll(perAppThemes);
- }
- mRequestType = requestType;
- mWallpaperId = wallpaperId;
- }
-
- private ThemeChangeRequest(Parcel source) {
- int numComponents = source.readInt();
- for (int i = 0; i < numComponents; i++) {
- mThemeComponents.put(source.readString(), source.readString());
- }
-
- numComponents = source.readInt();
- for (int i = 0 ; i < numComponents; i++) {
- mPerAppOverlays.put(source.readString(), source.readString());
- }
- mRequestType = RequestType.values()[source.readInt()];
- mWallpaperId = source.readLong();
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(mThemeComponents.size());
- for (String component : mThemeComponents.keySet()) {
- dest.writeString(component);
- dest.writeString(mThemeComponents.get(component));
- }
- dest.writeInt((mPerAppOverlays.size()));
- for (String appPkgName : mPerAppOverlays.keySet()) {
- dest.writeString(appPkgName);
- dest.writeString(mPerAppOverlays.get(appPkgName));
- }
- dest.writeInt(mRequestType.ordinal());
- dest.writeLong(mWallpaperId);
- }
-
- public static final Parcelable.Creator<ThemeChangeRequest> CREATOR =
- new Parcelable.Creator<ThemeChangeRequest>() {
- @Override
- public ThemeChangeRequest createFromParcel(Parcel source) {
- return new ThemeChangeRequest(source);
- }
-
- @Override
- public ThemeChangeRequest[] newArray(int size) {
- return new ThemeChangeRequest[size];
- }
- };
-
- public enum RequestType {
- USER_REQUEST,
- USER_REQUEST_MIXNMATCH,
- THEME_UPDATED,
- THEME_REMOVED,
- THEME_RESET;
- }
-
- public static class Builder {
- Map<String, String> mThemeComponents = new HashMap<String, String>();
- Map<String, String> mPerAppOverlays = new HashMap<String, String>();
- RequestType mRequestType = RequestType.USER_REQUEST;
- long mWallpaperId;
-
- public Builder() {}
-
- public Builder(ThemeConfig themeConfig) {
- if (themeConfig != null) {
- buildChangeRequestFromThemeConfig(themeConfig);
- }
- }
-
- public Builder setOverlay(String pkgName) {
- return setComponent(MODIFIES_OVERLAYS, pkgName);
- }
-
- public Builder setStatusBar(String pkgName) {
- return setComponent(MODIFIES_STATUS_BAR, pkgName);
- }
-
- public Builder setNavBar(String pkgName) {
- return setComponent(MODIFIES_NAVIGATION_BAR, pkgName);
- }
-
- public Builder setFont(String pkgName) {
- return setComponent(MODIFIES_FONTS, pkgName);
- }
-
- public Builder setIcons(String pkgName) {
- return setComponent(MODIFIES_ICONS, pkgName);
- }
-
- public Builder setBootanimation(String pkgName) {
- return setComponent(MODIFIES_BOOT_ANIM, pkgName);
- }
-
- public Builder setWallpaper(String pkgName) {
- return setComponent(MODIFIES_LAUNCHER, pkgName);
- }
-
- // Used in the case that more than one wallpaper exists for a given pkg name
- public Builder setWallpaperId(long id) {
- mWallpaperId = id;
- return this;
- }
-
- public Builder setLockWallpaper(String pkgName) {
- return setComponent(MODIFIES_LOCKSCREEN, pkgName);
- }
-
- public Builder setAlarm(String pkgName) {
- return setComponent(MODIFIES_ALARMS, pkgName);
- }
-
- public Builder setNotification(String pkgName) {
- return setComponent(MODIFIES_NOTIFICATIONS, pkgName);
- }
-
- public Builder setRingtone(String pkgName) {
- return setComponent(MODIFIES_RINGTONES, pkgName);
- }
-
- public Builder setLiveLockScreen(String pkgName) {
- return setComponent(MODIFIES_LIVE_LOCK_SCREEN, pkgName);
- }
-
- public Builder setComponent(String component, String pkgName) {
- if (pkgName != null) {
- mThemeComponents.put(component, pkgName);
- } else {
- mThemeComponents.remove(component);
- }
- return this;
- }
-
- public Builder setAppOverlay(String appPkgName, String themePkgName) {
- if (appPkgName != null) {
- if (themePkgName != null) {
- mPerAppOverlays.put(appPkgName, themePkgName);
- } else {
- mPerAppOverlays.remove(appPkgName);
- }
- }
-
- return this;
- }
-
- public Builder setRequestType(RequestType requestType) {
- mRequestType = requestType != null ? requestType : RequestType.USER_REQUEST;
- return this;
- }
-
- public ThemeChangeRequest build() {
- return new ThemeChangeRequest(mThemeComponents, mPerAppOverlays,
- mRequestType, mWallpaperId);
- }
-
- private void buildChangeRequestFromThemeConfig(ThemeConfig themeConfig) {
- if (themeConfig.getFontPkgName() != null) {
- this.setFont(themeConfig.getFontPkgName());
- }
- if (themeConfig.getIconPackPkgName() != null) {
- this.setIcons(themeConfig.getIconPackPkgName());
- }
- if (themeConfig.getOverlayPkgName() != null) {
- this.setOverlay(themeConfig.getOverlayPkgName());
- }
- if (themeConfig.getOverlayForStatusBar() != null) {
- this.setStatusBar(themeConfig.getOverlayForStatusBar());
- }
- if (themeConfig.getOverlayForNavBar() != null) {
- this.setNavBar(themeConfig.getOverlayForNavBar());
- }
-
- // Check if there are any per-app overlays using this theme
- final Map<String, ThemeConfig.AppTheme> themes = themeConfig.getAppThemes();
- for (String appPkgName : themes.keySet()) {
- if (ThemeUtils.isPerAppThemeComponent(appPkgName)) {
- this.setAppOverlay(appPkgName, themes.get(appPkgName).getOverlayPkgName());
- }
- }
- }
- }
-}
diff --git a/core/java/android/content/res/ThemeConfig.java b/core/java/android/content/res/ThemeConfig.java
index ac95d6b..f304801 100644
--- a/core/java/android/content/res/ThemeConfig.java
+++ b/core/java/android/content/res/ThemeConfig.java
@@ -1,12 +1,12 @@
/*
- * Copyright (C) 2014 The CyanogenMod Project
+ * Copyright (C) 2016 The CyanogenMod Project
* Portions copyright (C) 2014, T-Mobile USA, Inc.
*
* 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
+ * 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,
@@ -17,12 +17,13 @@
package android.content.res;
import android.content.ContentResolver;
-import android.content.res.ThemeChangeRequest.RequestType;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.UserHandle;
import android.provider.Settings;
import android.text.TextUtils;
+import android.util.ArrayMap;
+import android.util.ArraySet;
import android.util.JsonReader;
import android.util.JsonToken;
import android.util.JsonWriter;
@@ -34,8 +35,6 @@ import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
import java.util.Map;
/**
@@ -61,9 +60,7 @@ public class ThemeConfig implements Cloneable, Parcelable, Comparable<ThemeConfi
private static final SystemAppTheme mSystemAppTheme = new SystemAppTheme();
// Maps pkgname to theme (ex com.angry.birds -> red theme)
- protected final Map<String, AppTheme> mThemes = new HashMap<String, AppTheme>();
-
- private RequestType mLastThemeChangeRequestType = RequestType.USER_REQUEST;
+ protected final Map<String, AppTheme> mThemes = new ArrayMap<>();
public ThemeConfig(Map<String, AppTheme> appThemes) {
mThemes.putAll(appThemes);
@@ -111,10 +108,6 @@ public class ThemeConfig implements Cloneable, Parcelable, Comparable<ThemeConfi
return Collections.unmodifiableMap(mThemes);
}
- public RequestType getLastThemeChangeRequestType() {
- return mLastThemeChangeRequestType;
- }
-
private AppTheme getThemeFor(String pkgName) {
AppTheme theme = mThemes.get(pkgName);
if (theme == null) theme = getDefaultTheme();
@@ -136,12 +129,11 @@ public class ThemeConfig implements Cloneable, Parcelable, Comparable<ThemeConfi
ThemeConfig o = (ThemeConfig) object;
Map<String, AppTheme> currThemes = (mThemes == null) ?
- new HashMap<String, AppTheme>() : mThemes;
+ new ArrayMap<String, AppTheme>() : mThemes;
Map<String, AppTheme> newThemes = (o.mThemes == null) ?
- new HashMap<String, AppTheme>() : o.mThemes;
+ new ArrayMap<String, AppTheme>() : o.mThemes;
- return (currThemes.equals(newThemes) &&
- mLastThemeChangeRequestType == o.mLastThemeChangeRequestType);
+ return currThemes.equals(newThemes);
}
return false;
}
@@ -160,8 +152,6 @@ public class ThemeConfig implements Cloneable, Parcelable, Comparable<ThemeConfi
public int hashCode() {
int hash = 17;
hash = 31 * hash + mThemes.hashCode();
- hash = 31 * hash + (mLastThemeChangeRequestType == null ? 0 :
- mLastThemeChangeRequestType.ordinal());
return hash;
}
@@ -227,7 +217,6 @@ public class ThemeConfig implements Cloneable, Parcelable, Comparable<ThemeConfi
public void writeToParcel(Parcel dest, int flags) {
String json = JsonSerializer.toJson(this);
dest.writeString(json);
- dest.writeInt(mLastThemeChangeRequestType.ordinal());
}
public static final Parcelable.Creator<ThemeConfig> CREATOR =
@@ -235,7 +224,6 @@ public class ThemeConfig implements Cloneable, Parcelable, Comparable<ThemeConfi
public ThemeConfig createFromParcel(Parcel source) {
String json = source.readString();
ThemeConfig themeConfig = JsonSerializer.fromJson(json);
- themeConfig.mLastThemeChangeRequestType = RequestType.values()[source.readInt()];
return themeConfig;
}
@@ -351,10 +339,9 @@ public class ThemeConfig implements Cloneable, Parcelable, Comparable<ThemeConfi
public static class Builder {
- private HashMap<String, String> mOverlays = new HashMap<String, String>();
- private HashMap<String, String> mIcons = new HashMap<String, String>();
- private HashMap<String, String> mFonts = new HashMap<String, String>();
- private RequestType mLastThemeChangeRequestType = RequestType.USER_REQUEST;
+ private Map<String, String> mOverlays = new ArrayMap<>();
+ private Map<String, String> mIcons = new ArrayMap<>();
+ private Map<String, String> mFonts = new ArrayMap<>();
public Builder() {}
@@ -366,7 +353,6 @@ public class ThemeConfig implements Cloneable, Parcelable, Comparable<ThemeConfi
mIcons.put(key, appTheme.getIconPackPkgName());
mOverlays.put(key, appTheme.getOverlayPkgName());
}
- mLastThemeChangeRequestType = theme.mLastThemeChangeRequestType;
}
/**
@@ -427,18 +413,13 @@ public class ThemeConfig implements Cloneable, Parcelable, Comparable<ThemeConfi
return this;
}
- public Builder setLastThemeChangeRequestType(RequestType requestType) {
- mLastThemeChangeRequestType = requestType;
- return this;
- }
-
public ThemeConfig build() {
- HashSet<String> appPkgSet = new HashSet<String>();
+ ArraySet<String> appPkgSet = new ArraySet<>();
appPkgSet.addAll(mOverlays.keySet());
appPkgSet.addAll(mIcons.keySet());
appPkgSet.addAll(mFonts.keySet());
- HashMap<String, AppTheme> appThemes = new HashMap<String, AppTheme>();
+ Map<String, AppTheme> appThemes = new ArrayMap<>();
for(String appPkgName : appPkgSet) {
String icon = mIcons.get(appPkgName);
String overlay = mOverlays.get(appPkgName);
@@ -455,7 +436,6 @@ public class ThemeConfig implements Cloneable, Parcelable, Comparable<ThemeConfi
}
}
ThemeConfig themeConfig = new ThemeConfig(appThemes);
- themeConfig.mLastThemeChangeRequestType = mLastThemeChangeRequestType;
return themeConfig;
}
}
@@ -506,7 +486,7 @@ public class ThemeConfig implements Cloneable, Parcelable, Comparable<ThemeConfi
public static ThemeConfig fromJson(String json) {
if (json == null) return null;
- HashMap<String, AppTheme> map = new HashMap<String, AppTheme>();
+ Map<String, AppTheme> map = new ArrayMap<>();
StringReader reader = null;
JsonReader jsonReader = null;
try {
@@ -582,7 +562,7 @@ public class ThemeConfig implements Cloneable, Parcelable, Comparable<ThemeConfi
public static class SystemConfig extends ThemeConfig {
public SystemConfig() {
- super(new HashMap<String, AppTheme>());
+ super(new ArrayMap<String, AppTheme>());
}
}
@@ -593,7 +573,7 @@ public class ThemeConfig implements Cloneable, Parcelable, Comparable<ThemeConfi
@Override
public String toString() {
- return "No Theme Applied (Holo)";
+ return "No Theme Applied (System)";
}
}
}
diff --git a/core/java/android/content/res/ThemeManager.java b/core/java/android/content/res/ThemeManager.java
deleted file mode 100644
index fd05f1e..0000000
--- a/core/java/android/content/res/ThemeManager.java
+++ /dev/null
@@ -1,316 +0,0 @@
-/*
- * Copyright (C) 2014 The CyanogenMod Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.content.res;
-
-import android.content.Context;
-import android.content.pm.ThemeUtils;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * {@hide}
- */
-public class ThemeManager {
- private static final String TAG = ThemeManager.class.getName();
- private Context mContext;
- private IThemeService mService;
- private Handler mHandler;
-
- private Set<ThemeChangeListener> mChangeListeners =
- new HashSet<ThemeChangeListener>();
-
- private Set<ThemeProcessingListener> mProcessingListeners =
- new HashSet<ThemeProcessingListener>();
-
- public ThemeManager(Context context, IThemeService service) {
- mContext = context;
- mService = service;
- mHandler = new Handler(Looper.getMainLooper());
- }
-
- private final IThemeChangeListener mThemeChangeListener = new IThemeChangeListener.Stub() {
- @Override
- public void onProgress(final int progress) throws RemoteException {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- synchronized (mChangeListeners) {
- List<ThemeChangeListener> listenersToRemove = new ArrayList
- <ThemeChangeListener>();
- for (ThemeChangeListener listener : mChangeListeners) {
- try {
- listener.onProgress(progress);
- } catch (Throwable e) {
- Log.w(TAG, "Unable to update theme change progress", e);
- listenersToRemove.add(listener);
- }
- }
- if (listenersToRemove.size() > 0) {
- for (ThemeChangeListener listener : listenersToRemove) {
- mChangeListeners.remove(listener);
- }
- }
- }
- }
- });
- }
-
- @Override
- public void onFinish(final boolean isSuccess) throws RemoteException {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- synchronized (mChangeListeners) {
- List<ThemeChangeListener> listenersToRemove = new ArrayList
- <ThemeChangeListener>();
- for (ThemeChangeListener listener : mChangeListeners) {
- try {
- listener.onFinish(isSuccess);
- } catch (Throwable e) {
- Log.w(TAG, "Unable to update theme change listener", e);
- listenersToRemove.add(listener);
- }
- }
- if (listenersToRemove.size() > 0) {
- for (ThemeChangeListener listener : listenersToRemove) {
- mChangeListeners.remove(listener);
- }
- }
- }
- }
- });
- }
- };
-
- private final IThemeProcessingListener mThemeProcessingListener =
- new IThemeProcessingListener.Stub() {
- @Override
- public void onFinishedProcessing(final String pkgName) throws RemoteException {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- synchronized (mProcessingListeners) {
- List<ThemeProcessingListener> listenersToRemove = new ArrayList
- <ThemeProcessingListener>();
- for (ThemeProcessingListener listener : mProcessingListeners) {
- try {
- listener.onFinishedProcessing(pkgName);
- } catch (Throwable e) {
- Log.w(TAG, "Unable to update theme change progress", e);
- listenersToRemove.add(listener);
- }
- }
- if (listenersToRemove.size() > 0) {
- for (ThemeProcessingListener listener : listenersToRemove) {
- mProcessingListeners.remove(listener);
- }
- }
- }
- }
- });
- }
- };
-
-
- public void addClient(ThemeChangeListener listener) {
- synchronized (mChangeListeners) {
- if (mChangeListeners.contains(listener)) {
- throw new IllegalArgumentException("Client was already added ");
- }
- if (mChangeListeners.size() == 0) {
- try {
- mService.requestThemeChangeUpdates(mThemeChangeListener);
- } catch (RemoteException e) {
- Log.w(TAG, "Unable to register listener", e);
- }
- }
- mChangeListeners.add(listener);
- }
- }
-
- public void removeClient(ThemeChangeListener listener) {
- synchronized (mChangeListeners) {
- mChangeListeners.remove(listener);
- if (mChangeListeners.size() == 0) {
- try {
- mService.removeUpdates(mThemeChangeListener);
- } catch (RemoteException e) {
- Log.w(TAG, "Unable to remove listener", e);
- }
- }
- }
- }
-
- public void onClientPaused(ThemeChangeListener listener) {
- removeClient(listener);
- }
-
- public void onClientResumed(ThemeChangeListener listener) {
- addClient(listener);
- }
-
- public void onClientDestroyed(ThemeChangeListener listener) {
- removeClient(listener);
- }
-
- /**
- * Register a ThemeProcessingListener to be notified when a theme is done being processed.
- * @param listener ThemeChangeListener to register
- */
- public void registerProcessingListener(ThemeProcessingListener listener) {
- synchronized (mProcessingListeners) {
- if (mProcessingListeners.contains(listener)) {
- throw new IllegalArgumentException("Listener was already added ");
- }
- if (mProcessingListeners.size() == 0) {
- try {
- mService.registerThemeProcessingListener(mThemeProcessingListener);
- } catch (RemoteException e) {
- Log.w(TAG, "Unable to register listener", e);
- }
- }
- mProcessingListeners.add(listener);
- }
- }
-
- /**
- * Unregister a ThemeChangeListener.
- * @param listener ThemeChangeListener to unregister
- */
- public void unregisterProcessingListener(ThemeChangeListener listener) {
- synchronized (mProcessingListeners) {
- mProcessingListeners.remove(listener);
- if (mProcessingListeners.size() == 0) {
- try {
- mService.unregisterThemeProcessingListener(mThemeProcessingListener);
- } catch (RemoteException e) {
- Log.w(TAG, "Unable to remove listener", e);
- }
- }
- }
- }
-
- /**
- * Convenience method. Applies the entire theme.
- */
- public void requestThemeChange(String pkgName) {
- //List<String> components = ThemeUtils.getSupportedComponents(mContext, pkgName);
- //requestThemeChange(pkgName, components);
- }
-
- public void requestThemeChange(String pkgName, List<String> components) {
- requestThemeChange(pkgName, components, true);
- }
-
- public void requestThemeChange(String pkgName, List<String> components,
- boolean removePerAppThemes) {
- Map<String, String> componentMap = new HashMap<String, String>(components.size());
- for (String component : components) {
- componentMap.put(component, pkgName);
- }
- requestThemeChange(componentMap, removePerAppThemes);
- }
-
- public void requestThemeChange(Map<String, String> componentMap) {
- requestThemeChange(componentMap, true);
- }
-
- public void requestThemeChange(Map<String, String> componentMap, boolean removePerAppThemes) {
- ThemeChangeRequest.Builder builder = new ThemeChangeRequest.Builder();
- for (String component : componentMap.keySet()) {
- builder.setComponent(component, componentMap.get(component));
- }
-
- requestThemeChange(builder.build(), removePerAppThemes);
- }
-
- public void requestThemeChange(ThemeChangeRequest request, boolean removePerAppThemes) {
- try {
- mService.requestThemeChange(request, removePerAppThemes);
- } catch (RemoteException e) {
- logThemeServiceException(e);
- }
- }
-
- public void applyDefaultTheme() {
- try {
- mService.applyDefaultTheme();
- } catch (RemoteException e) {
- logThemeServiceException(e);
- }
- }
-
- public boolean isThemeApplying() {
- try {
- return mService.isThemeApplying();
- } catch (RemoteException e) {
- logThemeServiceException(e);
- }
-
- return false;
- }
-
- public boolean isThemeBeingProcessed(String themePkgName) {
- try {
- return mService.isThemeBeingProcessed(themePkgName);
- } catch (RemoteException e) {
- logThemeServiceException(e);
- }
- return false;
- }
-
- public int getProgress() {
- try {
- return mService.getProgress();
- } catch (RemoteException e) {
- logThemeServiceException(e);
- }
- return -1;
- }
-
- public boolean processThemeResources(String themePkgName) {
- try {
- return mService.processThemeResources(themePkgName);
- } catch (RemoteException e) {
- logThemeServiceException(e);
- }
- return false;
- }
-
- private void logThemeServiceException(Exception e) {
- Log.w(TAG, "Unable to access ThemeService", e);
- }
-
- public interface ThemeChangeListener {
- void onProgress(int progress);
- void onFinish(boolean isSuccess);
- }
-
- public interface ThemeProcessingListener {
- void onFinishedProcessing(String pkgName);
- }
-}
-
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index dc576a5..dd15d38 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -40,6 +40,7 @@ import android.util.Log;
import android.text.TextUtils;
import android.view.Surface;
import android.view.SurfaceHolder;
+import android.os.SystemProperties;
import java.io.IOException;
import java.lang.ref.WeakReference;
@@ -483,8 +484,21 @@ public class Camera {
mEventHandler = null;
}
- return native_setup(new WeakReference<Camera>(this), cameraId, halVersion,
- ActivityThread.currentOpPackageName());
+ String packageName = ActivityThread.currentOpPackageName();
+
+ //Force HAL1 if the package name falls in this bucket
+ String packageList = SystemProperties.get("camera.hal1.packagelist", "");
+ if (packageList.length() > 0) {
+ TextUtils.StringSplitter splitter = new TextUtils.SimpleStringSplitter(',');
+ splitter.setString(packageList);
+ for (String str : splitter) {
+ if (packageName.equals(str)) {
+ halVersion = CAMERA_HAL_API_VERSION_1_0;
+ break;
+ }
+ }
+ }
+ return native_setup(new WeakReference<Camera>(this), cameraId, halVersion, packageName);
}
private int cameraInitNormal(int cameraId) {
@@ -3471,8 +3485,8 @@ public class Camera {
}
/**
- * Sets GPS processing method. It will store up to 32 characters
- * in JPEG EXIF header.
+ * Sets GPS processing method. The method will be stored in a UTF-8 string up to 31 bytes
+ * long, in the JPEG EXIF header.
*
* @param processing_method The processing method to get this location.
*/
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index a2ef078..7464211 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -398,17 +398,24 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
* this camera device.</p>
* <p>For devices at the LEGACY level or above:</p>
* <ul>
- * <li>This list will always include (30, 30).</li>
- * <li>Also, for constant-framerate recording, for each normal
+ * <li>
+ * <p>For constant-framerate recording, for each normal
+ * {@link android.media.CamcorderProfile CamcorderProfile}, that is, a
* {@link android.media.CamcorderProfile CamcorderProfile} that has
* {@link android.media.CamcorderProfile#quality quality} in
* the range [{@link android.media.CamcorderProfile#QUALITY_LOW QUALITY_LOW},
* {@link android.media.CamcorderProfile#QUALITY_2160P QUALITY_2160P}], if the profile is
* supported by the device and has
* {@link android.media.CamcorderProfile#videoFrameRate videoFrameRate} <code>x</code>, this list will
- * always include (<code>x</code>,<code>x</code>).</li>
- * <li>For preview streaming use case, this list will always include (<code>min</code>, <code>max</code>) where
- * <code>min</code> &lt;= 15 and <code>max</code> &gt;= 30.</li>
+ * always include (<code>x</code>,<code>x</code>).</p>
+ * </li>
+ * <li>
+ * <p>Also, a camera device must either not support any
+ * {@link android.media.CamcorderProfile CamcorderProfile},
+ * or support at least one
+ * normal {@link android.media.CamcorderProfile CamcorderProfile} that has
+ * {@link android.media.CamcorderProfile#videoFrameRate videoFrameRate} <code>x</code> &gt;= 24.</p>
+ * </li>
* </ul>
* <p>For devices at the LIMITED level or above:</p>
* <ul>
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index 35a1d96..f61892e 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -472,13 +472,13 @@ public abstract class CameraMetadata<TKey> {
* <li>The maximum available resolution for RAW_SENSOR streams
* will match either the value in
* {@link CameraCharacteristics#SENSOR_INFO_PIXEL_ARRAY_SIZE android.sensor.info.pixelArraySize} or
- * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.</li>
+ * {@link CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE android.sensor.info.preCorrectionActiveArraySize}.</li>
* <li>All DNG-related optional metadata entries are provided
* by the camera device.</li>
* </ul>
*
- * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
* @see CameraCharacteristics#SENSOR_INFO_PIXEL_ARRAY_SIZE
+ * @see CameraCharacteristics#SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE
* @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
*/
public static final int REQUEST_AVAILABLE_CAPABILITIES_RAW = 3;
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index 3f566eb..67835a0 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -556,6 +556,10 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>>
* Set a capture request field to a value. The field definitions can be
* found in {@link CaptureRequest}.
*
+ * <p>Setting a field to {@code null} will remove that field from the capture request.
+ * Unless the field is optional, removing it will likely produce an error from the camera
+ * device when the request is submitted.</p>
+ *
* @param key The metadata field to write.
* @param value The value to set the field to, which must be of a matching
* type to the key.
diff --git a/core/java/android/net/INetworkPolicyManager.aidl b/core/java/android/net/INetworkPolicyManager.aidl
index 7f5f377..9e639e8 100644
--- a/core/java/android/net/INetworkPolicyManager.aidl
+++ b/core/java/android/net/INetworkPolicyManager.aidl
@@ -48,6 +48,9 @@ interface INetworkPolicyManager {
/** Snooze limit on policy matching given template. */
void snoozeLimit(in NetworkTemplate template);
+ /** Snooze warning on policy matching given template. */
+ void snoozeWarning(in NetworkTemplate template);
+
/** Control if background data is restricted system-wide. */
void setRestrictBackground(boolean restrictBackground);
boolean getRestrictBackground();
diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java
index a83e722..eab22b8 100644
--- a/core/java/android/net/NetworkPolicyManager.java
+++ b/core/java/android/net/NetworkPolicyManager.java
@@ -20,6 +20,7 @@ import static android.content.pm.PackageManager.GET_SIGNATURES;
import static android.net.NetworkPolicy.CYCLE_NONE;
import static android.text.format.Time.MONTH_DAY;
+import android.annotation.SystemApi;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
@@ -81,6 +82,54 @@ public class NetworkPolicyManager {
*/
public static final String EXTRA_NETWORK_TEMPLATE = "android.net.NETWORK_TEMPLATE";
+ /**
+ * Broadcast intent action for informing a custom component about a network policy
+ * notification.
+ * @hide
+ */
+ @SystemApi
+ public static final String ACTION_SHOW_NETWORK_POLICY_NOTIFICATION =
+ "android.net.action.SHOW_NETWORK_POLICY_NOTIFICATION";
+
+ /**
+ * The sequence number associated with the notification - a higher number
+ * indicates previous notifications may be disregarded.
+ * @hide
+ */
+ @SystemApi
+ public static final String EXTRA_NOTIFICATION_SEQUENCE_NUMBER =
+ "android.net.extra.NOTIFICATION_SEQUENCE_NUMBER";
+
+ /**
+ * The type of notification that should be presented to the user.
+ * @hide
+ */
+ @SystemApi
+ public static final String EXTRA_NOTIFICATION_TYPE = "android.net.extra.NOTIFICATION_TYPE";
+
+ @SystemApi
+ public static final int NOTIFICATION_TYPE_NONE = 0;
+ @SystemApi
+ public static final int NOTIFICATION_TYPE_USAGE_WARNING = 1;
+ @SystemApi
+ public static final int NOTIFICATION_TYPE_USAGE_REACHED_LIMIT = 2;
+ @SystemApi
+ public static final int NOTIFICATION_TYPE_USAGE_EXCEEDED_LIMIT = 3;
+
+ /**
+ * The number of bytes used on the network in the notification.
+ * @hide
+ */
+ @SystemApi
+ public static final String EXTRA_BYTES_USED = "android.net.extra.BYTES_USED";
+
+ /**
+ * The network policy for the network in the notification.
+ * @hide
+ */
+ @SystemApi
+ public static final String EXTRA_NETWORK_POLICY = "android.net.extra.NETWORK_POLICY";
+
private final Context mContext;
private INetworkPolicyManager mService;
diff --git a/core/java/android/net/NetworkScorerAppManager.java b/core/java/android/net/NetworkScorerAppManager.java
index 29daf35..5880e5d 100644
--- a/core/java/android/net/NetworkScorerAppManager.java
+++ b/core/java/android/net/NetworkScorerAppManager.java
@@ -33,6 +33,7 @@ import android.util.Log;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.List;
/**
@@ -90,8 +91,13 @@ public final class NetworkScorerAppManager {
* @return the list of scorers, or the empty list if there are no valid scorers.
*/
public static Collection<NetworkScorerAppData> getAllValidScorers(Context context) {
- List<NetworkScorerAppData> scorers = new ArrayList<>();
+ // Network scorer apps can only run as the primary user so exit early if we're not the
+ // primary user.
+ if (UserHandle.getCallingUserId() != 0 /*USER_SYSTEM*/) {
+ return Collections.emptyList();
+ }
+ List<NetworkScorerAppData> scorers = new ArrayList<>();
PackageManager pm = context.getPackageManager();
// Only apps installed under the primary user of the device can be scorers.
List<ResolveInfo> receivers =
@@ -104,8 +110,9 @@ public final class NetworkScorerAppManager {
continue;
}
if (!permission.BROADCAST_NETWORK_PRIVILEGED.equals(receiverInfo.permission)) {
- // Receiver doesn't require the BROADCAST_NETWORK_PRIVILEGED permission, which means
- // anyone could trigger network scoring and flood the framework with score requests.
+ // Receiver doesn't require the BROADCAST_NETWORK_PRIVILEGED permission, which
+ // means anyone could trigger network scoring and flood the framework with score
+ // requests.
continue;
}
if (pm.checkPermission(permission.SCORE_NETWORKS, receiverInfo.packageName) !=
@@ -127,8 +134,8 @@ public final class NetworkScorerAppManager {
}
}
- // NOTE: loadLabel will attempt to load the receiver's label and fall back to the app
- // label if none is present.
+ // NOTE: loadLabel will attempt to load the receiver's label and fall back to the
+ // app label if none is present.
scorers.add(new NetworkScorerAppData(receiverInfo.packageName,
receiverInfo.applicationInfo.uid, receiverInfo.loadLabel(pm),
configurationActivityClassName));
diff --git a/core/java/android/nfc/NfcActivityManager.java b/core/java/android/nfc/NfcActivityManager.java
index d619c0a..c7d4c65 100644
--- a/core/java/android/nfc/NfcActivityManager.java
+++ b/core/java/android/nfc/NfcActivityManager.java
@@ -371,40 +371,44 @@ public final class NfcActivityManager extends IAppCallback.Stub
flags = state.flags;
activity = state.activity;
}
-
- // Make callbacks without lock
- if (ndefCallback != null) {
- message = ndefCallback.createNdefMessage(event);
- }
- if (urisCallback != null) {
- uris = urisCallback.createBeamUris(event);
- if (uris != null) {
- ArrayList<Uri> validUris = new ArrayList<Uri>();
- for (Uri uri : uris) {
- if (uri == null) {
- Log.e(TAG, "Uri not allowed to be null.");
- continue;
- }
- String scheme = uri.getScheme();
- if (scheme == null || (!scheme.equalsIgnoreCase("file") &&
- !scheme.equalsIgnoreCase("content"))) {
- Log.e(TAG, "Uri needs to have " +
- "either scheme file or scheme content");
- continue;
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ // Make callbacks without lock
+ if (ndefCallback != null) {
+ message = ndefCallback.createNdefMessage(event);
+ }
+ if (urisCallback != null) {
+ uris = urisCallback.createBeamUris(event);
+ if (uris != null) {
+ ArrayList<Uri> validUris = new ArrayList<Uri>();
+ for (Uri uri : uris) {
+ if (uri == null) {
+ Log.e(TAG, "Uri not allowed to be null.");
+ continue;
+ }
+ String scheme = uri.getScheme();
+ if (scheme == null || (!scheme.equalsIgnoreCase("file") &&
+ !scheme.equalsIgnoreCase("content"))) {
+ Log.e(TAG, "Uri needs to have " +
+ "either scheme file or scheme content");
+ continue;
+ }
+ uri = ContentProvider.maybeAddUserId(uri, UserHandle.myUserId());
+ validUris.add(uri);
}
- uri = ContentProvider.maybeAddUserId(uri, UserHandle.myUserId());
- validUris.add(uri);
- }
- uris = validUris.toArray(new Uri[validUris.size()]);
+ uris = validUris.toArray(new Uri[validUris.size()]);
+ }
}
- }
- if (uris != null && uris.length > 0) {
- for (Uri uri : uris) {
- // Grant the NFC process permission to read these URIs
- activity.grantUriPermission("com.android.nfc", uri,
- Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ if (uris != null && uris.length > 0) {
+ for (Uri uri : uris) {
+ // Grant the NFC process permission to read these URIs
+ activity.grantUriPermission("com.android.nfc", uri,
+ Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ }
}
+ } finally {
+ Binder.restoreCallingIdentity(ident);
}
return new BeamShareData(message, uris, new UserHandle(UserHandle.myUserId()), flags);
}
diff --git a/core/java/android/os/BatteryManager.java b/core/java/android/os/BatteryManager.java
index 1f3e9a7..050820c 100644
--- a/core/java/android/os/BatteryManager.java
+++ b/core/java/android/os/BatteryManager.java
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 2016 The CyanogenMod Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,6 +17,7 @@
package android.os;
+import android.app.IBatteryService;
import android.content.Context;
import android.os.BatteryProperty;
import android.os.IBatteryPropertiesRegistrar;
@@ -95,6 +97,79 @@ public class BatteryManager {
/**
* Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
+ * integer containing the current dock status constant.
+ * @hide
+ */
+ public static final String EXTRA_DOCK_STATUS = "dock_status";
+
+ /**
+ * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
+ * integer containing the current dock health constant.
+ * @hide
+ */
+ public static final String EXTRA_DOCK_HEALTH = "dock_health";
+
+ /**
+ * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
+ * boolean indicating whether a dock battery is present.
+ * @hide
+ */
+ public static final String EXTRA_DOCK_PRESENT = "dock_present";
+
+ /**
+ * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
+ * integer field containing the current dock battery level, from 0 to
+ * {@link #EXTRA_SCALE}.
+ * @hide
+ */
+ public static final String EXTRA_DOCK_LEVEL = "dock_level";
+
+ /**
+ * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
+ * integer containing the maximum dock battery level.
+ * @hide
+ */
+ public static final String EXTRA_DOCK_SCALE = "dock_scale";
+
+ /**
+ * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
+ * integer containing the resource ID of a small status bar icon
+ * indicating the current dock battery state.
+ * @hide
+ */
+ public static final String EXTRA_DOCK_ICON_SMALL = "dock_icon-small";
+
+ /**
+ * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
+ * integer indicating whether the device is plugged in to a dock power
+ * source.
+ * @hide
+ */
+ public static final String EXTRA_DOCK_PLUGGED = "dock_plugged";
+
+ /**
+ * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
+ * integer containing the current dock battery voltage level.
+ * @hide
+ */
+ public static final String EXTRA_DOCK_VOLTAGE = "dock_voltage";
+
+ /**
+ * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
+ * integer containing the current dock battery temperature.
+ * @hide
+ */
+ public static final String EXTRA_DOCK_TEMPERATURE = "dock_temperature";
+
+ /**
+ * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
+ * String describing the technology of the current dock battery.
+ * @hide
+ */
+ public static final String EXTRA_DOCK_TECHNOLOGY = "dock_technology";
+
+ /**
+ * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
* Int value set to nonzero if an unsupported charger is attached
* to the device.
* {@hide}
@@ -133,10 +208,23 @@ public class BatteryManager {
/** Power source is wireless. */
public static final int BATTERY_PLUGGED_WIRELESS = 4;
+ // values of the "dock_plugged" field in the ACTION_BATTERY_CHANGED intent.
+ // These must be powers of 2.
+ /** Power source is an DockAC charger.
+ * @hide*/
+ public static final int BATTERY_DOCK_PLUGGED_AC = 1;
+ /** Power source is an DockUSB charger.
+ * @hide*/
+ public static final int BATTERY_DOCK_PLUGGED_USB = 2;
+
/** @hide */
public static final int BATTERY_PLUGGED_ANY =
BATTERY_PLUGGED_AC | BATTERY_PLUGGED_USB | BATTERY_PLUGGED_WIRELESS;
+ /** @hide */
+ public static final int BATTERY_DOCK_PLUGGED_ANY =
+ BATTERY_DOCK_PLUGGED_AC | BATTERY_DOCK_PLUGGED_USB;
+
/**
* Sent when the device's battery has started charging (or has reached full charge
* and the device is on power). This is a good time to do work that you would like to
@@ -191,6 +279,7 @@ public class BatteryManager {
*/
public static final int BATTERY_PROPERTY_ENERGY_COUNTER = 5;
+ private final IBatteryService mBatteryService;
private final IBatteryStats mBatteryStats;
private final IBatteryPropertiesRegistrar mBatteryPropertiesRegistrar;
@@ -202,6 +291,27 @@ public class BatteryManager {
ServiceManager.getService(BatteryStats.SERVICE_NAME));
mBatteryPropertiesRegistrar = IBatteryPropertiesRegistrar.Stub.asInterface(
ServiceManager.getService("batteryproperties"));
+ mBatteryService = null;
+ }
+
+ /** @hide */
+ public BatteryManager(IBatteryService service) {
+ super();
+ mBatteryStats = IBatteryStats.Stub.asInterface(
+ ServiceManager.getService(BatteryStats.SERVICE_NAME));
+ mBatteryPropertiesRegistrar = IBatteryPropertiesRegistrar.Stub.asInterface(
+ ServiceManager.getService("batteryproperties"));
+ mBatteryService = service;
+ }
+
+ /** @hide */
+ public boolean isDockBatterySupported() {
+ try {
+ return mBatteryService != null && mBatteryService.isDockBatterySupported();
+ } catch (RemoteException ex) {
+ // Ignore
+ }
+ return false;
}
/**
@@ -223,8 +333,10 @@ public class BatteryManager {
*
* Returns the requested value, or Long.MIN_VALUE if property not
* supported on this system or on other error.
+ * fromDock determines if the property is query from the normal battery
+ * or the dock battery.
*/
- private long queryProperty(int id) {
+ private long queryProperty(int id, boolean fromDock) {
long ret;
if (mBatteryPropertiesRegistrar == null) {
@@ -234,7 +346,13 @@ public class BatteryManager {
try {
BatteryProperty prop = new BatteryProperty();
- if (mBatteryPropertiesRegistrar.getProperty(id, prop) == 0)
+ final int callResult;
+ if (!fromDock) {
+ callResult = mBatteryPropertiesRegistrar.getProperty(id, prop);
+ } else {
+ callResult = mBatteryPropertiesRegistrar.getDockProperty(id, prop);
+ }
+ if (callResult == 0)
ret = prop.getLong();
else
ret = Long.MIN_VALUE;
@@ -255,7 +373,7 @@ public class BatteryManager {
* @return the property value, or Integer.MIN_VALUE if not supported.
*/
public int getIntProperty(int id) {
- return (int)queryProperty(id);
+ return (int)queryProperty(id, false);
}
/**
@@ -268,6 +386,40 @@ public class BatteryManager {
* @return the property value, or Long.MIN_VALUE if not supported.
*/
public long getLongProperty(int id) {
- return queryProperty(id);
+ return queryProperty(id, false);
+ }
+
+ /**
+ * Return the value of a dock battery property of integer type. If the
+ * platform does not provide the property queried, this value will
+ * be Integer.MIN_VALUE.
+ *
+ * @param id identifier of the requested property
+ *
+ * @return the property value, or Integer.MIN_VALUE if not supported.
+ * @hide
+ */
+ public int getIntDockProperty(int id) {
+ if (!isDockBatterySupported()) {
+ return Integer.MIN_VALUE;
+ }
+ return (int)queryProperty(id, true);
+ }
+
+ /**
+ * Return the value of a dock battery property of long type If the
+ * platform does not provide the property queried, this value will
+ * be Long.MIN_VALUE.
+ *
+ * @param id identifier of the requested property
+ *
+ * @return the property value, or Long.MIN_VALUE if not supported.
+ * @hide
+ */
+ public long getLongDockProperty(int id) {
+ if (!isDockBatterySupported()) {
+ return Long.MIN_VALUE;
+ }
+ return queryProperty(id, true);
}
}
diff --git a/core/java/android/os/BatteryManagerInternal.java b/core/java/android/os/BatteryManagerInternal.java
index f3a95b9..1abb3d5 100644
--- a/core/java/android/os/BatteryManagerInternal.java
+++ b/core/java/android/os/BatteryManagerInternal.java
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2016 The CyanogenMod Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -43,6 +44,26 @@ public abstract class BatteryManagerInternal {
public abstract boolean getBatteryLevelLow();
/**
+ * Returns whether dock batteries is supported
+ */
+ public abstract boolean isDockBatterySupported();
+
+ /**
+ * Returns the current dock plug type.
+ */
+ public abstract int getDockPlugType();
+
+ /**
+ * Returns dock battery level as a percentage.
+ */
+ public abstract int getDockBatteryLevel();
+
+ /**
+ * Returns whether we currently consider the dock battery level to be low.
+ */
+ public abstract boolean getDockBatteryLevelLow();
+
+ /**
* Returns a non-zero value if an unsupported charger is attached.
*/
public abstract int getInvalidCharger();
diff --git a/core/java/android/os/BatteryProperties.java b/core/java/android/os/BatteryProperties.java
index 29e868c..cad741a 100644
--- a/core/java/android/os/BatteryProperties.java
+++ b/core/java/android/os/BatteryProperties.java
@@ -1,4 +1,5 @@
/* Copyright 2013, The Android Open Source Project
+ * Copyright 2016, The CyanogenMod Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -31,6 +32,16 @@ public class BatteryProperties implements Parcelable {
public int batteryTemperature;
public String batteryTechnology;
+ public boolean dockBatterySupported;
+ public boolean chargerDockAcOnline;
+ public int dockBatteryStatus;
+ public int dockBatteryHealth;
+ public boolean dockBatteryPresent;
+ public int dockBatteryLevel;
+ public int dockBatteryVoltage;
+ public int dockBatteryTemperature;
+ public String dockBatteryTechnology;
+
public BatteryProperties() {
}
@@ -46,6 +57,16 @@ public class BatteryProperties implements Parcelable {
batteryVoltage = other.batteryVoltage;
batteryTemperature = other.batteryTemperature;
batteryTechnology = other.batteryTechnology;
+
+ dockBatterySupported = other.dockBatterySupported;
+ chargerDockAcOnline = other.chargerDockAcOnline;
+ dockBatteryStatus = other.dockBatteryStatus;
+ dockBatteryHealth = other.dockBatteryHealth;
+ dockBatteryPresent = other.dockBatteryPresent;
+ dockBatteryLevel = other.dockBatteryLevel;
+ dockBatteryVoltage = other.dockBatteryVoltage;
+ dockBatteryTemperature = other.dockBatteryTemperature;
+ dockBatteryTechnology = other.dockBatteryTechnology;
}
/*
@@ -65,6 +86,27 @@ public class BatteryProperties implements Parcelable {
batteryVoltage = p.readInt();
batteryTemperature = p.readInt();
batteryTechnology = p.readString();
+
+ dockBatterySupported = p.readInt() == 1 ? true : false;
+ if (dockBatterySupported) {
+ chargerDockAcOnline = p.readInt() == 1 ? true : false;
+ dockBatteryStatus = p.readInt();
+ dockBatteryHealth = p.readInt();
+ dockBatteryPresent = p.readInt() == 1 ? true : false;
+ dockBatteryLevel = p.readInt();
+ dockBatteryVoltage = p.readInt();
+ dockBatteryTemperature = p.readInt();
+ dockBatteryTechnology = p.readString();
+ } else {
+ chargerDockAcOnline = false;
+ dockBatteryStatus = BatteryManager.BATTERY_STATUS_UNKNOWN;
+ dockBatteryHealth = BatteryManager.BATTERY_HEALTH_UNKNOWN;
+ dockBatteryPresent = false;
+ dockBatteryLevel = 0;
+ dockBatteryVoltage = 0;
+ dockBatteryTemperature = 0;
+ dockBatteryTechnology = "";
+ }
}
public void writeToParcel(Parcel p, int flags) {
@@ -79,6 +121,18 @@ public class BatteryProperties implements Parcelable {
p.writeInt(batteryVoltage);
p.writeInt(batteryTemperature);
p.writeString(batteryTechnology);
+
+ p.writeInt(dockBatterySupported ? 1 : 0);
+ if (dockBatterySupported) {
+ p.writeInt(chargerDockAcOnline ? 1 : 0);
+ p.writeInt(dockBatteryStatus);
+ p.writeInt(dockBatteryHealth);
+ p.writeInt(dockBatteryPresent ? 1 : 0);
+ p.writeInt(dockBatteryLevel);
+ p.writeInt(dockBatteryVoltage);
+ p.writeInt(dockBatteryTemperature);
+ p.writeString(dockBatteryTechnology);
+ }
}
public static final Parcelable.Creator<BatteryProperties> CREATOR
diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java
index 2567a41..a800ed6 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -56,7 +56,7 @@ public class Environment {
private static final File DIR_ANDROID_STORAGE = getDirectory(ENV_ANDROID_STORAGE, "/storage");
private static final File DIR_OEM_ROOT = getDirectory(ENV_OEM_ROOT, "/oem");
private static final File DIR_VENDOR_ROOT = getDirectory(ENV_VENDOR_ROOT, "/vendor");
- private static final File DIR_PREBUNDLED_ROOT = getDirectory(ENV_PREBUNDLED_ROOT, "/vendor/bundled-app");
+ private static final File DIR_PREBUNDLED_ROOT = getDirectory(ENV_PREBUNDLED_ROOT, "/bundled-app");
private static final String SYSTEM_PROPERTY_EFS_ENABLED = "persist.security.efs.enabled";
diff --git a/core/java/android/os/IBatteryPropertiesRegistrar.aidl b/core/java/android/os/IBatteryPropertiesRegistrar.aidl
index fd01802..43b9650 100644
--- a/core/java/android/os/IBatteryPropertiesRegistrar.aidl
+++ b/core/java/android/os/IBatteryPropertiesRegistrar.aidl
@@ -1,5 +1,6 @@
/*
** Copyright 2013, The Android Open Source Project
+** Copyright 2016, The CyanogenMod Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
@@ -27,4 +28,5 @@ interface IBatteryPropertiesRegistrar {
void registerListener(IBatteryPropertiesListener listener);
void unregisterListener(IBatteryPropertiesListener listener);
int getProperty(in int id, out BatteryProperty prop);
+ int getDockProperty(in int id, out BatteryProperty prop);
}
diff --git a/core/java/android/os/PowerManagerInternal.java b/core/java/android/os/PowerManagerInternal.java
index 38037a6..39c12f0 100644
--- a/core/java/android/os/PowerManagerInternal.java
+++ b/core/java/android/os/PowerManagerInternal.java
@@ -117,6 +117,12 @@ public abstract class PowerManagerInternal {
public abstract void setUserActivityTimeoutOverrideFromWindowManager(long timeoutMillis);
/**
+ * Used by the window manager to tell the power manager that the user is no longer actively
+ * using the device.
+ */
+ public abstract void setUserInactiveOverrideFromWindowManager();
+
+ /**
* Used by device administration to set the maximum screen off timeout.
*
* This method must only be called by the device administration policy manager.
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index a738b83..f6642d8 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -6438,6 +6438,13 @@ public final class Settings {
public static final String AIRPLANE_MODE_TOGGLEABLE_RADIOS = "airplane_mode_toggleable_radios";
/**
+ * A Long representing a bitmap of profiles that should be disabled when bluetooth starts.
+ * See {@link android.bluetooth.BluetoothProfile}.
+ * {@hide}
+ */
+ public static final String BLUETOOTH_DISABLED_PROFILES = "bluetooth_disabled_profiles";
+
+ /**
* The policy for deciding when Wi-Fi should go to sleep (which will in
* turn switch to using the mobile data as an Internet connection).
* <p>
@@ -7693,10 +7700,12 @@ public final class Settings {
* The following keys are supported:
*
* <pre>
- * idle_duration (long)
+ * idle_duration2 (long)
* wallclock_threshold (long)
* parole_interval (long)
* parole_duration (long)
+ *
+ * idle_duration (long) // This is deprecated and used to circumvent b/26355386.
* </pre>
*
* <p>
@@ -8142,6 +8151,13 @@ public final class Settings {
public static final String LTE_SERVICE_FORCED = "lte_service_forced";
/**
+ * Whether to ignore the representation of outgoing calls set by the network.
+ *
+ * @hide
+ */
+ public static final String CONNECTED_LINE_IDENTIFICATION = "connected_line_identification";
+
+ /**
* Settings to backup. This is here so that it's in the same place as the settings
* keys and easy to update.
*
@@ -8567,6 +8583,13 @@ public final class Settings {
* @hide
*/
public static final String CONTACT_METADATA_SYNC = "contact_metadata_sync";
+
+ /**
+ * Whether to enable cellular on boot.
+ * The value 1 - enable, 0 - disable
+ * @hide
+ */
+ public static final String ENABLE_CELLULAR_ON_BOOT = "enable_cellular_on_boot";
}
/**
diff --git a/core/java/android/provider/ThemesContract.java b/core/java/android/provider/ThemesContract.java
deleted file mode 100644
index af7ab26..0000000
--- a/core/java/android/provider/ThemesContract.java
+++ /dev/null
@@ -1,731 +0,0 @@
-package android.provider;
-
-import android.net.Uri;
-
-/**
- * @hide
- */
-public class ThemesContract {
- public static final String AUTHORITY = "com.cyanogenmod.themes";
- public static final Uri AUTHORITY_URI = Uri.parse("content://" + AUTHORITY);
-
- public static class ThemesColumns {
- public static final Uri CONTENT_URI = Uri.withAppendedPath(AUTHORITY_URI, "themes");
-
- /**
- * The unique ID for a row.
- * <P>Type: INTEGER (long)</P>
- */
- public static final String _ID = "_id";
-
- /**
- * The user visible title.
- * <P>Type: TEXT</P>
- */
- public static final String TITLE = "title";
-
- /**
- * Unique text to identify the apk pkg. ie "com.foo.bar"
- * <P>Type: TEXT</P>
- */
- public static final String PKG_NAME = "pkg_name";
-
- /**
- * A 32 bit RRGGBB color representative of the themes color scheme
- * <P>Type: INTEGER</P>
- */
- public static final String PRIMARY_COLOR = "primary_color";
-
- /**
- * A 2nd 32 bit RRGGBB color representative of the themes color scheme
- * <P>Type: INTEGER</P>
- */
- public static final String SECONDARY_COLOR = "secondary_color";
-
- /**
- * Name of the author of the theme
- * <P>Type: TEXT</P>
- */
- public static final String AUTHOR = "author";
-
- /**
- * The time that this row was created on its originating client (msecs
- * since the epoch).
- * <P>Type: INTEGER</P>
- */
- public static final String DATE_CREATED = "created";
-
- /**
- * URI to an image that shows the homescreen with the theme applied
- * since the epoch).
- * <P>Type: TEXT</P>
- */
- public static final String HOMESCREEN_URI = "homescreen_uri";
-
- /**
- * URI to an image that shows the lockscreen with theme applied
- * <P>Type: TEXT</P>
- */
- public static final String LOCKSCREEN_URI = "lockscreen_uri";
-
- /**
- * URI to an image that shows the style (aka skin) with theme applied
- * <P>Type: TEXT</P>
- */
- public static final String STYLE_URI = "style_uri";
-
- /**
- * TODO: Figure structure for actual animation instead of static
- * URI to an image of the boot_anim.
- * <P>Type: TEXT</P>
- */
- public static final String BOOT_ANIM_URI = "bootanim_uri";
-
- /**
- * URI to an image of the status bar for this theme.
- * <P>Type: TEXT</P>
- */
- public static final String STATUSBAR_URI = "status_uri";
-
- /**
- * URI to an image of the fonts in this theme.
- * <P>Type: TEXT</P>
- */
- public static final String FONT_URI = "font_uri";
-
- /**
- * URI to an image of the fonts in this theme.
- * <P>Type: TEXT</P>
- */
- public static final String ICON_URI = "icon_uri";
-
- /**
- * URI to an image of the fonts in this theme.
- * <P>Type: TEXT</P>
- */
- public static final String OVERLAYS_URI = "overlays_uri";
-
- /**
- * 1 if theme modifies the launcher/homescreen else 0
- * <P>Type: INTEGER</P>
- * <P>Default: 0</P>
- */
- public static final String MODIFIES_LAUNCHER = "mods_homescreen";
-
- /**
- * 1 if theme modifies the lockscreen else 0
- * <P>Type: INTEGER</P>
- * <P>Default: 0</P>
- */
- public static final String MODIFIES_LOCKSCREEN = "mods_lockscreen";
-
- /**
- * 1 if theme modifies icons else 0
- * <P>Type: INTEGER</P>
- * <P>Default: 0</P>
- */
- public static final String MODIFIES_ICONS = "mods_icons";
-
- /**
- * 1 if theme modifies fonts
- * <P>Type: INTEGER</P>
- * <P>Default: 0</P>
- */
- public static final String MODIFIES_FONTS = "mods_fonts";
-
- /**
- * 1 if theme modifies boot animation
- * <P>Type: INTEGER</P>
- * <P>Default: 0</P>
- */
- public static final String MODIFIES_BOOT_ANIM = "mods_bootanim";
-
- /**
- * 1 if theme modifies notifications
- * <P>Type: INTEGER</P>
- * <P>Default: 0</P>
- */
- public static final String MODIFIES_NOTIFICATIONS = "mods_notifications";
-
- /**
- * 1 if theme modifies alarm sounds
- * <P>Type: INTEGER</P>
- * <P>Default: 0</P>
- */
- public static final String MODIFIES_ALARMS = "mods_alarms";
-
- /**
- * 1 if theme modifies ringtones
- * <P>Type: INTEGER</P>
- * <P>Default: 0</P>
- */
- public static final String MODIFIES_RINGTONES = "mods_ringtones";
-
- /**
- * 1 if theme has overlays
- * <P>Type: INTEGER</P>
- * <P>Default: 0</P>
- */
- public static final String MODIFIES_OVERLAYS = "mods_overlays";
-
- /**
- * 1 if theme has an overlay for SystemUI/StatusBar
- * <P>Type: INTEGER</P>
- * <P>Default: 0</P>
- */
- public static final String MODIFIES_STATUS_BAR = "mods_status_bar";
-
- /**
- * 1 if theme has an overlay for SystemUI/NavBar
- * <P>Type: INTEGER</P>
- * <P>Default: 0</P>
- */
- public static final String MODIFIES_NAVIGATION_BAR = "mods_navigation_bar";
-
- /**
- * 1 if theme has a live lock screen
- * <P>Type: INTEGER</P>
- * <P>Default: 0</P>
- */
- public static final String MODIFIES_LIVE_LOCK_SCREEN = "mods_live_lock_screen";
-
- /**
- * URI to the theme's wallpaper. We should support multiple wallpaper
- * but for now we will just have 1.
- * <P>Type: TEXT</P>
- */
- public static final String WALLPAPER_URI = "wallpaper_uri";
-
- /**
- * 1 if this row should actually be presented as a theme to the user.
- * For example if a "theme" only modifies one component (ex icons) then
- * we do not present it to the user under the themes table.
- * <P>Type: INTEGER</P>
- * <P>Default: 0</P>
- */
- public static final String PRESENT_AS_THEME = "present_as_theme";
-
- /**
- * 1 if this theme is a legacy theme.
- * <P>Type: INTEGER</P>
- * <P>Default: 0</P>
- */
- public static final String IS_LEGACY_THEME = "is_legacy_theme";
-
- /**
- * 1 if this theme is the system default theme.
- * <P>Type: INTEGER</P>
- * <P>Default: 0</P>
- */
- public static final String IS_DEFAULT_THEME = "is_default_theme";
-
- /**
- * 1 if this theme is a legacy iconpack. A legacy icon pack is an APK that was written
- * for Trebuchet or a 3rd party launcher.
- * <P>Type: INTEGER</P>
- * <P>Default: 0</P>
- */
- public static final String IS_LEGACY_ICONPACK = "is_legacy_iconpack";
-
- /**
- * install/update time in millisecs. When the row is inserted this column
- * is populated by the PackageInfo. It is used for syncing to PM
- * <P>Type: INTEGER</P>
- * <P>Default: 0</P>
- */
- public static final String LAST_UPDATE_TIME = "updateTime";
-
- /**
- * install time in millisecs. When the row is inserted this column
- * is populated by the PackageInfo.
- * <P>Type: INTEGER</P>
- * <P>Default: 0</P>
- */
- public static final String INSTALL_TIME = "install_time";
-
- /**
- * The target API this theme supports
- * is populated by the PackageInfo.
- * <P>Type: INTEGER</P>
- * <P>Default: 0</P>
- */
- public static final String TARGET_API = "target_api";
-
- /**
- * The install state of the theme.
- * Can be one of the following:
- * {@link InstallState#UNKNOWN}
- * {@link InstallState#INSTALLING}
- * {@link InstallState#UPDATING}
- * {@link InstallState#INSTALLED}
- * <P>Type: INTEGER</P>
- * <P>Default: 0</P>
- */
- public static final String INSTALL_STATE = "install_state";
-
- public static class InstallState {
- public static final int UNKNOWN = 0;
- public static final int INSTALLING = 1;
- public static final int UPDATING = 2;
- public static final int INSTALLED = 3;
- }
- }
-
- /**
- * Key-value table which assigns a component (ex wallpaper) to a theme's package
- */
- public static class MixnMatchColumns {
- public static final Uri CONTENT_URI = Uri.withAppendedPath(AUTHORITY_URI, "mixnmatch");
-
- /**
- * The unique key for a row. See the KEY_* constants
- * for valid examples
- * <P>Type: TEXT</P>
- */
- public static final String COL_KEY = "key";
-
- /**
- * The package name that corresponds to a given component.
- * <P>Type: String</P>
- */
- public static final String COL_VALUE = "value";
-
- /**
- * The package name that corresponds to where this component was applied from previously
- * <P>Type: String</P>
- */
- public static final String COL_PREV_VALUE = "previous_value";
-
- /**
- * Time when this entry was last updated
- * <P>Type: INTEGER</P>
- */
- public static final String COL_UPDATE_TIME = "update_time";
-
- /*
- * The unique ID for the component within a theme.
- * Always 0 unless multiples of a component exist.
- * <P>Type: INTEGER (long)</P>
- */
- public static final String COL_COMPONENT_ID = "component_id";
-
- /**
- * Valid keys
- */
- public static final String KEY_HOMESCREEN = "mixnmatch_homescreen";
- public static final String KEY_LOCKSCREEN = "mixnmatch_lockscreen";
- public static final String KEY_ICONS = "mixnmatch_icons";
- public static final String KEY_STATUS_BAR = "mixnmatch_status_bar";
- public static final String KEY_BOOT_ANIM = "mixnmatch_boot_anim";
- public static final String KEY_FONT = "mixnmatch_font";
- public static final String KEY_ALARM = "mixnmatch_alarm";
- public static final String KEY_NOTIFICATIONS = "mixnmatch_notifications";
- public static final String KEY_RINGTONE = "mixnmatch_ringtone";
- public static final String KEY_OVERLAYS = "mixnmatch_overlays";
- public static final String KEY_NAVIGATION_BAR = "mixnmatch_navigation_bar";
- public static final String KEY_LIVE_LOCK_SCREEN = "mixnmatch_live_lock_screen";
-
- public static final String[] ROWS = { KEY_HOMESCREEN,
- KEY_LOCKSCREEN,
- KEY_ICONS,
- KEY_STATUS_BAR,
- KEY_BOOT_ANIM,
- KEY_FONT,
- KEY_NOTIFICATIONS,
- KEY_RINGTONE,
- KEY_ALARM,
- KEY_OVERLAYS,
- KEY_NAVIGATION_BAR,
- KEY_LIVE_LOCK_SCREEN
- };
-
- /**
- * For a given key value in the MixNMatch table, return the column
- * associated with it in the Themes Table. This is useful for URI based
- * elements like wallpaper where the caller wishes to determine the
- * wallpaper URI.
- */
- public static String componentToImageColName(String component) {
- if (component.equals(MixnMatchColumns.KEY_HOMESCREEN)) {
- return ThemesColumns.HOMESCREEN_URI;
- } else if (component.equals(MixnMatchColumns.KEY_LOCKSCREEN)) {
- return ThemesColumns.LOCKSCREEN_URI;
- } else if (component.equals(MixnMatchColumns.KEY_BOOT_ANIM)) {
- return ThemesColumns.BOOT_ANIM_URI;
- } else if (component.equals(MixnMatchColumns.KEY_FONT)) {
- return ThemesColumns.FONT_URI;
- } else if (component.equals(MixnMatchColumns.KEY_ICONS)) {
- return ThemesColumns.ICON_URI;
- } else if (component.equals(MixnMatchColumns.KEY_STATUS_BAR)) {
- return ThemesColumns.STATUSBAR_URI;
- } else if (component.equals(MixnMatchColumns.KEY_NOTIFICATIONS)) {
- throw new IllegalArgumentException("Notifications mixnmatch component does not have a related column");
- } else if (component.equals(MixnMatchColumns.KEY_RINGTONE)) {
- throw new IllegalArgumentException("Ringtone mixnmatch component does not have a related column");
- } else if (component.equals(MixnMatchColumns.KEY_OVERLAYS)) {
- return ThemesColumns.OVERLAYS_URI;
- } else if (component.equals(MixnMatchColumns.KEY_STATUS_BAR)) {
- throw new IllegalArgumentException(
- "Status bar mixnmatch component does not have a related column");
- } else if (component.equals(MixnMatchColumns.KEY_NAVIGATION_BAR)) {
- throw new IllegalArgumentException(
- "Navigation bar mixnmatch component does not have a related column");
- } else if (component.equals(MixnMatchColumns.KEY_LIVE_LOCK_SCREEN)) {
- throw new IllegalArgumentException(
- "Live lock screen mixnmatch component does not have a related column");
- }
- return null;
- }
-
- /**
- * A component in the themes table (IE "mods_wallpaper") has an
- * equivalent key in mixnmatch table
- */
- public static String componentToMixNMatchKey(String component) {
- if (component.equals(ThemesColumns.MODIFIES_LAUNCHER)) {
- return MixnMatchColumns.KEY_HOMESCREEN;
- } else if (component.equals(ThemesColumns.MODIFIES_ICONS)) {
- return MixnMatchColumns.KEY_ICONS;
- } else if (component.equals(ThemesColumns.MODIFIES_LOCKSCREEN)) {
- return MixnMatchColumns.KEY_LOCKSCREEN;
- } else if (component.equals(ThemesColumns.MODIFIES_FONTS)) {
- return MixnMatchColumns.KEY_FONT;
- } else if (component.equals(ThemesColumns.MODIFIES_BOOT_ANIM)) {
- return MixnMatchColumns.KEY_BOOT_ANIM;
- } else if (component.equals(ThemesColumns.MODIFIES_ALARMS)) {
- return MixnMatchColumns.KEY_ALARM;
- } else if (component.equals(ThemesColumns.MODIFIES_NOTIFICATIONS)) {
- return MixnMatchColumns.KEY_NOTIFICATIONS;
- } else if (component.equals(ThemesColumns.MODIFIES_RINGTONES)) {
- return MixnMatchColumns.KEY_RINGTONE;
- } else if (component.equals(ThemesColumns.MODIFIES_OVERLAYS)) {
- return MixnMatchColumns.KEY_OVERLAYS;
- } else if (component.equals(ThemesColumns.MODIFIES_STATUS_BAR)) {
- return MixnMatchColumns.KEY_STATUS_BAR;
- } else if (component.equals(ThemesColumns.MODIFIES_NAVIGATION_BAR)) {
- return MixnMatchColumns.KEY_NAVIGATION_BAR;
- } else if (component.equals(ThemesColumns.MODIFIES_LIVE_LOCK_SCREEN)) {
- return MixnMatchColumns.KEY_LIVE_LOCK_SCREEN;
- }
- return null;
- }
-
- /**
- * A mixnmatch key in has an
- * equivalent value in the themes table
- */
- public static String mixNMatchKeyToComponent(String mixnmatchKey) {
- if (mixnmatchKey.equals(MixnMatchColumns.KEY_HOMESCREEN)) {
- return ThemesColumns.MODIFIES_LAUNCHER;
- } else if (mixnmatchKey.equals(MixnMatchColumns.KEY_ICONS)) {
- return ThemesColumns.MODIFIES_ICONS;
- } else if (mixnmatchKey.equals(MixnMatchColumns.KEY_LOCKSCREEN)) {
- return ThemesColumns.MODIFIES_LOCKSCREEN;
- } else if (mixnmatchKey.equals(MixnMatchColumns.KEY_FONT)) {
- return ThemesColumns.MODIFIES_FONTS;
- } else if (mixnmatchKey.equals(MixnMatchColumns.KEY_BOOT_ANIM)) {
- return ThemesColumns.MODIFIES_BOOT_ANIM;
- } else if (mixnmatchKey.equals(MixnMatchColumns.KEY_ALARM)) {
- return ThemesColumns.MODIFIES_ALARMS;
- } else if (mixnmatchKey.equals(MixnMatchColumns.KEY_NOTIFICATIONS)) {
- return ThemesColumns.MODIFIES_NOTIFICATIONS;
- } else if (mixnmatchKey.equals(MixnMatchColumns.KEY_RINGTONE)) {
- return ThemesColumns.MODIFIES_RINGTONES;
- } else if (mixnmatchKey.equals(MixnMatchColumns.KEY_OVERLAYS)) {
- return ThemesColumns.MODIFIES_OVERLAYS;
- } else if (mixnmatchKey.equals(MixnMatchColumns.KEY_STATUS_BAR)) {
- return ThemesColumns.MODIFIES_STATUS_BAR;
- } else if (mixnmatchKey.equals(MixnMatchColumns.KEY_NAVIGATION_BAR)) {
- return ThemesColumns.MODIFIES_NAVIGATION_BAR;
- } else if (mixnmatchKey.equals(MixnMatchColumns.KEY_LIVE_LOCK_SCREEN)) {
- return ThemesColumns.MODIFIES_LIVE_LOCK_SCREEN;
- }
- return null;
- }
- }
-
- /**
- * Table containing cached preview files for a given theme
- */
- public static class PreviewColumns {
- /**
- * Uri for retrieving the previews table.
- * Querying the themes provider using this URI will return a cursor with a key and value
- * columns, and a row for each component.
- */
- public static final Uri CONTENT_URI = Uri.withAppendedPath(AUTHORITY_URI, "previews");
-
- /**
- * Uri for retrieving the previews for the currently applied components.
- * Querying the themes provider using this URI will return a cursor with a single row
- * containing all the previews for the components that are currently applied.
- */
- public static final Uri APPLIED_URI = Uri.withAppendedPath(AUTHORITY_URI,
- "applied_previews");
-
- /**
- * Uri for retrieving the default previews for the theme.
- * Querying the themes provider using this URI will return a cursor with a single row
- * containing all the previews for the default components of the current theme.
- */
- public static final Uri COMPONENTS_URI = Uri.withAppendedPath(AUTHORITY_URI,
- "components_previews");
-
- /**
- * The unique ID for a row.
- * <P>Type: INTEGER (long)</P>
- */
- public static final String _ID = "_id";
-
- /**
- * The unique ID for the theme these previews belong to.
- * <P>Type: INTEGER (long)</P>
- */
- public static final String THEME_ID = "theme_id";
-
- /**
- * The unique ID for the component within a theme.
- * <P>Type: INTEGER (long)</P>
- */
- public static final String COMPONENT_ID = "component_id";
-
- /**
- * The unique key for a row. See the Valid key constants section below
- * for valid examples
- * <P>Type: TEXT</P>
- */
- public static final String COL_KEY = "key";
-
- /**
- * The package name that corresponds to a given component.
- * <P>Type: String</P>
- */
- public static final String COL_VALUE = "value";
-
- /**
- * Valid keys
- */
-
- /**
- * Cached image of the themed status bar background.
- * <P>Type: String (file path)</P>
- */
- public static final String STATUSBAR_BACKGROUND = "statusbar_background";
-
- /**
- * Cached image of the themed bluetooth status icon.
- * <P>Type: String (file path)</P>
- */
- public static final String STATUSBAR_BLUETOOTH_ICON = "statusbar_bluetooth_icon";
-
- /**
- * Cached image of the themed wifi status icon.
- * <P>Type: String (file path)</P>
- */
- public static final String STATUSBAR_WIFI_ICON = "statusbar_wifi_icon";
-
- /**
- * Cached image of the themed cellular signal status icon.
- * <P>Type: String (file path)</P>
- */
- public static final String STATUSBAR_SIGNAL_ICON = "statusbar_signal_icon";
-
- /**
- * Cached image of the themed battery using portrait style.
- * <P>Type: String (file path)</P>
- */
- public static final String STATUSBAR_BATTERY_PORTRAIT = "statusbar_battery_portrait";
-
- /**
- * Cached image of the themed battery using landscape style.
- * <P>Type: String (file path)</P>
- */
- public static final String STATUSBAR_BATTERY_LANDSCAPE = "statusbar_battery_landscape";
-
- /**
- * Cached image of the themed battery using circle style.
- * <P>Type: String (file path)</P>
- */
- public static final String STATUSBAR_BATTERY_CIRCLE = "statusbar_battery_circle";
-
- /**
- * The themed color used for clock text in the status bar.
- * <P>Type: INTEGER (int)</P>
- */
- public static final String STATUSBAR_CLOCK_TEXT_COLOR = "statusbar_clock_text_color";
-
- /**
- * The themed margin value between the wifi and rssi signal icons.
- * <P>Type: INTEGER (int)</P>
- */
- public static final String STATUSBAR_WIFI_COMBO_MARGIN_END = "wifi_combo_margin_end";
-
- /**
- * Cached image of the themed navigation bar background.
- * <P>Type: String (file path)</P>
- */
- public static final String NAVBAR_BACKGROUND = "navbar_background";
-
- /**
- * Cached image of the themed back button.
- * <P>Type: String (file path)</P>
- */
- public static final String NAVBAR_BACK_BUTTON = "navbar_back_button";
-
- /**
- * Cached image of the themed home button.
- * <P>Type: String (file path)</P>
- */
- public static final String NAVBAR_HOME_BUTTON = "navbar_home_button";
-
- /**
- * Cached image of the themed recents button.
- * <P>Type: String (file path)</P>
- */
- public static final String NAVBAR_RECENT_BUTTON = "navbar_recent_button";
-
- /**
- * Cached image of the 1/3 icons
- * <P>Type: String (file path)</P>
- */
- public static final String ICON_PREVIEW_1 = "icon_preview_1";
-
- /**
- * Cached image of the 2/3 icons
- * <P>Type: String (file path)</P>
- */
- public static final String ICON_PREVIEW_2 = "icon_preview_2";
-
- /**
- * Cached image of the 3/3 icons
- * <P>Type: String (file path)</P>
- */
- public static final String ICON_PREVIEW_3 = "icon_preview_3";
-
- /**
- * Full path to the theme's wallpaper asset.
- * <P>Type: String (file path)</P>
- */
- public static final String WALLPAPER_FULL = "wallpaper_full";
-
- /**
- * Cached preview of the theme's wallpaper which is larger than the thumbnail
- * but smaller than the full sized wallpaper.
- * <P>Type: String (file path)</P>
- */
- public static final String WALLPAPER_PREVIEW = "wallpaper_preview";
-
- /**
- * Cached thumbnail of the theme's wallpaper
- * <P>Type: String (file path)</P>
- */
- public static final String WALLPAPER_THUMBNAIL = "wallpaper_thumbnail";
-
- /**
- * Cached preview of the theme's lockscreen wallpaper which is larger than the thumbnail
- * but smaller than the full sized lockscreen wallpaper.
- * <P>Type: String (file path)</P>
- */
- public static final String LOCK_WALLPAPER_PREVIEW = "lock_wallpaper_preview";
-
- /**
- * Cached thumbnail of the theme's lockscreen wallpaper
- * <P>Type: String (file path)</P>
- */
- public static final String LOCK_WALLPAPER_THUMBNAIL = "lock_wallpaper_thumbnail";
-
- /**
- * Cached preview of UI controls representing the theme's style
- * <P>Type: String (file path)</P>
- */
- public static final String STYLE_PREVIEW = "style_preview";
-
- /**
- * Cached thumbnail preview of UI controls representing the theme's style
- * <P>Type: String (file path)</P>
- */
- public static final String STYLE_THUMBNAIL = "style_thumbnail";
-
- /**
- * Cached thumbnail of the theme's boot animation
- * <P>Type: String (file path)</P>
- */
- public static final String BOOTANIMATION_THUMBNAIL = "bootanimation_thumbnail";
-
- /**
- * Cached preview of live lock screen
- * <P>Type: String (file path)</P>
- */
- public static final String LIVE_LOCK_SCREEN_PREVIEW = "live_lock_screen_preview";
-
- /**
- * Cached thumbnail preview of live lock screen
- * <P>Type: String (file path)</P>
- */
- public static final String LIVE_LOCK_SCREEN_THUMBNAIL = "live_lock_screen_thumbnail";
-
- public static final String[] VALID_KEYS = {
- STATUSBAR_BACKGROUND,
- STATUSBAR_BLUETOOTH_ICON,
- STATUSBAR_WIFI_ICON,
- STATUSBAR_SIGNAL_ICON,
- STATUSBAR_BATTERY_PORTRAIT,
- STATUSBAR_BATTERY_LANDSCAPE,
- STATUSBAR_BATTERY_CIRCLE,
- STATUSBAR_CLOCK_TEXT_COLOR,
- STATUSBAR_WIFI_COMBO_MARGIN_END,
- NAVBAR_BACKGROUND,
- NAVBAR_BACK_BUTTON,
- NAVBAR_HOME_BUTTON,
- NAVBAR_RECENT_BUTTON,
- ICON_PREVIEW_1,
- ICON_PREVIEW_2,
- ICON_PREVIEW_3,
- WALLPAPER_FULL,
- WALLPAPER_PREVIEW,
- WALLPAPER_THUMBNAIL,
- LOCK_WALLPAPER_PREVIEW,
- LOCK_WALLPAPER_THUMBNAIL,
- STYLE_PREVIEW,
- STYLE_THUMBNAIL,
- BOOTANIMATION_THUMBNAIL,
- LIVE_LOCK_SCREEN_PREVIEW,
- LIVE_LOCK_SCREEN_THUMBNAIL,
- };
- }
-
- public static class Intent {
- /**
- * Action sent from the provider when a theme has been fully installed. Fully installed
- * means that the apk was installed by PackageManager and the theme resources were
- * processed and cached by {@link com.android.server.ThemeService}
- * Requires the {@link android.Manifest.permission#READ_THEMES} permission to receive
- * this broadcast.
- */
- public static final String ACTION_THEME_INSTALLED =
- "themescontract.intent.action.THEME_INSTALLED";
-
- /**
- * Action sent from the provider when a theme has been updated.
- * Requires the {@link android.Manifest.permission#READ_THEMES} permission to receive
- * this broadcast.
- */
- public static final String ACTION_THEME_UPDATED =
- "themescontract.intent.action.THEME_UPDATED";
-
- /**
- * Action sent from the provider when a theme has been removed.
- * Requires the {@link android.Manifest.permission#READ_THEMES} permission to receive
- * this broadcast.
- */
- public static final String ACTION_THEME_REMOVED =
- "themescontract.intent.action.THEME_REMOVED";
-
- /**
- * Uri scheme used to broadcast the theme's package name when broadcasting
- * {@link android.provider.ThemesContract.Intent#ACTION_THEME_INSTALLED} or
- * {@link android.provider.ThemesContract.Intent#ACTION_THEME_REMOVED}
- */
- public static final String URI_SCHEME_PACKAGE = "package";
- }
-}
diff --git a/core/java/android/service/gesture/EdgeGestureManager.java b/core/java/android/service/gesture/EdgeGestureManager.java
deleted file mode 100644
index 7c0ab2e..0000000
--- a/core/java/android/service/gesture/EdgeGestureManager.java
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Copyright (C) 2013 The CyanogenMod Project (Jens Doll)
- *
- * 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.service.gesture;
-
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.service.gesture.IEdgeGestureActivationListener;
-import android.service.gesture.IEdgeGestureHostCallback;
-import android.service.gesture.IEdgeGestureService;
-import android.util.Slog;
-
-import com.android.internal.util.gesture.EdgeGesturePosition;
-
-/**
- * This is a simple Manager class for edge gesture service on the application side. The application need
- * {@code INJECT_EVENTS} permission to register {@code EdgeGestureActivationListener}s.<br>
- * See {@link android.service.gesture.IEdgeGestureService} for more information.
- *
- * @see android.service.gesture.IEdgeGestureService
- * @hide
- */
-public class EdgeGestureManager {
- public static final String TAG = "EdgeGestureManager";
- public static final boolean DEBUG = false;
-
- private static EdgeGestureManager sInstance;
-
- private final IEdgeGestureService mPs;
-
- public static abstract class EdgeGestureActivationListener {
- private Handler mHandler;
- private IEdgeGestureHostCallback mCallback;
-
- private class Delegator extends IEdgeGestureActivationListener.Stub {
- public void onEdgeGestureActivation(final int touchX, final int touchY, final int positionIndex, final int flags)
- throws RemoteException {
- mHandler.post(new Runnable() {
- public void run() {
- EdgeGestureActivationListener.this.onEdgeGestureActivation(touchX, touchY, EdgeGesturePosition.values()[positionIndex], flags);
- }
- });
- }
- }
- private Delegator mDelegator;
-
- public EdgeGestureActivationListener() {
- this(Looper.getMainLooper());
- }
-
- public EdgeGestureActivationListener(Looper looper) {
- mHandler = new Handler(looper);
- mDelegator = new Delegator();
- }
-
- /* package */ void setHostCallback(IEdgeGestureHostCallback hostCallback) {
- mCallback = hostCallback;
- }
-
- /**
- * Override this to receive activations from the edge gesture service.
- *
- * @param touchX the last X position a touch event was registered.
- * @param touchY the last Y position a touch event was registered.
- * @param position the position of the activation.
- * @param flags currently 0.
- * @see IEdgeGestureActivationListener#onEdgeGestureActivation(int, int, int, int)
- */
- public abstract void onEdgeGestureActivation(int touchX, int touchY, EdgeGesturePosition position, int flags);
-
- /**
- * After being activated, this allows the edge gesture control to steal focus from the current
- * window.
- *
- * @see IEdgeGestureHostCallback#gainTouchFocus(IBinder)
- */
- public boolean gainTouchFocus(IBinder applicationWindowToken) {
- try {
- return mCallback.gainTouchFocus(applicationWindowToken);
- } catch (RemoteException e) {
- Slog.w(TAG, "gainTouchFocus failed: " + e.getMessage());
- /* fall through */
- }
- return false;
- }
-
- public boolean dropEventsUntilLift() {
- try {
- return mCallback.dropEventsUntilLift();
- } catch (RemoteException e) {
- Slog.w(TAG, "dropNextEvents failed: " + e.getMessage());
- /* fall through */
- }
- return false;
- }
-
- /**
- * Turns listening for edge gesture activation gestures on again, after it was disabled during
- * the call to the listener.
- *
- * @see IEdgeGestureHostCallback#restoreListenerState()
- */
- public void restoreListenerState() {
- if (DEBUG) {
- Slog.d(TAG, "restore listener state: " + Thread.currentThread().getName());
- }
- try {
- mCallback.restoreListenerState();
- } catch (RemoteException e) {
- Slog.w(TAG, "restoreListenerState failed: " + e.getMessage());
- /* fall through */
- }
- }
- }
-
- private EdgeGestureManager(IEdgeGestureService ps) {
- mPs = ps;
- }
-
- /**
- * Gets an instance of the edge gesture manager.
- *
- * @return The edge gesture manager instance.
- * @hide
- */
- public static EdgeGestureManager getInstance() {
- synchronized (EdgeGestureManager.class) {
- if (sInstance == null) {
- IBinder b = ServiceManager.getService("edgegestureservice");
- sInstance = new EdgeGestureManager(IEdgeGestureService.Stub.asInterface(b));
- }
- return sInstance;
- }
- }
-
- /**
- * Checks if the edge gesture service is present.
- * <p>
- * Since the service is only started at boot time and is bound to the system server, this
- * is constant for the devices up time.
- *
- * @return {@code true} when the edge gesture service is running on this device.
- * @hide
- */
- public boolean isPresent() {
- return mPs != null;
- }
-
- /**
- * Register a listener for edge gesture activation gestures. Initially the listener
- * is set to listen for no position. Use updateedge gestureActivationListener() to
- * bind the listener to positions.
- *
- * @param listener is the activation listener.
- * @return {@code true} if the registration was successful.
- * @hide
- */
- public boolean setEdgeGestureActivationListener(EdgeGestureActivationListener listener) {
- if (DEBUG) {
- Slog.d(TAG, "Set edge gesture activation listener");
- }
- try {
- IEdgeGestureHostCallback callback = mPs.registerEdgeGestureActivationListener(listener.mDelegator);
- listener.setHostCallback(callback);
- return true;
- } catch (RemoteException e) {
- Slog.e(TAG, "Failed to set edge gesture activation listener: " + e.getMessage());
- return false;
- }
- }
-
- /**
- * Update the listener to react on gestures in the given positions.
- *
- * @param listener is a already registered listener.
- * @param positions is a bit mask describing the positions to listen to.
- * @hide
- */
- public void updateEdgeGestureActivationListener(EdgeGestureActivationListener listener, int positions) {
- if (DEBUG) {
- Slog.d(TAG, "Update edge gesture activation listener: 0x" + Integer.toHexString(positions));
- }
- try {
- mPs.updateEdgeGestureActivationListener(listener.mDelegator.asBinder(), positions);
- } catch (RemoteException e) {
- Slog.e(TAG, "Failed to update edge gesture activation listener: " + e.getMessage());
- }
- }
-
-}
diff --git a/core/java/android/service/gesture/IEdgeGestureActivationListener.aidl b/core/java/android/service/gesture/IEdgeGestureActivationListener.aidl
deleted file mode 100644
index 0c9b24a..0000000
--- a/core/java/android/service/gesture/IEdgeGestureActivationListener.aidl
+++ /dev/null
@@ -1,14 +0,0 @@
-
-package android.service.gesture;
-
-import android.view.InputEvent;
-
-/** @hide */
-interface IEdgeGestureActivationListener {
-
- /** Called when a gesture is detected that fits to the activation gesture. At this point in
- * time gesture detection is disabled. Call IEdgeGestureHostCallback.restoreState() to
- * recover from this.
- */
- oneway void onEdgeGestureActivation(int touchX, int touchY, int positionIndex, int flags);
-} \ No newline at end of file
diff --git a/core/java/android/service/gesture/IEdgeGestureHostCallback.aidl b/core/java/android/service/gesture/IEdgeGestureHostCallback.aidl
deleted file mode 100644
index c261550..0000000
--- a/core/java/android/service/gesture/IEdgeGestureHostCallback.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-package android.service.gesture;
-
-/** @hide */
-interface IEdgeGestureHostCallback {
-
- /** After being activated, this allows to steal focus from the current
- * window
- */
- boolean gainTouchFocus(IBinder windowToken);
-
- /** Turns listening for activation gestures on again, after it was disabled during
- * the call to the listener.
- */
- oneway void restoreListenerState();
-
- /*
- * Tells filter to drop all events till touch up
- */
- boolean dropEventsUntilLift();
-} \ No newline at end of file
diff --git a/core/java/android/service/gesture/IEdgeGestureService.aidl b/core/java/android/service/gesture/IEdgeGestureService.aidl
deleted file mode 100644
index 342cf71..0000000
--- a/core/java/android/service/gesture/IEdgeGestureService.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-package android.service.gesture;
-
-import android.service.gesture.IEdgeGestureActivationListener;
-import android.service.gesture.IEdgeGestureHostCallback;
-
-/** @hide */
-interface IEdgeGestureService {
-
- /** Register a listener for activation gestures. Initially the listener
- * is set to listen for no position. Use updateEdgeGestureActivationListener() to
- * bind the listener to positions.
- * Use the returned IEdgeGestureHostCallback to manipulate the state after activation.
- */
- IEdgeGestureHostCallback registerEdgeGestureActivationListener(in IEdgeGestureActivationListener listener);
-
- /** Update the listener to react on gestures in the given positions.
- */
- void updateEdgeGestureActivationListener(in IBinder listener, int positionFlags);
-
-} \ No newline at end of file
diff --git a/core/java/android/service/gesture/package.html b/core/java/android/service/gesture/package.html
deleted file mode 100644
index c9f96a6..0000000
--- a/core/java/android/service/gesture/package.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<body>
-
-{@hide}
-
-</body>
diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java
index fa347b9..22ad634 100644
--- a/core/java/android/text/Layout.java
+++ b/core/java/android/text/Layout.java
@@ -1130,20 +1130,31 @@ public abstract class Layout {
*/
public int getOffsetForHorizontal(int line, float horiz) {
// TODO: use Paint.getOffsetForAdvance to avoid binary search
- int max = getLineEnd(line) - 1;
- int min = getLineStart(line);
+ final int lineEndOffset = getLineEnd(line);
+ final int lineStartOffset = getLineStart(line);
+
Directions dirs = getLineDirections(line);
- if (line == getLineCount() - 1)
- max++;
+ TextLine tl = TextLine.obtain();
+ // XXX: we don't care about tabs as we just use TextLine#getOffsetToLeftRightOf here.
+ tl.set(mPaint, mText, lineStartOffset, lineEndOffset, getParagraphDirection(line), dirs,
+ false, null);
- int best = min;
+ final int max;
+ if (line == getLineCount() - 1) {
+ max = lineEndOffset;
+ } else {
+ max = tl.getOffsetToLeftRightOf(lineEndOffset - lineStartOffset,
+ !isRtlCharAt(lineEndOffset - 1)) + lineStartOffset;
+ }
+ int best = lineStartOffset;
float bestdist = Math.abs(getPrimaryHorizontal(best) - horiz);
for (int i = 0; i < dirs.mDirections.length; i += 2) {
- int here = min + dirs.mDirections[i];
+ int here = lineStartOffset + dirs.mDirections[i];
int there = here + (dirs.mDirections[i+1] & RUN_LENGTH_MASK);
- int swap = (dirs.mDirections[i+1] & RUN_RTL_FLAG) != 0 ? -1 : 1;
+ boolean isRtl = (dirs.mDirections[i+1] & RUN_RTL_FLAG) != 0;
+ int swap = isRtl ? -1 : 1;
if (there > max)
there = max;
@@ -1163,23 +1174,23 @@ public abstract class Layout {
low = here + 1;
if (low < there) {
- low = getOffsetAtStartOf(low);
-
- float dist = Math.abs(getPrimaryHorizontal(low) - horiz);
-
- int aft = TextUtils.getOffsetAfter(mText, low);
- if (aft < there) {
- float other = Math.abs(getPrimaryHorizontal(aft) - horiz);
-
- if (other < dist) {
- dist = other;
- low = aft;
+ int aft = tl.getOffsetToLeftRightOf(low - lineStartOffset, isRtl) + lineStartOffset;
+ low = tl.getOffsetToLeftRightOf(aft - lineStartOffset, !isRtl) + lineStartOffset;
+ if (low >= here && low < there) {
+ float dist = Math.abs(getPrimaryHorizontal(low) - horiz);
+ if (aft < there) {
+ float other = Math.abs(getPrimaryHorizontal(aft) - horiz);
+
+ if (other < dist) {
+ dist = other;
+ low = aft;
+ }
}
- }
- if (dist < bestdist) {
- bestdist = dist;
- best = low;
+ if (dist < bestdist) {
+ bestdist = dist;
+ best = low;
+ }
}
}
@@ -1198,6 +1209,7 @@ public abstract class Layout {
best = max;
}
+ TextLine.recycle(tl);
return best;
}
diff --git a/core/java/android/text/TextLine.java b/core/java/android/text/TextLine.java
index 39e8694..3592187 100644
--- a/core/java/android/text/TextLine.java
+++ b/core/java/android/text/TextLine.java
@@ -718,13 +718,14 @@ class TextLine {
* @param bottom the bottom of the line
* @param fmi receives metrics information, can be null
* @param needWidth true if the width of the run is needed
+ * @param offset the offset for the purpose of measuring
* @return the signed width of the run based on the run direction; only
* valid if needWidth is true
*/
private float handleText(TextPaint wp, int start, int end,
int contextStart, int contextEnd, boolean runIsRtl,
Canvas c, float x, int top, int y, int bottom,
- FontMetricsInt fmi, boolean needWidth) {
+ FontMetricsInt fmi, boolean needWidth, int offset) {
// Get metrics first (even for empty strings or "0" width runs)
if (fmi != null) {
@@ -742,11 +743,11 @@ class TextLine {
if (needWidth || (c != null && (wp.bgColor != 0 || wp.underlineColor != 0 || runIsRtl))) {
if (mCharsValid) {
ret = wp.getRunAdvance(mChars, start, end, contextStart, contextEnd,
- runIsRtl, end);
+ runIsRtl, offset);
} else {
int delta = mStart;
ret = wp.getRunAdvance(mText, delta + start, delta + end,
- delta + contextStart, delta + contextEnd, runIsRtl, delta + end);
+ delta + contextStart, delta + contextEnd, runIsRtl, delta + offset);
}
}
@@ -895,8 +896,8 @@ class TextLine {
TextPaint wp = mWorkPaint;
wp.set(mPaint);
final int mlimit = measureLimit;
- return handleText(wp, start, mlimit, start, limit, runIsRtl, c, x, top,
- y, bottom, fmi, needWidth || mlimit < measureLimit);
+ return handleText(wp, start, limit, start, limit, runIsRtl, c, x, top,
+ y, bottom, fmi, needWidth || mlimit < measureLimit, mlimit);
}
mMetricAffectingSpanSpanSet.init(mSpanned, mStart + start, mStart + limit);
@@ -940,13 +941,14 @@ class TextLine {
}
for (int j = i, jnext; j < mlimit; j = jnext) {
- jnext = mCharacterStyleSpanSet.getNextTransition(mStart + j, mStart + mlimit) -
+ jnext = mCharacterStyleSpanSet.getNextTransition(mStart + j, mStart + inext) -
mStart;
+ int offset = Math.min(jnext, mlimit);
wp.set(mPaint);
for (int k = 0; k < mCharacterStyleSpanSet.numberOfSpans; k++) {
// Intentionally using >= and <= as explained above
- if ((mCharacterStyleSpanSet.spanStarts[k] >= mStart + jnext) ||
+ if ((mCharacterStyleSpanSet.spanStarts[k] >= mStart + offset) ||
(mCharacterStyleSpanSet.spanEnds[k] <= mStart + j)) continue;
CharacterStyle span = mCharacterStyleSpanSet.spans[k];
@@ -958,7 +960,7 @@ class TextLine {
wp.setHyphenEdit(0);
}
x += handleText(wp, j, jnext, i, inext, runIsRtl, c, x,
- top, y, bottom, fmi, needWidth || jnext < measureLimit);
+ top, y, bottom, fmi, needWidth || jnext < measureLimit, offset);
}
}
diff --git a/core/java/android/util/Patterns.java b/core/java/android/util/Patterns.java
index 2cc91b9..6fc8ae5 100644
--- a/core/java/android/util/Patterns.java
+++ b/core/java/android/util/Patterns.java
@@ -125,15 +125,35 @@ public class Patterns {
+ "|[1-9][0-9]|[0-9]))");
/**
+ * Match the characters without containing chinese characters
+ * @hide
+ */
+ private static final String GOOD_IRI_HOST_CHAR =
+ "a-zA-Z0-9\u00A0-\u2FFF\u3040-\u4DFF\u9FA6-\uD7FF"
+ + "\uF900-\uFDCF\uFDF0-\uFEFF";
+
+ /**
* RFC 1035 Section 2.3.4 limits the labels to a maximum 63 octets.
*/
- private static final String IRI
- = "[" + GOOD_IRI_CHAR + "]([" + GOOD_IRI_CHAR + "\\-]{0,61}[" + GOOD_IRI_CHAR + "]){0,1}";
+ private static final String IRI =
+ "[" + GOOD_IRI_HOST_CHAR + "]([" + GOOD_IRI_HOST_CHAR + "\\-]{0,61}["
+ + GOOD_IRI_HOST_CHAR + "]){0,1}";
private static final String GOOD_GTLD_CHAR =
- "a-zA-Z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF";
+ "a-zA-Z\u00A0-\u2FFF\u3040-\u4DFF\u9FA6-\uD7FF"
+ + "\uF900-\uFDCF\uFDF0-\uFEFF";
private static final String GTLD = "[" + GOOD_GTLD_CHAR + "]{2,63}";
private static final String HOST_NAME = "(" + IRI + "\\.)+" + GTLD;
+ // Halfwidth and fullwidth forms
+ private static final String HALF_FULL_WIDTH_CHAR = "\uFF00-\uFFEF";
+ // Symbols and punctuation
+ private static final String SYMBOLS_PUNCTUATION_CHAR = "\u3000-\u303F";
+ // Chinese characters
+ private static final String CHINESE_CHAR = "\u4E00-\u9FA5";
+ // Forbidden characters, should remove from URL,
+ private static final String FORBIDDEN_CHAR =
+ "[" + SYMBOLS_PUNCTUATION_CHAR + CHINESE_CHAR
+ + HALF_FULL_WIDTH_CHAR + "]";
public static final Pattern DOMAIN_NAME
= Pattern.compile("(" + HOST_NAME + "|" + IP_ADDRESS + ")");
@@ -149,11 +169,15 @@ public class Patterns {
+ "\\.\\+\\!\\*\\'\\(\\)\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,25})?\\@)?)?"
+ "(?:" + DOMAIN_NAME + ")"
+ "(?:\\:\\d{1,5})?)" // plus option port number
- + "(\\/(?:(?:[" + GOOD_IRI_CHAR + "\\;\\/\\?\\:\\@\\&\\=\\#\\~" // plus option query params
- + "\\-\\.\\+\\!\\*\\'\\(\\)\\,\\_])|(?:\\%[a-fA-F0-9]{2}))*)?"
- + "(?:\\b|$)"); // and finally, a word boundary or end of
- // input. This is to stop foo.sure from
- // matching as foo.su
+ + "(\\/(?:(?:[" + GOOD_IRI_HOST_CHAR
+ + "\\;\\/\\?\\:\\@\\&\\=\\#\\~" // plus option query params
+ + "\\-\\.\\+\\!\\*\\'\\(\\)\\_])|(?:\\,[" + GOOD_IRI_HOST_CHAR
+ + "])|(?:\\%[a-fA-F0-9]{2}))*)?"
+ + "(?:(?=" + FORBIDDEN_CHAR
+ + ")|\\b|$)");
+ // and finally, a word boundary or end of input. This is to stop
+ // foo.sure from matching as foo.su
+ // also should remove forbidden characters from end of URL.
public static final Pattern EMAIL_ADDRESS
= Pattern.compile(
diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java
index d43b962..85321f9 100644
--- a/core/java/android/view/DisplayInfo.java
+++ b/core/java/android/view/DisplayInfo.java
@@ -567,6 +567,8 @@ public final class DisplayInfo implements Parcelable {
} else if (type == Display.TYPE_BUILT_IN
&& (flags & Display.FLAG_PRESENTATION) == 0) {
outMetrics.setDensity(DisplayMetrics.DENSITY_PREFERRED);
+ } else {
+ outMetrics.setDensity(logicalDensityDpi);
}
}
diff --git a/core/java/android/view/InputDevice.java b/core/java/android/view/InputDevice.java
index 7642ed9..5f88c11 100644
--- a/core/java/android/view/InputDevice.java
+++ b/core/java/android/view/InputDevice.java
@@ -256,16 +256,13 @@ public final class InputDevice implements Parcelable {
public static final int SOURCE_TOUCH_NAVIGATION = 0x00200000 | SOURCE_CLASS_NONE;
/**
- * The input source is a touch device whose motions should be interpreted as gestures.
- *
- * For example, an upward swipe should be treated the same as a swipe of the touchscreen.
- * The same should apply for left, right, down swipes. Complex gestures may also be input.
+ * The input source is a rotating encoder device whose motions should be interpreted as akin to
+ * those of a scroll wheel.
*
* @see #SOURCE_CLASS_NONE
- *
- * @hide
+ * {@hide}
*/
- public static final int SOURCE_GESTURE_SENSOR = 0x00400000 | SOURCE_CLASS_NONE;
+ public static final int SOURCE_ROTARY_ENCODER = 0x00400000 | SOURCE_CLASS_NONE;
/**
* The input source is a joystick.
@@ -284,6 +281,18 @@ public final class InputDevice implements Parcelable {
public static final int SOURCE_HDMI = 0x02000000 | SOURCE_CLASS_BUTTON;
/**
+ * The input source is a touch device whose motions should be interpreted as gestures.
+ *
+ * For example, an upward swipe should be treated the same as a swipe of the touchscreen.
+ * The same should apply for left, right, down swipes. Complex gestures may also be input.
+ *
+ * @see #SOURCE_CLASS_NONE
+ *
+ * @hide
+ */
+ public static final int SOURCE_GESTURE_SENSOR = 0x10000000 | SOURCE_CLASS_NONE;
+
+ /**
* A special input source constant that is used when filtering input devices
* to match devices that provide any type of input source.
*/
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index d5847be..d128288 100644
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -761,6 +761,19 @@ public class KeyEvent extends InputEvent implements Parcelable {
* Backs out one level of a navigation hierarchy or collapses the item that currently has
* focus. */
public static final int KEYCODE_NAVIGATE_OUT = 263;
+ /** Key code constant: Primary stem key for Wear
+ * Main power/reset button on watch.
+ * @hide */
+ public static final int KEYCODE_STEM_PRIMARY = 264;
+ /** Key code constant: Generic stem key 1 for Wear
+ * @hide */
+ public static final int KEYCODE_STEM_1 = 265;
+ /** Key code constant: Generic stem key 2 for Wear
+ * @hide */
+ public static final int KEYCODE_STEM_2 = 266;
+ /** Key code constant: Generic stem key 3 for Wear
+ * @hide */
+ public static final int KEYCODE_STEM_3 = 267;
/** Key code constant: Skip forward media key. */
public static final int KEYCODE_MEDIA_SKIP_FORWARD = 272;
/** Key code constant: Skip backward media key. */
@@ -771,8 +784,11 @@ public class KeyEvent extends InputEvent implements Parcelable {
/** Key code constant: Step backward media key.
* Steps media backward, one frame at a time. */
public static final int KEYCODE_MEDIA_STEP_BACKWARD = 275;
+ /** Key code constant: put device to sleep unless a wakelock is held.
+ * @hide */
+ public static final int KEYCODE_SOFT_SLEEP = 276;
- private static final int LAST_KEYCODE = KEYCODE_MEDIA_STEP_BACKWARD;
+ private static final int LAST_KEYCODE = KEYCODE_SOFT_SLEEP;
// NOTE: If you add a new keycode here you must also add it to:
// isSystem()
@@ -1836,6 +1852,9 @@ public class KeyEvent extends InputEvent implements Parcelable {
case KeyEvent.KEYCODE_VOLUME_MUTE:
case KeyEvent.KEYCODE_CAMERA:
case KeyEvent.KEYCODE_FOCUS:
+ case KeyEvent.KEYCODE_STEM_1:
+ case KeyEvent.KEYCODE_STEM_2:
+ case KeyEvent.KEYCODE_STEM_3:
return true;
}
return false;
diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java
index 6026d04..527d7e5 100644
--- a/core/java/android/view/MotionEvent.java
+++ b/core/java/android/view/MotionEvent.java
@@ -962,6 +962,22 @@ public final class MotionEvent extends InputEvent implements Parcelable {
public static final int AXIS_TILT = 25;
/**
+ * Axis constant: Generic scroll axis of a motion event.
+ * <p>
+ * <ul>
+ * <li>Reports the relative movement of the generic scrolling device.
+ * </ul>
+ * </p><p>
+ * This axis should be used for scroll events that are neither strictly vertical nor horizontal.
+ * A good example would be the rotation of a rotary encoder input device.
+ * </p>
+ *
+ * @see #getAxisValue(int, int)
+ * {@hide}
+ */
+ public static final int AXIS_SCROLL = 26;
+
+ /**
* Axis constant: Generic 1 axis of a motion event.
* The interpretation of a generic axis is device-specific.
*
@@ -1171,6 +1187,7 @@ public final class MotionEvent extends InputEvent implements Parcelable {
names.append(AXIS_BRAKE, "AXIS_BRAKE");
names.append(AXIS_DISTANCE, "AXIS_DISTANCE");
names.append(AXIS_TILT, "AXIS_TILT");
+ names.append(AXIS_SCROLL, "AXIS_SCROLL");
names.append(AXIS_GENERIC_1, "AXIS_GENERIC_1");
names.append(AXIS_GENERIC_2, "AXIS_GENERIC_2");
names.append(AXIS_GENERIC_3, "AXIS_GENERIC_3");
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 93345c2..4b56352 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -16940,8 +16940,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
@CallSuper
protected boolean verifyDrawable(Drawable who) {
- return who == mBackground || (mScrollCache != null && mScrollCache.scrollBar == who)
- || (mForegroundInfo != null && mForegroundInfo.mDrawable == who);
+ // Avoid verifying the scroll bar drawable so that we don't end up in
+ // an invalidation loop. This effectively prevents the scroll bar
+ // drawable from triggering invalidations and scheduling runnables.
+ return who == mBackground || (mForegroundInfo != null && mForegroundInfo.mDrawable == who);
}
/**
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 42402eb..9569422 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -174,6 +174,10 @@ public final class ViewRootImpl implements ViewParent,
// so the window should no longer be active.
boolean mStopped = false;
+ // Set to true if the owner of this window is in ambient mode,
+ // which means it won't receive input events.
+ boolean mIsAmbientMode = false;
+
// Set to true to stop input during an Activity Transition.
boolean mPausedForTransition = false;
@@ -990,6 +994,10 @@ public final class ViewRootImpl implements ViewParent,
}
}
+ public void setIsAmbientMode(boolean ambient) {
+ mIsAmbientMode = ambient;
+ }
+
void setWindowStopped(boolean stopped) {
if (mStopped != stopped) {
mStopped = stopped;
@@ -3704,7 +3712,7 @@ public final class ViewRootImpl implements ViewParent,
return true;
} else if ((!mAttachInfo.mHasWindowFocus
&& !q.mEvent.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) || mStopped
- || (mPausedForTransition && !isBack(q.mEvent))) {
+ || mIsAmbientMode || (mPausedForTransition && !isBack(q.mEvent))) {
// This is a focus event and the window doesn't currently have input focus or
// has stopped. This could be an event that came back from the previous stage
// but the window has lost focus or stopped in the meantime.
@@ -5514,6 +5522,8 @@ public final class ViewRootImpl implements ViewParent,
writer.println(mProcessInputEventsScheduled);
writer.print(innerPrefix); writer.print("mTraversalScheduled=");
writer.print(mTraversalScheduled);
+ writer.print(innerPrefix); writer.print("mIsAmbientMode=");
+ writer.print(mIsAmbientMode);
if (mTraversalScheduled) {
writer.print(" (barrier="); writer.print(mTraversalBarrier); writer.println(")");
} else {
diff --git a/core/java/android/widget/LinearLayout.java b/core/java/android/widget/LinearLayout.java
index b5e08ca..df3d850 100644
--- a/core/java/android/widget/LinearLayout.java
+++ b/core/java/android/widget/LinearLayout.java
@@ -348,7 +348,6 @@ public class LinearLayout extends ViewGroup {
final int count = getVirtualChildCount();
for (int i = 0; i < count; i++) {
final View child = getVirtualChildAt(i);
-
if (child != null && child.getVisibility() != GONE) {
if (hasDividerBeforeChildAt(i)) {
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
@@ -377,7 +376,7 @@ public class LinearLayout extends ViewGroup {
*/
private View getLastNonGoneChild() {
for (int i = getVirtualChildCount() - 1; i >= 0; i--) {
- View child = getVirtualChildAt(i);
+ final View child = getVirtualChildAt(i);
if (child != null && child.getVisibility() != GONE) {
return child;
}
@@ -390,7 +389,6 @@ public class LinearLayout extends ViewGroup {
final boolean isLayoutRtl = isLayoutRtl();
for (int i = 0; i < count; i++) {
final View child = getVirtualChildAt(i);
-
if (child != null && child.getVisibility() != GONE) {
if (hasDividerBeforeChildAt(i)) {
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
@@ -577,8 +575,9 @@ public class LinearLayout extends ViewGroup {
* for an example.</p>
*
* @param index the child's index
- * @return the child at the specified index
+ * @return the child at the specified index, may be {@code null}
*/
+ @Nullable
View getVirtualChildAt(int index) {
return getChildAt(index);
}
@@ -659,7 +658,7 @@ public class LinearLayout extends ViewGroup {
*/
private boolean allViewsAreGoneBefore(int childIndex) {
for (int i = childIndex - 1; i >= 0; i--) {
- View child = getVirtualChildAt(i);
+ final View child = getVirtualChildAt(i);
if (child != null && child.getVisibility() != GONE) {
return false;
}
@@ -703,7 +702,6 @@ public class LinearLayout extends ViewGroup {
// See how tall everyone is. Also remember max width.
for (int i = 0; i < count; ++i) {
final View child = getVirtualChildAt(i);
-
if (child == null) {
mTotalLength += measureNullChild(i);
continue;
@@ -822,7 +820,6 @@ public class LinearLayout extends ViewGroup {
for (int i = 0; i < count; ++i) {
final View child = getVirtualChildAt(i);
-
if (child == null) {
mTotalLength += measureNullChild(i);
continue;
@@ -938,7 +935,6 @@ public class LinearLayout extends ViewGroup {
if (useLargestChild && heightMode != MeasureSpec.EXACTLY) {
for (int i = 0; i < count; i++) {
final View child = getVirtualChildAt(i);
-
if (child == null || child.getVisibility() == View.GONE) {
continue;
}
@@ -981,7 +977,7 @@ public class LinearLayout extends ViewGroup {
MeasureSpec.EXACTLY);
for (int i = 0; i< count; ++i) {
final View child = getVirtualChildAt(i);
- if (child.getVisibility() != GONE) {
+ if (child != null && child.getVisibility() != GONE) {
LinearLayout.LayoutParams lp = ((LinearLayout.LayoutParams)child.getLayoutParams());
if (lp.width == LayoutParams.MATCH_PARENT) {
@@ -1047,7 +1043,6 @@ public class LinearLayout extends ViewGroup {
// See how wide everyone is. Also remember max height.
for (int i = 0; i < count; ++i) {
final View child = getVirtualChildAt(i);
-
if (child == null) {
mTotalLength += measureNullChild(i);
continue;
@@ -1203,7 +1198,6 @@ public class LinearLayout extends ViewGroup {
for (int i = 0; i < count; ++i) {
final View child = getVirtualChildAt(i);
-
if (child == null) {
mTotalLength += measureNullChild(i);
continue;
@@ -1361,7 +1355,6 @@ public class LinearLayout extends ViewGroup {
if (useLargestChild && widthMode != MeasureSpec.EXACTLY) {
for (int i = 0; i < count; i++) {
final View child = getVirtualChildAt(i);
-
if (child == null || child.getVisibility() == View.GONE) {
continue;
}
@@ -1406,7 +1399,7 @@ public class LinearLayout extends ViewGroup {
MeasureSpec.EXACTLY);
for (int i = 0; i < count; ++i) {
final View child = getVirtualChildAt(i);
- if (child.getVisibility() != GONE) {
+ if (child != null && child.getVisibility() != GONE) {
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) child.getLayoutParams();
if (lp.height == LayoutParams.MATCH_PARENT) {
@@ -1666,9 +1659,8 @@ public class LinearLayout extends ViewGroup {
}
for (int i = 0; i < count; i++) {
- int childIndex = start + dir * i;
+ final int childIndex = start + dir * i;
final View child = getVirtualChildAt(childIndex);
-
if (child == null) {
childLeft += measureNullChild(childIndex);
} else if (child.getVisibility() != GONE) {
diff --git a/core/java/android/widget/OverScroller.java b/core/java/android/widget/OverScroller.java
index 9130d9a..50569d7 100644
--- a/core/java/android/widget/OverScroller.java
+++ b/core/java/android/widget/OverScroller.java
@@ -18,7 +18,6 @@ package android.widget;
import android.content.Context;
import android.hardware.SensorManager;
-import android.os.PowerManager;
import android.util.Log;
import android.view.ViewConfiguration;
import android.view.animation.AnimationUtils;
@@ -600,8 +599,6 @@ public class OverScroller {
private static final int CUBIC = 1;
private static final int BALLISTIC = 2;
- private final PowerManager mPm;
-
static {
float x_min = 0.0f;
float y_min = 0.0f;
@@ -646,7 +643,6 @@ public class OverScroller {
* 39.37f // inch/meter
* ppi
* 0.84f; // look and feel tuning
- mPm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
}
void updateScroll(float q) {
@@ -764,7 +760,6 @@ public class OverScroller {
if (velocity != 0) {
mDuration = mSplineDuration = getSplineFlingDuration(velocity);
totalDistance = getSplineFlingDistance(velocity);
- mPm.cpuBoost(mDuration * 1000);
}
mSplineDistance = (int) (totalDistance * Math.signum(velocity));
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 6c9c0e3..6a272e5 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -31,6 +31,7 @@ import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.ColorStateList;
import android.content.res.Configuration;
import android.content.res.Resources;
+import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.PorterDuff;
import android.graphics.Rect;
@@ -55,6 +56,8 @@ import android.view.ViewGroup;
import android.widget.AdapterView.OnItemClickListener;
import libcore.util.Objects;
+import com.android.internal.R;
+
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -206,14 +209,22 @@ public class RemoteViews implements Parcelable, Filter {
/** @hide */
public static class OnClickHandler {
+
+ private int mEnterAnimationId;
+
public boolean onClickHandler(View view, PendingIntent pendingIntent,
Intent fillInIntent) {
try {
// TODO: Unregister this handler if PendingIntent.FLAG_ONE_SHOT?
Context context = view.getContext();
- ActivityOptions opts = ActivityOptions.makeScaleUpAnimation(view,
- 0, 0,
- view.getMeasuredWidth(), view.getMeasuredHeight());
+ ActivityOptions opts;
+ if (mEnterAnimationId != 0) {
+ opts = ActivityOptions.makeCustomAnimation(context, mEnterAnimationId, 0);
+ } else {
+ opts = ActivityOptions.makeScaleUpAnimation(view,
+ 0, 0,
+ view.getMeasuredWidth(), view.getMeasuredHeight());
+ }
context.startIntentSender(
pendingIntent.getIntentSender(), fillInIntent,
Intent.FLAG_ACTIVITY_NEW_TASK,
@@ -228,6 +239,10 @@ public class RemoteViews implements Parcelable, Filter {
}
return true;
}
+
+ public void setEnterAnimationId(int enterAnimationId) {
+ mEnterAnimationId = enterAnimationId;
+ }
}
/**
@@ -2767,11 +2782,31 @@ public class RemoteViews implements Parcelable, Filter {
inflater.setFilter(this);
result = inflater.inflate(rvToApply.getLayoutId(), parent, false);
+ loadTransitionOverride(context, handler);
+
rvToApply.performApply(result, parent, handler);
return result;
}
+ private static void loadTransitionOverride(Context context,
+ RemoteViews.OnClickHandler handler) {
+ if (handler != null && context.getResources().getBoolean(
+ com.android.internal.R.bool.config_overrideRemoteViewsActivityTransition)) {
+ TypedArray windowStyle = context.getTheme().obtainStyledAttributes(
+ com.android.internal.R.styleable.Window);
+ int windowAnimations = windowStyle.getResourceId(
+ com.android.internal.R.styleable.Window_windowAnimationStyle, 0);
+ TypedArray windowAnimationStyle = context.obtainStyledAttributes(
+ windowAnimations, com.android.internal.R.styleable.WindowAnimation);
+ handler.setEnterAnimationId(windowAnimationStyle.getResourceId(
+ com.android.internal.R.styleable.
+ WindowAnimation_activityOpenRemoteViewsEnterAnimation, 0));
+ windowStyle.recycle();
+ windowAnimationStyle.recycle();
+ }
+ }
+
/**
* Applies all of the actions to the provided view.
*
diff --git a/core/java/android/widget/Scroller.java b/core/java/android/widget/Scroller.java
index a968eae..357c9c3 100644
--- a/core/java/android/widget/Scroller.java
+++ b/core/java/android/widget/Scroller.java
@@ -19,7 +19,6 @@ package android.widget;
import android.content.Context;
import android.hardware.SensorManager;
import android.os.Build;
-import android.os.PowerManager;
import android.view.ViewConfiguration;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
@@ -109,8 +108,6 @@ public class Scroller {
private float mDeceleration;
private final float mPpi;
- private final PowerManager mPm;
-
// A context-specific coefficient adjusted to physical values.
private float mPhysicalCoeff;
@@ -181,8 +178,6 @@ public class Scroller {
mFlywheel = flywheel;
mPhysicalCoeff = computeDeceleration(0.84f); // look and feel tuning
-
- mPm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
}
/**
@@ -400,8 +395,6 @@ public class Scroller {
mDeltaX = dx;
mDeltaY = dy;
mDurationReciprocal = 1.0f / (float) mDuration;
-
- mPm.cpuBoost(duration * 1000);
}
/**
diff --git a/core/java/android/widget/TableRow.java b/core/java/android/widget/TableRow.java
index f7f9c91..22931fc 100644
--- a/core/java/android/widget/TableRow.java
+++ b/core/java/android/widget/TableRow.java
@@ -98,7 +98,7 @@ public class TableRow extends LinearLayout {
* {@hide}
*/
void setColumnCollapsed(int columnIndex, boolean collapsed) {
- View child = getVirtualChildAt(columnIndex);
+ final View child = getVirtualChildAt(columnIndex);
if (child != null) {
child.setVisibility(collapsed ? GONE : VISIBLE);
}
diff --git a/core/java/android/widget/Toast.java b/core/java/android/widget/Toast.java
index 4b31af0..e8dccab 100644
--- a/core/java/android/widget/Toast.java
+++ b/core/java/android/widget/Toast.java
@@ -18,6 +18,7 @@ package android.widget;
import android.annotation.IntDef;
import android.annotation.StringRes;
+import android.app.ActivityManager;
import android.app.INotificationManager;
import android.app.ITransientNotification;
import android.content.Context;
@@ -405,14 +406,18 @@ public class Toast {
ImageView appIcon = (ImageView) mView.findViewById(android.R.id.icon);
if (appIcon != null) {
- PackageManager pm = context.getPackageManager();
- Drawable icon = null;
- try {
- icon = pm.getApplicationIcon(packageName);
- } catch (PackageManager.NameNotFoundException e) {
- // nothing to do
+ ActivityManager am =
+ (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
+ if (!am.isPackageInForeground(packageName)) {
+ PackageManager pm = context.getPackageManager();
+ Drawable icon = null;
+ try {
+ icon = pm.getApplicationIcon(packageName);
+ } catch (PackageManager.NameNotFoundException e) {
+ // nothing to do
+ }
+ appIcon.setImageDrawable(icon);
}
- appIcon.setImageDrawable(icon);
}
mWM = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
// We can resolve the Gravity here by using the Locale for getting
diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl
index 3cddbf6..ba92f48 100644
--- a/core/java/com/android/internal/app/IBatteryStats.aidl
+++ b/core/java/com/android/internal/app/IBatteryStats.aidl
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 2016 The CyanogenMod Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -121,4 +122,18 @@ interface IBatteryStats {
void setBatteryState(int status, int health, int plugType, int level, int temp, int volt);
long getAwakeTimeBattery();
long getAwakeTimePlugged();
+
+
+ /** @hide */
+ byte[] getDockStatistics();
+ /** @hide */
+ ParcelFileDescriptor getDockStatisticsStream();
+ /** @hide **/
+ void resetStatistics();
+ /** @hide **/
+ void setDockBatteryState(int status, int health, int plugType, int level, int temp, int volt);
+ /** @hide **/
+ long getAwakeTimeDockBattery();
+ /** @hide **/
+ long getAwakeTimeDockPlugged();
}
diff --git a/core/java/com/android/internal/os/BatteryStatsHelper.java b/core/java/com/android/internal/os/BatteryStatsHelper.java
index f178c8c..54a4e86 100644
--- a/core/java/com/android/internal/os/BatteryStatsHelper.java
+++ b/core/java/com/android/internal/os/BatteryStatsHelper.java
@@ -21,6 +21,7 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.SensorManager;
import android.net.ConnectivityManager;
+import android.os.BatteryManager;
import android.os.BatteryStats;
import android.os.BatteryStats.Uid;
import android.os.Bundle;
@@ -61,15 +62,18 @@ public final class BatteryStatsHelper {
private static final String TAG = BatteryStatsHelper.class.getSimpleName();
private static BatteryStats sStatsXfer;
+ private static BatteryStats sDockStatsXfer;
private static Intent sBatteryBroadcastXfer;
private static ArrayMap<File, BatteryStats> sFileXfer = new ArrayMap<>();
final private Context mContext;
+ final private BatteryManager mBatteryService;
final private boolean mCollectBatteryBroadcast;
final private boolean mWifiOnly;
private IBatteryStats mBatteryInfo;
private BatteryStats mStats;
+ private BatteryStats mDockStats;
private Intent mBatteryBroadcast;
private PowerProfile mPowerProfile;
@@ -160,19 +164,28 @@ public final class BatteryStatsHelper {
public BatteryStatsHelper(Context context, boolean collectBatteryBroadcast, boolean wifiOnly) {
mContext = context;
+ mBatteryService = ((BatteryManager) context.getSystemService(Context.BATTERY_SERVICE));
mCollectBatteryBroadcast = collectBatteryBroadcast;
mWifiOnly = wifiOnly;
}
public void storeStatsHistoryInFile(String fname) {
+ internalStoreStatsHistoryInFile(getStats(), fname);
+ }
+
+ public void storeDockStatsHistoryInFile(String fname) {
+ internalStoreStatsHistoryInFile(getDockStats(), fname);
+ }
+
+ public void internalStoreStatsHistoryInFile(BatteryStats stats, String fname) {
synchronized (sFileXfer) {
File path = makeFilePath(mContext, fname);
- sFileXfer.put(path, this.getStats());
+ sFileXfer.put(path, stats);
FileOutputStream fout = null;
try {
fout = new FileOutputStream(path);
Parcel hist = Parcel.obtain();
- getStats().writeToParcelWithoutUids(hist, 0);
+ stats.writeToParcelWithoutUids(hist, 0);
byte[] histData = hist.marshall();
fout.write(histData);
} catch (IOException e) {
@@ -229,18 +242,38 @@ public final class BatteryStatsHelper {
/** Clears the current stats and forces recreating for future use. */
public void clearStats() {
mStats = null;
+ mDockStats = null;
+ }
+
+ private void clearAllStats() {
+ clearStats();
+ sStatsXfer = null;
+ sDockStatsXfer = null;
+ sBatteryBroadcastXfer = null;
+ for (File f : sFileXfer.keySet()) {
+ f.delete();
+ }
+ sFileXfer.clear();
}
public BatteryStats getStats() {
if (mStats == null) {
- load();
+ loadStats();
}
return mStats;
}
+ public BatteryStats getDockStats() {
+ if (mDockStats == null) {
+ loadDockStats();
+ }
+ return mDockStats;
+ }
+
public Intent getBatteryBroadcast() {
if (mBatteryBroadcast == null && mCollectBatteryBroadcast) {
- load();
+ loadStats();
+ loadDockStats();
}
return mBatteryBroadcast;
}
@@ -257,6 +290,7 @@ public final class BatteryStatsHelper {
public void create(Bundle icicle) {
if (icicle != null) {
mStats = sStatsXfer;
+ mDockStats = sDockStatsXfer;
mBatteryBroadcast = sBatteryBroadcastXfer;
}
mBatteryInfo = IBatteryStats.Stub.asInterface(
@@ -266,6 +300,7 @@ public final class BatteryStatsHelper {
public void storeState() {
sStatsXfer = mStats;
+ sDockStatsXfer = mDockStats;
sBatteryBroadcastXfer = mBatteryBroadcast;
}
@@ -321,6 +356,7 @@ public final class BatteryStatsHelper {
long rawUptimeUs) {
// Initialize mStats if necessary.
getStats();
+ getDockStats();
mMaxPower = 0;
mMaxRealPower = 0;
@@ -739,7 +775,7 @@ public final class BatteryStatsHelper {
}
}
- private void load() {
+ private void loadStats() {
if (mBatteryInfo == null) {
return;
}
@@ -750,6 +786,26 @@ public final class BatteryStatsHelper {
}
}
+ private void loadDockStats() {
+ if (mBatteryInfo == null) {
+ return;
+ }
+ if (mBatteryService.isDockBatterySupported()) {
+ mDockStats = getDockStats(mBatteryInfo);
+ } else {
+ mDockStats = null;
+ }
+ }
+
+ public void resetStatistics() {
+ try {
+ clearAllStats();
+ mBatteryInfo.resetStatistics();
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException:", e);
+ }
+ }
+
private static BatteryStatsImpl getStats(IBatteryStats service) {
try {
ParcelFileDescriptor pfd = service.getStatisticsStream();
@@ -772,4 +828,27 @@ public final class BatteryStatsHelper {
}
return new BatteryStatsImpl();
}
+
+ private static BatteryStatsImpl getDockStats(IBatteryStats service) {
+ try {
+ ParcelFileDescriptor pfd = service.getDockStatisticsStream();
+ if (pfd != null) {
+ FileInputStream fis = new ParcelFileDescriptor.AutoCloseInputStream(pfd);
+ try {
+ byte[] data = readFully(fis, MemoryFile.getSize(pfd.getFileDescriptor()));
+ Parcel parcel = Parcel.obtain();
+ parcel.unmarshall(data, 0, data.length);
+ parcel.setDataPosition(0);
+ BatteryStatsImpl stats = com.android.internal.os.DockBatteryStatsImpl.CREATOR
+ .createFromParcel(parcel);
+ return stats;
+ } catch (IOException e) {
+ Log.w(TAG, "Unable to read statistics stream", e);
+ }
+ }
+ } catch (RemoteException e) {
+ Log.w(TAG, "RemoteException:", e);
+ }
+ return new BatteryStatsImpl();
+ }
}
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 64b7768..d0a169e 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2006-2007 The Android Open Source Project
+ * Copyright (C) 2016 The CyanogenMod Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -91,7 +92,7 @@ import java.util.concurrent.locks.ReentrantLock;
* battery life. All times are represented in microseconds except where indicated
* otherwise.
*/
-public final class BatteryStatsImpl extends BatteryStats {
+public class BatteryStatsImpl extends BatteryStats {
private static final String TAG = "BatteryStatsImpl";
private static final boolean DEBUG = false;
public static final boolean DEBUG_ENERGY = false;
@@ -105,7 +106,7 @@ public final class BatteryStatsImpl extends BatteryStats {
private static final int MAGIC = 0xBA757475; // 'BATSTATS'
// Current on-disk Parcel version
- private static final int VERSION = 132 + (USE_OLD_HISTORY ? 1000 : 0);
+ private static final int VERSION = 133 + (USE_OLD_HISTORY ? 1000 : 0);
// Maximum number of items we will record in the history.
private static final int MAX_HISTORY_ITEMS = 2000;
@@ -1968,8 +1969,14 @@ public final class BatteryStatsImpl extends BatteryStats {
private int buildBatteryLevelInt(HistoryItem h) {
return ((((int)h.batteryLevel)<<25)&0xfe000000)
- | ((((int)h.batteryTemperature)<<14)&0x01ff8000)
- | ((((int)h.batteryVoltage)<<1)&0x00007fff);
+ | ((((int)h.batteryTemperature)<<15)&0x01ff8000)
+ | ((((int)h.batteryVoltage)<<1)&0x00007ffe);
+ }
+
+ private void readBatteryLevelInt(int batteryLevelInt, HistoryItem out) {
+ out.batteryLevel = (byte)((batteryLevelInt & 0xfe000000) >>> 25);
+ out.batteryTemperature = (short)((batteryLevelInt & 0x01ff8000) >>> 15);
+ out.batteryVoltage = (char)((batteryLevelInt & 0x00007ffe) >>> 1);
}
private int buildStateInt(HistoryItem h) {
@@ -2110,9 +2117,7 @@ public final class BatteryStatsImpl extends BatteryStats {
final int batteryLevelInt;
if ((firstToken&DELTA_BATTERY_LEVEL_FLAG) != 0) {
batteryLevelInt = src.readInt();
- cur.batteryLevel = (byte)((batteryLevelInt>>25)&0x7f);
- cur.batteryTemperature = (short)((batteryLevelInt<<7)>>21);
- cur.batteryVoltage = (char)(batteryLevelInt&0x3fff);
+ readBatteryLevelInt(batteryLevelInt, cur);
cur.numReadInts += 1;
if (DEBUG) Slog.i(TAG, "READ DELTA: batteryToken=0x"
+ Integer.toHexString(batteryLevelInt)
@@ -6839,13 +6844,13 @@ public final class BatteryStatsImpl extends BatteryStats {
public BatteryStatsImpl(File systemDir, Handler handler, ExternalStatsSync externalSync) {
if (systemDir != null) {
- mFile = new JournaledFile(new File(systemDir, "batterystats.bin"),
- new File(systemDir, "batterystats.bin.tmp"));
+ mFile = new JournaledFile(new File(systemDir, getStatsName() + ".bin"),
+ new File(systemDir, getStatsName() + ".bin.tmp"));
} else {
mFile = null;
}
- mCheckinFile = new AtomicFile(new File(systemDir, "batterystats-checkin.bin"));
- mDailyFile = new AtomicFile(new File(systemDir, "batterystats-daily.xml"));
+ mCheckinFile = new AtomicFile(new File(systemDir, getStatsName() + "-checkin.bin"));
+ mDailyFile = new AtomicFile(new File(systemDir, getStatsName () + "-daily.xml"));
mExternalSync = externalSync;
mHandler = new MyHandler(handler.getLooper());
mStartCount++;
@@ -6921,6 +6926,16 @@ public final class BatteryStatsImpl extends BatteryStats {
readFromParcel(p);
}
+ /** @hide */
+ protected String getStatsName() {
+ return "batterystats";
+ }
+
+ /** @hide */
+ protected String getLogName() {
+ return "BatteryStats";
+ }
+
public void setPowerProfile(PowerProfile profile) {
synchronized (this) {
mPowerProfile = profile;
@@ -7699,26 +7714,35 @@ public final class BatteryStatsImpl extends BatteryStats {
}
final Uid u = getUidStatsLocked(mapUid(entry.uid));
- u.noteNetworkActivityLocked(NETWORK_WIFI_RX_DATA, entry.rxBytes,
- entry.rxPackets);
- u.noteNetworkActivityLocked(NETWORK_WIFI_TX_DATA, entry.txBytes,
- entry.txPackets);
- rxPackets.put(u.getUid(), entry.rxPackets);
- txPackets.put(u.getUid(), entry.txPackets);
+ if (entry.rxBytes != 0) {
+ u.noteNetworkActivityLocked(NETWORK_WIFI_RX_DATA, entry.rxBytes,
+ entry.rxPackets);
+ mNetworkByteActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked(
+ entry.rxBytes);
+ mNetworkPacketActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked(
+ entry.rxPackets);
- // Sum the total number of packets so that the Rx Power and Tx Power can
- // be evenly distributed amongst the apps.
- totalRxPackets += entry.rxPackets;
- totalTxPackets += entry.txPackets;
+ rxPackets.put(u.getUid(), entry.rxPackets);
- mNetworkByteActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked(
- entry.rxBytes);
- mNetworkByteActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked(
- entry.txBytes);
- mNetworkPacketActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked(
- entry.rxPackets);
- mNetworkPacketActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked(
- entry.txPackets);
+ // Sum the total number of packets so that the Rx Power can
+ // be evenly distributed amongst the apps.
+ totalRxPackets += entry.rxPackets;
+ }
+
+ if (entry.txBytes != 0) {
+ u.noteNetworkActivityLocked(NETWORK_WIFI_TX_DATA, entry.txBytes,
+ entry.txPackets);
+ mNetworkByteActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked(
+ entry.txBytes);
+ mNetworkPacketActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked(
+ entry.txPackets);
+
+ txPackets.put(u.getUid(), entry.txPackets);
+
+ // Sum the total number of packets so that the Tx Power can
+ // be evenly distributed amongst the apps.
+ totalTxPackets += entry.txPackets;
+ }
}
}
@@ -8434,7 +8458,13 @@ public final class BatteryStatsImpl extends BatteryStats {
public void setBatteryStateLocked(int status, int health, int plugType, int level,
int temp, int volt) {
- final boolean onBattery = plugType == BATTERY_PLUGGED_NONE;
+ // We need to add a extra check over the status because of dock batteries
+ // PlugType doesn't means that the dock battery is charging (some devices
+ // doesn't charge under dock usb)
+ boolean onBattery = plugType == BATTERY_PLUGGED_NONE &&
+ (status != BatteryManager.BATTERY_STATUS_CHARGING ||
+ status != BatteryManager.BATTERY_STATUS_FULL);
+
final long uptime = SystemClock.uptimeMillis();
final long elapsedRealtime = SystemClock.elapsedRealtime();
if (!mHaveBatteryLevel) {
diff --git a/core/java/com/android/internal/os/DockBatteryStatsImpl.java b/core/java/com/android/internal/os/DockBatteryStatsImpl.java
new file mode 100644
index 0000000..6099ad2
--- /dev/null
+++ b/core/java/com/android/internal/os/DockBatteryStatsImpl.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2016 The CyanogenMod Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.os;
+
+import android.os.Handler;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.io.File;
+
+public final class DockBatteryStatsImpl extends BatteryStatsImpl {
+ public DockBatteryStatsImpl() {
+ super();
+ }
+
+ public DockBatteryStatsImpl(Parcel p) {
+ super(p);
+ }
+
+ public DockBatteryStatsImpl(File systemDir, Handler handler, ExternalStatsSync externalSync) {
+ super(systemDir, handler, externalSync);
+ }
+
+ protected String getStatsName() {
+ return "dockbatterystats";
+ }
+
+ protected String getLogName() {
+ return "DockBatteryStats";
+ }
+
+ public static final Parcelable.Creator<DockBatteryStatsImpl> CREATOR =
+ new Parcelable.Creator<DockBatteryStatsImpl>() {
+ public DockBatteryStatsImpl createFromParcel(Parcel in) {
+ return new DockBatteryStatsImpl(in);
+ }
+
+ public DockBatteryStatsImpl[] newArray(int size) {
+ return new DockBatteryStatsImpl[size];
+ }
+ };
+}
diff --git a/core/java/com/android/internal/os/KernelCpuSpeedReader.java b/core/java/com/android/internal/os/KernelCpuSpeedReader.java
index 5b776ac..3f6ebb9 100644
--- a/core/java/com/android/internal/os/KernelCpuSpeedReader.java
+++ b/core/java/com/android/internal/os/KernelCpuSpeedReader.java
@@ -16,8 +16,11 @@
package com.android.internal.os;
import android.text.TextUtils;
+import android.system.OsConstants;
import android.util.Slog;
+import libcore.io.Libcore;
+
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
@@ -29,7 +32,7 @@ import java.util.Arrays;
*
* freq time
*
- * where time is measured in 1/100 seconds.
+ * where time is measured in jiffies.
*/
public class KernelCpuSpeedReader {
private static final String TAG = "KernelCpuSpeedReader";
@@ -38,6 +41,9 @@ public class KernelCpuSpeedReader {
private final long[] mLastSpeedTimes;
private final long[] mDeltaSpeedTimes;
+ // How long a CPU jiffy is in milliseconds.
+ private final long mJiffyMillis;
+
/**
* @param cpuNumber The cpu (cpu0, cpu1, etc) whose state to read.
*/
@@ -46,6 +52,8 @@ public class KernelCpuSpeedReader {
cpuNumber);
mLastSpeedTimes = new long[numSpeedSteps];
mDeltaSpeedTimes = new long[numSpeedSteps];
+ long jiffyHz = Libcore.os.sysconf(OsConstants._SC_CLK_TCK);
+ mJiffyMillis = 1000/jiffyHz;
}
/**
@@ -62,8 +70,7 @@ public class KernelCpuSpeedReader {
splitter.setString(line);
Long.parseLong(splitter.next());
- // The proc file reports time in 1/100 sec, so convert to milliseconds.
- long time = Long.parseLong(splitter.next()) * 10;
+ long time = Long.parseLong(splitter.next()) * mJiffyMillis;
if (time < mLastSpeedTimes[speedIndex]) {
// The stats reset when the cpu hotplugged. That means that the time
// we read is offset from 0, so the time is the delta.
diff --git a/core/java/com/android/internal/os/ProcessCpuTracker.java b/core/java/com/android/internal/os/ProcessCpuTracker.java
index bf97f1f..d831902 100644
--- a/core/java/com/android/internal/os/ProcessCpuTracker.java
+++ b/core/java/com/android/internal/os/ProcessCpuTracker.java
@@ -67,10 +67,10 @@ public class ProcessCpuTracker {
static final int PROCESS_STAT_UTIME = 2;
static final int PROCESS_STAT_STIME = 3;
- /** Stores user time and system time in 100ths of a second. */
+ /** Stores user time and system time in jiffies. */
private final long[] mProcessStatsData = new long[4];
- /** Stores user time and system time in 100ths of a second. Used for
+ /** Stores user time and system time in jiffies. Used for
* public API to retrieve CPU use for a process. Must lock while in use. */
private final long[] mSinglePidStatsData = new long[4];
diff --git a/core/java/com/android/internal/os/RuntimeInit.java b/core/java/com/android/internal/os/RuntimeInit.java
index f81658e..3377189 100644
--- a/core/java/com/android/internal/os/RuntimeInit.java
+++ b/core/java/com/android/internal/os/RuntimeInit.java
@@ -19,6 +19,7 @@ package com.android.internal.os;
import android.app.ActivityManagerNative;
import android.app.ActivityThread;
import android.app.ApplicationErrorReport;
+import android.content.res.ThemeConfig;
import android.os.Build;
import android.os.Debug;
import android.os.IBinder;
@@ -83,6 +84,10 @@ public class RuntimeInit {
message.append("Process: ").append(processName).append(", ");
}
message.append("PID: ").append(Process.myPid());
+ final ThemeConfig themeConfig =
+ ActivityManagerNative.getDefault().getConfiguration().themeConfig;
+ message.append("\nTheme: ").append(themeConfig == null ?
+ ThemeConfig.SYSTEM_DEFAULT : themeConfig);
Clog_e(TAG, message.toString(), e);
}
diff --git a/core/java/com/android/internal/util/StateMachine.java b/core/java/com/android/internal/util/StateMachine.java
index 447292c..be78a12 100644
--- a/core/java/com/android/internal/util/StateMachine.java
+++ b/core/java/com/android/internal/util/StateMachine.java
@@ -1879,6 +1879,33 @@ public class StateMachine {
}
/**
+ * Check if there are any pending messages with code 'what' in deferred messages queue.
+ */
+ protected final boolean hasDeferredMessages(int what) {
+ SmHandler smh = mSmHandler;
+ if (smh == null) return false;
+
+ Iterator<Message> iterator = smh.mDeferredMessages.iterator();
+ while (iterator.hasNext()) {
+ Message msg = iterator.next();
+ if (msg.what == what) return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Check if there are any pending posts of messages with code 'what' in
+ * the message queue. This does NOT check messages in deferred message queue.
+ */
+ protected final boolean hasMessages(int what) {
+ SmHandler smh = mSmHandler;
+ if (smh == null) return false;
+
+ return smh.hasMessages(what);
+ }
+
+ /**
* Validate that the message was sent by
* {@link StateMachine#quit} or {@link StateMachine#quitNow}.
* */
diff --git a/core/java/com/android/internal/util/cm/ImageUtils.java b/core/java/com/android/internal/util/cm/ImageUtils.java
deleted file mode 100644
index 73189a3..0000000
--- a/core/java/com/android/internal/util/cm/ImageUtils.java
+++ /dev/null
@@ -1,332 +0,0 @@
-/*
- * Copyright (C) 2013-2014 The CyanogenMod Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.util.cm;
-
-import android.app.WallpaperManager;
-import android.content.Context;
-import android.content.pm.ThemeUtils;
-import android.content.res.AssetManager;
-import android.database.Cursor;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Point;
-import android.net.Uri;
-import android.provider.ThemesContract;
-import android.provider.ThemesContract.ThemesColumns;
-import android.text.TextUtils;
-import android.util.Log;
-import android.webkit.URLUtil;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.InputStream;
-
-import libcore.io.IoUtils;
-
-public class ImageUtils {
- private static final String TAG = ImageUtils.class.getSimpleName();
-
- private static final String ASSET_URI_PREFIX = "file:///android_asset/";
- private static final int DEFAULT_IMG_QUALITY = 100;
-
- /**
- * Gets the Width and Height of the image
- *
- * @param inputStream The input stream of the image
- *
- * @return A point structure that holds the Width and Height (x and y)/*"
- */
- public static Point getImageDimension(InputStream inputStream) {
- if (inputStream == null) {
- throw new IllegalArgumentException("'inputStream' cannot be null!");
- }
- BitmapFactory.Options options = new BitmapFactory.Options();
- options.inJustDecodeBounds = true;
- BitmapFactory.decodeStream(inputStream, null, options);
- Point point = new Point(options.outWidth,options.outHeight);
- return point;
- }
-
- /**
- * Crops the input image and returns a new InputStream of the cropped area
- *
- * @param inputStream The input stream of the image
- * @param imageWidth Width of the input image
- * @param imageHeight Height of the input image
- * @param inputStream Desired Width
- * @param inputStream Desired Width
- *
- * @return a new InputStream of the cropped area/*"
- */
- public static InputStream cropImage(InputStream inputStream, int imageWidth, int imageHeight,
- int outWidth, int outHeight) throws IllegalArgumentException {
- if (inputStream == null){
- throw new IllegalArgumentException("inputStream cannot be null");
- }
-
- if (imageWidth <= 0 || imageHeight <= 0) {
- throw new IllegalArgumentException(
- String.format("imageWidth and imageHeight must be > 0: imageWidth=%d" +
- " imageHeight=%d", imageWidth, imageHeight));
- }
-
- if (outWidth <= 0 || outHeight <= 0) {
- throw new IllegalArgumentException(
- String.format("outWidth and outHeight must be > 0: outWidth=%d" +
- " outHeight=%d", imageWidth, outHeight));
- }
-
- int scaleDownSampleSize = Math.min(imageWidth / outWidth, imageHeight / outHeight);
- if (scaleDownSampleSize > 0) {
- imageWidth /= scaleDownSampleSize;
- imageHeight /= scaleDownSampleSize;
- } else {
- float ratio = (float) outWidth / outHeight;
- if (imageWidth < imageHeight * ratio) {
- outWidth = imageWidth;
- outHeight = (int) (outWidth / ratio);
- } else {
- outHeight = imageHeight;
- outWidth = (int) (outHeight * ratio);
- }
- }
- int left = (imageWidth - outWidth) / 2;
- int top = (imageHeight - outHeight) / 2;
- InputStream compressed = null;
- try {
- BitmapFactory.Options options = new BitmapFactory.Options();
- if (scaleDownSampleSize > 1) {
- options.inSampleSize = scaleDownSampleSize;
- }
- Bitmap bitmap = BitmapFactory.decodeStream(inputStream, null, options);
- if (bitmap == null) {
- return null;
- }
- Bitmap cropped = Bitmap.createBitmap(bitmap, left, top, outWidth, outHeight);
- ByteArrayOutputStream tmpOut = new ByteArrayOutputStream(2048);
- if (cropped.compress(Bitmap.CompressFormat.PNG, DEFAULT_IMG_QUALITY, tmpOut)) {
- byte[] outByteArray = tmpOut.toByteArray();
- compressed = new ByteArrayInputStream(outByteArray);
- }
- } catch (Exception e) {
- Log.e(TAG, "Exception " + e);
- }
- return compressed;
- }
-
- /**
- * Crops the lock screen image and returns a new InputStream of the cropped area
- *
- * @param pkgName Name of the theme package
- * @param context The context
- *
- * @return a new InputStream of the cropped image/*"
- */
- public static InputStream getCroppedKeyguardStream(String pkgName, Context context)
- throws IllegalArgumentException {
- if (TextUtils.isEmpty(pkgName)) {
- throw new IllegalArgumentException("'pkgName' cannot be null or empty!");
- }
- if (context == null) {
- throw new IllegalArgumentException("'context' cannot be null!");
- }
-
- InputStream cropped = null;
- InputStream stream = null;
- try {
- stream = getOriginalKeyguardStream(pkgName, context);
- if (stream == null) {
- return null;
- }
- Point point = getImageDimension(stream);
- IoUtils.closeQuietly(stream);
- if (point == null || point.x == 0 || point.y == 0) {
- return null;
- }
- WallpaperManager wm = WallpaperManager.getInstance(context);
- int outWidth = wm.getDesiredMinimumWidth();
- int outHeight = wm.getDesiredMinimumHeight();
- stream = getOriginalKeyguardStream(pkgName, context);
- if (stream == null) {
- return null;
- }
- cropped = cropImage(stream, point.x, point.y, outWidth, outHeight);
- } catch (Exception e) {
- Log.e(TAG, "Exception " + e);
- } finally {
- IoUtils.closeQuietly(stream);
- }
- return cropped;
- }
-
- /**
- * Crops the wallpaper image and returns a new InputStream of the cropped area
- *
- * @param pkgName Name of the theme package
- * @param context The context
- *
- * @return a new InputStream of the cropped image/*"
- */
- public static InputStream getCroppedWallpaperStream(String pkgName, long wallpaperId,
- Context context) {
- if (TextUtils.isEmpty(pkgName)) {
- throw new IllegalArgumentException("'pkgName' cannot be null or empty!");
- }
- if (context == null) {
- throw new IllegalArgumentException("'context' cannot be null!");
- }
-
- InputStream cropped = null;
- InputStream stream = null;
- try {
- stream = getOriginalWallpaperStream(pkgName, wallpaperId, context);
- if (stream == null) {
- return null;
- }
- Point point = getImageDimension(stream);
- IoUtils.closeQuietly(stream);
- if (point == null || point.x == 0 || point.y == 0) {
- return null;
- }
- WallpaperManager wm = WallpaperManager.getInstance(context);
- int outWidth = wm.getDesiredMinimumWidth();
- int outHeight = wm.getDesiredMinimumHeight();
- stream = getOriginalWallpaperStream(pkgName, wallpaperId, context);
- if (stream == null) {
- return null;
- }
- cropped = cropImage(stream, point.x, point.y, outWidth, outHeight);
- } catch (Exception e) {
- Log.e(TAG, "Exception " + e);
- } finally {
- IoUtils.closeQuietly(stream);
- }
- return cropped;
- }
-
- private static InputStream getOriginalKeyguardStream(String pkgName, Context context) {
- if (TextUtils.isEmpty(pkgName) || context == null) {
- return null;
- }
-
- InputStream inputStream = null;
- try {
- //Get input WP stream from the theme
- Context themeCtx = context.createPackageContext(pkgName,
- Context.CONTEXT_IGNORE_SECURITY);
- AssetManager assetManager = themeCtx.getAssets();
- String wpPath = ThemeUtils.getLockscreenWallpaperPath(assetManager);
- if (wpPath == null) {
- Log.w(TAG, "Not setting lockscreen wp because wallpaper file was not found.");
- } else {
- inputStream = ThemeUtils.getInputStreamFromAsset(themeCtx,
- ASSET_URI_PREFIX + wpPath);
- }
- } catch (Exception e) {
- Log.e(TAG, "There was an error setting lockscreen wp for pkg " + pkgName, e);
- }
- return inputStream;
- }
-
- private static InputStream getOriginalWallpaperStream(String pkgName, long componentId,
- Context context) {
- String wpPath;
- if (TextUtils.isEmpty(pkgName) || context == null) {
- return null;
- }
-
- InputStream inputStream = null;
- String selection = ThemesContract.ThemesColumns.PKG_NAME + "= ?";
- String[] selectionArgs = {pkgName};
- Cursor c = context.getContentResolver().query(ThemesColumns.CONTENT_URI,
- null, selection,
- selectionArgs, null);
- if (c == null || c.getCount() < 1) {
- if (c != null) c.close();
- return null;
- } else {
- c.moveToFirst();
- }
-
- try {
- Context themeContext = context.createPackageContext(pkgName,
- Context.CONTEXT_IGNORE_SECURITY);
- boolean isLegacyTheme = c.getInt(
- c.getColumnIndex(ThemesColumns.IS_LEGACY_THEME)) == 1;
- String wallpaper = c.getString(
- c.getColumnIndex(ThemesColumns.WALLPAPER_URI));
- if (wallpaper != null) {
- if (URLUtil.isAssetUrl(wallpaper)) {
- inputStream = ThemeUtils.getInputStreamFromAsset(themeContext, wallpaper);
- } else {
- inputStream = context.getContentResolver().openInputStream(
- Uri.parse(wallpaper));
- }
- } else {
- // try and get the wallpaper directly from the apk if the URI was null
- Context themeCtx = context.createPackageContext(pkgName,
- Context.CONTEXT_IGNORE_SECURITY);
- AssetManager assetManager = themeCtx.getAssets();
- wpPath = queryWpPathFromComponentId(context, pkgName, componentId);
- if (wpPath == null) wpPath = ThemeUtils.getWallpaperPath(assetManager);
- if (wpPath == null) {
- Log.e(TAG, "Not setting wp because wallpaper file was not found.");
- } else {
- inputStream = ThemeUtils.getInputStreamFromAsset(themeCtx,
- ASSET_URI_PREFIX + wpPath);
- }
- }
- } catch (Exception e) {
- Log.e(TAG, "getWallpaperStream: " + e);
- } finally {
- c.close();
- }
-
- return inputStream;
- }
-
- private static String queryWpPathFromComponentId(Context context, String pkgName,
- long componentId) {
- String wpPath = null;
- String[] projection = new String[] { ThemesContract.PreviewColumns.COL_VALUE };
- String selection = ThemesColumns.PKG_NAME + "=? AND " +
- ThemesContract.PreviewColumns.COMPONENT_ID + "=? AND " +
- ThemesContract.PreviewColumns.COL_KEY + "=?";
- String[] selectionArgs = new String[] {
- pkgName,
- Long.toString(componentId),
- ThemesContract.PreviewColumns.WALLPAPER_FULL
- };
-
- Cursor c = context.getContentResolver()
- .query(ThemesContract.PreviewColumns.COMPONENTS_URI,
- projection, selection, selectionArgs, null);
- if (c != null) {
- try {
- if (c.moveToFirst()) {
- int valIdx = c.getColumnIndex(ThemesContract.PreviewColumns.COL_VALUE);
- wpPath = c.getString(valIdx);
- }
- } catch(Exception e) {
- Log.e(TAG, "Could not get wallpaper path", e);
- } finally {
- c.close();
- }
- }
- return wpPath;
- }
-}
-
diff --git a/core/java/com/android/internal/util/gesture/EdgeGesturePosition.java b/core/java/com/android/internal/util/gesture/EdgeGesturePosition.java
deleted file mode 100644
index 01cfdea..0000000
--- a/core/java/com/android/internal/util/gesture/EdgeGesturePosition.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2013 The CyanogenMod Project (Jens Doll)
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.android.internal.util.gesture;
-
-/**
- * Defines the positions in which gestures may be recognized by the
- * edge gesture service.
- * This defines an index and an flag for each position.
- */
-public enum EdgeGesturePosition {
- LEFT(0, 0),
- BOTTOM(1, 1),
- RIGHT(2, 1),
- TOP(3, 0);
-
- EdgeGesturePosition(int index, int factor) {
- INDEX = index;
- FLAG = (0x01<<index);
- FACTOR = factor;
- }
-
- public final int INDEX;
- public final int FLAG;
- /**
- * This is 1 when the position is not at the axis (like {@link EdgeGesturePosition.RIGHT} is
- * at {@code Layout.getWidth()} not at {@code 0}).
- */
- public final int FACTOR;
-}
diff --git a/core/java/com/android/internal/util/gesture/EdgeServiceConstants.java b/core/java/com/android/internal/util/gesture/EdgeServiceConstants.java
deleted file mode 100644
index 4360086..0000000
--- a/core/java/com/android/internal/util/gesture/EdgeServiceConstants.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2013 The CyanogenMod Project (Jens Doll)
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.android.internal.util.gesture;
-
-/**
- * Constants needed for the edge gesture service.
- *
- * @see com.android.internal.util.gesture.EdgeGesturePosition
- */
-public final class EdgeServiceConstants {
-
- private EdgeServiceConstants() {
- // no object allowed
- }
-
- /**
- * Mask for coding positions within the flags of
- * {@code updateEdgeGestureActivationListener()}.
- * <p>
- * Positions are specified by {@code EdgeGesturePosition.FLAG}.
- */
- public static final int POSITION_MASK = 0x0000001f;
-
- /**
- * Mask for coding sensitivity within the flags of
- * {@code updateEdgeGestureActivationListener()}.
- * <p>
- * Sensitivity influences the speed of the swipe, the trigger area, and trigger distance that
- * is needed to activate the edge gesture.
- */
- public static final int SENSITIVITY_MASK = 0x70000000;
-
- /**
- * Number of bits to shift left, to get a integer within the {@link #SENSITIVITY_MASK}.
- */
- public static final int SENSITIVITY_SHIFT = 28;
-
- /**
- * No sensitivity specified at all, the service may choose a sensitivity level on its own.
- */
- public static final int SENSITIVITY_NONE = 0;
-
- /**
- * Default sensitivity, picked by the edge gesture service automatically.
- */
- public static final int SENSITIVITY_DEFAULT = 2;
-
- /**
- * Lowest valid sensitivity value.
- */
- public static final int SENSITIVITY_LOWEST = 1;
-
- /**
- * Highest sensitivity value.
- */
- public static final int SENSITIVITY_HIGHEST = 4;
-
- /**
- * Do not cut 10% area on th edges
- */
- public static final int UNRESTRICTED = 0x10;
-
- /**
- * This listener does not likes enabling/disabling filter
- * because it interrupt in motion events.
- */
- public static final int LONG_LIVING = 0x20;
-
-}
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index be827a4..d9c2a92 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -64,6 +64,11 @@ public class LockPatternUtils {
private static final boolean DEBUG = false;
/**
+ * The key to identify when the lock pattern enabled flag is being acccessed for legacy reasons.
+ */
+ public static final String LEGACY_LOCK_PATTERN_ENABLED = "legacy_lock_pattern_enabled";
+
+ /**
* The number of incorrect attempts before which we fall back on an alternative
* method of verifying the user, and resetting their lock pattern.
*/
@@ -1011,6 +1016,19 @@ public class LockPatternUtils {
return isLockPatternEnabled(getKeyguardStoredPasswordQuality(userId), userId);
}
+ @Deprecated
+ public boolean isLegacyLockPatternEnabled(int userId) {
+ // Note: this value should default to {@code true} to avoid any reset that might result.
+ // We must use a special key to read this value, since it will by default return the value
+ // based on the new logic.
+ return getBoolean(LEGACY_LOCK_PATTERN_ENABLED, true, userId);
+ }
+
+ @Deprecated
+ public void setLegacyLockPatternEnabled(int userId) {
+ setBoolean(Settings.Secure.LOCK_PATTERN_ENABLED, true, userId);
+ }
+
private boolean isLockPatternEnabled(int mode, int userId) {
return mode == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING
&& savedPatternExists(userId);
diff --git a/core/java/com/android/internal/widget/SwipeDismissLayout.java b/core/java/com/android/internal/widget/SwipeDismissLayout.java
index 35ed63b..d88f479 100644
--- a/core/java/com/android/internal/widget/SwipeDismissLayout.java
+++ b/core/java/com/android/internal/widget/SwipeDismissLayout.java
@@ -89,14 +89,21 @@ public class SwipeDismissLayout extends FrameLayout {
}
};
private BroadcastReceiver mScreenOffReceiver = new BroadcastReceiver() {
+ private Runnable mRunnable = new Runnable() {
+ @Override
+ public void run() {
+ if (mDismissed) {
+ dismiss();
+ } else {
+ cancel();
+ }
+ resetMembers();
+ }
+ };
+
@Override
public void onReceive(Context context, Intent intent) {
- if (mDismissed) {
- dismiss();
- } else {
- cancel();
- }
- resetMembers();
+ post(mRunnable);
}
};
private IntentFilter mScreenOffFilter = new IntentFilter(Intent.ACTION_SCREEN_OFF);