android 手机虚拟按键 震动过程的追溯(1)

matthew@matthew:/media/matt1/ze550kl-m/out/target/product/Z00L/system/framework$ adb push ./services.jar  /system/framework/
2 KB/s (205 bytes in 0.072s)
matthew@matthew:/media/matt1/ze550kl-m/out/target/product/Z00L/system/framework$ cd /oat/arm64/
bash: cd: /oat/arm64/: 没有那个文件或目录
matthew@matthew:/media/matt1/ze550kl-m/out/target/product/Z00L/system/framework$ cd oat/arm64/
matthew@matthew:/media/matt1/ze550kl-m/out/target/product/Z00L/system/framework/oat/arm64$ adb push ./services.odex  /system/framework/oat/arm64/






void TouchInputMapper::dispatchVirtualKey(nsecs_t when, uint32_t policyFlags,
        int32_t keyEventAction, int32_t keyEventFlags) {
   getListener()->notifyKey(&args);
}


到了
void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
           ALOGD("matt-interceptKeyBeforeQueueing5");
    mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
 }






 private int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) {
      Slog.e(TAG, "matt-interceptKeyBeforeQueueing3");
        return mWindowManagerCallbacks.interceptKeyBeforeQueueing(event, policyFlags);
    }
到了
   public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) {
        Slog.d(WindowManagerService.TAG, "matt-interceptKeyBeforeQueueing2 ");
        return mService.mPolicy.interceptKeyBeforeQueueing(event, policyFlags);
    }
到了






然后到了
 public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) {


 if (useHapticFeedback) {
            performHapticFeedbackLw(null, HapticFeedbackConstants.VIRTUAL_KEY, false);
        }     


}
然后到了


public boolean performHapticFeedbackLw(WindowState win, int effectId, boolean always) {


            owningUid = android.os.Process.myUid();
            owningPackage = mContext.getOpPackageName();






             if (pattern.length == 1) {
            // One-shot vibration
            mVibrator.vibrate(owningUid, owningPackage, pattern[0], VIBRATION_ATTRIBUTES);//调用震动器
        } else {
            // Pattern vibration
            mVibrator.vibrate(owningUid, owningPackage, pattern, -1, VIBRATION_ATTRIBUTES);//调用震动器
        }
}




到了SystemVibrator.java里
 public void vibrate(int uid, String opPkg, long[] pattern, int repeat,
            AudioAttributes attributes) {
            Log.e(TAG, "matt-+1");
        if (mService == null) {
            Log.w(TAG, "Failed to vibrate; no vibrator service.");
            return;
        }
        // catch this here because the server will do nothing.  pattern may
        // not be null, let that be checked, because the server will drop it
        // anyway
        if (repeat < pattern.length) {
            try {
                mService.vibratePattern(uid, opPkg, pattern, repeat, usageForAttributes(attributes),//启动震动
                        mToken);
            } catch (RemoteException e) {
                Log.w(TAG, "Failed to vibrate.", e);
            }
        } else {
            throw new ArrayIndexOutOfBoundsException();
        }
    }
到了
 public void vibratePattern(int uid, String packageName, long[] pattern, int repeat,
            int usageHint, IBinder token) {
        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.VIBRATE)
                != PackageManager.PERMISSION_GRANTED) {
            throw new SecurityException("Requires VIBRATE permission");
        }
        verifyIncomingUid(uid);
        // so wakelock calls will succeed
        long identity = Binder.clearCallingIdentity();
        try {
            if (DEBUG) {
                String s = "";
                int N = pattern.length;
                for (int i=0; i<N; i++) {
                    s += " " + pattern[i];
                }
                Slog.d(TAG, "Vibrating with pattern:" + s);
            }


            // we're running in the server so we can't fail
            if (pattern == null || pattern.length == 0
                    || isAll0(pattern)
                    || repeat >= pattern.length || token == null) {
                return;
            }


            Vibration vib = new Vibration(token, pattern, repeat, usageHint, uid, packageName);
            try {
                token.linkToDeath(vib, 0);
            } catch (RemoteException e) {
                return;
            }


            synchronized (mVibrations) {
                removeVibrationLocked(token);
                doCancelVibrateLocked();
                if (repeat >= 0) {
                    mVibrations.addFirst(vib);
                    startNextVibrationLocked(); //启动震动
                } else {
                    // A negative repeat means that this pattern is not meant
                    // to repeat. Treat it like a simple vibration.
                    mCurrentVibration = vib;
                    startVibrationLocked(vib);
                }
                addToPreviousVibrationsLocked(vib);
            }
        }
        finally {
            Binder.restoreCallingIdentity(identity);
        }
    }
