Merge "Correctly use ByteBuffer in UsbRequest"
diff --git a/Android.mk b/Android.mk
index 561d220..b549dde 100644
--- a/Android.mk
+++ b/Android.mk
@@ -241,6 +241,10 @@
core/java/android/os/IUpdateLock.aidl \
core/java/android/os/IUserManager.aidl \
core/java/android/os/IVibratorService.aidl \
+ core/java/android/os/storage/IMountService.aidl \
+ core/java/android/os/storage/IMountServiceListener.aidl \
+ core/java/android/os/storage/IMountShutdownObserver.aidl \
+ core/java/android/os/storage/IObbActionListener.aidl \
core/java/android/security/IKeystoreService.aidl \
core/java/android/security/keymaster/IKeyAttestationApplicationIdProvider.aidl \
core/java/android/service/carrier/ICarrierService.aidl \
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java
index 5d1cd3b..8124232 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -2849,6 +2849,17 @@
return mAnimationInfo.mEnterTransitionPostponed;
}
+ boolean isHideReplaced() {
+ if (mAnimationInfo == null) {
+ return false;
+ }
+ return mAnimationInfo.mIsHideReplaced;
+ }
+
+ void setHideReplaced(boolean replaced) {
+ ensureAnimationInfo().mIsHideReplaced = replaced;
+ }
+
/**
* Used internally to be notified when {@link #startPostponedEnterTransition()} has
* been called. This listener will only be called once and then be removed from the
@@ -2902,7 +2913,7 @@
// be set to null
OnStartEnterTransitionListener mStartEnterTransitionListener;
- // True if the View was added, and its animation has yet to be run.
- boolean mIsNewlyAdded;
+ // True if the View was hidden, but the transition is handling the hide
+ boolean mIsHideReplaced;
}
}
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index 9345a03..233fee7 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -1185,23 +1185,32 @@
if (anim != null) {
anim.setTarget(fragment.mView);
if (fragment.mHidden) {
- // Delay the actual hide operation until the animation finishes, otherwise
- // the fragment will just immediately disappear
- anim.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- animation.removeListener(this);
- if (fragment.mView != null) {
- fragment.mView.setVisibility(View.GONE);
+ if (fragment.isHideReplaced()) {
+ fragment.setHideReplaced(false);
+ } else {
+ // Delay the actual hide operation until the animation finishes, otherwise
+ // the fragment will just immediately disappear
+ anim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ animation.removeListener(this);
+ if (fragment.mView != null) {
+ fragment.mView.setVisibility(View.GONE);
+ }
}
- }
- });
+ });
+ }
}
setHWLayerAnimListenerIfAlpha(fragment.mView, anim);
anim.start();
} else {
- final int visibility = fragment.mHidden ? View.GONE : View.VISIBLE;
+ final int visibility = fragment.mHidden && !fragment.isHideReplaced()
+ ? View.GONE
+ : View.VISIBLE;
fragment.mView.setVisibility(visibility);
+ if (fragment.isHideReplaced()) {
+ fragment.setHideReplaced(false);
+ }
}
}
if (fragment.mAdded && fragment.mHasMenu && fragment.mMenuVisible) {
diff --git a/core/java/android/app/FragmentTransition.java b/core/java/android/app/FragmentTransition.java
index 6f52114..d27dff5 100644
--- a/core/java/android/app/FragmentTransition.java
+++ b/core/java/android/app/FragmentTransition.java
@@ -222,6 +222,7 @@
sharedElementTransition, inFragment, inIsPop);
if (transition != null) {
+ replaceHide(exitTransition, outFragment, exitingViews);
transition.setNameOverrides(nameOverrides);
scheduleRemoveTargets(transition,
enterTransition, enteringViews, exitTransition, exitingViews,
@@ -309,6 +310,38 @@
}
/**
+ * Replace hide operations with visibility changes on the exiting views. Instead of making
+ * the entire fragment's view GONE, make each exiting view INVISIBLE. At the end of the
+ * transition, make the fragment's view GONE.
+ */
+ private static void replaceHide(Transition exitTransition, Fragment exitingFragment,
+ final ArrayList<View> exitingViews) {
+ if (exitingFragment != null && exitTransition != null && exitingFragment.mAdded
+ && exitingFragment.mHidden && exitingFragment.mHiddenChanged) {
+ exitingFragment.setHideReplaced(true);
+ final View fragmentView = exitingFragment.getView();
+ final ViewGroup container = exitingFragment.mContainer;
+ container.getViewTreeObserver().addOnPreDrawListener(
+ new ViewTreeObserver.OnPreDrawListener() {
+ @Override
+ public boolean onPreDraw() {
+ container.getViewTreeObserver().removeOnPreDrawListener(this);
+ setViewVisibility(exitingViews, View.INVISIBLE);
+ return true;
+ }
+ });
+ exitTransition.addListener(new Transition.TransitionListenerAdapter() {
+ @Override
+ public void onTransitionEnd(Transition transition) {
+ transition.removeListener(this);
+ fragmentView.setVisibility(View.GONE);
+ setViewVisibility(exitingViews, View.VISIBLE);
+ }
+ });
+ }
+ }
+
+ /**
* This method is used for fragment transitions for unoptimized transactions to change the
* enter and exit transition targets after the call to
* {@link TransitionManager#beginDelayedTransition(ViewGroup, Transition)}. The exit transition
diff --git a/core/java/android/appwidget/AppWidgetHostView.java b/core/java/android/appwidget/AppWidgetHostView.java
index bb5f7a1..4c8360f 100644
--- a/core/java/android/appwidget/AppWidgetHostView.java
+++ b/core/java/android/appwidget/AppWidgetHostView.java
@@ -377,13 +377,13 @@
* AppWidget provider. Will animate into these new views as needed
*/
public void updateAppWidget(RemoteViews remoteViews) {
- applyRemoteViews(remoteViews);
+ applyRemoteViews(remoteViews, true);
}
/**
* @hide
*/
- protected void applyRemoteViews(RemoteViews remoteViews) {
+ protected void applyRemoteViews(RemoteViews remoteViews, boolean useAsyncIfPossible) {
if (LOGD) Log.d(TAG, "updateAppWidget called mOld=" + mOld);
boolean recycled = false;
@@ -423,7 +423,7 @@
mLayoutId = -1;
mViewMode = VIEW_MODE_DEFAULT;
} else {
- if (mAsyncExecutor != null) {
+ if (mAsyncExecutor != null && useAsyncIfPossible) {
inflateAsync(remoteViews);
return;
}
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index bc5af81..15dd282 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -726,7 +726,7 @@
/** @hide */
public UserManager(Context context, IUserManager service) {
mService = service;
- mContext = context;
+ mContext = context.getApplicationContext();
}
/**
diff --git a/core/java/android/os/storage/IMountService.aidl b/core/java/android/os/storage/IMountService.aidl
new file mode 100644
index 0000000..af0d7b7
--- /dev/null
+++ b/core/java/android/os/storage/IMountService.aidl
@@ -0,0 +1,291 @@
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os.storage;
+
+import android.content.pm.IPackageMoveObserver;
+import android.os.ParcelFileDescriptor;
+import android.os.storage.DiskInfo;
+import android.os.storage.IMountServiceListener;
+import android.os.storage.IMountShutdownObserver;
+import android.os.storage.IObbActionListener;
+import android.os.storage.StorageVolume;
+import android.os.storage.VolumeInfo;
+import android.os.storage.VolumeRecord;
+
+/**
+ * WARNING! Update IMountService.h and IMountService.cpp if you change this
+ * file. In particular, the transaction ids below must match the
+ * _TRANSACTION enum in IMountService.cpp
+ *
+ * @hide - Applications should use android.os.storage.StorageManager to access
+ * storage functions.
+ */
+interface IMountService {
+ /**
+ * Registers an IMountServiceListener for receiving async notifications.
+ */
+ void registerListener(IMountServiceListener listener) = 1;
+ /**
+ * Unregisters an IMountServiceListener
+ */
+ void unregisterListener(IMountServiceListener listener) = 2;
+ /**
+ * Returns true if a USB mass storage host is connected
+ */
+ boolean isUsbMassStorageConnected() = 3;
+ /**
+ * Enables / disables USB mass storage. The caller should check actual
+ * status of enabling/disabling USB mass storage via StorageEventListener.
+ */
+ void setUsbMassStorageEnabled(boolean enable) = 4;
+ /**
+ * Returns true if a USB mass storage host is enabled (media is shared)
+ */
+ boolean isUsbMassStorageEnabled() = 5;
+ /**
+ * Mount external storage at given mount point. Returns an int consistent
+ * with MountServiceResultCode
+ */
+ int mountVolume(in String mountPoint) = 6;
+ /**
+ * Safely unmount external storage at given mount point. The unmount is an
+ * asynchronous operation. Applications should register StorageEventListener
+ * for storage related status changes.
+ * @param mountPoint the mount point
+ * @param force whether or not to forcefully unmount it (e.g. even if programs are using this
+ * data currently)
+ * @param removeEncryption whether or not encryption mapping should be removed from the volume.
+ * This value implies {@code force}.
+ */
+ void unmountVolume(in String mountPoint, boolean force, boolean removeEncryption) = 7;
+ /**
+ * Format external storage given a mount point. Returns an int consistent
+ * with MountServiceResultCode
+ */
+ int formatVolume(in String mountPoint) = 8;
+ /**
+ * Returns an array of pids with open files on the specified path.
+ */
+ int[] getStorageUsers(in String path) = 9;
+ /**
+ * Gets the state of a volume via its mountpoint.
+ */
+ String getVolumeState(in String mountPoint) = 10;
+ /*
+ * Creates a secure container with the specified parameters. Returns an int
+ * consistent with MountServiceResultCode
+ */
+ int createSecureContainer(in String id, int sizeMb, in String fstype, in String key,
+ int ownerUid, boolean external) = 11;
+ /*
+ * Finalize a container which has just been created and populated. After
+ * finalization, the container is immutable. Returns an int consistent with
+ * MountServiceResultCode
+ */
+ int finalizeSecureContainer(in String id) = 12;
+ /*
+ * Destroy a secure container, and free up all resources associated with it.
+ * NOTE: Ensure all references are released prior to deleting. Returns an
+ * int consistent with MountServiceResultCode
+ */
+ int destroySecureContainer(in String id, boolean force) = 13;
+ /*
+ * Mount a secure container with the specified key and owner UID. Returns an
+ * int consistent with MountServiceResultCode
+ */
+ int mountSecureContainer(in String id, in String key, int ownerUid, boolean readOnly) = 14;
+ /*
+ * Unount a secure container. Returns an int consistent with
+ * MountServiceResultCode
+ */
+ int unmountSecureContainer(in String id, boolean force) = 15;
+ /*
+ * Returns true if the specified container is mounted
+ */
+ boolean isSecureContainerMounted(in String id) = 16;
+ /*
+ * Rename an unmounted secure container. Returns an int consistent with
+ * MountServiceResultCode
+ */
+ int renameSecureContainer(in String oldId, in String newId) = 17;
+ /*
+ * Returns the filesystem path of a mounted secure container.
+ */
+ String getSecureContainerPath(in String id) = 18;
+ /**
+ * Gets an Array of currently known secure container IDs
+ */
+ String[] getSecureContainerList() = 19;
+ /**
+ * Shuts down the MountService and gracefully unmounts all external media.
+ * Invokes call back once the shutdown is complete.
+ */
+ void shutdown(IMountShutdownObserver observer) = 20;
+ /**
+ * Call into MountService by PackageManager to notify that its done
+ * processing the media status update request.
+ */
+ void finishMediaUpdate() = 21;
+ /**
+ * Mounts an Opaque Binary Blob (OBB) with the specified decryption key and
+ * only allows the calling process's UID access to the contents.
+ * MountService will call back to the supplied IObbActionListener to inform
+ * it of the terminal state of the call.
+ */
+ void mountObb(in String rawPath, in String canonicalPath, in String key,
+ IObbActionListener token, int nonce) = 22;
+ /**
+ * Unmounts an Opaque Binary Blob (OBB). When the force flag is specified,
+ * any program using it will be forcibly killed to unmount the image.
+ * MountService will call back to the supplied IObbActionListener to inform
+ * it of the terminal state of the call.
+ */
+ void unmountObb(in String rawPath, boolean force, IObbActionListener token, int nonce) = 23;
+ /**
+ * Checks whether the specified Opaque Binary Blob (OBB) is mounted
+ * somewhere.
+ */
+ boolean isObbMounted(in String rawPath) = 24;
+ /**
+ * Gets the path to the mounted Opaque Binary Blob (OBB).
+ */
+ String getMountedObbPath(in String rawPath) = 25;
+ /**
+ * Returns whether or not the external storage is emulated.
+ */
+ boolean isExternalStorageEmulated() = 26;
+ /**
+ * Decrypts any encrypted volumes.
+ */
+ int decryptStorage(in String password) = 27;
+ /**
+ * Encrypts storage.
+ */
+ int encryptStorage(int type, in String password) = 28;
+ /**
+ * Changes the encryption password.
+ */
+ int changeEncryptionPassword(int type, in String password) = 29;
+ /**
+ * Returns list of all mountable volumes.
+ */
+ StorageVolume[] getVolumeList(int uid, in String packageName, int flags) = 30;
+ /**
+ * Gets the path on the filesystem for the ASEC container itself.
+ *
+ * @param cid ASEC container ID
+ * @return path to filesystem or {@code null} if it's not found
+ * @throws RemoteException
+ */
+ String getSecureContainerFilesystemPath(in String cid) = 31;
+ /**
+ * Determines the encryption state of the volume.
+ * @return a numerical value. See {@code ENCRYPTION_STATE_*} for possible
+ * values.
+ * Note that this has been replaced in most cases by the APIs in
+ * StorageManager (see isEncryptable and below)
+ * This is still useful to get the error state when encryption has failed
+ * and CryptKeeper needs to throw up a screen advising the user what to do
+ */
+ int getEncryptionState() = 32;
+ /**
+ * Verify the encryption password against the stored volume. This method
+ * may only be called by the system process.
+ */
+ int verifyEncryptionPassword(in String password) = 33;
+ /*
+ * Fix permissions in a container which has just been created and populated.
+ * Returns an int consistent with MountServiceResultCode
+ */
+ int fixPermissionsSecureContainer(in String id, int gid, in String filename) = 34;
+ /**
+ * Ensure that all directories along given path exist, creating parent
+ * directories as needed. Validates that given path is absolute and that it
+ * contains no relative "." or ".." paths or symlinks. Also ensures that
+ * path belongs to a volume managed by vold, and that path is either
+ * external storage data or OBB directory belonging to calling app.
+ */
+ int mkdirs(in String callingPkg, in String path) = 35;
+ /**
+ * Determines the type of the encryption password
+ * @return PasswordType
+ */
+ int getPasswordType() = 36;
+ /**
+ * Get password from vold
+ * @return password or empty string
+ */
+ String getPassword() = 37;
+ /**
+ * Securely clear password from vold
+ */
+ oneway void clearPassword() = 38;
+ /**
+ * Set a field in the crypto header.
+ * @param field field to set
+ * @param contents contents to set in field
+ */
+ oneway void setField(in String field, in String contents) = 39;
+ /**
+ * Gets a field from the crypto header.
+ * @param field field to get
+ * @return contents of field
+ */
+ String getField(in String field) = 40;
+ int resizeSecureContainer(in String id, int sizeMb, in String key) = 41;
+ /**
+ * Report the time of the last maintenance operation such as fstrim.
+ * @return Timestamp of the last maintenance operation, in the
+ * System.currentTimeMillis() time base
+ * @throws RemoteException
+ */
+ long lastMaintenance() = 42;
+ /**
+ * Kick off an immediate maintenance operation
+ * @throws RemoteException
+ */
+ void runMaintenance() = 43;
+ void waitForAsecScan() = 44;
+ DiskInfo[] getDisks() = 45;
+ VolumeInfo[] getVolumes(int flags) = 46;
+ VolumeRecord[] getVolumeRecords(int flags) = 47;
+ void mount(in String volId) = 48;
+ void unmount(in String volId) = 49;
+ void format(in String volId) = 50;
+ void partitionPublic(in String diskId) = 51;
+ void partitionPrivate(in String diskId) = 52;
+ void partitionMixed(in String diskId, int ratio) = 53;
+ void setVolumeNickname(in String fsUuid, in String nickname) = 54;
+ void setVolumeUserFlags(in String fsUuid, int flags, int mask) = 55;
+ void forgetVolume(in String fsUuid) = 56;
+ void forgetAllVolumes() = 57;
+ String getPrimaryStorageUuid() = 58;
+ void setPrimaryStorageUuid(in String volumeUuid, IPackageMoveObserver callback) = 59;
+ long benchmark(in String volId) = 60;
+ void setDebugFlags(int flags, int mask) = 61;
+ void createUserKey(int userId, int serialNumber, boolean ephemeral) = 62;
+ void destroyUserKey(int userId) = 63;
+ void unlockUserKey(int userId, int serialNumber, in byte[] token, in byte[] secret) = 64;
+ void lockUserKey(int userId) = 65;
+ boolean isUserKeyUnlocked(int userId) = 66;
+ void prepareUserStorage(in String volumeUuid, int userId, int serialNumber, int flags) = 67;
+ void destroyUserStorage(in String volumeUuid, int userId, int flags) = 68;
+ boolean isConvertibleToFBE() = 69;
+ ParcelFileDescriptor mountAppFuse(in String name) = 70;
+ void addUserKeyAuth(int userId, int serialNumber, in byte[] token, in byte[] secret) = 71;
+ void fixateNewestUserKeyAuth(int userId) = 72;
+}
\ No newline at end of file
diff --git a/core/java/android/os/storage/IMountService.java b/core/java/android/os/storage/IMountService.java
deleted file mode 100644
index b9bcd1c..0000000
--- a/core/java/android/os/storage/IMountService.java
+++ /dev/null
@@ -1,2491 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.os.storage;
-
-import android.content.pm.IPackageMoveObserver;
-import android.os.Binder;
-import android.os.IBinder;
-import android.os.IInterface;
-import android.os.Parcel;
-import android.os.ParcelFileDescriptor;
-import android.os.Parcelable;
-import android.os.RemoteException;
-
-/**
- * WARNING! Update IMountService.h and IMountService.cpp if you change this
- * file. In particular, the ordering of the methods below must match the
- * _TRANSACTION enum in IMountService.cpp
- *
- * @hide - Applications should use android.os.storage.StorageManager to access
- * storage functions.
- */
-public interface IMountService extends IInterface {
- /** Local-side IPC implementation stub class. */
- public static abstract class Stub extends Binder implements IMountService {
- private static class Proxy implements IMountService {
- private final IBinder mRemote;
-
- Proxy(IBinder remote) {
- mRemote = remote;
- }
-
- public IBinder asBinder() {
- return mRemote;
- }
-
- public String getInterfaceDescriptor() {
- return DESCRIPTOR;
- }
-
- /**
- * Registers an IMountServiceListener for receiving async
- * notifications.
- */
- public void registerListener(IMountServiceListener listener) throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeStrongBinder((listener != null ? listener.asBinder() : null));
- mRemote.transact(Stub.TRANSACTION_registerListener, _data, _reply, 0);
- _reply.readException();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- }
-
- /**
- * Unregisters an IMountServiceListener
- */
- public void unregisterListener(IMountServiceListener listener) throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeStrongBinder((listener != null ? listener.asBinder() : null));
- mRemote.transact(Stub.TRANSACTION_unregisterListener, _data, _reply, 0);
- _reply.readException();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- }
-
- /**
- * Returns true if a USB mass storage host is connected
- */
- public boolean isUsbMassStorageConnected() throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- boolean _result;
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- mRemote.transact(Stub.TRANSACTION_isUsbMassStorageConnected, _data, _reply, 0);
- _reply.readException();
- _result = 0 != _reply.readInt();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- return _result;
- }
-
- /**
- * Enables / disables USB mass storage. The caller should check
- * actual status of enabling/disabling USB mass storage via
- * StorageEventListener.
- */
- public void setUsbMassStorageEnabled(boolean enable) throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeInt((enable ? 1 : 0));
- mRemote.transact(Stub.TRANSACTION_setUsbMassStorageEnabled, _data, _reply, 0);
- _reply.readException();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- }
-
- /**
- * Returns true if a USB mass storage host is enabled (media is
- * shared)
- */
- public boolean isUsbMassStorageEnabled() throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- boolean _result;
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- mRemote.transact(Stub.TRANSACTION_isUsbMassStorageEnabled, _data, _reply, 0);
- _reply.readException();
- _result = 0 != _reply.readInt();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- return _result;
- }
-
- /**
- * Mount external storage at given mount point. Returns an int
- * consistent with MountServiceResultCode
- */
- public int mountVolume(String mountPoint) throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- int _result;
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeString(mountPoint);
- mRemote.transact(Stub.TRANSACTION_mountVolume, _data, _reply, 0);
- _reply.readException();
- _result = _reply.readInt();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- return _result;
- }
-
- /**
- * Safely unmount external storage at given mount point. The unmount
- * is an asynchronous operation. Applications should register
- * StorageEventListener for storage related status changes.
- */
- public void unmountVolume(String mountPoint, boolean force, boolean removeEncryption)
- throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeString(mountPoint);
- _data.writeInt((force ? 1 : 0));
- _data.writeInt((removeEncryption ? 1 : 0));
- mRemote.transact(Stub.TRANSACTION_unmountVolume, _data, _reply, 0);
- _reply.readException();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- }
-
- /**
- * Format external storage given a mount point. Returns an int
- * consistent with MountServiceResultCode
- */
- public int formatVolume(String mountPoint) throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- int _result;
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeString(mountPoint);
- mRemote.transact(Stub.TRANSACTION_formatVolume, _data, _reply, 0);
- _reply.readException();
- _result = _reply.readInt();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- return _result;
- }
-
- /**
- * Returns an array of pids with open files on the specified path.
- */
- public int[] getStorageUsers(String path) throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- int[] _result;
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeString(path);
- mRemote.transact(Stub.TRANSACTION_getStorageUsers, _data, _reply, 0);
- _reply.readException();
- _result = _reply.createIntArray();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- return _result;
- }
-
- /**
- * Gets the state of a volume via its mountpoint.
- */
- public String getVolumeState(String mountPoint) throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- String _result;
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeString(mountPoint);
- mRemote.transact(Stub.TRANSACTION_getVolumeState, _data, _reply, 0);
- _reply.readException();
- _result = _reply.readString();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- return _result;
- }
-
- /*
- * Creates a secure container with the specified parameters. Returns
- * an int consistent with MountServiceResultCode
- */
- public int createSecureContainer(String id, int sizeMb, String fstype, String key,
- int ownerUid, boolean external) throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- int _result;
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeString(id);
- _data.writeInt(sizeMb);
- _data.writeString(fstype);
- _data.writeString(key);
- _data.writeInt(ownerUid);
- _data.writeInt(external ? 1 : 0);
- mRemote.transact(Stub.TRANSACTION_createSecureContainer, _data, _reply, 0);
- _reply.readException();
- _result = _reply.readInt();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- return _result;
- }
-
- /*
- * Destroy a secure container, and free up all resources associated
- * with it. NOTE: Ensure all references are released prior to
- * deleting. Returns an int consistent with MountServiceResultCode
- */
- public int destroySecureContainer(String id, boolean force) throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- int _result;
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeString(id);
- _data.writeInt((force ? 1 : 0));
- mRemote.transact(Stub.TRANSACTION_destroySecureContainer, _data, _reply, 0);
- _reply.readException();
- _result = _reply.readInt();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- return _result;
- }
-
- /*
- * Finalize a container which has just been created and populated.
- * After finalization, the container is immutable. Returns an int
- * consistent with MountServiceResultCode
- */
- public int finalizeSecureContainer(String id) throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- int _result;
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeString(id);
- mRemote.transact(Stub.TRANSACTION_finalizeSecureContainer, _data, _reply, 0);
- _reply.readException();
- _result = _reply.readInt();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- return _result;
- }
-
- /*
- * Mount a secure container with the specified key and owner UID.
- * Returns an int consistent with MountServiceResultCode
- */
- public int mountSecureContainer(String id, String key, int ownerUid, boolean readOnly)
- throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- int _result;
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeString(id);
- _data.writeString(key);
- _data.writeInt(ownerUid);
- _data.writeInt(readOnly ? 1 : 0);
- mRemote.transact(Stub.TRANSACTION_mountSecureContainer, _data, _reply, 0);
- _reply.readException();
- _result = _reply.readInt();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- return _result;
- }
-
- /*
- * Unount a secure container. Returns an int consistent with
- * MountServiceResultCode
- */
- public int unmountSecureContainer(String id, boolean force) throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- int _result;
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeString(id);
- _data.writeInt((force ? 1 : 0));
- mRemote.transact(Stub.TRANSACTION_unmountSecureContainer, _data, _reply, 0);
- _reply.readException();
- _result = _reply.readInt();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- return _result;
- }
-
- /*
- * Returns true if the specified container is mounted
- */
- public boolean isSecureContainerMounted(String id) throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- boolean _result;
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeString(id);
- mRemote.transact(Stub.TRANSACTION_isSecureContainerMounted, _data, _reply, 0);
- _reply.readException();
- _result = 0 != _reply.readInt();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- return _result;
- }
-
- /*
- * Rename an unmounted secure container. Returns an int consistent
- * with MountServiceResultCode
- */
- public int renameSecureContainer(String oldId, String newId) throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- int _result;
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeString(oldId);
- _data.writeString(newId);
- mRemote.transact(Stub.TRANSACTION_renameSecureContainer, _data, _reply, 0);
- _reply.readException();
- _result = _reply.readInt();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- return _result;
- }
-
- /*
- * Returns the filesystem path of a mounted secure container.
- */
- public String getSecureContainerPath(String id) throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- String _result;
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeString(id);
- mRemote.transact(Stub.TRANSACTION_getSecureContainerPath, _data, _reply, 0);
- _reply.readException();
- _result = _reply.readString();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- return _result;
- }
-
- /**
- * Gets an Array of currently known secure container IDs
- */
- public String[] getSecureContainerList() throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- String[] _result;
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- mRemote.transact(Stub.TRANSACTION_getSecureContainerList, _data, _reply, 0);
- _reply.readException();
- _result = _reply.createStringArray();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- return _result;
- }
-
- /**
- * Shuts down the MountService and gracefully unmounts all external
- * media. Invokes call back once the shutdown is complete.
- */
- public void shutdown(IMountShutdownObserver observer)
- throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeStrongBinder((observer != null ? observer.asBinder() : null));
- mRemote.transact(Stub.TRANSACTION_shutdown, _data, _reply, 0);
- _reply.readException();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- }
-
- /**
- * Call into MountService by PackageManager to notify that its done
- * processing the media status update request.
- */
- public void finishMediaUpdate() throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- mRemote.transact(Stub.TRANSACTION_finishMediaUpdate, _data, _reply, 0);
- _reply.readException();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- }
-
- /**
- * Mounts an Opaque Binary Blob (OBB) with the specified decryption
- * key and only allows the calling process's UID access to the
- * contents. MountService will call back to the supplied
- * IObbActionListener to inform it of the terminal state of the
- * call.
- */
- public void mountObb(String rawPath, String canonicalPath, String key,
- IObbActionListener token, int nonce) throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeString(rawPath);
- _data.writeString(canonicalPath);
- _data.writeString(key);
- _data.writeStrongBinder((token != null ? token.asBinder() : null));
- _data.writeInt(nonce);
- mRemote.transact(Stub.TRANSACTION_mountObb, _data, _reply, 0);
- _reply.readException();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- }
-
- /**
- * Unmounts an Opaque Binary Blob (OBB). When the force flag is
- * specified, any program using it will be forcibly killed to
- * unmount the image. MountService will call back to the supplied
- * IObbActionListener to inform it of the terminal state of the
- * call.
- */
- public void unmountObb(
- String rawPath, boolean force, IObbActionListener token, int nonce)
- throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeString(rawPath);
- _data.writeInt((force ? 1 : 0));
- _data.writeStrongBinder((token != null ? token.asBinder() : null));
- _data.writeInt(nonce);
- mRemote.transact(Stub.TRANSACTION_unmountObb, _data, _reply, 0);
- _reply.readException();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- }
-
- /**
- * Checks whether the specified Opaque Binary Blob (OBB) is mounted
- * somewhere.
- */
- public boolean isObbMounted(String rawPath) throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- boolean _result;
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeString(rawPath);
- mRemote.transact(Stub.TRANSACTION_isObbMounted, _data, _reply, 0);
- _reply.readException();
- _result = 0 != _reply.readInt();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- return _result;
- }
-
- /**
- * Gets the path to the mounted Opaque Binary Blob (OBB).
- */
- public String getMountedObbPath(String rawPath) throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- String _result;
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeString(rawPath);
- mRemote.transact(Stub.TRANSACTION_getMountedObbPath, _data, _reply, 0);
- _reply.readException();
- _result = _reply.readString();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- return _result;
- }
-
- /**
- * Returns whether the external storage is emulated.
- */
- public boolean isExternalStorageEmulated() throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- boolean _result;
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- mRemote.transact(Stub.TRANSACTION_isExternalStorageEmulated, _data, _reply, 0);
- _reply.readException();
- _result = 0 != _reply.readInt();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- return _result;
- }
-
- public int getEncryptionState() throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- int _result;
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- mRemote.transact(Stub.TRANSACTION_getEncryptionState, _data, _reply, 0);
- _reply.readException();
- _result = _reply.readInt();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- return _result;
- }
-
- public int decryptStorage(String password) throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- int _result;
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeString(password);
- mRemote.transact(Stub.TRANSACTION_decryptStorage, _data, _reply, 0);
- _reply.readException();
- _result = _reply.readInt();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- return _result;
- }
-
- public int encryptStorage(int type, String password) throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- int _result;
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeInt(type);
- _data.writeString(password);
- mRemote.transact(Stub.TRANSACTION_encryptStorage, _data, _reply, 0);
- _reply.readException();
- _result = _reply.readInt();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- return _result;
- }
-
- public int changeEncryptionPassword(int type, String password) throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- int _result;
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeInt(type);
- _data.writeString(password);
- mRemote.transact(Stub.TRANSACTION_changeEncryptionPassword, _data, _reply, 0);
- _reply.readException();
- _result = _reply.readInt();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- return _result;
- }
-
- @Override
- public int verifyEncryptionPassword(String password) throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- int _result;
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeString(password);
- mRemote.transact(Stub.TRANSACTION_verifyEncryptionPassword, _data, _reply, 0);
- _reply.readException();
- _result = _reply.readInt();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- return _result;
- }
-
- public int getPasswordType() throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- int _result;
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- mRemote.transact(Stub.TRANSACTION_getPasswordType, _data, _reply, 0);
- _reply.readException();
- _result = _reply.readInt();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- return _result;
- }
-
- public String getPassword() throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- String _result;
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- mRemote.transact(Stub.TRANSACTION_getPassword, _data, _reply, 0);
- _reply.readException();
- _result = _reply.readString();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- return _result;
- }
-
- public void clearPassword() throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- mRemote.transact(Stub.TRANSACTION_clearPassword, _data, _reply, IBinder.FLAG_ONEWAY);
- _reply.readException();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- }
-
- public void setField(String field, String data) throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeString(field);
- _data.writeString(data);
- mRemote.transact(Stub.TRANSACTION_setField, _data, _reply, IBinder.FLAG_ONEWAY);
- _reply.readException();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- }
-
- public String getField(String field) throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- String _result;
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeString(field);
- mRemote.transact(Stub.TRANSACTION_getField, _data, _reply, 0);
- _reply.readException();
- _result = _reply.readString();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- return _result;
- }
-
- public boolean isConvertibleToFBE() throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- boolean _result;
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- mRemote.transact(Stub.TRANSACTION_isConvertibleToFBE, _data, _reply, 0);
- _reply.readException();
- _result = _reply.readInt() != 0;
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- return _result;
- }
-
- public StorageVolume[] getVolumeList(int uid, String packageName, int flags)
- throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- StorageVolume[] _result;
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeInt(uid);
- _data.writeString(packageName);
- _data.writeInt(flags);
- mRemote.transact(Stub.TRANSACTION_getVolumeList, _data, _reply, 0);
- _reply.readException();
- _result = _reply.createTypedArray(StorageVolume.CREATOR);
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- return _result;
- }
-
- /*
- * Returns the filesystem path of a mounted secure container.
- */
- public String getSecureContainerFilesystemPath(String id) throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- String _result;
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeString(id);
- mRemote.transact(Stub.TRANSACTION_getSecureContainerFilesystemPath, _data, _reply, 0);
- _reply.readException();
- _result = _reply.readString();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- return _result;
- }
-
- /**
- * Fix permissions in a container which has just been created and
- * populated. Returns an int consistent with MountServiceResultCode
- */
- public int fixPermissionsSecureContainer(String id, int gid, String filename)
- throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- int _result;
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeString(id);
- _data.writeInt(gid);
- _data.writeString(filename);
- mRemote.transact(Stub.TRANSACTION_fixPermissionsSecureContainer, _data, _reply, 0);
- _reply.readException();
- _result = _reply.readInt();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- return _result;
- }
-
- @Override
- public int mkdirs(String callingPkg, String path) throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- int _result;
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeString(callingPkg);
- _data.writeString(path);
- mRemote.transact(Stub.TRANSACTION_mkdirs, _data, _reply, 0);
- _reply.readException();
- _result = _reply.readInt();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- return _result;
- }
-
- @Override
- public int resizeSecureContainer(String id, int sizeMb, String key)
- throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- int _result;
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeString(id);
- _data.writeInt(sizeMb);
- _data.writeString(key);
- mRemote.transact(Stub.TRANSACTION_resizeSecureContainer, _data, _reply, 0);
- _reply.readException();
- _result = _reply.readInt();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- return _result;
- }
-
- @Override
- public long lastMaintenance() throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- long _result;
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- mRemote.transact(Stub.TRANSACTION_lastMaintenance, _data, _reply, 0);
- _reply.readException();
- _result = _reply.readLong();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- return _result;
- }
-
- @Override
- public void runMaintenance() throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- mRemote.transact(Stub.TRANSACTION_runMaintenance, _data, _reply, 0);
- _reply.readException();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- return;
- }
-
- @Override
- public void waitForAsecScan() throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- mRemote.transact(Stub.TRANSACTION_waitForAsecScan, _data, _reply, 0);
- _reply.readException();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- return;
- }
-
- @Override
- public DiskInfo[] getDisks() throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- DiskInfo[] _result;
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- mRemote.transact(Stub.TRANSACTION_getDisks, _data, _reply, 0);
- _reply.readException();
- _result = _reply.createTypedArray(DiskInfo.CREATOR);
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- return _result;
- }
-
- @Override
- public VolumeInfo[] getVolumes(int _flags) throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- VolumeInfo[] _result;
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeInt(_flags);
- mRemote.transact(Stub.TRANSACTION_getVolumes, _data, _reply, 0);
- _reply.readException();
- _result = _reply.createTypedArray(VolumeInfo.CREATOR);
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- return _result;
- }
-
- @Override
- public VolumeRecord[] getVolumeRecords(int _flags) throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- VolumeRecord[] _result;
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeInt(_flags);
- mRemote.transact(Stub.TRANSACTION_getVolumeRecords, _data, _reply, 0);
- _reply.readException();
- _result = _reply.createTypedArray(VolumeRecord.CREATOR);
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- return _result;
- }
-
- @Override
- public void mount(String volId) throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeString(volId);
- mRemote.transact(Stub.TRANSACTION_mount, _data, _reply, 0);
- _reply.readException();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- }
-
- @Override
- public void unmount(String volId) throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeString(volId);
- mRemote.transact(Stub.TRANSACTION_unmount, _data, _reply, 0);
- _reply.readException();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- }
-
- @Override
- public void format(String volId) throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeString(volId);
- mRemote.transact(Stub.TRANSACTION_format, _data, _reply, 0);
- _reply.readException();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- }
-
- @Override
- public long benchmark(String volId) throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeString(volId);
- mRemote.transact(Stub.TRANSACTION_benchmark, _data, _reply, 0);
- _reply.readException();
- return _reply.readLong();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- }
-
- @Override
- public void partitionPublic(String diskId) throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeString(diskId);
- mRemote.transact(Stub.TRANSACTION_partitionPublic, _data, _reply, 0);
- _reply.readException();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- }
-
- @Override
- public void partitionPrivate(String diskId) throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeString(diskId);
- mRemote.transact(Stub.TRANSACTION_partitionPrivate, _data, _reply, 0);
- _reply.readException();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- }
-
- @Override
- public void partitionMixed(String diskId, int ratio) throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeString(diskId);
- _data.writeInt(ratio);
- mRemote.transact(Stub.TRANSACTION_partitionMixed, _data, _reply, 0);
- _reply.readException();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- }
-
- @Override
- public void setVolumeNickname(String fsUuid, String nickname) throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeString(fsUuid);
- _data.writeString(nickname);
- mRemote.transact(Stub.TRANSACTION_setVolumeNickname, _data, _reply, 0);
- _reply.readException();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- }
-
- @Override
- public void setVolumeUserFlags(String fsUuid, int flags, int mask) throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeString(fsUuid);
- _data.writeInt(flags);
- _data.writeInt(mask);
- mRemote.transact(Stub.TRANSACTION_setVolumeUserFlags, _data, _reply, 0);
- _reply.readException();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- }
-
- @Override
- public void forgetVolume(String fsUuid) throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeString(fsUuid);
- mRemote.transact(Stub.TRANSACTION_forgetVolume, _data, _reply, 0);
- _reply.readException();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- }
-
- @Override
- public void forgetAllVolumes() throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- mRemote.transact(Stub.TRANSACTION_forgetAllVolumes, _data, _reply, 0);
- _reply.readException();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- }
-
- @Override
- public void setDebugFlags(int _flags, int _mask) throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeInt(_flags);
- _data.writeInt(_mask);
- mRemote.transact(Stub.TRANSACTION_setDebugFlags, _data, _reply, 0);
- _reply.readException();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- }
-
- @Override
- public String getPrimaryStorageUuid() throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- String _result;
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- mRemote.transact(Stub.TRANSACTION_getPrimaryStorageUuid, _data, _reply, 0);
- _reply.readException();
- _result = _reply.readString();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- return _result;
- }
-
- @Override
- public void setPrimaryStorageUuid(String volumeUuid, IPackageMoveObserver callback)
- throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeString(volumeUuid);
- _data.writeStrongBinder((callback != null ? callback.asBinder() : null));
- mRemote.transact(Stub.TRANSACTION_setPrimaryStorageUuid, _data, _reply, 0);
- _reply.readException();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- }
-
- @Override
- public void createUserKey(int userId, int serialNumber, boolean ephemeral)
- throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeInt(userId);
- _data.writeInt(serialNumber);
- _data.writeInt(ephemeral ? 1 : 0);
- mRemote.transact(Stub.TRANSACTION_createUserKey, _data, _reply, 0);
- _reply.readException();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- }
-
- @Override
- public void destroyUserKey(int userId) throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeInt(userId);
- mRemote.transact(Stub.TRANSACTION_destroyUserKey, _data, _reply, 0);
- _reply.readException();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- }
-
- @Override
- public void addUserKeyAuth(int userId, int serialNumber,
- byte[] token, byte[] secret) throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeInt(userId);
- _data.writeInt(serialNumber);
- _data.writeByteArray(token);
- _data.writeByteArray(secret);
- mRemote.transact(Stub.TRANSACTION_addUserKeyAuth, _data, _reply, 0);
- _reply.readException();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- }
-
- @Override
- public void fixateNewestUserKeyAuth(int userId) throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeInt(userId);
- mRemote.transact(Stub.TRANSACTION_fixateNewestUserKeyAuth, _data, _reply, 0);
- _reply.readException();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- }
-
- @Override
- public void unlockUserKey(int userId, int serialNumber,
- byte[] token, byte[] secret) throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeInt(userId);
- _data.writeInt(serialNumber);
- _data.writeByteArray(token);
- _data.writeByteArray(secret);
- mRemote.transact(Stub.TRANSACTION_unlockUserKey, _data, _reply, 0);
- _reply.readException();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- }
-
- @Override
- public void lockUserKey(int userId) throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeInt(userId);
- mRemote.transact(Stub.TRANSACTION_lockUserKey, _data, _reply, 0);
- _reply.readException();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- }
-
- @Override
- public boolean isUserKeyUnlocked(int userId) throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- boolean _result;
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeInt(userId);
- mRemote.transact(Stub.TRANSACTION_isUserKeyUnlocked, _data, _reply, 0);
- _reply.readException();
- _result = 0 != _reply.readInt();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- return _result;
- }
-
- @Override
- public void prepareUserStorage(
- String volumeUuid, int userId, int serialNumber, int flags)
- throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeString(volumeUuid);
- _data.writeInt(userId);
- _data.writeInt(serialNumber);
- _data.writeInt(flags);
- mRemote.transact(Stub.TRANSACTION_prepareUserStorage, _data, _reply, 0);
- _reply.readException();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- }
-
- @Override
- public void destroyUserStorage(String volumeUuid, int userId, int flags)
- throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeString(volumeUuid);
- _data.writeInt(userId);
- _data.writeInt(flags);
- mRemote.transact(Stub.TRANSACTION_destroyUserStorage, _data, _reply, 0);
- _reply.readException();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- }
-
- @Override
- public ParcelFileDescriptor mountAppFuse(String name) throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- ParcelFileDescriptor _result = null;
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeString(name);
- mRemote.transact(Stub.TRANSACTION_mountAppFuse, _data, _reply, 0);
- _reply.readException();
- _result = _reply.<ParcelFileDescriptor>readParcelable(
- ClassLoader.getSystemClassLoader());
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- return _result;
- }
- }
-
- private static final String DESCRIPTOR = "IMountService";
-
- static final int TRANSACTION_registerListener = IBinder.FIRST_CALL_TRANSACTION + 0;
-
- static final int TRANSACTION_unregisterListener = IBinder.FIRST_CALL_TRANSACTION + 1;
-
- static final int TRANSACTION_isUsbMassStorageConnected = IBinder.FIRST_CALL_TRANSACTION + 2;
-
- static final int TRANSACTION_setUsbMassStorageEnabled = IBinder.FIRST_CALL_TRANSACTION + 3;
-
- static final int TRANSACTION_isUsbMassStorageEnabled = IBinder.FIRST_CALL_TRANSACTION + 4;
-
- static final int TRANSACTION_mountVolume = IBinder.FIRST_CALL_TRANSACTION + 5;
-
- static final int TRANSACTION_unmountVolume = IBinder.FIRST_CALL_TRANSACTION + 6;
-
- static final int TRANSACTION_formatVolume = IBinder.FIRST_CALL_TRANSACTION + 7;
-
- static final int TRANSACTION_getStorageUsers = IBinder.FIRST_CALL_TRANSACTION + 8;
-
- static final int TRANSACTION_getVolumeState = IBinder.FIRST_CALL_TRANSACTION + 9;
-
- static final int TRANSACTION_createSecureContainer = IBinder.FIRST_CALL_TRANSACTION + 10;
-
- static final int TRANSACTION_finalizeSecureContainer = IBinder.FIRST_CALL_TRANSACTION + 11;
-
- static final int TRANSACTION_destroySecureContainer = IBinder.FIRST_CALL_TRANSACTION + 12;
-
- static final int TRANSACTION_mountSecureContainer = IBinder.FIRST_CALL_TRANSACTION + 13;
-
- static final int TRANSACTION_unmountSecureContainer = IBinder.FIRST_CALL_TRANSACTION + 14;
-
- static final int TRANSACTION_isSecureContainerMounted = IBinder.FIRST_CALL_TRANSACTION + 15;
-
- static final int TRANSACTION_renameSecureContainer = IBinder.FIRST_CALL_TRANSACTION + 16;
-
- static final int TRANSACTION_getSecureContainerPath = IBinder.FIRST_CALL_TRANSACTION + 17;
-
- static final int TRANSACTION_getSecureContainerList = IBinder.FIRST_CALL_TRANSACTION + 18;
-
- static final int TRANSACTION_shutdown = IBinder.FIRST_CALL_TRANSACTION + 19;
-
- static final int TRANSACTION_finishMediaUpdate = IBinder.FIRST_CALL_TRANSACTION + 20;
-
- static final int TRANSACTION_mountObb = IBinder.FIRST_CALL_TRANSACTION + 21;
-
- static final int TRANSACTION_unmountObb = IBinder.FIRST_CALL_TRANSACTION + 22;
-
- static final int TRANSACTION_isObbMounted = IBinder.FIRST_CALL_TRANSACTION + 23;
-
- static final int TRANSACTION_getMountedObbPath = IBinder.FIRST_CALL_TRANSACTION + 24;
-
- static final int TRANSACTION_isExternalStorageEmulated = IBinder.FIRST_CALL_TRANSACTION + 25;
-
- static final int TRANSACTION_decryptStorage = IBinder.FIRST_CALL_TRANSACTION + 26;
-
- static final int TRANSACTION_encryptStorage = IBinder.FIRST_CALL_TRANSACTION + 27;
-
- static final int TRANSACTION_changeEncryptionPassword = IBinder.FIRST_CALL_TRANSACTION + 28;
-
- static final int TRANSACTION_getVolumeList = IBinder.FIRST_CALL_TRANSACTION + 29;
-
- static final int TRANSACTION_getSecureContainerFilesystemPath = IBinder.FIRST_CALL_TRANSACTION + 30;
-
- static final int TRANSACTION_getEncryptionState = IBinder.FIRST_CALL_TRANSACTION + 31;
-
- static final int TRANSACTION_verifyEncryptionPassword = IBinder.FIRST_CALL_TRANSACTION + 32;
-
- static final int TRANSACTION_fixPermissionsSecureContainer = IBinder.FIRST_CALL_TRANSACTION + 33;
-
- static final int TRANSACTION_mkdirs = IBinder.FIRST_CALL_TRANSACTION + 34;
-
- static final int TRANSACTION_getPasswordType = IBinder.FIRST_CALL_TRANSACTION + 35;
-
- static final int TRANSACTION_getPassword = IBinder.FIRST_CALL_TRANSACTION + 36;
-
- static final int TRANSACTION_clearPassword = IBinder.FIRST_CALL_TRANSACTION + 37;
-
- static final int TRANSACTION_setField = IBinder.FIRST_CALL_TRANSACTION + 38;
-
- static final int TRANSACTION_getField = IBinder.FIRST_CALL_TRANSACTION + 39;
-
- static final int TRANSACTION_resizeSecureContainer = IBinder.FIRST_CALL_TRANSACTION + 40;
-
- static final int TRANSACTION_lastMaintenance = IBinder.FIRST_CALL_TRANSACTION + 41;
-
- static final int TRANSACTION_runMaintenance = IBinder.FIRST_CALL_TRANSACTION + 42;
-
- static final int TRANSACTION_waitForAsecScan = IBinder.FIRST_CALL_TRANSACTION + 43;
-
- static final int TRANSACTION_getDisks = IBinder.FIRST_CALL_TRANSACTION + 44;
- static final int TRANSACTION_getVolumes = IBinder.FIRST_CALL_TRANSACTION + 45;
- static final int TRANSACTION_getVolumeRecords = IBinder.FIRST_CALL_TRANSACTION + 46;
-
- static final int TRANSACTION_mount = IBinder.FIRST_CALL_TRANSACTION + 47;
- static final int TRANSACTION_unmount = IBinder.FIRST_CALL_TRANSACTION + 48;
- static final int TRANSACTION_format = IBinder.FIRST_CALL_TRANSACTION + 49;
-
- static final int TRANSACTION_partitionPublic = IBinder.FIRST_CALL_TRANSACTION + 50;
- static final int TRANSACTION_partitionPrivate = IBinder.FIRST_CALL_TRANSACTION + 51;
- static final int TRANSACTION_partitionMixed = IBinder.FIRST_CALL_TRANSACTION + 52;
-
- static final int TRANSACTION_setVolumeNickname = IBinder.FIRST_CALL_TRANSACTION + 53;
- static final int TRANSACTION_setVolumeUserFlags = IBinder.FIRST_CALL_TRANSACTION + 54;
- static final int TRANSACTION_forgetVolume = IBinder.FIRST_CALL_TRANSACTION + 55;
- static final int TRANSACTION_forgetAllVolumes = IBinder.FIRST_CALL_TRANSACTION + 56;
-
- static final int TRANSACTION_getPrimaryStorageUuid = IBinder.FIRST_CALL_TRANSACTION + 57;
- static final int TRANSACTION_setPrimaryStorageUuid = IBinder.FIRST_CALL_TRANSACTION + 58;
-
- static final int TRANSACTION_benchmark = IBinder.FIRST_CALL_TRANSACTION + 59;
- static final int TRANSACTION_setDebugFlags = IBinder.FIRST_CALL_TRANSACTION + 60;
-
- static final int TRANSACTION_createUserKey = IBinder.FIRST_CALL_TRANSACTION + 61;
- static final int TRANSACTION_destroyUserKey = IBinder.FIRST_CALL_TRANSACTION + 62;
-
- static final int TRANSACTION_unlockUserKey = IBinder.FIRST_CALL_TRANSACTION + 63;
- static final int TRANSACTION_lockUserKey = IBinder.FIRST_CALL_TRANSACTION + 64;
- static final int TRANSACTION_isUserKeyUnlocked = IBinder.FIRST_CALL_TRANSACTION + 65;
-
- static final int TRANSACTION_prepareUserStorage = IBinder.FIRST_CALL_TRANSACTION + 66;
- static final int TRANSACTION_destroyUserStorage = IBinder.FIRST_CALL_TRANSACTION + 67;
-
- static final int TRANSACTION_isConvertibleToFBE = IBinder.FIRST_CALL_TRANSACTION + 68;
-
- static final int TRANSACTION_mountAppFuse = IBinder.FIRST_CALL_TRANSACTION + 69;
-
- static final int TRANSACTION_addUserKeyAuth = IBinder.FIRST_CALL_TRANSACTION + 70;
-
- static final int TRANSACTION_fixateNewestUserKeyAuth = IBinder.FIRST_CALL_TRANSACTION + 71;
-
- /**
- * Cast an IBinder object into an IMountService interface, generating a
- * proxy if needed.
- */
- public static IMountService asInterface(IBinder obj) {
- if (obj == null) {
- return null;
- }
- IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
- if (iin != null && iin instanceof IMountService) {
- return (IMountService) iin;
- }
- return new IMountService.Stub.Proxy(obj);
- }
-
- /** Construct the stub at attach it to the interface. */
- public Stub() {
- attachInterface(this, DESCRIPTOR);
- }
-
- public IBinder asBinder() {
- return this;
- }
-
- @Override
- public boolean onTransact(int code, Parcel data, Parcel reply,
- int flags) throws RemoteException {
- switch (code) {
- case INTERFACE_TRANSACTION: {
- reply.writeString(DESCRIPTOR);
- return true;
- }
- case TRANSACTION_registerListener: {
- data.enforceInterface(DESCRIPTOR);
- IMountServiceListener listener;
- listener = IMountServiceListener.Stub.asInterface(data.readStrongBinder());
- registerListener(listener);
- reply.writeNoException();
- return true;
- }
- case TRANSACTION_unregisterListener: {
- data.enforceInterface(DESCRIPTOR);
- IMountServiceListener listener;
- listener = IMountServiceListener.Stub.asInterface(data.readStrongBinder());
- unregisterListener(listener);
- reply.writeNoException();
- return true;
- }
- case TRANSACTION_isUsbMassStorageConnected: {
- data.enforceInterface(DESCRIPTOR);
- boolean result = isUsbMassStorageConnected();
- reply.writeNoException();
- reply.writeInt((result ? 1 : 0));
- return true;
- }
- case TRANSACTION_setUsbMassStorageEnabled: {
- data.enforceInterface(DESCRIPTOR);
- boolean enable;
- enable = 0 != data.readInt();
- setUsbMassStorageEnabled(enable);
- reply.writeNoException();
- return true;
- }
- case TRANSACTION_isUsbMassStorageEnabled: {
- data.enforceInterface(DESCRIPTOR);
- boolean result = isUsbMassStorageEnabled();
- reply.writeNoException();
- reply.writeInt((result ? 1 : 0));
- return true;
- }
- case TRANSACTION_mountVolume: {
- data.enforceInterface(DESCRIPTOR);
- String mountPoint;
- mountPoint = data.readString();
- int resultCode = mountVolume(mountPoint);
- reply.writeNoException();
- reply.writeInt(resultCode);
- return true;
- }
- case TRANSACTION_unmountVolume: {
- data.enforceInterface(DESCRIPTOR);
- String mountPoint;
- mountPoint = data.readString();
- boolean force = 0 != data.readInt();
- boolean removeEncrypt = 0 != data.readInt();
- unmountVolume(mountPoint, force, removeEncrypt);
- reply.writeNoException();
- return true;
- }
- case TRANSACTION_formatVolume: {
- data.enforceInterface(DESCRIPTOR);
- String mountPoint;
- mountPoint = data.readString();
- int result = formatVolume(mountPoint);
- reply.writeNoException();
- reply.writeInt(result);
- return true;
- }
- case TRANSACTION_getStorageUsers: {
- data.enforceInterface(DESCRIPTOR);
- String path;
- path = data.readString();
- int[] pids = getStorageUsers(path);
- reply.writeNoException();
- reply.writeIntArray(pids);
- return true;
- }
- case TRANSACTION_getVolumeState: {
- data.enforceInterface(DESCRIPTOR);
- String mountPoint;
- mountPoint = data.readString();
- String state = getVolumeState(mountPoint);
- reply.writeNoException();
- reply.writeString(state);
- return true;
- }
- case TRANSACTION_createSecureContainer: {
- data.enforceInterface(DESCRIPTOR);
- String id;
- id = data.readString();
- int sizeMb;
- sizeMb = data.readInt();
- String fstype;
- fstype = data.readString();
- String key;
- key = data.readString();
- int ownerUid;
- ownerUid = data.readInt();
- boolean external;
- external = 0 != data.readInt();
- int resultCode = createSecureContainer(id, sizeMb, fstype, key, ownerUid,
- external);
- reply.writeNoException();
- reply.writeInt(resultCode);
- return true;
- }
- case TRANSACTION_finalizeSecureContainer: {
- data.enforceInterface(DESCRIPTOR);
- String id;
- id = data.readString();
- int resultCode = finalizeSecureContainer(id);
- reply.writeNoException();
- reply.writeInt(resultCode);
- return true;
- }
- case TRANSACTION_destroySecureContainer: {
- data.enforceInterface(DESCRIPTOR);
- String id;
- id = data.readString();
- boolean force;
- force = 0 != data.readInt();
- int resultCode = destroySecureContainer(id, force);
- reply.writeNoException();
- reply.writeInt(resultCode);
- return true;
- }
- case TRANSACTION_mountSecureContainer: {
- data.enforceInterface(DESCRIPTOR);
- String id;
- id = data.readString();
- String key;
- key = data.readString();
- int ownerUid;
- ownerUid = data.readInt();
- boolean readOnly;
- readOnly = data.readInt() != 0;
- int resultCode = mountSecureContainer(id, key, ownerUid, readOnly);
- reply.writeNoException();
- reply.writeInt(resultCode);
- return true;
- }
- case TRANSACTION_unmountSecureContainer: {
- data.enforceInterface(DESCRIPTOR);
- String id;
- id = data.readString();
- boolean force;
- force = 0 != data.readInt();
- int resultCode = unmountSecureContainer(id, force);
- reply.writeNoException();
- reply.writeInt(resultCode);
- return true;
- }
- case TRANSACTION_isSecureContainerMounted: {
- data.enforceInterface(DESCRIPTOR);
- String id;
- id = data.readString();
- boolean status = isSecureContainerMounted(id);
- reply.writeNoException();
- reply.writeInt((status ? 1 : 0));
- return true;
- }
- case TRANSACTION_renameSecureContainer: {
- data.enforceInterface(DESCRIPTOR);
- String oldId;
- oldId = data.readString();
- String newId;
- newId = data.readString();
- int resultCode = renameSecureContainer(oldId, newId);
- reply.writeNoException();
- reply.writeInt(resultCode);
- return true;
- }
- case TRANSACTION_getSecureContainerPath: {
- data.enforceInterface(DESCRIPTOR);
- String id;
- id = data.readString();
- String path = getSecureContainerPath(id);
- reply.writeNoException();
- reply.writeString(path);
- return true;
- }
- case TRANSACTION_getSecureContainerList: {
- data.enforceInterface(DESCRIPTOR);
- String[] ids = getSecureContainerList();
- reply.writeNoException();
- reply.writeStringArray(ids);
- return true;
- }
- case TRANSACTION_shutdown: {
- data.enforceInterface(DESCRIPTOR);
- IMountShutdownObserver observer;
- observer = IMountShutdownObserver.Stub.asInterface(data
- .readStrongBinder());
- shutdown(observer);
- reply.writeNoException();
- return true;
- }
- case TRANSACTION_finishMediaUpdate: {
- data.enforceInterface(DESCRIPTOR);
- finishMediaUpdate();
- reply.writeNoException();
- return true;
- }
- case TRANSACTION_mountObb: {
- data.enforceInterface(DESCRIPTOR);
- final String rawPath = data.readString();
- final String canonicalPath = data.readString();
- final String key = data.readString();
- IObbActionListener observer;
- observer = IObbActionListener.Stub.asInterface(data.readStrongBinder());
- int nonce;
- nonce = data.readInt();
- mountObb(rawPath, canonicalPath, key, observer, nonce);
- reply.writeNoException();
- return true;
- }
- case TRANSACTION_unmountObb: {
- data.enforceInterface(DESCRIPTOR);
- String filename;
- filename = data.readString();
- boolean force;
- force = 0 != data.readInt();
- IObbActionListener observer;
- observer = IObbActionListener.Stub.asInterface(data.readStrongBinder());
- int nonce;
- nonce = data.readInt();
- unmountObb(filename, force, observer, nonce);
- reply.writeNoException();
- return true;
- }
- case TRANSACTION_isObbMounted: {
- data.enforceInterface(DESCRIPTOR);
- String filename;
- filename = data.readString();
- boolean status = isObbMounted(filename);
- reply.writeNoException();
- reply.writeInt((status ? 1 : 0));
- return true;
- }
- case TRANSACTION_getMountedObbPath: {
- data.enforceInterface(DESCRIPTOR);
- String filename;
- filename = data.readString();
- String mountedPath = getMountedObbPath(filename);
- reply.writeNoException();
- reply.writeString(mountedPath);
- return true;
- }
- case TRANSACTION_isExternalStorageEmulated: {
- data.enforceInterface(DESCRIPTOR);
- boolean emulated = isExternalStorageEmulated();
- reply.writeNoException();
- reply.writeInt(emulated ? 1 : 0);
- return true;
- }
- case TRANSACTION_decryptStorage: {
- data.enforceInterface(DESCRIPTOR);
- String password = data.readString();
- int result = decryptStorage(password);
- reply.writeNoException();
- reply.writeInt(result);
- return true;
- }
- case TRANSACTION_encryptStorage: {
- data.enforceInterface(DESCRIPTOR);
- int type = data.readInt();
- String password = data.readString();
- int result = encryptStorage(type, password);
- reply.writeNoException();
- reply.writeInt(result);
- return true;
- }
- case TRANSACTION_changeEncryptionPassword: {
- data.enforceInterface(DESCRIPTOR);
- int type = data.readInt();
- String password = data.readString();
- int result = changeEncryptionPassword(type, password);
- reply.writeNoException();
- reply.writeInt(result);
- return true;
- }
- case TRANSACTION_getVolumeList: {
- data.enforceInterface(DESCRIPTOR);
- int uid = data.readInt();
- String packageName = data.readString();
- int _flags = data.readInt();
- StorageVolume[] result = getVolumeList(uid, packageName, _flags);
- reply.writeNoException();
- reply.writeTypedArray(result, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
- return true;
- }
- case TRANSACTION_getSecureContainerFilesystemPath: {
- data.enforceInterface(DESCRIPTOR);
- String id;
- id = data.readString();
- String path = getSecureContainerFilesystemPath(id);
- reply.writeNoException();
- reply.writeString(path);
- return true;
- }
- case TRANSACTION_getEncryptionState: {
- data.enforceInterface(DESCRIPTOR);
- int result = getEncryptionState();
- reply.writeNoException();
- reply.writeInt(result);
- return true;
- }
- case TRANSACTION_fixPermissionsSecureContainer: {
- data.enforceInterface(DESCRIPTOR);
- String id;
- id = data.readString();
- int gid;
- gid = data.readInt();
- String filename;
- filename = data.readString();
- int resultCode = fixPermissionsSecureContainer(id, gid, filename);
- reply.writeNoException();
- reply.writeInt(resultCode);
- return true;
- }
- case TRANSACTION_mkdirs: {
- data.enforceInterface(DESCRIPTOR);
- String callingPkg = data.readString();
- String path = data.readString();
- int result = mkdirs(callingPkg, path);
- reply.writeNoException();
- reply.writeInt(result);
- return true;
- }
- case TRANSACTION_getPasswordType: {
- data.enforceInterface(DESCRIPTOR);
- int result = getPasswordType();
- reply.writeNoException();
- reply.writeInt(result);
- return true;
- }
- case TRANSACTION_getPassword: {
- data.enforceInterface(DESCRIPTOR);
- String result = getPassword();
- reply.writeNoException();
- reply.writeString(result);
- return true;
- }
- case TRANSACTION_clearPassword: {
- data.enforceInterface(DESCRIPTOR);
- clearPassword();
- reply.writeNoException();
- return true;
- }
- case TRANSACTION_setField: {
- data.enforceInterface(DESCRIPTOR);
- String field = data.readString();
- String contents = data.readString();
- setField(field, contents);
- reply.writeNoException();
- return true;
- }
- case TRANSACTION_getField: {
- data.enforceInterface(DESCRIPTOR);
- String field = data.readString();
- String contents = getField(field);
- reply.writeNoException();
- reply.writeString(contents);
- return true;
- }
- case TRANSACTION_isConvertibleToFBE: {
- data.enforceInterface(DESCRIPTOR);
- int resultCode = isConvertibleToFBE() ? 1 : 0;
- reply.writeNoException();
- reply.writeInt(resultCode);
- return true;
- }
- case TRANSACTION_resizeSecureContainer: {
- data.enforceInterface(DESCRIPTOR);
- String id;
- id = data.readString();
- int sizeMb;
- sizeMb = data.readInt();
- String key;
- key = data.readString();
- int resultCode = resizeSecureContainer(id, sizeMb, key);
- reply.writeNoException();
- reply.writeInt(resultCode);
- return true;
- }
- case TRANSACTION_lastMaintenance: {
- data.enforceInterface(DESCRIPTOR);
- long lastMaintenance = lastMaintenance();
- reply.writeNoException();
- reply.writeLong(lastMaintenance);
- return true;
- }
- case TRANSACTION_runMaintenance: {
- data.enforceInterface(DESCRIPTOR);
- runMaintenance();
- reply.writeNoException();
- return true;
- }
- case TRANSACTION_waitForAsecScan: {
- data.enforceInterface(DESCRIPTOR);
- waitForAsecScan();
- reply.writeNoException();
- return true;
- }
- case TRANSACTION_getDisks: {
- data.enforceInterface(DESCRIPTOR);
- DiskInfo[] disks = getDisks();
- reply.writeNoException();
- reply.writeTypedArray(disks, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
- return true;
- }
- case TRANSACTION_getVolumes: {
- data.enforceInterface(DESCRIPTOR);
- int _flags = data.readInt();
- VolumeInfo[] volumes = getVolumes(_flags);
- reply.writeNoException();
- reply.writeTypedArray(volumes, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
- return true;
- }
- case TRANSACTION_getVolumeRecords: {
- data.enforceInterface(DESCRIPTOR);
- int _flags = data.readInt();
- VolumeRecord[] volumes = getVolumeRecords(_flags);
- reply.writeNoException();
- reply.writeTypedArray(volumes, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
- return true;
- }
- case TRANSACTION_mount: {
- data.enforceInterface(DESCRIPTOR);
- String volId = data.readString();
- mount(volId);
- reply.writeNoException();
- return true;
- }
- case TRANSACTION_unmount: {
- data.enforceInterface(DESCRIPTOR);
- String volId = data.readString();
- unmount(volId);
- reply.writeNoException();
- return true;
- }
- case TRANSACTION_format: {
- data.enforceInterface(DESCRIPTOR);
- String volId = data.readString();
- format(volId);
- reply.writeNoException();
- return true;
- }
- case TRANSACTION_benchmark: {
- data.enforceInterface(DESCRIPTOR);
- String volId = data.readString();
- long res = benchmark(volId);
- reply.writeNoException();
- reply.writeLong(res);
- return true;
- }
- case TRANSACTION_partitionPublic: {
- data.enforceInterface(DESCRIPTOR);
- String diskId = data.readString();
- partitionPublic(diskId);
- reply.writeNoException();
- return true;
- }
- case TRANSACTION_partitionPrivate: {
- data.enforceInterface(DESCRIPTOR);
- String diskId = data.readString();
- partitionPrivate(diskId);
- reply.writeNoException();
- return true;
- }
- case TRANSACTION_partitionMixed: {
- data.enforceInterface(DESCRIPTOR);
- String diskId = data.readString();
- int ratio = data.readInt();
- partitionMixed(diskId, ratio);
- reply.writeNoException();
- return true;
- }
- case TRANSACTION_setVolumeNickname: {
- data.enforceInterface(DESCRIPTOR);
- String volId = data.readString();
- String nickname = data.readString();
- setVolumeNickname(volId, nickname);
- reply.writeNoException();
- return true;
- }
- case TRANSACTION_setVolumeUserFlags: {
- data.enforceInterface(DESCRIPTOR);
- String volId = data.readString();
- int _flags = data.readInt();
- int _mask = data.readInt();
- setVolumeUserFlags(volId, _flags, _mask);
- reply.writeNoException();
- return true;
- }
- case TRANSACTION_forgetVolume: {
- data.enforceInterface(DESCRIPTOR);
- String fsUuid = data.readString();
- forgetVolume(fsUuid);
- reply.writeNoException();
- return true;
- }
- case TRANSACTION_forgetAllVolumes: {
- data.enforceInterface(DESCRIPTOR);
- forgetAllVolumes();
- reply.writeNoException();
- return true;
- }
- case TRANSACTION_setDebugFlags: {
- data.enforceInterface(DESCRIPTOR);
- int _flags = data.readInt();
- int _mask = data.readInt();
- setDebugFlags(_flags, _mask);
- reply.writeNoException();
- return true;
- }
- case TRANSACTION_getPrimaryStorageUuid: {
- data.enforceInterface(DESCRIPTOR);
- String volumeUuid = getPrimaryStorageUuid();
- reply.writeNoException();
- reply.writeString(volumeUuid);
- return true;
- }
- case TRANSACTION_setPrimaryStorageUuid: {
- data.enforceInterface(DESCRIPTOR);
- String volumeUuid = data.readString();
- IPackageMoveObserver listener = IPackageMoveObserver.Stub.asInterface(
- data.readStrongBinder());
- setPrimaryStorageUuid(volumeUuid, listener);
- reply.writeNoException();
- return true;
- }
- case TRANSACTION_createUserKey: {
- data.enforceInterface(DESCRIPTOR);
- int userId = data.readInt();
- int serialNumber = data.readInt();
- boolean ephemeral = data.readInt() != 0;
- createUserKey(userId, serialNumber, ephemeral);
- reply.writeNoException();
- return true;
- }
- case TRANSACTION_destroyUserKey: {
- data.enforceInterface(DESCRIPTOR);
- int userId = data.readInt();
- destroyUserKey(userId);
- reply.writeNoException();
- return true;
- }
- case TRANSACTION_addUserKeyAuth: {
- data.enforceInterface(DESCRIPTOR);
- int userId = data.readInt();
- int serialNumber = data.readInt();
- byte[] token = data.createByteArray();
- byte[] secret = data.createByteArray();
- addUserKeyAuth(userId, serialNumber, token, secret);
- reply.writeNoException();
- return true;
- }
- case TRANSACTION_fixateNewestUserKeyAuth: {
- data.enforceInterface(DESCRIPTOR);
- int userId = data.readInt();
- fixateNewestUserKeyAuth(userId);
- reply.writeNoException();
- return true;
- }
- case TRANSACTION_unlockUserKey: {
- data.enforceInterface(DESCRIPTOR);
- int userId = data.readInt();
- int serialNumber = data.readInt();
- byte[] token = data.createByteArray();
- byte[] secret = data.createByteArray();
- unlockUserKey(userId, serialNumber, token, secret);
- reply.writeNoException();
- return true;
- }
- case TRANSACTION_lockUserKey: {
- data.enforceInterface(DESCRIPTOR);
- int userId = data.readInt();
- lockUserKey(userId);
- reply.writeNoException();
- return true;
- }
- case TRANSACTION_isUserKeyUnlocked: {
- data.enforceInterface(DESCRIPTOR);
- int userId = data.readInt();
- boolean result = isUserKeyUnlocked(userId);
- reply.writeNoException();
- reply.writeInt(result ? 1 : 0);
- return true;
- }
- case TRANSACTION_prepareUserStorage: {
- data.enforceInterface(DESCRIPTOR);
- String volumeUuid = data.readString();
- int userId = data.readInt();
- int serialNumber = data.readInt();
- int _flags = data.readInt();
- prepareUserStorage(volumeUuid, userId, serialNumber, _flags);
- reply.writeNoException();
- return true;
- }
- case TRANSACTION_destroyUserStorage: {
- data.enforceInterface(DESCRIPTOR);
- String volumeUuid = data.readString();
- int userId = data.readInt();
- int _flags = data.readInt();
- destroyUserStorage(volumeUuid, userId, _flags);
- reply.writeNoException();
- return true;
- }
- case TRANSACTION_mountAppFuse: {
- data.enforceInterface(DESCRIPTOR);
- String name = data.readString();
- ParcelFileDescriptor fd = mountAppFuse(name);
- reply.writeNoException();
- reply.writeParcelable(fd, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
- return true;
- }
- }
- return super.onTransact(code, data, reply, flags);
- }
- }
-
- /*
- * Creates a secure container with the specified parameters. Returns an int
- * consistent with MountServiceResultCode
- */
- public int createSecureContainer(String id, int sizeMb, String fstype, String key,
- int ownerUid, boolean external) throws RemoteException;
-
- /*
- * Destroy a secure container, and free up all resources associated with it.
- * NOTE: Ensure all references are released prior to deleting. Returns an
- * int consistent with MountServiceResultCode
- */
- public int destroySecureContainer(String id, boolean force) throws RemoteException;
-
- /*
- * Finalize a container which has just been created and populated. After
- * finalization, the container is immutable. Returns an int consistent with
- * MountServiceResultCode
- */
- public int finalizeSecureContainer(String id) throws RemoteException;
-
- /**
- * Call into MountService by PackageManager to notify that its done
- * processing the media status update request.
- */
- public void finishMediaUpdate() throws RemoteException;
-
- /**
- * Format external storage given a mount point. Returns an int consistent
- * with MountServiceResultCode
- */
- public int formatVolume(String mountPoint) throws RemoteException;
-
- /**
- * Gets the path to the mounted Opaque Binary Blob (OBB).
- */
- public String getMountedObbPath(String rawPath) throws RemoteException;
-
- /**
- * Gets an Array of currently known secure container IDs
- */
- public String[] getSecureContainerList() throws RemoteException;
-
- /*
- * Returns the filesystem path of a mounted secure container.
- */
- public String getSecureContainerPath(String id) throws RemoteException;
-
- /**
- * Returns an array of pids with open files on the specified path.
- */
- public int[] getStorageUsers(String path) throws RemoteException;
-
- /**
- * Gets the state of a volume via its mountpoint.
- */
- public String getVolumeState(String mountPoint) throws RemoteException;
-
- /**
- * Checks whether the specified Opaque Binary Blob (OBB) is mounted
- * somewhere.
- */
- public boolean isObbMounted(String rawPath) throws RemoteException;
-
- /*
- * Returns true if the specified container is mounted
- */
- public boolean isSecureContainerMounted(String id) throws RemoteException;
-
- /**
- * Returns true if a USB mass storage host is connected
- */
- public boolean isUsbMassStorageConnected() throws RemoteException;
-
- /**
- * Returns true if a USB mass storage host is enabled (media is shared)
- */
- public boolean isUsbMassStorageEnabled() throws RemoteException;
-
- /**
- * Mounts an Opaque Binary Blob (OBB) with the specified decryption key and
- * only allows the calling process's UID access to the contents.
- * MountService will call back to the supplied IObbActionListener to inform
- * it of the terminal state of the call.
- */
- public void mountObb(String rawPath, String canonicalPath, String key,
- IObbActionListener token, int nonce) throws RemoteException;
-
- /*
- * Mount a secure container with the specified key and owner UID. Returns an
- * int consistent with MountServiceResultCode
- */
- public int mountSecureContainer(String id, String key, int ownerUid, boolean readOnly)
- throws RemoteException;
-
- /**
- * Mount external storage at given mount point. Returns an int consistent
- * with MountServiceResultCode
- */
- public int mountVolume(String mountPoint) throws RemoteException;
-
- /**
- * Registers an IMountServiceListener for receiving async notifications.
- */
- public void registerListener(IMountServiceListener listener) throws RemoteException;
-
- /*
- * Rename an unmounted secure container. Returns an int consistent with
- * MountServiceResultCode
- */
- public int renameSecureContainer(String oldId, String newId) throws RemoteException;
-
- /**
- * Enables / disables USB mass storage. The caller should check actual
- * status of enabling/disabling USB mass storage via StorageEventListener.
- */
- public void setUsbMassStorageEnabled(boolean enable) throws RemoteException;
-
- /**
- * Shuts down the MountService and gracefully unmounts all external media.
- * Invokes call back once the shutdown is complete.
- */
- public void shutdown(IMountShutdownObserver observer) throws RemoteException;
-
- /**
- * Unmounts an Opaque Binary Blob (OBB). When the force flag is specified,
- * any program using it will be forcibly killed to unmount the image.
- * MountService will call back to the supplied IObbActionListener to inform
- * it of the terminal state of the call.
- */
- public void unmountObb(String rawPath, boolean force, IObbActionListener token, int nonce)
- throws RemoteException;
-
- /*
- * Unount a secure container. Returns an int consistent with
- * MountServiceResultCode
- */
- public int unmountSecureContainer(String id, boolean force) throws RemoteException;
-
- /**
- * Safely unmount external storage at given mount point. The unmount is an
- * asynchronous operation. Applications should register StorageEventListener
- * for storage related status changes.
- * @param mountPoint the mount point
- * @param force whether or not to forcefully unmount it (e.g. even if programs are using this
- * data currently)
- * @param removeEncryption whether or not encryption mapping should be removed from the volume.
- * This value implies {@code force}.
- */
- public void unmountVolume(String mountPoint, boolean force, boolean removeEncryption)
- throws RemoteException;
-
- /**
- * Unregisters an IMountServiceListener
- */
- public void unregisterListener(IMountServiceListener listener) throws RemoteException;
-
- /**
- * Returns whether or not the external storage is emulated.
- */
- public boolean isExternalStorageEmulated() throws RemoteException;
-
- /** The volume is not encrypted. */
- static final int ENCRYPTION_STATE_NONE = 1;
- /** The volume has been encrypted succesfully. */
- static final int ENCRYPTION_STATE_OK = 0;
- /** The volume is in a bad state.*/
- static final int ENCRYPTION_STATE_ERROR_UNKNOWN = -1;
- /** Encryption is incomplete */
- static final int ENCRYPTION_STATE_ERROR_INCOMPLETE = -2;
- /** Encryption is incomplete and irrecoverable */
- static final int ENCRYPTION_STATE_ERROR_INCONSISTENT = -3;
- /** Underlying data is corrupt */
- static final int ENCRYPTION_STATE_ERROR_CORRUPT = -4;
-
- /**
- * Determines the encryption state of the volume.
- * @return a numerical value. See {@code ENCRYPTION_STATE_*} for possible
- * values.
- * Note that this has been replaced in most cases by the APIs in
- * StorageManager (see isEncryptable and below)
- * This is still useful to get the error state when encryption has failed
- * and CryptKeeper needs to throw up a screen advising the user what to do
- */
- public int getEncryptionState() throws RemoteException;
-
- /**
- * Decrypts any encrypted volumes.
- */
- public int decryptStorage(String password) throws RemoteException;
-
- /**
- * Encrypts storage.
- */
- public int encryptStorage(int type, String password) throws RemoteException;
-
- /**
- * Changes the encryption password.
- */
- public int changeEncryptionPassword(int type, String password)
- throws RemoteException;
-
- /**
- * Verify the encryption password against the stored volume. This method
- * may only be called by the system process.
- */
- public int verifyEncryptionPassword(String password) throws RemoteException;
-
- /**
- * Returns list of all mountable volumes.
- */
- public StorageVolume[] getVolumeList(int uid, String packageName, int flags) throws RemoteException;
-
- /**
- * Gets the path on the filesystem for the ASEC container itself.
- *
- * @param cid ASEC container ID
- * @return path to filesystem or {@code null} if it's not found
- * @throws RemoteException
- */
- public String getSecureContainerFilesystemPath(String cid) throws RemoteException;
-
- /*
- * Fix permissions in a container which has just been created and populated.
- * Returns an int consistent with MountServiceResultCode
- */
- public int fixPermissionsSecureContainer(String id, int gid, String filename)
- throws RemoteException;
-
- /**
- * Ensure that all directories along given path exist, creating parent
- * directories as needed. Validates that given path is absolute and that it
- * contains no relative "." or ".." paths or symlinks. Also ensures that
- * path belongs to a volume managed by vold, and that path is either
- * external storage data or OBB directory belonging to calling app.
- */
- public int mkdirs(String callingPkg, String path) throws RemoteException;
-
- /**
- * Determines the type of the encryption password
- * @return PasswordType
- */
- public int getPasswordType() throws RemoteException;
-
- /**
- * Get password from vold
- * @return password or empty string
- */
- public String getPassword() throws RemoteException;
-
- /**
- * Securely clear password from vold
- */
- public void clearPassword() throws RemoteException;
-
- /**
- * Set a field in the crypto header.
- * @param field field to set
- * @param contents contents to set in field
- */
- public void setField(String field, String contents) throws RemoteException;
-
- /**
- * Gets a field from the crypto header.
- * @param field field to get
- * @return contents of field
- */
- public String getField(String field) throws RemoteException;
-
- public boolean isConvertibleToFBE() throws RemoteException;
-
- public int resizeSecureContainer(String id, int sizeMb, String key) throws RemoteException;
-
- /**
- * Report the time of the last maintenance operation such as fstrim.
- * @return Timestamp of the last maintenance operation, in the
- * System.currentTimeMillis() time base
- * @throws RemoteException
- */
- public long lastMaintenance() throws RemoteException;
-
- /**
- * Kick off an immediate maintenance operation
- * @throws RemoteException
- */
- public void runMaintenance() throws RemoteException;
-
- public void waitForAsecScan() throws RemoteException;
-
- public DiskInfo[] getDisks() throws RemoteException;
- public VolumeInfo[] getVolumes(int flags) throws RemoteException;
- public VolumeRecord[] getVolumeRecords(int flags) throws RemoteException;
-
- public void mount(String volId) throws RemoteException;
- public void unmount(String volId) throws RemoteException;
- public void format(String volId) throws RemoteException;
- public long benchmark(String volId) throws RemoteException;
-
- public void partitionPublic(String diskId) throws RemoteException;
- public void partitionPrivate(String diskId) throws RemoteException;
- public void partitionMixed(String diskId, int ratio) throws RemoteException;
-
- public void setVolumeNickname(String fsUuid, String nickname) throws RemoteException;
- public void setVolumeUserFlags(String fsUuid, int flags, int mask) throws RemoteException;
- public void forgetVolume(String fsUuid) throws RemoteException;
- public void forgetAllVolumes() throws RemoteException;
- public void setDebugFlags(int flags, int mask) throws RemoteException;
-
- public String getPrimaryStorageUuid() throws RemoteException;
- public void setPrimaryStorageUuid(String volumeUuid, IPackageMoveObserver callback)
- throws RemoteException;
-
- public void createUserKey(int userId, int serialNumber, boolean ephemeral)
- throws RemoteException;
- public void destroyUserKey(int userId) throws RemoteException;
- public void addUserKeyAuth(int userId, int serialNumber,
- byte[] token, byte[] secret) throws RemoteException;
- public void fixateNewestUserKeyAuth(int userId) throws RemoteException;
-
- public void unlockUserKey(int userId, int serialNumber,
- byte[] token, byte[] secret) throws RemoteException;
- public void lockUserKey(int userId) throws RemoteException;
- public boolean isUserKeyUnlocked(int userId) throws RemoteException;
-
- public void prepareUserStorage(String volumeUuid, int userId, int serialNumber,
- int flags) throws RemoteException;
- public void destroyUserStorage(String volumeUuid, int userId, int flags) throws RemoteException;
-
- public ParcelFileDescriptor mountAppFuse(String name) throws RemoteException;
-}
diff --git a/core/java/android/os/storage/IMountServiceListener.aidl b/core/java/android/os/storage/IMountServiceListener.aidl
new file mode 100644
index 0000000..e149978
--- /dev/null
+++ b/core/java/android/os/storage/IMountServiceListener.aidl
@@ -0,0 +1,64 @@
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os.storage;
+
+import android.os.storage.DiskInfo;
+import android.os.storage.VolumeInfo;
+import android.os.storage.VolumeRecord;
+
+/**
+ * Callback class for receiving events from MountService.
+ *
+ * Don't change the existing transaction Ids as they could be used in the native code.
+ * When adding a new method, assign the next available transaction id.
+ *
+ * @hide - Applications should use IStorageEventListener for storage event
+ * callbacks.
+ */
+oneway interface IMountServiceListener {
+ /**
+ * Detection state of USB Mass Storage has changed
+ *
+ * @param available true if a UMS host is connected.
+ */
+ void onUsbMassStorageConnectionChanged(boolean connected) = 1;
+
+ /**
+ * Storage state has changed.
+ *
+ * @param path The volume mount path.
+ * @param oldState The old state of the volume.
+ * @param newState The new state of the volume. Note: State is one of the
+ * values returned by Environment.getExternalStorageState()
+ */
+ void onStorageStateChanged(in String path, in String oldState, in String newState) = 2;
+
+ void onVolumeStateChanged(in VolumeInfo vol, int oldState, int newState) = 3;
+
+ void onVolumeRecordChanged(in VolumeRecord rec) = 4;
+
+ void onVolumeForgotten(in String fsUuid) = 5;
+
+ void onDiskScanned(in DiskInfo disk, int volumeCount) = 6;
+
+ void onDiskDestroyed(in DiskInfo disk) = 7;
+
+ /**
+ * Don't change the existing transaction Ids as they could be used in the native code.
+ * When adding a new method, assign the next available transaction id.
+ */
+}
\ No newline at end of file
diff --git a/core/java/android/os/storage/IMountServiceListener.java b/core/java/android/os/storage/IMountServiceListener.java
deleted file mode 100644
index cade9d7..0000000
--- a/core/java/android/os/storage/IMountServiceListener.java
+++ /dev/null
@@ -1,309 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.os.storage;
-
-import android.os.Binder;
-import android.os.IBinder;
-import android.os.IInterface;
-import android.os.Parcel;
-import android.os.RemoteException;
-
-/**
- * Callback class for receiving events from MountService.
- *
- * @hide - Applications should use IStorageEventListener for storage event
- * callbacks.
- */
-public interface IMountServiceListener extends IInterface {
- /** Local-side IPC implementation stub class. */
- public static abstract class Stub extends Binder implements IMountServiceListener {
- private static final String DESCRIPTOR = "IMountServiceListener";
-
- /** Construct the stub at attach it to the interface. */
- public Stub() {
- this.attachInterface(this, DESCRIPTOR);
- }
-
- /**
- * Cast an IBinder object into an IMountServiceListener interface,
- * generating a proxy if needed.
- */
- public static IMountServiceListener asInterface(IBinder obj) {
- if ((obj == null)) {
- return null;
- }
- IInterface iin = (IInterface) obj.queryLocalInterface(DESCRIPTOR);
- if (((iin != null) && (iin instanceof IMountServiceListener))) {
- return ((IMountServiceListener) iin);
- }
- return new IMountServiceListener.Stub.Proxy(obj);
- }
-
- public IBinder asBinder() {
- return this;
- }
-
- @Override
- public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
- throws RemoteException {
- switch (code) {
- case INTERFACE_TRANSACTION: {
- reply.writeString(DESCRIPTOR);
- return true;
- }
- case TRANSACTION_onUsbMassStorageConnectionChanged: {
- data.enforceInterface(DESCRIPTOR);
- boolean connected;
- connected = (0 != data.readInt());
- this.onUsbMassStorageConnectionChanged(connected);
- reply.writeNoException();
- return true;
- }
- case TRANSACTION_onStorageStateChanged: {
- data.enforceInterface(DESCRIPTOR);
- final String path = data.readString();
- final String oldState = data.readString();
- final String newState = data.readString();
- this.onStorageStateChanged(path, oldState, newState);
- reply.writeNoException();
- return true;
- }
- case TRANSACTION_onVolumeStateChanged: {
- data.enforceInterface(DESCRIPTOR);
- final VolumeInfo vol = (VolumeInfo) data.readParcelable(null);
- final int oldState = data.readInt();
- final int newState = data.readInt();
- onVolumeStateChanged(vol, oldState, newState);
- reply.writeNoException();
- return true;
- }
- case TRANSACTION_onVolumeRecordChanged: {
- data.enforceInterface(DESCRIPTOR);
- final VolumeRecord rec = (VolumeRecord) data.readParcelable(null);
- onVolumeRecordChanged(rec);
- reply.writeNoException();
- return true;
- }
- case TRANSACTION_onVolumeForgotten: {
- data.enforceInterface(DESCRIPTOR);
- final String fsUuid = data.readString();
- onVolumeForgotten(fsUuid);
- reply.writeNoException();
- return true;
- }
- case TRANSACTION_onDiskScanned: {
- data.enforceInterface(DESCRIPTOR);
- final DiskInfo disk = (DiskInfo) data.readParcelable(null);
- final int volumeCount = data.readInt();
- onDiskScanned(disk, volumeCount);
- reply.writeNoException();
- return true;
- }
- case TRANSACTION_onDiskDestroyed: {
- data.enforceInterface(DESCRIPTOR);
- final DiskInfo disk = (DiskInfo) data.readParcelable(null);
- onDiskDestroyed(disk);
- reply.writeNoException();
- return true;
- }
- }
- return super.onTransact(code, data, reply, flags);
- }
-
- private static class Proxy implements IMountServiceListener {
- private IBinder mRemote;
-
- Proxy(IBinder remote) {
- mRemote = remote;
- }
-
- public IBinder asBinder() {
- return mRemote;
- }
-
- public String getInterfaceDescriptor() {
- return DESCRIPTOR;
- }
-
- /**
- * Detection state of USB Mass Storage has changed
- *
- * @param available true if a UMS host is connected.
- */
- public void onUsbMassStorageConnectionChanged(boolean connected) throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeInt(((connected) ? (1) : (0)));
- mRemote.transact(Stub.TRANSACTION_onUsbMassStorageConnectionChanged, _data,
- _reply, android.os.IBinder.FLAG_ONEWAY);
- _reply.readException();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- }
-
- /**
- * Storage state has changed.
- *
- * @param path The volume mount path.
- * @param oldState The old state of the volume.
- * @param newState The new state of the volume. Note: State is one
- * of the values returned by
- * Environment.getExternalStorageState()
- */
- public void onStorageStateChanged(String path, String oldState, String newState)
- throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeString(path);
- _data.writeString(oldState);
- _data.writeString(newState);
- mRemote.transact(Stub.TRANSACTION_onStorageStateChanged, _data, _reply,
- android.os.IBinder.FLAG_ONEWAY);
- _reply.readException();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- }
-
- @Override
- public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState)
- throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeParcelable(vol, 0);
- _data.writeInt(oldState);
- _data.writeInt(newState);
- mRemote.transact(Stub.TRANSACTION_onVolumeStateChanged, _data, _reply,
- android.os.IBinder.FLAG_ONEWAY);
- _reply.readException();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- }
-
- @Override
- public void onVolumeRecordChanged(VolumeRecord rec) throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeParcelable(rec, 0);
- mRemote.transact(Stub.TRANSACTION_onVolumeRecordChanged, _data, _reply,
- android.os.IBinder.FLAG_ONEWAY);
- _reply.readException();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- }
-
- @Override
- public void onVolumeForgotten(String fsUuid) throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeString(fsUuid);
- mRemote.transact(Stub.TRANSACTION_onVolumeForgotten, _data, _reply,
- android.os.IBinder.FLAG_ONEWAY);
- _reply.readException();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- }
-
- @Override
- public void onDiskScanned(DiskInfo disk, int volumeCount) throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeParcelable(disk, 0);
- _data.writeInt(volumeCount);
- mRemote.transact(Stub.TRANSACTION_onDiskScanned, _data, _reply,
- android.os.IBinder.FLAG_ONEWAY);
- _reply.readException();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- }
-
- @Override
- public void onDiskDestroyed(DiskInfo disk) throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeParcelable(disk, 0);
- mRemote.transact(Stub.TRANSACTION_onDiskDestroyed, _data, _reply,
- android.os.IBinder.FLAG_ONEWAY);
- _reply.readException();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- }
- }
-
- static final int TRANSACTION_onUsbMassStorageConnectionChanged = (IBinder.FIRST_CALL_TRANSACTION + 0);
- static final int TRANSACTION_onStorageStateChanged = (IBinder.FIRST_CALL_TRANSACTION + 1);
- static final int TRANSACTION_onVolumeStateChanged = (IBinder.FIRST_CALL_TRANSACTION + 2);
- static final int TRANSACTION_onVolumeRecordChanged = (IBinder.FIRST_CALL_TRANSACTION + 3);
- static final int TRANSACTION_onVolumeForgotten = (IBinder.FIRST_CALL_TRANSACTION + 4);
- static final int TRANSACTION_onDiskScanned = (IBinder.FIRST_CALL_TRANSACTION + 5);
- static final int TRANSACTION_onDiskDestroyed = (IBinder.FIRST_CALL_TRANSACTION + 6);
- }
-
- /**
- * Detection state of USB Mass Storage has changed
- *
- * @param available true if a UMS host is connected.
- */
- public void onUsbMassStorageConnectionChanged(boolean connected) throws RemoteException;
-
- /**
- * Storage state has changed.
- *
- * @param path The volume mount path.
- * @param oldState The old state of the volume.
- * @param newState The new state of the volume. Note: State is one of the
- * values returned by Environment.getExternalStorageState()
- */
- public void onStorageStateChanged(String path, String oldState, String newState)
- throws RemoteException;
-
- public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState)
- throws RemoteException;
- public void onVolumeRecordChanged(VolumeRecord rec) throws RemoteException;
- public void onVolumeForgotten(String fsUuid) throws RemoteException;
-
- public void onDiskScanned(DiskInfo disk, int volumeCount) throws RemoteException;
-
- public void onDiskDestroyed(DiskInfo disk) throws RemoteException;
-}
diff --git a/core/java/android/os/storage/IMountShutdownObserver.aidl b/core/java/android/os/storage/IMountShutdownObserver.aidl
new file mode 100644
index 0000000..3353bc5
--- /dev/null
+++ b/core/java/android/os/storage/IMountShutdownObserver.aidl
@@ -0,0 +1,39 @@
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os.storage;
+
+/**
+ * Callback class for receiving events related to shutdown.
+ *
+ * Don't change the existing transaction Ids as they could be used in the native code.
+ * When adding a new method, assign the next available transaction id.
+ *
+ * @hide - For internal consumption only.
+ */
+interface IMountShutdownObserver {
+ /**
+ * This method is called when the shutdown of MountService completed.
+ *
+ * @param statusCode indicates success or failure of the shutdown.
+ */
+ void onShutDownComplete(int statusCode) = 1;
+
+ /**
+ * Don't change the existing transaction Ids as they could be used in the native code.
+ * When adding a new method, assign the next available transaction id.
+ */
+}
\ No newline at end of file
diff --git a/core/java/android/os/storage/IMountShutdownObserver.java b/core/java/android/os/storage/IMountShutdownObserver.java
deleted file mode 100644
index d946e1a..0000000
--- a/core/java/android/os/storage/IMountShutdownObserver.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.os.storage;
-
-import android.os.Binder;
-import android.os.IBinder;
-import android.os.IInterface;
-import android.os.Parcel;
-import android.os.RemoteException;
-
-/**
- * Callback class for receiving events related to shutdown.
- *
- * @hide - For internal consumption only.
- */
-public interface IMountShutdownObserver extends IInterface {
- /** Local-side IPC implementation stub class. */
- public static abstract class Stub extends Binder implements IMountShutdownObserver {
- private static final java.lang.String DESCRIPTOR = "IMountShutdownObserver";
-
- /** Construct the stub at attach it to the interface. */
- public Stub() {
- this.attachInterface(this, DESCRIPTOR);
- }
-
- /**
- * Cast an IBinder object into an IMountShutdownObserver interface,
- * generating a proxy if needed.
- */
- public static IMountShutdownObserver asInterface(IBinder obj) {
- if ((obj == null)) {
- return null;
- }
- IInterface iin = (IInterface) obj.queryLocalInterface(DESCRIPTOR);
- if (((iin != null) && (iin instanceof IMountShutdownObserver))) {
- return ((IMountShutdownObserver) iin);
- }
- return new IMountShutdownObserver.Stub.Proxy(obj);
- }
-
- public IBinder asBinder() {
- return this;
- }
-
- @Override
- public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
- throws RemoteException {
- switch (code) {
- case INTERFACE_TRANSACTION: {
- reply.writeString(DESCRIPTOR);
- return true;
- }
- case TRANSACTION_onShutDownComplete: {
- data.enforceInterface(DESCRIPTOR);
- int statusCode;
- statusCode = data.readInt();
- this.onShutDownComplete(statusCode);
- reply.writeNoException();
- return true;
- }
- }
- return super.onTransact(code, data, reply, flags);
- }
-
- private static class Proxy implements IMountShutdownObserver {
- private IBinder mRemote;
-
- Proxy(IBinder remote) {
- mRemote = remote;
- }
-
- public IBinder asBinder() {
- return mRemote;
- }
-
- public java.lang.String getInterfaceDescriptor() {
- return DESCRIPTOR;
- }
-
- /**
- * This method is called when the shutdown of MountService
- * completed.
- *
- * @param statusCode indicates success or failure of the shutdown.
- */
- public void onShutDownComplete(int statusCode) throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeInt(statusCode);
- mRemote.transact(Stub.TRANSACTION_onShutDownComplete, _data, _reply, 0);
- _reply.readException();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- }
- }
-
- static final int TRANSACTION_onShutDownComplete = (IBinder.FIRST_CALL_TRANSACTION + 0);
- }
-
- /**
- * This method is called when the shutdown of MountService completed.
- *
- * @param statusCode indicates success or failure of the shutdown.
- */
- public void onShutDownComplete(int statusCode) throws RemoteException;
-}
diff --git a/core/java/android/os/storage/IObbActionListener.aidl b/core/java/android/os/storage/IObbActionListener.aidl
new file mode 100644
index 0000000..71e6aaf
--- /dev/null
+++ b/core/java/android/os/storage/IObbActionListener.aidl
@@ -0,0 +1,42 @@
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os.storage;
+
+/**
+ * Callback class for receiving events from MountService about Opaque Binary
+ * Blobs (OBBs).
+ *
+ * Don't change the existing transaction Ids as they could be used in the native code.
+ * When adding a new method, assign the next available transaction id.
+ *
+ * @hide - Applications should use StorageManager to interact with OBBs.
+ */
+oneway interface IObbActionListener {
+ /**
+ * Return from an OBB action result.
+ *
+ * @param filename the path to the OBB the operation was performed on
+ * @param nonce identifier that is meaningful to the receiver
+ * @param status status code as defined in {@link OnObbStateChangeListener}
+ */
+ void onObbResult(in String filename, int nonce, int status) = 1;
+
+ /**
+ * Don't change the existing transaction Ids as they could be used in the native code.
+ * When adding a new method, assign the next available transaction id.
+ */
+}
\ No newline at end of file
diff --git a/core/java/android/os/storage/IObbActionListener.java b/core/java/android/os/storage/IObbActionListener.java
deleted file mode 100644
index 35da4b0..0000000
--- a/core/java/android/os/storage/IObbActionListener.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.os.storage;
-
-import android.os.Binder;
-import android.os.IBinder;
-import android.os.IInterface;
-import android.os.Parcel;
-import android.os.RemoteException;
-
-/**
- * Callback class for receiving events from MountService about Opaque Binary
- * Blobs (OBBs).
- *
- * @hide - Applications should use StorageManager to interact with OBBs.
- */
-public interface IObbActionListener extends IInterface {
- /** Local-side IPC implementation stub class. */
- public static abstract class Stub extends Binder implements IObbActionListener {
- private static final String DESCRIPTOR = "IObbActionListener";
-
- /** Construct the stub at attach it to the interface. */
- public Stub() {
- this.attachInterface(this, DESCRIPTOR);
- }
-
- /**
- * Cast an IBinder object into an IObbActionListener interface,
- * generating a proxy if needed.
- */
- public static IObbActionListener asInterface(IBinder obj) {
- if ((obj == null)) {
- return null;
- }
- IInterface iin = (IInterface) obj.queryLocalInterface(DESCRIPTOR);
- if (((iin != null) && (iin instanceof IObbActionListener))) {
- return ((IObbActionListener) iin);
- }
- return new IObbActionListener.Stub.Proxy(obj);
- }
-
- public IBinder asBinder() {
- return this;
- }
-
- @Override
- public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
- throws RemoteException {
- switch (code) {
- case INTERFACE_TRANSACTION: {
- reply.writeString(DESCRIPTOR);
- return true;
- }
- case TRANSACTION_onObbResult: {
- data.enforceInterface(DESCRIPTOR);
- String filename;
- filename = data.readString();
- int nonce;
- nonce = data.readInt();
- int status;
- status = data.readInt();
- this.onObbResult(filename, nonce, status);
- reply.writeNoException();
- return true;
- }
- }
- return super.onTransact(code, data, reply, flags);
- }
-
- private static class Proxy implements IObbActionListener {
- private IBinder mRemote;
-
- Proxy(IBinder remote) {
- mRemote = remote;
- }
-
- public IBinder asBinder() {
- return mRemote;
- }
-
- public String getInterfaceDescriptor() {
- return DESCRIPTOR;
- }
-
- /**
- * Return from an OBB action result.
- *
- * @param filename the path to the OBB the operation was performed
- * on
- * @param returnCode status of the operation
- */
- public void onObbResult(String filename, int nonce, int status)
- throws RemoteException {
- Parcel _data = Parcel.obtain();
- Parcel _reply = Parcel.obtain();
- try {
- _data.writeInterfaceToken(DESCRIPTOR);
- _data.writeString(filename);
- _data.writeInt(nonce);
- _data.writeInt(status);
- mRemote.transact(Stub.TRANSACTION_onObbResult, _data, _reply,
- android.os.IBinder.FLAG_ONEWAY);
- _reply.readException();
- } finally {
- _reply.recycle();
- _data.recycle();
- }
- }
- }
-
- static final int TRANSACTION_onObbResult = (IBinder.FIRST_CALL_TRANSACTION + 0);
- }
-
- /**
- * Return from an OBB action result.
- *
- * @param filename the path to the OBB the operation was performed on
- * @param nonce identifier that is meaningful to the receiver
- * @param status status code as defined in {@link OnObbStateChangeListener}
- */
- public void onObbResult(String filename, int nonce, int status) throws RemoteException;
-}
diff --git a/core/java/android/os/storage/MountServiceListener.java b/core/java/android/os/storage/MountServiceListener.java
deleted file mode 100644
index bebb3f6..0000000
--- a/core/java/android/os/storage/MountServiceListener.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.os.storage;
-
-/**
- * Callback class for receiving progress reports during a restore operation. These
- * methods will all be called on your application's main thread.
- * @hide
- */
-public abstract class MountServiceListener {
- /**
- * USB Mass storage connection state has changed.
- *
- * @param connected True if UMS is connected.
- */
- void onUsbMassStorageConnectionChanged(boolean connected) {
- }
-
- /**
- * Storage state has changed.
- *
- * @param path The volume mount path.
- * @param oldState The old state of the volume.
- * @param newState The new state of the volume.
- *
- * @Note: State is one of the values returned by Environment.getExternalStorageState()
- */
- void onStorageStateChange(String path, String oldState, String newState) {
- }
-}
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index 1a78fe7..1942fde 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -41,6 +41,7 @@
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
+import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
@@ -133,6 +134,24 @@
/** {@hide} */
public static final int FLAG_INCLUDE_INVISIBLE = 1 << 10;
+ /** @hide The volume is not encrypted. */
+ public static final int ENCRYPTION_STATE_NONE = 1;
+
+ /** @hide The volume has been encrypted succesfully. */
+ public static final int ENCRYPTION_STATE_OK = 0;
+
+ /** @hide The volume is in a bad state.*/
+ public static final int ENCRYPTION_STATE_ERROR_UNKNOWN = -1;
+
+ /** @hide Encryption is incomplete */
+ public static final int ENCRYPTION_STATE_ERROR_INCOMPLETE = -2;
+
+ /** @hide Encryption is incomplete and irrecoverable */
+ public static final int ENCRYPTION_STATE_ERROR_INCONSISTENT = -3;
+
+ /** @hide Underlying data is corrupt */
+ public static final int ENCRYPTION_STATE_ERROR_CORRUPT = -4;
+
private static volatile IMountService sMountService = null;
// TODO: the location of the primary storage block varies from device to device, so we need to
@@ -929,22 +948,29 @@
}
/** {@hide} */
- public long getPrimaryStorageSize() {
+ public static Pair<String, Long> getPrimaryStoragePathAndSize() {
for (String path : INTERNAL_STORAGE_SIZE_PATHS) {
final long numberBlocks = readLong(path);
if (numberBlocks > 0) {
- return numberBlocks * INTERNAL_STORAGE_SECTOR_SIZE;
+ return new Pair<>(path, Long.valueOf(numberBlocks * INTERNAL_STORAGE_SECTOR_SIZE));
}
}
- return 0;
+ return null;
}
- private long readLong(String path) {
+
+ /** {@hide} */
+ public long getPrimaryStorageSize() {
+ final Pair<String, Long> pair = getPrimaryStoragePathAndSize();
+ return pair == null ? 0 : pair.second.longValue();
+ }
+
+ private static long readLong(String path) {
try (final FileInputStream fis = new FileInputStream(path);
final BufferedReader reader = new BufferedReader(new InputStreamReader(fis));) {
return Long.parseLong(reader.readLine());
} catch (Exception e) {
- Slog.w(TAG, "Could not read " + path, e);
+ Slog.w(TAG, "readLong(): could not read " + path + ": " + e);
return 0;
}
}
diff --git a/core/java/android/os/storage/VolumeRecord.aidl b/core/java/android/os/storage/VolumeRecord.aidl
new file mode 100644
index 0000000..27c4010
--- /dev/null
+++ b/core/java/android/os/storage/VolumeRecord.aidl
@@ -0,0 +1,20 @@
+/**
+ * Copyright (c) 2016, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os.storage;
+
+/** @hide */
+parcelable VolumeRecord;
\ No newline at end of file
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 184453b..d5a933c 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -6284,6 +6284,17 @@
* @param intent the intent used to identify the RemoteViewsService for the adapter to connect to.
*/
public void setRemoteViewsAdapter(Intent intent) {
+ setRemoteViewsAdapter(intent, false);
+ }
+
+ /** @hide **/
+ public Runnable setRemoteViewsAdapterAsync(final Intent intent) {
+ return new RemoteViewsAdapter.AsyncRemoteAdapterAction(this, intent);
+ }
+
+ /** @hide **/
+ @Override
+ public void setRemoteViewsAdapter(Intent intent, boolean isAsync) {
// Ensure that we don't already have a RemoteViewsAdapter that is bound to an existing
// service handling the specified intent.
if (mRemoteAdapter != null) {
@@ -6296,7 +6307,7 @@
}
mDeferNotifyDataSetChanged = false;
// Otherwise, create a new RemoteViewsAdapter for binding
- mRemoteAdapter = new RemoteViewsAdapter(getContext(), intent, this);
+ mRemoteAdapter = new RemoteViewsAdapter(getContext(), intent, this, isAsync);
if (mRemoteAdapter.isDataReady()) {
setAdapter(mRemoteAdapter);
}
diff --git a/core/java/android/widget/AdapterViewAnimator.java b/core/java/android/widget/AdapterViewAnimator.java
index 0e3a69f..6f29368 100644
--- a/core/java/android/widget/AdapterViewAnimator.java
+++ b/core/java/android/widget/AdapterViewAnimator.java
@@ -975,8 +975,19 @@
* @param intent the intent used to identify the RemoteViewsService for the adapter to
* connect to.
*/
- @android.view.RemotableViewMethod
+ @android.view.RemotableViewMethod(asyncImpl="setRemoteViewsAdapterAsync")
public void setRemoteViewsAdapter(Intent intent) {
+ setRemoteViewsAdapter(intent, false);
+ }
+
+ /** @hide **/
+ public Runnable setRemoteViewsAdapterAsync(final Intent intent) {
+ return new RemoteViewsAdapter.AsyncRemoteAdapterAction(this, intent);
+ }
+
+ /** @hide **/
+ @Override
+ public void setRemoteViewsAdapter(Intent intent, boolean isAsync) {
// Ensure that we don't already have a RemoteViewsAdapter that is bound to an existing
// service handling the specified intent.
if (mRemoteViewsAdapter != null) {
@@ -989,7 +1000,7 @@
}
mDeferNotifyDataSetChanged = false;
// Otherwise, create a new RemoteViewsAdapter for binding
- mRemoteViewsAdapter = new RemoteViewsAdapter(getContext(), intent, this);
+ mRemoteViewsAdapter = new RemoteViewsAdapter(getContext(), intent, this, isAsync);
if (mRemoteViewsAdapter.isDataReady()) {
setAdapter(mRemoteViewsAdapter);
}
diff --git a/core/java/android/widget/GridView.java b/core/java/android/widget/GridView.java
index 20543fb..82071d7 100644
--- a/core/java/android/widget/GridView.java
+++ b/core/java/android/widget/GridView.java
@@ -175,7 +175,7 @@
* through the specified intent.
* @param intent the intent used to identify the RemoteViewsService for the adapter to connect to.
*/
- @android.view.RemotableViewMethod
+ @android.view.RemotableViewMethod(asyncImpl="setRemoteViewsAdapterAsync")
public void setRemoteViewsAdapter(Intent intent) {
super.setRemoteViewsAdapter(intent);
}
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index 4d405c5..cd80651 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -455,7 +455,16 @@
/** @hide **/
public Runnable setImageResourceAsync(@DrawableRes int resId) {
- return new ImageDrawableCallback(getContext().getDrawable(resId), null, resId);
+ Drawable d = null;
+ if (resId != 0) {
+ try {
+ d = getContext().getDrawable(resId);
+ } catch (Exception e) {
+ Log.w(LOG_TAG, "Unable to find resource: " + resId, e);
+ resId = 0;
+ }
+ }
+ return new ImageDrawableCallback(d, null, resId);
}
/**
@@ -865,7 +874,7 @@
} catch (Exception e) {
Log.w(LOG_TAG, "Unable to find resource: " + mResource, e);
// Don't try again.
- mUri = null;
+ mResource = 0;
}
} else if (mUri != null) {
d = getDrawableFromUri(mUri);
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index e88c7ef..e52c13b 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -448,7 +448,7 @@
* through the specified intent.
* @param intent the intent used to identify the RemoteViewsService for the adapter to connect to.
*/
- @android.view.RemotableViewMethod
+ @android.view.RemotableViewMethod(asyncImpl="setRemoteViewsAdapterAsync")
public void setRemoteViewsAdapter(Intent intent) {
super.setRemoteViewsAdapter(intent);
}
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 6543d0c..316dab5 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -320,6 +320,10 @@
return this;
}
+ public boolean prefersAsyncApply() {
+ return false;
+ }
+
int viewId;
}
@@ -715,20 +719,29 @@
intent.putExtra(EXTRA_REMOTEADAPTER_APPWIDGET_ID, host.getAppWidgetId());
if (target instanceof AbsListView) {
AbsListView v = (AbsListView) target;
- v.setRemoteViewsAdapter(intent);
+ v.setRemoteViewsAdapter(intent, isAsync);
v.setRemoteViewsOnClickHandler(handler);
} else if (target instanceof AdapterViewAnimator) {
AdapterViewAnimator v = (AdapterViewAnimator) target;
- v.setRemoteViewsAdapter(intent);
+ v.setRemoteViewsAdapter(intent, isAsync);
v.setRemoteViewsOnClickHandler(handler);
}
}
+ @Override
+ public Action initActionAsync(ViewTree root, ViewGroup rootParent,
+ OnClickHandler handler) {
+ SetRemoteViewsAdapterIntent copy = new SetRemoteViewsAdapterIntent(viewId, intent);
+ copy.isAsync = true;
+ return copy;
+ }
+
public String getActionName() {
return "SetRemoteViewsAdapterIntent";
}
Intent intent;
+ boolean isAsync = false;
public final static int TAG = 10;
}
@@ -1461,6 +1474,11 @@
// unique from the standpoint of merging.
return "ReflectionAction" + this.methodName + this.type;
}
+
+ @Override
+ public boolean prefersAsyncApply() {
+ return this.type == URI || this.type == ICON;
+ }
}
/**
@@ -1598,6 +1616,11 @@
return MERGE_APPEND;
}
+ @Override
+ public boolean prefersAsyncApply() {
+ return nestedViews != null && nestedViews.prefersAsyncApply();
+ }
+
RemoteViews nestedViews;
public final static int TAG = 4;
@@ -1749,6 +1772,11 @@
return copy;
}
+ @Override
+ public boolean prefersAsyncApply() {
+ return useIcons;
+ }
+
public String getActionName() {
return "TextViewDrawableAction";
}
@@ -3443,6 +3471,24 @@
}
}
+ /**
+ * Returns true if the RemoteViews contains potentially costly operations and should be
+ * applied asynchronously.
+ *
+ * @hide
+ */
+ public boolean prefersAsyncApply() {
+ if (mActions != null) {
+ final int count = mActions.size();
+ for (int i = 0; i < count; i++) {
+ if (mActions.get(i).prefersAsyncApply()) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
private Context getContextForResources(Context context) {
if (mApplication != null) {
if (context.getUserId() == UserHandle.getUserId(mApplication.uid)
diff --git a/core/java/android/widget/RemoteViewsAdapter.java b/core/java/android/widget/RemoteViewsAdapter.java
index e0f94fd..11e0a3f 100644
--- a/core/java/android/widget/RemoteViewsAdapter.java
+++ b/core/java/android/widget/RemoteViewsAdapter.java
@@ -45,6 +45,12 @@
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedList;
+import java.util.concurrent.Executor;
+
+import java.lang.ref.WeakReference;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.LinkedList;
/**
* An adapter to a RemoteViewsService which fetches and caches RemoteViews
@@ -73,7 +79,8 @@
private final Context mContext;
private final Intent mIntent;
private final int mAppWidgetId;
- private LayoutInflater mLayoutInflater;
+ private final Executor mAsyncViewLoadExecutor;
+
private RemoteViewsAdapterServiceConnection mServiceConnection;
private WeakReference<RemoteAdapterConnectionCallback> mCallback;
private OnClickHandler mRemoteViewsOnClickHandler;
@@ -120,15 +127,33 @@
/**
* @return whether the adapter was set or not.
*/
- public boolean onRemoteAdapterConnected();
+ boolean onRemoteAdapterConnected();
- public void onRemoteAdapterDisconnected();
+ void onRemoteAdapterDisconnected();
/**
* This defers a notifyDataSetChanged on the pending RemoteViewsAdapter if it has not
* connected yet.
*/
- public void deferNotifyDataSetChanged();
+ void deferNotifyDataSetChanged();
+
+ void setRemoteViewsAdapter(Intent intent, boolean isAsync);
+ }
+
+ public static class AsyncRemoteAdapterAction implements Runnable {
+
+ private final RemoteAdapterConnectionCallback mCallback;
+ private final Intent mIntent;
+
+ public AsyncRemoteAdapterAction(RemoteAdapterConnectionCallback callback, Intent intent) {
+ mCallback = callback;
+ mIntent = intent;
+ }
+
+ @Override
+ public void run() {
+ mCallback.setRemoteViewsAdapter(mIntent, true);
+ }
}
/**
@@ -162,7 +187,7 @@
}
mIsConnecting = true;
} catch (Exception e) {
- Log.e("RemoteViewsAdapterServiceConnection", "bind(): " + e.getMessage());
+ Log.e("RVAServiceConnection", "bind(): " + e.getMessage());
mIsConnecting = false;
mIsConnected = false;
}
@@ -180,7 +205,7 @@
}
mIsConnecting = false;
} catch (Exception e) {
- Log.e("RemoteViewsAdapterServiceConnection", "unbind(): " + e.getMessage());
+ Log.e("RVAServiceConnection", "unbind(): " + e.getMessage());
mIsConnecting = false;
mIsConnected = false;
}
@@ -298,15 +323,29 @@
* Updates this RemoteViewsFrameLayout depending on the view that was loaded.
* @param view the RemoteViews that was loaded. If null, the RemoteViews was not loaded
* successfully.
+ * @param forceApplyAsync when true, the host will always try to inflate the view
+ * asynchronously (for eg, when we are already showing the loading
+ * view)
*/
- public void onRemoteViewsLoaded(RemoteViews view, OnClickHandler handler) {
+ public void onRemoteViewsLoaded(RemoteViews view, OnClickHandler handler,
+ boolean forceApplyAsync) {
setOnClickHandler(handler);
- applyRemoteViews(view);
+ applyRemoteViews(view, forceApplyAsync || ((view != null) && view.prefersAsyncApply()));
}
+ /**
+ * Creates a default loading view. Uses the size of the first row as a guide for the
+ * size of the loading view.
+ */
@Override
protected View getDefaultView() {
- return mCache.getMetaData().createDefaultLoadingView(this);
+ int viewHeight = mCache.getMetaData().getLoadingTemplate(getContext()).defaultHeight;
+ // Compose the loading view text
+ TextView loadingTextView = (TextView) LayoutInflater.from(getContext()).inflate(
+ com.android.internal.R.layout.remote_views_adapter_default_loading_view,
+ this, false);
+ loadingTextView.setHeight(viewHeight);
+ return loadingTextView;
}
@Override
@@ -359,7 +398,7 @@
if (refs != null) {
// Notify all the references for that position of the newly loaded RemoteViews
for (final RemoteViewsFrameLayout ref : refs) {
- ref.onRemoteViewsLoaded(view, mRemoteViewsOnClickHandler);
+ ref.onRemoteViewsLoaded(view, mRemoteViewsOnClickHandler, true);
if (mViewToLinkedList.containsKey(ref)) {
mViewToLinkedList.remove(ref);
}
@@ -402,9 +441,7 @@
// Used to determine how to construct loading views. If a loading view is not specified
// by the user, then we try and load the first view, and use its height as the height for
// the default loading view.
- RemoteViews mUserLoadingView;
- RemoteViews mFirstView;
- int mFirstViewHeight;
+ LoadingViewTemplate loadingTemplate;
// A mapping from type id to a set of unique type ids
private final SparseIntArray mTypeIdIndexMap = new SparseIntArray();
@@ -418,7 +455,7 @@
count = d.count;
viewTypeCount = d.viewTypeCount;
hasStableIds = d.hasStableIds;
- setLoadingViewTemplates(d.mUserLoadingView, d.mFirstView);
+ loadingTemplate = d.loadingTemplate;
}
}
@@ -428,20 +465,10 @@
// by default there is at least one dummy view type
viewTypeCount = 1;
hasStableIds = true;
- mUserLoadingView = null;
- mFirstView = null;
- mFirstViewHeight = 0;
+ loadingTemplate = null;
mTypeIdIndexMap.clear();
}
- public void setLoadingViewTemplates(RemoteViews loadingView, RemoteViews firstView) {
- mUserLoadingView = loadingView;
- if (firstView != null) {
- mFirstView = firstView;
- mFirstViewHeight = -1;
- }
- }
-
public int getMappedViewType(int typeId) {
int mappedTypeId = mTypeIdIndexMap.get(typeId, -1);
if (mappedTypeId == -1) {
@@ -457,33 +484,11 @@
return (mappedType < viewTypeCount);
}
- /**
- * Creates a default loading view. Uses the size of the first row as a guide for the
- * size of the loading view.
- */
- private synchronized View createDefaultLoadingView(ViewGroup parent) {
- final Context context = parent.getContext();
- if (mFirstViewHeight < 0) {
- try {
- View firstView = mFirstView.apply(parent.getContext(), parent);
- firstView.measure(
- MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
- MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
- mFirstViewHeight = firstView.getMeasuredHeight();
- } catch (Exception e) {
- float density = context.getResources().getDisplayMetrics().density;
- mFirstViewHeight = Math.round(sDefaultLoadingViewHeight * density);
- Log.w(TAG, "Error inflating first RemoteViews" + e);
- }
- mFirstView = null;
+ public synchronized LoadingViewTemplate getLoadingTemplate(Context context) {
+ if (loadingTemplate == null) {
+ loadingTemplate = new LoadingViewTemplate(null, context);
}
-
- // Compose the loading view text
- TextView loadingTextView = (TextView) LayoutInflater.from(context).inflate(
- com.android.internal.R.layout.remote_views_adapter_default_loading_view,
- parent, false);
- loadingTextView.setHeight(mFirstViewHeight);
- return loadingTextView;
+ return loadingTemplate;
}
}
@@ -772,7 +777,7 @@
}
public RemoteViewsAdapter(Context context, Intent intent,
- RemoteAdapterConnectionCallback callback) {
+ RemoteAdapterConnectionCallback callback, boolean useAsyncLoader) {
mContext = context;
mIntent = intent;
@@ -781,7 +786,6 @@
}
mAppWidgetId = intent.getIntExtra(RemoteViews.EXTRA_REMOTEADAPTER_APPWIDGET_ID, -1);
- mLayoutInflater = LayoutInflater.from(context);
mRequestedViews = new RemoteViewsFrameLayoutRefSet();
// Strip the previously injected app widget id from service intent
@@ -794,6 +798,7 @@
mWorkerThread.start();
mWorkerQueue = new Handler(mWorkerThread.getLooper());
mMainQueue = new Handler(Looper.myLooper(), this);
+ mAsyncViewLoadExecutor = useAsyncLoader ? new HandlerThreadExecutor(mWorkerThread) : null;
if (sCacheRemovalThread == null) {
sCacheRemovalThread = new HandlerThread("RemoteViewsAdapter-cachePruner");
@@ -941,10 +946,14 @@
boolean hasStableIds = factory.hasStableIds();
int viewTypeCount = factory.getViewTypeCount();
int count = factory.getCount();
- RemoteViews loadingView = factory.getLoadingView();
- RemoteViews firstView = null;
- if ((count > 0) && (loadingView == null)) {
- firstView = factory.getViewAt(0);
+ LoadingViewTemplate loadingTemplate =
+ new LoadingViewTemplate(factory.getLoadingView(), mContext);
+ if ((count > 0) && (loadingTemplate.remoteViews == null)) {
+ RemoteViews firstView = factory.getViewAt(0);
+ if (firstView != null) {
+ loadingTemplate.loadFirstViewHeight(firstView, mContext,
+ new HandlerThreadExecutor(mWorkerThread));
+ }
}
final RemoteViewsMetaData tmpMetaData = mCache.getTemporaryMetaData();
synchronized (tmpMetaData) {
@@ -952,7 +961,7 @@
// We +1 because the base view type is the loading view
tmpMetaData.viewTypeCount = viewTypeCount + 1;
tmpMetaData.count = count;
- tmpMetaData.setLoadingViewTemplates(loadingView, firstView);
+ tmpMetaData.loadingTemplate = loadingTemplate;
}
} catch(RemoteException e) {
processException("updateMetaData", e);
@@ -1100,18 +1109,25 @@
hasNewItems = mCache.queuePositionsToBePreloadedFromRequestedPosition(position);
}
- final RemoteViewsFrameLayout layout =
- (convertView instanceof RemoteViewsFrameLayout)
- ? (RemoteViewsFrameLayout) convertView
- : new RemoteViewsFrameLayout(parent.getContext(), mCache);
+ final RemoteViewsFrameLayout layout;
+ if (convertView instanceof RemoteViewsFrameLayout) {
+ layout = (RemoteViewsFrameLayout) convertView;
+ } else {
+ layout = new RemoteViewsFrameLayout(parent.getContext(), mCache);
+ layout.setAsyncExecutor(mAsyncViewLoadExecutor);
+ }
+
if (isInCache) {
- layout.onRemoteViewsLoaded(rv, mRemoteViewsOnClickHandler);
+ // Apply the view synchronously if possible, to avoid flickering
+ layout.onRemoteViewsLoaded(rv, mRemoteViewsOnClickHandler, false);
if (hasNewItems) loadNextIndexInBackground();
} else {
// If the views is not loaded, apply the loading view. If the loading view doesn't
// exist, the layout will create a default view based on the firstView height.
- layout.onRemoteViewsLoaded(mCache.getMetaData().mUserLoadingView,
- mRemoteViewsOnClickHandler);
+ layout.onRemoteViewsLoaded(
+ mCache.getMetaData().getLoadingTemplate(mContext).remoteViews,
+ mRemoteViewsOnClickHandler,
+ false);
mRequestedViews.add(position, layout);
mCache.queueRequestedPositionToLoad(position);
loadNextIndexInBackground();
@@ -1285,4 +1301,58 @@
mMainQueue.removeMessages(sUnbindServiceMessageType);
return mServiceConnection.isConnected();
}
+
+ private static class HandlerThreadExecutor implements Executor {
+ private final HandlerThread mThread;
+
+ HandlerThreadExecutor(HandlerThread thread) {
+ mThread = thread;
+ }
+
+ @Override
+ public void execute(Runnable runnable) {
+ if (Thread.currentThread().getId() == mThread.getId()) {
+ runnable.run();
+ } else {
+ new Handler(mThread.getLooper()).post(runnable);
+ }
+ }
+ }
+
+ private static class LoadingViewTemplate {
+ public final RemoteViews remoteViews;
+ public int defaultHeight;
+
+ LoadingViewTemplate(RemoteViews views, Context context) {
+ remoteViews = views;
+
+ float density = context.getResources().getDisplayMetrics().density;
+ defaultHeight = Math.round(sDefaultLoadingViewHeight * density);
+ }
+
+ public void loadFirstViewHeight(
+ RemoteViews firstView, Context context, Executor executor) {
+ // Inflate the first view on the worker thread
+ firstView.applyAsync(context, new RemoteViewsFrameLayout(context, null), executor,
+ new RemoteViews.OnViewAppliedListener() {
+ @Override
+ public void onViewApplied(View v) {
+ try {
+ v.measure(
+ MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
+ MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
+ defaultHeight = v.getMeasuredHeight();
+ } catch (Exception e) {
+ onError(e);
+ }
+ }
+
+ @Override
+ public void onError(Exception e) {
+ // Do nothing. The default height will stay the same.
+ Log.w(TAG, "Error inflating first RemoteViews", e);
+ }
+ });
+ }
+ }
}
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index 7950685..506a284 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -119,12 +119,15 @@
android/graphics/DrawFilter.cpp \
android/graphics/FontFamily.cpp \
android/graphics/CreateJavaOutputStreamAdaptor.cpp \
+ android/graphics/GIFMovie.cpp \
android/graphics/Graphics.cpp \
android/graphics/HarfBuzzNGFaceSkia.cpp \
android/graphics/Interpolator.cpp \
android/graphics/MaskFilter.cpp \
android/graphics/Matrix.cpp \
android/graphics/Movie.cpp \
+ android/graphics/MovieImpl.cpp \
+ android/graphics/Movie_FactoryDefault.cpp \
android/graphics/NinePatch.cpp \
android/graphics/NinePatchPeeker.cpp \
android/graphics/Paint.cpp \
@@ -200,6 +203,7 @@
$(TOP)/system/core/include \
$(TOP)/system/media/camera/include \
$(TOP)/system/netd/include \
+ external/giflib \
external/pdfium/core/include/fpdfapi \
external/pdfium/fpdfsdk/include \
external/pdfium/public \
@@ -219,6 +223,9 @@
external/freetype/include
# TODO: clean up Minikin so it doesn't need the freetype include
+LOCAL_STATIC_LIBRARIES := \
+ libgif \
+
LOCAL_SHARED_LIBRARIES := \
libmemtrack \
libandroidfw \
diff --git a/core/jni/android/graphics/GIFMovie.cpp b/core/jni/android/graphics/GIFMovie.cpp
new file mode 100644
index 0000000..035417e
--- /dev/null
+++ b/core/jni/android/graphics/GIFMovie.cpp
@@ -0,0 +1,451 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#include "Movie.h"
+#include "SkColor.h"
+#include "SkColorPriv.h"
+#include "SkStream.h"
+#include "SkTemplates.h"
+#include "SkUtils.h"
+
+#include "gif_lib.h"
+
+#if GIFLIB_MAJOR < 5 || (GIFLIB_MAJOR == 5 && GIFLIB_MINOR == 0)
+#define DGifCloseFile(a, b) DGifCloseFile(a)
+#endif
+
+class GIFMovie : public Movie {
+public:
+ GIFMovie(SkStream* stream);
+ virtual ~GIFMovie();
+
+protected:
+ virtual bool onGetInfo(Info*);
+ virtual bool onSetTime(SkMSec);
+ virtual bool onGetBitmap(SkBitmap*);
+
+private:
+ GifFileType* fGIF;
+ int fCurrIndex;
+ int fLastDrawIndex;
+ SkBitmap fBackup;
+ SkColor fPaintingColor;
+};
+
+static int Decode(GifFileType* fileType, GifByteType* out, int size) {
+ SkStream* stream = (SkStream*) fileType->UserData;
+ return (int) stream->read(out, size);
+}
+
+GIFMovie::GIFMovie(SkStream* stream)
+{
+#if GIFLIB_MAJOR < 5
+ fGIF = DGifOpen( stream, Decode );
+#else
+ fGIF = DGifOpen( stream, Decode, nullptr );
+#endif
+ if (nullptr == fGIF)
+ return;
+
+ if (DGifSlurp(fGIF) != GIF_OK)
+ {
+ DGifCloseFile(fGIF, nullptr);
+ fGIF = nullptr;
+ }
+ fCurrIndex = -1;
+ fLastDrawIndex = -1;
+ fPaintingColor = SkPackARGB32(0, 0, 0, 0);
+}
+
+GIFMovie::~GIFMovie()
+{
+ if (fGIF)
+ DGifCloseFile(fGIF, nullptr);
+}
+
+static SkMSec savedimage_duration(const SavedImage* image)
+{
+ for (int j = 0; j < image->ExtensionBlockCount; j++)
+ {
+ if (image->ExtensionBlocks[j].Function == GRAPHICS_EXT_FUNC_CODE)
+ {
+ SkASSERT(image->ExtensionBlocks[j].ByteCount >= 4);
+ const uint8_t* b = (const uint8_t*)image->ExtensionBlocks[j].Bytes;
+ return ((b[2] << 8) | b[1]) * 10;
+ }
+ }
+ return 0;
+}
+
+bool GIFMovie::onGetInfo(Info* info)
+{
+ if (nullptr == fGIF)
+ return false;
+
+ SkMSec dur = 0;
+ for (int i = 0; i < fGIF->ImageCount; i++)
+ dur += savedimage_duration(&fGIF->SavedImages[i]);
+
+ info->fDuration = dur;
+ info->fWidth = fGIF->SWidth;
+ info->fHeight = fGIF->SHeight;
+ info->fIsOpaque = false; // how to compute?
+ return true;
+}
+
+bool GIFMovie::onSetTime(SkMSec time)
+{
+ if (nullptr == fGIF)
+ return false;
+
+ SkMSec dur = 0;
+ for (int i = 0; i < fGIF->ImageCount; i++)
+ {
+ dur += savedimage_duration(&fGIF->SavedImages[i]);
+ if (dur >= time)
+ {
+ fCurrIndex = i;
+ return fLastDrawIndex != fCurrIndex;
+ }
+ }
+ fCurrIndex = fGIF->ImageCount - 1;
+ return true;
+}
+
+static void copyLine(uint32_t* dst, const unsigned char* src, const ColorMapObject* cmap,
+ int transparent, int width)
+{
+ for (; width > 0; width--, src++, dst++) {
+ if (*src != transparent) {
+ const GifColorType& col = cmap->Colors[*src];
+ *dst = SkPackARGB32(0xFF, col.Red, col.Green, col.Blue);
+ }
+ }
+}
+
+#if GIFLIB_MAJOR < 5
+static void copyInterlaceGroup(SkBitmap* bm, const unsigned char*& src,
+ const ColorMapObject* cmap, int transparent, int copyWidth,
+ int copyHeight, const GifImageDesc& imageDesc, int rowStep,
+ int startRow)
+{
+ int row;
+ // every 'rowStep'th row, starting with row 'startRow'
+ for (row = startRow; row < copyHeight; row += rowStep) {
+ uint32_t* dst = bm->getAddr32(imageDesc.Left, imageDesc.Top + row);
+ copyLine(dst, src, cmap, transparent, copyWidth);
+ src += imageDesc.Width;
+ }
+
+ // pad for rest height
+ src += imageDesc.Width * ((imageDesc.Height - row + rowStep - 1) / rowStep);
+}
+
+static void blitInterlace(SkBitmap* bm, const SavedImage* frame, const ColorMapObject* cmap,
+ int transparent)
+{
+ int width = bm->width();
+ int height = bm->height();
+ GifWord copyWidth = frame->ImageDesc.Width;
+ if (frame->ImageDesc.Left + copyWidth > width) {
+ copyWidth = width - frame->ImageDesc.Left;
+ }
+
+ GifWord copyHeight = frame->ImageDesc.Height;
+ if (frame->ImageDesc.Top + copyHeight > height) {
+ copyHeight = height - frame->ImageDesc.Top;
+ }
+
+ // deinterlace
+ const unsigned char* src = (unsigned char*)frame->RasterBits;
+
+ // group 1 - every 8th row, starting with row 0
+ copyInterlaceGroup(bm, src, cmap, transparent, copyWidth, copyHeight, frame->ImageDesc, 8, 0);
+
+ // group 2 - every 8th row, starting with row 4
+ copyInterlaceGroup(bm, src, cmap, transparent, copyWidth, copyHeight, frame->ImageDesc, 8, 4);
+
+ // group 3 - every 4th row, starting with row 2
+ copyInterlaceGroup(bm, src, cmap, transparent, copyWidth, copyHeight, frame->ImageDesc, 4, 2);
+
+ copyInterlaceGroup(bm, src, cmap, transparent, copyWidth, copyHeight, frame->ImageDesc, 2, 1);
+}
+#endif
+
+static void blitNormal(SkBitmap* bm, const SavedImage* frame, const ColorMapObject* cmap,
+ int transparent)
+{
+ int width = bm->width();
+ int height = bm->height();
+ const unsigned char* src = (unsigned char*)frame->RasterBits;
+ uint32_t* dst = bm->getAddr32(frame->ImageDesc.Left, frame->ImageDesc.Top);
+ GifWord copyWidth = frame->ImageDesc.Width;
+ if (frame->ImageDesc.Left + copyWidth > width) {
+ copyWidth = width - frame->ImageDesc.Left;
+ }
+
+ GifWord copyHeight = frame->ImageDesc.Height;
+ if (frame->ImageDesc.Top + copyHeight > height) {
+ copyHeight = height - frame->ImageDesc.Top;
+ }
+
+ for (; copyHeight > 0; copyHeight--) {
+ copyLine(dst, src, cmap, transparent, copyWidth);
+ src += frame->ImageDesc.Width;
+ dst += width;
+ }
+}
+
+static void fillRect(SkBitmap* bm, GifWord left, GifWord top, GifWord width, GifWord height,
+ uint32_t col)
+{
+ int bmWidth = bm->width();
+ int bmHeight = bm->height();
+ uint32_t* dst = bm->getAddr32(left, top);
+ GifWord copyWidth = width;
+ if (left + copyWidth > bmWidth) {
+ copyWidth = bmWidth - left;
+ }
+
+ GifWord copyHeight = height;
+ if (top + copyHeight > bmHeight) {
+ copyHeight = bmHeight - top;
+ }
+
+ for (; copyHeight > 0; copyHeight--) {
+ sk_memset32(dst, col, copyWidth);
+ dst += bmWidth;
+ }
+}
+
+static void drawFrame(SkBitmap* bm, const SavedImage* frame, const ColorMapObject* cmap)
+{
+ int transparent = -1;
+
+ for (int i = 0; i < frame->ExtensionBlockCount; ++i) {
+ ExtensionBlock* eb = frame->ExtensionBlocks + i;
+ if (eb->Function == GRAPHICS_EXT_FUNC_CODE &&
+ eb->ByteCount == 4) {
+ bool has_transparency = ((eb->Bytes[0] & 1) == 1);
+ if (has_transparency) {
+ transparent = (unsigned char)eb->Bytes[3];
+ }
+ }
+ }
+
+ if (frame->ImageDesc.ColorMap != nullptr) {
+ // use local color table
+ cmap = frame->ImageDesc.ColorMap;
+ }
+
+ if (cmap == nullptr || cmap->ColorCount != (1 << cmap->BitsPerPixel)) {
+ SkDEBUGFAIL("bad colortable setup");
+ return;
+ }
+
+#if GIFLIB_MAJOR < 5
+ // before GIFLIB 5, de-interlacing wasn't done by library at load time
+ if (frame->ImageDesc.Interlace) {
+ blitInterlace(bm, frame, cmap, transparent);
+ return;
+ }
+#endif
+
+ blitNormal(bm, frame, cmap, transparent);
+}
+
+static bool checkIfWillBeCleared(const SavedImage* frame)
+{
+ for (int i = 0; i < frame->ExtensionBlockCount; ++i) {
+ ExtensionBlock* eb = frame->ExtensionBlocks + i;
+ if (eb->Function == GRAPHICS_EXT_FUNC_CODE &&
+ eb->ByteCount == 4) {
+ // check disposal method
+ int disposal = ((eb->Bytes[0] >> 2) & 7);
+ if (disposal == 2 || disposal == 3) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+static void getTransparencyAndDisposalMethod(const SavedImage* frame, bool* trans, int* disposal)
+{
+ *trans = false;
+ *disposal = 0;
+ for (int i = 0; i < frame->ExtensionBlockCount; ++i) {
+ ExtensionBlock* eb = frame->ExtensionBlocks + i;
+ if (eb->Function == GRAPHICS_EXT_FUNC_CODE &&
+ eb->ByteCount == 4) {
+ *trans = ((eb->Bytes[0] & 1) == 1);
+ *disposal = ((eb->Bytes[0] >> 2) & 7);
+ }
+ }
+}
+
+// return true if area of 'target' is completely covers area of 'covered'
+static bool checkIfCover(const SavedImage* target, const SavedImage* covered)
+{
+ if (target->ImageDesc.Left <= covered->ImageDesc.Left
+ && covered->ImageDesc.Left + covered->ImageDesc.Width <=
+ target->ImageDesc.Left + target->ImageDesc.Width
+ && target->ImageDesc.Top <= covered->ImageDesc.Top
+ && covered->ImageDesc.Top + covered->ImageDesc.Height <=
+ target->ImageDesc.Top + target->ImageDesc.Height) {
+ return true;
+ }
+ return false;
+}
+
+static void disposeFrameIfNeeded(SkBitmap* bm, const SavedImage* cur, const SavedImage* next,
+ SkBitmap* backup, SkColor color)
+{
+ // We can skip disposal process if next frame is not transparent
+ // and completely covers current area
+ bool curTrans;
+ int curDisposal;
+ getTransparencyAndDisposalMethod(cur, &curTrans, &curDisposal);
+ bool nextTrans;
+ int nextDisposal;
+ getTransparencyAndDisposalMethod(next, &nextTrans, &nextDisposal);
+ if ((curDisposal == 2 || curDisposal == 3)
+ && (nextTrans || !checkIfCover(next, cur))) {
+ switch (curDisposal) {
+ // restore to background color
+ // -> 'background' means background under this image.
+ case 2:
+ fillRect(bm, cur->ImageDesc.Left, cur->ImageDesc.Top,
+ cur->ImageDesc.Width, cur->ImageDesc.Height,
+ color);
+ break;
+
+ // restore to previous
+ case 3:
+ bm->swap(*backup);
+ break;
+ }
+ }
+
+ // Save current image if next frame's disposal method == 3
+ if (nextDisposal == 3) {
+ const uint32_t* src = bm->getAddr32(0, 0);
+ uint32_t* dst = backup->getAddr32(0, 0);
+ int cnt = bm->width() * bm->height();
+ memcpy(dst, src, cnt*sizeof(uint32_t));
+ }
+}
+
+bool GIFMovie::onGetBitmap(SkBitmap* bm)
+{
+ const GifFileType* gif = fGIF;
+ if (nullptr == gif)
+ return false;
+
+ if (gif->ImageCount < 1) {
+ return false;
+ }
+
+ const int width = gif->SWidth;
+ const int height = gif->SHeight;
+ if (width <= 0 || height <= 0) {
+ return false;
+ }
+
+ // no need to draw
+ if (fLastDrawIndex >= 0 && fLastDrawIndex == fCurrIndex) {
+ return true;
+ }
+
+ int startIndex = fLastDrawIndex + 1;
+ if (fLastDrawIndex < 0 || !bm->readyToDraw()) {
+ // first time
+
+ startIndex = 0;
+
+ // create bitmap
+ if (!bm->tryAllocN32Pixels(width, height)) {
+ return false;
+ }
+ // create bitmap for backup
+ if (!fBackup.tryAllocN32Pixels(width, height)) {
+ return false;
+ }
+ } else if (startIndex > fCurrIndex) {
+ // rewind to 1st frame for repeat
+ startIndex = 0;
+ }
+
+ int lastIndex = fCurrIndex;
+ if (lastIndex < 0) {
+ // first time
+ lastIndex = 0;
+ } else if (lastIndex > fGIF->ImageCount - 1) {
+ // this block must not be reached.
+ lastIndex = fGIF->ImageCount - 1;
+ }
+
+ SkColor bgColor = SkPackARGB32(0, 0, 0, 0);
+ if (gif->SColorMap != nullptr) {
+ const GifColorType& col = gif->SColorMap->Colors[fGIF->SBackGroundColor];
+ bgColor = SkColorSetARGB(0xFF, col.Red, col.Green, col.Blue);
+ }
+
+ // draw each frames - not intelligent way
+ for (int i = startIndex; i <= lastIndex; i++) {
+ const SavedImage* cur = &fGIF->SavedImages[i];
+ if (i == 0) {
+ bool trans;
+ int disposal;
+ getTransparencyAndDisposalMethod(cur, &trans, &disposal);
+ if (!trans && gif->SColorMap != nullptr) {
+ fPaintingColor = bgColor;
+ } else {
+ fPaintingColor = SkColorSetARGB(0, 0, 0, 0);
+ }
+
+ bm->eraseColor(fPaintingColor);
+ fBackup.eraseColor(fPaintingColor);
+ } else {
+ // Dispose previous frame before move to next frame.
+ const SavedImage* prev = &fGIF->SavedImages[i-1];
+ disposeFrameIfNeeded(bm, prev, cur, &fBackup, fPaintingColor);
+ }
+
+ // Draw frame
+ // We can skip this process if this index is not last and disposal
+ // method == 2 or method == 3
+ if (i == lastIndex || !checkIfWillBeCleared(cur)) {
+ drawFrame(bm, cur, gif->SColorMap);
+ }
+ }
+
+ // save index
+ fLastDrawIndex = lastIndex;
+ return true;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+#include "SkTRegistry.h"
+
+Movie* Factory(SkStreamRewindable* stream) {
+ char buf[GIF_STAMP_LEN];
+ if (stream->read(buf, GIF_STAMP_LEN) == GIF_STAMP_LEN) {
+ if (memcmp(GIF_STAMP, buf, GIF_STAMP_LEN) == 0 ||
+ memcmp(GIF87_STAMP, buf, GIF_STAMP_LEN) == 0 ||
+ memcmp(GIF89_STAMP, buf, GIF_STAMP_LEN) == 0) {
+ // must rewind here, since our construct wants to re-read the data
+ stream->rewind();
+ return new GIFMovie(stream);
+ }
+ }
+ return nullptr;
+}
+
+static SkTRegistry<Movie*(*)(SkStreamRewindable*)> gReg(Factory);
diff --git a/core/jni/android/graphics/Movie.cpp b/core/jni/android/graphics/Movie.cpp
index ad1b0c3..776ed66 100644
--- a/core/jni/android/graphics/Movie.cpp
+++ b/core/jni/android/graphics/Movie.cpp
@@ -2,7 +2,7 @@
#include "GraphicsJNI.h"
#include "ScopedLocalRef.h"
#include "SkFrontBufferedStream.h"
-#include "SkMovie.h"
+#include "Movie.h"
#include "SkStream.h"
#include "SkUtils.h"
#include "Utils.h"
@@ -19,7 +19,7 @@
static jmethodID gMovie_constructorMethodID;
static jfieldID gMovie_nativeInstanceID;
-jobject create_jmovie(JNIEnv* env, SkMovie* moov) {
+jobject create_jmovie(JNIEnv* env, Movie* moov) {
if (NULL == moov) {
return NULL;
}
@@ -27,11 +27,11 @@
static_cast<jlong>(reinterpret_cast<uintptr_t>(moov)));
}
-static SkMovie* J2Movie(JNIEnv* env, jobject movie) {
+static Movie* J2Movie(JNIEnv* env, jobject movie) {
SkASSERT(env);
SkASSERT(movie);
SkASSERT(env->IsInstanceOf(movie, gMovie_class));
- SkMovie* m = (SkMovie*)env->GetLongField(movie, gMovie_nativeInstanceID);
+ Movie* m = (Movie*)env->GetLongField(movie, gMovie_nativeInstanceID);
SkASSERT(m);
return m;
}
@@ -74,7 +74,7 @@
// therefore may be NULL.
SkASSERT(c != NULL);
- SkMovie* m = J2Movie(env, movie);
+ Movie* m = J2Movie(env, movie);
const SkBitmap& b = m->bitmap();
sk_sp<android::Bitmap> wrapper = android::Bitmap::createFrom(b.info(), *b.pixelRef());
c->drawBitmap(*wrapper, fx, fy, p);
@@ -84,7 +84,7 @@
android::Asset* asset = reinterpret_cast<android::Asset*>(native_asset);
if (asset == NULL) return NULL;
android::AssetStreamAdaptor stream(asset);
- SkMovie* moov = SkMovie::DecodeStream(&stream);
+ Movie* moov = Movie::DecodeStream(&stream);
return create_jmovie(env, moov);
}
@@ -107,7 +107,7 @@
std::unique_ptr<SkStreamRewindable> bufferedStream(SkFrontBufferedStream::Create(strm, 6));
SkASSERT(bufferedStream.get() != NULL);
- SkMovie* moov = SkMovie::DecodeStream(bufferedStream.get());
+ Movie* moov = Movie::DecodeStream(bufferedStream.get());
return create_jmovie(env, moov);
}
@@ -124,12 +124,12 @@
}
AutoJavaByteArray ar(env, byteArray);
- SkMovie* moov = SkMovie::DecodeMemory(ar.ptr() + offset, length);
+ Movie* moov = Movie::DecodeMemory(ar.ptr() + offset, length);
return create_jmovie(env, moov);
}
static void movie_destructor(JNIEnv* env, jobject, jlong movieHandle) {
- SkMovie* movie = (SkMovie*) movieHandle;
+ Movie* movie = (Movie*) movieHandle;
delete movie;
}
diff --git a/core/jni/android/graphics/Movie.h b/core/jni/android/graphics/Movie.h
new file mode 100644
index 0000000..c0fbe4f
--- /dev/null
+++ b/core/jni/android/graphics/Movie.h
@@ -0,0 +1,78 @@
+
+/*
+ * Copyright 2008 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#ifndef Movie_DEFINED
+#define Movie_DEFINED
+
+#include "SkRefCnt.h"
+#include "SkCanvas.h"
+
+class SkStreamRewindable;
+
+class Movie : public SkRefCnt {
+public:
+ /** Try to create a movie from the stream. If the stream format is not
+ supported, return NULL.
+ */
+ static Movie* DecodeStream(SkStreamRewindable*);
+ /** Try to create a movie from the specified file path. If the file is not
+ found, or the format is not supported, return NULL. If a movie is
+ returned, the stream may be retained by the movie (via ref()) until
+ the movie is finished with it (by calling unref()).
+ */
+ static Movie* DecodeFile(const char path[]);
+ /** Try to create a movie from the specified memory.
+ If the format is not supported, return NULL. If a movie is returned,
+ the data will have been read or copied, and so the caller may free
+ it.
+ */
+ static Movie* DecodeMemory(const void* data, size_t length);
+
+ SkMSec duration();
+ int width();
+ int height();
+ int isOpaque();
+
+ /** Specify the time code (between 0...duration) to sample a bitmap
+ from the movie. Returns true if this time code generated a different
+ bitmap/frame from the previous state (i.e. true means you need to
+ redraw).
+ */
+ bool setTime(SkMSec);
+
+ // return the right bitmap for the current time code
+ const SkBitmap& bitmap();
+
+protected:
+ struct Info {
+ SkMSec fDuration;
+ int fWidth;
+ int fHeight;
+ bool fIsOpaque;
+ };
+
+ virtual bool onGetInfo(Info*) = 0;
+ virtual bool onSetTime(SkMSec) = 0;
+ virtual bool onGetBitmap(SkBitmap*) = 0;
+
+ // visible for subclasses
+ Movie();
+
+private:
+ Info fInfo;
+ SkMSec fCurrTime;
+ SkBitmap fBitmap;
+ bool fNeedBitmap;
+
+ void ensureInfo();
+
+ typedef SkRefCnt INHERITED;
+};
+
+#endif
diff --git a/core/jni/android/graphics/MovieImpl.cpp b/core/jni/android/graphics/MovieImpl.cpp
new file mode 100644
index 0000000..ae9e04e
--- /dev/null
+++ b/core/jni/android/graphics/MovieImpl.cpp
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "Movie.h"
+#include "SkCanvas.h"
+#include "SkPaint.h"
+
+// We should never see this in normal operation since our time values are
+// 0-based. So we use it as a sentinal.
+#define UNINITIALIZED_MSEC ((SkMSec)-1)
+
+Movie::Movie()
+{
+ fInfo.fDuration = UNINITIALIZED_MSEC; // uninitialized
+ fCurrTime = UNINITIALIZED_MSEC; // uninitialized
+ fNeedBitmap = true;
+}
+
+void Movie::ensureInfo()
+{
+ if (fInfo.fDuration == UNINITIALIZED_MSEC && !this->onGetInfo(&fInfo))
+ memset(&fInfo, 0, sizeof(fInfo)); // failure
+}
+
+SkMSec Movie::duration()
+{
+ this->ensureInfo();
+ return fInfo.fDuration;
+}
+
+int Movie::width()
+{
+ this->ensureInfo();
+ return fInfo.fWidth;
+}
+
+int Movie::height()
+{
+ this->ensureInfo();
+ return fInfo.fHeight;
+}
+
+int Movie::isOpaque()
+{
+ this->ensureInfo();
+ return fInfo.fIsOpaque;
+}
+
+bool Movie::setTime(SkMSec time)
+{
+ SkMSec dur = this->duration();
+ if (time > dur)
+ time = dur;
+
+ bool changed = false;
+ if (time != fCurrTime)
+ {
+ fCurrTime = time;
+ changed = this->onSetTime(time);
+ fNeedBitmap |= changed;
+ }
+ return changed;
+}
+
+const SkBitmap& Movie::bitmap()
+{
+ if (fCurrTime == UNINITIALIZED_MSEC) // uninitialized
+ this->setTime(0);
+
+ if (fNeedBitmap)
+ {
+ if (!this->onGetBitmap(&fBitmap)) // failure
+ fBitmap.reset();
+ fNeedBitmap = false;
+ }
+ return fBitmap;
+}
+
+////////////////////////////////////////////////////////////////////
+
+#include "SkStream.h"
+
+Movie* Movie::DecodeMemory(const void* data, size_t length) {
+ SkMemoryStream stream(data, length, false);
+ return Movie::DecodeStream(&stream);
+}
+
+Movie* Movie::DecodeFile(const char path[]) {
+ std::unique_ptr<SkStreamRewindable> stream = SkStream::MakeFromFile(path);
+ return stream ? Movie::DecodeStream(stream.get()) : nullptr;
+}
diff --git a/core/jni/android/graphics/Movie_FactoryDefault.cpp b/core/jni/android/graphics/Movie_FactoryDefault.cpp
new file mode 100644
index 0000000..175e0a6
--- /dev/null
+++ b/core/jni/android/graphics/Movie_FactoryDefault.cpp
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2006 The Android Open Source Project
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "Movie.h"
+#include "SkStream.h"
+
+typedef SkTRegistry<Movie*(*)(SkStreamRewindable*)> MovieReg;
+
+Movie* Movie::DecodeStream(SkStreamRewindable* stream) {
+ const MovieReg* curr = MovieReg::Head();
+ while (curr) {
+ Movie* movie = curr->factory()(stream);
+ if (movie) {
+ return movie;
+ }
+ // we must rewind only if we got nullptr, since we gave the stream to the
+ // movie, who may have already started reading from it
+ stream->rewind();
+ curr = curr->next();
+ }
+ return nullptr;
+}
diff --git a/core/res/res/layout-watch/progress_dialog_material.xml b/core/res/res/layout-watch/progress_dialog_material.xml
index 228f724..96bda1d 100644
--- a/core/res/res/layout-watch/progress_dialog_material.xml
+++ b/core/res/res/layout-watch/progress_dialog_material.xml
@@ -32,14 +32,15 @@
<ProgressBar
android:id="@id/progress"
- style="?android:attr/progressBarStyleSmall"
+ style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:max="10000"
- android:layout_marginEnd="?attr/dialogPreferredPadding" />
+ android:layout_marginEnd="8dp" />
<TextView
android:id="@+id/message"
+ android:textAppearance="?attr/textAppearanceListItem"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical" />
diff --git a/core/res/res/values-watch/dimens_material.xml b/core/res/res/values-watch/dimens_material.xml
index b48cde6..3c4904c 100644
--- a/core/res/res/values-watch/dimens_material.xml
+++ b/core/res/res/values-watch/dimens_material.xml
@@ -39,4 +39,9 @@
<!-- Date and time picker legacy dimens -->
<dimen name="picker_top_margin">1dip</dimen>
<dimen name="picker_bottom_margin">1dip</dimen>
+
+ <!-- Progress bar dimens -->
+ <dimen name="progress_bar_size_small">16dip</dimen>
+ <dimen name="progress_bar_size_medium">32dip</dimen>
+ <dimen name="progress_bar_size_large">64dip</dimen>
</resources>
diff --git a/core/res/res/values/dimens_material.xml b/core/res/res/values/dimens_material.xml
index ae31165..30e7b31 100644
--- a/core/res/res/values/dimens_material.xml
+++ b/core/res/res/values/dimens_material.xml
@@ -193,4 +193,9 @@
<!-- Date and time picker legacy dimens -->
<dimen name="picker_top_margin">16dip</dimen>
<dimen name="picker_bottom_margin">16dip</dimen>
+
+ <!-- Progress bar dimens -->
+ <dimen name="progress_bar_size_small">16dip</dimen>
+ <dimen name="progress_bar_size_medium">48dp</dimen>
+ <dimen name="progress_bar_size_large">76dp</dimen>
</resources>
diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml
index 22bdf7e..a1e12d2 100644
--- a/core/res/res/values/styles_material.xml
+++ b/core/res/res/values/styles_material.xml
@@ -739,6 +739,10 @@
<style name="Widget.Material.ProgressBar" parent="Widget.ProgressBar">
<item name="indeterminateDrawable">@drawable/progress_medium_material</item>
+ <item name="minWidth">@dimen/progress_bar_size_medium</item>
+ <item name="maxWidth">@dimen/progress_bar_size_medium</item>
+ <item name="minHeight">@dimen/progress_bar_size_medium</item>
+ <item name="maxHeight">@dimen/progress_bar_size_medium</item>
</style>
<style name="Widget.Material.ProgressBar.Inverse"/>
@@ -752,6 +756,10 @@
<style name="Widget.Material.ProgressBar.Small" parent="Widget.ProgressBar.Small">
<item name="indeterminateDrawable">@drawable/progress_small_material</item>
+ <item name="minWidth">@dimen/progress_bar_size_small</item>
+ <item name="maxWidth">@dimen/progress_bar_size_small</item>
+ <item name="minHeight">@dimen/progress_bar_size_small</item>
+ <item name="maxHeight">@dimen/progress_bar_size_small</item>
</style>
<style name="Widget.Material.ProgressBar.Small.Inverse"/>
@@ -759,6 +767,10 @@
<style name="Widget.Material.ProgressBar.Large" parent="Widget.ProgressBar.Large">
<item name="indeterminateDrawable">@drawable/progress_large_material</item>
+ <item name="minWidth">@dimen/progress_bar_size_large</item>
+ <item name="maxWidth">@dimen/progress_bar_size_large</item>
+ <item name="minHeight">@dimen/progress_bar_size_large</item>
+ <item name="maxHeight">@dimen/progress_bar_size_large</item>
</style>
<style name="Widget.Material.ProgressBar.Large.Inverse"/>
diff --git a/packages/BackupRestoreConfirmation/src/com/android/backupconfirm/BackupRestoreConfirmation.java b/packages/BackupRestoreConfirmation/src/com/android/backupconfirm/BackupRestoreConfirmation.java
index 0b7b99f..bfc9ff3 100644
--- a/packages/BackupRestoreConfirmation/src/com/android/backupconfirm/BackupRestoreConfirmation.java
+++ b/packages/BackupRestoreConfirmation/src/com/android/backupconfirm/BackupRestoreConfirmation.java
@@ -272,7 +272,7 @@
boolean deviceIsEncrypted() {
try {
return mMountService.getEncryptionState()
- != IMountService.ENCRYPTION_STATE_NONE
+ != StorageManager.ENCRYPTION_STATE_NONE
&& mMountService.getPasswordType()
!= StorageManager.CRYPT_TYPE_DEFAULT;
} catch (Exception e) {
diff --git a/packages/SystemUI/src/com/android/systemui/DejankUtils.java b/packages/SystemUI/src/com/android/systemui/DejankUtils.java
index f8ce1d3..eba1d0f 100644
--- a/packages/SystemUI/src/com/android/systemui/DejankUtils.java
+++ b/packages/SystemUI/src/com/android/systemui/DejankUtils.java
@@ -16,8 +16,9 @@
package com.android.systemui;
+import com.android.systemui.util.Assert;
+
import android.os.Handler;
-import android.os.Looper;
import android.view.Choreographer;
import java.util.ArrayList;
@@ -50,7 +51,7 @@
* <p>Needs to be called from the main thread.
*/
public static void postAfterTraversal(Runnable r) {
- throwIfNotCalledOnMainThread();
+ Assert.isMainThread();
sPendingRunnables.add(r);
postAnimationCallback();
}
@@ -61,7 +62,7 @@
* <p>Needs to be called from the main thread.
*/
public static void removeCallbacks(Runnable r) {
- throwIfNotCalledOnMainThread();
+ Assert.isMainThread();
sPendingRunnables.remove(r);
sHandler.removeCallbacks(r);
}
@@ -70,10 +71,4 @@
sChoreographer.postCallback(Choreographer.CALLBACK_ANIMATION, sAnimationCallbackRunnable,
null);
}
-
- private static void throwIfNotCalledOnMainThread() {
- if (!Looper.getMainLooper().isCurrentThread()) {
- throw new IllegalStateException("should be called from the main thread.");
- }
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
new file mode 100644
index 0000000..fd1ac8e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.doze;
+
+import com.android.internal.hardware.AmbientDisplayConfiguration;
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.MetricsProto;
+import com.android.systemui.statusbar.phone.DozeParameters;
+
+import android.annotation.AnyThread;
+import android.app.ActivityManager;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.hardware.Sensor;
+import android.hardware.SensorManager;
+import android.hardware.TriggerEvent;
+import android.hardware.TriggerEventListener;
+import android.media.AudioAttributes;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.PowerManager;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.os.Vibrator;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.util.List;
+
+public class DozeSensors {
+
+ private static final boolean DEBUG = DozeService.DEBUG;
+
+ private static final String TAG = "DozeSensors";
+
+ private final Context mContext;
+ private final SensorManager mSensorManager;
+ private final TriggerSensor[] mSensors;
+ private final ContentResolver mResolver;
+ private final TriggerSensor mPickupSensor;
+ private final DozeParameters mDozeParameters;
+ private final AmbientDisplayConfiguration mConfig;
+ private final PowerManager.WakeLock mWakeLock;
+ private final Callback mCallback;
+
+ private final Handler mHandler = new Handler();
+
+
+ public DozeSensors(Context context, SensorManager sensorManager, DozeParameters dozeParameters,
+ AmbientDisplayConfiguration config, PowerManager.WakeLock wakeLock, Callback callback) {
+ mContext = context;
+ mSensorManager = sensorManager;
+ mDozeParameters = dozeParameters;
+ mConfig = config;
+ mWakeLock = wakeLock;
+ mResolver = mContext.getContentResolver();
+
+ mSensors = new TriggerSensor[] {
+ new TriggerSensor(
+ mSensorManager.getDefaultSensor(Sensor.TYPE_SIGNIFICANT_MOTION),
+ null /* setting */,
+ dozeParameters.getPulseOnSigMotion(),
+ DozeLog.PULSE_REASON_SENSOR_SIGMOTION),
+ mPickupSensor = new TriggerSensor(
+ mSensorManager.getDefaultSensor(Sensor.TYPE_PICK_UP_GESTURE),
+ Settings.Secure.DOZE_PULSE_ON_PICK_UP,
+ config.pulseOnPickupAvailable(),
+ DozeLog.PULSE_REASON_SENSOR_PICKUP),
+ new TriggerSensor(
+ findSensorWithType(config.doubleTapSensorType()),
+ Settings.Secure.DOZE_PULSE_ON_DOUBLE_TAP,
+ true /* configured */,
+ DozeLog.PULSE_REASON_SENSOR_DOUBLE_TAP)
+ };
+ mCallback = callback;
+ }
+
+ private Sensor findSensorWithType(String type) {
+ if (TextUtils.isEmpty(type)) {
+ return null;
+ }
+ List<Sensor> sensorList = mSensorManager.getSensorList(Sensor.TYPE_ALL);
+ for (Sensor s : sensorList) {
+ if (type.equals(s.getStringType())) {
+ return s;
+ }
+ }
+ return null;
+ }
+
+ public void setListen(boolean listen) {
+ for (TriggerSensor s : mSensors) {
+ s.setListening(listen);
+ if (listen) {
+ s.registerSettingsObserver(mSettingsObserver);
+ }
+ }
+ if (!listen) {
+ mResolver.unregisterContentObserver(mSettingsObserver);
+ }
+ }
+
+ public void reregisterAllSensors() {
+ for (TriggerSensor s : mSensors) {
+ s.setListening(false);
+ }
+ for (TriggerSensor s : mSensors) {
+ s.setListening(true);
+ }
+ }
+
+ public void onUserSwitched() {
+ for (TriggerSensor s : mSensors) {
+ s.updateListener();
+ }
+ }
+
+ private final ContentObserver mSettingsObserver = new ContentObserver(mHandler) {
+ @Override
+ public void onChange(boolean selfChange, Uri uri, int userId) {
+ if (userId != ActivityManager.getCurrentUser()) {
+ return;
+ }
+ for (TriggerSensor s : mSensors) {
+ s.updateListener();
+ }
+ }
+ };
+
+ public void setDisableSensorsInterferingWithProximity(boolean disable) {
+ mPickupSensor.setDisabled(disable);
+ }
+
+ private class TriggerSensor extends TriggerEventListener {
+ final Sensor mSensor;
+ final boolean mConfigured;
+ final int mPulseReason;
+ final String mSetting;
+
+ private boolean mRequested;
+ private boolean mRegistered;
+ private boolean mDisabled;
+
+ public TriggerSensor(Sensor sensor, String setting, boolean configured, int pulseReason) {
+ mSensor = sensor;
+ mSetting = setting;
+ mConfigured = configured;
+ mPulseReason = pulseReason;
+ }
+
+ public void setListening(boolean listen) {
+ if (mRequested == listen) return;
+ mRequested = listen;
+ updateListener();
+ }
+
+ public void setDisabled(boolean disabled) {
+ if (mDisabled == disabled) return;
+ mDisabled = disabled;
+ updateListener();
+ }
+
+ public void updateListener() {
+ if (!mConfigured || mSensor == null) return;
+ if (mRequested && !mDisabled && enabledBySetting() && !mRegistered) {
+ mRegistered = mSensorManager.requestTriggerSensor(this, mSensor);
+ if (DEBUG) Log.d(TAG, "requestTriggerSensor " + mRegistered);
+ } else if (mRegistered) {
+ final boolean rt = mSensorManager.cancelTriggerSensor(this, mSensor);
+ if (DEBUG) Log.d(TAG, "cancelTriggerSensor " + rt);
+ mRegistered = false;
+ }
+ }
+
+ private boolean enabledBySetting() {
+ if (TextUtils.isEmpty(mSetting)) {
+ return true;
+ }
+ return Settings.Secure.getIntForUser(mResolver, mSetting, 1,
+ UserHandle.USER_CURRENT) != 0;
+ }
+
+ @Override
+ public String toString() {
+ return new StringBuilder("{mRegistered=").append(mRegistered)
+ .append(", mRequested=").append(mRequested)
+ .append(", mDisabled=").append(mDisabled)
+ .append(", mConfigured=").append(mConfigured)
+ .append(", mSensor=").append(mSensor).append("}").toString();
+ }
+
+ @Override
+ @AnyThread
+ public void onTrigger(TriggerEvent event) {
+ mHandler.post(mWakeLock.wrap(() -> {
+ if (DEBUG)
+ Log.d(TAG, "onTrigger: " + triggerEventToString(event));
+ boolean sensorPerformsProxCheck = false;
+ if (mSensor.getType() == Sensor.TYPE_PICK_UP_GESTURE) {
+ int subType = (int) event.values[0];
+ MetricsLogger.action(
+ mContext, MetricsProto.MetricsEvent.ACTION_AMBIENT_GESTURE,
+ subType);
+ sensorPerformsProxCheck =
+ mDozeParameters.getPickupSubtypePerformsProxCheck(subType);
+ }
+
+ mRegistered = false;
+ mCallback.onSensorPulse(mPulseReason, sensorPerformsProxCheck);
+ updateListener(); // reregister, this sensor only fires once
+ }));
+ }
+
+ public void registerSettingsObserver(ContentObserver settingsObserver) {
+ if (mConfigured && !TextUtils.isEmpty(mSetting)) {
+ mResolver.registerContentObserver(
+ Settings.Secure.getUriFor(mSetting), false /* descendants */,
+ mSettingsObserver, UserHandle.USER_ALL);
+ }
+ }
+
+ private String triggerEventToString(TriggerEvent event) {
+ if (event == null) return null;
+ final StringBuilder sb = new StringBuilder("TriggerEvent[")
+ .append(event.timestamp).append(',')
+ .append(event.sensor.getName());
+ if (event.values != null) {
+ for (int i = 0; i < event.values.length; i++) {
+ sb.append(',').append(event.values[i]);
+ }
+ }
+ return sb.append(']').toString();
+ }
+ }
+
+ public interface Callback {
+ void onSensorPulse(int pulseReason, boolean sensorPerformedProxCheck);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
index 6c35243..8789845c 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
@@ -16,47 +16,38 @@
package com.android.systemui.doze;
-import android.app.ActivityManager;
import android.app.UiModeManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Configuration;
-import android.database.ContentObserver;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
-import android.hardware.TriggerEvent;
-import android.hardware.TriggerEventListener;
-import android.media.AudioAttributes;
-import android.net.Uri;
import android.os.Handler;
import android.os.PowerManager;
import android.os.SystemClock;
import android.os.UserHandle;
-import android.os.Vibrator;
-import android.provider.Settings;
import android.service.dreams.DreamService;
-import android.text.TextUtils;
import android.util.Log;
import android.view.Display;
import com.android.internal.hardware.AmbientDisplayConfiguration;
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.MetricsProto.MetricsEvent;
+import com.android.internal.util.Preconditions;
+import com.android.systemui.DejankUtils;
import com.android.systemui.SystemUIApplication;
import com.android.systemui.statusbar.phone.DozeParameters;
+import com.android.systemui.util.Assert;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.Date;
-import java.util.List;
-public class DozeService extends DreamService {
+public class DozeService extends DreamService implements DozeSensors.Callback {
private static final String TAG = "DozeService";
- private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+ static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
private static final String ACTION_BASE = "com.android.systemui.doze";
private static final String PULSE_ACTION = ACTION_BASE + ".pulse";
@@ -72,9 +63,8 @@
private final Handler mHandler = new Handler();
private DozeHost mHost;
+ private DozeSensors mDozeSensors;
private SensorManager mSensorManager;
- private TriggerSensor[] mSensors;
- private TriggerSensor mPickupSensor;
private PowerManager mPowerManager;
private PowerManager.WakeLock mWakeLock;
private UiModeManager mUiModeManager;
@@ -101,10 +91,6 @@
pw.print(" mWakeLock: held="); pw.println(mWakeLock.isHeld());
pw.print(" mHost: "); pw.println(mHost);
pw.print(" mBroadcastReceiverRegistered: "); pw.println(mBroadcastReceiverRegistered);
- for (TriggerSensor s : mSensors) {
- pw.print(" sensor: ");
- pw.println(s);
- }
pw.print(" mDisplayStateSupported: "); pw.println(mDisplayStateSupported);
pw.print(" mPowerSaveActive: "); pw.println(mPowerSaveActive);
pw.print(" mCarMode: "); pw.println(mCarMode);
@@ -129,30 +115,14 @@
mSensorManager = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE);
mConfig = new AmbientDisplayConfiguration(mContext);
- mSensors = new TriggerSensor[] {
- new TriggerSensor(
- mSensorManager.getDefaultSensor(Sensor.TYPE_SIGNIFICANT_MOTION),
- null /* setting */,
- mDozeParameters.getPulseOnSigMotion(),
- mDozeParameters.getVibrateOnSigMotion(),
- DozeLog.PULSE_REASON_SENSOR_SIGMOTION),
- mPickupSensor = new TriggerSensor(
- mSensorManager.getDefaultSensor(Sensor.TYPE_PICK_UP_GESTURE),
- Settings.Secure.DOZE_PULSE_ON_PICK_UP,
- mConfig.pulseOnPickupAvailable(), mDozeParameters.getVibrateOnPickup(),
- DozeLog.PULSE_REASON_SENSOR_PICKUP),
- new TriggerSensor(
- findSensorWithType(mConfig.doubleTapSensorType()),
- Settings.Secure.DOZE_PULSE_ON_DOUBLE_TAP, true,
- mDozeParameters.getVibrateOnPickup(),
- DozeLog.PULSE_REASON_SENSOR_DOUBLE_TAP)
- };
mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
mWakeLock.setReferenceCounted(true);
mDisplayStateSupported = mDozeParameters.getDisplayStateSupported();
mUiModeManager = (UiModeManager) mContext.getSystemService(Context.UI_MODE_SERVICE);
turnDisplayOff();
+ mDozeSensors = new DozeSensors(mContext, mSensorManager, mDozeParameters,
+ mConfig, mWakeLock, this);
}
@Override
@@ -221,6 +191,7 @@
}
private void requestPulse(final int reason, boolean performedProxCheck) {
+ Assert.isMainThread();
if (mHost != null && mDreaming && !mPulsing) {
// Let the host know we want to pulse. Wait for it to be ready, then
// turn the screen on. When finished, turn the screen off again.
@@ -282,7 +253,7 @@
if (mPulsing && mDreaming) {
mPulsing = false;
if (REREGISTER_ALL_SENSORS_ON_SCREEN_OFF) {
- reregisterAllSensors();
+ mDozeSensors.reregisterAllSensors();
}
turnDisplayOff();
}
@@ -313,22 +284,11 @@
private void listenForPulseSignals(boolean listen) {
if (DEBUG) Log.d(mTag, "listenForPulseSignals: " + listen);
- for (TriggerSensor s : mSensors) {
- s.setListening(listen);
- }
+ mDozeSensors.setListen(listen);
listenForBroadcasts(listen);
listenForNotifications(listen);
}
- private void reregisterAllSensors() {
- for (TriggerSensor s : mSensors) {
- s.setListening(false);
- }
- for (TriggerSensor s : mSensors) {
- s.setListening(true);
- }
- }
-
private void listenForBroadcasts(boolean listen) {
if (listen) {
final IntentFilter filter = new IntentFilter(PULSE_ACTION);
@@ -336,18 +296,10 @@
filter.addAction(Intent.ACTION_USER_SWITCHED);
mContext.registerReceiver(mBroadcastReceiver, filter);
- for (TriggerSensor s : mSensors) {
- if (s.mConfigured && !TextUtils.isEmpty(s.mSetting)) {
- mContext.getContentResolver().registerContentObserver(
- Settings.Secure.getUriFor(s.mSetting), false /* descendants */,
- mSettingsObserver, UserHandle.USER_ALL);
- }
- }
mBroadcastReceiverRegistered = true;
} else {
if (mBroadcastReceiverRegistered) {
mContext.unregisterReceiver(mBroadcastReceiver);
- mContext.getContentResolver().unregisterContentObserver(mSettingsObserver);
}
mBroadcastReceiverRegistered = false;
}
@@ -368,17 +320,18 @@
requestPulse(DozeLog.PULSE_REASON_NOTIFICATION);
}
- private static String triggerEventToString(TriggerEvent event) {
- if (event == null) return null;
- final StringBuilder sb = new StringBuilder("TriggerEvent[")
- .append(event.timestamp).append(',')
- .append(event.sensor.getName());
- if (event.values != null) {
- for (int i = 0; i < event.values.length; i++) {
- sb.append(',').append(event.values[i]);
- }
+ @Override
+ public void onSensorPulse(int pulseReason, boolean sensorPerformedProxCheck) {
+ requestPulse(pulseReason, sensorPerformedProxCheck);
+
+ if (pulseReason == DozeLog.PULSE_REASON_SENSOR_PICKUP) {
+ final long timeSinceNotification =
+ SystemClock.elapsedRealtime() - mNotificationPulseTime;
+ final boolean withinVibrationThreshold =
+ timeSinceNotification < mDozeParameters.getPickupVibrationThreshold();
+ DozeLog.tracePickupPulse(mContext, withinVibrationThreshold);
}
- return sb.append(']').toString();
+
}
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@@ -395,21 +348,7 @@
}
}
if (Intent.ACTION_USER_SWITCHED.equals(intent.getAction())) {
- for (TriggerSensor s : mSensors) {
- s.updateListener();
- }
- }
- }
- };
-
- private final ContentObserver mSettingsObserver = new ContentObserver(mHandler) {
- @Override
- public void onChange(boolean selfChange, Uri uri, int userId) {
- if (userId != ActivityManager.getCurrentUser()) {
- return;
- }
- for (TriggerSensor s : mSensors) {
- s.updateListener();
+ mDozeSensors.onUserSwitched();
}
}
};
@@ -442,122 +381,6 @@
}
};
- private Sensor findSensorWithType(String type) {
- if (TextUtils.isEmpty(type)) {
- return null;
- }
- List<Sensor> sensorList = mSensorManager.getSensorList(Sensor.TYPE_ALL);
- for (Sensor s : sensorList) {
- if (type.equals(s.getStringType())) {
- return s;
- }
- }
- return null;
- }
-
- private class TriggerSensor extends TriggerEventListener {
- final Sensor mSensor;
- final boolean mConfigured;
- final boolean mDebugVibrate;
- final int mPulseReason;
- final String mSetting;
-
- private boolean mRequested;
- private boolean mRegistered;
- private boolean mDisabled;
-
- public TriggerSensor(Sensor sensor, String setting, boolean configured,
- boolean debugVibrate, int pulseReason) {
- mSensor = sensor;
- mSetting = setting;
- mConfigured = configured;
- mDebugVibrate = debugVibrate;
- mPulseReason = pulseReason;
- }
-
- public void setListening(boolean listen) {
- if (mRequested == listen) return;
- mRequested = listen;
- updateListener();
- }
-
- public void setDisabled(boolean disabled) {
- if (mDisabled == disabled) return;
- mDisabled = disabled;
- updateListener();
- }
-
- public void updateListener() {
- if (!mConfigured || mSensor == null) return;
- if (mRequested && !mDisabled && enabledBySetting() && !mRegistered) {
- mRegistered = mSensorManager.requestTriggerSensor(this, mSensor);
- if (DEBUG) Log.d(mTag, "requestTriggerSensor " + mRegistered);
- } else if (mRegistered) {
- final boolean rt = mSensorManager.cancelTriggerSensor(this, mSensor);
- if (DEBUG) Log.d(mTag, "cancelTriggerSensor " + rt);
- mRegistered = false;
- }
- }
-
- private boolean enabledBySetting() {
- if (TextUtils.isEmpty(mSetting)) {
- return true;
- }
- return Settings.Secure.getIntForUser(mContext.getContentResolver(), mSetting, 1,
- UserHandle.USER_CURRENT) != 0;
- }
-
- @Override
- public String toString() {
- return new StringBuilder("{mRegistered=").append(mRegistered)
- .append(", mRequested=").append(mRequested)
- .append(", mDisabled=").append(mDisabled)
- .append(", mConfigured=").append(mConfigured)
- .append(", mDebugVibrate=").append(mDebugVibrate)
- .append(", mSensor=").append(mSensor).append("}").toString();
- }
-
- @Override
- public void onTrigger(TriggerEvent event) {
- mWakeLock.acquire();
- try {
- if (DEBUG) Log.d(mTag, "onTrigger: " + triggerEventToString(event));
- boolean sensorPerformsProxCheck = false;
- if (mSensor.getType() == Sensor.TYPE_PICK_UP_GESTURE) {
- int subType = (int) event.values[0];
- MetricsLogger.action(mContext, MetricsEvent.ACTION_AMBIENT_GESTURE, subType);
- sensorPerformsProxCheck = mDozeParameters.getPickupSubtypePerformsProxCheck(
- subType);
- }
- if (mDebugVibrate) {
- final Vibrator v = (Vibrator) mContext.getSystemService(
- Context.VIBRATOR_SERVICE);
- if (v != null) {
- v.vibrate(1000, new AudioAttributes.Builder()
- .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
- .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION).build());
- }
- }
-
- mRegistered = false;
- requestPulse(mPulseReason, sensorPerformsProxCheck);
- updateListener(); // reregister, this sensor only fires once
-
- // record pickup gesture, also keep track of whether we might have been triggered
- // by recent vibration.
- final long timeSinceNotification = SystemClock.elapsedRealtime()
- - mNotificationPulseTime;
- final boolean withinVibrationThreshold =
- timeSinceNotification < mDozeParameters.getPickupVibrationThreshold();
- if (mSensor.getType() == Sensor.TYPE_PICK_UP_GESTURE) {
- DozeLog.tracePickupPulse(mContext, withinVibrationThreshold);
- }
- } finally {
- mWakeLock.release();
- }
- }
- }
-
private abstract class ProximityCheck implements SensorEventListener, Runnable {
private static final int TIMEOUT_DELAY_MS = 500;
@@ -581,8 +404,7 @@
finishWithResult(RESULT_UNKNOWN);
return;
}
- // the pickup sensor interferes with the prox event, disable it until we have a result
- mPickupSensor.setDisabled(true);
+ mDozeSensors.setDisableSensorsInterferingWithProximity(true);
mMaxRange = sensor.getMaximumRange();
mSensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_NORMAL, 0,
@@ -614,8 +436,7 @@
if (mRegistered) {
mHandler.removeCallbacks(this);
mSensorManager.unregisterListener(this);
- // we're done - reenable the pickup sensor
- mPickupSensor.setDisabled(false);
+ mDozeSensors.setDisableSensorsInterferingWithProximity(false);
mRegistered = false;
}
onProximityResult(result);
diff --git a/packages/SystemUI/src/com/android/systemui/util/Assert.java b/packages/SystemUI/src/com/android/systemui/util/Assert.java
new file mode 100644
index 0000000..af447f3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/Assert.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.util;
+
+import android.os.Looper;
+
+/**
+ * Helper providing common assertions.
+ */
+public class Assert {
+
+ public static void isMainThread() {
+ if (!Looper.getMainLooper().isCurrentThread()) {
+ throw new IllegalStateException("should be called from the main thread.");
+ }
+ }
+}
diff --git a/services/core/proto/ipconnectivity.proto b/proto/src/ipconnectivity.proto
similarity index 100%
rename from services/core/proto/ipconnectivity.proto
rename to proto/src/ipconnectivity.proto
diff --git a/proto/src/wifi.proto b/proto/src/wifi.proto
new file mode 100644
index 0000000..9416ac1
--- /dev/null
+++ b/proto/src/wifi.proto
@@ -0,0 +1,443 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+
+package clearcut.connectivity;
+
+option java_package = "com.android.server.wifi";
+option java_outer_classname = "WifiMetricsProto";
+
+// The information about the Wifi events.
+message WifiLog {
+
+ // Session information that gets logged for every Wifi connection.
+ repeated ConnectionEvent connection_event = 1;
+
+ // Number of saved networks in the user profile.
+ optional int32 num_saved_networks = 2;
+
+ // Number of open networks in the saved networks.
+ optional int32 num_open_networks = 3;
+
+ // Number of personal networks.
+ optional int32 num_personal_networks = 4;
+
+ // Number of enterprise networks.
+ optional int32 num_enterprise_networks = 5;
+
+ // Does the user have location setting enabled.
+ optional bool is_location_enabled = 6;
+
+ // Does the user have scanning enabled.
+ optional bool is_scanning_always_enabled = 7;
+
+ // Number of times user toggled wifi using the settings menu.
+ optional int32 num_wifi_toggled_via_settings = 8;
+
+ // Number of times user toggled wifi using the airplane menu.
+ optional int32 num_wifi_toggled_via_airplane = 9;
+
+ // Number of networks added by the user.
+ optional int32 num_networks_added_by_user = 10;
+
+ // Number of networks added by applications.
+ optional int32 num_networks_added_by_apps = 11;
+
+ // Number scans that returned empty results.
+ optional int32 num_empty_scan_results = 12;
+
+ // Number scans that returned at least one result.
+ optional int32 num_non_empty_scan_results = 13;
+
+ // Number of scans that were one time.
+ optional int32 num_oneshot_scans = 14;
+
+ // Number of repeated background scans that were scheduled to the chip.
+ optional int32 num_background_scans = 15;
+
+ // Error codes that a scan can result in.
+ enum ScanReturnCode {
+
+ // Return Code is unknown.
+ SCAN_UNKNOWN = 0;
+
+ // Scan was successful.
+ SCAN_SUCCESS = 1;
+
+ // Scan was successfully started, but was interrupted.
+ SCAN_FAILURE_INTERRUPTED = 2;
+
+ // Scan failed to start because of invalid configuration
+ // (bad channel, etc).
+ SCAN_FAILURE_INVALID_CONFIGURATION = 3;
+
+ // Could not start a scan because wifi is disabled.
+ FAILURE_WIFI_DISABLED = 4;
+
+ }
+
+ // Mapping of error codes to the number of times that scans resulted
+ // in that error.
+ repeated ScanReturnEntry scan_return_entries = 16;
+
+ message ScanReturnEntry {
+
+ // Return code of the scan.
+ optional ScanReturnCode scan_return_code = 1;
+
+ // Number of entries that were found in the scan.
+ optional int32 scan_results_count = 2;
+ }
+
+ // State of the Wifi.
+ enum WifiState {
+
+ // State is unknown.
+ WIFI_UNKNOWN = 0;
+
+ // Wifi is disabled.
+ WIFI_DISABLED = 1;
+
+ // Wifi is enabled.
+ WIFI_DISCONNECTED = 2;
+
+ // Wifi is enabled and associated with an AP.
+ WIFI_ASSOCIATED = 3;
+ }
+
+ // Mapping of system state to the number of times that scans were requested in
+ // that state
+ repeated WifiSystemStateEntry wifi_system_state_entries = 17;
+
+ message WifiSystemStateEntry {
+
+ // Current WiFi state.
+ optional WifiState wifi_state = 1;
+
+ // Count of scans in state.
+ optional int32 wifi_state_count = 2;
+
+ // Is screen on.
+ optional bool is_screen_on = 3;
+ }
+
+ // Mapping of Error/Success codes to the number of background scans that resulted in it
+ repeated ScanReturnEntry background_scan_return_entries = 18;
+
+ // Mapping of system state to the number of times that Background scans were requested in that
+ // state
+ repeated WifiSystemStateEntry background_scan_request_state = 19;
+
+ // Total number of times the Watchdog of Last Resort triggered, resetting the wifi stack
+ optional int32 num_last_resort_watchdog_triggers = 20;
+
+ // Total number of networks over bad association threshold when watchdog triggered
+ optional int32 num_last_resort_watchdog_bad_association_networks_total = 21;
+
+ // Total number of networks over bad authentication threshold when watchdog triggered
+ optional int32 num_last_resort_watchdog_bad_authentication_networks_total = 22;
+
+ // Total number of networks over bad dhcp threshold when watchdog triggered
+ optional int32 num_last_resort_watchdog_bad_dhcp_networks_total = 23;
+
+ // Total number of networks over bad other threshold when watchdog triggered
+ optional int32 num_last_resort_watchdog_bad_other_networks_total = 24;
+
+ // Total count of networks seen when watchdog triggered
+ optional int32 num_last_resort_watchdog_available_networks_total = 25;
+
+ // Total count of triggers with atleast one bad association network
+ optional int32 num_last_resort_watchdog_triggers_with_bad_association = 26;
+
+ // Total count of triggers with atleast one bad authentication network
+ optional int32 num_last_resort_watchdog_triggers_with_bad_authentication = 27;
+
+ // Total count of triggers with atleast one bad dhcp network
+ optional int32 num_last_resort_watchdog_triggers_with_bad_dhcp = 28;
+
+ // Total count of triggers with atleast one bad other network
+ optional int32 num_last_resort_watchdog_triggers_with_bad_other = 29;
+
+ // Count of times connectivity watchdog confirmed pno is working
+ optional int32 num_connectivity_watchdog_pno_good = 30;
+
+ // Count of times connectivity watchdog found pno not working
+ optional int32 num_connectivity_watchdog_pno_bad = 31;
+
+ // Count of times connectivity watchdog confirmed background scan is working
+ optional int32 num_connectivity_watchdog_background_good = 32;
+
+ // Count of times connectivity watchdog found background scan not working
+ optional int32 num_connectivity_watchdog_background_bad = 33;
+
+ // The time duration represented by this wifi log, from start to end of capture
+ optional int32 record_duration_sec = 34;
+
+ // Counts the occurrences of each individual RSSI poll level
+ repeated RssiPollCount rssi_poll_rssi_count = 35;
+
+ // Total number of times WiFi connected immediately after a Last Resort Watchdog trigger,
+ // without new networks becoming available.
+ optional int32 num_last_resort_watchdog_successes = 36;
+
+ // Total number of saved hidden networks
+ optional int32 num_hidden_networks = 37;
+
+ // Total number of saved passpoint / hotspot 2.0 networks
+ optional int32 num_passpoint_networks = 38;
+
+ // Total number of scan results
+ optional int32 num_total_scan_results = 39;
+
+ // Total number of scan results for open networks
+ optional int32 num_open_network_scan_results = 40;
+
+ // Total number of scan results for personal networks
+ optional int32 num_personal_network_scan_results = 41;
+
+ // Total number of scan results for enterprise networks
+ optional int32 num_enterprise_network_scan_results = 42;
+
+ // Total number of scan results for hidden networks
+ optional int32 num_hidden_network_scan_results = 43;
+
+ // Total number of scan results for hotspot 2.0 r1 networks
+ optional int32 num_hotspot2_r1_network_scan_results = 44;
+
+ // Total number of scan results for hotspot 2.0 r2 networks
+ optional int32 num_hotspot2_r2_network_scan_results = 45;
+
+ // Total number of scans handled by framework (oneshot or otherwise)
+ optional int32 num_scans = 46;
+
+ // Counts the occurrences of each alert reason.
+ repeated AlertReasonCount alert_reason_count = 47;
+
+ // Counts the occurrences of each Wifi score
+ repeated WifiScoreCount wifi_score_count = 48;
+
+ // Histogram of Soft AP Durations
+ repeated SoftApDurationBucket soft_ap_duration = 49;
+
+ // Histogram of Soft AP ReturnCode
+ repeated SoftApReturnCodeCount soft_ap_return_code = 50;
+
+ // Histogram of the delta between scan result RSSI and RSSI polls
+ repeated RssiPollCount rssi_poll_delta_count = 51;
+}
+
+// Information that gets logged for every WiFi connection.
+message RouterFingerPrint {
+
+ enum RoamType {
+
+ // Type is unknown.
+ ROAM_TYPE_UNKNOWN = 0;
+
+ // No roaming - usually happens on a single band (2.4 GHz) router.
+ ROAM_TYPE_NONE = 1;
+
+ // Enterprise router.
+ ROAM_TYPE_ENTERPRISE = 2;
+
+ // DBDC => Dual Band Dual Concurrent essentially a router that
+ // supports both 2.4 GHz and 5 GHz bands.
+ ROAM_TYPE_DBDC = 3;
+ }
+
+ enum Auth {
+
+ // Auth is unknown.
+ AUTH_UNKNOWN = 0;
+
+ // No authentication.
+ AUTH_OPEN = 1;
+
+ // If the router uses a personal authentication.
+ AUTH_PERSONAL = 2;
+
+ // If the router is setup for enterprise authentication.
+ AUTH_ENTERPRISE = 3;
+ }
+
+ enum RouterTechnology {
+
+ // Router is unknown.
+ ROUTER_TECH_UNKNOWN = 0;
+
+ // Router Channel A.
+ ROUTER_TECH_A = 1;
+
+ // Router Channel B.
+ ROUTER_TECH_B = 2;
+
+ // Router Channel G.
+ ROUTER_TECH_G = 3;
+
+ // Router Channel N.
+ ROUTER_TECH_N = 4;
+
+ // Router Channel AC.
+ ROUTER_TECH_AC = 5;
+
+ // When the channel is not one of the above.
+ ROUTER_TECH_OTHER = 6;
+ }
+
+ optional RoamType roam_type = 1;
+
+ // Channel on which the connection takes place.
+ optional int32 channel_info = 2;
+
+ // DTIM setting of the router.
+ optional int32 dtim = 3;
+
+ // Authentication scheme of the router.
+ optional Auth authentication = 4;
+
+ // If the router is hidden.
+ optional bool hidden = 5;
+
+ // Channel information.
+ optional RouterTechnology router_technology = 6;
+
+ // whether ipv6 is supported.
+ optional bool supports_ipv6 = 7;
+
+ // If the router is a passpoint / hotspot 2.0 network
+ optional bool passpoint = 8;
+}
+
+message ConnectionEvent {
+
+ // Roam Type.
+ enum RoamType {
+
+ // Type is unknown.
+ ROAM_UNKNOWN = 0;
+
+ // No roaming.
+ ROAM_NONE = 1;
+
+ // DBDC roaming.
+ ROAM_DBDC = 2;
+
+ // Enterprise roaming.
+ ROAM_ENTERPRISE = 3;
+
+ // User selected roaming.
+ ROAM_USER_SELECTED = 4;
+
+ // Unrelated.
+ ROAM_UNRELATED = 5;
+ }
+
+ // Connectivity Level Failure.
+ enum ConnectivityLevelFailure {
+
+ // Failure is unknown.
+ HLF_UNKNOWN = 0;
+
+ // No failure.
+ HLF_NONE = 1;
+
+ // DHCP failure.
+ HLF_DHCP = 2;
+
+ // No internet connection.
+ HLF_NO_INTERNET = 3;
+
+ // No internet connection.
+ HLF_UNWANTED = 4;
+ }
+
+ // Start time of the connection.
+ optional int64 start_time_millis = 1;// [(datapol.semantic_type) = ST_TIMESTAMP];
+
+ // Duration to connect.
+ optional int32 duration_taken_to_connect_millis = 2;
+
+ // Router information.
+ optional RouterFingerPrint router_fingerprint = 3;
+
+ // RSSI at the start of the connection.
+ optional int32 signal_strength = 4;
+
+ // Roam Type.
+ optional RoamType roam_type = 5;
+
+ // Result of the connection.
+ optional int32 connection_result = 6;
+
+ // Reasons for level 2 failure (needs to be coordinated with wpa-supplicant).
+ optional int32 level_2_failure_code = 7;
+
+ // Failures that happen at the connectivity layer.
+ optional ConnectivityLevelFailure connectivity_level_failure_code = 8;
+
+ // Has bug report been taken.
+ optional bool automatic_bug_report_taken = 9;
+}
+
+// Number of occurrences of a specific RSSI poll rssi value
+message RssiPollCount {
+ // RSSI
+ optional int32 rssi = 1;
+
+ // Number of RSSI polls with 'rssi'
+ optional int32 count = 2;
+}
+
+// Number of occurrences of a specific alert reason value
+message AlertReasonCount {
+ // Alert reason
+ optional int32 reason = 1;
+
+ // Number of alerts with |reason|.
+ optional int32 count = 2;
+}
+
+// Counts the number of instances of a specific Wifi Score calculated by WifiScoreReport
+message WifiScoreCount {
+ // Wifi Score
+ optional int32 score = 1;
+
+ // Number of Wifi score reports with this score
+ optional int32 count = 2;
+}
+
+// Number of occurrences of Soft AP session durations
+message SoftApDurationBucket {
+ // Bucket covers duration : [duration_sec, duration_sec + bucket_size_sec)
+ // The (inclusive) lower bound of Soft AP session duration represented by this bucket
+ optional int32 duration_sec = 1;
+
+ // The size of this bucket
+ optional int32 bucket_size_sec = 2;
+
+ // Number of soft AP session durations that fit into this bucket
+ optional int32 count = 3;
+}
+
+// Number of occurrences of a soft AP session return code
+message SoftApReturnCodeCount {
+ // Return code of the soft AP session
+ optional int32 return_code = 1;
+
+ // Occurrences of this soft AP return code
+ optional int32 count = 2;
+}
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index 9d3035a..6375e9a 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -3983,7 +3983,7 @@
boolean deviceIsEncrypted() {
try {
return mMountService.getEncryptionState()
- != IMountService.ENCRYPTION_STATE_NONE
+ != StorageManager.ENCRYPTION_STATE_NONE
&& mMountService.getPasswordType()
!= StorageManager.CRYPT_TYPE_DEFAULT;
} catch (Exception e) {
diff --git a/services/core/Android.mk b/services/core/Android.mk
index 9efafb7..11586ee 100644
--- a/services/core/Android.mk
+++ b/services/core/Android.mk
@@ -8,7 +8,6 @@
LOCAL_SRC_FILES += \
$(call all-java-files-under,java) \
- $(call all-proto-files-under, proto) \
java/com/android/server/EventLogTags.logtags \
java/com/android/server/am/EventLogTags.logtags \
../../../../system/netd/server/binder/android/net/INetd.aidl \
@@ -24,7 +23,6 @@
android.hardware.light@2.0-java
LOCAL_STATIC_JAVA_LIBRARIES := tzdata_update
-LOCAL_PROTOC_OPTIMIZE_TYPE := nano
ifneq ($(INCREMENTAL_BUILDS),)
LOCAL_PROGUARD_ENABLED := disabled
diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java
index b9a4831..8bb9326 100644
--- a/services/core/java/com/android/server/MountService.java
+++ b/services/core/java/com/android/server/MountService.java
@@ -46,6 +46,7 @@
import android.content.pm.UserInfo;
import android.content.res.Configuration;
import android.content.res.ObbInfo;
+import android.net.TrafficStats;
import android.net.Uri;
import android.os.Binder;
import android.os.DropBoxManager;
@@ -86,6 +87,7 @@
import android.util.ArrayMap;
import android.util.AtomicFile;
import android.util.Log;
+import android.util.Pair;
import android.util.Slog;
import android.util.TimeUtils;
import android.util.Xml;
@@ -2535,11 +2537,11 @@
} catch (NumberFormatException e) {
// Bad result - unexpected.
Slog.w(TAG, "Unable to parse result from cryptfs cryptocomplete");
- return ENCRYPTION_STATE_ERROR_UNKNOWN;
+ return StorageManager.ENCRYPTION_STATE_ERROR_UNKNOWN;
} catch (NativeDaemonConnectorException e) {
// Something bad happened.
Slog.w(TAG, "Error in communicating with cryptfs in validating");
- return ENCRYPTION_STATE_ERROR_UNKNOWN;
+ return StorageManager.ENCRYPTION_STATE_ERROR_UNKNOWN;
}
}
@@ -3738,6 +3740,18 @@
pw.println();
pw.println("Primary storage UUID: " + mPrimaryStorageUuid);
+ final Pair<String, Long> pair = StorageManager.getPrimaryStoragePathAndSize();
+ if (pair == null) {
+ pw.println("Internal storage total size: N/A");
+ } else {
+ pw.print("Internal storage (");
+ pw.print(pair.first);
+ pw.print(") total size: ");
+ pw.print(pair.second);
+ pw.print(" (");
+ pw.print((float) pair.second / TrafficStats.GB_IN_BYTES);
+ pw.println(" GB)");
+ }
pw.println("Force adoptable: " + mForceAdoptable);
pw.println();
pw.println("Local unlocked users: " + Arrays.toString(mLocalUnlockedUsers));
diff --git a/services/core/java/com/android/server/pm/EphemeralResolverConnection.java b/services/core/java/com/android/server/pm/EphemeralResolverConnection.java
index 68b465a..a6a3774 100644
--- a/services/core/java/com/android/server/pm/EphemeralResolverConnection.java
+++ b/services/core/java/com/android/server/pm/EphemeralResolverConnection.java
@@ -56,6 +56,7 @@
/** Intent used to bind to the service */
private final Intent mIntent;
+ private volatile boolean mBindRequested;
private IEphemeralResolver mRemoteInstance;
public EphemeralResolverConnection(Context context, ComponentName componentName) {
@@ -111,8 +112,11 @@
return;
}
- mContext.bindServiceAsUser(mIntent, mServiceConnection,
- Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE, UserHandle.SYSTEM);
+ if (!mBindRequested) {
+ mBindRequested = true;
+ mContext.bindServiceAsUser(mIntent, mServiceConnection,
+ Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE, UserHandle.SYSTEM);
+ }
final long startMillis = SystemClock.uptimeMillis();
while (true) {
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index efd6f46..d0baaf0 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -2483,6 +2483,7 @@
*/
@Override
public boolean removeUser(int userHandle) {
+ Slog.i(LOG_TAG, "removeUser u" + userHandle);
checkManageOrCreateUsersPermission("Only the system can remove users");
if (getUserRestrictions(UserHandle.getCallingUserId()).getBoolean(
UserManager.DISALLOW_REMOVE_USER, false)) {
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 6e5c025..40dfcda 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -7922,6 +7922,12 @@
if (oldRotation == mUpsideDownRotation || newRotation == mUpsideDownRotation) {
return false;
}
+ // If the navigation bar can't change sides, then it will
+ // jump when we change orientations and we don't rotate
+ // seamlessly.
+ if (!mNavigationBarCanMove) {
+ return false;
+ }
int delta = newRotation - oldRotation;
if (delta < 0) delta += 4;
// Likewise we don't rotate seamlessly for 180 degree rotations
diff --git a/services/tests/servicestests/src/com/android/server/connectivity/IpConnectivityEventBuilderTest.java b/services/tests/servicestests/src/com/android/server/connectivity/IpConnectivityEventBuilderTest.java
index 84f0f90..6ff0c5a 100644
--- a/services/tests/servicestests/src/com/android/server/connectivity/IpConnectivityEventBuilderTest.java
+++ b/services/tests/servicestests/src/com/android/server/connectivity/IpConnectivityEventBuilderTest.java
@@ -16,6 +16,17 @@
package com.android.server.connectivity;
+import static com.android.server.connectivity.MetricsTestUtil.aBool;
+import static com.android.server.connectivity.MetricsTestUtil.aByteArray;
+import static com.android.server.connectivity.MetricsTestUtil.aLong;
+import static com.android.server.connectivity.MetricsTestUtil.aString;
+import static com.android.server.connectivity.MetricsTestUtil.aType;
+import static com.android.server.connectivity.MetricsTestUtil.anInt;
+import static com.android.server.connectivity.MetricsTestUtil.anIntArray;
+import static com.android.server.connectivity.MetricsTestUtil.b;
+import static com.android.server.connectivity.MetricsTestUtil.describeIpEvent;
+import static com.android.server.connectivity.metrics.IpConnectivityLogClass.IpConnectivityLog;
+
import android.net.ConnectivityMetricsEvent;
import android.net.metrics.ApfProgramEvent;
import android.net.metrics.ApfStats;
@@ -28,21 +39,10 @@
import android.net.metrics.NetworkEvent;
import android.net.metrics.RaEvent;
import android.net.metrics.ValidationProbeEvent;
-import com.google.protobuf.nano.MessageNano;
-import java.util.Arrays;
+
import junit.framework.TestCase;
-import static com.android.server.connectivity.metrics.IpConnectivityLogClass.IpConnectivityLog;
-import static com.android.server.connectivity.MetricsTestUtil.aBool;
-import static com.android.server.connectivity.MetricsTestUtil.aByteArray;
-import static com.android.server.connectivity.MetricsTestUtil.aLong;
-import static com.android.server.connectivity.MetricsTestUtil.aString;
-import static com.android.server.connectivity.MetricsTestUtil.aType;
-import static com.android.server.connectivity.MetricsTestUtil.anInt;
-import static com.android.server.connectivity.MetricsTestUtil.anIntArray;
-import static com.android.server.connectivity.MetricsTestUtil.b;
-import static com.android.server.connectivity.MetricsTestUtil.describeIpEvent;
-import static com.android.server.connectivity.MetricsTestUtil.ipEv;
+import java.util.Arrays;
public class IpConnectivityEventBuilderTest extends TestCase {
@@ -351,8 +351,7 @@
static void verifySerialization(String want, ConnectivityMetricsEvent... input) {
try {
byte[] got = IpConnectivityEventBuilder.serialize(0, Arrays.asList(input));
- IpConnectivityLog log = new IpConnectivityLog();
- MessageNano.mergeFrom(log, got);
+ IpConnectivityLog log = IpConnectivityLog.parseFrom(got);
assertEquals(want, log.toString());
} catch (Exception e) {
fail(e.toString());
diff --git a/services/tests/servicestests/src/com/android/server/connectivity/IpConnectivityMetricsTest.java b/services/tests/servicestests/src/com/android/server/connectivity/IpConnectivityMetricsTest.java
index aa491bb..c7982b1 100644
--- a/services/tests/servicestests/src/com/android/server/connectivity/IpConnectivityMetricsTest.java
+++ b/services/tests/servicestests/src/com/android/server/connectivity/IpConnectivityMetricsTest.java
@@ -16,6 +16,9 @@
package com.android.server.connectivity;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.verify;
+
import android.content.Context;
import android.net.ConnectivityMetricsEvent;
import android.net.IIpConnectivityMetrics;
@@ -30,22 +33,21 @@
import android.net.metrics.ValidationProbeEvent;
import android.os.Parcelable;
import android.util.Base64;
+
import com.android.server.connectivity.metrics.IpConnectivityLogClass;
-import com.google.protobuf.nano.MessageNano;
+
+import junit.framework.TestCase;
+
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
-import junit.framework.TestCase;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import static org.mockito.Mockito.timeout;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
public class IpConnectivityMetricsTest extends TestCase {
static final IpReachabilityEvent FAKE_EV =
@@ -254,8 +256,7 @@
try {
byte[] got = Base64.decode(output, Base64.DEFAULT);
IpConnectivityLogClass.IpConnectivityLog log =
- new IpConnectivityLogClass.IpConnectivityLog();
- MessageNano.mergeFrom(log, got);
+ IpConnectivityLogClass.IpConnectivityLog.parseFrom(got);
assertEquals(want, log.toString());
} catch (Exception e) {
fail(e.toString());