Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9fd000bf authored by Xin Li's avatar Xin Li Committed by Gerrit Code Review
Browse files

Merge "DO NOT MERGE - Merge QQ2A.200405.005 into master"

parents 43a219ee ab1261dd
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -1157,8 +1157,11 @@ public final class AssetManager implements AutoCloseable {
            }
        }

        synchronized (this) {
            if (mObject != 0) {
                nativeDestroy(mObject);
                mObject = 0;
            }
        }
    }

+0 −1
Original line number Diff line number Diff line
@@ -157,7 +157,6 @@ public class ExternalVibration implements Parcelable {
        out.writeInt(mUid);
        out.writeString(mPkg);
        writeAudioAttributes(mAttrs, out, flags);
        out.writeParcelable(mAttrs, flags);
        out.writeStrongBinder(mController.asBinder());
        out.writeStrongBinder(mToken);
    }
+30 −67
Original line number Diff line number Diff line
@@ -92,10 +92,7 @@ import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.CancellationException;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

/**
@@ -424,13 +421,6 @@ public final class InputMethodManager {
    int mCursorCandStart;
    int mCursorCandEnd;

    /**
     * Initial startInput with {@link StartInputReason.WINDOW_FOCUS_GAIN} is executed
     * in a background thread. Later, if there is an actual startInput it will wait on
     * main thread till the background thread completes.
     */
    private CompletableFuture<Void> mWindowFocusGainFuture;

    /**
     * The instance that has previously been sent to the input method.
     */