到了
private void startVibrationLocked(final Vibration vib) {
        try {
            if (mLowPowerMode
                    && vib.mUsageHint != AudioAttributes.USAGE_NOTIFICATION_RINGTONE) {
                return;
            }


            int mode = mAppOpsService.checkAudioOperation(AppOpsManager.OP_VIBRATE,
                    vib.mUsageHint, vib.mUid, vib.mOpPkg);
            if (mode == AppOpsManager.MODE_ALLOWED) {
                mode = mAppOpsService.startOperation(AppOpsManager.getToken(mAppOpsService),
                    AppOpsManager.OP_VIBRATE, vib.mUid, vib.mOpPkg);
            }
            if (mode != AppOpsManager.MODE_ALLOWED) {
                if (mode == AppOpsManager.MODE_ERRORED) {
                    Slog.w(TAG, "Would be an error: vibrate from uid " + vib.mUid);
                }
                mH.post(mVibrationRunnable);
                return;
            }
        } catch (RemoteException e) {
        }
        if (vib.mTimeout != 0) {
            doVibratorOn(vib.mTimeout, vib.mUid, vib.mUsageHint);
            // <asus-olaf20151119+>
            switch (asus_PRJ_ID) {
                case 1://ASUS600KL
                    mH.postDelayed(mVibrationRunnable, vib.mTimeout + VIB_CAL_MS);
                    break;
                default:
                    mH.postDelayed(mVibrationRunnable, vib.mTimeout);
                    break;
            }
            // <asus-olaf20151119->
        } else {
            // mThread better be null here. doCancelVibrate should always be
            // called before startNextVibrationLocked or startVibrationLocked.
            mThread = new VibrateThread(vib);  //启动一个新的线程
            mThread.start();
        }
    }
跑到了run函数
public void run() {
            Process.setThreadPriority(Process.THREAD_PRIORITY_URGENT_DISPLAY);
            synchronized (this) {
                final long[] pattern = mVibration.mPattern;
                final int len = pattern.length;
                final int repeat = mVibration.mRepeat;
                final int uid = mVibration.mUid;
                final int usageHint = mVibration.mUsageHint;
                int index = 0;
                long duration = 0;


                while (!mDone) {
                    // add off-time duration to any accumulated on-time duration
                    if (index < len) {
                        duration += pattern[index++];
                    }


                    // sleep until it is time to start the vibrator
                    delay(duration);
                    if (mDone) {
                        break;
                    }


                    if (index < len) {
                        // read on-time duration and start the vibrator
                        // duration is saved for delay() at top of loop
                        duration = pattern[index++];
                        if (duration > 0) {
                            VibratorService.this.doVibratorOn(duration, uid, usageHint);//最后是这边震动
                        }
                    } else {
                        if (repeat < 0) {
                            break;
                        } else {
                            index = repeat;
                            duration = 0;
                        }
                    }
                }
                mWakeLock.release();
            }
            synchronized (mVibrations) {
                if (mThread == this) {
                    mThread = null;
                }
                if (!mDone) {
                    // If this vibration finished naturally, start the next
                    // vibration.
                    unlinkVibration(mVibration);
                    startNextVibrationLocked();
                }
            }
        }
    }
跑到
private void doVibratorOn(long millis, int uid, int usageHint) {
        synchronized (mInputDeviceVibrators) {
            if (DEBUG) {
                Slog.d(TAG, "Turning vibrator on for " + millis + " ms.");
            }
            try {
                mBatteryStatsService.noteVibratorOn(uid, millis);
                mCurVibUid = uid;
            } catch (RemoteException e) {
            }
            final int vibratorCount = mInputDeviceVibrators.size();
            if (vibratorCount != 0) {
                final AudioAttributes attributes = new AudioAttributes.Builder().setUsage(usageHint)
                        .build();
                for (int i = 0; i < vibratorCount; i++) {
                    mInputDeviceVibrators.get(i).vibrate(millis, attributes);
                }
            } else {
// <asus-olaf20151119+>
                switch (asus_PRJ_ID) {
                    case 1://ASUS600KL
                        vibratorOn(millis + VIB_CAL_MS);
                        break;
                    default:
                        vibratorOn(millis);
                        break;
                }
                // <asus-olaf20151119->
            }
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值