summaryrefslogtreecommitdiffstats
path: root/core/java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/animation/AnimatorSet.java7
-rw-r--r--core/java/android/app/Activity.java32
-rw-r--r--core/java/android/app/ActivityManagerInternal.java7
-rw-r--r--core/java/android/app/ActivityTransitionCoordinator.java39
-rw-r--r--core/java/android/app/AlarmManager.java93
-rw-r--r--core/java/android/app/AppOpsManager.java2
-rw-r--r--core/java/android/app/ApplicationPackageManager.java49
-rw-r--r--core/java/android/app/AssistAction.java277
-rw-r--r--core/java/android/app/EnterTransitionCoordinator.java21
-rw-r--r--core/java/android/app/ExitTransitionCoordinator.java25
-rw-r--r--core/java/android/app/SystemServiceRegistry.java10
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java13
-rw-r--r--core/java/android/app/admin/IDevicePolicyManager.aidl5
-rw-r--r--core/java/android/app/admin/SystemUpdatePolicy.aidl20
-rw-r--r--core/java/android/app/admin/SystemUpdatePolicy.java182
-rw-r--r--core/java/android/app/usage/IUsageStatsManager.aidl4
-rw-r--r--core/java/android/app/usage/UsageStats.java20
-rw-r--r--core/java/android/app/usage/UsageStatsManager.java8
-rw-r--r--core/java/android/app/usage/UsageStatsManagerInternal.java8
-rw-r--r--core/java/android/bluetooth/IBluetooth.aidl4
-rw-r--r--core/java/android/content/Context.java10
-rw-r--r--core/java/android/content/Intent.java8
-rw-r--r--core/java/android/content/pm/IPackageManager.aidl9
-rw-r--r--core/java/android/content/pm/LauncherActivityInfo.java55
-rw-r--r--core/java/android/content/pm/PackageManager.java112
-rw-r--r--core/java/android/content/pm/ResolveInfo.java20
-rw-r--r--core/java/android/hardware/usb/IUsbManager.aidl3
-rw-r--r--core/java/android/hardware/usb/UsbManager.java37
-rw-r--r--core/java/android/net/ConnectivityManager.java2
-rw-r--r--core/java/android/os/IDeviceIdleController.aidl1
-rw-r--r--core/java/android/os/IUserManager.aidl2
-rw-r--r--core/java/android/os/PowerManagerInternal.java2
-rw-r--r--core/java/android/os/UserManager.java18
-rw-r--r--core/java/android/provider/Settings.java9
-rw-r--r--core/java/android/service/chooser/ChooserTarget.java149
-rw-r--r--core/java/android/view/AccessibilityInteractionController.java7
-rw-r--r--core/java/android/view/KeyEvent.java2
-rw-r--r--core/java/android/view/ViewGroup.java2
-rw-r--r--core/java/android/view/ViewRootImpl.java32
-rw-r--r--core/java/android/view/WindowManagerGlobal.java3
-rw-r--r--core/java/android/widget/AppSecurityPermissions.java2
-rw-r--r--core/java/android/widget/CalendarViewLegacyDelegate.java2
-rw-r--r--core/java/android/widget/Editor.java5
-rw-r--r--core/java/android/widget/Toolbar.java8
-rw-r--r--core/java/com/android/internal/app/ChooserActivity.java298
-rw-r--r--core/java/com/android/internal/app/ResolverActivity.java285
-rw-r--r--core/java/com/android/internal/logging/MetricsLogger.java37
-rw-r--r--core/java/com/android/internal/widget/ActionBarContextView.java4
-rw-r--r--core/java/com/android/internal/widget/ActionBarView.java4
-rw-r--r--core/java/com/android/internal/widget/FloatingToolbar.java10
50 files changed, 1105 insertions, 859 deletions
diff --git a/core/java/android/animation/AnimatorSet.java b/core/java/android/animation/AnimatorSet.java
index 6503d89..951fe49 100644
--- a/core/java/android/animation/AnimatorSet.java
+++ b/core/java/android/animation/AnimatorSet.java
@@ -16,9 +16,10 @@
package android.animation;
+import android.util.ArrayMap;
+
import java.util.ArrayList;
import java.util.Collection;
-import java.util.HashMap;
import java.util.List;
/**
@@ -68,7 +69,7 @@ public final class AnimatorSet extends Animator {
* to a single node representing that Animator, not create a new Node
* if one already exists.
*/
- private HashMap<Animator, Node> mNodeMap = new HashMap<Animator, Node>();
+ private ArrayMap<Animator, Node> mNodeMap = new ArrayMap<Animator, Node>();
/**
* Set of all nodes created for this AnimatorSet. This list is used upon
@@ -646,7 +647,7 @@ public final class AnimatorSet extends Animator {
anim.mTerminated = false;
anim.mStarted = false;
anim.mPlayingSet = new ArrayList<Animator>();
- anim.mNodeMap = new HashMap<Animator, Node>();
+ anim.mNodeMap = new ArrayMap<Animator, Node>();
anim.mNodes = new ArrayList<Node>(nodeCount);
anim.mSortedNodes = new ArrayList<Node>(nodeCount);
anim.mReversible = mReversible;
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 9968dbb..49f5099 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -3841,10 +3841,7 @@ public class Activity extends ContextThemeWrapper
mStartedActivity = true;
}
- final View decor = mWindow != null ? mWindow.peekDecorView() : null;
- if (decor != null) {
- decor.cancelPendingInputEvents();
- }
+ cancelInputsAndStartExitTransition(options);
// TODO Consider clearing/flushing other event sources and events for child windows.
} else {
if (options != null) {
@@ -3855,6 +3852,18 @@ public class Activity extends ContextThemeWrapper
mParent.startActivityFromChild(this, intent, requestCode);
}
}
+ }
+
+ /**
+ * Cancels pending inputs and if an Activity Transition is to be run, starts the transition.
+ *
+ * @param options The ActivityOptions bundle used to start an Activity.
+ */
+ private void cancelInputsAndStartExitTransition(Bundle options) {
+ final View decor = mWindow != null ? mWindow.peekDecorView() : null;
+ if (decor != null) {
+ decor.cancelPendingInputEvents();
+ }
if (options != null && !isTopOfTask()) {
mActivityTransitionState.startExitOutTransition(this, options);
}
@@ -3872,9 +3881,6 @@ public class Activity extends ContextThemeWrapper
*/
public void startActivityForResultAsUser(Intent intent, int requestCode,
@Nullable Bundle options, UserHandle user) {
- if (options != null) {
- mActivityTransitionState.startExitOutTransition(this, options);
- }
if (mParent != null) {
throw new RuntimeException("Can't be called from a child");
}
@@ -3896,10 +3902,7 @@ public class Activity extends ContextThemeWrapper
mStartedActivity = true;
}
- final View decor = mWindow != null ? mWindow.peekDecorView() : null;
- if (decor != null) {
- decor.cancelPendingInputEvents();
- }
+ cancelInputsAndStartExitTransition(options);
}
/**
@@ -3925,6 +3928,7 @@ public class Activity extends ContextThemeWrapper
mToken, mEmbeddedID, -1, ar.getResultCode(),
ar.getResultData());
}
+ cancelInputsAndStartExitTransition(options);
}
/**
@@ -3948,6 +3952,7 @@ public class Activity extends ContextThemeWrapper
mToken, mEmbeddedID, -1, ar.getResultCode(),
ar.getResultData());
}
+ cancelInputsAndStartExitTransition(options);
}
/**
@@ -4380,6 +4385,7 @@ public class Activity extends ContextThemeWrapper
mToken, child.mEmbeddedID, requestCode,
ar.getResultCode(), ar.getResultData());
}
+ cancelInputsAndStartExitTransition(options);
}
/**
@@ -4431,9 +4437,6 @@ public class Activity extends ContextThemeWrapper
@Override
public void startActivityForResult(
String who, Intent intent, int requestCode, @Nullable Bundle options) {
- if (options != null) {
- mActivityTransitionState.startExitOutTransition(this, options);
- }
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, who,
@@ -4443,6 +4446,7 @@ public class Activity extends ContextThemeWrapper
mToken, who, requestCode,
ar.getResultCode(), ar.getResultData());
}
+ cancelInputsAndStartExitTransition(options);
}
/**
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index bde8f39..40eb799 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -17,6 +17,7 @@
package android.app;
import android.annotation.NonNull;
+import android.content.ComponentName;
/**
* Activity manager local system service interface.
@@ -48,4 +49,10 @@ public abstract class ActivityManagerInternal {
*/
public abstract void release();
}
+
+ /**
+ * Returns home activity for the specified user.
+ * @param userId ID of the user or {@link android.os.UserHandle#USER_ALL}
+ */
+ public abstract ComponentName getHomeActivityForUser(int userId);
}
diff --git a/core/java/android/app/ActivityTransitionCoordinator.java b/core/java/android/app/ActivityTransitionCoordinator.java
index 968c956..fa81412 100644
--- a/core/java/android/app/ActivityTransitionCoordinator.java
+++ b/core/java/android/app/ActivityTransitionCoordinator.java
@@ -31,6 +31,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroupOverlay;
import android.view.ViewParent;
+import android.view.ViewRootImpl;
import android.view.ViewTreeObserver;
import android.view.Window;
import android.widget.ImageView;
@@ -187,11 +188,6 @@ abstract class ActivityTransitionCoordinator extends ResultReceiver {
*/
public static final int MSG_SHARED_ELEMENT_DESTINATION = 107;
- /**
- * Send the shared element positions.
- */
- public static final int MSG_SEND_SHARED_ELEMENT_DESTINATION = 108;
-
private Window mWindow;
final protected ArrayList<String> mAllSharedElementNames;
final protected ArrayList<View> mSharedElements = new ArrayList<View>();
@@ -207,6 +203,8 @@ abstract class ActivityTransitionCoordinator extends ResultReceiver {
new ArrayList<GhostViewListeners>();
private ArrayMap<View, Float> mOriginalAlphas = new ArrayMap<View, Float>();
private ArrayList<Matrix> mSharedElementParentMatrices;
+ private boolean mSharedElementTransitionComplete;
+ private boolean mViewsTransitionComplete;
public ActivityTransitionCoordinator(Window window,
ArrayList<String> allSharedElementNames,
@@ -219,6 +217,11 @@ abstract class ActivityTransitionCoordinator extends ResultReceiver {
}
protected void viewsReady(ArrayMap<String, View> sharedElements) {
+ final View decor = getDecor();
+ final ViewRootImpl viewRoot = decor == null ? null : decor.getViewRootImpl();
+ if (viewRoot != null) {
+ viewRoot.setPausedForTransition(true);
+ }
sharedElements.retainAll(mAllSharedElementNames);
if (mListener != null) {
mListener.onMapSharedElements(mAllSharedElementNames, sharedElements);
@@ -878,6 +881,32 @@ abstract class ActivityTransitionCoordinator extends ResultReceiver {
}
}
+ protected boolean isViewsTransitionComplete() {
+ return mViewsTransitionComplete;
+ }
+
+ protected void viewsTransitionComplete() {
+ mViewsTransitionComplete = true;
+ startInputWhenTransitionsComplete();
+ }
+
+ protected void sharedElementTransitionComplete() {
+ mSharedElementTransitionComplete = true;
+ startInputWhenTransitionsComplete();
+ }
+ private void startInputWhenTransitionsComplete() {
+ if (mViewsTransitionComplete && mSharedElementTransitionComplete) {
+ final View decor = getDecor();
+ if (decor != null) {
+ final ViewRootImpl viewRoot = decor.getViewRootImpl();
+ viewRoot.setPausedForTransition(false);
+ }
+ onTransitionsComplete();
+ }
+ }
+
+ protected void onTransitionsComplete() {}
+
protected class ContinueTransitionListener extends Transition.TransitionListenerAdapter {
@Override
public void onTransitionStart(Transition transition) {
diff --git a/core/java/android/app/AlarmManager.java b/core/java/android/app/AlarmManager.java
index b0fda9c..5e7bd0d 100644
--- a/core/java/android/app/AlarmManager.java
+++ b/core/java/android/app/AlarmManager.java
@@ -71,10 +71,7 @@ import java.io.IOException;
* {@link android.content.Context#getSystemService
* Context.getSystemService(Context.ALARM_SERVICE)}.
*/
-public class AlarmManager
-{
- private static final String TAG = "AlarmManager";
-
+public class AlarmManager {
/**
* Alarm time in {@link System#currentTimeMillis System.currentTimeMillis()}
* (wall clock time in UTC), which will wake up the device when
@@ -558,7 +555,93 @@ public class AlarmManager
long intervalMillis, PendingIntent operation) {
setImpl(type, triggerAtMillis, WINDOW_HEURISTIC, intervalMillis, 0, operation, null, null);
}
-
+
+ /**
+ * Like {@link #set(int, long, PendingIntent)}, but this alarm will be allowed to execute
+ * even when the system is in low-power idle modes. This type of alarm must <b>only</b>
+ * be used for situations where it is actually required that the alarm go off while in
+ * idle -- a reasonable example would be for a calendar notification that should make a
+ * sound so the user is aware of it. These alarms can significantly impact the power use
+ * of the device when idle (and thus cause significant battery blame to the app scheduling
+ * them), so they should be used with care.
+ *
+ * <p>Unlike other alarms, the system is free to reschedule this type of alarm to happen
+ * out of order with any other alarms, even those from the same app. This will clearly happen
+ * when the device is idle (since this alarm can go off while idle, when any other alarms
+ * from the app will be held until later), but may also happen even when not idle.</p>
+ *
+ * <p>Regardless of the app's target SDK version, this call always allows batching of the
+ * alarm.</p>
+ *
+ * @param type One of {@link #ELAPSED_REALTIME}, {@link #ELAPSED_REALTIME_WAKEUP},
+ * {@link #RTC}, or {@link #RTC_WAKEUP}.
+ * @param triggerAtMillis time in milliseconds that the alarm should go
+ * off, using the appropriate clock (depending on the alarm type).
+ * @param operation Action to perform when the alarm goes off;
+ * typically comes from {@link PendingIntent#getBroadcast
+ * IntentSender.getBroadcast()}.
+ *
+ * @see #set(int, long, PendingIntent)
+ * @see #setExactAndAllowWhileIdle
+ * @see #cancel
+ * @see android.content.Context#sendBroadcast
+ * @see android.content.Context#registerReceiver
+ * @see android.content.Intent#filterEquals
+ * @see #ELAPSED_REALTIME
+ * @see #ELAPSED_REALTIME_WAKEUP
+ * @see #RTC
+ * @see #RTC_WAKEUP
+ */
+ public void setAndAllowWhileIdle(int type, long triggerAtMillis, PendingIntent operation) {
+ setImpl(type, triggerAtMillis, WINDOW_HEURISTIC, 0, FLAG_ALLOW_WHILE_IDLE, operation,
+ null, null);
+ }
+
+ /**
+ * Like {@link #setExact(int, long, PendingIntent)}, but this alarm will be allowed to execute
+ * even when the system is in low-power idle modes. If you don't need exact scheduling of
+ * the alarm but still need to execute while idle, consider using
+ * {@link #setAndAllowWhileIdle}. This type of alarm must <b>only</b>
+ * be used for situations where it is actually required that the alarm go off while in
+ * idle -- a reasonable example would be for a calendar notification that should make a
+ * sound so the user is aware of it. These alarms can significantly impact the power use
+ * of the device when idle (and thus cause significant battery blame to the app scheduling
+ * them), so they should be used with care.
+ *
+ * <p>Unlike other alarms, the system is free to reschedule this type of alarm to happen
+ * out of order with any other alarms, even those from the same app. This will clearly happen
+ * when the device is idle (since this alarm can go off while idle, when any other alarms
+ * from the app will be held until later), but may also happen even when not idle.
+ * Note that the OS will allow itself more flexibility for scheduling these alarms than
+ * regular exact alarms, since the application has opted into this behavior. When the
+ * device is idle it may take even more liberties with scheduling in order to optimize
+ * for battery life.</p>
+ *
+ * @param type One of {@link #ELAPSED_REALTIME}, {@link #ELAPSED_REALTIME_WAKEUP},
+ * {@link #RTC}, or {@link #RTC_WAKEUP}.
+ * @param triggerAtMillis time in milliseconds that the alarm should go
+ * off, using the appropriate clock (depending on the alarm type).
+ * @param operation Action to perform when the alarm goes off;
+ * typically comes from {@link PendingIntent#getBroadcast
+ * IntentSender.getBroadcast()}.
+ *
+ * @see #set
+ * @see #setRepeating
+ * @see #setWindow
+ * @see #cancel
+ * @see android.content.Context#sendBroadcast
+ * @see android.content.Context#registerReceiver
+ * @see android.content.Intent#filterEquals
+ * @see #ELAPSED_REALTIME
+ * @see #ELAPSED_REALTIME_WAKEUP
+ * @see #RTC
+ * @see #RTC_WAKEUP
+ */
+ public void setExactAndAllowWhileIdle(int type, long triggerAtMillis, PendingIntent operation) {
+ setImpl(type, triggerAtMillis, WINDOW_EXACT, 0, FLAG_ALLOW_WHILE_IDLE, operation,
+ null, null);
+ }
+
/**
* Remove any alarms with a matching {@link Intent}.
* Any alarm, of any type, whose Intent matches this one (as defined by
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 5aa399b..7104185 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -606,7 +606,7 @@ public class AppOpsManager {
UserManager.DISALLOW_CREATE_WINDOWS, //SYSTEM_ALERT_WINDOW
null, //ACCESS_NOTIFICATIONS
null, //CAMERA
- null, //RECORD_AUDIO
+ UserManager.DISALLOW_RECORD_AUDIO, //RECORD_AUDIO
null, //PLAY_AUDIO
null, //READ_CLIPBOARD
null, //WRITE_CLIPBOARD
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 90293a4..04f6430 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -446,18 +446,40 @@ final class ApplicationPackageManager extends PackageManager {
}
@Override
- public void grantPermission(String packageName, String permissionName, UserHandle user) {
+ public void grantRuntimePermission(String packageName, String permissionName,
+ UserHandle user) {
+ try {
+ mPM.grantRuntimePermission(packageName, permissionName, user.getIdentifier());
+ } catch (RemoteException e) {
+ throw new RuntimeException("Package manager has died", e);
+ }
+ }
+
+ @Override
+ public void revokeRuntimePermission(String packageName, String permissionName,
+ UserHandle user) {
+ try {
+ mPM.revokeRuntimePermission(packageName, permissionName, user.getIdentifier());
+ } catch (RemoteException e) {
+ throw new RuntimeException("Package manager has died", e);
+ }
+ }
+
+ @Override
+ public int getPermissionFlags(String permissionName, String packageName, UserHandle user) {
try {
- mPM.grantPermission(packageName, permissionName, user.getIdentifier());
+ return mPM.getPermissionFlags(permissionName, packageName, user.getIdentifier());
} catch (RemoteException e) {
throw new RuntimeException("Package manager has died", e);
}
}
@Override
- public void revokePermission(String packageName, String permissionName, UserHandle user) {
+ public void updatePermissionFlags(String permissionName, String packageName,
+ int flagMask, int flagValues, UserHandle user) {
try {
- mPM.revokePermission(packageName, permissionName, user.getIdentifier());
+ mPM.updatePermissionFlags(permissionName, packageName, flagMask,
+ flagValues, user.getIdentifier());
} catch (RemoteException e) {
throw new RuntimeException("Package manager has died", e);
}
@@ -1571,9 +1593,15 @@ final class ApplicationPackageManager extends PackageManager {
final VolumeInfo currentVol = getPrimaryStorageCurrentVolume();
final List<VolumeInfo> vols = storage.getVolumes();
final List<VolumeInfo> candidates = new ArrayList<>();
- for (VolumeInfo vol : vols) {
- if (Objects.equals(vol, currentVol) || isPrimaryStorageCandidateVolume(vol)) {
- candidates.add(vol);
+ if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL,
+ storage.getPrimaryStorageUuid()) && currentVol != null) {
+ // TODO: support moving primary physical to emulated volume
+ candidates.add(currentVol);
+ } else {
+ for (VolumeInfo vol : vols) {
+ if (Objects.equals(vol, currentVol) || isPrimaryStorageCandidateVolume(vol)) {
+ candidates.add(vol);
+ }
}
}
return candidates;
@@ -1590,12 +1618,7 @@ final class ApplicationPackageManager extends PackageManager {
return false;
}
- // We can move to public volumes on legacy devices
- if ((vol.getType() == VolumeInfo.TYPE_PUBLIC) && vol.getDisk().isDefaultPrimary()) {
- return true;
- }
-
- // Otherwise we can move to any private volume
+ // We can move to any private volume
return (vol.getType() == VolumeInfo.TYPE_PRIVATE);
}
diff --git a/core/java/android/app/AssistAction.java b/core/java/android/app/AssistAction.java
deleted file mode 100644
index eb33542..0000000
--- a/core/java/android/app/AssistAction.java
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
- * Copyright (C) 2015 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.app;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.Uri;
-import android.os.Bundle;
-import android.text.TextUtils;
-
-import com.android.internal.util.Preconditions;
-
-/**
- * Helper class for building a {@link Bundle} representing an action being performed by the user,
- * to be included in the Bundle generated by {@link Activity#onProvideAssistData}.
- *
- * @see Activity#onProvideAssistData
- */
-public final class AssistAction {
-
- /**
- * Key name for the Bundle containing the schema.org representation of
- * an action performed, and should be stored in the Bundle generated by
- * {@link Activity#onProvideAssistData}.
- */
- public static final String ASSIST_ACTION_KEY = "android:assist_action";
-
- /** Bundle key to specify the schema.org ID of the content. */
- public static final String KEY_ID = "@id";
-
- /** Bundle key to specify the schema.org type of the content. */
- public static final String KEY_TYPE = "@type";
-
- /** Bundle key to specify the name of the content. */
- public static final String KEY_NAME = "name";
-
- /** Bundle key to specify the description of the content. */
- public static final String KEY_DESCRIPTION = "description";
-
- /** Bundle key to specify the URL of the content. */
- public static final String KEY_URL = "url";
-
- /** Bundle key to specify the object of an action. */
- public static final String KEY_ACTION_OBJECT = "object";
-
- /** Bundle key to specify the action's status. */
- public static final String KEY_ACTION_STATUS = "actionStatus";
-
- /** The act of editing by adding an object to a collection. */
- public static final String TYPE_ADD_ACTION = "AddAction";
-
- /** The act of bookmarking an object. */
- public static final String TYPE_BOOKMARK_ACTION = "BookmarkAction";
-
- /** The act of liking an object. */
- public static final String TYPE_LIKE_ACTION = "LikeAction";
-
- /** The act of consuming audio content. */
- public static final String TYPE_LISTEN_ACTION = "ListenAction";
-
- /** The act of consuming static visual content. */
- public static final String TYPE_VIEW_ACTION = "ViewAction";
-
- /** The act of expressing a desire about the object. */
- public static final String TYPE_WANT_ACTION = "WantAction";
-
- /** The act of watching an object. */
- public static final String TYPE_WATCH_ACTION = "WatchAction";
-
- /** The status of an active action. */
- public static final String STATUS_TYPE_ACTIVE = "ActiveActionStatus";
-
- /** The status of a completed action. */
- public static final String STATUS_TYPE_COMPLETED = "CompletedActionStatus";
-
- private AssistAction() {
- }
-
- /**
- * Update the Bundle passed into {@link Activity#onProvideAssistData} with the action Bundle,
- * built with {@link ActionBuilder}.
- *
- * @param assistDataBundle The Bundle provided to {@link Activity#onProvideAssistData}.
- * @param actionBundle The Bundle representing an schema.org action.
- */
- public static void updateAssistData(Bundle assistDataBundle, Bundle actionBundle) {
- Preconditions.checkNotNull(assistDataBundle);
- Preconditions.checkNotNull(actionBundle);
-
- Preconditions.checkNotNull(actionBundle.getString(KEY_TYPE),
- "The '@type' property is required in the provided actionBundle");
- assistDataBundle.putParcelable(ASSIST_ACTION_KEY, actionBundle);
- }
-
- /**
- * Builds a {@link Bundle} representing a schema.org entity.
- */
- public static final class ThingBuilder {
- private final Bundle mBundle;
-
- public ThingBuilder() {
- mBundle = new Bundle();
- }
-
- /**
- * Sets the name of the content.
- *
- * @param name The name of the content.
- */
- public ThingBuilder setName(@Nullable String name) {
- set(KEY_NAME, name);
- return this;
- }
-
- /**
- * Sets the app URI of the content.
- *
- * @param uri The app URI of the content.
- */
- public ThingBuilder setUrl(@Nullable Uri uri) {
- if (uri != null) {
- set(KEY_URL, uri.toString());
- }
- return this;
- }
-
- /**
- * Sets the ID of the content.
- *
- * @param id Set the ID of the content.
- */
- public ThingBuilder setId(@Nullable String id) {
- set(KEY_ID, id);
- return this;
- }
-
- /**
- * Sets the schema.org type of the content.
- *
- * @param type The schema.org type.
- */
- public ThingBuilder setType(@Nullable String type) {
- set(KEY_TYPE, type);
- return this;
- }
-
- /**
- * Sets the optional description of the content.
- *
- * @param description The description of the content.
- */
- public ThingBuilder setDescription(@Nullable String description) {
- set(KEY_DESCRIPTION, description);
- return this;
- }
-
- /**
- * Sets a property of the content.
- *
- * @param key The schema.org property. Must not be null.
- * @param value The value of the schema.org property.
- * If null, the value will be ignored.
- */
- public ThingBuilder set(@NonNull String key, @Nullable String value) {
- if (value != null) {
- mBundle.putString(key, value);
- }
- return this;
- }
-
- /**
- * Sets a property of the content.
- *
- * @param key The schema.org property. Must not be null.
- * @param value The value of the schema.org property represented as a bundle.
- * If null, the value will be ignored.
- */
- public ThingBuilder set(@NonNull String key, @Nullable Bundle value) {
- if (value != null) {
- mBundle.putParcelable(key, value);
- }
- return this;
- }
-
- /**
- * Build the {@link Bundle} object representing the schema.org entity.
- */
- public Bundle build() {
- return mBundle;
- }
- }
-
- /**
- * Builds a {@link Bundle} representing a schema.org action.
- */
- public static final class ActionBuilder {
- private final Bundle mBundle;
-
- public ActionBuilder() {
- mBundle = new Bundle();
- }
-
- /**
- * Sets the schema.org type of the action.
- *
- * @param type The schema.org type.
- */
- public ActionBuilder setType(@Nullable String type) {
- set(KEY_TYPE, type);
- return this;
- }
-
- /**
- * Sets the schema.org object of the action.
- *
- * @param object The schema.org object of the action.
- */
- public ActionBuilder setObject(@Nullable Bundle object) {
- set(KEY_ACTION_OBJECT, object);
- return this;
- }
-
- /**
- * Sets a property of the action.
- *
- * @param key The schema.org property. Must not be null.
- * @param value The value of the schema.org property.
- * If null, the value will be ignored.
- */
- public ActionBuilder set(@NonNull String key, @Nullable String value) {
- if (value != null) {
- mBundle.putString(key, value);
- }
- return this;
- }
-
- /**
- * Sets a property of the action.
- *
- * @param key The schema.org property. Must not be null.
- * @param value The value of the schema.org property represented as a bundle.
- * If null, the value will be ignored.
- */
- public ActionBuilder set(@NonNull String key, @Nullable Bundle value) {
- if (value != null) {
- mBundle.putParcelable(key, value);
- }
- return this;
- }
-
- /**
- * Build the {@link Bundle} object representing the schema.org action.
- */
- public Bundle build() {
- if (TextUtils.isEmpty(mBundle.getString(KEY_TYPE, null))) {
- // Defaults to the base action type http://schema.org/Action.
- setType("Action");
- }
-
- return mBundle;
- }
- }
-}
diff --git a/core/java/android/app/EnterTransitionCoordinator.java b/core/java/android/app/EnterTransitionCoordinator.java
index e84a8da..4db4be0 100644
--- a/core/java/android/app/EnterTransitionCoordinator.java
+++ b/core/java/android/app/EnterTransitionCoordinator.java
@@ -55,8 +55,6 @@ class EnterTransitionCoordinator extends ActivityTransitionCoordinator {
private boolean mWasOpaque;
private boolean mAreViewsReady;
private boolean mIsViewsTransitionStarted;
- private boolean mIsViewsTransitionComplete;
- private boolean mIsSharedElementTransitionComplete;
private Transition mEnterViewsTransition;
public EnterTransitionCoordinator(Activity activity, ResultReceiver resultReceiver,
@@ -456,7 +454,7 @@ class EnterTransitionCoordinator extends ActivityTransitionCoordinator {
}
}
if (viewsTransition == null) {
- viewTransitionComplete();
+ viewsTransitionComplete();
} else {
viewsTransition.forceVisibility(View.INVISIBLE, true);
final ArrayList<View> transitioningViews = mTransitioningViews;
@@ -474,7 +472,7 @@ class EnterTransitionCoordinator extends ActivityTransitionCoordinator {
public void onTransitionEnd(Transition transition) {
mEnterViewsTransition = null;
transition.removeListener(this);
- viewTransitionComplete();
+ viewsTransitionComplete();
super.onTransitionEnd(transition);
}
});
@@ -497,18 +495,9 @@ class EnterTransitionCoordinator extends ActivityTransitionCoordinator {
return transition;
}
- private void viewTransitionComplete() {
- mIsViewsTransitionComplete = true;
- if (mIsSharedElementTransitionComplete) {
- moveSharedElementsFromOverlay();
- }
- }
-
- private void sharedElementTransitionComplete() {
- mIsSharedElementTransitionComplete = true;
- if (mIsViewsTransitionComplete) {
- moveSharedElementsFromOverlay();
- }
+ @Override
+ protected void onTransitionsComplete() {
+ moveSharedElementsFromOverlay();
}
private void sharedElementTransitionStarted() {
diff --git a/core/java/android/app/ExitTransitionCoordinator.java b/core/java/android/app/ExitTransitionCoordinator.java
index 0f286fb..9ddebb0 100644
--- a/core/java/android/app/ExitTransitionCoordinator.java
+++ b/core/java/android/app/ExitTransitionCoordinator.java
@@ -46,8 +46,6 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator {
private static final String TAG = "ExitTransitionCoordinator";
private static final long MAX_WAIT_MS = 1000;
- private boolean mExitComplete;
-
private Bundle mSharedElementBundle;
private boolean mExitNotified;
@@ -165,7 +163,7 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator {
@Override
public void onTransitionEnd(Transition transition) {
transition.removeListener(this);
- if (mExitComplete) {
+ if (isViewsTransitionComplete()) {
delayCancel();
}
}
@@ -310,14 +308,14 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator {
viewsTransition = configureTransition(getViewsTransition(), true);
}
if (viewsTransition == null) {
- exitTransitionComplete();
+ viewsTransitionComplete();
} else {
final ArrayList<View> transitioningViews = mTransitioningViews;
viewsTransition.addListener(new ContinueTransitionListener() {
@Override
public void onTransitionEnd(Transition transition) {
transition.removeListener(this);
- exitTransitionComplete();
+ viewsTransitionComplete();
if (mIsHidden && transitioningViews != null) {
showViews(transitioningViews, true);
}
@@ -373,19 +371,15 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator {
}
}
- private void exitTransitionComplete() {
- mExitComplete = true;
- notifyComplete();
- }
-
protected boolean isReadyToNotify() {
return mSharedElementBundle != null && mResultReceiver != null && mIsBackgroundReady;
}
- private void sharedElementTransitionComplete() {
+ @Override
+ protected void sharedElementTransitionComplete() {
mSharedElementBundle = mExitSharedElementBundle == null
? captureSharedElementState() : captureExitSharedElementsState();
- notifyComplete();
+ super.sharedElementTransitionComplete();
}
private Bundle captureExitSharedElementsState() {
@@ -405,6 +399,11 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator {
return bundle;
}
+ @Override
+ protected void onTransitionsComplete() {
+ notifyComplete();
+ }
+
protected void notifyComplete() {
if (isReadyToNotify()) {
if (!mSharedElementNotified) {
@@ -433,7 +432,7 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator {
}
private void notifyExitComplete() {
- if (!mExitNotified && mExitComplete) {
+ if (!mExitNotified && isViewsTransitionComplete()) {
mExitNotified = true;
mResultReceiver.send(MSG_EXIT_TRANSITION_COMPLETE, null);
mResultReceiver = null; // done talking
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 391131a..0d00908 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -55,7 +55,6 @@ import android.location.CountryDetector;
import android.location.ICountryDetector;
import android.location.ILocationManager;
import android.location.LocationManager;
-import android.media.AudioDevicesManager;
import android.media.AudioManager;
import android.media.MediaRouter;
import android.media.midi.IMidiManager;
@@ -701,13 +700,6 @@ final class SystemServiceRegistry {
public RadioManager createService(ContextImpl ctx) {
return new RadioManager(ctx);
}});
-
- registerService(Context.AUDIO_DEVICES_SERVICE, AudioDevicesManager.class,
- new CachedServiceFetcher<AudioDevicesManager>() {
- @Override
- public AudioDevicesManager createService(ContextImpl ctx) {
- return new AudioDevicesManager(ctx);
- }});
}
/**
@@ -726,7 +718,7 @@ final class SystemServiceRegistry {
}
/**
- * Gets the name of the system-level service that is represented by the specified class.
+ * Gets the name of the system-level service that is represented by the specified class.
*/
public static String getSystemServiceName(Class<?> serviceClass) {
return SYSTEM_SERVICE_NAMES.get(serviceClass);
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index ae07206..3fb7059 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -4253,11 +4253,7 @@ public class DevicePolicyManager {
public void setSystemUpdatePolicy(ComponentName who, SystemUpdatePolicy policy) {
if (mService != null) {
try {
- if (policy != null) {
- mService.setSystemUpdatePolicy(who, policy.getPolicyBundle());
- } else {
- mService.setSystemUpdatePolicy(who, null);
- }
+ mService.setSystemUpdatePolicy(who, policy);
} catch (RemoteException re) {
Log.w(TAG, "Error calling setSystemUpdatePolicy", re);
}
@@ -4272,12 +4268,7 @@ public class DevicePolicyManager {
public SystemUpdatePolicy getSystemUpdatePolicy() {
if (mService != null) {
try {
- PersistableBundle bundle = mService.getSystemUpdatePolicy();
- if (bundle != null) {
- return new SystemUpdatePolicy(bundle);
- } else {
- return null;
- }
+ return mService.getSystemUpdatePolicy();
} catch (RemoteException re) {
Log.w(TAG, "Error calling getSystemUpdatePolicy", re);
}
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index e81e7c1..481ff62 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -17,6 +17,7 @@
package android.app.admin;
+import android.app.admin.SystemUpdatePolicy;
import android.content.ComponentName;
import android.content.Intent;
import android.content.IntentFilter;
@@ -221,8 +222,8 @@ interface IDevicePolicyManager {
void setUserIcon(in ComponentName admin, in Bitmap icon);
void sendDeviceInitializerStatus(int statusCode, String description);
- void setSystemUpdatePolicy(in ComponentName who, in PersistableBundle policy);
- PersistableBundle getSystemUpdatePolicy();
+ void setSystemUpdatePolicy(in ComponentName who, in SystemUpdatePolicy policy);
+ SystemUpdatePolicy getSystemUpdatePolicy();
boolean setKeyguardDisabled(in ComponentName admin, boolean disabled);
boolean setStatusBarDisabled(in ComponentName who, boolean disabled);
diff --git a/core/java/android/app/admin/SystemUpdatePolicy.aidl b/core/java/android/app/admin/SystemUpdatePolicy.aidl
new file mode 100644
index 0000000..58e8d15
--- /dev/null
+++ b/core/java/android/app/admin/SystemUpdatePolicy.aidl
@@ -0,0 +1,20 @@
+/*
+**
+** Copyright 2015, 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.app.admin;
+
+parcelable SystemUpdatePolicy;
diff --git a/core/java/android/app/admin/SystemUpdatePolicy.java b/core/java/android/app/admin/SystemUpdatePolicy.java
index de56cd0..20ddb77 100644
--- a/core/java/android/app/admin/SystemUpdatePolicy.java
+++ b/core/java/android/app/admin/SystemUpdatePolicy.java
@@ -17,8 +17,15 @@
package android.app.admin;
import android.annotation.IntDef;
+import android.os.Parcel;
+import android.os.Parcelable;
import android.os.PersistableBundle;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -28,7 +35,7 @@ import java.lang.annotation.RetentionPolicy;
* @see DevicePolicyManager#setSystemUpdatePolicy
* @see DevicePolicyManager#getSystemUpdatePolicy
*/
-public class SystemUpdatePolicy {
+public class SystemUpdatePolicy implements Parcelable {
/** @hide */
@IntDef({
@@ -39,6 +46,10 @@ public class SystemUpdatePolicy {
@interface SystemUpdatePolicyType {}
/**
+ * Unknown policy type, used only internally.
+ */
+ private static final int TYPE_UNKNOWN = -1;
+ /**
* Install system update automatically as soon as one is available.
*/
public static final int TYPE_INSTALL_AUTOMATIC = 1;
@@ -63,45 +74,40 @@ public class SystemUpdatePolicy {
private static final String KEY_POLICY_TYPE = "policy_type";
private static final String KEY_INSTALL_WINDOW_START = "install_window_start";
private static final String KEY_INSTALL_WINDOW_END = "install_window_end";
+ /**
+ * The upper boundary of the daily maintenance window: 24 * 60 minutes.
+ */
+ private static final int WINDOW_BOUNDARY = 24 * 60;
- private PersistableBundle mPolicy;
+ @SystemUpdatePolicyType
+ private int mPolicyType;
- public SystemUpdatePolicy() {
- mPolicy = new PersistableBundle();
- }
+ private int mMaintenanceWindowStart;
+ private int mMaintenanceWindowEnd;
- /**
- * Construct an SystemUpdatePolicy object from a bundle.
- * @hide
- */
- public SystemUpdatePolicy(PersistableBundle in) {
- mPolicy = new PersistableBundle(in);
- }
- /**
- * Retrieve the underlying bundle where the policy is stored.
- * @hide
- */
- public PersistableBundle getPolicyBundle() {
- return new PersistableBundle(mPolicy);
+ private SystemUpdatePolicy() {
+ mPolicyType = TYPE_UNKNOWN;
}
/**
- * Set the policy to: install update automatically as soon as one is available.
+ * Create a policy object and set it to install update automatically as soon as one is
+ * available.
*
* @see #TYPE_INSTALL_AUTOMATIC
*/
- public void setAutomaticInstallPolicy() {
- mPolicy.clear();
- mPolicy.putInt(KEY_POLICY_TYPE, TYPE_INSTALL_AUTOMATIC);
+ public static SystemUpdatePolicy createAutomaticInstallPolicy() {
+ SystemUpdatePolicy policy = new SystemUpdatePolicy();
+ policy.mPolicyType = TYPE_INSTALL_AUTOMATIC;
+ return policy;
}
/**
- * Set the policy to: new system update will only be installed automatically when the system
- * clock is inside a daily maintenance window. If the start and end times are the same, the
- * window is considered to include the WHOLE 24 hours, that is, updates can install at any time.
- * If the given window in invalid, a {@link SystemUpdatePolicy.InvalidWindowException} will be
- * thrown. If start time is later than end time, the window is considered spanning midnight,
+ * Create a policy object and set it to: new system update will only be installed automatically
+ * when the system clock is inside a daily maintenance window. If the start and end times are
+ * the same, the window is considered to include the WHOLE 24 hours, that is, updates can
+ * install at any time. If the given window in invalid, a {@link IllegalArgumentException} will
+ * be thrown. If start time is later than end time, the window is considered spanning midnight,
* i.e. end time donates a time on the next day. The maintenance window will last for 30 days,
* after which the system should revert back to its normal behavior as if no policy were set.
*
@@ -111,25 +117,29 @@ public class SystemUpdatePolicy {
* midnight in the device's local time. Must be in the range of [0, 1440).
* @see #TYPE_INSTALL_WINDOWED
*/
- public void setWindowedInstallPolicy(int startTime, int endTime) throws InvalidWindowException{
- if (startTime < 0 || startTime >= 1440 || endTime < 0 || endTime >= 1440) {
- throw new InvalidWindowException("startTime and endTime must be inside [0, 1440)");
+ public static SystemUpdatePolicy createWindowedInstallPolicy(int startTime, int endTime) {
+ if (startTime < 0 || startTime >= WINDOW_BOUNDARY
+ || endTime < 0 || endTime >= WINDOW_BOUNDARY) {
+ throw new IllegalArgumentException("startTime and endTime must be inside [0, 1440)");
}
- mPolicy.clear();
- mPolicy.putInt(KEY_POLICY_TYPE, TYPE_INSTALL_WINDOWED);
- mPolicy.putInt(KEY_INSTALL_WINDOW_START, startTime);
- mPolicy.putInt(KEY_INSTALL_WINDOW_END, endTime);
+ SystemUpdatePolicy policy = new SystemUpdatePolicy();
+ policy.mPolicyType = TYPE_INSTALL_WINDOWED;
+ policy.mMaintenanceWindowStart = startTime;
+ policy.mMaintenanceWindowEnd = endTime;
+ return policy;
}
/**
- * Set the policy to: block installation for a maximum period of 30 days. After expiration the
- * system should revert back to its normal behavior as if no policy were set.
+ * Create a policy object and set it to block installation for a maximum period of 30 days.
+ * After expiration the system should revert back to its normal behavior as if no policy were
+ * set.
*
* @see #TYPE_POSTPONE
*/
- public void setPostponeInstallPolicy() {
- mPolicy.clear();
- mPolicy.putInt(KEY_POLICY_TYPE, TYPE_POSTPONE);
+ public static SystemUpdatePolicy createPostponeInstallPolicy() {
+ SystemUpdatePolicy policy = new SystemUpdatePolicy();
+ policy.mPolicyType = TYPE_POSTPONE;
+ return policy;
}
/**
@@ -140,7 +150,7 @@ public class SystemUpdatePolicy {
*/
@SystemUpdatePolicyType
public int getPolicyType() {
- return mPolicy.getInt(KEY_POLICY_TYPE, -1);
+ return mPolicyType;
}
/**
@@ -150,8 +160,8 @@ public class SystemUpdatePolicy {
* or -1 if the policy does not have a maintenance window.
*/
public int getInstallWindowStart() {
- if (getPolicyType() == TYPE_INSTALL_WINDOWED) {
- return mPolicy.getInt(KEY_INSTALL_WINDOW_START, -1);
+ if (mPolicyType == TYPE_INSTALL_WINDOWED) {
+ return mMaintenanceWindowStart;
} else {
return -1;
}
@@ -164,26 +174,98 @@ public class SystemUpdatePolicy {
* or -1 if the policy does not have a maintenance window.
*/
public int getInstallWindowEnd() {
- if (getPolicyType() == TYPE_INSTALL_WINDOWED) {
- return mPolicy.getInt(KEY_INSTALL_WINDOW_END, -1);
+ if (mPolicyType == TYPE_INSTALL_WINDOWED) {
+ return mMaintenanceWindowEnd;
} else {
return -1;
}
}
+ /**
+ * Return if this object represents a valid policy.
+ * @hide
+ */
+ public boolean isValid() {
+ if (mPolicyType == TYPE_INSTALL_AUTOMATIC || mPolicyType == TYPE_POSTPONE) {
+ return true;
+ } else if (mPolicyType == TYPE_INSTALL_WINDOWED) {
+ return mMaintenanceWindowStart >= 0 && mMaintenanceWindowStart < WINDOW_BOUNDARY
+ && mMaintenanceWindowEnd >= 0 && mMaintenanceWindowEnd < WINDOW_BOUNDARY;
+ } else {
+ return false;
+ }
+ }
+
@Override
public String toString() {
- return mPolicy.toString();
+ return String.format("SystemUpdatePolicy (type: %d, windowStart: %d, windowEnd: %d)",
+ mPolicyType, mMaintenanceWindowStart, mMaintenanceWindowEnd);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
}
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mPolicyType);
+ dest.writeInt(mMaintenanceWindowStart);
+ dest.writeInt(mMaintenanceWindowEnd);
+ }
+
+ public static final Parcelable.Creator<SystemUpdatePolicy> CREATOR =
+ new Parcelable.Creator<SystemUpdatePolicy>() {
+
+ @Override
+ public SystemUpdatePolicy createFromParcel(Parcel source) {
+ SystemUpdatePolicy policy = new SystemUpdatePolicy();
+ policy.mPolicyType = source.readInt();
+ policy.mMaintenanceWindowStart = source.readInt();
+ policy.mMaintenanceWindowEnd = source.readInt();
+ return policy;
+ }
+
+ @Override
+ public SystemUpdatePolicy[] newArray(int size) {
+ return new SystemUpdatePolicy[size];
+ }
+ };
+
+
/**
- * Exception thrown by {@link SystemUpdatePolicy#setWindowedInstallPolicy(int, int)} in case the
- * specified window is invalid.
+ * @hide
*/
- public static class InvalidWindowException extends Exception {
- public InvalidWindowException(String reason) {
- super(reason);
+ public static SystemUpdatePolicy restoreFromXml(XmlPullParser parser) {
+ try {
+ SystemUpdatePolicy policy = new SystemUpdatePolicy();
+ String value = parser.getAttributeValue(null, KEY_POLICY_TYPE);
+ if (value != null) {
+ policy.mPolicyType = Integer.parseInt(value);
+
+ value = parser.getAttributeValue(null, KEY_INSTALL_WINDOW_START);
+ if (value != null) {
+ policy.mMaintenanceWindowStart = Integer.parseInt(value);
+ }
+ value = parser.getAttributeValue(null, KEY_INSTALL_WINDOW_END);
+ if (value != null) {
+ policy.mMaintenanceWindowEnd = Integer.parseInt(value);
+ }
+ return policy;
+ }
+ } catch (NumberFormatException e) {
+ // Fail through
}
+ return null;
+ }
+
+ /**
+ * @hide
+ */
+ public void saveToXml(XmlSerializer out) throws IOException {
+ out.attribute(null, KEY_POLICY_TYPE, Integer.toString(mPolicyType));
+ out.attribute(null, KEY_INSTALL_WINDOW_START, Integer.toString(mMaintenanceWindowStart));
+ out.attribute(null, KEY_INSTALL_WINDOW_END, Integer.toString(mMaintenanceWindowEnd));
}
}
diff --git a/core/java/android/app/usage/IUsageStatsManager.aidl b/core/java/android/app/usage/IUsageStatsManager.aidl
index 23659e3..254408a 100644
--- a/core/java/android/app/usage/IUsageStatsManager.aidl
+++ b/core/java/android/app/usage/IUsageStatsManager.aidl
@@ -30,6 +30,6 @@ interface IUsageStatsManager {
ParceledListSlice queryConfigurationStats(int bucketType, long beginTime, long endTime,
String callingPackage);
UsageEvents queryEvents(long beginTime, long endTime, String callingPackage);
- void setAppIdle(String packageName, boolean idle, int userId);
- boolean isAppIdle(String packageName, int userId);
+ void setAppInactive(String packageName, boolean inactive, int userId);
+ boolean isAppInactive(String packageName, int userId);
}
diff --git a/core/java/android/app/usage/UsageStats.java b/core/java/android/app/usage/UsageStats.java
index abfc435..81c7422 100644
--- a/core/java/android/app/usage/UsageStats.java
+++ b/core/java/android/app/usage/UsageStats.java
@@ -46,6 +46,13 @@ public final class UsageStats implements Parcelable {
public long mLastTimeUsed;
/**
+ * Last time the package was used and the beginning of the idle countdown.
+ * This uses a different timebase that is about how much the device has been in use in general.
+ * {@hide}
+ */
+ public long mBeginIdleTime;
+
+ /**
* {@hide}
*/
public long mTotalTimeInForeground;
@@ -74,6 +81,7 @@ public final class UsageStats implements Parcelable {
mTotalTimeInForeground = stats.mTotalTimeInForeground;
mLaunchCount = stats.mLaunchCount;
mLastEvent = stats.mLastEvent;
+ mBeginIdleTime = stats.mBeginIdleTime;
}
public String getPackageName() {
@@ -110,6 +118,15 @@ public final class UsageStats implements Parcelable {
}
/**
+ * @hide
+ * Get the last time this package was active, measured in milliseconds. This timestamp
+ * uses a timebase that represents how much the device was used and not wallclock time.
+ */
+ public long getBeginIdleTime() {
+ return mBeginIdleTime;
+ }
+
+ /**
* Get the total time this package spent in the foreground, measured in milliseconds.
*/
public long getTotalTimeInForeground() {
@@ -133,6 +150,7 @@ public final class UsageStats implements Parcelable {
mLastEvent = right.mLastEvent;
mEndTimeStamp = right.mEndTimeStamp;
mLastTimeUsed = right.mLastTimeUsed;
+ mBeginIdleTime = right.mBeginIdleTime;
}
mBeginTimeStamp = Math.min(mBeginTimeStamp, right.mBeginTimeStamp);
mTotalTimeInForeground += right.mTotalTimeInForeground;
@@ -153,6 +171,7 @@ public final class UsageStats implements Parcelable {
dest.writeLong(mTotalTimeInForeground);
dest.writeInt(mLaunchCount);
dest.writeInt(mLastEvent);
+ dest.writeLong(mBeginIdleTime);
}
public static final Creator<UsageStats> CREATOR = new Creator<UsageStats>() {
@@ -166,6 +185,7 @@ public final class UsageStats implements Parcelable {
stats.mTotalTimeInForeground = in.readLong();
stats.mLaunchCount = in.readInt();
stats.mLastEvent = in.readInt();
+ stats.mBeginIdleTime = in.readLong();
return stats;
}
diff --git a/core/java/android/app/usage/UsageStatsManager.java b/core/java/android/app/usage/UsageStatsManager.java
index 8a01d66..c74bbdd 100644
--- a/core/java/android/app/usage/UsageStatsManager.java
+++ b/core/java/android/app/usage/UsageStatsManager.java
@@ -220,15 +220,15 @@ public final class UsageStatsManager {
}
/**
- * Returns whether the specified app is currently considered idle. This will be true if the
+ * Returns whether the specified app is currently considered inactive. This will be true if the
* app hasn't been used directly or indirectly for a period of time defined by the system. This
* could be of the order of several hours or days.
* @param packageName The package name of the app to query
- * @return whether the app is currently considered idle
+ * @return whether the app is currently considered inactive
*/
- public boolean isAppIdle(String packageName) {
+ public boolean isAppInactive(String packageName) {
try {
- return mService.isAppIdle(packageName, UserHandle.myUserId());
+ return mService.isAppInactive(packageName, UserHandle.myUserId());
} catch (RemoteException e) {
// fall through and return default
}
diff --git a/core/java/android/app/usage/UsageStatsManagerInternal.java b/core/java/android/app/usage/UsageStatsManagerInternal.java
index 8b3fc2e..7bcc038 100644
--- a/core/java/android/app/usage/UsageStatsManagerInternal.java
+++ b/core/java/android/app/usage/UsageStatsManagerInternal.java
@@ -69,14 +69,6 @@ public abstract class UsageStatsManagerInternal {
public abstract boolean isAppIdle(String packageName, int userId);
/**
- * Returns the most recent time that the specified package was active for the given user.
- * @param packageName The package to search.
- * @param userId The user id of the user of interest.
- * @return The timestamp of when the package was last used, or -1 if it hasn't been used.
- */
- public abstract long getLastPackageAccessTime(String packageName, int userId);
-
- /**
* Sets up a listener for changes to packages being accessed.
* @param listener A listener within the system process.
*/
diff --git a/core/java/android/bluetooth/IBluetooth.aidl b/core/java/android/bluetooth/IBluetooth.aidl
index a3eceb5..7a894ae 100644
--- a/core/java/android/bluetooth/IBluetooth.aidl
+++ b/core/java/android/bluetooth/IBluetooth.aidl
@@ -101,8 +101,8 @@ interface IBluetooth
void getActivityEnergyInfoFromController();
BluetoothActivityEnergyInfo reportActivityInfo();
- // for dumpsys support
- String dump();
+ // For dumpsys support
+ void dump(in ParcelFileDescriptor fd);
void onLeServiceUp();
void onBrEdrDown();
}
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 17f946b..a434c7b 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -3136,16 +3136,6 @@ public abstract class Context {
public static final String RADIO_SERVICE = "radio";
/**
- * Use with {@link #getSystemService} to retrieve a
- * {@link android.media.AudioDevicesManager} for handling device enumeration & notification.
- *
- * @see #getSystemService
- * @see android.media.AudioDevicesManager
- */
- public static final String AUDIO_DEVICES_SERVICE = "audio_devices_manager";
-
-
- /**
* Determine whether the given permission is allowed for a particular
* process and user ID running in the system.
*
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 6f543a8..7d76760 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -3365,14 +3365,6 @@ public class Intent implements Parcelable, Cloneable {
public static final String EXTRA_INITIAL_INTENTS = "android.intent.extra.INITIAL_INTENTS";
/**
- * A Parcelable[] of {@link android.service.chooser.ChooserTarget ChooserTarget} objects
- * as set with {@link #putExtra(String, Parcelable[])} representing additional app-specific
- * targets to place at the front of the list of choices. Shown to the user with
- * {@link #ACTION_CHOOSER}.
- */
- public static final String EXTRA_CHOOSER_TARGETS = "android.intent.extra.CHOOSER_TARGETS";
-
- /**
* A Bundle forming a mapping of potential target package names to different extras Bundles
* to add to the default intent extras in {@link #EXTRA_INTENT} when used with
* {@link #ACTION_CHOOSER}. Each key should be a package name. The package need not
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 94b0223..ddff782 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -96,9 +96,14 @@ interface IPackageManager {
void removePermission(String name);
- void grantPermission(String packageName, String permissionName, int userId);
+ void grantRuntimePermission(String packageName, String permissionName, int userId);
- void revokePermission(String packageName, String permissionName, int userId);
+ void revokeRuntimePermission(String packageName, String permissionName, int userId);
+
+ int getPermissionFlags(String permissionName, String packageName, int userId);
+
+ void updatePermissionFlags(String permissionName, String packageName, int flagMask,
+ int flagValues, int userId);
boolean isProtectedBroadcast(String actionName);
diff --git a/core/java/android/content/pm/LauncherActivityInfo.java b/core/java/android/content/pm/LauncherActivityInfo.java
index 87b97aa..6827d7a 100644
--- a/core/java/android/content/pm/LauncherActivityInfo.java
+++ b/core/java/android/content/pm/LauncherActivityInfo.java
@@ -103,20 +103,30 @@ public class LauncherActivityInfo {
* density DPI values from {@link DisplayMetrics}.
* @see #getBadgedIcon(int)
* @see DisplayMetrics
- * @return The drawable associated with the activity
+ * @return The drawable associated with the activity.
*/
public Drawable getIcon(int density) {
- int iconRes = mResolveInfo.getIconResource();
- Resources resources = null;
- Drawable icon = null;
- // Get the preferred density icon from the app's resources
- if (density != 0 && iconRes != 0) {
- try {
- resources = mPm.getResourcesForApplication(mActivityInfo.applicationInfo);
- icon = resources.getDrawableForDensity(iconRes, density);
- } catch (NameNotFoundException | Resources.NotFoundException exc) {
- }
+ final int iconRes = mResolveInfo.getIconResource();
+ Drawable icon = getDrawableForDensity(iconRes, density);
+ // Get the default density icon
+ if (icon == null) {
+ icon = mResolveInfo.loadIcon(mPm);
}
+ return icon;
+ }
+
+ /**
+ * Returns the icon for this activity, without any badging for the profile.
+ * This function can get the icon no matter the icon needs to be badged or not.
+ * @param density The preferred density of the icon, zero for default density. Use
+ * density DPI values from {@link DisplayMetrics}.
+ * @see #getBadgedIcon(int)
+ * @see DisplayMetrics
+ * @return The drawable associated with the activity.
+ */
+ private Drawable getOriginalIcon(int density) {
+ final int iconRes = mResolveInfo.getIconResourceInternal();
+ Drawable icon = getDrawableForDensity(iconRes, density);
// Get the default density icon
if (icon == null) {
icon = mResolveInfo.loadIcon(mPm);
@@ -125,6 +135,27 @@ public class LauncherActivityInfo {
}
/**
+ * Returns the drawable for this activity, without any badging for the profile.
+ * @param resource id of the drawable.
+ * @param density The preferred density of the icon, zero for default density. Use
+ * density DPI values from {@link DisplayMetrics}.
+ * @see DisplayMetrics
+ * @return The drawable associated with the resource id.
+ */
+ private Drawable getDrawableForDensity(int iconRes, int density) {
+ // Get the preferred density icon from the app's resources
+ if (density != 0 && iconRes != 0) {
+ try {
+ final Resources resources
+ = mPm.getResourcesForApplication(mActivityInfo.applicationInfo);
+ return resources.getDrawableForDensity(iconRes, density);
+ } catch (NameNotFoundException | Resources.NotFoundException exc) {
+ }
+ }
+ return null;
+ }
+
+ /**
* Returns the application flags from the ApplicationInfo of the activity.
*
* @return Application flags
@@ -167,7 +198,7 @@ public class LauncherActivityInfo {
* @return A badged icon for the activity.
*/
public Drawable getBadgedIcon(int density) {
- Drawable originalIcon = getIcon(density);
+ Drawable originalIcon = getOriginalIcon(density);
if (originalIcon instanceof BitmapDrawable) {
return mPm.getUserBadgedIcon(originalIcon, mUser);
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 51fa075..6401fe6 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -1888,6 +1888,57 @@ public abstract class PackageManager {
public static final String EXTRA_FAILURE_EXISTING_PERMISSION
= "android.content.pm.extra.FAILURE_EXISTING_PERMISSION";
+ /**
+ * Permission flag: The permission is set in its current state
+ * by the user and apps can still request it at runtime.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final int FLAG_PERMISSION_USER_SET = 1 << 0;
+
+ /**
+ * Permission flag: The permission is set in its current state
+ * by the user and it is fixed, i.e. apps can no longer request
+ * this permission.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final int FLAG_PERMISSION_USER_FIXED = 1 << 1;
+
+ /**
+ * Permission flag: The permission is set in its current state
+ * by device policy and neither apps nor the user can change
+ * its state.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final int FLAG_PERMISSION_POLICY_FIXED = 1 << 2;
+
+ /**
+ * Permission flag: The permission is set in a granted state but
+ * access to resources it guards is restricted by other means to
+ * enable revoking a permission on legacy apps that do not support
+ * runtime permissions. If this permission is upgraded to runtime
+ * because the app was updated to support runtime permissions, the
+ * the permission will be revoked in the upgrade process.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final int FLAG_PERMISSION_REVOKE_ON_UPGRADE = 1 << 3;
+
+
+ /**
+ * Mask for all permission flags.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final int MASK_PERMISSION_FLAGS = 0xF;
+
/**
* Retrieve overall information about an application package that is
* installed on the system.
@@ -2374,6 +2425,20 @@ public abstract class PackageManager {
*/
public abstract void removePermission(String name);
+
+ /**
+ * Permission flags set when granting or revoking a permission.
+ *
+ * @hide
+ */
+ @SystemApi
+ @IntDef({FLAG_PERMISSION_USER_SET,
+ FLAG_PERMISSION_USER_FIXED,
+ FLAG_PERMISSION_POLICY_FIXED,
+ FLAG_PERMISSION_REVOKE_ON_UPGRADE})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface PermissionFlags {}
+
/**
* Grant a runtime permission to an application which the application does not
* already have. The permission must have been requested by the application.
@@ -2389,19 +2454,20 @@ public abstract class PackageManager {
* @param permissionName The permission name to grant.
* @param user The user for which to grant the permission.
*
- * @see #revokePermission(String, String, android.os.UserHandle)
+ * @see #revokeRuntimePermission(String, String, android.os.UserHandle)
+ * @see android.content.pm.PackageManager.PermissionFlags
*
* @hide
*/
@SystemApi
- public abstract void grantPermission(@NonNull String packageName,
+ public abstract void grantRuntimePermission(@NonNull String packageName,
@NonNull String permissionName, @NonNull UserHandle user);
/**
* Revoke a runtime permission that was previously granted by {@link
- * #grantPermission(String, String, android.os.UserHandle)}. The permission
- * must have been requested by and granted to the application. If the
- * application is not allowed to hold the permission, a {@link
+ * #grantRuntimePermission(String, String, android.os.UserHandle)}. The
+ * permission must have been requested by and granted to the application.
+ * If the application is not allowed to hold the permission, a {@link
* java.lang.SecurityException} is thrown.
* <p>
* <strong>Note: </strong>Using this API requires holding
@@ -2413,15 +2479,47 @@ public abstract class PackageManager {
* @param permissionName The permission name to revoke.
* @param user The user for which to revoke the permission.
*
- * @see #grantPermission(String, String, android.os.UserHandle)
+ * @see #grantRuntimePermission(String, String, android.os.UserHandle)
+ * @see android.content.pm.PackageManager.PermissionFlags
*
* @hide
*/
@SystemApi
- public abstract void revokePermission(@NonNull String packageName,
+ public abstract void revokeRuntimePermission(@NonNull String packageName,
@NonNull String permissionName, @NonNull UserHandle user);
/**
+ * Gets the state flags associated with a permission.
+ *
+ * @param permissionName The permission for which to get the flags.
+ * @param packageName The package name for which to get the flags.
+ * @param user The user for which to get permission flags.
+ * @return The permission flags.
+ *
+ * @hide
+ */
+ @SystemApi
+ public abstract @PermissionFlags int getPermissionFlags(String permissionName,
+ String packageName, @NonNull UserHandle user);
+
+ /**
+ * Updates the flags associated with a permission by replacing the flags in
+ * the specified mask with the provided flag values.
+ *
+ * @param permissionName The permission for which to update the flags.
+ * @param packageName The package name for which to update the flags.
+ * @param flagMask The flags which to replace.
+ * @param flagValues The flags with which to replace.
+ * @param user The user for which to update the permission flags.
+ *
+ * @hide
+ */
+ @SystemApi
+ public abstract void updatePermissionFlags(String permissionName,
+ String packageName, @PermissionFlags int flagMask, int flagValues,
+ @NonNull UserHandle user);
+
+ /**
* Returns an {@link android.content.Intent} suitable for passing to
* {@link android.app.Activity#startActivityForResult(android.content.Intent, int)}
* which prompts the user to grant permissions to this application.
diff --git a/core/java/android/content/pm/ResolveInfo.java b/core/java/android/content/pm/ResolveInfo.java
index 05f5e90..649fdb4 100644
--- a/core/java/android/content/pm/ResolveInfo.java
+++ b/core/java/android/content/pm/ResolveInfo.java
@@ -221,16 +221,16 @@ public class ResolveInfo implements Parcelable {
}
return ci.loadIcon(pm);
}
-
+
/**
* Return the icon resource identifier to use for this match. If the
* match defines an icon, that is used; else if the activity defines
* an icon, that is used; else, the application icon is used.
- *
+ * This function does not check noResourceId flag.
+ *
* @return The icon associated with this match.
*/
- public final int getIconResource() {
- if (noResourceId) return 0;
+ final int getIconResourceInternal() {
if (icon != 0) return icon;
final ComponentInfo ci = getComponentInfo();
if (ci != null) {
@@ -239,6 +239,18 @@ public class ResolveInfo implements Parcelable {
return 0;
}
+ /**
+ * Return the icon resource identifier to use for this match. If the
+ * match defines an icon, that is used; else if the activity defines
+ * an icon, that is used; else, the application icon is used.
+ *
+ * @return The icon associated with this match.
+ */
+ public final int getIconResource() {
+ if (noResourceId) return 0;
+ return getIconResourceInternal();
+ }
+
public void dump(Printer pw, String prefix) {
if (filter != null) {
pw.println(prefix + "Filter:");
diff --git a/core/java/android/hardware/usb/IUsbManager.aidl b/core/java/android/hardware/usb/IUsbManager.aidl
index 9bc967f..e4ab3f2 100644
--- a/core/java/android/hardware/usb/IUsbManager.aidl
+++ b/core/java/android/hardware/usb/IUsbManager.aidl
@@ -85,9 +85,6 @@ interface IUsbManager
/* Sets the current USB function. */
void setCurrentFunction(String function, boolean makeDefault);
- /* Sets the file path for USB mass storage backing file. */
- void setMassStorageBackingFile(String path);
-
/* Allow USB debugging from the attached host. If alwaysAllow is true, add the
* the public key to list of host keys that the user has approved.
*/
diff --git a/core/java/android/hardware/usb/UsbManager.java b/core/java/android/hardware/usb/UsbManager.java
index f283051..a45d4ca 100644
--- a/core/java/android/hardware/usb/UsbManager.java
+++ b/core/java/android/hardware/usb/UsbManager.java
@@ -410,28 +410,6 @@ public class UsbManager {
}
}
- private static boolean propertyContainsFunction(String property, String function) {
- String functions = SystemProperties.get(property, "");
- int index = functions.indexOf(function);
- if (index < 0) return false;
- if (index > 0 && functions.charAt(index - 1) != ',') return false;
- int charAfter = index + function.length();
- if (charAfter < functions.length() && functions.charAt(charAfter) != ',') return false;
- return true;
- }
-
- /**
- * Returns true if the specified USB function is currently enabled.
- *
- * @param function name of the USB function
- * @return true if the USB function is enabled.
- *
- * {@hide}
- */
- public boolean isFunctionEnabled(String function) {
- return propertyContainsFunction("sys.usb.config", function);
- }
-
/**
* Returns the current default USB function.
*
@@ -465,19 +443,4 @@ public class UsbManager {
Log.e(TAG, "RemoteException in setCurrentFunction", e);
}
}
-
- /**
- * Sets the file path for USB mass storage backing file.
- *
- * @param path backing file path
- *
- * {@hide}
- */
- public void setMassStorageBackingFile(String path) {
- try {
- mService.setMassStorageBackingFile(path);
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in setDefaultFunction", e);
- }
- }
}
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index d8c3361..26878c0 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -496,6 +496,8 @@ public class ConnectivityManager {
* Tests if a given integer represents a valid network type.
* @param networkType the type to be tested
* @return a boolean. {@code true} if the type is valid, else {@code false}
+ * @deprecated All APIs accepting a network type are deprecated. There should be no need to
+ * validate a network type.
*/
public static boolean isNetworkTypeValid(int networkType) {
return networkType >= 0 && networkType <= MAX_NETWORK_TYPE;
diff --git a/core/java/android/os/IDeviceIdleController.aidl b/core/java/android/os/IDeviceIdleController.aidl
index 3cb29ff..602bfea 100644
--- a/core/java/android/os/IDeviceIdleController.aidl
+++ b/core/java/android/os/IDeviceIdleController.aidl
@@ -23,4 +23,5 @@ interface IDeviceIdleController {
String[] getSystemPowerWhitelist();
String[] getFullPowerWhitelist();
int[] getAppIdWhitelist();
+ boolean isPowerSaveWhitelistApp(String name);
}
diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl
index 811418b..f212daf 100644
--- a/core/java/android/os/IUserManager.aidl
+++ b/core/java/android/os/IUserManager.aidl
@@ -45,6 +45,8 @@ interface IUserManager {
Bundle getUserRestrictions(int userHandle);
boolean hasUserRestriction(in String restrictionKey, int userHandle);
void setUserRestrictions(in Bundle restrictions, int userHandle);
+ void setUserRestriction(String key, boolean value, int userId);
+ void setSystemControlledUserRestriction(String key, boolean value, int userId);
void setApplicationRestrictions(in String packageName, in Bundle restrictions,
int userHandle);
Bundle getApplicationRestrictions(in String packageName);
diff --git a/core/java/android/os/PowerManagerInternal.java b/core/java/android/os/PowerManagerInternal.java
index 00ab262..9a0d0d0 100644
--- a/core/java/android/os/PowerManagerInternal.java
+++ b/core/java/android/os/PowerManagerInternal.java
@@ -134,4 +134,6 @@ public abstract class PowerManagerInternal {
}
public abstract void setDeviceIdleMode(boolean enabled);
+
+ public abstract void setDeviceIdleWhitelist(int[] appids);
}
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index c7ac7ce..cc37d5e 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -412,6 +412,16 @@ public class UserManager {
public static final String DISALLOW_SAFE_BOOT = "no_safe_boot";
/**
+ * Specifies if a user is not allowed to record audio. This restriction is always enabled for
+ * background users. The default value is <code>false</code>.
+ *
+ * @see #setUserRestrictions(Bundle)
+ * @see #getUserRestrictions()
+ * @hide
+ */
+ public static final String DISALLOW_RECORD_AUDIO = "no_record_audio";
+
+ /**
* Application restriction key that is used to indicate the pending arrival
* of real restrictions for the app.
*
@@ -688,9 +698,11 @@ public class UserManager {
*/
@Deprecated
public void setUserRestriction(String key, boolean value, UserHandle userHandle) {
- Bundle bundle = getUserRestrictions(userHandle);
- bundle.putBoolean(key, value);
- setUserRestrictions(bundle, userHandle);
+ try {
+ mService.setUserRestriction(key, value, userHandle.getIdentifier());
+ } catch (RemoteException re) {
+ Log.w(TAG, "Could not set user restriction", re);
+ }
}
/**
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index dc70d7b..d3a5561 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -5517,6 +5517,12 @@ public final class Settings {
public static final String APP_IDLE_DURATION = "app_idle_duration";
/**
+ * Controls whether double tap to wake is enabled.
+ * @hide
+ */
+ public static final String DOUBLE_TAP_TO_WAKE = "double_tap_to_wake";
+
+ /**
* This are the settings to be backed up.
*
* NOTE: Settings are backed up and restored in the order they appear
@@ -5571,7 +5577,8 @@ public final class Settings {
MOUNT_UMS_PROMPT,
MOUNT_UMS_NOTIFY_ENABLED,
UI_NIGHT_MODE,
- SLEEP_TIMEOUT
+ SLEEP_TIMEOUT,
+ DOUBLE_TAP_TO_WAKE,
};
/**
diff --git a/core/java/android/service/chooser/ChooserTarget.java b/core/java/android/service/chooser/ChooserTarget.java
index f0ca276..4c94ee7 100644
--- a/core/java/android/service/chooser/ChooserTarget.java
+++ b/core/java/android/service/chooser/ChooserTarget.java
@@ -58,12 +58,6 @@ public final class ChooserTarget implements Parcelable {
private IntentSender mIntentSender;
/**
- * A raw intent provided in lieu of an IntentSender. Will be filled in and sent
- * by {@link #sendIntent(Context, Intent)}.
- */
- private Intent mIntent;
-
- /**
* The score given to this item. It can be normalized.
*/
private float mScore;
@@ -146,43 +140,6 @@ public final class ChooserTarget implements Parcelable {
mIntentSender = intentSender;
}
- /**
- * Construct a deep link target for presentation by a chooser UI.
- *
- * <p>A target is composed of a title and an icon for presentation to the user.
- * The UI presenting this target may truncate the title if it is too long to be presented
- * in the available space, as well as crop, resize or overlay the supplied icon.</p>
- *
- * <p>The creator of a target may supply a ranking score. This score is assumed to be relative
- * to the other targets supplied by the same
- * {@link ChooserTargetService#onGetChooserTargets(ComponentName, IntentFilter) query}.
- * Scores should be in the range from 0.0f (unlikely match) to 1.0f (very relevant match).
- * Scores for a set of targets do not need to sum to 1.</p>
- *
- * <p>Before being sent, the Intent supplied will be
- * {@link Intent#fillIn(Intent, int) filled in} by the Intent originally supplied
- * to the chooser.</p>
- *
- * <p>Take care not to place custom {@link android.os.Parcelable} types into
- * the Intent as extras, as the system will not be able to unparcel it to merge
- * additional extras.</p>
- *
- * @param title title of this target that will be shown to a user
- * @param icon icon to represent this target
- * @param score ranking score for this target between 0.0f and 1.0f, inclusive
- * @param intent Intent to fill in and send if the user chooses this target
- */
- public ChooserTarget(CharSequence title, Bitmap icon, float score, Intent intent) {
- mTitle = title;
- mIcon = icon;
- if (score > 1.f || score < 0.f) {
- throw new IllegalArgumentException("Score " + score + " out of range; "
- + "must be between 0.0f and 1.0f");
- }
- mScore = score;
- mIntent = intent;
- }
-
ChooserTarget(Parcel in) {
mTitle = in.readCharSequence();
if (in.readInt() != 0) {
@@ -192,9 +149,6 @@ public final class ChooserTarget implements Parcelable {
}
mScore = in.readFloat();
mIntentSender = IntentSender.readIntentSenderOrNullFromParcel(in);
- if (in.readInt() != 0) {
- mIntent = Intent.CREATOR.createFromParcel(in);
- }
}
/**
@@ -241,18 +195,6 @@ public final class ChooserTarget implements Parcelable {
}
/**
- * Returns the Intent supplied by the ChooserTarget's creator.
- * This may be null if the creator specified an IntentSender or PendingIntent instead.
- *
- * <p>To fill in and send the intent, see {@link #sendIntent(Context, Intent)}.</p>
- *
- * @return the Intent supplied by the ChooserTarget's creator
- */
- public Intent getIntent() {
- return mIntent;
- }
-
- /**
* Fill in the IntentSender supplied by the ChooserTarget's creator and send it.
*
* @param context the sending Context; generally the Activity presenting the chooser UI
@@ -272,91 +214,8 @@ public final class ChooserTarget implements Parcelable {
Log.e(TAG, "sendIntent " + this + " failed", e);
return false;
}
- } else if (mIntent != null) {
- try {
- final Intent toSend = new Intent(mIntent);
- toSend.fillIn(fillInIntent, 0);
- context.startActivity(toSend);
- return true;
- } catch (Exception e) {
- Log.e(TAG, "sendIntent " + this + " failed", e);
- return false;
- }
} else {
- Log.e(TAG, "sendIntent " + this + " failed - no IntentSender or Intent to send");
- return false;
- }
- }
-
- /**
- * Same as {@link #sendIntent(Context, Intent)}, but offers a userId field to use
- * for launching the {@link #getIntent() intent} using
- * {@link Activity#startActivityAsCaller(Intent, Bundle, int)} if the
- * {@link #getIntentSender() IntentSender} is not present. If the IntentSender is present,
- * it will be invoked as usual with its own calling identity.
- *
- * @hide internal use only.
- */
- public boolean sendIntentAsCaller(Activity context, Intent fillInIntent, int userId) {
- if (fillInIntent != null) {
- fillInIntent.migrateExtraStreamToClipData();
- fillInIntent.prepareToLeaveProcess();
- }
- if (mIntentSender != null) {
- try {
- mIntentSender.sendIntent(context, 0, fillInIntent, null, null);
- return true;
- } catch (IntentSender.SendIntentException e) {
- Log.e(TAG, "sendIntent " + this + " failed", e);
- return false;
- }
- } else if (mIntent != null) {
- try {
- final Intent toSend = new Intent(mIntent);
- toSend.fillIn(fillInIntent, 0);
- context.startActivityAsCaller(toSend, null, userId);
- return true;
- } catch (Exception e) {
- Log.e(TAG, "sendIntent " + this + " failed", e);
- return false;
- }
- } else {
- Log.e(TAG, "sendIntent " + this + " failed - no IntentSender or Intent to send");
- return false;
- }
- }
-
- /**
- * The UserHandle is only used if we're launching a raw intent. The IntentSender will be
- * launched with its associated identity.
- *
- * @hide Internal use only
- */
- public boolean sendIntentAsUser(Activity context, Intent fillInIntent, UserHandle user) {
- if (fillInIntent != null) {
- fillInIntent.migrateExtraStreamToClipData();
- fillInIntent.prepareToLeaveProcess();
- }
- if (mIntentSender != null) {
- try {
- mIntentSender.sendIntent(context, 0, fillInIntent, null, null);
- return true;
- } catch (IntentSender.SendIntentException e) {
- Log.e(TAG, "sendIntent " + this + " failed", e);
- return false;
- }
- } else if (mIntent != null) {
- try {
- final Intent toSend = new Intent(mIntent);
- toSend.fillIn(fillInIntent, 0);
- context.startActivityAsUser(toSend, user);
- return true;
- } catch (Exception e) {
- Log.e(TAG, "sendIntent " + this + " failed", e);
- return false;
- }
- } else {
- Log.e(TAG, "sendIntent " + this + " failed - no IntentSender or Intent to send");
+ Log.e(TAG, "sendIntent " + this + " failed - no IntentSender to send");
return false;
}
}
@@ -364,7 +223,7 @@ public final class ChooserTarget implements Parcelable {
@Override
public String toString() {
return "ChooserTarget{"
- + (mIntentSender != null ? mIntentSender.getCreatorPackage() : mIntent)
+ + (mIntentSender != null ? mIntentSender.getCreatorPackage() : null)
+ ", "
+ "'" + mTitle
+ "', " + mScore + "}";
@@ -386,10 +245,6 @@ public final class ChooserTarget implements Parcelable {
}
dest.writeFloat(mScore);
IntentSender.writeIntentSenderOrNullToParcel(mIntentSender, dest);
- dest.writeInt(mIntent != null ? 1 : 0);
- if (mIntent != null) {
- mIntent.writeToParcel(dest, 0);
- }
}
public static final Creator<ChooserTarget> CREATOR
diff --git a/core/java/android/view/AccessibilityInteractionController.java b/core/java/android/view/AccessibilityInteractionController.java
index 68ad782..3781d40 100644
--- a/core/java/android/view/AccessibilityInteractionController.java
+++ b/core/java/android/view/AccessibilityInteractionController.java
@@ -586,7 +586,7 @@ final class AccessibilityInteractionController {
}
}
- private void perfromAccessibilityActionUiThread(Message message) {
+ private void performAccessibilityActionUiThread(Message message) {
final int flags = message.arg1;
final int accessibilityViewId = message.arg2;
@@ -602,7 +602,8 @@ final class AccessibilityInteractionController {
boolean succeeded = false;
try {
- if (mViewRootImpl.mView == null || mViewRootImpl.mAttachInfo == null) {
+ if (mViewRootImpl.mView == null || mViewRootImpl.mAttachInfo == null ||
+ mViewRootImpl.mStopped || mViewRootImpl.mPausedForTransition) {
return;
}
mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = flags;
@@ -1146,7 +1147,7 @@ final class AccessibilityInteractionController {
findAccessibilityNodeInfoByAccessibilityIdUiThread(message);
} break;
case MSG_PERFORM_ACCESSIBILITY_ACTION: {
- perfromAccessibilityActionUiThread(message);
+ performAccessibilityActionUiThread(message);
} break;
case MSG_FIND_ACCESSIBILITY_NODE_INFOS_BY_VIEW_ID: {
findAccessibilityNodeInfosByViewIdUiThread(message);
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index 1ac3f45..f6ce353 100644
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -1817,9 +1817,7 @@ public class KeyEvent extends InputEvent implements Parcelable {
public static final boolean isWakeKey(int keyCode) {
switch (keyCode) {
case KeyEvent.KEYCODE_BACK:
- case KeyEvent.KEYCODE_POWER:
case KeyEvent.KEYCODE_MENU:
- case KeyEvent.KEYCODE_SLEEP:
case KeyEvent.KEYCODE_WAKEUP:
case KeyEvent.KEYCODE_PAIRING:
return true;
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 51c4760..b476e9b 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -586,6 +586,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
mGroupFlags |= FLAG_CLIP_CHILDREN;
mGroupFlags |= FLAG_CLIP_TO_PADDING;
mGroupFlags |= FLAG_ANIMATION_DONE;
+ mGroupFlags |= FLAG_ANIMATION_CACHE;
+ mGroupFlags |= FLAG_ALWAYS_DRAWN_WITH_CACHE;
if (mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB) {
mGroupFlags |= FLAG_SPLIT_MOTION_EVENTS;
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index ea1dadb..57c6cbf 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -174,6 +174,9 @@ public final class ViewRootImpl implements ViewParent,
// so the window should no longer be active.
boolean mStopped = false;
+ // Set to true to stop input during an Activity Transition.
+ boolean mPausedForTransition = false;
+
boolean mLastInCompatMode = false;
SurfaceHolder.Callback2 mSurfaceHolderCallback;
@@ -982,15 +985,25 @@ public final class ViewRootImpl implements ViewParent,
return null;
}
- void setStopped(boolean stopped) {
+ void setWindowStopped(boolean stopped) {
if (mStopped != stopped) {
mStopped = stopped;
- if (!stopped) {
+ if (!mStopped) {
scheduleTraversals();
}
}
}
+ /**
+ * Block the input events during an Activity Transition. The KEYCODE_BACK event is allowed
+ * through to allow quick reversal of the Activity Transition.
+ *
+ * @param paused true to pause, false to resume.
+ */
+ public void setPausedForTransition(boolean paused) {
+ mPausedForTransition = paused;
+ }
+
@Override
public ViewParent getParent() {
return null;
@@ -3637,8 +3650,9 @@ public final class ViewRootImpl implements ViewParent,
if (mView == null || !mAdded) {
Slog.w(TAG, "Dropping event due to root view being removed: " + q.mEvent);
return true;
- } else if ((!mAttachInfo.mHasWindowFocus || mStopped)
- && !q.mEvent.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) {
+ } else if ((!mAttachInfo.mHasWindowFocus
+ && !q.mEvent.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) || mStopped
+ || (mPausedForTransition && !isBack(q.mEvent))) {
// This is a focus event and the window doesn't currently have input focus or
// has stopped. This could be an event that came back from the previous stage
// but the window has lost focus or stopped in the meantime.
@@ -3661,6 +3675,14 @@ public final class ViewRootImpl implements ViewParent,
mNext.dump(prefix, writer);
}
}
+
+ private boolean isBack(InputEvent event) {
+ if (event instanceof KeyEvent) {
+ return ((KeyEvent) event).getKeyCode() == KeyEvent.KEYCODE_BACK;
+ } else {
+ return false;
+ }
+ }
}
/**
@@ -6228,7 +6250,7 @@ public final class ViewRootImpl implements ViewParent,
@Override
public boolean requestSendAccessibilityEvent(View child, AccessibilityEvent event) {
- if (mView == null) {
+ if (mView == null || mStopped || mPausedForTransition) {
return false;
}
// Intercept accessibility focus events fired by virtual nodes to keep
diff --git a/core/java/android/view/WindowManagerGlobal.java b/core/java/android/view/WindowManagerGlobal.java
index 57558ff..e7a7ba8 100644
--- a/core/java/android/view/WindowManagerGlobal.java
+++ b/core/java/android/view/WindowManagerGlobal.java
@@ -21,7 +21,6 @@ import android.app.ActivityManager;
import android.content.ComponentCallbacks2;
import android.content.Context;
import android.content.res.Configuration;
-import android.os.Build;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -552,7 +551,7 @@ public final class WindowManagerGlobal {
for (int i = 0; i < count; i++) {
if (token == null || mParams.get(i).token == token) {
ViewRootImpl root = mRoots.get(i);
- root.setStopped(stopped);
+ root.setWindowStopped(stopped);
}
}
}
diff --git a/core/java/android/widget/AppSecurityPermissions.java b/core/java/android/widget/AppSecurityPermissions.java
index 6feb94b..bb4a948 100644
--- a/core/java/android/widget/AppSecurityPermissions.java
+++ b/core/java/android/widget/AppSecurityPermissions.java
@@ -244,7 +244,7 @@ public class AppSecurityPermissions {
@Override
public void onClick(DialogInterface dialog, int which) {
PackageManager pm = getContext().getPackageManager();
- pm.revokePermission(mPackageName, mPerm.name,
+ pm.revokeRuntimePermission(mPackageName, mPerm.name,
new UserHandle(mContext.getUserId()));
PermissionItemView.this.setVisibility(View.GONE);
}
diff --git a/core/java/android/widget/CalendarViewLegacyDelegate.java b/core/java/android/widget/CalendarViewLegacyDelegate.java
index 6ab3828..442fb33 100644
--- a/core/java/android/widget/CalendarViewLegacyDelegate.java
+++ b/core/java/android/widget/CalendarViewLegacyDelegate.java
@@ -713,7 +713,7 @@ class CalendarViewLegacyDelegate extends CalendarView.AbstractCalendarViewDelega
for (int i = 1, count = mDayNamesHeader.getChildCount(); i < count; i++) {
label = (TextView) mDayNamesHeader.getChildAt(i);
if (mWeekDayTextAppearanceResId > -1) {
- label.setTextAppearance(mContext, mWeekDayTextAppearanceResId);
+ label.setTextAppearance(mWeekDayTextAppearanceResId);
}
if (i < mDaysPerWeek + 1) {
label.setText(mDayNamesShort[i - 1]);
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 78c418b..2e36cee 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -2055,7 +2055,7 @@ public class Editor {
shadowView.setText(text);
shadowView.setTextColor(mTextView.getTextColors());
- shadowView.setTextAppearance(mTextView.getContext(), R.styleable.Theme_textAppearanceLarge);
+ shadowView.setTextAppearance(R.styleable.Theme_textAppearanceLarge);
shadowView.setGravity(Gravity.CENTER);
shadowView.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
@@ -3902,6 +3902,9 @@ public class Editor {
@Override
public void updatePosition(float x, float y) {
positionAtCursorOffset(mTextView.getOffsetForPosition(x, y), false);
+ if (mSelectionActionMode != null) {
+ mSelectionActionMode.invalidate();
+ }
}
@Override
diff --git a/core/java/android/widget/Toolbar.java b/core/java/android/widget/Toolbar.java
index 087406a..62d948d 100644
--- a/core/java/android/widget/Toolbar.java
+++ b/core/java/android/widget/Toolbar.java
@@ -590,7 +590,7 @@ public class Toolbar extends ViewGroup {
mTitleTextView.setSingleLine();
mTitleTextView.setEllipsize(TextUtils.TruncateAt.END);
if (mTitleTextAppearance != 0) {
- mTitleTextView.setTextAppearance(context, mTitleTextAppearance);
+ mTitleTextView.setTextAppearance(mTitleTextAppearance);
}
if (mTitleTextColor != 0) {
mTitleTextView.setTextColor(mTitleTextColor);
@@ -644,7 +644,7 @@ public class Toolbar extends ViewGroup {
mSubtitleTextView.setSingleLine();
mSubtitleTextView.setEllipsize(TextUtils.TruncateAt.END);
if (mSubtitleTextAppearance != 0) {
- mSubtitleTextView.setTextAppearance(context, mSubtitleTextAppearance);
+ mSubtitleTextView.setTextAppearance(mSubtitleTextAppearance);
}
if (mSubtitleTextColor != 0) {
mSubtitleTextView.setTextColor(mSubtitleTextColor);
@@ -670,7 +670,7 @@ public class Toolbar extends ViewGroup {
public void setTitleTextAppearance(Context context, @StyleRes int resId) {
mTitleTextAppearance = resId;
if (mTitleTextView != null) {
- mTitleTextView.setTextAppearance(context, resId);
+ mTitleTextView.setTextAppearance(resId);
}
}
@@ -681,7 +681,7 @@ public class Toolbar extends ViewGroup {
public void setSubtitleTextAppearance(Context context, @StyleRes int resId) {
mSubtitleTextAppearance = resId;
if (mSubtitleTextView != null) {
- mSubtitleTextView.setTextAppearance(context, resId);
+ mSubtitleTextView.setTextAppearance(resId);
}
}
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 62ca1f0..83fa967 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -24,9 +24,11 @@ import android.content.IntentSender;
import android.content.IntentSender.SendIntentException;
import android.content.ServiceConnection;
import android.content.pm.ActivityInfo;
+import android.content.pm.LabeledIntent;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
+import android.database.DataSetObserver;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
@@ -37,6 +39,7 @@ import android.os.Parcelable;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.UserHandle;
+import android.os.UserManager;
import android.service.chooser.ChooserTarget;
import android.service.chooser.ChooserTargetService;
import android.service.chooser.IChooserTargetResult;
@@ -44,8 +47,16 @@ import android.service.chooser.IChooserTargetService;
import android.text.TextUtils;
import android.util.Log;
import android.util.Slog;
+import android.view.LayoutInflater;
import android.view.View;
+import android.view.View.OnClickListener;
import android.view.ViewGroup;
+import android.view.ViewGroup.LayoutParams;
+import android.widget.AbsListView;
+import android.widget.BaseAdapter;
+import android.widget.LinearLayout;
+import android.widget.ListView;
+import com.android.internal.R;
import java.util.ArrayList;
import java.util.List;
@@ -63,7 +74,7 @@ public class ChooserActivity extends ResolverActivity {
private IntentSender mRefinementIntentSender;
private RefinementResultReceiver mRefinementResultReceiver;
- private ChooserTarget[] mCallerChooserTargets;
+ private ChooserListAdapter mChooserListAdapter;
private final List<ChooserTargetServiceConnection> mServiceConnections = new ArrayList<>();
@@ -84,8 +95,7 @@ public class ChooserActivity extends ResolverActivity {
+ " Have you considered returning results faster?");
break;
}
- final ChooserListAdapter cla = (ChooserListAdapter) getAdapter();
- cla.addServiceResults(sri.originalTarget, sri.resultTargets);
+ mChooserListAdapter.addServiceResults(sri.originalTarget, sri.resultTargets);
unbindService(sri.connection);
mServiceConnections.remove(sri.connection);
break;
@@ -166,20 +176,6 @@ public class ChooserActivity extends ResolverActivity {
}
}
- pa = intent.getParcelableArrayExtra(Intent.EXTRA_CHOOSER_TARGETS);
- if (pa != null) {
- final ChooserTarget[] targets = new ChooserTarget[pa.length];
- for (int i = 0; i < pa.length; i++) {
- if (!(pa[i] instanceof ChooserTarget)) {
- Log.w(TAG, "Chooser target #" + i + " is not a ChooserTarget: " + pa[i]);
- finish();
- super.onCreate(null);
- return;
- }
- targets[i] = (ChooserTarget) pa[i];
- }
- mCallerChooserTargets = targets;
- }
mChosenComponentSender = intent.getParcelableExtra(
Intent.EXTRA_CHOSEN_COMPONENT_INTENT_SENDER);
mRefinementIntentSender = intent.getParcelableExtra(
@@ -233,8 +229,19 @@ public class ChooserActivity extends ResolverActivity {
}
@Override
+ void onPrepareAdapterView(AbsListView adapterView, ResolveListAdapter adapter,
+ boolean alwaysUseOption) {
+ final ListView listView = adapterView instanceof ListView ? (ListView) adapterView : null;
+ mChooserListAdapter = (ChooserListAdapter) adapter;
+ adapterView.setAdapter(new ChooserRowAdapter(mChooserListAdapter));
+ if (listView != null) {
+ listView.setItemsCanFocus(true);
+ }
+ }
+
+ @Override
int getLayoutResource() {
- return com.android.internal.R.layout.chooser_grid;
+ return R.layout.chooser_grid;
}
@Override
@@ -413,10 +420,11 @@ public class ChooserActivity extends ResolverActivity {
}
@Override
- ResolveListAdapter createAdapter(Context context, Intent[] initialIntents,
- List<ResolveInfo> rList, int launchedFromUid, boolean filterLastUsed) {
- final ChooserListAdapter adapter = new ChooserListAdapter(context, initialIntents, rList,
- launchedFromUid, filterLastUsed, mCallerChooserTargets);
+ ResolveListAdapter createAdapter(Context context, List<Intent> payloadIntents,
+ Intent[] initialIntents, List<ResolveInfo> rList, int launchedFromUid,
+ boolean filterLastUsed) {
+ final ChooserListAdapter adapter = new ChooserListAdapter(context, payloadIntents,
+ initialIntents, rList, launchedFromUid, filterLastUsed);
if (DEBUG) Log.d(TAG, "Adapter created; querying services");
queryTargetServices(adapter);
return adapter;
@@ -426,17 +434,23 @@ public class ChooserActivity extends ResolverActivity {
private final DisplayResolveInfo mSourceInfo;
private final ResolveInfo mBackupResolveInfo;
private final ChooserTarget mChooserTarget;
+ private Drawable mBadgeIcon = null;
private final Drawable mDisplayIcon;
private final Intent mFillInIntent;
private final int mFillInFlags;
- public ChooserTargetInfo(ChooserTarget target) {
- this(null, target);
- }
-
public ChooserTargetInfo(DisplayResolveInfo sourceInfo, ChooserTarget chooserTarget) {
mSourceInfo = sourceInfo;
mChooserTarget = chooserTarget;
+ if (sourceInfo != null) {
+ final ResolveInfo ri = sourceInfo.getResolveInfo();
+ if (ri != null) {
+ final ActivityInfo ai = ri.activityInfo;
+ if (ai != null && ai.applicationInfo != null) {
+ mBadgeIcon = getPackageManager().getApplicationIcon(ai.applicationInfo);
+ }
+ }
+ }
mDisplayIcon = new BitmapDrawable(getResources(), chooserTarget.getIcon());
if (sourceInfo != null) {
@@ -453,6 +467,7 @@ public class ChooserActivity extends ResolverActivity {
mSourceInfo = other.mSourceInfo;
mBackupResolveInfo = other.mBackupResolveInfo;
mChooserTarget = other.mChooserTarget;
+ mBadgeIcon = other.mBadgeIcon;
mDisplayIcon = other.mDisplayIcon;
mFillInIntent = fillInIntent;
mFillInFlags = flags;
@@ -460,10 +475,7 @@ public class ChooserActivity extends ResolverActivity {
@Override
public Intent getResolvedIntent() {
- final Intent targetIntent = mChooserTarget.getIntent();
- if (targetIntent != null) {
- return targetIntent;
- } else if (mSourceInfo != null) {
+ if (mSourceInfo != null) {
return mSourceInfo.getResolvedIntent();
}
return getTargetIntent();
@@ -507,7 +519,8 @@ public class ChooserActivity extends ResolverActivity {
if (intent == null) {
return false;
}
- return mChooserTarget.sendIntentAsCaller(activity, intent, userId);
+ // ChooserTargets will launch with their IntentSender's identity
+ return mChooserTarget.sendIntent(activity, intent);
}
@Override
@@ -516,7 +529,8 @@ public class ChooserActivity extends ResolverActivity {
if (intent == null) {
return false;
}
- return mChooserTarget.sendIntentAsUser(activity, intent, user);
+ // ChooserTargets will launch with their IntentSender's identity
+ return mChooserTarget.sendIntent(activity, intent);
}
@Override
@@ -540,6 +554,11 @@ public class ChooserActivity extends ResolverActivity {
}
@Override
+ public Drawable getBadgeIcon() {
+ return mBadgeIcon;
+ }
+
+ @Override
public TargetInfo cloneFilledIn(Intent fillInIntent, int flags) {
return new ChooserTargetInfo(this, fillInIntent, flags);
}
@@ -556,16 +575,49 @@ public class ChooserActivity extends ResolverActivity {
}
public class ChooserListAdapter extends ResolveListAdapter {
- private final List<ChooserTargetInfo> mServiceTargets = new ArrayList<>();
- private final List<ChooserTargetInfo> mCallerTargets = new ArrayList<>();
-
- public ChooserListAdapter(Context context, Intent[] initialIntents, List<ResolveInfo> rList,
- int launchedFromUid, boolean filterLastUsed, ChooserTarget[] callerChooserTargets) {
- super(context, initialIntents, rList, launchedFromUid, filterLastUsed);
+ public static final int TARGET_BAD = -1;
+ public static final int TARGET_CALLER = 0;
+ public static final int TARGET_SERVICE = 1;
+ public static final int TARGET_STANDARD = 2;
- if (callerChooserTargets != null) {
- for (ChooserTarget target : callerChooserTargets) {
- mCallerTargets.add(new ChooserTargetInfo(target));
+ private final List<ChooserTargetInfo> mServiceTargets = new ArrayList<>();
+ private final List<TargetInfo> mCallerTargets = new ArrayList<>();
+
+ public ChooserListAdapter(Context context, List<Intent> payloadIntents,
+ Intent[] initialIntents, List<ResolveInfo> rList, int launchedFromUid,
+ boolean filterLastUsed) {
+ // Don't send the initial intents through the shared ResolverActivity path,
+ // we want to separate them into a different section.
+ super(context, payloadIntents, null, rList, launchedFromUid, filterLastUsed);
+
+ if (initialIntents != null) {
+ final PackageManager pm = getPackageManager();
+ for (int i = 0; i < initialIntents.length; i++) {
+ final Intent ii = initialIntents[i];
+ if (ii == null) {
+ continue;
+ }
+ final ActivityInfo ai = ii.resolveActivityInfo(pm, 0);
+ if (ai == null) {
+ Log.w(TAG, "No activity found for " + ii);
+ continue;
+ }
+ ResolveInfo ri = new ResolveInfo();
+ ri.activityInfo = ai;
+ UserManager userManager =
+ (UserManager) getSystemService(Context.USER_SERVICE);
+ if (userManager.isManagedProfile()) {
+ ri.noResourceId = true;
+ }
+ if (ii instanceof LabeledIntent) {
+ LabeledIntent li = (LabeledIntent)ii;
+ ri.resolvePackageName = li.getSourcePackage();
+ ri.labelRes = li.getLabelResource();
+ ri.nonLocalizedLabel = li.getNonLocalizedLabel();
+ ri.icon = li.getIconResource();
+ }
+ mCallerTargets.add(new DisplayResolveInfo(ii, ri,
+ ri.loadLabel(pm), null, ii));
}
}
}
@@ -578,7 +630,7 @@ public class ChooserActivity extends ResolverActivity {
}
@Override
- public View createView(ViewGroup parent) {
+ public View onCreateView(ViewGroup parent) {
return mInflater.inflate(
com.android.internal.R.layout.resolve_grid_item, parent, false);
}
@@ -600,6 +652,41 @@ public class ChooserActivity extends ResolverActivity {
return super.getCount() + mServiceTargets.size() + mCallerTargets.size();
}
+ public int getCallerTargetsCount() {
+ return mCallerTargets.size();
+ }
+
+ public int getServiceTargetsCount() {
+ return mServiceTargets.size();
+ }
+
+ public int getStandardTargetCount() {
+ return super.getCount();
+ }
+
+ public int getPositionTargetType(int position) {
+ int offset = 0;
+
+ final int callerTargetCount = mCallerTargets.size();
+ if (position < callerTargetCount) {
+ return TARGET_CALLER;
+ }
+ offset += callerTargetCount;
+
+ final int serviceTargetCount = mServiceTargets.size();
+ if (position - offset < serviceTargetCount) {
+ return TARGET_SERVICE;
+ }
+ offset += serviceTargetCount;
+
+ final int standardTargetCount = super.getCount();
+ if (position - offset < standardTargetCount) {
+ return TARGET_STANDARD;
+ }
+
+ return TARGET_BAD;
+ }
+
@Override
public TargetInfo getItem(int position) {
int offset = 0;
@@ -643,6 +730,133 @@ public class ChooserActivity extends ResolverActivity {
}
}
+ class ChooserRowAdapter extends BaseAdapter {
+ private ChooserListAdapter mChooserListAdapter;
+ private final LayoutInflater mLayoutInflater;
+ private final int mColumnCount = 4;
+
+ public ChooserRowAdapter(ChooserListAdapter wrappedAdapter) {
+ mChooserListAdapter = wrappedAdapter;
+ mLayoutInflater = LayoutInflater.from(ChooserActivity.this);
+
+ wrappedAdapter.registerDataSetObserver(new DataSetObserver() {
+ @Override
+ public void onChanged() {
+ super.onChanged();
+ notifyDataSetChanged();
+ }
+
+ @Override
+ public void onInvalidated() {
+ super.onInvalidated();
+ notifyDataSetInvalidated();
+ }
+ });
+ }
+
+ @Override
+ public int getCount() {
+ return (int) (
+ Math.ceil((float) mChooserListAdapter.getCallerTargetsCount() / mColumnCount)
+ + Math.ceil((float) mChooserListAdapter.getServiceTargetsCount() / mColumnCount)
+ + Math.ceil((float) mChooserListAdapter.getStandardTargetCount() / mColumnCount)
+ );
+ }
+
+ @Override
+ public Object getItem(int position) {
+ // We have nothing useful to return here.
+ return position;
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ final View[] holder;
+ if (convertView == null) {
+ holder = createViewHolder(parent);
+ } else {
+ holder = (View[]) convertView.getTag();
+ }
+ bindViewHolder(position, holder);
+
+ // We keep the actual list item view as the last item in the holder array
+ return holder[mColumnCount];
+ }
+
+ View[] createViewHolder(ViewGroup parent) {
+ final View[] holder = new View[mColumnCount + 1];
+
+ final ViewGroup row = (ViewGroup) mLayoutInflater.inflate(R.layout.chooser_row,
+ parent, false);
+ for (int i = 0; i < mColumnCount; i++) {
+ holder[i] = mChooserListAdapter.createView(row);
+ row.addView(holder[i]);
+ }
+ row.setTag(holder);
+ holder[mColumnCount] = row;
+ return holder;
+ }
+
+ void bindViewHolder(int rowPosition, View[] holder) {
+ final int start = getFirstRowPosition(rowPosition);
+ final int startType = mChooserListAdapter.getPositionTargetType(start);
+
+ int end = start + mColumnCount - 1;
+ while (mChooserListAdapter.getPositionTargetType(end) != startType && end >= start) {
+ end--;
+ }
+
+ final ViewGroup row = (ViewGroup) holder[mColumnCount];
+
+ if (startType == ChooserListAdapter.TARGET_SERVICE) {
+ row.setBackgroundColor(getColor(R.color.chooser_service_row_background_color));
+ } else {
+ row.setBackground(null);
+ }
+
+ for (int i = 0; i < mColumnCount; i++) {
+ final View v = holder[i];
+ if (start + i <= end) {
+ v.setVisibility(View.VISIBLE);
+ final int itemIndex = start + i;
+ mChooserListAdapter.bindView(itemIndex, v);
+ v.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ startSelected(itemIndex, false, true);
+ }
+ });
+ } else {
+ v.setVisibility(View.GONE);
+ }
+ }
+ }
+
+ int getFirstRowPosition(int row) {
+ final int callerCount = mChooserListAdapter.getCallerTargetsCount();
+ final int callerRows = (int) Math.ceil((float) callerCount / mColumnCount);
+
+ if (row < callerRows) {
+ return row * mColumnCount;
+ }
+
+ final int serviceCount = mChooserListAdapter.getServiceTargetsCount();
+ final int serviceRows = (int) Math.ceil((float) serviceCount / mColumnCount);
+
+ if (row < callerRows + serviceRows) {
+ return callerCount + (row - callerRows) * mColumnCount;
+ }
+
+ return callerCount + serviceCount
+ + (row - callerRows - serviceRows) * mColumnCount;
+ }
+ }
+
class ChooserTargetServiceConnection implements ServiceConnection {
private final DisplayResolveInfo mOriginalTarget;
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 2048664..4696757 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -25,7 +25,6 @@ import android.provider.Settings;
import android.text.TextUtils;
import android.util.Slog;
import android.widget.AbsListView;
-import android.widget.GridView;
import com.android.internal.R;
import com.android.internal.content.PackageMonitor;
@@ -83,7 +82,7 @@ import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
* which there is more than one matching activity, allowing the user to decide
* which to go to. It is not normally used directly by application developers.
*/
-public class ResolverActivity extends Activity implements AdapterView.OnItemClickListener {
+public class ResolverActivity extends Activity {
private static final String TAG = "ResolverActivity";
private static final boolean DEBUG = false;
@@ -93,8 +92,6 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
private boolean mSafeForwardingMode;
private boolean mAlwaysUseOption;
private AbsListView mAdapterView;
- private ListView mListView;
- private GridView mGridView;
private Button mAlwaysButton;
private Button mOnceButton;
private View mProfileView;
@@ -217,6 +214,13 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
} catch (RemoteException e) {
mLaunchedFromUid = -1;
}
+
+ if (mLaunchedFromUid < 0 || UserHandle.isIsolated(mLaunchedFromUid)) {
+ // Gulp!
+ finish();
+ return;
+ }
+
mPm = getPackageManager();
mUsm = (UsageStatsManager) getSystemService(Context.USAGE_STATS_SERVICE);
@@ -229,67 +233,11 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
final ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
mIconDpi = am.getLauncherLargeIconDensity();
+ // Add our initial intent as the first item, regardless of what else has already been added.
mIntents.add(0, new Intent(intent));
- mAdapter = createAdapter(this, initialIntents, rList, mLaunchedFromUid, alwaysUseOption);
- final int layoutId;
- final boolean useHeader;
- if (mAdapter.hasFilteredItem()) {
- layoutId = R.layout.resolver_list_with_default;
- alwaysUseOption = false;
- useHeader = true;
- } else {
- useHeader = false;
- layoutId = getLayoutResource();
- }
- mAlwaysUseOption = alwaysUseOption;
+ configureContentView(mIntents, initialIntents, rList, alwaysUseOption);
- if (mLaunchedFromUid < 0 || UserHandle.isIsolated(mLaunchedFromUid)) {
- // Gulp!
- finish();
- return;
- }
-
- int count = mAdapter.mDisplayList.size();
- if (count > 1 || (count == 1 && mAdapter.getOtherProfile() != null)) {
- setContentView(layoutId);
- mAdapterView = (AbsListView) findViewById(R.id.resolver_list);
- mAdapterView.setAdapter(mAdapter);
- mAdapterView.setOnItemClickListener(this);
- mAdapterView.setOnItemLongClickListener(new ItemLongClickListener());
-
- // Initialize the different types of collection views we may have. Depending
- // on which ones are initialized later we'll configure different properties.
- if (mAdapterView instanceof ListView) {
- mListView = (ListView) mAdapterView;
- }
- if (mAdapterView instanceof GridView) {
- mGridView = (GridView) mAdapterView;
- }
-
- if (alwaysUseOption) {
- mAdapterView.setChoiceMode(AbsListView.CHOICE_MODE_SINGLE);
- }
-
- if (useHeader && mListView != null) {
- mListView.addHeaderView(LayoutInflater.from(this).inflate(
- R.layout.resolver_different_item_header, mListView, false));
- }
- } else if (count == 1) {
- safelyStartActivity(mAdapter.targetInfoForPosition(0, false));
- mPackageMonitor.unregister();
- mRegistered = false;
- finish();
- return;
- } else {
- setContentView(R.layout.resolver_list);
-
- final TextView empty = (TextView) findViewById(R.id.empty);
- empty.setVisibility(View.VISIBLE);
-
- mAdapterView = (AbsListView) findViewById(R.id.resolver_list);
- mAdapterView.setVisibility(View.GONE);
- }
// Prevent the Resolver window from becoming the top fullscreen window and thus from taking
// control of the system bars.
getWindow().clearFlags(FLAG_LAYOUT_IN_SCREEN|FLAG_LAYOUT_INSET_DECOR);
@@ -548,29 +496,6 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
}
}
- @Override
- public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
- if (mListView != null) {
- position -= mListView.getHeaderViewsCount();
- }
- if (position < 0) {
- // Header views don't count.
- return;
- }
- final int checkedPos = mAdapterView.getCheckedItemPosition();
- final boolean hasValidSelection = checkedPos != ListView.INVALID_POSITION;
- if (mAlwaysUseOption && (!hasValidSelection || mLastSelected != checkedPos)) {
- setAlwaysButtonEnabled(hasValidSelection, checkedPos, true);
- mOnceButton.setEnabled(hasValidSelection);
- if (hasValidSelection) {
- mAdapterView.smoothScrollToPosition(checkedPos);
- }
- mLastSelected = checkedPos;
- } else {
- startSelected(position, false, true);
- }
- }
-
private boolean hasManagedProfile() {
UserManager userManager = (UserManager) getSystemService(Context.USER_SERVICE);
if (userManager == null) {
@@ -743,29 +668,37 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
if (r.match > bestMatch) bestMatch = r.match;
}
if (alwaysCheck) {
- PackageManager pm = getPackageManager();
+ final int userId = getUserId();
+ final PackageManager pm = getPackageManager();
// Set the preferred Activity
pm.addPreferredActivity(filter, bestMatch, set, intent.getComponent());
- // Update Domain Verification status
- int userId = getUserId();
- ComponentName cn = intent.getComponent();
- String packageName = cn.getPackageName();
- String dataScheme = (data != null) ? data.getScheme() : null;
-
- boolean isHttpOrHttps = (dataScheme != null) &&
- (dataScheme.equals(IntentFilter.SCHEME_HTTP) ||
- dataScheme.equals(IntentFilter.SCHEME_HTTPS));
-
- boolean isViewAction = (action != null) && action.equals(Intent.ACTION_VIEW);
- boolean hasCategoryBrowsable = (categories != null) &&
- categories.contains(Intent.CATEGORY_BROWSABLE);
-
- if (isHttpOrHttps && isViewAction && hasCategoryBrowsable) {
- pm.updateIntentVerificationStatus(packageName,
- PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS,
- userId);
+ if (ri.handleAllWebDataURI) {
+ // Set default Browser if needed
+ final String packageName = pm.getDefaultBrowserPackageName(userId);
+ if (TextUtils.isEmpty(packageName)) {
+ pm.setDefaultBrowserPackageName(ri.activityInfo.packageName, userId);
+ }
+ } else {
+ // Update Domain Verification status
+ ComponentName cn = intent.getComponent();
+ String packageName = cn.getPackageName();
+ String dataScheme = (data != null) ? data.getScheme() : null;
+
+ boolean isHttpOrHttps = (dataScheme != null) &&
+ (dataScheme.equals(IntentFilter.SCHEME_HTTP) ||
+ dataScheme.equals(IntentFilter.SCHEME_HTTPS));
+
+ boolean isViewAction = (action != null) && action.equals(Intent.ACTION_VIEW);
+ boolean hasCategoryBrowsable = (categories != null) &&
+ categories.contains(Intent.CATEGORY_BROWSABLE);
+
+ if (isHttpOrHttps && isViewAction && hasCategoryBrowsable) {
+ pm.updateIntentVerificationStatus(packageName,
+ PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS,
+ userId);
+ }
}
} else {
try {
@@ -831,14 +764,68 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
startActivity(in);
}
- ResolveListAdapter createAdapter(Context context, Intent[] initialIntents,
- List<ResolveInfo> rList, int launchedFromUid, boolean filterLastUsed) {
- return new ResolveListAdapter(context, initialIntents, rList, launchedFromUid,
- filterLastUsed);
+ ResolveListAdapter createAdapter(Context context, List<Intent> payloadIntents,
+ Intent[] initialIntents, List<ResolveInfo> rList, int launchedFromUid,
+ boolean filterLastUsed) {
+ return new ResolveListAdapter(context, payloadIntents, initialIntents, rList,
+ launchedFromUid, filterLastUsed);
}
- ResolveListAdapter getAdapter() {
- return mAdapter;
+ void configureContentView(List<Intent> payloadIntents, Intent[] initialIntents,
+ List<ResolveInfo> rList, boolean alwaysUseOption) {
+ mAdapter = createAdapter(this, payloadIntents, initialIntents, rList,
+ mLaunchedFromUid, alwaysUseOption);
+
+ final int layoutId;
+ if (mAdapter.hasFilteredItem()) {
+ layoutId = R.layout.resolver_list_with_default;
+ alwaysUseOption = false;
+ } else {
+ layoutId = getLayoutResource();
+ }
+ mAlwaysUseOption = alwaysUseOption;
+
+ int count = mAdapter.mDisplayList.size();
+ if (count > 1 || (count == 1 && mAdapter.getOtherProfile() != null)) {
+ setContentView(layoutId);
+ mAdapterView = (AbsListView) findViewById(R.id.resolver_list);
+ onPrepareAdapterView(mAdapterView, mAdapter, alwaysUseOption);
+ } else if (count == 1) {
+ safelyStartActivity(mAdapter.targetInfoForPosition(0, false));
+ mPackageMonitor.unregister();
+ mRegistered = false;
+ finish();
+ return;
+ } else {
+ setContentView(R.layout.resolver_list);
+
+ final TextView empty = (TextView) findViewById(R.id.empty);
+ empty.setVisibility(View.VISIBLE);
+
+ mAdapterView = (AbsListView) findViewById(R.id.resolver_list);
+ mAdapterView.setVisibility(View.GONE);
+ }
+ }
+
+ void onPrepareAdapterView(AbsListView adapterView, ResolveListAdapter adapter,
+ boolean alwaysUseOption) {
+ final boolean useHeader = adapter.hasFilteredItem();
+ final ListView listView = adapterView instanceof ListView ? (ListView) adapterView : null;
+
+ adapterView.setAdapter(mAdapter);
+
+ final ItemClickListener listener = new ItemClickListener();
+ adapterView.setOnItemClickListener(listener);
+ adapterView.setOnItemLongClickListener(listener);
+
+ if (alwaysUseOption) {
+ listView.setChoiceMode(AbsListView.CHOICE_MODE_SINGLE);
+ }
+
+ if (useHeader && listView != null) {
+ listView.addHeaderView(LayoutInflater.from(this).inflate(
+ R.layout.resolver_different_item_header, listView, false));
+ }
}
final class DisplayResolveInfo implements TargetInfo {
@@ -888,6 +875,10 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
return mDisplayIcon;
}
+ public Drawable getBadgeIcon() {
+ return null;
+ }
+
@Override
public TargetInfo cloneFilledIn(Intent fillInIntent, int flags) {
return new DisplayResolveInfo(this, fillInIntent, flags);
@@ -1024,6 +1015,11 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
public Drawable getDisplayIcon();
/**
+ * @return The (small) icon to badge the target with
+ */
+ public Drawable getBadgeIcon();
+
+ /**
* Clone this target with the given fill-in information.
*/
public TargetInfo cloneFilledIn(Intent fillInIntent, int flags);
@@ -1035,6 +1031,7 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
}
class ResolveListAdapter extends BaseAdapter {
+ private final List<Intent> mIntents;
private final Intent[] mInitialIntents;
private final List<ResolveInfo> mBaseResolveList;
private ResolveInfo mLastChosen;
@@ -1050,8 +1047,10 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
private int mLastChosenPosition = -1;
private boolean mFilterLastUsed;
- public ResolveListAdapter(Context context, Intent[] initialIntents,
- List<ResolveInfo> rList, int launchedFromUid, boolean filterLastUsed) {
+ public ResolveListAdapter(Context context, List<Intent> payloadIntents,
+ Intent[] initialIntents, List<ResolveInfo> rList, int launchedFromUid,
+ boolean filterLastUsed) {
+ mIntents = payloadIntents;
mInitialIntents = initialIntents;
mBaseResolveList = rList;
mLaunchedFromUid = launchedFromUid;
@@ -1430,15 +1429,19 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
View view = convertView;
if (view == null) {
view = createView(parent);
-
- final ViewHolder holder = new ViewHolder(view);
- view.setTag(holder);
}
- bindView(view, getItem(position));
+ onBindView(view, getItem(position));
+ return view;
+ }
+
+ public final View createView(ViewGroup parent) {
+ final View view = onCreateView(parent);
+ final ViewHolder holder = new ViewHolder(view);
+ view.setTag(holder);
return view;
}
- public View createView(ViewGroup parent) {
+ public View onCreateView(ViewGroup parent) {
return mInflater.inflate(
com.android.internal.R.layout.resolve_list_item, parent, false);
}
@@ -1447,7 +1450,11 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
return !TextUtils.isEmpty(info.getExtendedInfo());
}
- private final void bindView(View view, TargetInfo info) {
+ public final void bindView(int position, View view) {
+ onBindView(view, getItem(position));
+ }
+
+ private void onBindView(View view, TargetInfo info) {
final ViewHolder holder = (ViewHolder) view.getTag();
holder.text.setText(info.getDisplayLabel());
if (showsExtendedInfo(info)) {
@@ -1461,6 +1468,15 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
new LoadAdapterIconTask((DisplayResolveInfo) info).execute();
}
holder.icon.setImageDrawable(info.getDisplayIcon());
+ if (holder.badge != null) {
+ final Drawable badge = info.getBadgeIcon();
+ if (badge != null) {
+ holder.badge.setImageDrawable(badge);
+ holder.badge.setVisibility(View.VISIBLE);
+ } else {
+ holder.badge.setVisibility(View.GONE);
+ }
+ }
}
}
@@ -1514,20 +1530,47 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
public TextView text;
public TextView text2;
public ImageView icon;
+ public ImageView badge;
public ViewHolder(View view) {
text = (TextView) view.findViewById(com.android.internal.R.id.text1);
text2 = (TextView) view.findViewById(com.android.internal.R.id.text2);
icon = (ImageView) view.findViewById(R.id.icon);
+ badge = (ImageView) view.findViewById(R.id.target_badge);
}
}
- class ItemLongClickListener implements AdapterView.OnItemLongClickListener {
+ class ItemClickListener implements AdapterView.OnItemClickListener,
+ AdapterView.OnItemLongClickListener {
+ @Override
+ public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+ final ListView listView = parent instanceof ListView ? (ListView) parent : null;
+ if (listView != null) {
+ position -= listView.getHeaderViewsCount();
+ }
+ if (position < 0) {
+ // Header views don't count.
+ return;
+ }
+ final int checkedPos = mAdapterView.getCheckedItemPosition();
+ final boolean hasValidSelection = checkedPos != ListView.INVALID_POSITION;
+ if (mAlwaysUseOption && (!hasValidSelection || mLastSelected != checkedPos)) {
+ setAlwaysButtonEnabled(hasValidSelection, checkedPos, true);
+ mOnceButton.setEnabled(hasValidSelection);
+ if (hasValidSelection) {
+ mAdapterView.smoothScrollToPosition(checkedPos);
+ }
+ mLastSelected = checkedPos;
+ } else {
+ startSelected(position, false, true);
+ }
+ }
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
- if (mListView != null) {
- position -= mListView.getHeaderViewsCount();
+ final ListView listView = parent instanceof ListView ? (ListView) parent : null;
+ if (listView != null) {
+ position -= listView.getHeaderViewsCount();
}
if (position < 0) {
// Header views don't count.
diff --git a/core/java/com/android/internal/logging/MetricsLogger.java b/core/java/com/android/internal/logging/MetricsLogger.java
index 9277f9b..cf25cef 100644
--- a/core/java/com/android/internal/logging/MetricsLogger.java
+++ b/core/java/com/android/internal/logging/MetricsLogger.java
@@ -27,7 +27,6 @@ import android.view.View;
*/
public class MetricsLogger implements MetricsConstants {
// These constants are temporary, they should migrate to MetricsConstants.
- // next value is 148;
public static final int NOTIFICATION_ZEN_MODE_SCHEDULE_RULE = 144;
public static final int NOTIFICATION_ZEN_MODE_EXTERNAL_RULE = 145;
@@ -38,6 +37,34 @@ public class MetricsLogger implements MetricsConstants {
public static final int QS_BLUETOOTH_DETAILS = 150;
public static final int QS_CAST_DETAILS = 151;
public static final int QS_WIFI_DETAILS = 152;
+ public static final int QS_WIFI_TOGGLE = 153;
+ public static final int QS_BLUETOOTH_TOGGLE = 154;
+ public static final int QS_CELLULAR_TOGGLE = 155;
+ public static final int QS_SWITCH_USER = 156;
+ public static final int QS_CAST_SELECT = 157;
+ public static final int QS_CAST_DISCONNECT = 158;
+ public static final int ACTION_BLUETOOTH_TOGGLE = 159;
+ public static final int ACTION_BLUETOOTH_SCAN = 160;
+ public static final int ACTION_BLUETOOTH_RENAME = 161;
+ public static final int ACTION_BLUETOOTH_FILES = 162;
+ public static final int QS_DND_TIME = 163;
+ public static final int QS_DND_CONDITION_SELECT = 164;
+ public static final int QS_DND_ZEN_SELECT = 165;
+ public static final int QS_DND_TOGGLE = 166;
+ public static final int ACTION_ZEN_ALLOW_REMINDERS = 167;
+ public static final int ACTION_ZEN_ALLOW_EVENTS = 168;
+ public static final int ACTION_ZEN_ALLOW_MESSAGES = 169;
+ public static final int ACTION_ZEN_ALLOW_CALLS = 170;
+ public static final int ACTION_ZEN_ALLOW_REPEAT_CALLS = 171;
+ public static final int ACTION_ZEN_ADD_RULE = 172;
+ public static final int ACTION_ZEN_ADD_RULE_OK = 173;
+ public static final int ACTION_ZEN_DELETE_RULE = 174;
+ public static final int ACTION_ZEN_DELETE_RULE_OK = 175;
+ public static final int ACTION_ZEN_ENABLE_RULE = 176;
+ public static final int ACTION_AIRPLANE_TOGGLE = 177;
+ public static final int ACTION_CELL_DATA_TOGGLE = 178;
+ public static final int NOTIFICATION_ACCESS = 179;
+ public static final int NOTIFICATION_ZEN_MODE_ACCESS = 180;
public static void visible(Context context, int category) throws IllegalArgumentException {
if (Build.IS_DEBUGGABLE && category == VIEW_UNKNOWN) {
@@ -71,6 +98,14 @@ public class MetricsLogger implements MetricsConstants {
action(context, category, "");
}
+ public static void action(Context context, int category, int value) {
+ action(context, category, Integer.toString(value));
+ }
+
+ public static void action(Context context, int category, boolean value) {
+ action(context, category, Boolean.toString(value));
+ }
+
public static void action(Context context, int category, String pkg) {
if (Build.IS_DEBUGGABLE && category == VIEW_UNKNOWN) {
throw new IllegalArgumentException("Must define metric category");
diff --git a/core/java/com/android/internal/widget/ActionBarContextView.java b/core/java/com/android/internal/widget/ActionBarContextView.java
index 2946456..106272b 100644
--- a/core/java/com/android/internal/widget/ActionBarContextView.java
+++ b/core/java/com/android/internal/widget/ActionBarContextView.java
@@ -192,10 +192,10 @@ public class ActionBarContextView extends AbsActionBarView implements AnimatorLi
mTitleView = (TextView) mTitleLayout.findViewById(R.id.action_bar_title);
mSubtitleView = (TextView) mTitleLayout.findViewById(R.id.action_bar_subtitle);
if (mTitleStyleRes != 0) {
- mTitleView.setTextAppearance(mContext, mTitleStyleRes);
+ mTitleView.setTextAppearance(mTitleStyleRes);
}
if (mSubtitleStyleRes != 0) {
- mSubtitleView.setTextAppearance(mContext, mSubtitleStyleRes);
+ mSubtitleView.setTextAppearance(mSubtitleStyleRes);
}
}
diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java
index 6b781c3..825e336 100644
--- a/core/java/com/android/internal/widget/ActionBarView.java
+++ b/core/java/com/android/internal/widget/ActionBarView.java
@@ -813,14 +813,14 @@ public class ActionBarView extends AbsActionBarView implements DecorToolbar {
mSubtitleView = (TextView) mTitleLayout.findViewById(R.id.action_bar_subtitle);
if (mTitleStyleRes != 0) {
- mTitleView.setTextAppearance(mContext, mTitleStyleRes);
+ mTitleView.setTextAppearance(mTitleStyleRes);
}
if (mTitle != null) {
mTitleView.setText(mTitle);
}
if (mSubtitleStyleRes != 0) {
- mSubtitleView.setTextAppearance(mContext, mSubtitleStyleRes);
+ mSubtitleView.setTextAppearance(mSubtitleStyleRes);
}
if (mSubtitle != null) {
mSubtitleView.setText(mSubtitle);
diff --git a/core/java/com/android/internal/widget/FloatingToolbar.java b/core/java/com/android/internal/widget/FloatingToolbar.java
index 3f7696f..f98fbfc 100644
--- a/core/java/com/android/internal/widget/FloatingToolbar.java
+++ b/core/java/com/android/internal/widget/FloatingToolbar.java
@@ -1247,9 +1247,13 @@ public final class FloatingToolbar {
}
private static int getAdjustedToolbarWidth(Context context, int width) {
- if (width <= 0 || width > getScreenWidth(context)) {
- width = context.getResources()
- .getDimensionPixelSize(R.dimen.floating_toolbar_default_width);
+ int maximumWidth = getScreenWidth(context) - 2 * context.getResources()
+ .getDimensionPixelSize(R.dimen.floating_toolbar_horizontal_margin);
+
+ if (width <= 0 || width > maximumWidth) {
+ int defaultWidth = context.getResources()
+ .getDimensionPixelSize(R.dimen.floating_toolbar_preferred_width);
+ width = Math.min(defaultWidth, maximumWidth);
}
return width;
}