@@ -655,7 +645,6 @@ public final class InputMethodManager {
                            } catch (RemoteException e) {
                            }
                        }
                    }
                        // Check focus again in case that "onWindowFocus" is called before
                        // handling this message.
                        if (mServedView != null && canStartInput(mServedView)) {
@@ -665,6 +654,7 @@ public final class InputMethodManager {
                                startInputInner(reason, null, 0, 0, 0);
                            }
                        }
                    }
                    return;
                }
                case MSG_SEND_INPUT_EVENT: {
@@ -1225,10 +1215,6 @@ public final class InputMethodManager {
     */
    void clearBindingLocked() {
        if (DEBUG) Log.v(TAG, "Clearing binding!");
        if (mWindowFocusGainFuture != null) {
            mWindowFocusGainFuture.cancel(false /* mayInterruptIfRunning */);
            mWindowFocusGainFuture = null;
        }
        clearConnectionLocked();
        setInputChannelLocked(null);
        mBindSequence = -1;
@@ -1612,18 +1598,6 @@ public final class InputMethodManager {
    boolean startInputInner(@StartInputReason int startInputReason,
            @Nullable IBinder windowGainingFocus, @StartInputFlags int startInputFlags,
            @SoftInputModeFlags int softInputMode, int windowFlags) {
        if (startInputReason != StartInputReason.WINDOW_FOCUS_GAIN
                && mWindowFocusGainFuture != null) {
            try {
                mWindowFocusGainFuture.get();
            } catch (ExecutionException | InterruptedException e) {
                // do nothing
            } catch (CancellationException e) {
                // window no longer has focus.
                return true;
            }
        }

        final View view;
        synchronized (mH) {
            view = mServedView;
@@ -1977,19 +1951,13 @@ public final class InputMethodManager {
            startInputFlags |= StartInputFlags.FIRST_WINDOW_FOCUS_GAIN;
        }

        final boolean forceNewFocus1 = forceNewFocus;
        final int startInputFlags1 = startInputFlags;
        if (mWindowFocusGainFuture != null) {
            mWindowFocusGainFuture.cancel(false/* mayInterruptIfRunning */);
        }
        mWindowFocusGainFuture = CompletableFuture.runAsync(() -> {
            if (checkFocusNoStartInput(forceNewFocus1)) {
        if (checkFocusNoStartInput(forceNewFocus)) {
            // We need to restart input on the current focus view.  This
            // should be done in conjunction with telling the system service
            // about the window gaining focus, to help make the transition
            // smooth.
            if (startInputInner(StartInputReason.WINDOW_FOCUS_GAIN, rootView.getWindowToken(),
                        startInputFlags1, softInputMode, windowFlags)) {
                    startInputFlags, softInputMode, windowFlags)) {
                return;
            }
        }
@@ -2001,14 +1969,13 @@ public final class InputMethodManager {
                if (DEBUG) Log.v(TAG, "Reporting focus gain, without startInput");
                mService.startInputOrWindowGainedFocus(
                        StartInputReason.WINDOW_FOCUS_GAIN_REPORT_ONLY, mClient,
                            rootView.getWindowToken(), startInputFlags1, softInputMode, windowFlags,
                        rootView.getWindowToken(), startInputFlags, softInputMode, windowFlags,
                        null, null, 0 /* missingMethodFlags */,
                        rootView.getContext().getApplicationInfo().targetSdkVersion);
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        }
        });
    }

    /** @hide */
@@ -2023,10 +1990,6 @@ public final class InputMethodManager {
                // If the mCurRootView is losing window focus, release the strong reference to it
                // so as not to prevent it from being garbage-collected.
                mCurRootView = null;
                if (mWindowFocusGainFuture != null) {
                    mWindowFocusGainFuture.cancel(false /* mayInterruptIfRunning */);
                    mWindowFocusGainFuture = null;
                }
            } else {
                if (DEBUG) {
                    Log.v(TAG, "Ignoring onPreWindowFocus()."
+47 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.os;

import static junit.framework.Assert.assertEquals;

import static org.mockito.Mockito.mock;

import android.media.AudioAttributes;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.junit.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.class)
public class ExternalVibrationTest {
    @Test
    public void testSerialization() {
        AudioAttributes audio = new AudioAttributes.Builder().build();
        IExternalVibrationController controller = mock(IExternalVibrationController.class);
        ExternalVibration original = new ExternalVibration(
                123, // uid
                "pkg",
                audio,
                controller);
        Parcel p = Parcel.obtain();
        original.writeToParcel(p, 0);
        p.setDataPosition(0);
        ExternalVibration restored = ExternalVibration.CREATOR.createFromParcel(p);
        assertEquals(original, restored);
    }
}
+43 −8
Original line number Diff line number Diff line
@@ -195,20 +195,32 @@ public class AppOpsControllerImpl implements AppOpsController,
            mNotedItems.remove(item);
            if (DEBUG) Log.w(TAG, "Removed item: " + item.toString());
        }
        boolean active;
        // Check if the item is also active
        synchronized (mActiveItems) {
            active = getAppOpItem(mActiveItems, code, uid, packageName) != null;
        }
        if (!active) {
            notifySuscribers(code, uid, packageName, false);
        }
    }

    private void addNoted(int code, int uid, String packageName) {
    private boolean addNoted(int code, int uid, String packageName) {
        AppOpItem item;
        boolean createdNew = false;
        synchronized (mNotedItems) {
            item = getAppOpItem(mNotedItems, code, uid, packageName);
            if (item == null) {
                item = new AppOpItem(code, uid, packageName, System.currentTimeMillis());
                mNotedItems.add(item);
                if (DEBUG) Log.w(TAG, "Added item: " + item.toString());
                createdNew = true;
            }
        }
        // We should keep this so we make sure it cannot time out.
        mBGHandler.removeCallbacksAndMessages(item);
        mBGHandler.scheduleRemoval(item, NOTED_OP_TIME_DELAY_MS);
        return createdNew;
    }

    /**
@@ -255,23 +267,46 @@ public class AppOpsControllerImpl implements AppOpsController,

    @Override
    public void onOpActiveChanged(int code, int uid, String packageName, boolean active) {
        if (updateActives(code, uid, packageName, active)) {
            notifySuscribers(code, uid, packageName, active);
        if (DEBUG) {
            Log.w(TAG, String.format("onActiveChanged(%d,%d,%s,%s", code, uid, packageName,
                    Boolean.toString(active)));
        }
        boolean activeChanged = updateActives(code, uid, packageName, active);
        if (!activeChanged) return; // early return
        // Check if the item is also noted, in that case, there's no update.
        boolean alsoNoted;
        synchronized (mNotedItems) {
            alsoNoted = getAppOpItem(mNotedItems, code, uid, packageName) != null;
        }
        // If active is true, we only send the update if the op is not actively noted (already true)
        // If active is false, we only send the update if the op is not actively noted (prevent
        // early removal)
        if (!alsoNoted) {
            mBGHandler.post(() -> notifySuscribers(code, uid, packageName, active));
        }
    }

    @Override
    public void onOpNoted(int code, int uid, String packageName, int result) {
        if (DEBUG) {
            Log.w(TAG, "Op: " + code + " with result " + AppOpsManager.MODE_NAMES[result]);
            Log.w(TAG, "Noted op: " + code + " with result "
                    + AppOpsManager.MODE_NAMES[result] + " for package " + packageName);
        }
        if (result != AppOpsManager.MODE_ALLOWED) return;
        addNoted(code, uid, packageName);
        notifySuscribers(code, uid, packageName, true);
        boolean notedAdded = addNoted(code, uid, packageName);
        if (!notedAdded) return; // early return
        boolean alsoActive;
        synchronized (mActiveItems) {
            alsoActive = getAppOpItem(mActiveItems, code, uid, packageName) != null;
        }
        if (!alsoActive) {
            mBGHandler.post(() -> notifySuscribers(code, uid, packageName, true));
        }
    }

    private void notifySuscribers(int code, int uid, String packageName, boolean active) {
        if (mCallbacksByCode.containsKey(code)) {
            if (DEBUG) Log.d(TAG, "Notifying of change in package " + packageName);
            for (Callback cb: mCallbacksByCode.get(code)) {
                cb.onActiveStateChanged(code, uid, packageName, active);
            }
@@ -295,7 +330,7 @@ public class AppOpsControllerImpl implements AppOpsController,

    }

    protected final class H extends Handler {
    protected class H extends Handler {
        H(Looper looper) {
            super(looper);
        }
Loading