diff options
42 files changed, 796 insertions, 107 deletions
diff --git a/cmds/svc/src/com/android/commands/svc/NfcCommand.java b/cmds/svc/src/com/android/commands/svc/NfcCommand.java new file mode 100644 index 0000000..e0f09ee --- /dev/null +++ b/cmds/svc/src/com/android/commands/svc/NfcCommand.java @@ -0,0 +1,85 @@ +/* + * 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 com.android.commands.svc; + +import android.content.Context; +import android.content.pm.IPackageManager; +import android.content.pm.PackageManager; +import android.nfc.INfcAdapter; +import android.os.RemoteException; +import android.os.ServiceManager; + +public class NfcCommand extends Svc.Command { + + public NfcCommand() { + super("nfc"); + } + + @Override + public String shortHelp() { + return "Control NFC functions"; + } + + @Override + public String longHelp() { + return shortHelp() + "\n" + + "\n" + + "usage: svc nfc [enable|disable]\n" + + " Turn NFC on or off.\n\n"; + } + + @Override + public void run(String[] args) { + boolean validCommand = false; + if (args.length >= 2) { + boolean flag = false; + if ("enable".equals(args[1])) { + flag = true; + validCommand = true; + } else if ("disable".equals(args[1])) { + flag = false; + validCommand = true; + } + if (validCommand) { + IPackageManager pm = IPackageManager.Stub.asInterface( + ServiceManager.getService("package")); + try { + if (pm.hasSystemFeature(PackageManager.FEATURE_NFC)) { + INfcAdapter nfc = INfcAdapter.Stub + .asInterface(ServiceManager.getService(Context.NFC_SERVICE)); + try { + if (flag) { + nfc.enable(); + } else + nfc.disable(true); + } catch (RemoteException e) { + System.err.println("NFC operation failed: " + e); + } + } else { + System.err.println("NFC feature not supported."); + } + } catch (RemoteException e) { + System.err.println("RemoteException while calling PackageManager, is the " + + "system running?"); + } + return; + } + } + System.err.println(longHelp()); + } + +} diff --git a/cmds/svc/src/com/android/commands/svc/Svc.java b/cmds/svc/src/com/android/commands/svc/Svc.java index 0fbba11..2cccd1a 100644 --- a/cmds/svc/src/com/android/commands/svc/Svc.java +++ b/cmds/svc/src/com/android/commands/svc/Svc.java @@ -95,6 +95,7 @@ public class Svc { new PowerCommand(), new DataCommand(), new WifiCommand(), - new UsbCommand() + new UsbCommand(), + new NfcCommand(), }; } diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index ed7a2a3..7032c9a 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -4520,6 +4520,17 @@ public class PackageParser { return applicationInfo.isUpdatedSystemApp(); } + /** + * @hide + */ + public boolean canHaveOatDir() { + // The following app types CANNOT have oat directory + // - non-updated system apps + // - forward-locked apps or apps installed in ASEC containers + return (!isSystemApp() || isUpdatedSystemApp()) + && !isForwardLocked() && !applicationInfo.isExternalAsec(); + } + public String toString() { return "Package{" + Integer.toHexString(System.identityHashCode(this)) diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java index 7fef5e1..122df23 100644 --- a/core/java/android/hardware/fingerprint/FingerprintManager.java +++ b/core/java/android/hardware/fingerprint/FingerprintManager.java @@ -775,7 +775,7 @@ public class FingerprintManager { if (fingerId != reqFingerId) { Log.w(TAG, "Finger id didn't match: " + fingerId + " != " + reqFingerId); } - if (fingerId != reqFingerId) { + if (groupId != reqGroupId) { Log.w(TAG, "Group id didn't match: " + groupId + " != " + reqGroupId); } mRemovalCallback.onRemovalSucceeded(mRemovalFingerprint); diff --git a/core/java/android/nfc/cardemulation/AidGroup.java b/core/java/android/nfc/cardemulation/AidGroup.java index 4407c9d..78a9401 100644 --- a/core/java/android/nfc/cardemulation/AidGroup.java +++ b/core/java/android/nfc/cardemulation/AidGroup.java @@ -1,3 +1,19 @@ +/* + * 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.nfc.cardemulation; import java.io.IOException; diff --git a/core/java/android/nfc/cardemulation/HostApduService.java b/core/java/android/nfc/cardemulation/HostApduService.java index ad34e61..a299479 100644 --- a/core/java/android/nfc/cardemulation/HostApduService.java +++ b/core/java/android/nfc/cardemulation/HostApduService.java @@ -1,3 +1,19 @@ +/* + * 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.nfc.cardemulation; import android.annotation.SdkConstant; diff --git a/core/java/android/nfc/cardemulation/OffHostApduService.java b/core/java/android/nfc/cardemulation/OffHostApduService.java index 0d01762..6a8aeee 100644 --- a/core/java/android/nfc/cardemulation/OffHostApduService.java +++ b/core/java/android/nfc/cardemulation/OffHostApduService.java @@ -1,3 +1,19 @@ +/* + * 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.nfc.cardemulation; import android.annotation.SdkConstant; diff --git a/core/java/android/os/PowerManagerInternal.java b/core/java/android/os/PowerManagerInternal.java index e742f98..17bce30 100644 --- a/core/java/android/os/PowerManagerInternal.java +++ b/core/java/android/os/PowerManagerInternal.java @@ -53,6 +53,15 @@ public abstract class PowerManagerInternal { */ public static final int WAKEFULNESS_DOZING = 3; + + /** + * Power hint: The user is interacting with the device. The corresponding data field must be + * the expected duration of the fling, or 0 if unknown. + * + * This must be kept in sync with the values in hardware/libhardware/include/hardware/power.h + */ + public static final int POWER_HINT_INTERACTION = 2; + public static String wakefulnessToString(int wakefulness) { switch (wakefulness) { case WAKEFULNESS_ASLEEP: @@ -142,4 +151,6 @@ public abstract class PowerManagerInternal { public abstract void updateUidProcState(int uid, int procState); public abstract void uidGone(int uid); + + public abstract void powerHint(int hintId, int data); } diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 2053dbe..1822067 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -3283,7 +3283,6 @@ public final class Settings { DOCK_SOUNDS_ENABLED, // moved to global LOCKSCREEN_SOUNDS_ENABLED, SHOW_WEB_SUGGESTIONS, - NOTIFICATION_LIGHT_PULSE, SIP_CALL_OPTIONS, SIP_RECEIVE_CALLS, POINTER_SPEED, diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index ed858e7..6e9a418 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -2395,6 +2395,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te lp.itemId = mAdapter.getItemId(position); } lp.viewType = mAdapter.getItemViewType(position); + lp.isEnabled = mAdapter.isEnabled(position); if (lp != vlp) { child.setLayoutParams(lp); } @@ -2416,19 +2417,33 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } final int position = getPositionForView(host); - final ListAdapter adapter = getAdapter(); - - if ((position == INVALID_POSITION) || (adapter == null)) { + if (position == INVALID_POSITION || mAdapter == null) { // Cannot perform actions on invalid items. return false; } - if (!isEnabled() || !adapter.isEnabled(position)) { - // Cannot perform actions on disabled items. + if (position >= mAdapter.getCount()) { + // The position is no longer valid, likely due to a data set + // change. We could fail here for all data set changes, since + // there is a chance that the data bound to the view may no + // longer exist at the same position within the adapter, but + // it's more consistent with the standard touch interaction to + // click at whatever may have moved into that position. return false; } - final long id = getItemIdAtPosition(position); + final boolean isItemEnabled; + final ViewGroup.LayoutParams lp = host.getLayoutParams(); + if (lp instanceof AbsListView.LayoutParams) { + isItemEnabled = ((AbsListView.LayoutParams) lp).isEnabled; + } else { + isItemEnabled = false; + } + + if (!isEnabled() || !isItemEnabled) { + // Cannot perform actions on disabled items. + return false; + } switch (action) { case AccessibilityNodeInfo.ACTION_CLEAR_SELECTION: { @@ -2445,11 +2460,13 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } return false; case AccessibilityNodeInfo.ACTION_CLICK: { if (isClickable()) { + final long id = getItemIdAtPosition(position); return performItemClick(host, position, id); } } return false; case AccessibilityNodeInfo.ACTION_LONG_CLICK: { if (isLongClickable()) { + final long id = getItemIdAtPosition(position); return performLongPress(host, position, id); } } return false; @@ -2469,13 +2486,20 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te */ public void onInitializeAccessibilityNodeInfoForItem( View view, int position, AccessibilityNodeInfo info) { - final ListAdapter adapter = getAdapter(); - if (position == INVALID_POSITION || adapter == null) { + if (position == INVALID_POSITION) { // The item doesn't exist, so there's not much we can do here. return; } - if (!isEnabled() || !adapter.isEnabled(position)) { + final boolean isItemEnabled; + final ViewGroup.LayoutParams lp = view.getLayoutParams(); + if (lp instanceof AbsListView.LayoutParams) { + isItemEnabled = ((AbsListView.LayoutParams) lp).isEnabled; + } else { + isItemEnabled = false; + } + + if (!isEnabled() || !isItemEnabled) { info.setEnabled(false); return; } @@ -6315,6 +6339,9 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te */ long itemId = -1; + /** Whether the adapter considers the item enabled. */ + boolean isEnabled; + public LayoutParams(Context c, AttributeSet attrs) { super(c, attrs); } @@ -6340,6 +6367,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te encoder.addProperty("list:viewType", viewType); encoder.addProperty("list:recycledHeaderFooter", recycledHeaderFooter); encoder.addProperty("list:forceAdd", forceAdd); + encoder.addProperty("list:isEnabled", isEnabled); } } diff --git a/core/java/android/widget/AdapterView.java b/core/java/android/widget/AdapterView.java index 0cc1b25..2cfefba 100644 --- a/core/java/android/widget/AdapterView.java +++ b/core/java/android/widget/AdapterView.java @@ -600,13 +600,20 @@ public abstract class AdapterView<T extends Adapter> extends ViewGroup { } /** - * Get the position within the adapter's data set for the view, where view is a an adapter item - * or a descendant of an adapter item. + * Returns the position within the adapter's data set for the view, where + * view is a an adapter item or a descendant of an adapter item. + * <p> + * <strong>Note:</strong> The result of this method only reflects the + * position of the data bound to <var>view</var> during the most recent + * layout pass. If the adapter's data set has changed without a subsequent + * layout pass, the position returned by this method may not match the + * current position of the data within the adapter. * - * @param view an adapter item, or a descendant of an adapter item. This must be visible in this - * AdapterView at the time of the call. - * @return the position within the adapter's data set of the view, or {@link #INVALID_POSITION} - * if the view does not correspond to a list item (or it is not currently visible). + * @param view an adapter item, or a descendant of an adapter item. This + * must be visible in this AdapterView at the time of the call. + * @return the position within the adapter's data set of the view, or + * {@link #INVALID_POSITION} if the view does not correspond to a + * list item (or it is not currently visible) */ public int getPositionForView(View view) { View listItem = view; diff --git a/core/java/android/widget/GridView.java b/core/java/android/widget/GridView.java index f994d4a..607e955 100644 --- a/core/java/android/widget/GridView.java +++ b/core/java/android/widget/GridView.java @@ -1070,6 +1070,7 @@ public class GridView extends AbsListView { child.setLayoutParams(p); } p.viewType = mAdapter.getItemViewType(0); + p.isEnabled = mAdapter.isEnabled(0); p.forceAdd = true; int childHeightSpec = getChildMeasureSpec( @@ -1480,6 +1481,7 @@ public class GridView extends AbsListView { p = (AbsListView.LayoutParams) generateDefaultLayoutParams(); } p.viewType = mAdapter.getItemViewType(position); + p.isEnabled = mAdapter.isEnabled(position); if (recycled && !p.forceAdd) { attachViewToParent(child, where, p); diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java index c5632ec..00d017f 100644 --- a/core/java/android/widget/ListView.java +++ b/core/java/android/widget/ListView.java @@ -1200,6 +1200,7 @@ public class ListView extends AbsListView { child.setLayoutParams(p); } p.viewType = mAdapter.getItemViewType(position); + p.isEnabled = mAdapter.isEnabled(position); p.forceAdd = true; final int childWidthSpec = ViewGroup.getChildMeasureSpec(widthMeasureSpec, @@ -1913,6 +1914,7 @@ public class ListView extends AbsListView { p = (AbsListView.LayoutParams) generateDefaultLayoutParams(); } p.viewType = mAdapter.getItemViewType(position); + p.isEnabled = mAdapter.isEnabled(position); if ((recycled && !p.forceAdd) || (p.recycledHeaderFooter && p.viewType == AdapterView.ITEM_VIEW_TYPE_HEADER_OR_FOOTER)) { diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java index d9faece..80f9b0f 100644 --- a/core/java/com/android/internal/app/ChooserActivity.java +++ b/core/java/com/android/internal/app/ChooserActivity.java @@ -104,6 +104,7 @@ public class ChooserActivity extends ResolverActivity { sri.resultTargets); } unbindService(sri.connection); + sri.connection.destroy(); mServiceConnections.remove(sri.connection); if (mServiceConnections.isEmpty()) { mChooserHandler.removeMessages(CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT); @@ -208,6 +209,8 @@ public class ChooserActivity extends ResolverActivity { mRefinementResultReceiver.destroy(); mRefinementResultReceiver = null; } + unbindRemainingServices(); + mChooserHandler.removeMessages(CHOOSER_TARGET_SERVICE_RESULT); } @Override @@ -265,6 +268,11 @@ public class ChooserActivity extends ResolverActivity { return true; } + @Override + boolean shouldAutoLaunchSingleChoice() { + return false; + } + private void modifyTargetIntent(Intent in) { final String action = in.getAction(); if (Intent.ACTION_SEND.equals(action) || @@ -371,7 +379,8 @@ public class ChooserActivity extends ResolverActivity { continue; } - final ChooserTargetServiceConnection conn = new ChooserTargetServiceConnection(dri); + final ChooserTargetServiceConnection conn = + new ChooserTargetServiceConnection(this, dri); if (bindServiceAsUser(serviceIntent, conn, BIND_AUTO_CREATE | BIND_NOT_FOREGROUND, UserHandle.CURRENT)) { if (DEBUG) { @@ -425,6 +434,7 @@ public class ChooserActivity extends ResolverActivity { final ChooserTargetServiceConnection conn = mServiceConnections.get(i); if (DEBUG) Log.d(TAG, "unbinding " + conn); unbindService(conn); + conn.destroy(); } mServiceConnections.clear(); mChooserHandler.removeMessages(CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT); @@ -1024,54 +1034,93 @@ public class ChooserActivity extends ResolverActivity { } } - class ChooserTargetServiceConnection implements ServiceConnection { + static class ChooserTargetServiceConnection implements ServiceConnection { private final DisplayResolveInfo mOriginalTarget; + private ComponentName mConnectedComponent; + private ChooserActivity mChooserActivity; + private final Object mLock = new Object(); private final IChooserTargetResult mChooserTargetResult = new IChooserTargetResult.Stub() { @Override public void sendResult(List<ChooserTarget> targets) throws RemoteException { - filterServiceTargets(mOriginalTarget.getResolveInfo().activityInfo.packageName, - targets); - final Message msg = Message.obtain(); - msg.what = CHOOSER_TARGET_SERVICE_RESULT; - msg.obj = new ServiceResultInfo(mOriginalTarget, targets, - ChooserTargetServiceConnection.this); - mChooserHandler.sendMessage(msg); + synchronized (mLock) { + if (mChooserActivity == null) { + Log.e(TAG, "destroyed ChooserTargetServiceConnection received result from " + + mConnectedComponent + "; ignoring..."); + return; + } + mChooserActivity.filterServiceTargets( + mOriginalTarget.getResolveInfo().activityInfo.packageName, targets); + final Message msg = Message.obtain(); + msg.what = CHOOSER_TARGET_SERVICE_RESULT; + msg.obj = new ServiceResultInfo(mOriginalTarget, targets, + ChooserTargetServiceConnection.this); + mChooserActivity.mChooserHandler.sendMessage(msg); + } } }; - public ChooserTargetServiceConnection(DisplayResolveInfo dri) { + public ChooserTargetServiceConnection(ChooserActivity chooserActivity, + DisplayResolveInfo dri) { + mChooserActivity = chooserActivity; mOriginalTarget = dri; } @Override public void onServiceConnected(ComponentName name, IBinder service) { if (DEBUG) Log.d(TAG, "onServiceConnected: " + name); - final IChooserTargetService icts = IChooserTargetService.Stub.asInterface(service); - try { - icts.getChooserTargets(mOriginalTarget.getResolvedComponentName(), - mOriginalTarget.getResolveInfo().filter, mChooserTargetResult); - } catch (RemoteException e) { - Log.e(TAG, "Querying ChooserTargetService " + name + " failed.", e); - unbindService(this); - mServiceConnections.remove(this); + synchronized (mLock) { + if (mChooserActivity == null) { + Log.e(TAG, "destroyed ChooserTargetServiceConnection got onServiceConnected"); + return; + } + + final IChooserTargetService icts = IChooserTargetService.Stub.asInterface(service); + try { + icts.getChooserTargets(mOriginalTarget.getResolvedComponentName(), + mOriginalTarget.getResolveInfo().filter, mChooserTargetResult); + } catch (RemoteException e) { + Log.e(TAG, "Querying ChooserTargetService " + name + " failed.", e); + mChooserActivity.unbindService(this); + destroy(); + mChooserActivity.mServiceConnections.remove(this); + } } } @Override public void onServiceDisconnected(ComponentName name) { if (DEBUG) Log.d(TAG, "onServiceDisconnected: " + name); - unbindService(this); - mServiceConnections.remove(this); - if (mServiceConnections.isEmpty()) { - mChooserHandler.removeMessages(CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT); - sendVoiceChoicesIfNeeded(); + synchronized (mLock) { + if (mChooserActivity == null) { + Log.e(TAG, + "destroyed ChooserTargetServiceConnection got onServiceDisconnected"); + return; + } + + mChooserActivity.unbindService(this); + destroy(); + mChooserActivity.mServiceConnections.remove(this); + if (mChooserActivity.mServiceConnections.isEmpty()) { + mChooserActivity.mChooserHandler.removeMessages( + CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT); + mChooserActivity.sendVoiceChoicesIfNeeded(); + } + mConnectedComponent = null; + } + } + + public void destroy() { + synchronized (mLock) { + mChooserActivity = null; } } @Override public String toString() { - return mOriginalTarget.getResolveInfo().activityInfo.toString(); + return "ChooserTargetServiceConnection{service=" + + mConnectedComponent + ", activity=" + + mOriginalTarget.getResolveInfo().activityInfo.toString() + "}"; } } diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java index 7dd3bed..9272193 100644 --- a/core/java/com/android/internal/app/ResolverActivity.java +++ b/core/java/com/android/internal/app/ResolverActivity.java @@ -234,7 +234,9 @@ public class ResolverActivity extends Activity { mResolverComparator = new ResolverComparator(this, getTargetIntent(), referrerPackage); - configureContentView(mIntents, initialIntents, rList, alwaysUseOption); + if (configureContentView(mIntents, initialIntents, rList, alwaysUseOption)) { + return; + } // Prevent the Resolver window from becoming the top fullscreen window and thus from taking // control of the system bars. @@ -794,6 +796,10 @@ public class ResolverActivity extends Activity { return false; } + boolean shouldAutoLaunchSingleChoice() { + return true; + } + void showAppDetails(ResolveInfo ri) { Intent in = new Intent().setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS) .setData(Uri.fromParts("package", ri.activityInfo.packageName, null)) @@ -808,7 +814,10 @@ public class ResolverActivity extends Activity { launchedFromUid, filterLastUsed); } - void configureContentView(List<Intent> payloadIntents, Intent[] initialIntents, + /** + * Returns true if the activity is finishing and creation should halt + */ + boolean configureContentView(List<Intent> payloadIntents, Intent[] initialIntents, List<ResolveInfo> rList, boolean alwaysUseOption) { // The last argument of createAdapter is whether to do special handling // of the last used choice to highlight it in the list. We need to always @@ -828,7 +837,9 @@ public class ResolverActivity extends Activity { mAlwaysUseOption = alwaysUseOption; int count = mAdapter.getUnfilteredCount(); - if (count > 1 || (count == 1 && mAdapter.getOtherProfile() != null)) { + if ((!shouldAutoLaunchSingleChoice() && count > 0) + || count > 1 + || (count == 1 && mAdapter.getOtherProfile() != null)) { setContentView(layoutId); mAdapterView = (AbsListView) findViewById(R.id.resolver_list); onPrepareAdapterView(mAdapterView, mAdapter, alwaysUseOption); @@ -837,7 +848,7 @@ public class ResolverActivity extends Activity { mPackageMonitor.unregister(); mRegistered = false; finish(); - return; + return true; } else { setContentView(R.layout.resolver_list); @@ -847,6 +858,7 @@ public class ResolverActivity extends Activity { mAdapterView = (AbsListView) findViewById(R.id.resolver_list); mAdapterView.setVisibility(View.GONE); } + return false; } void onPrepareAdapterView(AbsListView adapterView, ResolveListAdapter adapter, diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java index a873ef8..82ae2f3 100644 --- a/core/java/com/android/internal/widget/LockPatternUtils.java +++ b/core/java/com/android/internal/widget/LockPatternUtils.java @@ -1071,12 +1071,22 @@ public class LockPatternUtils { * enter a pattern. */ public long getLockoutAttemptDeadline(int userId) { - final long deadline = getLong(LOCKOUT_ATTEMPT_DEADLINE, 0L, userId); + long deadline = getLong(LOCKOUT_ATTEMPT_DEADLINE, 0L, userId); final long timeoutMs = getLong(LOCKOUT_ATTEMPT_TIMEOUT_MS, 0L, userId); final long now = SystemClock.elapsedRealtime(); - if (deadline < now || deadline > (now + timeoutMs)) { + if (deadline < now) { + // timeout expired + setLong(LOCKOUT_ATTEMPT_DEADLINE, 0, userId); + setLong(LOCKOUT_ATTEMPT_TIMEOUT_MS, 0, userId); return 0L; } + + if (deadline > (now + timeoutMs)) { + // device was rebooted, set new deadline + deadline = now + timeoutMs; + setLong(LOCKOUT_ATTEMPT_DEADLINE, deadline, userId); + } + return deadline; } diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index f711c80..fd600e3 100755..100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -2285,6 +2285,9 @@ <string-array name="config_cell_retries_per_error_code"> </string-array> + <!-- Set initial MaxRetry value for operators --> + <integer name="config_mdc_initial_max_retry">1</integer> + <!-- The OEM specified sensor type for the gesture to launch the camear app. --> <integer name="config_cameraLaunchGestureSensorType">-1</integer> <!-- The OEM specified sensor string type for the gesture to launch camera app, this value diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 0e85f43..357d4c3 100755..100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -404,6 +404,7 @@ <java-symbol type="integer" name="config_volte_replacement_rat"/> <java-symbol type="integer" name="config_valid_wappush_index" /> <java-symbol type="integer" name="config_overrideHasPermanentMenuKey" /> + <java-symbol type="integer" name="config_mdc_initial_max_retry" /> <java-symbol type="bool" name="config_hasPermanentDpad" /> <java-symbol type="color" name="tab_indicator_text_v4" /> diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java index b752c9b..e342865 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -129,6 +129,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { private static final int MSG_REPORT_EMERGENCY_CALL_ACTION = 318; private static final int MSG_STARTED_WAKING_UP = 319; private static final int MSG_FINISHED_GOING_TO_SLEEP = 320; + private static final int MSG_STARTED_GOING_TO_SLEEP = 321; private static final int MSG_KEYGUARD_BOUNCER_CHANGED = 322; private static final int MSG_FACE_UNLOCK_STATE_CHANGED = 327; private static final int MSG_SIM_SUBSCRIPTION_INFO_CHANGED = 328; @@ -170,6 +171,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { * until the Keyguard has been dismissed. */ private boolean mFingerprintAlreadyAuthenticated; + private boolean mGoingToSleep; private boolean mBouncer; private boolean mBootCompleted; @@ -249,6 +251,9 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { case MSG_REPORT_EMERGENCY_CALL_ACTION: handleReportEmergencyCallAction(); break; + case MSG_STARTED_GOING_TO_SLEEP: + handleStartedGoingToSleep(msg.arg1); + break; case MSG_FINISHED_GOING_TO_SLEEP: handleFinishedGoingToSleep(msg.arg1); break; @@ -884,19 +889,32 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { } } - protected void handleFinishedGoingToSleep(int arg1) { + protected void handleStartedGoingToSleep(int arg1) { clearFingerprintRecognized(); final int count = mCallbacks.size(); for (int i = 0; i < count; i++) { KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); if (cb != null) { - cb.onFinishedGoingToSleep(arg1); + cb.onStartedGoingToSleep(arg1); } } + mGoingToSleep = true; mFingerprintAlreadyAuthenticated = false; updateFingerprintListeningState(); } + protected void handleFinishedGoingToSleep(int arg1) { + mGoingToSleep = false; + final int count = mCallbacks.size(); + for (int i = 0; i < count; i++) { + KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); + if (cb != null) { + cb.onFinishedGoingToSleep(arg1); + } + } + updateFingerprintListeningState(); + } + private void handleScreenTurnedOn() { final int count = mCallbacks.size(); for (int i = 0; i < count; i++) { @@ -1032,8 +1050,9 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { } private boolean shouldListenForFingerprint() { - return (mKeyguardIsVisible || !mDeviceInteractive) && !mSwitchingUser - && !mFingerprintAlreadyAuthenticated && !isFingerprintDisabled(getCurrentUser()); + return (mKeyguardIsVisible || !mDeviceInteractive || mBouncer || mGoingToSleep) + && !mSwitchingUser && !mFingerprintAlreadyAuthenticated + && !isFingerprintDisabled(getCurrentUser()); } private void startListeningForFingerprint() { @@ -1365,6 +1384,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { cb.onKeyguardBouncerChanged(isBouncer); } } + updateFingerprintListeningState(); } /** @@ -1604,6 +1624,10 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { mHandler.sendEmptyMessage(MSG_STARTED_WAKING_UP); } + public void dispatchStartedGoingToSleep(int why) { + mHandler.sendMessage(mHandler.obtainMessage(MSG_STARTED_GOING_TO_SLEEP, why, 0)); + } + public void dispatchFinishedGoingToSleep(int why) { synchronized(this) { mDeviceInteractive = false; @@ -1629,6 +1653,10 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { return mDeviceInteractive; } + public boolean isGoingToSleep() { + return mGoingToSleep; + } + /** * Find the next SubscriptionId for a SIM in the given state, favoring lower slot numbers first. * @param state diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java index 15ffe9f..bd6c51c 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java @@ -153,6 +153,12 @@ public class KeyguardUpdateMonitorCallback { public void onStartedWakingUp() { } /** + * Called when the device has started going to sleep. + * @param why see {@link #onFinishedGoingToSleep(int)} + */ + public void onStartedGoingToSleep(int why) { } + + /** * Called when the device has finished going to sleep. * @param why either {@link WindowManagerPolicy#OFF_BECAUSE_OF_ADMIN}, * {@link WindowManagerPolicy#OFF_BECAUSE_OF_USER}, or diff --git a/packages/SettingsLib/src/com/android/settingslib/TetherUtil.java b/packages/SettingsLib/src/com/android/settingslib/TetherUtil.java index 5062423..5294199 100644 --- a/packages/SettingsLib/src/com/android/settingslib/TetherUtil.java +++ b/packages/SettingsLib/src/com/android/settingslib/TetherUtil.java @@ -25,6 +25,7 @@ import android.net.wifi.WifiManager; import android.os.SystemProperties; import android.os.UserHandle; import android.provider.Settings; +import android.telephony.CarrierConfigManager; public class TetherUtil { @@ -62,6 +63,13 @@ public class TetherUtil { return wifiManager.getWifiApState() == WifiManager.WIFI_AP_STATE_ENABLED; } + private static boolean isEntitlementCheckRequired(Context context) { + final CarrierConfigManager configManager = (CarrierConfigManager) context + .getSystemService(Context.CARRIER_CONFIG_SERVICE); + return configManager.getConfig().getBoolean(CarrierConfigManager + .KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL); + } + public static boolean isProvisioningNeeded(Context context) { // Keep in sync with other usage of config_mobile_hotspot_provision_app. // ConnectivityManager#enforceTetherChangePermission @@ -71,6 +79,10 @@ public class TetherUtil { || provisionApp == null) { return false; } + // Check carrier config for entitlement checks + if (isEntitlementCheckRequired(context) == false) { + return false; + } return (provisionApp.length == 2); } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index da4ffa4..8a09b7c 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -74,6 +74,8 @@ import com.android.systemui.statusbar.phone.ScrimController; import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; import com.android.systemui.statusbar.phone.StatusBarWindowManager; +import java.io.FileDescriptor; +import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; @@ -152,6 +154,7 @@ public class KeyguardViewMediator extends SystemUI { private static final int NOTIFY_STARTED_WAKING_UP = 21; private static final int NOTIFY_SCREEN_TURNED_ON = 22; private static final int NOTIFY_SCREEN_TURNED_OFF = 23; + private static final int NOTIFY_STARTED_GOING_TO_SLEEP = 24; /** * The default amount of time we stay awake (used for all key input) @@ -649,6 +652,7 @@ public class KeyguardViewMediator extends SystemUI { final boolean lockImmediately = mLockPatternUtils.getPowerButtonInstantlyLocks(currentUser) || !mLockPatternUtils.isSecure(currentUser); + long timeout = getLockTimeout(); if (mExitSecureCallback != null) { if (DEBUG) Log.d(TAG, "pending exit secure callback cancelled"); @@ -663,9 +667,9 @@ public class KeyguardViewMediator extends SystemUI { } } else if (mShowing) { mPendingReset = true; - } else if (why == WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT + } else if ((why == WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT && timeout > 0) || (why == WindowManagerPolicy.OFF_BECAUSE_OF_USER && !lockImmediately)) { - doKeyguardLaterLocked(); + doKeyguardLaterLocked(timeout); } else if (!mLockPatternUtils.isLockScreenDisabled(currentUser)) { mPendingLock = true; } @@ -674,6 +678,8 @@ public class KeyguardViewMediator extends SystemUI { playSounds(true); } } + KeyguardUpdateMonitor.getInstance(mContext).dispatchStartedGoingToSleep(why); + notifyStartedGoingToSleep(); } public void onFinishedGoingToSleep(int why) { @@ -699,7 +705,7 @@ public class KeyguardViewMediator extends SystemUI { KeyguardUpdateMonitor.getInstance(mContext).dispatchFinishedGoingToSleep(why); } - private void doKeyguardLaterLocked() { + private long getLockTimeout() { // if the screen turned off because of timeout or the user hit the power button // and we don't need to lock immediately, set an alarm // to enable it a little bit later (i.e, give the user a chance @@ -728,23 +734,30 @@ public class KeyguardViewMediator extends SystemUI { } else { timeout = lockAfterTimeout; } + return timeout; + } - if (timeout <= 0) { - // Lock now + private void doKeyguardLaterLocked() { + long timeout = getLockTimeout(); + if (timeout == 0) { doKeyguardLocked(null); } else { - // Lock in the future - long when = SystemClock.elapsedRealtime() + timeout; - Intent intent = new Intent(DELAYED_KEYGUARD_ACTION); - intent.putExtra("seq", mDelayedShowingSequence); - PendingIntent sender = PendingIntent.getBroadcast(mContext, - 0, intent, PendingIntent.FLAG_CANCEL_CURRENT); - mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, when, sender); - if (DEBUG) Log.d(TAG, "setting alarm to turn off keyguard, seq = " - + mDelayedShowingSequence); + doKeyguardLaterLocked(timeout); } } + private void doKeyguardLaterLocked(long timeout) { + // Lock in the future + long when = SystemClock.elapsedRealtime() + timeout; + Intent intent = new Intent(DELAYED_KEYGUARD_ACTION); + intent.putExtra("seq", mDelayedShowingSequence); + PendingIntent sender = PendingIntent.getBroadcast(mContext, + 0, intent, PendingIntent.FLAG_CANCEL_CURRENT); + mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, when, sender); + if (DEBUG) Log.d(TAG, "setting alarm to turn off keyguard, seq = " + + mDelayedShowingSequence); + } + private void cancelDoKeyguardLaterLocked() { mDelayedShowingSequence++; } @@ -1090,6 +1103,11 @@ public class KeyguardViewMediator extends SystemUI { mHandler.sendEmptyMessage(VERIFY_UNLOCK); } + private void notifyStartedGoingToSleep() { + if (DEBUG) Log.d(TAG, "notifyStartedGoingToSleep"); + mHandler.sendEmptyMessage(NOTIFY_STARTED_GOING_TO_SLEEP); + } + private void notifyFinishedGoingToSleep() { if (DEBUG) Log.d(TAG, "notifyFinishedGoingToSleep"); mHandler.sendEmptyMessage(NOTIFY_FINISHED_GOING_TO_SLEEP); @@ -1201,6 +1219,9 @@ public class KeyguardViewMediator extends SystemUI { case VERIFY_UNLOCK: handleVerifyUnlock(); break; + case NOTIFY_STARTED_GOING_TO_SLEEP: + handleNotifyStartedGoingToSleep(); + break; case NOTIFY_FINISHED_GOING_TO_SLEEP: handleNotifyFinishedGoingToSleep(); break; @@ -1528,6 +1549,13 @@ public class KeyguardViewMediator extends SystemUI { } } + private void handleNotifyStartedGoingToSleep() { + synchronized (KeyguardViewMediator.this) { + if (DEBUG) Log.d(TAG, "handleNotifyStartedGoingToSleep"); + mStatusBarKeyguardViewManager.onStartedGoingToSleep(); + } + } + /** * Handle message sent by {@link #notifyFinishedGoingToSleep()} * @see #NOTIFY_FINISHED_GOING_TO_SLEEP @@ -1625,6 +1653,30 @@ public class KeyguardViewMediator extends SystemUI { return mViewMediatorCallback; } + @Override + public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { + pw.print(" mSystemReady: "); pw.println(mSystemReady); + pw.print(" mBootCompleted: "); pw.println(mBootCompleted); + pw.print(" mBootSendUserPresent: "); pw.println(mBootSendUserPresent); + pw.print(" mExternallyEnabled: "); pw.println(mExternallyEnabled); + pw.print(" mNeedToReshowWhenReenabled: "); pw.println(mNeedToReshowWhenReenabled); + pw.print(" mShowing: "); pw.println(mShowing); + pw.print(" mInputRestricted: "); pw.println(mInputRestricted); + pw.print(" mOccluded: "); pw.println(mOccluded); + pw.print(" mDelayedShowingSequence: "); pw.println(mDelayedShowingSequence); + pw.print(" mExitSecureCallback: "); pw.println(mExitSecureCallback); + pw.print(" mDeviceInteractive: "); pw.println(mDeviceInteractive); + pw.print(" mGoingToSleep: "); pw.println(mGoingToSleep); + pw.print(" mHiding: "); pw.println(mHiding); + pw.print(" mWaitingUntilKeyguardVisible: "); pw.println(mWaitingUntilKeyguardVisible); + pw.print(" mKeyguardDonePending: "); pw.println(mKeyguardDonePending); + pw.print(" mHideAnimationRun: "); pw.println(mHideAnimationRun); + pw.print(" mPendingReset: "); pw.println(mPendingReset); + pw.print(" mPendingLock: "); pw.println(mPendingLock); + pw.print(" mWakeAndUnlocking: "); pw.println(mWakeAndUnlocking); + pw.print(" mDrawnCallback: "); pw.println(mDrawnCallback); + } + private static class StartKeyguardExitAnimParams { long startTime; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java index 84082db..2912963 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java @@ -93,6 +93,8 @@ public class FingerprintUnlockController extends KeyguardUpdateMonitorCallback { private KeyguardViewMediator mKeyguardViewMediator; private ScrimController mScrimController; private PhoneStatusBar mPhoneStatusBar; + private boolean mGoingToSleep; + private int mPendingAuthenticatedUserId = -1; public FingerprintUnlockController(Context context, StatusBarWindowManager statusBarWindowManager, @@ -161,6 +163,10 @@ public class FingerprintUnlockController extends KeyguardUpdateMonitorCallback { @Override public void onFingerprintAuthenticated(int userId) { + if (mUpdateMonitor.isGoingToSleep()) { + mPendingAuthenticatedUserId = userId; + return; + } boolean wasDeviceInteractive = mUpdateMonitor.isDeviceInteractive(); mMode = calculateMode(); if (!wasDeviceInteractive) { @@ -205,6 +211,26 @@ public class FingerprintUnlockController extends KeyguardUpdateMonitorCallback { mPhoneStatusBar.notifyFpAuthModeChanged(); } + @Override + public void onStartedGoingToSleep(int why) { + mPendingAuthenticatedUserId = -1; + } + + @Override + public void onFinishedGoingToSleep(int why) { + if (mPendingAuthenticatedUserId != -1) { + + // Post this to make sure it's executed after the device is fully locked. + mHandler.post(new Runnable() { + @Override + public void run() { + onFingerprintAuthenticated(mPendingAuthenticatedUserId); + } + }); + } + mPendingAuthenticatedUserId = -1; + } + public int getMode() { return mMode; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index 548125d..2bedef7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -312,6 +312,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, boolean mLeaveOpenOnKeyguardHide; KeyguardIndicationController mKeyguardIndicationController; + // Keyguard is going away soon. + private boolean mKeyguardGoingAway; + // Keyguard is actually fading away now. private boolean mKeyguardFadingAway; private long mKeyguardFadingAwayDelay; private long mKeyguardFadingAwayDuration; @@ -485,12 +488,18 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, private boolean mLaunchTransitionFadingAway; private ExpandableNotificationRow mDraggedDownRow; private boolean mLaunchCameraOnScreenTurningOn; + private boolean mLaunchCameraOnFinishedGoingToSleep; private PowerManager.WakeLock mGestureWakeLock; private Vibrator mVibrator; // Fingerprint (as computed by getLoggingFingerprint() of the last logged state. private int mLastLoggedStateFingerprint; + /** + * If set, the device has started going to sleep but isn't fully non-interactive yet. + */ + protected boolean mStartedGoingToSleep; + private static final int VISIBLE_LOCATIONS = StackViewState.LOCATION_FIRST_CARD | StackViewState.LOCATION_MAIN_AREA; @@ -3558,6 +3567,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, // Treat Keyguard exit animation as an app transition to achieve nice transition for status // bar. + mKeyguardGoingAway = true; mIconController.appTransitionPending(); } @@ -3589,6 +3599,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, */ public void finishKeyguardFadingAway() { mKeyguardFadingAway = false; + mKeyguardGoingAway = false; } public void stopWaitingForKeyguardExit() { @@ -3903,15 +3914,32 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, disable(mDisabledUnmodified1, mDisabledUnmodified2, true /* animate */); } + public void onStartedGoingToSleep() { + mStartedGoingToSleep = true; + } + public void onFinishedGoingToSleep() { mNotificationPanel.onAffordanceLaunchEnded(); releaseGestureWakeLock(); mLaunchCameraOnScreenTurningOn = false; + mStartedGoingToSleep = false; mDeviceInteractive = false; mWakeUpComingFromTouch = false; mWakeUpTouchLocation = null; mStackScroller.setAnimationsEnabled(false); updateVisibleToUser(); + if (mLaunchCameraOnFinishedGoingToSleep) { + mLaunchCameraOnFinishedGoingToSleep = false; + + // This gets executed before we will show Keyguard, so post it in order that the state + // is correct. + mHandler.post(new Runnable() { + @Override + public void run() { + onCameraLaunchGestureDetected(); + } + }); + } } public void onStartedWakingUp() { @@ -3931,7 +3959,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } private void vibrateForCameraGesture() { - mVibrator.vibrate(750L); + // Make sure to pass -1 for repeat so VibratorService doesn't stop us when going to sleep. + mVibrator.vibrate(new long[] { 0, 750L }, -1 /* repeat */); } public void onScreenTurnedOn() { @@ -4079,9 +4108,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, public void appTransitionStarting(long startTime, long duration) { // Use own timings when Keyguard is going away, see keyguardGoingAway and - // setKeyguardFadingAway. When duration is 0, skip this one because no animation is really - // playing. - if (!mKeyguardFadingAway && duration > 0) { + // setKeyguardFadingAway. + if (!mKeyguardGoingAway) { mIconController.appTransitionStarting(startTime, duration); } if (mIconPolicy != null) { @@ -4091,6 +4119,10 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, @Override public void onCameraLaunchGestureDetected() { + if (mStartedGoingToSleep) { + mLaunchCameraOnFinishedGoingToSleep = true; + return; + } if (!mNotificationPanel.canCameraGestureBeLaunched( mStatusBarKeyguardViewManager.isShowing() && mExpandedVisible)) { return; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java index e26f423..394ff3f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java @@ -164,6 +164,10 @@ public class StatusBarKeyguardViewManager { } } + public void onStartedGoingToSleep() { + mPhoneStatusBar.onStartedGoingToSleep(); + } + public void onFinishedGoingToSleep() { mDeviceInteractive = false; mPhoneStatusBar.onFinishedGoingToSleep(); diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index d1e1683..6190a5a 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -2270,8 +2270,9 @@ public class ConnectivityService extends IConnectivityManager.Stub mNetworkRequestInfoLogs.log("REGISTER " + nri); if (!nri.isRequest) { for (NetworkAgentInfo network : mNetworkAgentInfos.values()) { - if (network.satisfiesImmutableCapabilitiesOf(nri.request)) { - updateSignalStrengthThresholds(network); + if (nri.request.networkCapabilities.hasSignalStrength() && + network.satisfiesImmutableCapabilitiesOf(nri.request)) { + updateSignalStrengthThresholds(network, "REGISTER", nri.request); } } } @@ -2388,8 +2389,9 @@ public class ConnectivityService extends IConnectivityManager.Stub // if this listen request applies and remove it. for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) { nai.networkRequests.remove(nri.request.requestId); - if (nai.satisfiesImmutableCapabilitiesOf(nri.request)) { - updateSignalStrengthThresholds(nai); + if (nri.request.networkCapabilities.hasSignalStrength() && + nai.satisfiesImmutableCapabilitiesOf(nri.request)) { + updateSignalStrengthThresholds(nai, "RELEASE", nri.request); } } } @@ -3639,9 +3641,24 @@ public class ConnectivityService extends IConnectivityManager.Stub return new ArrayList<Integer>(thresholds); } - private void updateSignalStrengthThresholds(NetworkAgentInfo nai) { + private void updateSignalStrengthThresholds( + NetworkAgentInfo nai, String reason, NetworkRequest request) { + ArrayList<Integer> thresholdsArray = getSignalStrengthThresholds(nai); Bundle thresholds = new Bundle(); - thresholds.putIntegerArrayList("thresholds", getSignalStrengthThresholds(nai)); + thresholds.putIntegerArrayList("thresholds", thresholdsArray); + + // TODO: Switch to VDBG. + if (DBG) { + String detail; + if (request != null && request.networkCapabilities.hasSignalStrength()) { + detail = reason + " " + request.networkCapabilities.getSignalStrength(); + } else { + detail = reason; + } + log(String.format("updateSignalStrengthThresholds: %s, sending %s to %s", + detail, Arrays.toString(thresholdsArray.toArray()), nai.name())); + } + nai.asyncChannel.sendMessage( android.net.NetworkAgent.CMD_SET_SIGNAL_STRENGTH_THRESHOLDS, 0, 0, thresholds); @@ -4624,7 +4641,7 @@ public class ConnectivityService extends IConnectivityManager.Stub // so we could decide to tear it down immediately afterwards. That's fine though - on // disconnection NetworkAgents should stop any signal strength monitoring they have been // doing. - updateSignalStrengthThresholds(networkAgent); + updateSignalStrengthThresholds(networkAgent, "CONNECT", null); // Consider network even though it is not yet validated. rematchNetworkAndRequests(networkAgent, ReapUnvalidatedNetworks.REAP); diff --git a/services/core/java/com/android/server/GestureLauncherService.java b/services/core/java/com/android/server/GestureLauncherService.java index 69f0cef..bd7d4b2 100644 --- a/services/core/java/com/android/server/GestureLauncherService.java +++ b/services/core/java/com/android/server/GestureLauncherService.java @@ -101,8 +101,8 @@ public class GestureLauncherService extends SystemService { * Whether camera double tap power button gesture is currently enabled; */ private boolean mCameraDoubleTapPowerEnabled; - private long mLastPowerDownWhileNonInteractive = 0; - + private long mLastPowerDownWhileNonInteractive; + private long mLastPowerDownWhileInteractive; public GestureLauncherService(Context context) { super(context); @@ -251,23 +251,30 @@ public class GestureLauncherService extends SystemService { public boolean interceptPowerKeyDown(KeyEvent event, boolean interactive) { boolean launched = false; + boolean intercept = false; synchronized (this) { if (!mCameraDoubleTapPowerEnabled) { mLastPowerDownWhileNonInteractive = 0; + mLastPowerDownWhileInteractive = 0; return false; } if (event.getEventTime() - mLastPowerDownWhileNonInteractive < CAMERA_POWER_DOUBLE_TAP_TIME_MS) { launched = true; + intercept = true; + } else if (event.getEventTime() - mLastPowerDownWhileInteractive + < CAMERA_POWER_DOUBLE_TAP_TIME_MS) { + launched = true; } mLastPowerDownWhileNonInteractive = interactive ? 0 : event.getEventTime(); + mLastPowerDownWhileInteractive = interactive ? event.getEventTime() : 0; } if (launched) { Slog.i(TAG, "Power button double tap gesture detected, launching camera."); launched = handleCameraLaunchGesture(false /* useWakelock */, MetricsLogger.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE); } - return launched; + return intercept && launched; } /** diff --git a/services/core/java/com/android/server/VibratorService.java b/services/core/java/com/android/server/VibratorService.java index 30f4dce..c228422 100644 --- a/services/core/java/com/android/server/VibratorService.java +++ b/services/core/java/com/android/server/VibratorService.java @@ -59,6 +59,7 @@ public class VibratorService extends IVibratorService.Stub implements InputManager.InputDeviceListener { private static final String TAG = "VibratorService"; private static final boolean DEBUG = false; + private static final String SYSTEM_UI_PACKAGE = "com.android.systemui"; private final LinkedList<Vibration> mVibrations; private final LinkedList<VibrationInfo> mPreviousVibrations; @@ -147,7 +148,8 @@ public class VibratorService extends IVibratorService.Stub } public boolean isSystemHapticFeedback() { - return (mUid == Process.SYSTEM_UID || mUid == 0) && mRepeat < 0; + return (mUid == Process.SYSTEM_UID || mUid == 0 || SYSTEM_UI_PACKAGE.equals(mOpPkg)) + && mRepeat < 0; } } diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java index d590d7a..d5e9a32 100644 --- a/services/core/java/com/android/server/accounts/AccountManagerService.java +++ b/services/core/java/com/android/server/accounts/AccountManagerService.java @@ -2607,6 +2607,7 @@ public class AccountManagerService // be passed in the original caller's uid here, which is what should be used for filtering. if (packageUid != -1 && UserHandle.isSameApp(callingUid, Process.myUid())) { callingUid = packageUid; + opPackageName = callingPackage; } List<String> visibleAccountTypes = getTypesVisibleToCaller(callingUid, userId, diff --git a/services/core/java/com/android/server/connectivity/NetworkDiagnostics.java b/services/core/java/com/android/server/connectivity/NetworkDiagnostics.java index aca6991..5fd39c0 100644 --- a/services/core/java/com/android/server/connectivity/NetworkDiagnostics.java +++ b/services/core/java/com/android/server/connectivity/NetworkDiagnostics.java @@ -18,6 +18,7 @@ package com.android.server.connectivity; import static android.system.OsConstants.*; +import android.net.LinkAddress; import android.net.LinkProperties; import android.net.Network; import android.net.NetworkUtils; @@ -27,6 +28,7 @@ import android.system.ErrnoException; import android.system.Os; import android.system.StructTimeval; import android.text.TextUtils; +import android.util.Pair; import com.android.internal.util.IndentingPrintWriter; @@ -149,6 +151,8 @@ public class NetworkDiagnostics { } private final Map<InetAddress, Measurement> mIcmpChecks = new HashMap<>(); + private final Map<Pair<InetAddress, InetAddress>, Measurement> mExplicitSourceIcmpChecks = + new HashMap<>(); private final Map<InetAddress, Measurement> mDnsUdpChecks = new HashMap<>(); private final String mDescription; @@ -178,7 +182,11 @@ public class NetworkDiagnostics { for (RouteInfo route : mLinkProperties.getRoutes()) { if (route.hasGateway()) { - prepareIcmpMeasurement(route.getGateway()); + InetAddress gateway = route.getGateway(); + prepareIcmpMeasurement(gateway); + if (route.isIPv6Default()) { + prepareExplicitSourceIcmpMeasurements(gateway); + } } } for (InetAddress nameserver : mLinkProperties.getDnsServers()) { @@ -213,6 +221,20 @@ public class NetworkDiagnostics { } } + private void prepareExplicitSourceIcmpMeasurements(InetAddress target) { + for (LinkAddress l : mLinkProperties.getLinkAddresses()) { + InetAddress source = l.getAddress(); + if (source instanceof Inet6Address && l.isGlobalPreferred()) { + Pair<InetAddress, InetAddress> srcTarget = new Pair<>(source, target); + if (!mExplicitSourceIcmpChecks.containsKey(srcTarget)) { + Measurement measurement = new Measurement(); + measurement.thread = new Thread(new IcmpCheck(source, target, measurement)); + mExplicitSourceIcmpChecks.put(srcTarget, measurement); + } + } + } + } + private void prepareDnsMeasurement(InetAddress target) { if (!mDnsUdpChecks.containsKey(target)) { Measurement measurement = new Measurement(); @@ -222,13 +244,16 @@ public class NetworkDiagnostics { } private int totalMeasurementCount() { - return mIcmpChecks.size() + mDnsUdpChecks.size(); + return mIcmpChecks.size() + mExplicitSourceIcmpChecks.size() + mDnsUdpChecks.size(); } private void startMeasurements() { for (Measurement measurement : mIcmpChecks.values()) { measurement.thread.start(); } + for (Measurement measurement : mExplicitSourceIcmpChecks.values()) { + measurement.thread.start(); + } for (Measurement measurement : mDnsUdpChecks.values()) { measurement.thread.start(); } @@ -261,6 +286,10 @@ public class NetworkDiagnostics { pw.println(entry.getValue().toString()); } } + for (Map.Entry<Pair<InetAddress, InetAddress>, Measurement> entry : + mExplicitSourceIcmpChecks.entrySet()) { + pw.println(entry.getValue().toString()); + } for (Map.Entry<InetAddress, Measurement> entry : mDnsUdpChecks.entrySet()) { if (entry.getKey() instanceof Inet4Address) { pw.println(entry.getValue().toString()); @@ -276,13 +305,15 @@ public class NetworkDiagnostics { private class SimpleSocketCheck implements Closeable { + protected final InetAddress mSource; // Usually null. protected final InetAddress mTarget; protected final int mAddressFamily; protected final Measurement mMeasurement; protected FileDescriptor mFileDescriptor; protected SocketAddress mSocketAddress; - protected SimpleSocketCheck(InetAddress target, Measurement measurement) { + protected SimpleSocketCheck( + InetAddress source, InetAddress target, Measurement measurement) { mMeasurement = measurement; if (target instanceof Inet6Address) { @@ -301,6 +332,14 @@ public class NetworkDiagnostics { mTarget = target; mAddressFamily = AF_INET; } + + // We don't need to check the scope ID here because we currently only do explicit-source + // measurements from global IPv6 addresses. + mSource = source; + } + + protected SimpleSocketCheck(InetAddress target, Measurement measurement) { + this(null, target, measurement); } protected void setupSocket( @@ -314,6 +353,9 @@ public class NetworkDiagnostics { SOL_SOCKET, SO_RCVTIMEO, StructTimeval.fromMillis(readTimeout)); // TODO: Use IP_RECVERR/IPV6_RECVERR, pending OsContants availability. mNetwork.bindSocket(mFileDescriptor); + if (mSource != null) { + Os.bind(mFileDescriptor, mSource, 0); + } Os.connect(mFileDescriptor, mTarget, dstPort); mSocketAddress = Os.getsockname(mFileDescriptor); } @@ -343,8 +385,8 @@ public class NetworkDiagnostics { private final int mProtocol; private final int mIcmpType; - public IcmpCheck(InetAddress target, Measurement measurement) { - super(target, measurement); + public IcmpCheck(InetAddress source, InetAddress target, Measurement measurement) { + super(source, target, measurement); if (mAddressFamily == AF_INET6) { mProtocol = IPPROTO_ICMPV6; @@ -359,6 +401,10 @@ public class NetworkDiagnostics { mMeasurement.description += " dst{" + mTarget.getHostAddress() + "}"; } + public IcmpCheck(InetAddress target, Measurement measurement) { + this(null, target, measurement); + } + @Override public void run() { // Check if this measurement has already failed during setup. diff --git a/services/core/java/com/android/server/display/DisplayPowerState.java b/services/core/java/com/android/server/display/DisplayPowerState.java index f53ccc9..2eabd32 100644 --- a/services/core/java/com/android/server/display/DisplayPowerState.java +++ b/services/core/java/com/android/server/display/DisplayPowerState.java @@ -341,7 +341,8 @@ final class DisplayPowerState { private int mPendingBacklight = INITIAL_BACKLIGHT; private int mActualState = INITIAL_SCREEN_STATE; private int mActualBacklight = INITIAL_BACKLIGHT; - private boolean mChangeInProgress; + private boolean mStateChangeInProgress; + private boolean mBacklightChangeInProgress; public PhotonicModulator() { super("PhotonicModulator"); @@ -349,7 +350,9 @@ final class DisplayPowerState { public boolean setState(int state, int backlight) { synchronized (mLock) { - if (state != mPendingState || backlight != mPendingBacklight) { + boolean stateChanged = state != mPendingState; + boolean backlightChanged = backlight != mPendingBacklight; + if (stateChanged || backlightChanged) { if (DEBUG) { Slog.d(TAG, "Requesting new screen state: state=" + Display.stateToString(state) + ", backlight=" + backlight); @@ -358,12 +361,15 @@ final class DisplayPowerState { mPendingState = state; mPendingBacklight = backlight; - if (!mChangeInProgress) { - mChangeInProgress = true; + boolean changeInProgress = mStateChangeInProgress || mBacklightChangeInProgress; + mStateChangeInProgress = stateChanged; + mBacklightChangeInProgress = backlightChanged; + + if (!changeInProgress) { mLock.notifyAll(); } } - return !mChangeInProgress; + return !mStateChangeInProgress; } } @@ -375,7 +381,8 @@ final class DisplayPowerState { pw.println(" mPendingBacklight=" + mPendingBacklight); pw.println(" mActualState=" + Display.stateToString(mActualState)); pw.println(" mActualBacklight=" + mActualBacklight); - pw.println(" mChangeInProgress=" + mChangeInProgress); + pw.println(" mStateChangeInProgress=" + mStateChangeInProgress); + pw.println(" mBacklightChangeInProgress=" + mBacklightChangeInProgress); } } @@ -392,10 +399,15 @@ final class DisplayPowerState { stateChanged = (state != mActualState); backlight = mPendingBacklight; backlightChanged = (backlight != mActualBacklight); - if (!stateChanged && !backlightChanged) { - // All changed applied, notify outer class and wait for more. - mChangeInProgress = false; + if (!stateChanged) { + // State changed applied, notify outer class. postScreenUpdateThreadSafe(); + mStateChangeInProgress = false; + } + if (!backlightChanged) { + mBacklightChangeInProgress = false; + } + if (!stateChanged && !backlightChanged) { try { mLock.wait(); } catch (InterruptedException ex) { } diff --git a/services/core/java/com/android/server/fingerprint/FingerprintService.java b/services/core/java/com/android/server/fingerprint/FingerprintService.java index ea7d85e..ec7c1c4 100644 --- a/services/core/java/com/android/server/fingerprint/FingerprintService.java +++ b/services/core/java/com/android/server/fingerprint/FingerprintService.java @@ -337,7 +337,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe return; } stopPendingOperations(true); - mEnrollClient = new ClientMonitor(token, receiver, groupId, restricted); + mEnrollClient = new ClientMonitor(token, receiver, groupId, restricted, token.toString()); final int timeout = (int) (ENROLLMENT_TIMEOUT_MS / MS_PER_SEC); try { final int result = daemon.enroll(cryptoToken, groupId, timeout); @@ -417,14 +417,15 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe } void startAuthentication(IBinder token, long opId, int groupId, - IFingerprintServiceReceiver receiver, int flags, boolean restricted) { + IFingerprintServiceReceiver receiver, int flags, boolean restricted, + String opPackageName) { IFingerprintDaemon daemon = getFingerprintDaemon(); if (daemon == null) { Slog.w(TAG, "startAuthentication: no fingeprintd!"); return; } stopPendingOperations(true); - mAuthClient = new ClientMonitor(token, receiver, groupId, restricted); + mAuthClient = new ClientMonitor(token, receiver, groupId, restricted, opPackageName); if (inLockoutMode()) { Slog.v(TAG, "In lockout mode; disallowing authentication"); if (!mAuthClient.sendError(FingerprintManager.FINGERPRINT_ERROR_LOCKOUT)) { @@ -481,7 +482,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe } stopPendingOperations(true); - mRemoveClient = new ClientMonitor(token, receiver, userId, restricted); + mRemoveClient = new ClientMonitor(token, receiver, userId, restricted, token.toString()); // The fingerprint template ids will be removed when we get confirmation from the HAL try { final int result = daemon.remove(fingerId, userId); @@ -574,11 +575,11 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe } if (mAppOps.noteOp(AppOpsManager.OP_USE_FINGERPRINT, uid, opPackageName) != AppOpsManager.MODE_ALLOWED) { - Slog.v(TAG, "Rejecting " + opPackageName + " ; permission denied"); + Slog.w(TAG, "Rejecting " + opPackageName + " ; permission denied"); return false; } if (foregroundOnly && !isForegroundActivity(uid, pid)) { - Slog.v(TAG, "Rejecting " + opPackageName + " ; not in foreground"); + Slog.w(TAG, "Rejecting " + opPackageName + " ; not in foreground"); return false; } return true; @@ -606,13 +607,15 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe IFingerprintServiceReceiver receiver; int userId; boolean restricted; // True if client does not have MANAGE_FINGERPRINT permission + String owner; public ClientMonitor(IBinder token, IFingerprintServiceReceiver receiver, int userId, - boolean restricted) { + boolean restricted, String owner) { this.token = token; this.receiver = receiver; this.userId = userId; this.restricted = restricted; + this.owner = owner; // name of the client that owns this - for debugging try { token.linkToDeath(this, 0); } catch (RemoteException e) { @@ -695,6 +698,10 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe if (!authenticated) { receiver.onAuthenticationFailed(mHalDeviceId); } else { + if (DEBUG) { + Slog.v(TAG, "onAuthenticated(owner=" + mAuthClient.owner + + ", id=" + fpId + ", gp=" + groupId + ")"); + } Fingerprint fp = !restricted ? new Fingerprint("" /* TODO */, groupId, fpId, mHalDeviceId) : null; receiver.onAuthenticationSucceeded(mHalDeviceId, fp); @@ -915,6 +922,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe final IFingerprintServiceReceiver receiver, final int flags, final String opPackageName) { if (!canUseFingerprint(opPackageName, true /* foregroundOnly */)) { + if (DEBUG) Slog.v(TAG, "authenticate(): reject " + opPackageName); return; } @@ -927,7 +935,8 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe @Override public void run() { MetricsLogger.histogram(mContext, "fingerprint_token", opId != 0L ? 1 : 0); - startAuthentication(token, opId, effectiveGroupId, receiver, flags, restricted); + startAuthentication(token, opId, effectiveGroupId, receiver, flags, restricted, + opPackageName); } }); } diff --git a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java index 96a5e00..b504605 100644 --- a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java +++ b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java @@ -245,6 +245,8 @@ final class DefaultPermissionGrantPolicy { if (verifierPackage != null && doesPackageSupportRuntimePermissions(verifierPackage)) { grantRuntimePermissionsLPw(verifierPackage, STORAGE_PERMISSIONS, true, userId); + grantRuntimePermissionsLPw(verifierPackage, PHONE_PERMISSIONS, false, userId); + grantRuntimePermissionsLPw(verifierPackage, SMS_PERMISSIONS, false, userId); } // SetupWizard diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java index 7024ec8..8c23648 100644 --- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java +++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java @@ -217,8 +217,7 @@ final class PackageDexOptimizer { @Nullable private String createOatDirIfSupported(PackageParser.Package pkg, String dexInstructionSet) throws IOException { - if ((pkg.isSystemApp() && !pkg.isUpdatedSystemApp()) || pkg.isForwardLocked() - || pkg.applicationInfo.isExternalAsec()) { + if (!pkg.canHaveOatDir()) { return null; } File codePath = new File(pkg.codePath); diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 96c5460..3330a50 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -13628,7 +13628,21 @@ public class PackageManagerService extends IPackageManager.Stub { // TODO(multiArch): Extend getSizeInfo to look at *all* instruction sets, not // just the primary. String[] dexCodeInstructionSets = getDexCodeInstructionSets(getAppDexInstructionSets(ps)); - int res = mInstaller.getSizeInfo(p.volumeUuid, packageName, userHandle, p.baseCodePath, + + String apkPath; + File packageDir = new File(p.codePath); + + if (packageDir.isDirectory() && p.canHaveOatDir()) { + apkPath = packageDir.getAbsolutePath(); + // If libDirRoot is inside a package dir, set it to null to avoid it being counted twice + if (libDirRoot != null && libDirRoot.startsWith(apkPath)) { + libDirRoot = null; + } + } else { + apkPath = p.baseCodePath; + } + + int res = mInstaller.getSizeInfo(p.volumeUuid, packageName, userHandle, apkPath, libDirRoot, publicSrcDir, asecPath, dexCodeInstructionSets, pStats); if (res < 0) { return false; diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index d7e3c54..31286b6 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -65,6 +65,7 @@ import android.os.Looper; import android.os.Message; import android.os.Messenger; import android.os.PowerManager; +import android.os.PowerManagerInternal; import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; @@ -267,6 +268,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { PowerManager mPowerManager; ActivityManagerInternal mActivityManagerInternal; DreamManagerInternal mDreamManagerInternal; + PowerManagerInternal mPowerManagerInternal; IStatusBarService mStatusBarService; boolean mPreloadedRecentApps; final Object mServiceAquireLock = new Object(); @@ -1330,6 +1332,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class); mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class); mDreamManagerInternal = LocalServices.getService(DreamManagerInternal.class); + mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class); mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE); // Init display burn-in protection @@ -1506,6 +1509,13 @@ public class PhoneWindowManager implements WindowManagerPolicy { } } @Override + public void onFling(int duration) { + if (mPowerManagerInternal != null) { + mPowerManagerInternal.powerHint( + PowerManagerInternal.POWER_HINT_INTERACTION, duration); + } + } + @Override public void onDebug() { // no-op } @@ -6074,6 +6084,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { mKeyguardDelegate.bindService(mContext); mKeyguardDelegate.onBootCompleted(); } + mSystemGestures.systemReady(); } /** {@inheritDoc} */ @@ -7017,5 +7028,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { if (mBurnInProtectionHelper != null) { mBurnInProtectionHelper.dump(prefix, pw); } + if (mKeyguardDelegate != null) { + mKeyguardDelegate.dump(prefix, pw); + } } } diff --git a/services/core/java/com/android/server/policy/SystemGesturesPointerEventListener.java b/services/core/java/com/android/server/policy/SystemGesturesPointerEventListener.java index 627b328..e4bd21d 100644 --- a/services/core/java/com/android/server/policy/SystemGesturesPointerEventListener.java +++ b/services/core/java/com/android/server/policy/SystemGesturesPointerEventListener.java @@ -17,9 +17,14 @@ package com.android.server.policy; import android.content.Context; +import android.os.Handler; +import android.os.Looper; +import android.os.SystemClock; import android.util.Slog; +import android.view.GestureDetector; import android.view.MotionEvent; import android.view.WindowManagerPolicy.PointerEventListener; +import android.widget.OverScroller; /* * Listens for system-wide input gestures, firing callbacks when detected. @@ -31,12 +36,14 @@ public class SystemGesturesPointerEventListener implements PointerEventListener private static final long SWIPE_TIMEOUT_MS = 500; private static final int MAX_TRACKED_POINTERS = 32; // max per input system private static final int UNTRACKED_POINTER = -1; + private static final int MAX_FLING_TIME_MILLIS = 5000; private static final int SWIPE_NONE = 0; private static final int SWIPE_FROM_TOP = 1; private static final int SWIPE_FROM_BOTTOM = 2; private static final int SWIPE_FROM_RIGHT = 3; + private final Context mContext; private final int mSwipeStartThreshold; private final int mSwipeDistanceThreshold; private final Callbacks mCallbacks; @@ -45,13 +52,18 @@ public class SystemGesturesPointerEventListener implements PointerEventListener private final float[] mDownY = new float[MAX_TRACKED_POINTERS]; private final long[] mDownTime = new long[MAX_TRACKED_POINTERS]; + private GestureDetector mGestureDetector; + private OverScroller mOverscroller; + int screenHeight; int screenWidth; private int mDownPointers; private boolean mSwipeFireable; private boolean mDebugFireable; + private long mLastFlingTime; public SystemGesturesPointerEventListener(Context context, Callbacks callbacks) { + mContext = context; mCallbacks = checkNull("callbacks", callbacks); mSwipeStartThreshold = checkNull("context", context).getResources() .getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height); @@ -67,8 +79,17 @@ public class SystemGesturesPointerEventListener implements PointerEventListener return arg; } + public void systemReady() { + Handler h = new Handler(Looper.myLooper()); + mGestureDetector = new GestureDetector(mContext, new FlingGestureDetector(), h); + mOverscroller = new OverScroller(mContext); + } + @Override public void onPointerEvent(MotionEvent event) { + if (mGestureDetector != null) { + mGestureDetector.onTouchEvent(event); + } switch (event.getActionMasked()) { case MotionEvent.ACTION_DOWN: mSwipeFireable = true; @@ -190,10 +211,40 @@ public class SystemGesturesPointerEventListener implements PointerEventListener return SWIPE_NONE; } + private final class FlingGestureDetector extends GestureDetector.SimpleOnGestureListener { + @Override + public boolean onSingleTapUp(MotionEvent e) { + if (!mOverscroller.isFinished()) { + mOverscroller.forceFinished(true); + } + return true; + } + @Override + public boolean onFling(MotionEvent down, MotionEvent up, + float velocityX, float velocityY) { + mOverscroller.computeScrollOffset(); + long now = SystemClock.uptimeMillis(); + + if (mLastFlingTime != 0 && now > mLastFlingTime + MAX_FLING_TIME_MILLIS) { + mOverscroller.forceFinished(true); + } + mOverscroller.fling(0, 0, (int)velocityX, (int)velocityY, + Integer.MIN_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE, Integer.MAX_VALUE); + int duration = mOverscroller.getDuration(); + if (duration > MAX_FLING_TIME_MILLIS) { + duration = MAX_FLING_TIME_MILLIS; + } + mLastFlingTime = now; + mCallbacks.onFling(duration); + return true; + } + } + interface Callbacks { void onSwipeFromTop(); void onSwipeFromBottom(); void onSwipeFromRight(); + void onFling(int durationMs); void onDown(); void onUpOrCancel(); void onDebug(); diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java index 6b45941..7ae3c79 100644 --- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java +++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java @@ -23,6 +23,8 @@ import com.android.internal.policy.IKeyguardDrawnCallback; import com.android.internal.policy.IKeyguardExitCallback; import com.android.internal.policy.IKeyguardService; +import java.io.PrintWriter; + /** * A local class that keeps a cache of keyguard state that can be restored in the event * keyguard crashes. It currently also allows runtime-selectable @@ -393,4 +395,26 @@ public class KeyguardServiceDelegate { mKeyguardService.onActivityDrawn(); } } + + public void dump(String prefix, PrintWriter pw) { + pw.println(prefix + TAG); + prefix += " "; + pw.println(prefix + "showing=" + mKeyguardState.showing); + pw.println(prefix + "showingAndNotOccluded=" + mKeyguardState.showingAndNotOccluded); + pw.println(prefix + "inputRestricted=" + mKeyguardState.inputRestricted); + pw.println(prefix + "occluded=" + mKeyguardState.occluded); + pw.println(prefix + "secure=" + mKeyguardState.secure); + pw.println(prefix + "dreaming=" + mKeyguardState.dreaming); + pw.println(prefix + "systemIsReady=" + mKeyguardState.systemIsReady); + pw.println(prefix + "deviceHasKeyguard=" + mKeyguardState.deviceHasKeyguard); + pw.println(prefix + "enabled=" + mKeyguardState.enabled); + pw.println(prefix + "offReason=" + mKeyguardState.offReason); + pw.println(prefix + "currentUser=" + mKeyguardState.currentUser); + pw.println(prefix + "bootCompleted=" + mKeyguardState.bootCompleted); + pw.println(prefix + "screenState=" + mKeyguardState.screenState); + pw.println(prefix + "interactiveState=" + mKeyguardState.interactiveState); + if (mKeyguardService != null) { + mKeyguardService.dump(prefix, pw); + } + } } diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java index cd88b66..429b188 100644 --- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java +++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java @@ -27,6 +27,8 @@ import com.android.internal.policy.IKeyguardExitCallback; import com.android.internal.policy.IKeyguardService; import com.android.internal.policy.IKeyguardStateCallback; +import java.io.PrintWriter; + /** * A wrapper class for KeyguardService. It implements IKeyguardService to ensure the interface * remains consistent. @@ -239,4 +241,8 @@ public class KeyguardServiceWrapper implements IKeyguardService { public boolean isInputRestricted() { return mKeyguardStateMonitor.isInputRestricted(); } + + public void dump(String prefix, PrintWriter pw) { + mKeyguardStateMonitor.dump(prefix, pw); + } }
\ No newline at end of file diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java b/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java index f1f9c50..30cff03 100644 --- a/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java +++ b/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java @@ -25,6 +25,8 @@ import com.android.internal.policy.IKeyguardService; import com.android.internal.policy.IKeyguardStateCallback; import com.android.internal.widget.LockPatternUtils; +import java.io.PrintWriter; + /** * Maintains a cached copy of Keyguard's state. * @hide @@ -90,4 +92,13 @@ public class KeyguardStateMonitor extends IKeyguardStateCallback.Stub { public void onInputRestrictedStateChanged(boolean inputRestricted) { mInputRestricted = inputRestricted; } + + public void dump(String prefix, PrintWriter pw) { + pw.println(prefix + TAG); + prefix += " "; + pw.println(prefix + "mIsShowing=" + mIsShowing); + pw.println(prefix + "mSimSecure=" + mSimSecure); + pw.println(prefix + "mInputRestricted=" + mInputRestricted); + pw.println(prefix + "mCurrentUserId=" + mCurrentUserId); + } }
\ No newline at end of file diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java index b920f97..f7a8970 100644 --- a/services/core/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -76,6 +76,7 @@ import java.util.Arrays; import libcore.util.Objects; +import static android.os.PowerManagerInternal.POWER_HINT_INTERACTION; import static android.os.PowerManagerInternal.WAKEFULNESS_ASLEEP; import static android.os.PowerManagerInternal.WAKEFULNESS_AWAKE; import static android.os.PowerManagerInternal.WAKEFULNESS_DREAMING; @@ -150,7 +151,6 @@ public final class PowerManagerService extends SystemService private static final int SCREEN_BRIGHTNESS_BOOST_TIMEOUT = 5 * 1000; // Power hints defined in hardware/libhardware/include/hardware/power.h. - private static final int POWER_HINT_INTERACTION = 2; private static final int POWER_HINT_LOW_POWER = 5; // Power features defined in hardware/libhardware/include/hardware/power.h. @@ -3534,5 +3534,10 @@ public final class PowerManagerService extends SystemService public void uidGone(int uid) { uidGoneInternal(uid); } + + @Override + public void powerHint(int hintId, int data) { + powerHintInternal(hintId, data); + } } } diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index 4a04cf1..aa4da4b 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -78,6 +78,15 @@ public class CarrierConfigManager { public static final String KEY_WORLD_PHONE_BOOL = "world_phone_bool"; /** + * Flag to require or skip entitlement checks. + * If true, entitlement checks will be executed if device has been configured for it, + * If false, entitlement checks will be skipped. + * @hide + */ + public static final String + KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL = "require_entitlement_checks_bool"; + + /** * If true, enable vibration (haptic feedback) for key presses in the EmergencyDialer activity. * The pattern is set on a per-platform basis using config_virtualKeyVibePattern. To be * consistent with the regular Dialer, this value should agree with the corresponding values @@ -277,6 +286,17 @@ public class CarrierConfigManager { "carrier_instant_lettering_invalid_chars_string"; /** + * When IMS instant lettering is available for a carrier (see + * {@link #KEY_CARRIER_INSTANT_LETTERING_AVAILABLE_BOOL}), determines a list of characters which + * must be escaped with a backslash '\' character. Should be specified as a string containing + * the characters to be escaped. For example to escape quote and backslash the string would be + * a quote and a backslash. + * @hide + */ + public static final String KEY_CARRIER_INSTANT_LETTERING_ESCAPED_CHARS_STRING = + "carrier_instant_lettering_escaped_chars_string"; + + /** * If Voice Radio Technology is RIL_RADIO_TECHNOLOGY_LTE:14 or RIL_RADIO_TECHNOLOGY_UNKNOWN:0 * this is the value that should be used instead. A configuration value of * RIL_RADIO_TECHNOLOGY_UNKNOWN:0 means there is no replacement value and that the default @@ -299,6 +319,14 @@ public class CarrierConfigManager { public static final String KEY_CARRIER_FORCE_DISABLE_ETWS_CMAS_TEST_BOOL = "carrier_force_disable_etws_cmas_test_bool"; + /** + * The default flag specifying whether "Turn on Notifications" option will be always shown in + * Settings->More->Emergency broadcasts menu regardless developer options is turned on or not. + * @hide + */ + public static final String KEY_ALWAYS_SHOW_EMERGENCY_ALERT_ONOFF_BOOL = + "always_show_emergency_alert_onoff_bool"; + /* The following 3 fields are related to carrier visual voicemail. */ /** @@ -357,6 +385,14 @@ public class CarrierConfigManager { * successive DTMF tones on the network. * @hide */ + public static final String KEY_GSM_DTMF_TONE_DELAY_INT = "gsm_dtmf_tone_delay_int"; + + /** + * Specifies the amount of gap to be added in millis between DTMF tones. When a non-zero value + * is specified, the UE shall wait for the specified amount of time before it sends out + * successive DTMF tones on the network. + * @hide + */ public static final String KEY_IMS_DTMF_TONE_DELAY_INT = "ims_dtmf_tone_delay_int"; /** @@ -455,6 +491,7 @@ public class CarrierConfigManager { sDefaults.putBoolean(KEY_CARRIER_ALLOW_TURNOFF_IMS_BOOL, true); sDefaults.putBoolean(KEY_CARRIER_INSTANT_LETTERING_AVAILABLE_BOOL, false); sDefaults.putString(KEY_CARRIER_INSTANT_LETTERING_INVALID_CHARS_STRING, ""); + sDefaults.putString(KEY_CARRIER_INSTANT_LETTERING_ESCAPED_CHARS_STRING, ""); sDefaults.putBoolean(KEY_DISABLE_CDMA_ACTIVATION_CODE_BOOL, false); sDefaults.putBoolean(KEY_DTMF_TYPE_ENABLED_BOOL, false); sDefaults.putBoolean(KEY_ENABLE_DIALER_KEY_VIBRATION_BOOL, true); @@ -475,6 +512,7 @@ public class CarrierConfigManager { sDefaults.putBoolean(KEY_VOICEMAIL_NOTIFICATION_PERSISTENT_BOOL, false); sDefaults.putBoolean(KEY_VOICE_PRIVACY_DISABLE_UI_BOOL, false); sDefaults.putBoolean(KEY_WORLD_PHONE_BOOL, false); + sDefaults.putBoolean(KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL, true); sDefaults.putInt(KEY_VOLTE_REPLACEMENT_RAT_INT, 0); sDefaults.putString(KEY_DEFAULT_SIM_CALL_MANAGER_STRING, ""); sDefaults.putString(KEY_VVM_DESTINATION_NUMBER_STRING, ""); @@ -486,12 +524,14 @@ public class CarrierConfigManager { sDefaults.putString(KEY_CI_ACTION_ON_SYS_UPDATE_EXTRA_STRING, ""); sDefaults.putString(KEY_CI_ACTION_ON_SYS_UPDATE_EXTRA_VAL_STRING, ""); sDefaults.putBoolean(KEY_CSP_ENABLED_BOOL, false); + sDefaults.putBoolean(KEY_ALWAYS_SHOW_EMERGENCY_ALERT_ONOFF_BOOL, false); sDefaults.putStringArray(KEY_GSM_ROAMING_NETWORKS_STRING_ARRAY, null); sDefaults.putStringArray(KEY_GSM_NONROAMING_NETWORKS_STRING_ARRAY, null); sDefaults.putStringArray(KEY_CDMA_ROAMING_NETWORKS_STRING_ARRAY, null); sDefaults.putStringArray(KEY_CDMA_NONROAMING_NETWORKS_STRING_ARRAY, null); sDefaults.putBoolean(KEY_FORCE_HOME_NETWORK_BOOL, false); + sDefaults.putInt(KEY_GSM_DTMF_TONE_DELAY_INT, 0); sDefaults.putInt(KEY_IMS_DTMF_TONE_DELAY_INT, 0); sDefaults.putBoolean(KEY_SUPPORT_CONFERENCE_CALL_BOOL, true); sDefaults.putBoolean(KEY_EDITABLE_ENHANCED_4G_LTE_BOOL, true); |
